mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
This commit is contained in:
		
						commit
						ae3568adf4
					
				
					 145 changed files with 3891 additions and 2859 deletions
				
			
		
							
								
								
									
										20
									
								
								MAINTAINERS
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								MAINTAINERS
									
										
									
									
									
								
							|  | @ -3671,7 +3671,7 @@ F:	include/linux/mv643xx.h | |||
| MARVELL MWL8K WIRELESS DRIVER | ||||
| M:	Lennert Buytenhek <buytenh@wantstofly.org> | ||||
| L:	linux-wireless@vger.kernel.org | ||||
| S:	Maintained | ||||
| S:	Odd Fixes | ||||
| F:	drivers/net/wireless/mwl8k.c | ||||
| 
 | ||||
| MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER | ||||
|  | @ -4522,7 +4522,7 @@ PRISM54 WIRELESS DRIVER | |||
| M:	"Luis R. Rodriguez" <mcgrof@gmail.com> | ||||
| L:	linux-wireless@vger.kernel.org | ||||
| W:	http://prism54.org | ||||
| S:	Maintained | ||||
| S:	Obsolete | ||||
| F:	drivers/net/wireless/prism54/ | ||||
| 
 | ||||
| PROMISE DC4030 CACHING DISK CONTROLLER DRIVER | ||||
|  | @ -4712,9 +4712,8 @@ S:	Maintained | |||
| F:	drivers/rapidio/ | ||||
| 
 | ||||
| RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER | ||||
| M:	Corey Thomas <coreythomas@charter.net> | ||||
| L:	linux-wireless@vger.kernel.org | ||||
| S:	Maintained | ||||
| S:	Orphan | ||||
| F:	drivers/net/wireless/ray* | ||||
| 
 | ||||
| RCUTORTURE MODULE | ||||
|  | @ -6037,10 +6036,9 @@ F:	Documentation/video4linux/zc0301.txt | |||
| F:	drivers/media/video/zc0301/ | ||||
| 
 | ||||
| USB ZD1201 DRIVER | ||||
| M:	Jeroen Vreeken <pe1rxq@amsat.org> | ||||
| L:	linux-usb@vger.kernel.org | ||||
| L:	linux-wireless@vger.kernel.org | ||||
| W:	http://linux-lc100020.sourceforge.net | ||||
| S:	Maintained | ||||
| S:	Orphan | ||||
| F:	drivers/net/wireless/zd1201.* | ||||
| 
 | ||||
| USB ZR364XX DRIVER | ||||
|  | @ -6226,14 +6224,6 @@ F:	Documentation/watchdog/ | |||
| F:	drivers/watchdog/ | ||||
| F:	include/linux/watchdog.h | ||||
| 
 | ||||
| WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS | ||||
| M:	Jean Tourrilhes <jt@hpl.hp.com> | ||||
| L:	linux-wireless@vger.kernel.org | ||||
| W:	http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ | ||||
| S:	Maintained | ||||
| F:	Documentation/networking/wavelan.txt | ||||
| F:	drivers/staging/wavelan/ | ||||
| 
 | ||||
| WD7000 SCSI DRIVER | ||||
| M:	Miroslav Zagorac <zaga@fly.cc.fer.hr> | ||||
| L:	linux-scsi@vger.kernel.org | ||||
|  |  | |||
|  | @ -58,6 +58,18 @@ config BT_HCIUART_BCSP | |||
| 
 | ||||
| 	  Say Y here to compile support for HCI BCSP protocol. | ||||
| 
 | ||||
| config BT_HCIUART_ATH3K | ||||
| 	bool "Atheros AR300x serial support" | ||||
| 	depends on BT_HCIUART | ||||
| 	help | ||||
| 	  HCIATH3K (HCI Atheros AR300x) is a serial protocol for | ||||
| 	  communication between host and Atheros AR300x Bluetooth devices. | ||||
| 	  This protocol enables AR300x chips to be enabled with | ||||
| 	  power management support. | ||||
| 	  Enable this if you have Atheros AR300x serial Bluetooth device. | ||||
| 
 | ||||
| 	  Say Y here to compile support for HCI UART ATH3K protocol. | ||||
| 
 | ||||
| config BT_HCIUART_LL | ||||
| 	bool "HCILL protocol support" | ||||
| 	depends on BT_HCIUART | ||||
|  |  | |||
|  | @ -26,4 +26,5 @@ hci_uart-y				:= hci_ldisc.o | |||
| hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o | ||||
| hci_uart-$(CONFIG_BT_HCIUART_BCSP)	+= hci_bcsp.o | ||||
| hci_uart-$(CONFIG_BT_HCIUART_LL)	+= hci_ll.o | ||||
| hci_uart-$(CONFIG_BT_HCIUART_ATH3K)	+= hci_ath.o | ||||
| hci_uart-objs				:= $(hci_uart-y) | ||||
|  |  | |||
|  | @ -224,7 +224,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 
 | ||||
| 	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); | ||||
| 
 | ||||
| 	data->fw_data = kmalloc(firmware->size, GFP_KERNEL); | ||||
| 	data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL); | ||||
| 	if (!data->fw_data) { | ||||
| 		BT_ERR("Can't allocate memory for firmware image"); | ||||
| 		release_firmware(firmware); | ||||
|  | @ -234,7 +234,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(data->fw_data, firmware->data, firmware->size); | ||||
| 	data->fw_size = firmware->size; | ||||
| 	data->fw_sent = 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ struct hci_vendor_hdr { | |||
| 	__u8    type; | ||||
| 	__le16  snum; | ||||
| 	__le16  dlen; | ||||
| } __attribute__ ((packed)); | ||||
| } __packed; | ||||
| 
 | ||||
| static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) | ||||
| { | ||||
|  |  | |||
|  | @ -216,7 +216,7 @@ static const struct file_operations btmrvl_gpiogap_fops = { | |||
| static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | ||||
| 						size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data; | ||||
| 	struct btmrvl_private *priv = file->private_data; | ||||
| 	char buf[16]; | ||||
| 	long result, ret; | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,6 +76,7 @@ struct btmrvl_private { | |||
| 	int (*hw_host_to_card) (struct btmrvl_private *priv, | ||||
| 				u8 *payload, u16 nb); | ||||
| 	int (*hw_wakeup_firmware) (struct btmrvl_private *priv); | ||||
| 	int (*hw_process_int_status) (struct btmrvl_private *priv); | ||||
| 	spinlock_t driver_lock;		/* spinlock used by driver */ | ||||
| #ifdef CONFIG_DEBUG_FS | ||||
| 	void *debugfs_data; | ||||
|  | @ -118,13 +119,13 @@ struct btmrvl_cmd { | |||
| 	__le16 ocf_ogf; | ||||
| 	u8 length; | ||||
| 	u8 data[4]; | ||||
| } __attribute__ ((packed)); | ||||
| } __packed; | ||||
| 
 | ||||
| struct btmrvl_event { | ||||
| 	u8 ec;		/* event counter */ | ||||
| 	u8 length; | ||||
| 	u8 data[4]; | ||||
| } __attribute__ ((packed)); | ||||
| } __packed; | ||||
| 
 | ||||
| /* Prototype of global function */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -502,14 +502,17 @@ static int btmrvl_service_main_thread(void *data) | |||
| 		spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 		if (adapter->int_count) { | ||||
| 			adapter->int_count = 0; | ||||
| 			spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 			priv->hw_process_int_status(priv); | ||||
| 		} else if (adapter->ps_state == PS_SLEEP && | ||||
| 					!skb_queue_empty(&adapter->tx_queue)) { | ||||
| 			spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 			adapter->wakeup_tries++; | ||||
| 			priv->hw_wakeup_firmware(priv); | ||||
| 			continue; | ||||
| 		} | ||||
| 		} else { | ||||
| 			spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 		} | ||||
| 
 | ||||
| 		if (adapter->ps_state == PS_SLEEP) | ||||
| 			continue; | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ | |||
|  * module_exit function is called. | ||||
|  */ | ||||
| static u8 user_rmmod; | ||||
| static u8 sdio_ireg; | ||||
| 
 | ||||
| static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { | ||||
| 	.helper		= "sd8688_helper.bin", | ||||
|  | @ -83,10 +84,10 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) | |||
| 	*dat = 0; | ||||
| 
 | ||||
| 	fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); | ||||
| 	if (ret) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	if (!ret) | ||||
| 	fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); | ||||
| 
 | ||||
| 	if (ret) | ||||
| 		return -EIO; | ||||
| 
 | ||||
|  | @ -216,7 +217,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
| 
 | ||||
| 	tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); | ||||
| 
 | ||||
| 	tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); | ||||
| 	tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL); | ||||
| 	if (!tmphlprbuf) { | ||||
| 		BT_ERR("Unable to allocate buffer for helper." | ||||
| 			" Terminating download"); | ||||
|  | @ -224,8 +225,6 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	memset(tmphlprbuf, 0, tmphlprbufsz); | ||||
| 
 | ||||
| 	helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN); | ||||
| 
 | ||||
| 	/* Perform helper data transfer */ | ||||
|  | @ -318,7 +317,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
| 	BT_DBG("Downloading FW image (%d bytes)", firmwarelen); | ||||
| 
 | ||||
| 	tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); | ||||
| 	tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); | ||||
| 	tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL); | ||||
| 	if (!tmpfwbuf) { | ||||
| 		BT_ERR("Unable to allocate buffer for firmware." | ||||
| 		       " Terminating download"); | ||||
|  | @ -326,8 +325,6 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	memset(tmpfwbuf, 0, tmpfwbufsz); | ||||
| 
 | ||||
| 	/* Ensure aligned firmware buffer */ | ||||
| 	fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN); | ||||
| 
 | ||||
|  | @ -555,79 +552,80 @@ exit: | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg) | ||||
| static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv) | ||||
| { | ||||
| 	int ret; | ||||
| 	u8 sdio_ireg = 0; | ||||
| 	ulong flags; | ||||
| 	u8 ireg; | ||||
| 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; | ||||
| 
 | ||||
| 	*ireg = 0; | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 	ireg = sdio_ireg; | ||||
| 	sdio_ireg = 0; | ||||
| 	spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 
 | ||||
| 	sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); | ||||
| 	if (ret) { | ||||
| 		BT_ERR("sdio_readb: read int status register failed"); | ||||
| 		ret = -EIO; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	if (sdio_ireg != 0) { | ||||
| 		/*
 | ||||
| 		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS | ||||
| 		 * Clear the interrupt status register and re-enable the | ||||
| 		 * interrupt. | ||||
| 		 */ | ||||
| 		BT_DBG("sdio_ireg = 0x%x", sdio_ireg); | ||||
| 
 | ||||
| 		sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS | | ||||
| 							UP_LD_HOST_INT_STATUS), | ||||
| 			    HOST_INTSTATUS_REG, &ret); | ||||
| 		if (ret) { | ||||
| 			BT_ERR("sdio_writeb: clear int status register " | ||||
| 				"failed"); | ||||
| 			ret = -EIO; | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (sdio_ireg & DN_LD_HOST_INT_STATUS) { | ||||
| 	sdio_claim_host(card->func); | ||||
| 	if (ireg & DN_LD_HOST_INT_STATUS) { | ||||
| 		if (priv->btmrvl_dev.tx_dnld_rdy) | ||||
| 			BT_DBG("tx_done already received: " | ||||
| 				" int_status=0x%x", sdio_ireg); | ||||
| 				" int_status=0x%x", ireg); | ||||
| 		else | ||||
| 			priv->btmrvl_dev.tx_dnld_rdy = true; | ||||
| 	} | ||||
| 
 | ||||
| 	if (sdio_ireg & UP_LD_HOST_INT_STATUS) | ||||
| 	if (ireg & UP_LD_HOST_INT_STATUS) | ||||
| 		btmrvl_sdio_card_to_host(priv); | ||||
| 
 | ||||
| 	*ireg = sdio_ireg; | ||||
| 	sdio_release_host(card->func); | ||||
| 
 | ||||
| 	ret = 0; | ||||
| 
 | ||||
| done: | ||||
| 	return ret; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void btmrvl_sdio_interrupt(struct sdio_func *func) | ||||
| { | ||||
| 	struct btmrvl_private *priv; | ||||
| 	struct hci_dev *hcidev; | ||||
| 	struct btmrvl_sdio_card *card; | ||||
| 	ulong flags; | ||||
| 	u8 ireg = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	card = sdio_get_drvdata(func); | ||||
| 	if (card && card->priv) { | ||||
| 		priv = card->priv; | ||||
| 		hcidev = priv->btmrvl_dev.hcidev; | ||||
| 	if (!card || !card->priv) { | ||||
| 		BT_ERR("sbi_interrupt(%p) card or priv is " | ||||
| 				"NULL, card=%p\n", func, card); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 		if (btmrvl_sdio_get_int_status(priv, &ireg)) | ||||
| 			BT_ERR("reading HOST_INT_STATUS_REG failed"); | ||||
| 		else | ||||
| 			BT_DBG("HOST_INT_STATUS_REG %#x", ireg); | ||||
| 	priv = card->priv; | ||||
| 
 | ||||
| 	ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); | ||||
| 	if (ret) { | ||||
| 		BT_ERR("sdio_readb: read int status register failed"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ireg != 0) { | ||||
| 		/*
 | ||||
| 		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS | ||||
| 		 * Clear the interrupt status register and re-enable the | ||||
| 		 * interrupt. | ||||
| 		 */ | ||||
| 		BT_DBG("ireg = 0x%x", ireg); | ||||
| 
 | ||||
| 		sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | | ||||
| 					UP_LD_HOST_INT_STATUS), | ||||
| 				HOST_INTSTATUS_REG, &ret); | ||||
| 		if (ret) { | ||||
| 			BT_ERR("sdio_writeb: clear int status register failed"); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 	sdio_ireg |= ireg; | ||||
| 	spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 
 | ||||
| 	btmrvl_interrupt(priv); | ||||
| } | ||||
| } | ||||
| 
 | ||||
| static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | ||||
| { | ||||
|  | @ -930,6 +928,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
| 	/* Initialize the interface specific function pointers */ | ||||
| 	priv->hw_host_to_card = btmrvl_sdio_host_to_card; | ||||
| 	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw; | ||||
| 	priv->hw_process_int_status = btmrvl_sdio_process_int_status; | ||||
| 
 | ||||
| 	if (btmrvl_register_hdev(priv)) { | ||||
| 		BT_ERR("Register hdev failed!"); | ||||
|  |  | |||
|  | @ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = { | |||
| 	/* Generic Bluetooth USB device */ | ||||
| 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | ||||
| 
 | ||||
| 	/* Apple iMac11,1 */ | ||||
| 	{ USB_DEVICE(0x05ac, 0x8215) }, | ||||
| 
 | ||||
| 	/* AVM BlueFRITZ! USB v2.0 */ | ||||
| 	{ USB_DEVICE(0x057c, 0x3800) }, | ||||
| 
 | ||||
|  | @ -146,6 +149,7 @@ static struct usb_device_id blacklist_table[] = { | |||
| #define BTUSB_BULK_RUNNING	1 | ||||
| #define BTUSB_ISOC_RUNNING	2 | ||||
| #define BTUSB_SUSPENDING	3 | ||||
| #define BTUSB_DID_ISO_RESUME	4 | ||||
| 
 | ||||
| struct btusb_data { | ||||
| 	struct hci_dev       *hdev; | ||||
|  | @ -179,7 +183,6 @@ struct btusb_data { | |||
| 	unsigned int sco_num; | ||||
| 	int isoc_altsetting; | ||||
| 	int suspend_count; | ||||
| 	int did_iso_resume:1; | ||||
| }; | ||||
| 
 | ||||
| static int inc_tx(struct btusb_data *data) | ||||
|  | @ -807,7 +810,7 @@ static void btusb_work(struct work_struct *work) | |||
| 	int err; | ||||
| 
 | ||||
| 	if (hdev->conn_hash.sco_num > 0) { | ||||
| 		if (!data->did_iso_resume) { | ||||
| 		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { | ||||
| 			err = usb_autopm_get_interface(data->isoc); | ||||
| 			if (err < 0) { | ||||
| 				clear_bit(BTUSB_ISOC_RUNNING, &data->flags); | ||||
|  | @ -815,7 +818,7 @@ static void btusb_work(struct work_struct *work) | |||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			data->did_iso_resume = 1; | ||||
| 			set_bit(BTUSB_DID_ISO_RESUME, &data->flags); | ||||
| 		} | ||||
| 		if (data->isoc_altsetting != 2) { | ||||
| 			clear_bit(BTUSB_ISOC_RUNNING, &data->flags); | ||||
|  | @ -836,12 +839,10 @@ static void btusb_work(struct work_struct *work) | |||
| 		usb_kill_anchored_urbs(&data->isoc_anchor); | ||||
| 
 | ||||
| 		__set_isoc_interface(hdev, 0); | ||||
| 		if (data->did_iso_resume) { | ||||
| 			data->did_iso_resume = 0; | ||||
| 		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) | ||||
| 			usb_autopm_put_interface(data->isoc); | ||||
| 	} | ||||
| } | ||||
| } | ||||
| 
 | ||||
| static void btusb_waker(struct work_struct *work) | ||||
| { | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ typedef struct { | |||
| 	u8 type; | ||||
| 	u8 zero; | ||||
| 	u16 len; | ||||
| } __attribute__ ((packed)) nsh_t;	/* Nokia Specific Header */ | ||||
| } __packed nsh_t;	/* Nokia Specific Header */ | ||||
| 
 | ||||
| #define NSHL  4				/* Nokia Specific Header Length */ | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										235
									
								
								drivers/bluetooth/hci_ath.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								drivers/bluetooth/hci_ath.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,235 @@ | |||
| /*
 | ||||
|  *  Atheros Communication Bluetooth HCIATH3K UART protocol | ||||
|  * | ||||
|  *  HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's | ||||
|  *  power management protocol extension to H4 to support AR300x Bluetooth Chip. | ||||
|  * | ||||
|  *  Copyright (c) 2009-2010 Atheros Communications Inc. | ||||
|  * | ||||
|  *  Acknowledgements: | ||||
|  *  This file is based on hci_h4.c, which was written | ||||
|  *  by Maxim Krasnyansky and Marcel Holtmann. | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License as published by | ||||
|  *  the Free Software Foundation; either version 2 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/module.h> | ||||
| #include <linux/kernel.h> | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/tty.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/ioctl.h> | ||||
| #include <linux/skbuff.h> | ||||
| 
 | ||||
| #include <net/bluetooth/bluetooth.h> | ||||
| #include <net/bluetooth/hci_core.h> | ||||
| 
 | ||||
| #include "hci_uart.h" | ||||
| 
 | ||||
| struct ath_struct { | ||||
| 	struct hci_uart *hu; | ||||
| 	unsigned int cur_sleep; | ||||
| 
 | ||||
| 	struct sk_buff_head txq; | ||||
| 	struct work_struct ctxtsw; | ||||
| }; | ||||
| 
 | ||||
| static int ath_wakeup_ar3k(struct tty_struct *tty) | ||||
| { | ||||
| 	struct termios settings; | ||||
| 	int status = tty->driver->ops->tiocmget(tty, NULL); | ||||
| 
 | ||||
| 	if (status & TIOCM_CTS) | ||||
| 		return status; | ||||
| 
 | ||||
| 	/* Disable Automatic RTSCTS */ | ||||
| 	n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); | ||||
| 	settings.c_cflag &= ~CRTSCTS; | ||||
| 	n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); | ||||
| 
 | ||||
| 	/* Clear RTS first */ | ||||
| 	status = tty->driver->ops->tiocmget(tty, NULL); | ||||
| 	tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS); | ||||
| 	mdelay(20); | ||||
| 
 | ||||
| 	/* Set RTS, wake up board */ | ||||
| 	status = tty->driver->ops->tiocmget(tty, NULL); | ||||
| 	tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00); | ||||
| 	mdelay(20); | ||||
| 
 | ||||
| 	status = tty->driver->ops->tiocmget(tty, NULL); | ||||
| 
 | ||||
| 	n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); | ||||
| 	settings.c_cflag |= CRTSCTS; | ||||
| 	n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); | ||||
| 
 | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| static void ath_hci_uart_work(struct work_struct *work) | ||||
| { | ||||
| 	int status; | ||||
| 	struct ath_struct *ath; | ||||
| 	struct hci_uart *hu; | ||||
| 	struct tty_struct *tty; | ||||
| 
 | ||||
| 	ath = container_of(work, struct ath_struct, ctxtsw); | ||||
| 
 | ||||
| 	hu = ath->hu; | ||||
| 	tty = hu->tty; | ||||
| 
 | ||||
| 	/* verify and wake up controller */ | ||||
| 	if (ath->cur_sleep) { | ||||
| 		status = ath_wakeup_ar3k(tty); | ||||
| 		if (!(status & TIOCM_CTS)) | ||||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Ready to send Data */ | ||||
| 	clear_bit(HCI_UART_SENDING, &hu->tx_state); | ||||
| 	hci_uart_tx_wakeup(hu); | ||||
| } | ||||
| 
 | ||||
| /* Initialize protocol */ | ||||
| static int ath_open(struct hci_uart *hu) | ||||
| { | ||||
| 	struct ath_struct *ath; | ||||
| 
 | ||||
| 	BT_DBG("hu %p", hu); | ||||
| 
 | ||||
| 	ath = kzalloc(sizeof(*ath), GFP_ATOMIC); | ||||
| 	if (!ath) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	skb_queue_head_init(&ath->txq); | ||||
| 
 | ||||
| 	hu->priv = ath; | ||||
| 	ath->hu = hu; | ||||
| 
 | ||||
| 	INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Flush protocol data */ | ||||
| static int ath_flush(struct hci_uart *hu) | ||||
| { | ||||
| 	struct ath_struct *ath = hu->priv; | ||||
| 
 | ||||
| 	BT_DBG("hu %p", hu); | ||||
| 
 | ||||
| 	skb_queue_purge(&ath->txq); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Close protocol */ | ||||
| static int ath_close(struct hci_uart *hu) | ||||
| { | ||||
| 	struct ath_struct *ath = hu->priv; | ||||
| 
 | ||||
| 	BT_DBG("hu %p", hu); | ||||
| 
 | ||||
| 	skb_queue_purge(&ath->txq); | ||||
| 
 | ||||
| 	cancel_work_sync(&ath->ctxtsw); | ||||
| 
 | ||||
| 	hu->priv = NULL; | ||||
| 	kfree(ath); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #define HCI_OP_ATH_SLEEP 0xFC04 | ||||
| 
 | ||||
| /* Enqueue frame for transmittion */ | ||||
| static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) | ||||
| { | ||||
| 	struct ath_struct *ath = hu->priv; | ||||
| 
 | ||||
| 	if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { | ||||
| 		kfree_skb(skb); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Update power management enable flag with parameters of | ||||
| 	 * HCI sleep enable vendor specific HCI command. | ||||
| 	 */ | ||||
| 	if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { | ||||
| 		struct hci_command_hdr *hdr = (void *)skb->data; | ||||
| 
 | ||||
| 		if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP) | ||||
| 			ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE]; | ||||
| 	} | ||||
| 
 | ||||
| 	BT_DBG("hu %p skb %p", hu, skb); | ||||
| 
 | ||||
| 	/* Prepend skb with frame type */ | ||||
| 	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | ||||
| 
 | ||||
| 	skb_queue_tail(&ath->txq, skb); | ||||
| 	set_bit(HCI_UART_SENDING, &hu->tx_state); | ||||
| 
 | ||||
| 	schedule_work(&ath->ctxtsw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct sk_buff *ath_dequeue(struct hci_uart *hu) | ||||
| { | ||||
| 	struct ath_struct *ath = hu->priv; | ||||
| 
 | ||||
| 	return skb_dequeue(&ath->txq); | ||||
| } | ||||
| 
 | ||||
| /* Recv data */ | ||||
| static int ath_recv(struct hci_uart *hu, void *data, int count) | ||||
| { | ||||
| 	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | ||||
| 		BT_ERR("Frame Reassembly Failed"); | ||||
| 
 | ||||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| static struct hci_uart_proto athp = { | ||||
| 	.id = HCI_UART_ATH3K, | ||||
| 	.open = ath_open, | ||||
| 	.close = ath_close, | ||||
| 	.recv = ath_recv, | ||||
| 	.enqueue = ath_enqueue, | ||||
| 	.dequeue = ath_dequeue, | ||||
| 	.flush = ath_flush, | ||||
| }; | ||||
| 
 | ||||
| int __init ath_init(void) | ||||
| { | ||||
| 	int err = hci_uart_register_proto(&athp); | ||||
| 
 | ||||
| 	if (!err) | ||||
| 		BT_INFO("HCIATH3K protocol initialized"); | ||||
| 	else | ||||
| 		BT_ERR("HCIATH3K protocol registration failed"); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| int __exit ath_deinit(void) | ||||
| { | ||||
| 	return hci_uart_unregister_proto(&athp); | ||||
| } | ||||
|  | @ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = { | |||
| 	.flush		= bcsp_flush | ||||
| }; | ||||
| 
 | ||||
| int bcsp_init(void) | ||||
| int __init bcsp_init(void) | ||||
| { | ||||
| 	int err = hci_uart_register_proto(&bcsp); | ||||
| 
 | ||||
|  | @ -751,7 +751,7 @@ int bcsp_init(void) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| int bcsp_deinit(void) | ||||
| int __exit bcsp_deinit(void) | ||||
| { | ||||
| 	return hci_uart_unregister_proto(&bcsp); | ||||
| } | ||||
|  |  | |||
|  | @ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
| /* Recv data */ | ||||
| static int h4_recv(struct hci_uart *hu, void *data, int count) | ||||
| { | ||||
| 	struct h4_struct *h4 = hu->priv; | ||||
| 	register char *ptr; | ||||
| 	struct hci_event_hdr *eh; | ||||
| 	struct hci_acl_hdr   *ah; | ||||
| 	struct hci_sco_hdr   *sh; | ||||
| 	register int len, type, dlen; | ||||
| 
 | ||||
| 	BT_DBG("hu %p count %d rx_state %ld rx_count %ld",  | ||||
| 			hu, count, h4->rx_state, h4->rx_count); | ||||
| 
 | ||||
| 	ptr = data; | ||||
| 	while (count) { | ||||
| 		if (h4->rx_count) { | ||||
| 			len = min_t(unsigned int, h4->rx_count, count); | ||||
| 			memcpy(skb_put(h4->rx_skb, len), ptr, len); | ||||
| 			h4->rx_count -= len; count -= len; ptr += len; | ||||
| 
 | ||||
| 			if (h4->rx_count) | ||||
| 				continue; | ||||
| 
 | ||||
| 			switch (h4->rx_state) { | ||||
| 			case H4_W4_DATA: | ||||
| 				BT_DBG("Complete data"); | ||||
| 
 | ||||
| 				hci_recv_frame(h4->rx_skb); | ||||
| 
 | ||||
| 				h4->rx_state = H4_W4_PACKET_TYPE; | ||||
| 				h4->rx_skb = NULL; | ||||
| 				continue; | ||||
| 
 | ||||
| 			case H4_W4_EVENT_HDR: | ||||
| 				eh = hci_event_hdr(h4->rx_skb); | ||||
| 
 | ||||
| 				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); | ||||
| 
 | ||||
| 				h4_check_data_len(h4, eh->plen); | ||||
| 				continue; | ||||
| 
 | ||||
| 			case H4_W4_ACL_HDR: | ||||
| 				ah = hci_acl_hdr(h4->rx_skb); | ||||
| 				dlen = __le16_to_cpu(ah->dlen); | ||||
| 
 | ||||
| 				BT_DBG("ACL header: dlen %d", dlen); | ||||
| 
 | ||||
| 				h4_check_data_len(h4, dlen); | ||||
| 				continue; | ||||
| 
 | ||||
| 			case H4_W4_SCO_HDR: | ||||
| 				sh = hci_sco_hdr(h4->rx_skb); | ||||
| 
 | ||||
| 				BT_DBG("SCO header: dlen %d", sh->dlen); | ||||
| 
 | ||||
| 				h4_check_data_len(h4, sh->dlen); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		/* H4_W4_PACKET_TYPE */ | ||||
| 		switch (*ptr) { | ||||
| 		case HCI_EVENT_PKT: | ||||
| 			BT_DBG("Event packet"); | ||||
| 			h4->rx_state = H4_W4_EVENT_HDR; | ||||
| 			h4->rx_count = HCI_EVENT_HDR_SIZE; | ||||
| 			type = HCI_EVENT_PKT; | ||||
| 			break; | ||||
| 
 | ||||
| 		case HCI_ACLDATA_PKT: | ||||
| 			BT_DBG("ACL packet"); | ||||
| 			h4->rx_state = H4_W4_ACL_HDR; | ||||
| 			h4->rx_count = HCI_ACL_HDR_SIZE; | ||||
| 			type = HCI_ACLDATA_PKT; | ||||
| 			break; | ||||
| 
 | ||||
| 		case HCI_SCODATA_PKT: | ||||
| 			BT_DBG("SCO packet"); | ||||
| 			h4->rx_state = H4_W4_SCO_HDR; | ||||
| 			h4->rx_count = HCI_SCO_HDR_SIZE; | ||||
| 			type = HCI_SCODATA_PKT; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr); | ||||
| 			hu->hdev->stat.err_rx++; | ||||
| 			ptr++; count--; | ||||
| 			continue; | ||||
| 		}; | ||||
| 
 | ||||
| 		ptr++; count--; | ||||
| 
 | ||||
| 		/* Allocate packet */ | ||||
| 		h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); | ||||
| 		if (!h4->rx_skb) { | ||||
| 			BT_ERR("Can't allocate mem for new packet"); | ||||
| 			h4->rx_state = H4_W4_PACKET_TYPE; | ||||
| 			h4->rx_count = 0; | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 
 | ||||
| 		h4->rx_skb->dev = (void *) hu->hdev; | ||||
| 		bt_cb(h4->rx_skb)->pkt_type = type; | ||||
| 	} | ||||
| 	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | ||||
| 		BT_ERR("Frame Reassembly Failed"); | ||||
| 
 | ||||
| 	return count; | ||||
| } | ||||
|  | @ -272,7 +173,7 @@ static struct hci_uart_proto h4p = { | |||
| 	.flush		= h4_flush, | ||||
| }; | ||||
| 
 | ||||
| int h4_init(void) | ||||
| int __init h4_init(void) | ||||
| { | ||||
| 	int err = hci_uart_register_proto(&h4p); | ||||
| 
 | ||||
|  | @ -284,7 +185,7 @@ int h4_init(void) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| int h4_deinit(void) | ||||
| int __exit h4_deinit(void) | ||||
| { | ||||
| 	return hci_uart_unregister_proto(&h4p); | ||||
| } | ||||
|  |  | |||
|  | @ -210,7 +210,6 @@ static int hci_uart_close(struct hci_dev *hdev) | |||
| static int hci_uart_send_frame(struct sk_buff *skb) | ||||
| { | ||||
| 	struct hci_dev* hdev = (struct hci_dev *) skb->dev; | ||||
| 	struct tty_struct *tty; | ||||
| 	struct hci_uart *hu; | ||||
| 
 | ||||
| 	if (!hdev) { | ||||
|  | @ -222,7 +221,6 @@ static int hci_uart_send_frame(struct sk_buff *skb) | |||
| 		return -EBUSY; | ||||
| 
 | ||||
| 	hu = (struct hci_uart *) hdev->driver_data; | ||||
| 	tty = hu->tty; | ||||
| 
 | ||||
| 	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); | ||||
| 
 | ||||
|  | @ -397,6 +395,9 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
| 	if (!reset) | ||||
| 		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); | ||||
| 
 | ||||
| 	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) | ||||
| 		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); | ||||
| 
 | ||||
| 	if (hci_register_dev(hdev) < 0) { | ||||
| 		BT_ERR("Can't register HCI device"); | ||||
| 		hci_free_dev(hdev); | ||||
|  | @ -477,6 +478,15 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, | |||
| 			return hu->hdev->id; | ||||
| 		return -EUNATCH; | ||||
| 
 | ||||
| 	case HCIUARTSETFLAGS: | ||||
| 		if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) | ||||
| 			return -EBUSY; | ||||
| 		hu->hdev_flags = arg; | ||||
| 		break; | ||||
| 
 | ||||
| 	case HCIUARTGETFLAGS: | ||||
| 		return hu->hdev_flags; | ||||
| 
 | ||||
| 	default: | ||||
| 		err = n_tty_ioctl_helper(tty, file, cmd, arg); | ||||
| 		break; | ||||
|  | @ -542,6 +552,9 @@ static int __init hci_uart_init(void) | |||
| #ifdef CONFIG_BT_HCIUART_LL | ||||
| 	ll_init(); | ||||
| #endif | ||||
| #ifdef CONFIG_BT_HCIUART_ATH3K | ||||
| 	ath_init(); | ||||
| #endif | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -559,6 +572,9 @@ static void __exit hci_uart_exit(void) | |||
| #ifdef CONFIG_BT_HCIUART_LL | ||||
| 	ll_deinit(); | ||||
| #endif | ||||
| #ifdef CONFIG_BT_HCIUART_ATH3K | ||||
| 	ath_deinit(); | ||||
| #endif | ||||
| 
 | ||||
| 	/* Release tty registration of line discipline */ | ||||
| 	if ((err = tty_unregister_ldisc(N_HCI))) | ||||
|  |  | |||
|  | @ -74,7 +74,7 @@ enum hcill_states_e { | |||
| 
 | ||||
| struct hcill_cmd { | ||||
| 	u8 cmd; | ||||
| } __attribute__((packed)); | ||||
| } __packed; | ||||
| 
 | ||||
| struct ll_struct { | ||||
| 	unsigned long rx_state; | ||||
|  | @ -517,7 +517,7 @@ static struct hci_uart_proto llp = { | |||
| 	.flush		= ll_flush, | ||||
| }; | ||||
| 
 | ||||
| int ll_init(void) | ||||
| int __init ll_init(void) | ||||
| { | ||||
| 	int err = hci_uart_register_proto(&llp); | ||||
| 
 | ||||
|  | @ -529,7 +529,7 @@ int ll_init(void) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| int ll_deinit(void) | ||||
| int __exit ll_deinit(void) | ||||
| { | ||||
| 	return hci_uart_unregister_proto(&llp); | ||||
| } | ||||
|  |  | |||
|  | @ -31,15 +31,20 @@ | |||
| #define HCIUARTSETPROTO		_IOW('U', 200, int) | ||||
| #define HCIUARTGETPROTO		_IOR('U', 201, int) | ||||
| #define HCIUARTGETDEVICE	_IOR('U', 202, int) | ||||
| #define HCIUARTSETFLAGS		_IOW('U', 203, int) | ||||
| #define HCIUARTGETFLAGS		_IOR('U', 204, int) | ||||
| 
 | ||||
| /* UART protocols */ | ||||
| #define HCI_UART_MAX_PROTO	5 | ||||
| #define HCI_UART_MAX_PROTO	6 | ||||
| 
 | ||||
| #define HCI_UART_H4	0 | ||||
| #define HCI_UART_BCSP	1 | ||||
| #define HCI_UART_3WIRE	2 | ||||
| #define HCI_UART_H4DS	3 | ||||
| #define HCI_UART_LL	4 | ||||
| #define HCI_UART_ATH3K	5 | ||||
| 
 | ||||
| #define HCI_UART_RAW_DEVICE	0 | ||||
| 
 | ||||
| struct hci_uart; | ||||
| 
 | ||||
|  | @ -57,6 +62,7 @@ struct hci_uart { | |||
| 	struct tty_struct	*tty; | ||||
| 	struct hci_dev		*hdev; | ||||
| 	unsigned long		flags; | ||||
| 	unsigned long		hdev_flags; | ||||
| 
 | ||||
| 	struct hci_uart_proto	*proto; | ||||
| 	void			*priv; | ||||
|  | @ -66,7 +72,7 @@ struct hci_uart { | |||
| 	spinlock_t		rx_lock; | ||||
| }; | ||||
| 
 | ||||
| /* HCI_UART flag bits */ | ||||
| /* HCI_UART proto flag bits */ | ||||
| #define HCI_UART_PROTO_SET	0 | ||||
| 
 | ||||
| /* TX states  */ | ||||
|  | @ -91,3 +97,8 @@ int bcsp_deinit(void); | |||
| int ll_init(void); | ||||
| int ll_deinit(void); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_BT_HCIUART_ATH3K | ||||
| int ath_init(void); | ||||
| int ath_deinit(void); | ||||
| #endif | ||||
|  |  | |||
|  | @ -373,8 +373,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
| 		pktlen = status & RDES0_STATUS_FL; | ||||
| 		if (pktlen > RX_PKT_SIZE) { | ||||
| 			if (net_ratelimit()) | ||||
| 				printk(KERN_DEBUG "%s: frame too long (%d)\n", | ||||
| 				       wiphy_name(dev->wiphy), pktlen); | ||||
| 				wiphy_debug(dev->wiphy, "frame too long (%d)\n", | ||||
| 					    pktlen); | ||||
| 			pktlen = RX_PKT_SIZE; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -457,7 +457,7 @@ static irqreturn_t adm8211_interrupt(int irq, void *dev_id) | |||
| #define ADM8211_INT(x)						\ | ||||
| do {								\ | ||||
| 	if (unlikely(stsr & ADM8211_STSR_ ## x))		\ | ||||
| 		printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \ | ||||
| 		wiphy_debug(dev->wiphy, "%s\n", #x);		\ | ||||
| } while (0) | ||||
| 
 | ||||
| 	struct ieee80211_hw *dev = dev_id; | ||||
|  | @ -570,9 +570,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) | |||
| 	} | ||||
| 
 | ||||
| 	if (timeout == 0) { | ||||
| 		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" | ||||
| 		       " prewrite (reg=0x%08x)\n", | ||||
| 		       wiphy_name(dev->wiphy), addr, data, reg); | ||||
| 		wiphy_debug(dev->wiphy, | ||||
| 			    "adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n", | ||||
| 			    addr, data, reg); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -605,9 +605,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) | |||
| 	if (timeout == 0) { | ||||
| 		ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) & | ||||
| 				  ~ADM8211_BBPCTL_WR); | ||||
| 		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" | ||||
| 		       " postwrite (reg=0x%08x)\n", | ||||
| 		       wiphy_name(dev->wiphy), addr, data, reg); | ||||
| 		wiphy_debug(dev->wiphy, | ||||
| 			    "adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n", | ||||
| 			    addr, data, reg); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -675,8 +675,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) | |||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		printk(KERN_DEBUG "%s: unsupported transceiver type %d\n", | ||||
| 		       wiphy_name(dev->wiphy), priv->transceiver_type); | ||||
| 		wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n", | ||||
| 			    priv->transceiver_type); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -732,8 +732,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) | |||
| 
 | ||||
| 	/* Nothing to do for ADMtek BBP */ | ||||
| 	} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) | ||||
| 		printk(KERN_DEBUG "%s: unsupported BBP type %d\n", | ||||
| 		       wiphy_name(dev->wiphy), priv->bbp_type); | ||||
| 		wiphy_debug(dev->wiphy, "unsupported bbp type %d\n", | ||||
| 			    priv->bbp_type); | ||||
| 
 | ||||
| 	ADM8211_RESTORE(); | ||||
| 
 | ||||
|  | @ -1027,13 +1027,12 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev) | |||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			printk(KERN_DEBUG "%s: unsupported transceiver %d\n", | ||||
| 			       wiphy_name(dev->wiphy), priv->transceiver_type); | ||||
| 			wiphy_debug(dev->wiphy, "unsupported transceiver %d\n", | ||||
| 				    priv->transceiver_type); | ||||
| 			break; | ||||
| 		} | ||||
| 	} else | ||||
| 		printk(KERN_DEBUG "%s: unsupported BBP %d\n", | ||||
| 		       wiphy_name(dev->wiphy), priv->bbp_type); | ||||
| 		wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type); | ||||
| 
 | ||||
| 	ADM8211_CSR_WRITE(SYNRF, 0); | ||||
| 
 | ||||
|  | @ -1509,15 +1508,13 @@ static int adm8211_start(struct ieee80211_hw *dev) | |||
| 	/* Power up MAC and RF chips */ | ||||
| 	retval = adm8211_hw_reset(dev); | ||||
| 	if (retval) { | ||||
| 		printk(KERN_ERR "%s: hardware reset failed\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "hardware reset failed\n"); | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
| 	retval = adm8211_init_rings(dev); | ||||
| 	if (retval) { | ||||
| 		printk(KERN_ERR "%s: failed to initialize rings\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "failed to initialize rings\n"); | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1528,8 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev) | |||
| 	retval = request_irq(priv->pdev->irq, adm8211_interrupt, | ||||
| 			     IRQF_SHARED, "adm8211", dev); | ||||
| 	if (retval) { | ||||
| 		printk(KERN_ERR "%s: failed to register IRQ handler\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "failed to register irq handler\n"); | ||||
| 		goto fail; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1906,9 +1902,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
| 		goto err_free_eeprom; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n", | ||||
| 	       wiphy_name(dev->wiphy), dev->wiphy->perm_addr, | ||||
| 	       pdev->revision); | ||||
| 	wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n", | ||||
| 		   dev->wiphy->perm_addr, pdev->revision); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -92,17 +92,14 @@ | |||
| #define at76_dbg(bits, format, arg...)					\ | ||||
| do {									\ | ||||
| 	if (at76_debug & (bits))					\ | ||||
| 			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ | ||||
| 			       ## arg);					 \ | ||||
| 		printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg);	\ | ||||
| } while (0) | ||||
| 
 | ||||
| #define at76_dbg_dump(bits, buf, len, format, arg...)			\ | ||||
| do {									\ | ||||
| 	if (at76_debug & (bits)) {					\ | ||||
| 			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ | ||||
| 			       ## arg);					 \ | ||||
| 			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,     \ | ||||
| 					     buf, len);			 \ | ||||
| 		printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg);	\ | ||||
| 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);	\ | ||||
| 	}								\ | ||||
| } while (0) | ||||
| 
 | ||||
|  | @ -658,8 +655,8 @@ static int at76_get_hw_config(struct at76_priv *priv) | |||
| exit: | ||||
| 	kfree(hwcfg); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n", | ||||
| 			  ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -794,8 +791,9 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) | |||
| 	do { | ||||
| 		status = at76_get_cmd_status(priv->udev, cmd); | ||||
| 		if (status < 0) { | ||||
| 			printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", | ||||
| 			       wiphy_name(priv->hw->wiphy), status); | ||||
| 			wiphy_err(priv->hw->wiphy, | ||||
| 				  "at76_get_cmd_status failed: %d\n", | ||||
| 				  status); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -810,9 +808,8 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) | |||
| 
 | ||||
| 		schedule_timeout_interruptible(HZ / 10);	/* 100 ms */ | ||||
| 		if (time_after(jiffies, timeout)) { | ||||
| 			printk(KERN_ERR | ||||
| 			       "%s: completion timeout for command %d\n", | ||||
| 			       wiphy_name(priv->hw->wiphy), cmd); | ||||
| 			wiphy_err(priv->hw->wiphy, | ||||
| 				  "completion timeout for command %d\n", cmd); | ||||
| 			status = -ETIMEDOUT; | ||||
| 			break; | ||||
| 		} | ||||
|  | @ -833,9 +830,9 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf) | |||
| 
 | ||||
| 	ret = at76_wait_completion(priv, CMD_SET_MIB); | ||||
| 	if (ret != CMD_STATUS_COMPLETE) { | ||||
| 		printk(KERN_INFO | ||||
| 		       "%s: set_mib: at76_wait_completion failed " | ||||
| 		       "with %d\n", wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_info(priv->hw->wiphy, | ||||
| 			   "set_mib: at76_wait_completion failed with %d\n", | ||||
| 			   ret); | ||||
| 		ret = -EIO; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -855,8 +852,8 @@ static int at76_set_radio(struct at76_priv *priv, int enable) | |||
| 
 | ||||
| 	ret = at76_set_card_command(priv->udev, cmd, NULL, 0); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), cmd, ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_set_card_command(%d) failed: %d\n", cmd, ret); | ||||
| 	else | ||||
| 		ret = 1; | ||||
| 
 | ||||
|  | @ -876,8 +873,8 @@ static int at76_set_pm_mode(struct at76_priv *priv) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "set_mib (pm_mode) failed: %d\n", | ||||
| 			  ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -893,8 +890,8 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "set_mib (preamble) failed: %d\n", | ||||
| 			  ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -910,8 +907,8 @@ static int at76_set_frag(struct at76_priv *priv, u16 size) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "set_mib (frag threshold) failed: %d\n", ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -927,8 +924,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "set_mib (rts) failed: %d\n", ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -944,8 +940,8 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "set_mib (autorate fallback) failed: %d\n", ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -963,8 +959,8 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) | |||
| 	ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m, | ||||
| 			   sizeof(struct mib_mac_addr)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (mac_addr) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -992,8 +988,8 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) | |||
| 	ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m, | ||||
| 			   sizeof(struct mib_mac_wep)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (mac_wep) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1029,8 +1025,8 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) | |||
| 	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m, | ||||
| 			   sizeof(struct mib_mac_mgmt)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (mac_mgmt) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1065,8 +1061,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv) | |||
| 
 | ||||
| 	ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (mac) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1102,8 +1098,8 @@ static void at76_dump_mib_phy(struct at76_priv *priv) | |||
| 
 | ||||
| 	ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (phy) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1135,8 +1131,8 @@ static void at76_dump_mib_local(struct at76_priv *priv) | |||
| 
 | ||||
| 	ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (local) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1161,8 +1157,8 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) | |||
| 	ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m, | ||||
| 			   sizeof(struct mib_mdomain)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "at76_get_mib (mdomain) failed: %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1233,16 +1229,16 @@ static int at76_submit_rx_urb(struct at76_priv *priv) | |||
| 	struct sk_buff *skb = priv->rx_skb; | ||||
| 
 | ||||
| 	if (!priv->rx_urb) { | ||||
| 		printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), __func__); | ||||
| 		wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n", | ||||
| 			  __func__); | ||||
| 		return -EFAULT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!skb) { | ||||
| 		skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); | ||||
| 		if (!skb) { | ||||
| 			printk(KERN_ERR "%s: cannot allocate rx skbuff\n", | ||||
| 			       wiphy_name(priv->hw->wiphy)); | ||||
| 			wiphy_err(priv->hw->wiphy, | ||||
| 				  "cannot allocate rx skbuff\n"); | ||||
| 			ret = -ENOMEM; | ||||
| 			goto exit; | ||||
| 		} | ||||
|  | @ -1261,15 +1257,14 @@ static int at76_submit_rx_urb(struct at76_priv *priv) | |||
| 			at76_dbg(DBG_DEVSTART, | ||||
| 				 "usb_submit_urb returned -ENODEV"); | ||||
| 		else | ||||
| 			printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", | ||||
| 			       wiphy_name(priv->hw->wiphy), ret); | ||||
| 			wiphy_err(priv->hw->wiphy, | ||||
| 				  "rx, usb_submit_urb failed: %d\n", ret); | ||||
| 	} | ||||
| 
 | ||||
| exit: | ||||
| 	if (ret < 0 && ret != -ENODEV) | ||||
| 		printk(KERN_ERR "%s: cannot submit rx urb - please unload the " | ||||
| 		       "driver and/or power cycle the device\n", | ||||
| 		       wiphy_name(priv->hw->wiphy)); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "cannot submit rx urb - please unload the driver and/or power cycle the device\n"); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -1438,8 +1433,8 @@ static int at76_startup_device(struct at76_priv *priv) | |||
| 	ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config, | ||||
| 				    sizeof(struct at76_card_config)); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", | ||||
| 			  ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1504,8 +1499,8 @@ static void at76_work_set_promisc(struct work_struct *work) | |||
| 
 | ||||
| 	ret = at76_set_mib(priv, &priv->mib_buf); | ||||
| 	if (ret < 0) | ||||
| 		printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "set_mib (promiscuous_mode) failed: %d\n", ret); | ||||
| 
 | ||||
| 	mutex_unlock(&priv->mtx); | ||||
| } | ||||
|  | @ -1668,16 +1663,16 @@ static int at76_join(struct at76_priv *priv) | |||
| 				    sizeof(struct at76_req_join)); | ||||
| 
 | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", | ||||
| 			  ret); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = at76_wait_completion(priv, CMD_JOIN); | ||||
| 	at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); | ||||
| 	if (ret != CMD_STATUS_COMPLETE) { | ||||
| 		printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "at76_wait_completion failed: %d\n", | ||||
| 			  ret); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1745,8 +1740,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 	at76_dbg(DBG_MAC80211, "%s()", __func__); | ||||
| 
 | ||||
| 	if (priv->tx_urb->status == -EINPROGRESS) { | ||||
| 		printk(KERN_ERR "%s: %s called while tx urb is pending\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), __func__); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "%s called while tx urb is pending\n", __func__); | ||||
| 		return NETDEV_TX_BUSY; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1794,12 +1789,11 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 			  submit_len, at76_mac80211_tx_callback, priv); | ||||
| 	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR "%s: error in tx submit urb: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); | ||||
| 		if (ret == -EINVAL) | ||||
| 			printk(KERN_ERR | ||||
| 			       "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", | ||||
| 			       wiphy_name(priv->hw->wiphy), priv->tx_urb, | ||||
| 			wiphy_err(priv->hw->wiphy, | ||||
| 				  "-einval: tx urb %p hcpriv %p complete %p\n", | ||||
| 				  priv->tx_urb, | ||||
| 				  priv->tx_urb->hcpriv, priv->tx_urb->complete); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1817,8 +1811,8 @@ static int at76_mac80211_start(struct ieee80211_hw *hw) | |||
| 
 | ||||
| 	ret = at76_submit_rx_urb(priv); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), ret); | ||||
| 		wiphy_err(priv->hw->wiphy, "open: submit_rx_urb failed: %d\n", | ||||
| 			  ret); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -2316,13 +2310,11 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
| 
 | ||||
| 	priv->mac80211_registered = 1; | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n", | ||||
| 	       wiphy_name(priv->hw->wiphy), | ||||
| 	wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n", | ||||
| 		   dev_name(&interface->dev), priv->mac_addr, | ||||
| 		   priv->fw_version.major, priv->fw_version.minor, | ||||
| 		   priv->fw_version.patch, priv->fw_version.build); | ||||
| 	printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", | ||||
| 	       wiphy_name(priv->hw->wiphy), | ||||
| 	wiphy_info(priv->hw->wiphy, "regulatory domain 0x%02x: %s\n", | ||||
| 		   priv->regulatory_domain, priv->domain->name); | ||||
| 
 | ||||
| exit: | ||||
|  | @ -2485,7 +2477,7 @@ static void at76_disconnect(struct usb_interface *interface) | |||
| 	if (!priv) | ||||
| 		return; | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy)); | ||||
| 	wiphy_info(priv->hw->wiphy, "disconnecting\n"); | ||||
| 	at76_delete_device(priv); | ||||
| 	dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); | ||||
| } | ||||
|  |  | |||
|  | @ -48,8 +48,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) | |||
| 
 | ||||
| 	err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); | ||||
| 	if (err) | ||||
| 		printk(KERN_DEBUG "%s: writing memory failed\n", | ||||
| 		       wiphy_name(ar->hw->wiphy)); | ||||
| 		wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  | @ -67,8 +66,8 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) | |||
| 	err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), | ||||
| 			   (u8 *) buf, 0, NULL); | ||||
| 	if (err) | ||||
| 		printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), reg, val); | ||||
| 		wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", | ||||
| 			    reg, val); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -133,8 +133,8 @@ static int ar9170_register_led(struct ar9170 *ar, int i, char *name, | |||
| 	err = led_classdev_register(wiphy_dev(ar->hw->wiphy), | ||||
| 				    &ar->leds[i].l); | ||||
| 	if (err) | ||||
| 		printk(KERN_ERR "%s: failed to register %s LED (%d).\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), ar->leds[i].name, err); | ||||
| 		wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", | ||||
| 			  ar->leds[i].name, err); | ||||
| 	else | ||||
| 		ar->leds[i].registered = true; | ||||
| 
 | ||||
|  |  | |||
|  | @ -198,9 +198,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | |||
| 	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | ||||
| 	struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d " | ||||
| 	wiphy_debug(ar->hw->wiphy, | ||||
| 		    "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d " | ||||
| 		    "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", | ||||
| 	       wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | ||||
| 		    skb, skb_get_queue_mapping(skb), | ||||
| 		    ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), | ||||
| 		    le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), | ||||
| 		    jiffies_to_msecs(arinfo->timeout - jiffies)); | ||||
|  | @ -213,8 +214,8 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar, | |||
| 	int i = 0; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "---[ cut here ]---\n"); | ||||
| 	printk(KERN_DEBUG "%s: %d entries in queue.\n", | ||||
| 	       wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); | ||||
| 	wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n", | ||||
| 		    skb_queue_len(queue)); | ||||
| 
 | ||||
| 	skb_queue_walk(queue, skb) { | ||||
| 		printk(KERN_DEBUG "index:%d =>\n", i++); | ||||
|  | @ -244,13 +245,12 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) | |||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s: QoS queue stats\n", | ||||
| 	       wiphy_name(ar->hw->wiphy)); | ||||
| 	wiphy_debug(ar->hw->wiphy, "qos queue stats\n"); | ||||
| 
 | ||||
| 	for (i = 0; i < __AR9170_NUM_TXQ; i++) | ||||
| 		printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d " | ||||
| 		       " stopped:%d\n", wiphy_name(ar->hw->wiphy), i, | ||||
| 		       ar->tx_stats[i].limit, ar->tx_stats[i].len, | ||||
| 		wiphy_debug(ar->hw->wiphy, | ||||
| 			    "queue:%d limit:%d len:%d waitack:%d stopped:%d\n", | ||||
| 			    i, ar->tx_stats[i].limit, ar->tx_stats[i].len, | ||||
| 			    skb_queue_len(&ar->tx_status[i]), | ||||
| 			    ieee80211_queue_stopped(ar->hw, i)); | ||||
| } | ||||
|  | @ -274,8 +274,8 @@ static void ar9170_recycle_expired(struct ar9170 *ar, | |||
| 
 | ||||
| 		if (time_is_before_jiffies(arinfo->timeout)) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " | ||||
| 			       "recycle\n", wiphy_name(ar->hw->wiphy), | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "[%ld > %ld] frame expired => recycle\n", | ||||
| 				    jiffies, arinfo->timeout); | ||||
| 			ar9170_print_txheader(ar, skb); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
|  | @ -317,8 +317,8 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		printk(KERN_ERR "%s: invalid tx_status response (%x).\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), tx_status); | ||||
| 		wiphy_err(ar->hw->wiphy, | ||||
| 			  "invalid tx_status response (%x)\n", tx_status); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -339,8 +339,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
| 
 | ||||
| 	if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { | ||||
| #ifdef AR9170_QUEUE_STOP_DEBUG | ||||
| 		printk(KERN_DEBUG "%s: wake queue %d\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), queue); | ||||
| 		wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue); | ||||
| 		__ar9170_dump_txstats(ar); | ||||
| #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||||
| 		ieee80211_wake_queue(ar->hw, queue); | ||||
|  | @ -387,9 +386,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
| 
 | ||||
| 		if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), mac, | ||||
| 			       ieee80211_get_DA(hdr)); | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "skip frame => da %pm != %pm\n", | ||||
| 				    mac, ieee80211_get_DA(hdr)); | ||||
| 			ar9170_print_txheader(ar, skb); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 			continue; | ||||
|  | @ -400,8 +399,8 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
| 
 | ||||
| 		if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), rate, r); | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "skip frame => rate %d != %d\n", rate, r); | ||||
| 			ar9170_print_txheader(ar, skb); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 			continue; | ||||
|  | @ -413,9 +412,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
| 	} | ||||
| 
 | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 	printk(KERN_ERR "%s: ESS:[%pM] does not have any " | ||||
| 			"outstanding frames in queue.\n", | ||||
| 			wiphy_name(ar->hw->wiphy), mac); | ||||
| 	wiphy_err(ar->hw->wiphy, | ||||
| 		  "ESS:[%pM] does not have any outstanding frames in queue.\n", | ||||
| 		  mac); | ||||
| 	__ar9170_dump_txqueue(ar, queue); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 	spin_unlock_irqrestore(&queue->lock, flags); | ||||
|  | @ -444,8 +443,8 @@ static void ar9170_tx_janitor(struct work_struct *work) | |||
| 
 | ||||
| 	for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 		printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), i); | ||||
| 		wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n", | ||||
| 			    i); | ||||
| 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||||
| 		ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
|  | @ -495,8 +494,9 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
| 		u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> | ||||
| 			AR9170_TX_PHY_QOS_SHIFT; | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 		printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); | ||||
| 		wiphy_debug(ar->hw->wiphy, | ||||
| 			    "recv tx_status for %pm, p:%08x, q:%d\n", | ||||
| 			    cmd->tx_status.dst, phy, q); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 
 | ||||
| 		skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, | ||||
|  | @ -582,7 +582,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		printk(KERN_INFO "received unhandled event %x\n", cmd->type); | ||||
| 		pr_info("received unhandled event %x\n", cmd->type); | ||||
| 		print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); | ||||
| 		break; | ||||
| 	} | ||||
|  | @ -675,9 +675,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
| 		/* TODO: update netdevice's RX dropped/errors statistics */ | ||||
| 
 | ||||
| 		if (ar9170_nag_limiter(ar)) | ||||
| 			printk(KERN_DEBUG "%s: received frame with " | ||||
| 			       "suspicious error code (%#x).\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), error); | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "received frame with suspicious error code (%#x).\n", | ||||
| 				    error); | ||||
| 
 | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | @ -704,8 +704,8 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
| 			break; | ||||
| 		default: | ||||
| 			if (ar9170_nag_limiter(ar)) | ||||
| 				printk(KERN_ERR "%s: invalid plcp cck rate " | ||||
| 				       "(%x).\n", wiphy_name(ar->hw->wiphy), | ||||
| 				wiphy_err(ar->hw->wiphy, | ||||
| 					  "invalid plcp cck rate (%x).\n", | ||||
| 					  head->plcp[0]); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
|  | @ -740,8 +740,8 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
| 			break; | ||||
| 		default: | ||||
| 			if (ar9170_nag_limiter(ar)) | ||||
| 				printk(KERN_ERR "%s: invalid plcp ofdm rate " | ||||
| 				       "(%x).\n", wiphy_name(ar->hw->wiphy), | ||||
| 				wiphy_err(ar->hw->wiphy, | ||||
| 					  "invalid plcp ofdm rate (%x).\n", | ||||
| 					  head->plcp[0]); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
|  | @ -761,8 +761,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
| 
 | ||||
| 	default: | ||||
| 		if (ar9170_nag_limiter(ar)) | ||||
| 			printk(KERN_ERR "%s: invalid modulation\n", | ||||
| 			       wiphy_name(ar->hw->wiphy)); | ||||
| 			wiphy_err(ar->hw->wiphy, "invalid modulation\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -863,8 +862,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | |||
| 			ar->rx_mpdu.has_plcp = true; | ||||
| 		} else { | ||||
| 			if (ar9170_nag_limiter(ar)) | ||||
| 				printk(KERN_ERR "%s: plcp info is clipped.\n", | ||||
| 				       wiphy_name(ar->hw->wiphy)); | ||||
| 				wiphy_err(ar->hw->wiphy, | ||||
| 					  "plcp info is clipped.\n"); | ||||
| 			return ; | ||||
| 		} | ||||
| 		break; | ||||
|  | @ -877,8 +876,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | |||
| 			phy = (void *)(buf + mpdu_len); | ||||
| 		} else { | ||||
| 			if (ar9170_nag_limiter(ar)) | ||||
| 				printk(KERN_ERR "%s: frame tail is clipped.\n", | ||||
| 				       wiphy_name(ar->hw->wiphy)); | ||||
| 				wiphy_err(ar->hw->wiphy, | ||||
| 					  "frame tail is clipped.\n"); | ||||
| 			return ; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -888,9 +887,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | |||
| 			if (!ar9170_nag_limiter(ar)) | ||||
| 				return ; | ||||
| 
 | ||||
| 			printk(KERN_ERR "%s: rx stream did not start " | ||||
| 					"with a first_mpdu frame tag.\n", | ||||
| 			       wiphy_name(ar->hw->wiphy)); | ||||
| 			wiphy_err(ar->hw->wiphy, | ||||
| 				  "rx stream did not start with a first_mpdu frame tag.\n"); | ||||
| 
 | ||||
| 			return ; | ||||
| 		} | ||||
|  | @ -954,8 +952,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
| 			if (!ar->rx_failover_missing) { | ||||
| 				/* this is no "short read". */ | ||||
| 				if (ar9170_nag_limiter(ar)) { | ||||
| 					printk(KERN_ERR "%s: missing tag!\n", | ||||
| 					       wiphy_name(ar->hw->wiphy)); | ||||
| 					wiphy_err(ar->hw->wiphy, | ||||
| 						  "missing tag!\n"); | ||||
| 					goto err_telluser; | ||||
| 				} else | ||||
| 					goto err_silent; | ||||
|  | @ -963,9 +961,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
| 
 | ||||
| 			if (ar->rx_failover_missing > tlen) { | ||||
| 				if (ar9170_nag_limiter(ar)) { | ||||
| 					printk(KERN_ERR "%s: possible multi " | ||||
| 					       "stream corruption!\n", | ||||
| 					       wiphy_name(ar->hw->wiphy)); | ||||
| 					wiphy_err(ar->hw->wiphy, | ||||
| 						  "possible multi stream corruption!\n"); | ||||
| 					goto err_telluser; | ||||
| 				} else | ||||
| 					goto err_silent; | ||||
|  | @ -997,9 +994,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
| 			if (ar->rx_failover_missing) { | ||||
| 				/* TODO: handle double stream corruption. */ | ||||
| 				if (ar9170_nag_limiter(ar)) { | ||||
| 					printk(KERN_ERR "%s: double rx stream " | ||||
| 					       "corruption!\n", | ||||
| 						wiphy_name(ar->hw->wiphy)); | ||||
| 					wiphy_err(ar->hw->wiphy, | ||||
| 						  "double rx stream corruption!\n"); | ||||
| 					goto err_telluser; | ||||
| 				} else | ||||
| 					goto err_silent; | ||||
|  | @ -1042,9 +1038,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
| 
 | ||||
| 	if (tlen) { | ||||
| 		if (net_ratelimit()) | ||||
| 			printk(KERN_ERR "%s: %d bytes of unprocessed " | ||||
| 					"data left in rx stream!\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), tlen); | ||||
| 			wiphy_err(ar->hw->wiphy, | ||||
| 				  "%d bytes of unprocessed data left in rx stream!\n", | ||||
| 				  tlen); | ||||
| 
 | ||||
| 		goto err_telluser; | ||||
| 	} | ||||
|  | @ -1052,10 +1048,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
| 	return ; | ||||
| 
 | ||||
| err_telluser: | ||||
| 	printk(KERN_ERR "%s: damaged RX stream data [want:%d, " | ||||
| 			"data:%d, rx:%d, pending:%d ]\n", | ||||
| 	       wiphy_name(ar->hw->wiphy), clen, wlen, tlen, | ||||
| 	       ar->rx_failover_missing); | ||||
| 	wiphy_err(ar->hw->wiphy, | ||||
| 		  "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n", | ||||
| 		  clen, wlen, tlen, ar->rx_failover_missing); | ||||
| 
 | ||||
| 	if (ar->rx_failover_missing) | ||||
| 		print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, | ||||
|  | @ -1065,9 +1060,8 @@ err_telluser: | |||
| 	print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, | ||||
| 			     skb->data, skb->len); | ||||
| 
 | ||||
| 	printk(KERN_ERR "%s: please check your hardware and cables, if " | ||||
| 			"you see this message frequently.\n", | ||||
| 	       wiphy_name(ar->hw->wiphy)); | ||||
| 	wiphy_err(ar->hw->wiphy, | ||||
| 		  "If you see this message frequently, please check your hardware and cables.\n"); | ||||
| 
 | ||||
| err_silent: | ||||
| 	if (ar->rx_failover_missing) { | ||||
|  | @ -1384,10 +1378,10 @@ static void ar9170_tx(struct ar9170 *ar) | |||
| 
 | ||||
| 		if (remaining_space < frames) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "tx quota reached queue:%d, " | ||||
| 				    "remaining slots:%d, needed:%d\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), i, remaining_space, | ||||
| 			       frames); | ||||
| 				    i, remaining_space, frames); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 			frames = remaining_space; | ||||
| 		} | ||||
|  | @ -1396,18 +1390,14 @@ static void ar9170_tx(struct ar9170 *ar) | |||
| 		ar->tx_stats[i].count += frames; | ||||
| 		if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: queue %d full\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), i); | ||||
| 
 | ||||
| 			printk(KERN_DEBUG "%s: stuck frames: ===>\n", | ||||
| 			       wiphy_name(ar->hw->wiphy)); | ||||
| 			wiphy_debug(ar->hw->wiphy, "queue %d full\n", i); | ||||
| 			wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n"); | ||||
| 			ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||||
| 			ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 
 | ||||
| #ifdef AR9170_QUEUE_STOP_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: stop queue %d\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), i); | ||||
| 			wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i); | ||||
| 			__ar9170_dump_txstats(ar); | ||||
| #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||||
| 			ieee80211_stop_queue(ar->hw, i); | ||||
|  | @ -1435,8 +1425,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
| 					  msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||||
| 
 | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: send frame q:%d =>\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), i); | ||||
| 			wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i); | ||||
| 			ar9170_print_txheader(ar, skb); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 
 | ||||
|  | @ -1453,26 +1442,25 @@ static void ar9170_tx(struct ar9170 *ar) | |||
| 		} | ||||
| 
 | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 		printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", | ||||
| 		       wiphy_name(ar->hw->wiphy), i); | ||||
| 		wiphy_debug(ar->hw->wiphy, | ||||
| 			    "ar9170_tx report for queue %d\n", i); | ||||
| 
 | ||||
| 		printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", | ||||
| 		       wiphy_name(ar->hw->wiphy)); | ||||
| 		wiphy_debug(ar->hw->wiphy, | ||||
| 			    "unprocessed pending frames left:\n"); | ||||
| 		ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 
 | ||||
| 		if (unlikely(frames_failed)) { | ||||
| #ifdef AR9170_QUEUE_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: frames failed %d =>\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), frames_failed); | ||||
| 			wiphy_debug(ar->hw->wiphy, | ||||
| 				    "frames failed %d =>\n", frames_failed); | ||||
| #endif /* AR9170_QUEUE_DEBUG */ | ||||
| 
 | ||||
| 			spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||||
| 			ar->tx_stats[i].len -= frames_failed; | ||||
| 			ar->tx_stats[i].count -= frames_failed; | ||||
| #ifdef AR9170_QUEUE_STOP_DEBUG | ||||
| 			printk(KERN_DEBUG "%s: wake queue %d\n", | ||||
| 			       wiphy_name(ar->hw->wiphy), i); | ||||
| 			wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i); | ||||
| 			__ar9170_dump_txstats(ar); | ||||
| #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||||
| 			ieee80211_wake_queue(ar->hw, i); | ||||
|  | @ -1917,6 +1905,24 @@ static int ar9170_get_stats(struct ieee80211_hw *hw, | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ar9170_get_survey(struct ieee80211_hw *hw, int idx, | ||||
| 				struct survey_info *survey) | ||||
| { | ||||
| 	struct ar9170 *ar = hw->priv; | ||||
| 	struct ieee80211_conf *conf = &hw->conf; | ||||
| 
 | ||||
| 	if (idx != 0) | ||||
| 		return -ENOENT; | ||||
| 
 | ||||
| 	/* TODO: update noise value, e.g. call ar9170_set_channel */ | ||||
| 
 | ||||
| 	survey->channel = conf->channel; | ||||
| 	survey->filled = SURVEY_INFO_NOISE_DBM; | ||||
| 	survey->noise = ar->noise[0]; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||||
| 			  const struct ieee80211_tx_queue_params *param) | ||||
| { | ||||
|  | @ -1969,6 +1975,7 @@ static const struct ieee80211_ops ar9170_ops = { | |||
| 	.get_tsf		= ar9170_op_get_tsf, | ||||
| 	.set_key		= ar9170_set_key, | ||||
| 	.get_stats		= ar9170_get_stats, | ||||
| 	.get_survey		= ar9170_get_survey, | ||||
| 	.ampdu_action		= ar9170_ampdu_action, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -670,8 +670,7 @@ static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) | |||
| 	ar9170_regwrite_finish(); | ||||
| 	err = ar9170_regwrite_result(); | ||||
| 	if (err) | ||||
| 		printk(KERN_ERR "%s: rf init failed\n", | ||||
| 		       wiphy_name(ar->hw->wiphy)); | ||||
| 		wiphy_err(ar->hw->wiphy, "rf init failed\n"); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  | @ -1702,9 +1701,8 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | |||
| 				       0x200 | ar->phy_heavy_clip); | ||||
| 		if (err) { | ||||
| 			if (ar9170_nag_limiter(ar)) | ||||
| 				printk(KERN_ERR "%s: failed to set " | ||||
| 				       "heavy clip\n", | ||||
| 				       wiphy_name(ar->hw->wiphy)); | ||||
| 				wiphy_err(ar->hw->wiphy, | ||||
| 					  "failed to set heavy clip\n"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -239,6 +239,9 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, | |||
| 		"TSF\t\t0x%016llx\tTU: %08x\n", | ||||
| 		(unsigned long long)tsf, TSF_TO_TU(tsf)); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -334,6 +337,9 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, | |||
| 		sc->debug.level == dbg_info[i].level ? '+' : ' ', | ||||
| 		dbg_info[i].level, dbg_info[i].desc); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -433,6 +439,9 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf, | |||
| 	len += snprintf(buf+len, sizeof(buf)-len, | ||||
| 			"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -542,6 +551,9 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, | |||
| 	len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", | ||||
| 			st->tx_all_count); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -681,6 +693,9 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, | |||
| 			ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - | ||||
| 			ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2))); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -766,6 +781,9 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, | |||
| 		len += snprintf(buf+len, sizeof(buf)-len, "  len: %d\n", n); | ||||
| 	} | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -131,11 +131,8 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
| 
 | ||||
| 	ah = sc->sc_ah; | ||||
| 	ath9k_hw_name(ah, hw_name, sizeof(hw_name)); | ||||
| 	printk(KERN_INFO | ||||
| 	       "%s: %s mem=0x%lx, irq=%d\n", | ||||
| 	       wiphy_name(hw->wiphy), | ||||
| 	       hw_name, | ||||
| 	       (unsigned long)mem, irq); | ||||
| 	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | ||||
| 		   hw_name, (unsigned long)mem, irq); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1506,6 +1506,9 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah, | |||
| 	nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); | ||||
| 	nfarray[2] = sign_extend(nf, 9); | ||||
| 
 | ||||
| 	if (!IS_CHAN_HT40(ah->curchan)) | ||||
| 		return; | ||||
| 
 | ||||
| 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | ||||
| 	nfarray[3] = sign_extend(nf, 9); | ||||
| 
 | ||||
|  |  | |||
|  | @ -477,6 +477,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, | |||
| 	nfarray[0] = sign_extend(nf, 9); | ||||
| 
 | ||||
| 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); | ||||
| 	if (IS_CHAN_HT40(ah->curchan)) | ||||
| 		nfarray[3] = sign_extend(nf, 9); | ||||
| 
 | ||||
| 	if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||||
|  | @ -486,6 +487,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, | |||
| 	nfarray[1] = sign_extend(nf, 9); | ||||
| 
 | ||||
| 	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); | ||||
| 	if (IS_CHAN_HT40(ah->curchan)) | ||||
| 		nfarray[4] = sign_extend(nf, 9); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1029,6 +1029,9 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah, | |||
| 	nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); | ||||
| 	nfarray[2] = sign_extend(nf, 9); | ||||
| 
 | ||||
| 	if (!IS_CHAN_HT40(ah->curchan)) | ||||
| 		return; | ||||
| 
 | ||||
| 	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | ||||
| 	nfarray[3] = sign_extend(nf, 9); | ||||
| 
 | ||||
|  |  | |||
|  | @ -687,7 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc); | |||
| void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); | ||||
| 
 | ||||
| void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); | ||||
| void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | ||||
| bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | ||||
| 
 | ||||
| void ath_start_rfkill_poll(struct ath_softc *sc); | ||||
| extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); | ||||
|  |  | |||
|  | @ -172,26 +172,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
| 	struct ath9k_nfcal_hist *h; | ||||
| 	unsigned i, j; | ||||
| 	int32_t val; | ||||
| 	u8 chainmask; | ||||
| 	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 
 | ||||
| 	if (AR_SREV_9300_20_OR_LATER(ah)) | ||||
| 		chainmask = 0x3F; | ||||
| 	else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||||
| 		chainmask = 0x9; | ||||
| 	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { | ||||
| 		if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4)) | ||||
| 			chainmask = 0x1B; | ||||
| 		else | ||||
| 			chainmask = 0x09; | ||||
| 	} else { | ||||
| 		if (ah->rxchainmask & 0x4) | ||||
| 			chainmask = 0x3F; | ||||
| 		else if (ah->rxchainmask & 0x2) | ||||
| 			chainmask = 0x1B; | ||||
| 		else | ||||
| 			chainmask = 0x09; | ||||
| 	} | ||||
| 	h = ah->nfCalHist; | ||||
| 
 | ||||
| 	for (i = 0; i < NUM_NF_READINGS; i++) { | ||||
|  | @ -278,7 +261,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) | |||
| 
 | ||||
| 		ath_print(common, ATH_DBG_CALIBRATE, | ||||
| 			  "NF calibrated [%s] [chain %d] is %d\n", | ||||
| 			  (i > 3 ? "ext" : "ctl"), i % 3, nf[i]); | ||||
| 			  (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); | ||||
| 
 | ||||
| 		if (nf[i] > limit->max) { | ||||
| 			ath_print(common, ATH_DBG_CALIBRATE, | ||||
|  |  | |||
|  | @ -524,6 +524,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | |||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 			"%19s : %10u\n", "TX Rate", priv->debug.txrate); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -569,6 +572,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
| 			"%20s : %10u\n", "VO queued", | ||||
| 			priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  | @ -595,6 +601,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
| 			"%20s : %10u\n", "SKBs Dropped", | ||||
| 			priv->debug.rx_stats.skb_dropped); | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
| 	return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -532,7 +532,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
| 
 | ||||
| 	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { | ||||
| 		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || | ||||
| 		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) { | ||||
| 		    ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && | ||||
| 		     !ah->is_pciexpress)) { | ||||
| 			ah->config.serialize_regmode = | ||||
| 				SER_REG_MODE_ON; | ||||
| 		} else { | ||||
|  |  | |||
|  | @ -1994,11 +1994,12 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
| 
 | ||||
| 	mutex_lock(&sc->mutex); | ||||
| 	if (ath9k_wiphy_scanning(sc)) { | ||||
| 		printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the " | ||||
| 		       "same time\n"); | ||||
| 		/*
 | ||||
| 		 * Do not allow the concurrent scanning state for now. This | ||||
| 		 * could be improved with scanning control moved into ath9k. | ||||
| 		 * There is a race here in mac80211 but fixing it requires | ||||
| 		 * we revisit how we handle the scan complete callback. | ||||
| 		 * After mac80211 fixes we will not have configured hardware | ||||
| 		 * to the home channel nor would we have configured the RX | ||||
| 		 * filter yet. | ||||
| 		 */ | ||||
| 		mutex_unlock(&sc->mutex); | ||||
| 		return; | ||||
|  | @ -2014,6 +2015,10 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
| 	mutex_unlock(&sc->mutex); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * XXX: this requires a revisit after the driver | ||||
|  * scan_complete gets moved to another place/removed in mac80211. | ||||
|  */ | ||||
| static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | ||||
| { | ||||
| 	struct ath_wiphy *aphy = hw->priv; | ||||
|  |  | |||
|  | @ -209,11 +209,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 	} | ||||
| 
 | ||||
| 	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); | ||||
| 	printk(KERN_INFO | ||||
| 	       "%s: %s mem=0x%lx, irq=%d\n", | ||||
| 	       wiphy_name(hw->wiphy), | ||||
| 	       hw_name, | ||||
| 	       (unsigned long)mem, pdev->irq); | ||||
| 	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | ||||
| 		   hw_name, (unsigned long)mem, pdev->irq); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,95 +20,145 @@ | |||
| #include "ath9k.h" | ||||
| 
 | ||||
| static const struct ath_rate_table ar5416_11na_ratetable = { | ||||
| 	43, | ||||
| 	68, | ||||
| 	8, /* MCS start */ | ||||
| 	{ | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 0, 12, 0, 0, 0, 0, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800,  1, 18, 0, 1, 1, 1, 1 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10000, 2, 24, 2, 2, 2, 2, 2 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			13900, 3, 36, 2, 3, 3, 3, 3 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17300, 4, 48, 4, 4, 4, 4, 4 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23000, 5, 72, 4, 5, 5, 5, 5 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 6, 96, 4, 6, 6, 6, 6 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			29300, 7, 108, 4, 7, 7, 7, 7 }, | ||||
| 		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ | ||||
| 			6400, 0, 0, 0, 8, 25, 8, 25 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ | ||||
| 			12700, 1, 1, 2, 9, 26, 9, 26 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ | ||||
| 			18800, 2, 2, 2, 10, 27, 10, 27 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ | ||||
| 			25000, 3, 3, 4, 11, 28, 11, 28 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ | ||||
| 			36700, 4, 4, 4, 12, 29, 12, 29 }, | ||||
| 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ | ||||
| 			48100, 5, 5, 4, 13, 30, 13, 30 }, | ||||
| 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ | ||||
| 			53500, 6, 6, 4, 14, 31, 14, 31 }, | ||||
| 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ | ||||
| 			59000, 7, 7, 4, 15, 32, 15, 33 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ | ||||
| 			12700, 8, 8, 3, 16, 34, 16, 34 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ | ||||
| 			24800, 9, 9, 2, 17, 35, 17, 35 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ | ||||
| 			36600, 10, 10, 2, 18, 36, 18, 36 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ | ||||
| 			48100, 11, 11, 4, 19, 37, 19, 37 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ | ||||
| 			69500, 12, 12, 4, 20, 38, 20, 38 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ | ||||
| 			89500, 13, 13, 4, 21, 39, 21, 39 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ | ||||
| 			98900, 14, 14, 4, 22, 40, 22, 40 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ | ||||
| 			108300, 15, 15, 4, 23, 41, 24, 42 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */ | ||||
| 			12000, 15, 15, 4, 23, 41, 24, 42 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ | ||||
| 			13200, 0, 0, 0, 8, 25, 25, 25 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ | ||||
| 			25900, 1, 1, 2, 9, 26, 26, 26 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ | ||||
| 			38600, 2, 2, 2, 10, 27, 27, 27 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ | ||||
| 			49800, 3, 3, 4, 11, 28, 28, 28 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ | ||||
| 			72200, 4, 4, 4, 12, 29, 29, 29 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ | ||||
| 			92900, 5, 5, 4, 13, 30, 30, 30 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ | ||||
| 			102700, 6, 6, 4, 14, 31, 31, 31 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ | ||||
| 			112000, 7, 7, 4, 15, 32, 33, 33 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ | ||||
| 			122000, 7, 7, 4, 15, 32, 33, 33 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ | ||||
| 			25800, 8, 8, 0, 16, 34, 34, 34 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ | ||||
| 			49800, 9, 9, 2, 17, 35, 35, 35 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ | ||||
| 			71900, 10, 10, 2, 18, 36, 36, 36 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ | ||||
| 			92500, 11, 11, 4, 19, 37, 37, 37 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ | ||||
| 			130300, 12, 12, 4, 20, 38, 38, 38 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ | ||||
| 			162800, 13, 13, 4, 21, 39, 39, 39 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ | ||||
| 			178200, 14, 14, 4, 22, 40, 40, 40 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ | ||||
| 			192100, 15, 15, 4, 23, 41, 42, 42 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ | ||||
| 			207000, 15, 15, 4, 23, 41, 42, 42 }, | ||||
| 		[0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, | ||||
| 			5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */ | ||||
| 		[1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, | ||||
| 			7800,  1, 18, 0, 1, 1, 1 }, /* 9 Mb */ | ||||
| 		[2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, | ||||
| 			10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */ | ||||
| 		[3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, | ||||
| 			13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */ | ||||
| 		[4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, | ||||
| 			17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */ | ||||
| 		[5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, | ||||
| 			23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */ | ||||
| 		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, | ||||
| 			27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */ | ||||
| 		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, | ||||
| 			29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */ | ||||
| 		[8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500, | ||||
| 			6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */ | ||||
| 		[9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, | ||||
| 			12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */ | ||||
| 		[10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, | ||||
| 			18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */ | ||||
| 		[11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, | ||||
| 			25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */ | ||||
| 		[12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, | ||||
| 			36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */ | ||||
| 		[13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, | ||||
| 			48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */ | ||||
| 		[14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, | ||||
| 			53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */ | ||||
| 		[15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, | ||||
| 			59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */ | ||||
| 		[16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, | ||||
| 			65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */ | ||||
| 		[17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, | ||||
| 			12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */ | ||||
| 		[18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, | ||||
| 			24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */ | ||||
| 		[19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, | ||||
| 			36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */ | ||||
| 		[20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, | ||||
| 			48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */ | ||||
| 		[21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, | ||||
| 			69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */ | ||||
| 		[22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, | ||||
| 			89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */ | ||||
| 		[23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, | ||||
| 			98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */ | ||||
| 		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, | ||||
| 			108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */ | ||||
| 		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, | ||||
| 			120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */ | ||||
| 		[26] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, | ||||
| 			17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */ | ||||
| 		[27] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, | ||||
| 			35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */ | ||||
| 		[28] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, | ||||
| 			52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */ | ||||
| 		[29] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, | ||||
| 			70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */ | ||||
| 		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, | ||||
| 			104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */ | ||||
| 		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, | ||||
| 			115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/ | ||||
| 		[32] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, | ||||
| 			137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */ | ||||
| 		[33] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, | ||||
| 			151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */ | ||||
| 		[34] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, | ||||
| 			152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */ | ||||
| 		[35] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, | ||||
| 			168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/ | ||||
| 		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, | ||||
| 			168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */ | ||||
| 		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, | ||||
| 			185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */ | ||||
| 		[38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, | ||||
| 			13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/ | ||||
| 		[39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, | ||||
| 			25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/ | ||||
| 		[40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, | ||||
| 			38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/ | ||||
| 		[41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, | ||||
| 			49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */ | ||||
| 		[42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, | ||||
| 			72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */ | ||||
| 		[43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, | ||||
| 			92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */ | ||||
| 		[44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, | ||||
| 			102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/ | ||||
| 		[45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, | ||||
| 			112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */ | ||||
| 		[46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, | ||||
| 			122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */ | ||||
| 		[47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, | ||||
| 			25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */ | ||||
| 		[48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, | ||||
| 			49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */ | ||||
| 		[49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, | ||||
| 			71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */ | ||||
| 		[50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, | ||||
| 			92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */ | ||||
| 		[51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, | ||||
| 			130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */ | ||||
| 		[52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, | ||||
| 			162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */ | ||||
| 		[53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, | ||||
| 			178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */ | ||||
| 		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, | ||||
| 			192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */ | ||||
| 		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, | ||||
| 			207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */ | ||||
| 		[56] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, | ||||
| 			36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */ | ||||
| 		[57] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, | ||||
| 			72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */ | ||||
| 		[58] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, | ||||
| 			108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */ | ||||
| 		[59] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, | ||||
| 			142000, 19, 19, 4, 59, 59, 59 }, /*  162 Mb */ | ||||
| 		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, | ||||
| 			205100, 20, 20, 4, 60, 61, 61 }, /*  243 Mb */ | ||||
| 		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, | ||||
| 			224700, 20, 20, 4, 60, 61, 61 }, /*  270 Mb */ | ||||
| 		[62] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, | ||||
| 			263100, 21, 21, 4, 62, 63, 63 }, /*  324 Mb */ | ||||
| 		[63] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, | ||||
| 			288000, 21, 21, 4, 62, 63, 63 }, /*  360 Mb */ | ||||
| 		[64] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, | ||||
| 			290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */ | ||||
| 		[65] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, | ||||
| 			317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */ | ||||
| 		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, | ||||
| 			317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */ | ||||
| 		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, | ||||
| 			346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */ | ||||
| 	}, | ||||
| 	50,  /* probe interval */ | ||||
| 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */ | ||||
|  | @ -118,103 +168,153 @@ static const struct ath_rate_table ar5416_11na_ratetable = { | |||
|  * for HT are the 64K max aggregate limit */ | ||||
| 
 | ||||
| static const struct ath_rate_table ar5416_11ng_ratetable = { | ||||
| 	47, | ||||
| 	72, | ||||
| 	12, /* MCS start */ | ||||
| 	{ | ||||
| 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||||
| 			900, 0, 2, 0, 0, 0, 0, 0 }, | ||||
| 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||||
| 			1900, 1, 4, 1, 1, 1, 1, 1 }, | ||||
| 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||||
| 			4900, 2, 11, 2, 2, 2, 2, 2 }, | ||||
| 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||||
| 			8100, 3, 22, 3, 3, 3, 3, 3 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 4, 12, 4, 4, 4, 4, 4 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800, 5, 18, 4, 5, 5, 5, 5 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10100, 6, 24, 6, 6, 6, 6, 6 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			14100, 7, 36, 6, 7, 7, 7, 7 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17700, 8, 48, 8, 8, 8, 8, 8 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23700, 9, 72, 8, 9, 9, 9, 9 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 10, 96, 8, 10, 10, 10, 10 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			30900, 11, 108, 8, 11, 11, 11, 11 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ | ||||
| 			6400, 0, 0, 4, 12, 29, 12, 29 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ | ||||
| 			12700, 1, 1, 6, 13, 30, 13, 30 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ | ||||
| 			18800, 2, 2, 6, 14, 31, 14, 31 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ | ||||
| 			25000, 3, 3, 8, 15, 32, 15, 32 }, | ||||
| 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ | ||||
| 			36700, 4, 4, 8, 16, 33, 16, 33 }, | ||||
| 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ | ||||
| 			48100, 5, 5, 8, 17, 34, 17, 34 }, | ||||
| 		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ | ||||
| 			53500, 6, 6, 8, 18, 35, 18, 35 }, | ||||
| 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ | ||||
| 			59000, 7, 7, 8, 19, 36, 19, 37 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ | ||||
| 			12700, 8, 8, 4, 20, 38, 20, 38 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ | ||||
| 			24800, 9, 9, 6, 21, 39, 21, 39 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ | ||||
| 			36600, 10, 10, 6, 22, 40, 22, 40 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ | ||||
| 			48100, 11, 11, 8, 23, 41, 23, 41 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ | ||||
| 			69500, 12, 12, 8, 24, 42, 24, 42 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ | ||||
| 			89500, 13, 13, 8, 25, 43, 25, 43 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ | ||||
| 			98900, 14, 14, 8, 26, 44, 26, 44 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ | ||||
| 			108300, 15, 15, 8, 27, 45, 28, 46 }, | ||||
| 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */ | ||||
| 			120000, 15, 15, 8, 27, 45, 28, 46 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ | ||||
| 			13200, 0, 0, 8, 12, 29, 29, 29 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ | ||||
| 			25900, 1, 1, 8, 13, 30, 30, 30 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ | ||||
| 			38600, 2, 2, 8, 14, 31, 31, 31 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ | ||||
| 			49800, 3, 3, 8,  15, 32, 32, 32 }, | ||||
| 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ | ||||
| 			72200, 4, 4, 8, 16, 33, 33, 33 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ | ||||
| 			92900, 5, 5, 8, 17, 34, 34, 34 }, | ||||
| 		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ | ||||
| 			102700, 6, 6, 8, 18, 35, 35, 35 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ | ||||
| 			112000, 7, 7, 8, 19, 36, 37, 37 }, | ||||
| 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ | ||||
| 			122000, 7, 7, 8, 19, 36, 37, 37 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ | ||||
| 			25800, 8, 8, 8, 20, 38, 38, 38 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ | ||||
| 			49800, 9, 9, 8, 21, 39, 39, 39 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ | ||||
| 			71900, 10, 10, 8, 22, 40, 40, 40 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ | ||||
| 			92500, 11, 11, 8, 23, 41, 41, 41 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ | ||||
| 			130300, 12, 12, 8, 24, 42, 42, 42 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ | ||||
| 			162800, 13, 13, 8, 25, 43, 43, 43 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ | ||||
| 			178200, 14, 14, 8, 26, 44, 44, 44 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ | ||||
| 			192100, 15, 15, 8, 27, 45, 46, 46 }, | ||||
| 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ | ||||
| 			207000, 15, 15, 8, 27, 45, 46, 46 }, | ||||
| 		[0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000, | ||||
| 			900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */ | ||||
| 		[1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000, | ||||
| 			1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */ | ||||
| 		[2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500, | ||||
| 			4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */ | ||||
| 		[3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000, | ||||
| 			8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */ | ||||
| 		[4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, | ||||
| 			5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */ | ||||
| 		[5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, | ||||
| 			7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */ | ||||
| 		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, | ||||
| 			10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */ | ||||
| 		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, | ||||
| 			14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */ | ||||
| 		[8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, | ||||
| 			17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */ | ||||
| 		[9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, | ||||
| 			23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */ | ||||
| 		[10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, | ||||
| 			27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */ | ||||
| 		[11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, | ||||
| 			30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */ | ||||
| 		[12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, | ||||
| 			6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */ | ||||
| 		[13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, | ||||
| 			12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */ | ||||
| 		[14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, | ||||
| 			18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/ | ||||
| 		[15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, | ||||
| 			25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */ | ||||
| 		[16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, | ||||
| 			36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */ | ||||
| 		[17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, | ||||
| 			48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */ | ||||
| 		[18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, | ||||
| 			53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */ | ||||
| 		[19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, | ||||
| 			59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */ | ||||
| 		[20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, | ||||
| 			65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/ | ||||
| 		[21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, | ||||
| 			12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */ | ||||
| 		[22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, | ||||
| 			24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */ | ||||
| 		[23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, | ||||
| 			36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */ | ||||
| 		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, | ||||
| 			48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */ | ||||
| 		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, | ||||
| 			69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */ | ||||
| 		[26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, | ||||
| 			89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */ | ||||
| 		[27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, | ||||
| 			98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */ | ||||
| 		[28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, | ||||
| 			108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */ | ||||
| 		[29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, | ||||
| 			120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */ | ||||
| 		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, | ||||
| 			17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */ | ||||
| 		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, | ||||
| 			35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */ | ||||
| 		[32] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, | ||||
| 			52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */ | ||||
| 		[33] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, | ||||
| 			70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */ | ||||
| 		[34] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, | ||||
| 			104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */ | ||||
| 		[35] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, | ||||
| 			115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */ | ||||
| 		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, | ||||
| 			137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */ | ||||
| 		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, | ||||
| 			151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */ | ||||
| 		[38] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, | ||||
| 			152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */ | ||||
| 		[39] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, | ||||
| 			168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */ | ||||
| 		[40] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, | ||||
| 			168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */ | ||||
| 		[41] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, | ||||
| 			185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */ | ||||
| 		[42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, | ||||
| 			13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */ | ||||
| 		[43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, | ||||
| 			25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */ | ||||
| 		[44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, | ||||
| 			38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */ | ||||
| 		[45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, | ||||
| 			49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */ | ||||
| 		[46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, | ||||
| 			72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */ | ||||
| 		[47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, | ||||
| 			92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */ | ||||
| 		[48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, | ||||
| 			102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */ | ||||
| 		[49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, | ||||
| 			112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */ | ||||
| 		[50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, | ||||
| 			122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */ | ||||
| 		[51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, | ||||
| 			25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */ | ||||
| 		[52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, | ||||
| 			49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */ | ||||
| 		[53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, | ||||
| 			71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */ | ||||
| 		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, | ||||
| 			92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */ | ||||
| 		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, | ||||
| 			130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */ | ||||
| 		[56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, | ||||
| 			162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */ | ||||
| 		[57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, | ||||
| 			178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */ | ||||
| 		[58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, | ||||
| 			192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */ | ||||
| 		[59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, | ||||
| 			207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */ | ||||
| 		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, | ||||
| 			36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */ | ||||
| 		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, | ||||
| 			72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */ | ||||
| 		[62] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, | ||||
| 			108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */ | ||||
| 		[63] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, | ||||
| 			142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */ | ||||
| 		[64] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, | ||||
| 			205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ | ||||
| 		[65] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, | ||||
| 			224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ | ||||
| 		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, | ||||
| 			263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ | ||||
| 		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, | ||||
| 			288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */ | ||||
| 		[68] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, | ||||
| 			290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */ | ||||
| 		[69] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, | ||||
| 			317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */ | ||||
| 		[70] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, | ||||
| 			317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */ | ||||
| 		[71] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, | ||||
| 			346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */ | ||||
| 	}, | ||||
| 	50,  /* probe interval */ | ||||
| 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */ | ||||
|  | @ -224,22 +324,22 @@ static const struct ath_rate_table ar5416_11a_ratetable = { | |||
| 	8, | ||||
| 	0, | ||||
| 	{ | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 0, 12, 0, 0, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800,  1, 18, 0, 1, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10000, 2, 24, 2, 2, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			13900, 3, 36, 2, 3, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17300, 4, 48, 4, 4, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23000, 5, 72, 4, 5, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 6, 96, 4, 6, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			29300, 7, 108, 4, 7, 0 }, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 0, 12, 0}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800,  1, 18, 0}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10000, 2, 24, 2}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			13900, 3, 36, 2}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17300, 4, 48, 4}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23000, 5, 72, 4}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 6, 96, 4}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			29300, 7, 108, 4}, | ||||
| 	}, | ||||
| 	50,  /* probe interval */ | ||||
| 	0,   /* Phy rates allowed initially */ | ||||
|  | @ -249,30 +349,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = { | |||
| 	12, | ||||
| 	0, | ||||
| 	{ | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||||
| 			900, 0, 2, 0, 0, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||||
| 			1900, 1, 4, 1, 1, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||||
| 			4900, 2, 11, 2, 2, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||||
| 			8100, 3, 22, 3, 3, 0 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 4, 12, 4, 4, 0 }, | ||||
| 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800, 5, 18, 4, 5, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10000, 6, 24, 6, 6, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			13900, 7, 36, 6, 7, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17300, 8, 48, 8, 8, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23000, 9, 72, 8, 9, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 10, 96, 8, 10, 0 }, | ||||
| 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			29300, 11, 108, 8, 11, 0 }, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||||
| 			900, 0, 2, 0}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||||
| 			1900, 1, 4, 1}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||||
| 			4900, 2, 11, 2}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||||
| 			8100, 3, 22, 3}, | ||||
| 		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||||
| 			5400, 4, 12, 4}, | ||||
| 		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||||
| 			7800, 5, 18, 4}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||||
| 			10000, 6, 24, 6}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||||
| 			13900, 7, 36, 6}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||||
| 			17300, 8, 48, 8}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||||
| 			23000, 9, 72, 8}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||||
| 			27400, 10, 96, 8}, | ||||
| 		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||||
| 			29300, 11, 108, 8}, | ||||
| 	}, | ||||
| 	50,  /* probe interval */ | ||||
| 	0,   /* Phy rates allowed initially */ | ||||
|  | @ -342,7 +442,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, | |||
| 					   u8 index, int valid_tx_rate) | ||||
| { | ||||
| 	BUG_ON(index > ath_rc_priv->rate_table_size); | ||||
| 	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; | ||||
| 	ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate; | ||||
| } | ||||
| 
 | ||||
| static inline | ||||
|  | @ -374,6 +474,8 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) | |||
| 		return 0; | ||||
| 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) | ||||
| 		return 0; | ||||
| 	if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG)) | ||||
| 		return 0; | ||||
| 	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) | ||||
| 		return 0; | ||||
| 	if (!ignore_cw && WLAN_RC_PHY_HT(phy)) | ||||
|  | @ -404,13 +506,9 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, | |||
| 				 u32 capflag) | ||||
| { | ||||
| 	u8 i, hi = 0; | ||||
| 	u32 valid; | ||||
| 
 | ||||
| 	for (i = 0; i < rate_table->rate_cnt; i++) { | ||||
| 		valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||||
| 			 rate_table->info[i].valid_single_stream : | ||||
| 			 rate_table->info[i].valid); | ||||
| 		if (valid == 1) { | ||||
| 		if (rate_table->info[i].rate_flags & RC_LEGACY) { | ||||
| 			u32 phy = rate_table->info[i].phy; | ||||
| 			u8 valid_rate_count = 0; | ||||
| 
 | ||||
|  | @ -422,7 +520,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, | |||
| 			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; | ||||
| 			ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||||
| 			ath_rc_set_valid_txmask(ath_rc_priv, i, 1); | ||||
| 			hi = A_MAX(hi, i); | ||||
| 			hi = i; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -440,9 +538,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, | |||
| 	for (i = 0; i < rateset->rs_nrates; i++) { | ||||
| 		for (j = 0; j < rate_table->rate_cnt; j++) { | ||||
| 			u32 phy = rate_table->info[j].phy; | ||||
| 			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||||
| 				     rate_table->info[j].valid_single_stream : | ||||
| 				     rate_table->info[j].valid); | ||||
| 			u16 rate_flags = rate_table->info[i].rate_flags; | ||||
| 			u8 rate = rateset->rs_rates[i]; | ||||
| 			u8 dot11rate = rate_table->info[j].dot11rate; | ||||
| 
 | ||||
|  | @ -451,8 +547,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, | |||
| 			 * (VALID/VALID_20/VALID_40) flags */ | ||||
| 
 | ||||
| 			if ((rate == dot11rate) && | ||||
| 			    ((valid & WLAN_RC_CAP_MODE(capflag)) == | ||||
| 			     WLAN_RC_CAP_MODE(capflag)) && | ||||
| 			    (rate_flags & WLAN_RC_CAP_MODE(capflag)) == | ||||
| 			    WLAN_RC_CAP_MODE(capflag) && | ||||
| 			    (rate_flags & WLAN_RC_CAP_STREAM(capflag)) && | ||||
| 			    !WLAN_RC_PHY_HT(phy)) { | ||||
| 				u8 valid_rate_count = 0; | ||||
| 
 | ||||
|  | @ -486,14 +583,13 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, | |||
| 	for (i = 0; i < rateset->rs_nrates; i++) { | ||||
| 		for (j = 0; j < rate_table->rate_cnt; j++) { | ||||
| 			u32 phy = rate_table->info[j].phy; | ||||
| 			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||||
| 				     rate_table->info[j].valid_single_stream : | ||||
| 				     rate_table->info[j].valid); | ||||
| 			u16 rate_flags = rate_table->info[j].rate_flags; | ||||
| 			u8 rate = rateset->rs_rates[i]; | ||||
| 			u8 dot11rate = rate_table->info[j].dot11rate; | ||||
| 
 | ||||
| 			if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) || | ||||
| 			    !WLAN_RC_PHY_HT_VALID(valid, capflag)) | ||||
| 			    !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) || | ||||
| 			    !WLAN_RC_PHY_HT_VALID(rate_flags, capflag)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (!ath_rc_valid_phyrate(phy, capflag, 0)) | ||||
|  | @ -589,12 +685,15 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, | |||
| 	if (rate > (ath_rc_priv->rate_table_size - 1)) | ||||
| 		rate = ath_rc_priv->rate_table_size - 1; | ||||
| 
 | ||||
| 	if (rate_table->info[rate].valid && | ||||
| 	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) | ||||
| 	if (RC_TS_ONLY(rate_table->info[rate].rate_flags) && | ||||
| 	    (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG)) | ||||
| 		return rate; | ||||
| 
 | ||||
| 	if (rate_table->info[rate].valid_single_stream && | ||||
| 	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) | ||||
| 	if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) && | ||||
| 	    (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG))) | ||||
| 		return rate; | ||||
| 
 | ||||
| 	if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags)) | ||||
| 		return rate; | ||||
| 
 | ||||
| 	/* This should not happen */ | ||||
|  | @ -1007,12 +1106,19 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
| static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | ||||
| 				struct ieee80211_tx_rate *rate) | ||||
| { | ||||
| 	int rix; | ||||
| 	int rix = 0, i = 0; | ||||
| 	int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; | ||||
| 
 | ||||
| 	if (!(rate->flags & IEEE80211_TX_RC_MCS)) | ||||
| 		return rate->idx; | ||||
| 
 | ||||
| 	rix = rate->idx + rate_table->mcs_start; | ||||
| 	while (rate->idx > mcs_rix_off[i] && | ||||
| 	      i < sizeof(mcs_rix_off)/sizeof(int)) { | ||||
| 		rix++; i++; | ||||
| 	} | ||||
| 
 | ||||
| 	rix += rate->idx + rate_table->mcs_start; | ||||
| 
 | ||||
| 	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||||
| 	    (rate->flags & IEEE80211_TX_RC_SHORT_GI)) | ||||
| 		rix = rate_table->info[rix].ht_index; | ||||
|  | @ -1020,8 +1126,6 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | |||
| 		rix = rate_table->info[rix].sgi_index; | ||||
| 	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||||
| 		rix = rate_table->info[rix].cw40index; | ||||
| 	else | ||||
| 		rix = rate_table->info[rix].base_index; | ||||
| 
 | ||||
| 	return rix; | ||||
| } | ||||
|  | @ -1203,13 +1307,14 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
| 
 | ||||
| 	if (sta->ht_cap.ht_supported) { | ||||
| 		caps = WLAN_RC_HT_FLAG; | ||||
| 		if (sta->ht_cap.mcs.rx_mask[1]) | ||||
| 		if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2]) | ||||
| 			caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; | ||||
| 		else if (sta->ht_cap.mcs.rx_mask[1]) | ||||
| 			caps |= WLAN_RC_DS_FLAG; | ||||
| 		if (is_cw40) | ||||
| 			caps |= WLAN_RC_40_FLAG; | ||||
| 		if (is_sgi) | ||||
| 			caps |= WLAN_RC_SGI_FLAG; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return caps; | ||||
|  |  | |||
|  | @ -24,32 +24,63 @@ | |||
| struct ath_softc; | ||||
| 
 | ||||
| #define ATH_RATE_MAX     30 | ||||
| #define RATE_TABLE_SIZE  64 | ||||
| #define RATE_TABLE_SIZE  72 | ||||
| #define MAX_TX_RATE_PHY  48 | ||||
| 
 | ||||
| /* VALID_ALL - valid for 20/40/Legacy,
 | ||||
|  * VALID - Legacy only, | ||||
|  * VALID_20 - HT 20 only, | ||||
|  * VALID_40 - HT 40 only */ | ||||
| 
 | ||||
| #define INVALID    0x0 | ||||
| #define VALID      0x1 | ||||
| #define VALID_20   0x2 | ||||
| #define VALID_40   0x4 | ||||
| #define VALID_2040 (VALID_20|VALID_40) | ||||
| #define VALID_ALL  (VALID_2040|VALID) | ||||
| #define RC_INVALID	0x0000 | ||||
| #define RC_LEGACY	0x0001 | ||||
| #define RC_SS		0x0002 | ||||
| #define RC_DS		0x0004 | ||||
| #define RC_TS		0x0008 | ||||
| #define RC_HT_20	0x0010 | ||||
| #define RC_HT_40	0x0020 | ||||
| 
 | ||||
| #define RC_STREAM_MASK	0xe | ||||
| #define RC_DS_OR_LATER(f)	((((f) & RC_STREAM_MASK) == RC_DS) || \ | ||||
| 				(((f) & RC_STREAM_MASK) == (RC_DS | RC_TS))) | ||||
| #define RC_TS_ONLY(f)		(((f) & RC_STREAM_MASK) == RC_TS) | ||||
| #define RC_SS_OR_LEGACY(f)	((f) & (RC_SS | RC_LEGACY)) | ||||
| 
 | ||||
| #define RC_HT_2040		(RC_HT_20 | RC_HT_40) | ||||
| #define RC_ALL_STREAM		(RC_SS | RC_DS | RC_TS) | ||||
| #define RC_L_SD			(RC_LEGACY | RC_SS | RC_DS) | ||||
| #define RC_L_SDT		(RC_LEGACY | RC_SS | RC_DS | RC_TS) | ||||
| #define RC_HT_S_20		(RC_HT_20 | RC_SS) | ||||
| #define RC_HT_D_20		(RC_HT_20 | RC_DS) | ||||
| #define RC_HT_T_20		(RC_HT_20 | RC_TS) | ||||
| #define RC_HT_S_40		(RC_HT_40 | RC_SS) | ||||
| #define RC_HT_D_40		(RC_HT_40 | RC_DS) | ||||
| #define RC_HT_T_40		(RC_HT_40 | RC_TS) | ||||
| 
 | ||||
| #define RC_HT_SD_20		(RC_HT_20 | RC_SS | RC_DS) | ||||
| #define RC_HT_DT_20		(RC_HT_20 | RC_DS | RC_TS) | ||||
| #define RC_HT_SD_40		(RC_HT_40 | RC_SS | RC_DS) | ||||
| #define RC_HT_DT_40		(RC_HT_40 | RC_DS | RC_TS) | ||||
| 
 | ||||
| #define RC_HT_SD_2040		(RC_HT_2040 | RC_SS | RC_DS) | ||||
| #define RC_HT_SDT_2040		(RC_HT_2040 | RC_SS | RC_DS | RC_TS) | ||||
| 
 | ||||
| #define RC_HT_SDT_20		(RC_HT_20 | RC_SS | RC_DS | RC_TS) | ||||
| #define RC_HT_SDT_40		(RC_HT_40 | RC_SS | RC_DS | RC_TS) | ||||
| 
 | ||||
| #define RC_ALL			(RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM) | ||||
| 
 | ||||
| enum { | ||||
| 	WLAN_RC_PHY_OFDM, | ||||
| 	WLAN_RC_PHY_CCK, | ||||
| 	WLAN_RC_PHY_HT_20_SS, | ||||
| 	WLAN_RC_PHY_HT_20_DS, | ||||
| 	WLAN_RC_PHY_HT_20_TS, | ||||
| 	WLAN_RC_PHY_HT_40_SS, | ||||
| 	WLAN_RC_PHY_HT_40_DS, | ||||
| 	WLAN_RC_PHY_HT_40_TS, | ||||
| 	WLAN_RC_PHY_HT_20_SS_HGI, | ||||
| 	WLAN_RC_PHY_HT_20_DS_HGI, | ||||
| 	WLAN_RC_PHY_HT_20_TS_HGI, | ||||
| 	WLAN_RC_PHY_HT_40_SS_HGI, | ||||
| 	WLAN_RC_PHY_HT_40_DS_HGI, | ||||
| 	WLAN_RC_PHY_HT_40_TS_HGI, | ||||
| 	WLAN_RC_PHY_MAX | ||||
| }; | ||||
| 
 | ||||
|  | @ -57,36 +88,50 @@ enum { | |||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||||
| #define WLAN_RC_PHY_TS(_phy)   ((_phy == WLAN_RC_PHY_HT_20_TS)		\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_TS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||||
| #define WLAN_RC_PHY_20(_phy)   ((_phy == WLAN_RC_PHY_HT_20_SS)		\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_DS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_TS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)) | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI)) | ||||
| #define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)		\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_TS)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)	\ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||||
| #define WLAN_RC_PHY_SGI(_phy)  ((_phy == WLAN_RC_PHY_HT_20_SS_HGI)      \ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI)   \ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI)   \ | ||||
| 				|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) | ||||
| 
 | ||||
| #define WLAN_RC_PHY_HT(_phy)    (_phy >= WLAN_RC_PHY_HT_20_SS) | ||||
| 
 | ||||
| #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ?	\ | ||||
| 		(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID)) | ||||
| 	((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY)) | ||||
| 
 | ||||
| #define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ?	\ | ||||
| 	(RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS))) | ||||
| 
 | ||||
| /* Return TRUE if flag supports HT20 && client supports HT20 or
 | ||||
|  * return TRUE if flag supports HT40 && client supports HT40. | ||||
|  * This is used becos some rates overlap between HT20/HT40. | ||||
|  */ | ||||
| #define WLAN_RC_PHY_HT_VALID(flag, capflag)			\ | ||||
| 	(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \ | ||||
| 	 ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG))) | ||||
| 	(((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \ | ||||
| 	 ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG))) | ||||
| 
 | ||||
| #define WLAN_RC_DS_FLAG         (0x01) | ||||
| #define WLAN_RC_40_FLAG         (0x02) | ||||
| #define WLAN_RC_SGI_FLAG        (0x04) | ||||
| #define WLAN_RC_HT_FLAG         (0x08) | ||||
| #define WLAN_RC_TS_FLAG         (0x02) | ||||
| #define WLAN_RC_40_FLAG         (0x04) | ||||
| #define WLAN_RC_SGI_FLAG        (0x08) | ||||
| #define WLAN_RC_HT_FLAG         (0x10) | ||||
| 
 | ||||
| /**
 | ||||
|  * struct ath_rate_table - Rate Control table | ||||
|  | @ -110,15 +155,13 @@ struct ath_rate_table { | |||
| 	int rate_cnt; | ||||
| 	int mcs_start; | ||||
| 	struct { | ||||
| 		u8 valid; | ||||
| 		u8 valid_single_stream; | ||||
| 		u16 rate_flags; | ||||
| 		u8 phy; | ||||
| 		u32 ratekbps; | ||||
| 		u32 user_ratekbps; | ||||
| 		u8 ratecode; | ||||
| 		u8 dot11rate; | ||||
| 		u8 ctrl_rate; | ||||
| 		u8 base_index; | ||||
| 		u8 cw40index; | ||||
| 		u8 sgi_index; | ||||
| 		u8 ht_index; | ||||
|  |  | |||
|  | @ -695,16 +695,18 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) | |||
| 		  idle ? "idle" : "not-idle"); | ||||
| } | ||||
| /* Only bother starting a queue on an active virtual wiphy */ | ||||
| void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) | ||||
| bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) | ||||
| { | ||||
| 	struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||||
| 	unsigned int i; | ||||
| 	bool txq_started = false; | ||||
| 
 | ||||
| 	spin_lock_bh(&sc->wiphy_lock); | ||||
| 
 | ||||
| 	/* Start the primary wiphy */ | ||||
| 	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { | ||||
| 		ieee80211_wake_queue(hw, skb_queue); | ||||
| 		txq_started = true; | ||||
| 		goto unlock; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -718,11 +720,13 @@ void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) | |||
| 
 | ||||
| 		hw = aphy->hw; | ||||
| 		ieee80211_wake_queue(hw, skb_queue); | ||||
| 		txq_started = true; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| unlock: | ||||
| 	spin_unlock_bh(&sc->wiphy_lock); | ||||
| 	return txq_started; | ||||
| } | ||||
| 
 | ||||
| /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ | ||||
|  |  | |||
|  | @ -518,6 +518,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 		bf = bf_next; | ||||
| 	} | ||||
| 
 | ||||
| 	/* prepend un-acked frames to the beginning of the pending frame queue */ | ||||
| 	if (!list_empty(&bf_pending)) { | ||||
| 		spin_lock_bh(&txq->axq_lock); | ||||
| 		list_splice(&bf_pending, &tid->buf_q); | ||||
| 		ath_tx_queue_tid(txq, tid); | ||||
| 		spin_unlock_bh(&txq->axq_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	if (tid->state & AGGR_CLEANUP) { | ||||
| 		if (tid->baw_head == tid->baw_tail) { | ||||
| 			tid->state &= ~AGGR_ADDBA_COMPLETE; | ||||
|  | @ -530,14 +538,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* prepend un-acked frames to the beginning of the pending frame queue */ | ||||
| 	if (!list_empty(&bf_pending)) { | ||||
| 		spin_lock_bh(&txq->axq_lock); | ||||
| 		list_splice(&bf_pending, &tid->buf_q); | ||||
| 		ath_tx_queue_tid(txq, tid); | ||||
| 		spin_unlock_bh(&txq->axq_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	rcu_read_unlock(); | ||||
| 
 | ||||
| 	if (needreset) | ||||
|  | @ -2077,7 +2077,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | |||
| 
 | ||||
| 	spin_lock_bh(&txq->axq_lock); | ||||
| 	if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { | ||||
| 		ath_mac80211_start_queue(sc, qnum); | ||||
| 		if (ath_mac80211_start_queue(sc, qnum)) | ||||
| 			txq->stopped = 0; | ||||
| 	} | ||||
| 	spin_unlock_bh(&txq->axq_lock); | ||||
|  |  | |||
|  | @ -828,7 +828,6 @@ struct libipw_device { | |||
| 	int host_strip_iv_icv; | ||||
| 
 | ||||
| 	int host_open_frag; | ||||
| 	int host_build_iv; | ||||
| 	int ieee802_1x;		/* is IEEE 802.1X used */ | ||||
| 
 | ||||
| 	/* WPA data */ | ||||
|  |  | |||
|  | @ -260,7 +260,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size, | ||||
| 	    rts_required; | ||||
| 	unsigned long flags; | ||||
| 	int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv; | ||||
| 	int encrypt, host_encrypt, host_encrypt_msdu; | ||||
| 	__be16 ether_type; | ||||
| 	int bytes, fc, hdr_len; | ||||
| 	struct sk_buff *skb_frag; | ||||
|  | @ -301,7 +301,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 
 | ||||
| 	host_encrypt = ieee->host_encrypt && encrypt && crypt; | ||||
| 	host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt; | ||||
| 	host_build_iv = ieee->host_build_iv && encrypt && crypt; | ||||
| 
 | ||||
| 	if (!encrypt && ieee->ieee802_1x && | ||||
| 	    ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) { | ||||
|  | @ -313,7 +312,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 	skb_copy_from_linear_data(skb, dest, ETH_ALEN); | ||||
| 	skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN); | ||||
| 
 | ||||
| 	if (host_encrypt || host_build_iv) | ||||
| 	if (host_encrypt) | ||||
| 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | | ||||
| 		    IEEE80211_FCTL_PROTECTED; | ||||
| 	else | ||||
|  | @ -467,7 +466,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 	for (; i < nr_frags; i++) { | ||||
| 		skb_frag = txb->fragments[i]; | ||||
| 
 | ||||
| 		if (host_encrypt || host_build_iv) | ||||
| 		if (host_encrypt) | ||||
| 			skb_reserve(skb_frag, | ||||
| 				    crypt->ops->extra_mpdu_prefix_len); | ||||
| 
 | ||||
|  | @ -502,15 +501,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 		 * to insert the IV between the header and the payload */ | ||||
| 		if (host_encrypt) | ||||
| 			libipw_encrypt_fragment(ieee, skb_frag, hdr_len); | ||||
| 		else if (host_build_iv) { | ||||
| 			atomic_inc(&crypt->refcnt); | ||||
| 			if (crypt->ops->build_iv) | ||||
| 				crypt->ops->build_iv(skb_frag, hdr_len, | ||||
| 				      ieee->sec.keys[ieee->sec.active_key], | ||||
| 				      ieee->sec.key_sizes[ieee->sec.active_key], | ||||
| 				      crypt->priv); | ||||
| 			atomic_dec(&crypt->refcnt); | ||||
| 		} | ||||
| 
 | ||||
| 		if (ieee->config & | ||||
| 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS)) | ||||
|  |  | |||
|  | @ -320,7 +320,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee, | |||
| 	}; | ||||
| 	int i, key, key_provided, len; | ||||
| 	struct lib80211_crypt_data **crypt; | ||||
| 	int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; | ||||
| 	int host_crypto = ieee->host_encrypt || ieee->host_decrypt; | ||||
| 	DECLARE_SSID_BUF(ssid); | ||||
| 
 | ||||
| 	LIBIPW_DEBUG_WX("SET_ENCODE\n"); | ||||
|  |  | |||
|  | @ -222,6 +222,7 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 	}, | ||||
| 	.recover_from_tx_stall = iwl_bg_monitor_recover, | ||||
| 	.check_plcp_health = iwl_good_plcp_health, | ||||
|  |  | |||
|  | @ -1605,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) | |||
| 	if (!test_bit(STATUS_TEMPERATURE, &priv->status)) | ||||
| 		vt = sign_extend(R4, 23); | ||||
| 	else | ||||
| 		vt = sign_extend(le32_to_cpu( | ||||
| 				priv->_agn.statistics.general.temperature), 23); | ||||
| 		vt = sign_extend(le32_to_cpu(priv->_agn.statistics. | ||||
| 				 general.common.temperature), 23); | ||||
| 
 | ||||
| 	IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); | ||||
| 
 | ||||
|  | @ -2285,6 +2285,7 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 	}, | ||||
| 	.recover_from_tx_stall = iwl_bg_monitor_recover, | ||||
| 	.check_plcp_health = iwl_good_plcp_health, | ||||
|  |  | |||
|  | @ -265,7 +265,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) | |||
| 	u32 vt = 0; | ||||
| 	s32 offset =  iwl_temp_calib_to_offset(priv); | ||||
| 
 | ||||
| 	vt = le32_to_cpu(priv->_agn.statistics.general.temperature); | ||||
| 	vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); | ||||
| 	vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; | ||||
| 	/* now vt hold the temperature in Kelvin */ | ||||
| 	priv->temperature = KELVIN_TO_CELSIUS(vt); | ||||
|  | @ -398,6 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 	}, | ||||
| 	.recover_from_tx_stall = iwl_bg_monitor_recover, | ||||
| 	.check_plcp_health = iwl_good_plcp_health, | ||||
|  |  | |||
|  | @ -323,6 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 	}, | ||||
| 	.recover_from_tx_stall = iwl_bg_monitor_recover, | ||||
| 	.check_plcp_health = iwl_good_plcp_health, | ||||
|  | @ -500,6 +501,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl6000g2b_2abg_cfg = { | ||||
|  | @ -535,6 +537,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl6000g2b_2bgn_cfg = { | ||||
|  | @ -572,6 +575,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl6000g2b_2bg_cfg = { | ||||
|  | @ -607,6 +611,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl6000g2b_bgn_cfg = { | ||||
|  | @ -644,6 +649,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl6000g2b_bg_cfg = { | ||||
|  | @ -679,6 +685,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { | |||
| 	.sensitivity_calib_by_driver = true, | ||||
| 	.chain_noise_calib_by_driver = true, | ||||
| 	.need_dc_calib = true, | ||||
| 	.bt_statistics = true, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
|  | @ -605,8 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
| 	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); | ||||
| } | ||||
| 
 | ||||
| void iwl_sensitivity_calibration(struct iwl_priv *priv, | ||||
| 				    struct iwl_notif_statistics *resp) | ||||
| void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) | ||||
| { | ||||
| 	u32 rx_enable_time; | ||||
| 	u32 fa_cck; | ||||
|  | @ -616,8 +615,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, | |||
| 	u32 norm_fa_ofdm; | ||||
| 	u32 norm_fa_cck; | ||||
| 	struct iwl_sensitivity_data *data = NULL; | ||||
| 	struct statistics_rx_non_phy *rx_info = &(resp->rx.general); | ||||
| 	struct statistics_rx *statistics = &(resp->rx); | ||||
| 	struct statistics_rx_non_phy *rx_info; | ||||
| 	struct statistics_rx_phy *ofdm, *cck; | ||||
| 	unsigned long flags; | ||||
| 	struct statistics_general_data statis; | ||||
| 
 | ||||
|  | @ -632,6 +631,16 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, | |||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> | ||||
| 			      rx.general.common); | ||||
| 		ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); | ||||
| 		cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); | ||||
| 	} else { | ||||
| 		rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); | ||||
| 		ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); | ||||
| 		cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); | ||||
| 	} | ||||
| 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | ||||
| 		IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); | ||||
| 		spin_unlock_irqrestore(&priv->lock, flags); | ||||
|  | @ -640,23 +649,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, | |||
| 
 | ||||
| 	/* Extract Statistics: */ | ||||
| 	rx_enable_time = le32_to_cpu(rx_info->channel_load); | ||||
| 	fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt); | ||||
| 	fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt); | ||||
| 	bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err); | ||||
| 	bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err); | ||||
| 	fa_cck = le32_to_cpu(cck->false_alarm_cnt); | ||||
| 	fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt); | ||||
| 	bad_plcp_cck = le32_to_cpu(cck->plcp_err); | ||||
| 	bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err); | ||||
| 
 | ||||
| 	statis.beacon_silence_rssi_a = | ||||
| 			le32_to_cpu(statistics->general.beacon_silence_rssi_a); | ||||
| 			le32_to_cpu(rx_info->beacon_silence_rssi_a); | ||||
| 	statis.beacon_silence_rssi_b = | ||||
| 			le32_to_cpu(statistics->general.beacon_silence_rssi_b); | ||||
| 			le32_to_cpu(rx_info->beacon_silence_rssi_b); | ||||
| 	statis.beacon_silence_rssi_c = | ||||
| 			le32_to_cpu(statistics->general.beacon_silence_rssi_c); | ||||
| 			le32_to_cpu(rx_info->beacon_silence_rssi_c); | ||||
| 	statis.beacon_energy_a = | ||||
| 			le32_to_cpu(statistics->general.beacon_energy_a); | ||||
| 			le32_to_cpu(rx_info->beacon_energy_a); | ||||
| 	statis.beacon_energy_b = | ||||
| 			le32_to_cpu(statistics->general.beacon_energy_b); | ||||
| 			le32_to_cpu(rx_info->beacon_energy_b); | ||||
| 	statis.beacon_energy_c = | ||||
| 			le32_to_cpu(statistics->general.beacon_energy_c); | ||||
| 			le32_to_cpu(rx_info->beacon_energy_c); | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
|  | @ -728,8 +737,7 @@ static inline u8 find_first_chain(u8 mask) | |||
|  * 1)  Which antennas are connected. | ||||
|  * 2)  Differential rx gain settings to balance the 3 receivers. | ||||
|  */ | ||||
| void iwl_chain_noise_calibration(struct iwl_priv *priv, | ||||
| 				 struct iwl_notif_statistics *stat_resp) | ||||
| void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) | ||||
| { | ||||
| 	struct iwl_chain_noise_data *data = NULL; | ||||
| 
 | ||||
|  | @ -753,7 +761,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, | |||
| 	u32 active_chains = 0; | ||||
| 	u8 num_tx_chains; | ||||
| 	unsigned long flags; | ||||
| 	struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general); | ||||
| 	struct statistics_rx_non_phy *rx_info; | ||||
| 	u8 first_chain; | ||||
| 
 | ||||
| 	if (priv->disable_chain_noise_cal) | ||||
|  | @ -772,6 +780,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, | |||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> | ||||
| 			      rx.general.common); | ||||
| 	} else { | ||||
| 		rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> | ||||
| 			      rx.general); | ||||
| 	} | ||||
| 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | ||||
| 		IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); | ||||
| 		spin_unlock_irqrestore(&priv->lock, flags); | ||||
|  | @ -780,8 +795,19 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, | |||
| 
 | ||||
| 	rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); | ||||
| 	rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); | ||||
| 	stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); | ||||
| 	stat_chnum = le32_to_cpu(stat_resp->flag) >> 16; | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		stat_band24 = !!(((struct iwl_bt_notif_statistics *) | ||||
| 				 stat_resp)->flag & | ||||
| 				 STATISTICS_REPLY_FLG_BAND_24G_MSK); | ||||
| 		stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) | ||||
| 					 stat_resp)->flag) >> 16; | ||||
| 	} else { | ||||
| 		stat_band24 = !!(((struct iwl_notif_statistics *) | ||||
| 				 stat_resp)->flag & | ||||
| 				 STATISTICS_REPLY_FLG_BAND_24G_MSK); | ||||
| 		stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) | ||||
| 					 stat_resp)->flag) >> 16; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Make sure we accumulate data for just the associated channel
 | ||||
| 	 *   (even if scanning). */ | ||||
|  |  | |||
|  | @ -31,21 +31,24 @@ | |||
| static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | ||||
| { | ||||
| 	int p = 0; | ||||
| 	u32 flag; | ||||
| 
 | ||||
| 	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", | ||||
| 		       le32_to_cpu(priv->_agn.statistics.flag)); | ||||
| 	if (le32_to_cpu(priv->_agn.statistics.flag) & | ||||
| 			UCODE_STATISTICS_CLEAR_MSK) | ||||
| 	if (priv->cfg->bt_statistics) | ||||
| 		flag = le32_to_cpu(priv->_agn.statistics_bt.flag); | ||||
| 	else | ||||
| 		flag = le32_to_cpu(priv->_agn.statistics.flag); | ||||
| 
 | ||||
| 	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | ||||
| 	if (flag & UCODE_STATISTICS_CLEAR_MSK) | ||||
| 		p += scnprintf(buf + p, bufsz - p, | ||||
| 		"\tStatistics have been cleared\n"); | ||||
| 	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", | ||||
| 		       (le32_to_cpu(priv->_agn.statistics.flag) & | ||||
| 			UCODE_STATISTICS_FREQUENCY_MSK) | ||||
| 		(flag & UCODE_STATISTICS_FREQUENCY_MSK) | ||||
| 		? "2.4 GHz" : "5.2 GHz"); | ||||
| 	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", | ||||
| 		       (le32_to_cpu(priv->_agn.statistics.flag) & | ||||
| 			UCODE_STATISTICS_NARROW_BAND_MSK) | ||||
| 		(flag & UCODE_STATISTICS_NARROW_BAND_MSK) | ||||
| 		 ? "enabled" : "disabled"); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
|  | @ -79,6 +82,26 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | |||
| 	 * the last statistics notification from uCode | ||||
| 	 * might not reflect the current uCode activity | ||||
| 	 */ | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		ofdm = &priv->_agn.statistics_bt.rx.ofdm; | ||||
| 		cck = &priv->_agn.statistics_bt.rx.cck; | ||||
| 		general = &priv->_agn.statistics_bt.rx.general.common; | ||||
| 		ht = &priv->_agn.statistics_bt.rx.ofdm_ht; | ||||
| 		accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; | ||||
| 		accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; | ||||
| 		accum_general = | ||||
| 			&priv->_agn.accum_statistics_bt.rx.general.common; | ||||
| 		accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; | ||||
| 		delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; | ||||
| 		delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; | ||||
| 		delta_general = | ||||
| 			&priv->_agn.delta_statistics_bt.rx.general.common; | ||||
| 		delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; | ||||
| 		max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; | ||||
| 		max_cck = &priv->_agn.max_delta_bt.rx.cck; | ||||
| 		max_general = &priv->_agn.max_delta_bt.rx.general.common; | ||||
| 		max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; | ||||
| 	} else { | ||||
| 		ofdm = &priv->_agn.statistics.rx.ofdm; | ||||
| 		cck = &priv->_agn.statistics.rx.cck; | ||||
| 		general = &priv->_agn.statistics.rx.general; | ||||
|  | @ -95,6 +118,7 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | |||
| 		max_cck = &priv->_agn.max_delta.rx.cck; | ||||
| 		max_general = &priv->_agn.max_delta.rx.general; | ||||
| 		max_ht = &priv->_agn.max_delta.rx.ofdm_ht; | ||||
| 	} | ||||
| 
 | ||||
| 	pos += iwl_statistics_flag(priv, buf, bufsz); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current" | ||||
|  | @ -560,10 +584,18 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, | |||
| 	  * the last statistics notification from uCode | ||||
| 	  * might not reflect the current uCode activity | ||||
| 	  */ | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		tx = &priv->_agn.statistics_bt.tx; | ||||
| 		accum_tx = &priv->_agn.accum_statistics_bt.tx; | ||||
| 		delta_tx = &priv->_agn.delta_statistics_bt.tx; | ||||
| 		max_tx = &priv->_agn.max_delta_bt.tx; | ||||
| 	} else { | ||||
| 		tx = &priv->_agn.statistics.tx; | ||||
| 		accum_tx = &priv->_agn.accum_statistics.tx; | ||||
| 		delta_tx = &priv->_agn.delta_statistics.tx; | ||||
| 		max_tx = &priv->_agn.max_delta.tx; | ||||
| 	} | ||||
| 
 | ||||
| 	pos += iwl_statistics_flag(priv, buf, bufsz); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos,  "%-32s     current" | ||||
| 			 "acumulative       delta         max\n", | ||||
|  | @ -759,8 +791,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | |||
| 	char *buf; | ||||
| 	int bufsz = sizeof(struct statistics_general) * 10 + 300; | ||||
| 	ssize_t ret; | ||||
| 	struct statistics_general *general, *accum_general; | ||||
| 	struct statistics_general *delta_general, *max_general; | ||||
| 	struct statistics_general_common *general, *accum_general; | ||||
| 	struct statistics_general_common *delta_general, *max_general; | ||||
| 	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | ||||
| 	struct statistics_div *div, *accum_div, *delta_div, *max_div; | ||||
| 
 | ||||
|  | @ -777,18 +809,34 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | |||
| 	  * the last statistics notification from uCode | ||||
| 	  * might not reflect the current uCode activity | ||||
| 	  */ | ||||
| 	general = &priv->_agn.statistics.general; | ||||
| 	dbg = &priv->_agn.statistics.general.dbg; | ||||
| 	div = &priv->_agn.statistics.general.div; | ||||
| 	accum_general = &priv->_agn.accum_statistics.general; | ||||
| 	delta_general = &priv->_agn.delta_statistics.general; | ||||
| 	max_general = &priv->_agn.max_delta.general; | ||||
| 	accum_dbg = &priv->_agn.accum_statistics.general.dbg; | ||||
| 	delta_dbg = &priv->_agn.delta_statistics.general.dbg; | ||||
| 	max_dbg = &priv->_agn.max_delta.general.dbg; | ||||
| 	accum_div = &priv->_agn.accum_statistics.general.div; | ||||
| 	delta_div = &priv->_agn.delta_statistics.general.div; | ||||
| 	max_div = &priv->_agn.max_delta.general.div; | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		general = &priv->_agn.statistics_bt.general.common; | ||||
| 		dbg = &priv->_agn.statistics_bt.general.common.dbg; | ||||
| 		div = &priv->_agn.statistics_bt.general.common.div; | ||||
| 		accum_general = &priv->_agn.accum_statistics_bt.general.common; | ||||
| 		accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; | ||||
| 		accum_div = &priv->_agn.accum_statistics_bt.general.common.div; | ||||
| 		delta_general = &priv->_agn.delta_statistics_bt.general.common; | ||||
| 		max_general = &priv->_agn.max_delta_bt.general.common; | ||||
| 		delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; | ||||
| 		max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; | ||||
| 		delta_div = &priv->_agn.delta_statistics_bt.general.common.div; | ||||
| 		max_div = &priv->_agn.max_delta_bt.general.common.div; | ||||
| 	} else { | ||||
| 		general = &priv->_agn.statistics.general.common; | ||||
| 		dbg = &priv->_agn.statistics.general.common.dbg; | ||||
| 		div = &priv->_agn.statistics.general.common.div; | ||||
| 		accum_general = &priv->_agn.accum_statistics.general.common; | ||||
| 		accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; | ||||
| 		accum_div = &priv->_agn.accum_statistics.general.common.div; | ||||
| 		delta_general = &priv->_agn.delta_statistics.general.common; | ||||
| 		max_general = &priv->_agn.max_delta.general.common; | ||||
| 		delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; | ||||
| 		max_dbg = &priv->_agn.max_delta.general.common.dbg; | ||||
| 		delta_div = &priv->_agn.delta_statistics.general.common.div; | ||||
| 		max_div = &priv->_agn.max_delta.general.common.div; | ||||
| 	} | ||||
| 
 | ||||
| 	pos += iwl_statistics_flag(priv, buf, bufsz); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, "%-32s     current" | ||||
| 			 "acumulative       delta         max\n", | ||||
|  | @ -876,3 +924,90 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | |||
| 	kfree(buf); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| ssize_t iwl_ucode_bt_stats_read(struct file *file, | ||||
| 				char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||||
| 	int pos = 0; | ||||
| 	char *buf; | ||||
| 	int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; | ||||
| 	ssize_t ret; | ||||
| 	struct statistics_bt_activity *bt, *accum_bt; | ||||
| 
 | ||||
| 	if (!iwl_is_alive(priv)) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	/* make request to uCode to retrieve statistics information */ | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| 
 | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, | ||||
| 			"Error sending statistics request: %zd\n", ret); | ||||
| 		return -EAGAIN; | ||||
| 	} | ||||
| 	buf = kzalloc(bufsz, GFP_KERNEL); | ||||
| 	if (!buf) { | ||||
| 		IWL_ERR(priv, "Can not allocate Buffer\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * the statistic information display here is based on | ||||
| 	 * the last statistics notification from uCode | ||||
| 	 * might not reflect the current uCode activity | ||||
| 	 */ | ||||
| 	bt = &priv->_agn.statistics_bt.general.activity; | ||||
| 	accum_bt = &priv->_agn.accum_statistics_bt.general.activity; | ||||
| 
 | ||||
| 	pos += iwl_statistics_flag(priv, buf, bufsz); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			"\t\t\tcurrent\t\t\taccumulative\n"); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->hi_priority_tx_req_cnt), | ||||
| 			 accum_bt->hi_priority_tx_req_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->hi_priority_tx_denied_cnt), | ||||
| 			 accum_bt->hi_priority_tx_denied_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->lo_priority_tx_req_cnt), | ||||
| 			 accum_bt->lo_priority_tx_req_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->lo_priority_tx_denied_cnt), | ||||
| 			 accum_bt->lo_priority_tx_denied_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->hi_priority_rx_req_cnt), | ||||
| 			 accum_bt->hi_priority_rx_req_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->hi_priority_rx_denied_cnt), | ||||
| 			 accum_bt->hi_priority_rx_denied_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->lo_priority_rx_req_cnt), | ||||
| 			 accum_bt->lo_priority_rx_req_cnt); | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(bt->lo_priority_rx_denied_cnt), | ||||
| 			 accum_bt->lo_priority_rx_denied_cnt); | ||||
| 
 | ||||
| 	pos += scnprintf(buf + pos, bufsz - pos, | ||||
| 			 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", | ||||
| 			 le32_to_cpu(priv->_agn.statistics_bt.rx. | ||||
| 				general.num_bt_kills), | ||||
| 			 priv->_agn.accum_statistics_bt.rx. | ||||
| 				general.num_bt_kills); | ||||
| 
 | ||||
| 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||||
| 	kfree(buf); | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -37,6 +37,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, | |||
| 				size_t count, loff_t *ppos); | ||||
| ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||||
| 				     size_t count, loff_t *ppos); | ||||
| ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos); | ||||
| #else | ||||
| static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
|  | @ -53,4 +55,9 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user | |||
| { | ||||
| 	return 0; | ||||
| } | ||||
| static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -164,7 +164,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, | |||
| 
 | ||||
| 		memset(&cmd, 0, sizeof(cmd)); | ||||
| 
 | ||||
| 		cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; | ||||
| 		cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; | ||||
| 		cmd.hdr.first_group = 0; | ||||
| 		cmd.hdr.groups_num = 1; | ||||
| 		cmd.hdr.data_valid = 1; | ||||
|  | @ -197,7 +197,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
| 		data->beacon_count = 0; | ||||
| 
 | ||||
| 		memset(&cmd, 0, sizeof(cmd)); | ||||
| 		cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; | ||||
| 		cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; | ||||
| 		cmd.hdr.first_group = 0; | ||||
| 		cmd.hdr.groups_num = 1; | ||||
| 		cmd.hdr.data_valid = 1; | ||||
|  |  | |||
|  | @ -364,7 +364,7 @@ void iwlagn_temperature(struct iwl_priv *priv) | |||
| { | ||||
| 	/* store temperature from statistics (in Celsius) */ | ||||
| 	priv->temperature = | ||||
| 		le32_to_cpu(priv->_agn.statistics.general.temperature); | ||||
| 		le32_to_cpu(priv->_agn.statistics.general.common.temperature); | ||||
| 	iwl_tt_handler(priv); | ||||
| } | ||||
| 
 | ||||
|  | @ -1234,7 +1234,10 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 
 | ||||
| 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | ||||
| 		spin_lock_irqsave(&priv->lock, flags); | ||||
| 		interval = vif ? vif->bss_conf.beacon_int : 0; | ||||
| 		if (priv->is_internal_short_scan) | ||||
| 			interval = 0; | ||||
| 		else | ||||
| 			interval = vif->bss_conf.beacon_int; | ||||
| 		spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
| 		scan->suspend_time = 0; | ||||
|  |  | |||
|  | @ -67,18 +67,23 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
|  *   exactly when to expect beacons, therefore only when we're associated. */ | ||||
| static void iwl_rx_calc_noise(struct iwl_priv *priv) | ||||
| { | ||||
| 	struct statistics_rx_non_phy *rx_info | ||||
| 				= &(priv->_agn.statistics.rx.general); | ||||
| 	struct statistics_rx_non_phy *rx_info; | ||||
| 	int num_active_rx = 0; | ||||
| 	int total_silence = 0; | ||||
| 	int bcn_silence_a = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | ||||
| 	int bcn_silence_b = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | ||||
| 	int bcn_silence_c = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | ||||
| 	int bcn_silence_a, bcn_silence_b, bcn_silence_c; | ||||
| 	int last_rx_noise; | ||||
| 
 | ||||
| 	if (priv->cfg->bt_statistics) | ||||
| 		rx_info = &(priv->_agn.statistics_bt.rx.general.common); | ||||
| 	else | ||||
| 		rx_info = &(priv->_agn.statistics.rx.general); | ||||
| 	bcn_silence_a = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | ||||
| 	bcn_silence_b = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | ||||
| 	bcn_silence_c = | ||||
| 		le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | ||||
| 
 | ||||
| 	if (bcn_silence_a) { | ||||
| 		total_silence += bcn_silence_a; | ||||
| 		num_active_rx++; | ||||
|  | @ -112,17 +117,35 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
| static void iwl_accumulative_statistics(struct iwl_priv *priv, | ||||
| 					__le32 *stats) | ||||
| { | ||||
| 	int i; | ||||
| 	int i, size; | ||||
| 	__le32 *prev_stats; | ||||
| 	u32 *accum_stats; | ||||
| 	u32 *delta, *max_delta; | ||||
| 	struct statistics_general_common *general, *accum_general; | ||||
| 	struct statistics_tx *tx, *accum_tx; | ||||
| 
 | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		prev_stats = (__le32 *)&priv->_agn.statistics_bt; | ||||
| 		accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; | ||||
| 		size = sizeof(struct iwl_bt_notif_statistics); | ||||
| 		general = &priv->_agn.statistics_bt.general.common; | ||||
| 		accum_general = &priv->_agn.accum_statistics_bt.general.common; | ||||
| 		tx = &priv->_agn.statistics_bt.tx; | ||||
| 		accum_tx = &priv->_agn.accum_statistics_bt.tx; | ||||
| 		delta = (u32 *)&priv->_agn.delta_statistics_bt; | ||||
| 		max_delta = (u32 *)&priv->_agn.max_delta_bt; | ||||
| 	} else { | ||||
| 		prev_stats = (__le32 *)&priv->_agn.statistics; | ||||
| 		accum_stats = (u32 *)&priv->_agn.accum_statistics; | ||||
| 		size = sizeof(struct iwl_notif_statistics); | ||||
| 		general = &priv->_agn.statistics.general.common; | ||||
| 		accum_general = &priv->_agn.accum_statistics.general.common; | ||||
| 		tx = &priv->_agn.statistics.tx; | ||||
| 		accum_tx = &priv->_agn.accum_statistics.tx; | ||||
| 		delta = (u32 *)&priv->_agn.delta_statistics; | ||||
| 		max_delta = (u32 *)&priv->_agn.max_delta; | ||||
| 
 | ||||
| 	for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); | ||||
| 	} | ||||
| 	for (i = sizeof(__le32); i < size; | ||||
| 	     i += sizeof(__le32), stats++, prev_stats++, delta++, | ||||
| 	     max_delta++, accum_stats++) { | ||||
| 		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { | ||||
|  | @ -135,18 +158,12 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, | |||
| 	} | ||||
| 
 | ||||
| 	/* reset accumulative statistics for "no-counter" type statistics */ | ||||
| 	priv->_agn.accum_statistics.general.temperature = | ||||
| 		priv->_agn.statistics.general.temperature; | ||||
| 	priv->_agn.accum_statistics.general.temperature_m = | ||||
| 		priv->_agn.statistics.general.temperature_m; | ||||
| 	priv->_agn.accum_statistics.general.ttl_timestamp = | ||||
| 		priv->_agn.statistics.general.ttl_timestamp; | ||||
| 	priv->_agn.accum_statistics.tx.tx_power.ant_a = | ||||
| 		priv->_agn.statistics.tx.tx_power.ant_a; | ||||
| 	priv->_agn.accum_statistics.tx.tx_power.ant_b = | ||||
| 		priv->_agn.statistics.tx.tx_power.ant_b; | ||||
| 	priv->_agn.accum_statistics.tx.tx_power.ant_c = | ||||
| 		priv->_agn.statistics.tx.tx_power.ant_c; | ||||
| 	accum_general->temperature = general->temperature; | ||||
| 	accum_general->temperature_m = general->temperature_m; | ||||
| 	accum_general->ttl_timestamp = general->ttl_timestamp; | ||||
| 	accum_tx->tx_power.ant_a = tx->tx_power.ant_a; | ||||
| 	accum_tx->tx_power.ant_b = tx->tx_power.ant_b; | ||||
| 	accum_tx->tx_power.ant_c = tx->tx_power.ant_c; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | @ -185,11 +202,30 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, | |||
| 	 * by zero. | ||||
| 	 */ | ||||
| 	if (plcp_msec) { | ||||
| 		struct statistics_rx_phy *ofdm; | ||||
| 		struct statistics_rx_ht_phy *ofdm_ht; | ||||
| 
 | ||||
| 		if (priv->cfg->bt_statistics) { | ||||
| 			ofdm = &pkt->u.stats_bt.rx.ofdm; | ||||
| 			ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | ||||
| 			combined_plcp_delta = | ||||
| 			(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - | ||||
| 			le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) + | ||||
| 			(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - | ||||
| 			le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err)); | ||||
| 			   (le32_to_cpu(ofdm->plcp_err) - | ||||
| 			   le32_to_cpu(priv->_agn.statistics_bt. | ||||
| 				       rx.ofdm.plcp_err)) + | ||||
| 			   (le32_to_cpu(ofdm_ht->plcp_err) - | ||||
| 			   le32_to_cpu(priv->_agn.statistics_bt. | ||||
| 				       rx.ofdm_ht.plcp_err)); | ||||
| 		} else { | ||||
| 			ofdm = &pkt->u.stats.rx.ofdm; | ||||
| 			ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | ||||
| 			combined_plcp_delta = | ||||
| 			    (le32_to_cpu(ofdm->plcp_err) - | ||||
| 			    le32_to_cpu(priv->_agn.statistics. | ||||
| 					rx.ofdm.plcp_err)) + | ||||
| 			    (le32_to_cpu(ofdm_ht->plcp_err) - | ||||
| 			    le32_to_cpu(priv->_agn.statistics. | ||||
| 					rx.ofdm_ht.plcp_err)); | ||||
| 		} | ||||
| 
 | ||||
| 		if ((combined_plcp_delta > 0) && | ||||
| 		    ((combined_plcp_delta * 100) / plcp_msec) > | ||||
|  | @ -208,13 +244,12 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, | |||
| 			IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||||
| 				    "%u, %u, %u, %u, %d, %u mSecs\n", | ||||
| 				    priv->cfg->plcp_delta_threshold, | ||||
| 				le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), | ||||
| 				le32_to_cpu( | ||||
| 				       priv->_agn.statistics.rx.ofdm.plcp_err), | ||||
| 				le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), | ||||
| 				le32_to_cpu( | ||||
| 				  priv->_agn.statistics.rx.ofdm_ht.plcp_err), | ||||
| 				    le32_to_cpu(ofdm->plcp_err), | ||||
| 				    le32_to_cpu(ofdm->plcp_err), | ||||
| 				    le32_to_cpu(ofdm_ht->plcp_err), | ||||
| 				    le32_to_cpu(ofdm_ht->plcp_err), | ||||
| 				    combined_plcp_delta, plcp_msec); | ||||
| 
 | ||||
| 			rc = false; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -227,22 +262,48 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
| 	int change; | ||||
| 	struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||||
| 
 | ||||
| 	if (priv->cfg->bt_statistics) { | ||||
| 		IWL_DEBUG_RX(priv, | ||||
| 			     "Statistics notification received (%d vs %d).\n", | ||||
| 			     (int)sizeof(struct iwl_bt_notif_statistics), | ||||
| 			     le32_to_cpu(pkt->len_n_flags) & | ||||
| 			     FH_RSCSR_FRAME_SIZE_MSK); | ||||
| 
 | ||||
| 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | ||||
| 		     (int)sizeof(priv->_agn.statistics), | ||||
| 		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | ||||
| 		change = ((priv->_agn.statistics_bt.general.common.temperature != | ||||
| 			   pkt->u.stats_bt.general.common.temperature) || | ||||
| 			   ((priv->_agn.statistics_bt.flag & | ||||
| 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | ||||
| 			   (pkt->u.stats_bt.flag & | ||||
| 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | ||||
| #ifdef CONFIG_IWLWIFI_DEBUGFS | ||||
| 		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); | ||||
| #endif | ||||
| 
 | ||||
| 	change = ((priv->_agn.statistics.general.temperature != | ||||
| 		   pkt->u.stats.general.temperature) || | ||||
| 	} else { | ||||
| 		IWL_DEBUG_RX(priv, | ||||
| 			     "Statistics notification received (%d vs %d).\n", | ||||
| 			     (int)sizeof(struct iwl_notif_statistics), | ||||
| 			     le32_to_cpu(pkt->len_n_flags) & | ||||
| 			     FH_RSCSR_FRAME_SIZE_MSK); | ||||
| 
 | ||||
| 		change = ((priv->_agn.statistics.general.common.temperature != | ||||
| 			   pkt->u.stats.general.common.temperature) || | ||||
| 			   ((priv->_agn.statistics.flag & | ||||
| 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | ||||
| 		   (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | ||||
| 
 | ||||
| 			   (pkt->u.stats.flag & | ||||
| 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | ||||
| #ifdef CONFIG_IWLWIFI_DEBUGFS | ||||
| 		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | ||||
| #endif | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_recover_from_statistics(priv, pkt); | ||||
| 
 | ||||
| 	if (priv->cfg->bt_statistics) | ||||
| 		memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | ||||
| 			sizeof(priv->_agn.statistics_bt)); | ||||
| 	else | ||||
| 		memcpy(&priv->_agn.statistics, &pkt->u.stats, | ||||
| 			sizeof(priv->_agn.statistics)); | ||||
| 
 | ||||
|  | @ -277,6 +338,12 @@ void iwl_reply_statistics(struct iwl_priv *priv, | |||
| 			sizeof(struct iwl_notif_statistics)); | ||||
| 		memset(&priv->_agn.max_delta, 0, | ||||
| 			sizeof(struct iwl_notif_statistics)); | ||||
| 		memset(&priv->_agn.accum_statistics_bt, 0, | ||||
| 			sizeof(struct iwl_bt_notif_statistics)); | ||||
| 		memset(&priv->_agn.delta_statistics_bt, 0, | ||||
| 			sizeof(struct iwl_bt_notif_statistics)); | ||||
| 		memset(&priv->_agn.max_delta_bt, 0, | ||||
| 			sizeof(struct iwl_bt_notif_statistics)); | ||||
| #endif | ||||
| 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | ||||
| 	} | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ | |||
|  * | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/init.h> | ||||
|  | @ -292,9 +294,7 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, | |||
| 					  struct ieee80211_hdr *hdr, | ||||
| 					  int left) | ||||
| { | ||||
| 	if (!iwl_is_associated(priv) || !priv->ibss_beacon || | ||||
| 	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && | ||||
| 	     (priv->iw_mode != NL80211_IFTYPE_AP))) | ||||
| 	if (!priv->ibss_beacon) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (priv->ibss_beacon->len > left) | ||||
|  | @ -1692,6 +1692,7 @@ static void iwl_nic_start(struct iwl_priv *priv) | |||
| 
 | ||||
| struct iwlagn_ucode_capabilities { | ||||
| 	u32 max_probe_length; | ||||
| 	u32 standard_phy_calibration_size; | ||||
| }; | ||||
| 
 | ||||
| static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||||
|  | @ -1827,7 +1828,6 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
| 	u32 tlv_len; | ||||
| 	enum iwl_ucode_tlv_type tlv_type; | ||||
| 	const u8 *tlv_data; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	if (len < sizeof(*ucode)) { | ||||
| 		IWL_ERR(priv, "uCode has invalid length: %zd\n", len); | ||||
|  | @ -1863,9 +1863,8 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
| 
 | ||||
| 	len -= sizeof(*ucode); | ||||
| 
 | ||||
| 	while (len >= sizeof(*tlv) && !ret) { | ||||
| 	while (len >= sizeof(*tlv)) { | ||||
| 		u16 tlv_alt; | ||||
| 		u32 fixed_tlv_size = 4; | ||||
| 
 | ||||
| 		len -= sizeof(*tlv); | ||||
| 		tlv = (void *)data; | ||||
|  | @ -1913,60 +1912,58 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
| 			pieces->boot_size = tlv_len; | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			capa->max_probe_length = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->init_evtlog_ptr = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->init_evtlog_size = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->init_errlog_ptr = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->inst_evtlog_ptr = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->inst_evtlog_size = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||||
| 			if (tlv_len != fixed_tlv_size) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			pieces->inst_errlog_ptr = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||||
| 			if (tlv_len) | ||||
| 				ret = -EINVAL; | ||||
| 			else | ||||
| 				goto invalid_tlv_len; | ||||
| 			priv->enhance_sensitivity_table = true; | ||||
| 			break; | ||||
| 		case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||||
| 			if (tlv_len != sizeof(u32)) | ||||
| 				goto invalid_tlv_len; | ||||
| 			capa->standard_phy_calibration_size = | ||||
| 					le32_to_cpup((__le32 *)tlv_data); | ||||
| 			break; | ||||
| 		default: | ||||
| 			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); | ||||
| 			break; | ||||
|  | @ -1976,14 +1973,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
| 	if (len) { | ||||
| 		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); | ||||
| 		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); | ||||
| 		ret = -EINVAL; | ||||
| 	} else if (ret) { | ||||
| 		IWL_ERR(priv, "TLV %d has invalid size: %u\n", | ||||
| 			tlv_type, tlv_len); | ||||
| 		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| 	return 0; | ||||
| 
 | ||||
|  invalid_tlv_len: | ||||
| 	IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||||
| 	iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); | ||||
| 
 | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -2005,6 +2004,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 	u32 build; | ||||
| 	struct iwlagn_ucode_capabilities ucode_capa = { | ||||
| 		.max_probe_length = 200, | ||||
| 		.standard_phy_calibration_size = | ||||
| 			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, | ||||
| 	}; | ||||
| 
 | ||||
| 	memset(&pieces, 0, sizeof(pieces)); | ||||
|  | @ -2226,6 +2227,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 			pieces.boot_size); | ||||
| 	memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * figure out the offset of chain noise reset and gain commands | ||||
| 	 * base on the size of standard phy calibration commands table size | ||||
| 	 */ | ||||
| 	if (ucode_capa.standard_phy_calibration_size > | ||||
| 	    IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||||
| 		ucode_capa.standard_phy_calibration_size = | ||||
| 			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||||
| 
 | ||||
| 	priv->_agn.phy_calib_chain_noise_reset_cmd = | ||||
| 		ucode_capa.standard_phy_calibration_size; | ||||
| 	priv->_agn.phy_calib_chain_noise_gain_cmd = | ||||
| 		ucode_capa.standard_phy_calibration_size + 1; | ||||
| 
 | ||||
| 	/**************************************************
 | ||||
| 	 * This is still part of probe() in a sense... | ||||
| 	 * | ||||
|  | @ -3008,9 +3023,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
| 	} | ||||
| 
 | ||||
| 	if (priv->start_calib) { | ||||
| 		iwl_chain_noise_calibration(priv, &priv->_agn.statistics); | ||||
| 
 | ||||
| 		iwl_sensitivity_calibration(priv, &priv->_agn.statistics); | ||||
| 		if (priv->cfg->bt_statistics) { | ||||
| 			iwl_chain_noise_calibration(priv, | ||||
| 					(void *)&priv->_agn.statistics_bt); | ||||
| 			iwl_sensitivity_calibration(priv, | ||||
| 					(void *)&priv->_agn.statistics_bt); | ||||
| 		} else { | ||||
| 			iwl_chain_noise_calibration(priv, | ||||
| 					(void *)&priv->_agn.statistics); | ||||
| 			iwl_sensitivity_calibration(priv, | ||||
| 					(void *)&priv->_agn.statistics); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	mutex_unlock(&priv->mutex); | ||||
|  | @ -3909,8 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 	struct ieee80211_hw *hw; | ||||
| 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | ||||
| 	unsigned long flags; | ||||
| 	u16 pci_cmd; | ||||
| 	u8 perm_addr[ETH_ALEN]; | ||||
| 	u16 pci_cmd, num_mac; | ||||
| 
 | ||||
| 	/************************
 | ||||
| 	 * 1. Allocating HW data | ||||
|  | @ -4028,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 		goto out_free_eeprom; | ||||
| 
 | ||||
| 	/* extract MAC Address */ | ||||
| 	iwl_eeprom_get_mac(priv, perm_addr); | ||||
| 	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr); | ||||
| 	SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr); | ||||
| 	iwl_eeprom_get_mac(priv, priv->addresses[0].addr); | ||||
| 	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); | ||||
| 	priv->hw->wiphy->addresses = priv->addresses; | ||||
| 	priv->hw->wiphy->n_addresses = 1; | ||||
| 	num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); | ||||
| 	if (num_mac > 1) { | ||||
| 		memcpy(priv->addresses[1].addr, priv->addresses[0].addr, | ||||
| 		       ETH_ALEN); | ||||
| 		priv->addresses[1].addr[5]++; | ||||
| 		priv->hw->wiphy->n_addresses++; | ||||
| 	} | ||||
| 
 | ||||
| 	/************************
 | ||||
| 	 * 5. Setup HW constants | ||||
|  | @ -4389,19 +4419,18 @@ static int __init iwl_init(void) | |||
| { | ||||
| 
 | ||||
| 	int ret; | ||||
| 	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||||
| 	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); | ||||
| 	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||||
| 	pr_info(DRV_COPYRIGHT "\n"); | ||||
| 
 | ||||
| 	ret = iwlagn_rate_control_register(); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR DRV_NAME | ||||
| 		       "Unable to register rate control algorithm: %d\n", ret); | ||||
| 		pr_err("Unable to register rate control algorithm: %d\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = pci_register_driver(&iwl_driver); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); | ||||
| 		pr_err("Unable to initialize PCI module\n"); | ||||
| 		goto error_register; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -66,10 +66,8 @@ | |||
| #include "iwl-core.h" | ||||
| #include "iwl-commands.h" | ||||
| 
 | ||||
| void iwl_chain_noise_calibration(struct iwl_priv *priv, | ||||
| 				struct iwl_notif_statistics *stat_resp); | ||||
| void iwl_sensitivity_calibration(struct iwl_priv *priv, | ||||
| 				struct iwl_notif_statistics *resp); | ||||
| void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); | ||||
| void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); | ||||
| 
 | ||||
| void iwl_init_sensitivity(struct iwl_priv *priv); | ||||
| void iwl_reset_run_time_calib(struct iwl_priv *priv); | ||||
|  |  | |||
|  | @ -964,8 +964,8 @@ struct iwl_qosparam_cmd { | |||
| #define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/ | ||||
| #define	IWL_INVALID_STATION 	255 | ||||
| 
 | ||||
| #define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2); | ||||
| #define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8); | ||||
| #define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2) | ||||
| #define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8) | ||||
| #define STA_FLG_RTS_MIMO_PROT_MSK	cpu_to_le32(1 << 17) | ||||
| #define STA_FLG_AGG_MPDU_8US_MSK	cpu_to_le32(1 << 18) | ||||
| #define STA_FLG_MAX_AGG_SIZE_POS	(19) | ||||
|  | @ -3127,6 +3127,13 @@ struct statistics_rx_non_phy { | |||
| 	__le32 beacon_energy_c; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_rx_non_phy_bt { | ||||
| 	struct statistics_rx_non_phy common; | ||||
| 	/* additional stats for bt */ | ||||
| 	__le32 num_bt_kills; | ||||
| 	__le32 reserved[2]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_rx { | ||||
| 	struct statistics_rx_phy ofdm; | ||||
| 	struct statistics_rx_phy cck; | ||||
|  | @ -3134,6 +3141,13 @@ struct statistics_rx { | |||
| 	struct statistics_rx_ht_phy ofdm_ht; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_rx_bt { | ||||
| 	struct statistics_rx_phy ofdm; | ||||
| 	struct statistics_rx_phy cck; | ||||
| 	struct statistics_rx_non_phy_bt general; | ||||
| 	struct statistics_rx_ht_phy ofdm_ht; | ||||
| } __packed; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct statistics_tx_power - current tx power | ||||
|  * | ||||
|  | @ -3196,7 +3210,7 @@ struct statistics_div { | |||
| 	__le32 reserved2; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_general { | ||||
| struct statistics_general_common { | ||||
| 	__le32 temperature;   /* radio temperature */ | ||||
| 	__le32 temperature_m; /* for 5000 and up, this is radio voltage */ | ||||
| 	struct statistics_dbg dbg; | ||||
|  | @ -3212,6 +3226,30 @@ struct statistics_general { | |||
| 	 *  in order to get out of bad PHY status | ||||
| 	 */ | ||||
| 	__le32 num_of_sos_states; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_bt_activity { | ||||
| 	/* Tx statistics */ | ||||
| 	__le32 hi_priority_tx_req_cnt; | ||||
| 	__le32 hi_priority_tx_denied_cnt; | ||||
| 	__le32 lo_priority_tx_req_cnt; | ||||
| 	__le32 lo_priority_tx_denied_cnt; | ||||
| 	/* Rx statistics */ | ||||
| 	__le32 hi_priority_rx_req_cnt; | ||||
| 	__le32 hi_priority_rx_denied_cnt; | ||||
| 	__le32 lo_priority_rx_req_cnt; | ||||
| 	__le32 lo_priority_rx_denied_cnt; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_general { | ||||
| 	struct statistics_general_common common; | ||||
| 	__le32 reserved2; | ||||
| 	__le32 reserved3; | ||||
| } __packed; | ||||
| 
 | ||||
| struct statistics_general_bt { | ||||
| 	struct statistics_general_common common; | ||||
| 	struct statistics_bt_activity activity; | ||||
| 	__le32 reserved2; | ||||
| 	__le32 reserved3; | ||||
| } __packed; | ||||
|  | @ -3273,6 +3311,12 @@ struct iwl_notif_statistics { | |||
| 	struct statistics_general general; | ||||
| } __packed; | ||||
| 
 | ||||
| struct iwl_bt_notif_statistics { | ||||
| 	__le32 flag; | ||||
| 	struct statistics_rx_bt rx; | ||||
| 	struct statistics_tx tx; | ||||
| 	struct statistics_general_bt general; | ||||
| } __packed; | ||||
| 
 | ||||
| /*
 | ||||
|  * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) | ||||
|  | @ -3616,10 +3660,10 @@ enum { | |||
| 	IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD	= 15, | ||||
| 	IWL_PHY_CALIBRATE_BASE_BAND_CMD		= 16, | ||||
| 	IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD	= 17, | ||||
| 	IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD	= 18, | ||||
| 	IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD	= 19, | ||||
| 	IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE	= 18, | ||||
| }; | ||||
| 
 | ||||
| #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE		(253) | ||||
| 
 | ||||
| #define IWL_CALIB_INIT_CFG_ALL	cpu_to_le32(0xffffffff) | ||||
| 
 | ||||
|  | @ -3944,6 +3988,7 @@ struct iwl_rx_packet { | |||
| 		struct iwl_sleep_notification sleep_notif; | ||||
| 		struct iwl_spectrum_resp spectrum; | ||||
| 		struct iwl_notif_statistics stats; | ||||
| 		struct iwl_bt_notif_statistics stats_bt; | ||||
| 		struct iwl_compressed_ba_resp compressed_ba; | ||||
| 		struct iwl_missed_beacon_notif missed_beacon; | ||||
| 		struct iwl_coex_medium_notification coex_medium_notif; | ||||
|  |  | |||
|  | @ -170,7 +170,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, | |||
| 	struct ieee80211_hw *hw = | ||||
| 		ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); | ||||
| 	if (hw == NULL) { | ||||
| 		printk(KERN_ERR "%s: Can not allocate network device\n", | ||||
| 		pr_err("%s: Can not allocate network device\n", | ||||
| 		       cfg->name); | ||||
| 		goto out; | ||||
| 	} | ||||
|  | @ -1748,6 +1748,37 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv) | |||
| 	iwlcore_commit_rxon(priv); | ||||
| } | ||||
| 
 | ||||
| static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||||
| { | ||||
| 	struct iwl_priv *priv = hw->priv; | ||||
| 	unsigned long flags; | ||||
| 	__le64 timestamp; | ||||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "enter\n"); | ||||
| 
 | ||||
| 	if (!iwl_is_ready_rf(priv)) { | ||||
| 		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 
 | ||||
| 	if (priv->ibss_beacon) | ||||
| 		dev_kfree_skb(priv->ibss_beacon); | ||||
| 
 | ||||
| 	priv->ibss_beacon = skb; | ||||
| 
 | ||||
| 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||||
| 	priv->timestamp = le64_to_cpu(timestamp); | ||||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "leave\n"); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
| 	priv->cfg->ops->lib->post_associate(priv, priv->vif); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void iwl_bss_info_changed(struct ieee80211_hw *hw, | ||||
| 			  struct ieee80211_vif *vif, | ||||
| 			  struct ieee80211_bss_conf *bss_conf, | ||||
|  | @ -1914,38 +1945,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
| } | ||||
| EXPORT_SYMBOL(iwl_bss_info_changed); | ||||
| 
 | ||||
| int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||||
| { | ||||
| 	struct iwl_priv *priv = hw->priv; | ||||
| 	unsigned long flags; | ||||
| 	__le64 timestamp; | ||||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "enter\n"); | ||||
| 
 | ||||
| 	if (!iwl_is_ready_rf(priv)) { | ||||
| 		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 
 | ||||
| 	if (priv->ibss_beacon) | ||||
| 		dev_kfree_skb(priv->ibss_beacon); | ||||
| 
 | ||||
| 	priv->ibss_beacon = skb; | ||||
| 
 | ||||
| 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||||
| 	priv->timestamp = le64_to_cpu(timestamp); | ||||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "leave\n"); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
| 	priv->cfg->ops->lib->post_associate(priv, priv->vif); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(iwl_mac_beacon_update); | ||||
| 
 | ||||
| static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) | ||||
| { | ||||
| 	iwl_connection_init_rx_config(priv, vif); | ||||
|  |  | |||
|  | @ -125,6 +125,8 @@ struct iwl_debugfs_ops { | |||
| 				 size_t count, loff_t *ppos); | ||||
| 	ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				      size_t count, loff_t *ppos); | ||||
| 	ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				 size_t count, loff_t *ppos); | ||||
| }; | ||||
| 
 | ||||
| struct iwl_temp_ops { | ||||
|  | @ -335,6 +337,7 @@ struct iwl_cfg { | |||
| 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | ||||
| 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; | ||||
| 	const bool need_dc_calib; | ||||
| 	const bool bt_statistics; | ||||
| }; | ||||
| 
 | ||||
| /***************************
 | ||||
|  | @ -377,7 +380,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
| 				     struct ieee80211_vif *vif, | ||||
| 				     struct ieee80211_bss_conf *bss_conf, | ||||
| 				     u32 changes); | ||||
| int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||||
| int iwl_commit_rxon(struct iwl_priv *priv); | ||||
| int iwl_mac_add_interface(struct ieee80211_hw *hw, | ||||
| 			  struct ieee80211_vif *vif); | ||||
|  |  | |||
|  | @ -1519,6 +1519,16 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | ||||
| 					char __user *user_buf, | ||||
| 					size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||||
| 
 | ||||
| 	return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file, | ||||
| 			user_buf, count, ppos); | ||||
| } | ||||
| 
 | ||||
| DEBUGFS_READ_FILE_OPS(rx_statistics); | ||||
| DEBUGFS_READ_FILE_OPS(tx_statistics); | ||||
| DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | ||||
|  | @ -1541,6 +1551,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(force_reset); | |||
| DEBUGFS_READ_FILE_OPS(rxon_flags); | ||||
| DEBUGFS_READ_FILE_OPS(rxon_filter_flags); | ||||
| DEBUGFS_WRITE_FILE_OPS(txfifo_flush); | ||||
| DEBUGFS_READ_FILE_OPS(ucode_bt_stats); | ||||
| 
 | ||||
| /*
 | ||||
|  * Create the debugfs files and directories | ||||
|  | @ -1608,6 +1619,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
| 		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | ||||
| 	if (priv->cfg->ucode_tracing) | ||||
| 		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | ||||
| 	if (priv->cfg->bt_statistics) | ||||
| 		DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); | ||||
| 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | ||||
| 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | ||||
| 	if (priv->cfg->sensitivity_calib_by_driver) | ||||
|  |  | |||
|  | @ -571,6 +571,7 @@ enum iwl_ucode_tlv_type { | |||
| 	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12, | ||||
| 	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13, | ||||
| 	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14, | ||||
| 	IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_ucode_tlv { | ||||
|  | @ -1153,6 +1154,9 @@ struct iwl_priv { | |||
| 	u32  hw_wa_rev; | ||||
| 	u8   rev_id; | ||||
| 
 | ||||
| 	/* EEPROM MAC addresses */ | ||||
| 	struct mac_address addresses[2]; | ||||
| 
 | ||||
| 	/* uCode images, save to reload in case of failure */ | ||||
| 	int fw_index;			/* firmware we're trying to load */ | ||||
| 	u32 ucode_ver;			/* version of ucode, copy of
 | ||||
|  | @ -1321,11 +1325,23 @@ struct iwl_priv { | |||
| 			u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||||
| 			u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * chain noise reset and gain commands are the | ||||
| 			 * two extra calibration commands follows the standard | ||||
| 			 * phy calibration commands | ||||
| 			 */ | ||||
| 			u8 phy_calib_chain_noise_reset_cmd; | ||||
| 			u8 phy_calib_chain_noise_gain_cmd; | ||||
| 
 | ||||
| 			struct iwl_notif_statistics statistics; | ||||
| 			struct iwl_bt_notif_statistics statistics_bt; | ||||
| #ifdef CONFIG_IWLWIFI_DEBUGFS | ||||
| 			struct iwl_notif_statistics accum_statistics; | ||||
| 			struct iwl_notif_statistics delta_statistics; | ||||
| 			struct iwl_notif_statistics max_delta; | ||||
| 			struct iwl_bt_notif_statistics accum_statistics_bt; | ||||
| 			struct iwl_bt_notif_statistics delta_statistics_bt; | ||||
| 			struct iwl_bt_notif_statistics max_delta_bt; | ||||
| #endif | ||||
| 		} _agn; | ||||
| #endif | ||||
|  |  | |||
|  | @ -402,6 +402,7 @@ struct iwl_eeprom_calib_info { | |||
| #define EEPROM_WOWLAN_MODE                  (2*0x47)	/* 2  bytes */ | ||||
| #define EEPROM_RADIO_CONFIG                 (2*0x48)	/* 2  bytes */ | ||||
| #define EEPROM_3945_M_VERSION               (2*0x4A)	/* 1  bytes */ | ||||
| #define EEPROM_NUM_MAC_ADDRESS              (2*0x4C)	/* 2  bytes */ | ||||
| 
 | ||||
| /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ | ||||
| #define EEPROM_RF_CFG_TYPE_MSK(x)   (x & 0x3)         /* bits 0-1   */ | ||||
|  |  | |||
|  | @ -429,10 +429,9 @@ void iwl_bg_scan_check(struct work_struct *data) | |||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_SCANNING, &priv->status) || | ||||
| 	    test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||||
| 		IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting " | ||||
| 			"adapter (%dms)\n", | ||||
| 	if (test_bit(STATUS_SCANNING, &priv->status) && | ||||
| 	    !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||||
| 		IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", | ||||
| 			       jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | ||||
| 
 | ||||
| 		if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
|  | @ -498,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work) | |||
| 	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	cancel_delayed_work(&priv->scan_check); | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 
 | ||||
| 	cancel_delayed_work_sync(&priv->scan_check); | ||||
| 	set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||||
| 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) | ||||
| 		iwl_send_scan_abort(priv); | ||||
| 
 | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| EXPORT_SYMBOL(iwl_bg_abort_scan); | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ | |||
|  * | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/init.h> | ||||
|  | @ -311,9 +313,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, | |||
| 				int left) | ||||
| { | ||||
| 
 | ||||
| 	if (!iwl_is_associated(priv) || !priv->ibss_beacon || | ||||
| 	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && | ||||
| 	     (priv->iw_mode != NL80211_IFTYPE_AP))) | ||||
| 	if (!iwl_is_associated(priv) || !priv->ibss_beacon) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (priv->ibss_beacon->len > left) | ||||
|  | @ -2883,7 +2883,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | ||||
| 
 | ||||
| 		spin_lock_irqsave(&priv->lock, flags); | ||||
| 		interval = vif ? vif->bss_conf.beacon_int : 0; | ||||
| 		if (priv->is_internal_short_scan) | ||||
| 			interval = 0; | ||||
| 		else | ||||
| 			interval = vif->bss_conf.beacon_int; | ||||
| 		spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
| 		scan->suspend_time = 0; | ||||
|  | @ -3932,7 +3935,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
| 	 *   space for this driver's private structure */ | ||||
| 	hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); | ||||
| 	if (hw == NULL) { | ||||
| 		printk(KERN_ERR DRV_NAME "Can not allocate network device\n"); | ||||
| 		pr_err("Can not allocate network device\n"); | ||||
| 		err = -ENOMEM; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | @ -4224,19 +4227,18 @@ static int __init iwl3945_init(void) | |||
| { | ||||
| 
 | ||||
| 	int ret; | ||||
| 	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||||
| 	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); | ||||
| 	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||||
| 	pr_info(DRV_COPYRIGHT "\n"); | ||||
| 
 | ||||
| 	ret = iwl3945_rate_control_register(); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR DRV_NAME | ||||
| 		       "Unable to register rate control algorithm: %d\n", ret); | ||||
| 		pr_err("Unable to register rate control algorithm: %d\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = pci_register_driver(&iwl3945_driver); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); | ||||
| 		pr_err("Unable to initialize PCI module\n"); | ||||
| 		goto error_register; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,7 +7,6 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <linux/slab.h> | ||||
| #include <linux/if_arp.h> | ||||
| #include <linux/ieee80211.h> | ||||
| #include <net/cfg80211.h> | ||||
| #include <asm/unaligned.h> | ||||
|  | @ -1383,93 +1382,10 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
|  * Monitor mode | ||||
|  */ | ||||
| 
 | ||||
| /* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we
 | ||||
|  * get rid of WEXT, this should go into host.h */ | ||||
| struct cmd_monitor_mode { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le16 mode; | ||||
| } __packed; | ||||
| 
 | ||||
| static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode) | ||||
| { | ||||
| 	struct cmd_monitor_mode cmd; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CFG80211); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * cmd       98 00 | ||||
| 	 * size      0c 00 | ||||
| 	 * sequence  xx xx | ||||
| 	 * result    00 00 | ||||
| 	 * action    01 00    ACT_SET | ||||
| 	 * enable    01 00 | ||||
| 	 */ | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_SET); | ||||
| 	cmd.mode = cpu_to_le16(mode); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); | ||||
| 
 | ||||
| 	if (ret == 0) | ||||
| 		priv->dev->type = ARPHRD_IEEE80211_RADIOTAP; | ||||
| 	else | ||||
| 		priv->dev->type = ARPHRD_ETHER; | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CFG80211); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
|  * Get station | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Returns the signal or 0 in case of an error. | ||||
|  */ | ||||
| 
 | ||||
| /* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid
 | ||||
|  * of WEXT, this should go into host.h */ | ||||
| struct cmd_rssi { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 n_or_snr; | ||||
| 	__le16 nf; | ||||
| 	__le16 avg_snr; | ||||
| 	__le16 avg_nf; | ||||
| } __packed; | ||||
| 
 | ||||
| static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise) | ||||
| { | ||||
| 	struct cmd_rssi cmd; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); | ||||
| 
 | ||||
| 	if (ret == 0) { | ||||
| 		*signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), | ||||
| 				le16_to_cpu(cmd.nf)); | ||||
| 		*noise  = CAL_NF(le16_to_cpu(cmd.nf)); | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | ||||
| 			      u8 *mac, struct station_info *sinfo) | ||||
| { | ||||
|  | @ -1490,7 +1406,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
| 	sinfo->rx_packets = priv->dev->stats.rx_packets; | ||||
| 
 | ||||
| 	/* Get current RSSI */ | ||||
| 	ret = lbs_get_signal(priv, &signal, &noise); | ||||
| 	ret = lbs_get_rssi(priv, &signal, &noise); | ||||
| 	if (ret == 0) { | ||||
| 		sinfo->signal = signal; | ||||
| 		sinfo->filled |= STATION_INFO_SIGNAL; | ||||
|  | @ -1530,7 +1446,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, | |||
| 	survey->channel = ieee80211_get_channel(wiphy, | ||||
| 		ieee80211_channel_to_frequency(priv->channel)); | ||||
| 
 | ||||
| 	ret = lbs_get_signal(priv, &signal, &noise); | ||||
| 	ret = lbs_get_rssi(priv, &signal, &noise); | ||||
| 	if (ret == 0) { | ||||
| 		survey->filled = SURVEY_INFO_NOISE_DBM; | ||||
| 		survey->noise = noise; | ||||
|  | @ -1558,17 +1474,17 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, | |||
| 
 | ||||
| 	switch (type) { | ||||
| 	case NL80211_IFTYPE_MONITOR: | ||||
| 		ret = lbs_enable_monitor_mode(priv, 1); | ||||
| 		ret = lbs_set_monitor_mode(priv, 1); | ||||
| 		break; | ||||
| 	case NL80211_IFTYPE_STATION: | ||||
| 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) | ||||
| 			ret = lbs_enable_monitor_mode(priv, 0); | ||||
| 			ret = lbs_set_monitor_mode(priv, 0); | ||||
| 		if (!ret) | ||||
| 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); | ||||
| 		break; | ||||
| 	case NL80211_IFTYPE_ADHOC: | ||||
| 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) | ||||
| 			ret = lbs_enable_monitor_mode(priv, 0); | ||||
| 			ret = lbs_set_monitor_mode(priv, 0); | ||||
| 		if (!ret) | ||||
| 			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); | ||||
| 		break; | ||||
|  | @ -2063,113 +1979,20 @@ int lbs_cfg_register(struct lbs_private *priv) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function sets DOMAIN INFO to FW | ||||
|  *  @param priv       pointer to struct lbs_private | ||||
|  *  @return          0; -1 | ||||
| */ | ||||
| static int lbs_11d_set_domain_info(struct lbs_private *priv) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, | ||||
| 			CMD_ACT_SET, | ||||
| 			CMD_OPTION_WAITFORRSP, 0, NULL); | ||||
| 	if (ret) | ||||
| 		lbs_deb_11d("fail to dnld domain info\n"); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy, | ||||
| 					struct regulatory_request *request) | ||||
| { | ||||
| 	u8   no_of_triplet = 0; | ||||
| 	u8   no_of_parsed_chan = 0; | ||||
| 	u8   first_channel = 0, next_chan = 0, max_pwr = 0; | ||||
| 	u8   i, flag = 0; | ||||
| 	enum ieee80211_band band; | ||||
| 	struct ieee80211_supported_band *sband; | ||||
| 	struct ieee80211_channel *ch; | ||||
| 	struct lbs_private *priv = wiphy_priv(wiphy); | ||||
| 	struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CFG80211); | ||||
| 
 | ||||
| 	/* Set country code */ | ||||
| 	domain_info->country_code[0] = request->alpha2[0]; | ||||
| 	domain_info->country_code[1] = request->alpha2[1]; | ||||
| 	domain_info->country_code[2] = ' '; | ||||
| 
 | ||||
| 	for (band = 0; band < IEEE80211_NUM_BANDS ; band++) { | ||||
| 
 | ||||
| 		if (!wiphy->bands[band]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		sband = wiphy->bands[band]; | ||||
| 
 | ||||
| 		for (i = 0; i < sband->n_channels ; i++) { | ||||
| 			ch = &sband->channels[i]; | ||||
| 			if (ch->flags & IEEE80211_CHAN_DISABLED) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (!flag) { | ||||
| 				flag = 1; | ||||
| 				next_chan = first_channel = (u32) ch->hw_value; | ||||
| 				max_pwr = ch->max_power; | ||||
| 				no_of_parsed_chan = 1; | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			if (ch->hw_value == next_chan + 1 && | ||||
| 					ch->max_power == max_pwr) { | ||||
| 				next_chan++; | ||||
| 				no_of_parsed_chan++; | ||||
| 			} else { | ||||
| 				domain_info->triplet[no_of_triplet] | ||||
| 					.chans.first_channel = first_channel; | ||||
| 				domain_info->triplet[no_of_triplet] | ||||
| 					.chans.num_channels = no_of_parsed_chan; | ||||
| 				domain_info->triplet[no_of_triplet] | ||||
| 					.chans.max_power = max_pwr; | ||||
| 				no_of_triplet++; | ||||
| 				flag = 0; | ||||
| 			} | ||||
| 		} | ||||
| 		if (flag) { | ||||
| 			domain_info->triplet[no_of_triplet] | ||||
| 				.chans.first_channel = first_channel; | ||||
| 			domain_info->triplet[no_of_triplet] | ||||
| 				.chans.num_channels = no_of_parsed_chan; | ||||
| 			domain_info->triplet[no_of_triplet] | ||||
| 				.chans.max_power = max_pwr; | ||||
| 			no_of_triplet++; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	domain_info->no_triplet = no_of_triplet; | ||||
| 
 | ||||
| 	/* Set domain info */ | ||||
| 	ret = lbs_11d_set_domain_info(priv); | ||||
| 	if (ret) | ||||
| 		lbs_pr_err("11D: error setting domain info in FW\n"); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CFG80211); | ||||
| } | ||||
| 
 | ||||
| int lbs_reg_notifier(struct wiphy *wiphy, | ||||
| 		struct regulatory_request *request) | ||||
| { | ||||
| 	struct lbs_private *priv = wiphy_priv(wiphy); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " | ||||
| 			"callback for domain %c%c\n", request->alpha2[0], | ||||
| 			request->alpha2[1]); | ||||
| 
 | ||||
| 	lbs_send_domain_info_cmd_fw(wiphy, request); | ||||
| 	ret = lbs_set_11d_domain_info(priv, request, wiphy->bands); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CFG80211); | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void lbs_scan_deinit(struct lbs_private *priv) | ||||
|  |  | |||
|  | @ -13,12 +13,6 @@ void lbs_cfg_free(struct lbs_private *priv); | |||
| int lbs_reg_notifier(struct wiphy *wiphy, | ||||
| 		struct regulatory_request *request); | ||||
| 
 | ||||
| /* All of those are TODOs: */ | ||||
| #define lbs_cmd_802_11_rssi(priv, cmdptr) (0) | ||||
| #define lbs_ret_802_11_rssi(priv, resp) (0) | ||||
| #define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0) | ||||
| #define lbs_ret_802_11_bcn_ctrl(priv, resp) (0) | ||||
| 
 | ||||
| void lbs_send_disconnect_notification(struct lbs_private *priv); | ||||
| void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,13 +6,14 @@ | |||
| #include <linux/kfifo.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/if_arp.h> | ||||
| 
 | ||||
| #include "decl.h" | ||||
| #include "cfg.h" | ||||
| #include "cmd.h" | ||||
| 
 | ||||
| 
 | ||||
| static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); | ||||
| #define CAL_NF(nf)		((s32)(-(s32)(nf))) | ||||
| #define CAL_RSSI(snr, nf)	((s32)((s32)(snr) + CAL_NF(nf))) | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Simple callback that copies response back into command | ||||
|  | @ -73,30 +74,6 @@ static u8 is_command_allowed_in_ps(u16 cmd) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function checks if the command is allowed. | ||||
|  * | ||||
|  *  @param priv         A pointer to lbs_private structure | ||||
|  *  @return             allowed or not allowed. | ||||
|  */ | ||||
| 
 | ||||
| static int lbs_is_cmd_allowed(struct lbs_private *priv) | ||||
| { | ||||
| 	int ret = 1; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	if (!priv->is_auto_deep_sleep_enabled) { | ||||
| 		if (priv->is_deep_sleep) { | ||||
| 			lbs_deb_cmd("command not allowed in deep sleep\n"); | ||||
| 			ret = 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Updates the hardware details like MAC address and regulatory region | ||||
|  * | ||||
|  | @ -227,42 +204,49 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | |||
| } | ||||
| EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); | ||||
| 
 | ||||
| static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd, | ||||
| 				   u16 cmd_action) | ||||
| /**
 | ||||
|  *  @brief Sets the Power Save mode | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param cmd_action	The Power Save operation (PS_MODE_ACTION_ENTER_PS or | ||||
|  *                         PS_MODE_ACTION_EXIT_PS) | ||||
|  *  @param block	Whether to block on a response or not | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) | ||||
| { | ||||
| 	struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; | ||||
| 	struct cmd_ds_802_11_ps_mode cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	cmd->command = cpu_to_le16(CMD_802_11_PS_MODE); | ||||
| 	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + | ||||
| 				sizeof(struct cmd_header)); | ||||
| 	psm->action = cpu_to_le16(cmd_action); | ||||
| 	psm->multipledtim = 0; | ||||
| 	switch (cmd_action) { | ||||
| 	case CMD_SUBCMD_ENTER_PS: | ||||
| 		lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(cmd_action); | ||||
| 
 | ||||
| 		psm->locallisteninterval = 0; | ||||
| 		psm->nullpktinterval = 0; | ||||
| 		psm->multipledtim = | ||||
| 		    cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_SUBCMD_EXIT_PS: | ||||
| 		lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_SUBCMD_SLEEP_CONFIRMED: | ||||
| 		lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		break; | ||||
| 	if (cmd_action == PS_MODE_ACTION_ENTER_PS) { | ||||
| 		lbs_deb_cmd("PS_MODE: action ENTER_PS\n"); | ||||
| 		cmd.multipledtim = cpu_to_le16(1);  /* Default DTIM multiple */ | ||||
| 	} else if (cmd_action == PS_MODE_ACTION_EXIT_PS) { | ||||
| 		lbs_deb_cmd("PS_MODE: action EXIT_PS\n"); | ||||
| 	} else { | ||||
| 		/* We don't handle CONFIRM_SLEEP here because it needs to
 | ||||
| 		 * be fastpathed to the firmware. | ||||
| 		 */ | ||||
| 		lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action); | ||||
| 		ret = -EOPNOTSUPP; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	return 0; | ||||
| 	if (block) | ||||
| 		ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd); | ||||
| 	else | ||||
| 		lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd)); | ||||
| 
 | ||||
| out: | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, | ||||
|  | @ -576,23 +560,35 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, | ||||
| 				      u16 cmd_action, void *pdata_buf) | ||||
| /**
 | ||||
|  *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW) | ||||
|  * | ||||
|  *  @param priv        A pointer to struct lbs_private structure | ||||
|  *  @param enable      1 to enable monitor mode, 0 to disable | ||||
|  * | ||||
|  *  @return            0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_monitor_mode(struct lbs_private *priv, int enable) | ||||
| { | ||||
| 	struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; | ||||
| 	struct cmd_ds_802_11_monitor_mode cmd; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE); | ||||
| 	cmd->size = | ||||
| 	    cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) + | ||||
| 			     sizeof(struct cmd_header)); | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_SET); | ||||
| 	if (enable) | ||||
| 		cmd.mode = cpu_to_le16(0x1); | ||||
| 
 | ||||
| 	monitor->action = cpu_to_le16(cmd_action); | ||||
| 	if (cmd_action == CMD_ACT_SET) { | ||||
| 		monitor->mode = | ||||
| 		    cpu_to_le16((u16) (*(u32 *) pdata_buf)); | ||||
| 	lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); | ||||
| 	if (ret == 0) { | ||||
| 		priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP : | ||||
| 						ARPHRD_ETHER; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -677,78 +673,242 @@ out: | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, | ||||
| 			       u8 cmd_action, void *pdata_buf) | ||||
| /**
 | ||||
|  *  @brief Get current RSSI and noise floor | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @param rssi		On successful return, signal level in mBm | ||||
|  * | ||||
|  *  @return 	   	The channel on success, error on failure | ||||
|  */ | ||||
| int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | ||||
| { | ||||
| 	struct lbs_offset_value *offval; | ||||
| 	struct cmd_ds_802_11_rssi cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	offval = (struct lbs_offset_value *)pdata_buf; | ||||
| 	BUG_ON(rssi == NULL); | ||||
| 	BUG_ON(nf == NULL); | ||||
| 
 | ||||
| 	switch (le16_to_cpu(cmdptr->command)) { | ||||
| 	case CMD_MAC_REG_ACCESS: | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	/* Average SNR over last 8 beacons */ | ||||
| 	cmd.n_or_snr = cpu_to_le16(8); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); | ||||
| 	if (ret == 0) { | ||||
| 		*nf = CAL_NF(le16_to_cpu(cmd.nf)); | ||||
| 		*rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf)); | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Send regulatory and 802.11d domain information to the firmware | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param request	cfg80211 regulatory request structure | ||||
|  *  @param bands	the device's supported bands and channels | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
| */ | ||||
| int lbs_set_11d_domain_info(struct lbs_private *priv, | ||||
| 			    struct regulatory_request *request, | ||||
| 			    struct ieee80211_supported_band **bands) | ||||
| { | ||||
| 			struct cmd_ds_mac_reg_access *macreg; | ||||
| 	struct cmd_ds_802_11d_domain_info cmd; | ||||
| 	struct mrvl_ie_domain_param_set *domain = &cmd.domain; | ||||
| 	struct ieee80211_country_ie_triplet *t; | ||||
| 	enum ieee80211_band band; | ||||
| 	struct ieee80211_channel *ch; | ||||
| 	u8 num_triplet = 0; | ||||
| 	u8 num_parsed_chan = 0; | ||||
| 	u8 first_channel = 0, next_chan = 0, max_pwr = 0; | ||||
| 	u8 i, flag = 0; | ||||
| 	size_t triplet_size; | ||||
| 	int ret; | ||||
| 
 | ||||
| 			cmdptr->size = | ||||
| 			    cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access) | ||||
| 					+ sizeof(struct cmd_header)); | ||||
| 			macreg = | ||||
| 			    (struct cmd_ds_mac_reg_access *)&cmdptr->params. | ||||
| 			    macreg; | ||||
| 	lbs_deb_enter(LBS_DEB_11D); | ||||
| 
 | ||||
| 			macreg->action = cpu_to_le16(cmd_action); | ||||
| 			macreg->offset = cpu_to_le16((u16) offval->offset); | ||||
| 			macreg->value = cpu_to_le32(offval->value); | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_SET); | ||||
| 
 | ||||
| 			break; | ||||
| 	lbs_deb_11d("Setting country code '%c%c'\n", | ||||
| 		    request->alpha2[0], request->alpha2[1]); | ||||
| 
 | ||||
| 	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); | ||||
| 
 | ||||
| 	/* Set country code */ | ||||
| 	domain->country_code[0] = request->alpha2[0]; | ||||
| 	domain->country_code[1] = request->alpha2[1]; | ||||
| 	domain->country_code[2] = ' '; | ||||
| 
 | ||||
| 	/* Now set up the channel triplets; firmware is somewhat picky here
 | ||||
| 	 * and doesn't validate channel numbers and spans; hence it would | ||||
| 	 * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39.  Since | ||||
| 	 * the last 3 aren't valid channels, the driver is responsible for | ||||
| 	 * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20) | ||||
| 	 * etc. | ||||
| 	 */ | ||||
| 	for (band = 0; | ||||
| 	     (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS); | ||||
| 	     band++) { | ||||
| 
 | ||||
| 		if (!bands[band]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		for (i = 0; | ||||
| 		     (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS); | ||||
| 		     i++) { | ||||
| 			ch = &bands[band]->channels[i]; | ||||
| 			if (ch->flags & IEEE80211_CHAN_DISABLED) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (!flag) { | ||||
| 				flag = 1; | ||||
| 				next_chan = first_channel = (u32) ch->hw_value; | ||||
| 				max_pwr = ch->max_power; | ||||
| 				num_parsed_chan = 1; | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 	case CMD_BBP_REG_ACCESS: | ||||
| 			if ((ch->hw_value == next_chan + 1) && | ||||
| 					(ch->max_power == max_pwr)) { | ||||
| 				/* Consolidate adjacent channels */ | ||||
| 				next_chan++; | ||||
| 				num_parsed_chan++; | ||||
| 			} else { | ||||
| 				/* Add this triplet */ | ||||
| 				lbs_deb_11d("11D triplet (%d, %d, %d)\n", | ||||
| 					first_channel, num_parsed_chan, | ||||
| 					max_pwr); | ||||
| 				t = &domain->triplet[num_triplet]; | ||||
| 				t->chans.first_channel = first_channel; | ||||
| 				t->chans.num_channels = num_parsed_chan; | ||||
| 				t->chans.max_power = max_pwr; | ||||
| 				num_triplet++; | ||||
| 				flag = 0; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (flag) { | ||||
| 			/* Add last triplet */ | ||||
| 			lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel, | ||||
| 				num_parsed_chan, max_pwr); | ||||
| 			t = &domain->triplet[num_triplet]; | ||||
| 			t->chans.first_channel = first_channel; | ||||
| 			t->chans.num_channels = num_parsed_chan; | ||||
| 			t->chans.max_power = max_pwr; | ||||
| 			num_triplet++; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_11d("# triplets %d\n", num_triplet); | ||||
| 
 | ||||
| 	/* Set command header sizes */ | ||||
| 	triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet); | ||||
| 	domain->header.len = cpu_to_le16(sizeof(domain->country_code) + | ||||
| 					triplet_size); | ||||
| 
 | ||||
| 	lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set", | ||||
| 			(u8 *) &cmd.domain.country_code, | ||||
| 			le16_to_cpu(domain->header.len)); | ||||
| 
 | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) + | ||||
| 				   sizeof(cmd.action) + | ||||
| 				   sizeof(cmd.domain.header) + | ||||
| 				   sizeof(cmd.domain.country_code) + | ||||
| 				   triplet_size); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Read a MAC, Baseband, or RF register | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param cmd		register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @param offset       byte offset of the register to get | ||||
|  *  @param value        on success, the value of the register at 'offset' | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
| */ | ||||
| int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) | ||||
| { | ||||
| 			struct cmd_ds_bbp_reg_access *bbpreg; | ||||
| 	struct cmd_ds_reg_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 			cmdptr->size = | ||||
| 			    cpu_to_le16(sizeof | ||||
| 					     (struct cmd_ds_bbp_reg_access) | ||||
| 					     + sizeof(struct cmd_header)); | ||||
| 			bbpreg = | ||||
| 			    (struct cmd_ds_bbp_reg_access *)&cmdptr->params. | ||||
| 			    bbpreg; | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 			bbpreg->action = cpu_to_le16(cmd_action); | ||||
| 			bbpreg->offset = cpu_to_le16((u16) offval->offset); | ||||
| 			bbpreg->value = (u8) offval->value; | ||||
| 	BUG_ON(value == NULL); | ||||
| 
 | ||||
| 			break; | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_GET); | ||||
| 
 | ||||
| 	if (reg != CMD_MAC_REG_ACCESS && | ||||
| 	    reg != CMD_BBP_REG_ACCESS && | ||||
| 	    reg != CMD_RF_REG_ACCESS) { | ||||
| 		ret = -EINVAL; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	case CMD_RF_REG_ACCESS: | ||||
| 	ret = lbs_cmd_with_response(priv, reg, &cmd); | ||||
| 	if (ret) { | ||||
| 		if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) | ||||
| 			*value = cmd.value.bbp_rf; | ||||
| 		else if (reg == CMD_MAC_REG_ACCESS) | ||||
| 			*value = le32_to_cpu(cmd.value.mac); | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Write a MAC, Baseband, or RF register | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param cmd		register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @param offset       byte offset of the register to set | ||||
|  *  @param value        the value to write to the register at 'offset' | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
| */ | ||||
| int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) | ||||
| { | ||||
| 			struct cmd_ds_rf_reg_access *rfreg; | ||||
| 	struct cmd_ds_reg_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 			cmdptr->size = | ||||
| 			    cpu_to_le16(sizeof | ||||
| 					     (struct cmd_ds_rf_reg_access) + | ||||
| 					     sizeof(struct cmd_header)); | ||||
| 			rfreg = | ||||
| 			    (struct cmd_ds_rf_reg_access *)&cmdptr->params. | ||||
| 			    rfreg; | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 			rfreg->action = cpu_to_le16(cmd_action); | ||||
| 			rfreg->offset = cpu_to_le16((u16) offval->offset); | ||||
| 			rfreg->value = (u8) offval->value; | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_SET); | ||||
| 
 | ||||
| 			break; | ||||
| 	if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) | ||||
| 		cmd.value.bbp_rf = (u8) (value & 0xFF); | ||||
| 	else if (reg == CMD_MAC_REG_ACCESS) | ||||
| 		cmd.value.mac = cpu_to_le32(value); | ||||
| 	else { | ||||
| 		ret = -EINVAL; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	ret = lbs_cmd_with_response(priv, reg, &cmd); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	return 0; | ||||
| out: | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void lbs_queue_cmd(struct lbs_private *priv, | ||||
|  | @ -771,16 +931,15 @@ static void lbs_queue_cmd(struct lbs_private *priv, | |||
| 
 | ||||
| 	/* Exit_PS command needs to be queued in the header always. */ | ||||
| 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { | ||||
| 		struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1]; | ||||
| 		struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf; | ||||
| 
 | ||||
| 		if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { | ||||
| 		if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { | ||||
| 			if (priv->psstate != PS_STATE_FULL_POWER) | ||||
| 				addtail = 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (le16_to_cpu(cmdnode->cmdbuf->command) == | ||||
| 			CMD_802_11_WAKEUP_CONFIRM) | ||||
| 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) | ||||
| 		addtail = 0; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
|  | @ -815,7 +974,6 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
| 
 | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 	priv->cur_cmd = cmdnode; | ||||
| 	priv->cur_cmd_retcode = 0; | ||||
| 	spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 
 | ||||
| 	cmdsize = le16_to_cpu(cmd->size); | ||||
|  | @ -888,9 +1046,6 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, | |||
| void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, | ||||
| 			  int result) | ||||
| { | ||||
| 	if (cmd == priv->cur_cmd) | ||||
| 		priv->cur_cmd_retcode = result; | ||||
| 
 | ||||
| 	cmd->result = result; | ||||
| 	cmd->cmdwaitqwoken = 1; | ||||
| 	wake_up_interruptible(&cmd->cmdwait_q); | ||||
|  | @ -957,240 +1112,6 @@ void lbs_set_mac_control(struct lbs_private *priv) | |||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function implements command CMD_802_11D_DOMAIN_INFO | ||||
|  *  @param priv       pointer to struct lbs_private | ||||
|  *  @param cmd        pointer to cmd buffer | ||||
|  *  @param cmdno      cmd ID | ||||
|  *  @param cmdOption  cmd action | ||||
|  *  @return           0 | ||||
| */ | ||||
| int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, | ||||
| 				 struct cmd_ds_command *cmd, | ||||
| 				 u16 cmdoption) | ||||
| { | ||||
| 	struct cmd_ds_802_11d_domain_info *pdomaininfo = | ||||
| 	    &cmd->params.domaininfo; | ||||
| 	struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain; | ||||
| 	u8 nr_triplet = priv->domain_reg.no_triplet; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_11D); | ||||
| 
 | ||||
| 	lbs_deb_11d("nr_triplet=%x\n", nr_triplet); | ||||
| 
 | ||||
| 	pdomaininfo->action = cpu_to_le16(cmdoption); | ||||
| 	if (cmdoption == CMD_ACT_GET) { | ||||
| 		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + | ||||
| 					sizeof(struct cmd_header)); | ||||
| 		lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, | ||||
| 			le16_to_cpu(cmd->size)); | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); | ||||
| 	memcpy(domain->countrycode, priv->domain_reg.country_code, | ||||
| 	       sizeof(domain->countrycode)); | ||||
| 
 | ||||
| 	domain->header.len = cpu_to_le16(nr_triplet | ||||
| 				* sizeof(struct ieee80211_country_ie_triplet) | ||||
| 				+ sizeof(domain->countrycode)); | ||||
| 
 | ||||
| 	if (nr_triplet) { | ||||
| 		memcpy(domain->triplet, priv->domain_reg.triplet, | ||||
| 				nr_triplet * | ||||
| 				sizeof(struct ieee80211_country_ie_triplet)); | ||||
| 
 | ||||
| 		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + | ||||
| 					     le16_to_cpu(domain->header.len) + | ||||
| 					     sizeof(struct mrvl_ie_header) + | ||||
| 					     sizeof(struct cmd_header)); | ||||
| 	} else { | ||||
| 		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + | ||||
| 					sizeof(struct cmd_header)); | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, | ||||
| 			le16_to_cpu(cmd->size)); | ||||
| 
 | ||||
| done: | ||||
| 	lbs_deb_enter(LBS_DEB_11D); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function prepare the command before send to firmware. | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @param cmd_no	command number | ||||
|  *  @param cmd_action	command action: GET or SET | ||||
|  *  @param wait_option	wait option: wait response or not | ||||
|  *  @param cmd_oid	cmd oid: treated as sub command | ||||
|  *  @param pdata_buf	A pointer to informaion buffer | ||||
|  *  @return 		0 or -1 | ||||
|  */ | ||||
| int lbs_prepare_and_send_command(struct lbs_private *priv, | ||||
| 			  u16 cmd_no, | ||||
| 			  u16 cmd_action, | ||||
| 			  u16 wait_option, u32 cmd_oid, void *pdata_buf) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct cmd_ctrl_node *cmdnode; | ||||
| 	struct cmd_ds_command *cmdptr; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_HOST); | ||||
| 
 | ||||
| 	if (!priv) { | ||||
| 		lbs_deb_host("PREP_CMD: priv is NULL\n"); | ||||
| 		ret = -1; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	if (priv->surpriseremoved) { | ||||
| 		lbs_deb_host("PREP_CMD: card removed\n"); | ||||
| 		ret = -1; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!lbs_is_cmd_allowed(priv)) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	cmdnode = lbs_get_cmd_ctrl_node(priv); | ||||
| 
 | ||||
| 	if (cmdnode == NULL) { | ||||
| 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); | ||||
| 
 | ||||
| 		/* Wake up main thread to execute next command */ | ||||
| 		wake_up_interruptible(&priv->waitq); | ||||
| 		ret = -1; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	cmdnode->callback = NULL; | ||||
| 	cmdnode->callback_arg = (unsigned long)pdata_buf; | ||||
| 
 | ||||
| 	cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; | ||||
| 
 | ||||
| 	lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); | ||||
| 
 | ||||
| 	/* Set sequence number, command and INT option */ | ||||
| 	priv->seqnum++; | ||||
| 	cmdptr->seqnum = cpu_to_le16(priv->seqnum); | ||||
| 
 | ||||
| 	cmdptr->command = cpu_to_le16(cmd_no); | ||||
| 	cmdptr->result = 0; | ||||
| 
 | ||||
| 	switch (cmd_no) { | ||||
| 	case CMD_802_11_PS_MODE: | ||||
| 		ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_MAC_REG_ACCESS: | ||||
| 	case CMD_BBP_REG_ACCESS: | ||||
| 	case CMD_RF_REG_ACCESS: | ||||
| 		ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_802_11_MONITOR_MODE: | ||||
| 		ret = lbs_cmd_802_11_monitor_mode(cmdptr, | ||||
| 				          cmd_action, pdata_buf); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_802_11_RSSI: | ||||
| 		ret = lbs_cmd_802_11_rssi(priv, cmdptr); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_802_11_SET_AFC: | ||||
| 	case CMD_802_11_GET_AFC: | ||||
| 
 | ||||
| 		cmdptr->command = cpu_to_le16(cmd_no); | ||||
| 		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) + | ||||
| 					   sizeof(struct cmd_header)); | ||||
| 
 | ||||
| 		memmove(&cmdptr->params.afc, | ||||
| 			pdata_buf, sizeof(struct cmd_ds_802_11_afc)); | ||||
| 
 | ||||
| 		ret = 0; | ||||
| 		goto done; | ||||
| 
 | ||||
| 	case CMD_802_11D_DOMAIN_INFO: | ||||
| 		cmdptr->command = cpu_to_le16(cmd_no); | ||||
| 		ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_802_11_TPC_CFG: | ||||
| 		cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); | ||||
| 		cmdptr->size = | ||||
| 		    cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) + | ||||
| 				     sizeof(struct cmd_header)); | ||||
| 
 | ||||
| 		memmove(&cmdptr->params.tpccfg, | ||||
| 			pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg)); | ||||
| 
 | ||||
| 		ret = 0; | ||||
| 		break; | ||||
| 
 | ||||
| #ifdef CONFIG_LIBERTAS_MESH | ||||
| 
 | ||||
| 	case CMD_BT_ACCESS: | ||||
| 		ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_FWT_ACCESS: | ||||
| 		ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); | ||||
| 		break; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 	case CMD_802_11_BEACON_CTRL: | ||||
| 		ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); | ||||
| 		break; | ||||
| 	case CMD_802_11_DEEP_SLEEP: | ||||
| 		cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP); | ||||
| 		cmdptr->size = cpu_to_le16(sizeof(struct cmd_header)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no); | ||||
| 		ret = -1; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* return error, since the command preparation failed */ | ||||
| 	if (ret != 0) { | ||||
| 		lbs_deb_host("PREP_CMD: command preparation failed\n"); | ||||
| 		lbs_cleanup_and_insert_cmd(priv, cmdnode); | ||||
| 		ret = -1; | ||||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	cmdnode->cmdwaitqwoken = 0; | ||||
| 
 | ||||
| 	lbs_queue_cmd(priv, cmdnode); | ||||
| 	wake_up_interruptible(&priv->waitq); | ||||
| 
 | ||||
| 	if (wait_option & CMD_OPTION_WAITFORRSP) { | ||||
| 		lbs_deb_host("PREP_CMD: wait for response\n"); | ||||
| 		might_sleep(); | ||||
| 		wait_event_interruptible(cmdnode->cmdwait_q, | ||||
| 					 cmdnode->cmdwaitqwoken); | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 	if (priv->cur_cmd_retcode) { | ||||
| 		lbs_deb_host("PREP_CMD: command failed with return code %d\n", | ||||
| 		       priv->cur_cmd_retcode); | ||||
| 		priv->cur_cmd_retcode = 0; | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 	spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 
 | ||||
| done: | ||||
| 	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function allocates the command buffer and link | ||||
|  *  it to command free queue. | ||||
|  | @ -1284,7 +1205,7 @@ done: | |||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL | ||||
|  */ | ||||
| static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) | ||||
| static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) | ||||
| { | ||||
| 	struct cmd_ctrl_node *tempnode; | ||||
| 	unsigned long flags; | ||||
|  | @ -1367,10 +1288,10 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
| 			/*
 | ||||
| 			 * 1. Non-PS command: | ||||
| 			 * Queue it. set needtowakeup to TRUE if current state | ||||
| 			 * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS. | ||||
| 			 * 2. PS command but not Exit_PS: | ||||
| 			 * is SLEEP, otherwise call send EXIT_PS. | ||||
| 			 * 2. PS command but not EXIT_PS: | ||||
| 			 * Ignore it. | ||||
| 			 * 3. PS command Exit_PS: | ||||
| 			 * 3. PS command EXIT_PS: | ||||
| 			 * Set needtowakeup to TRUE if current state is SLEEP, | ||||
| 			 * otherwise send this command down to firmware | ||||
| 			 * immediately. | ||||
|  | @ -1384,8 +1305,11 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
| 					/* w/ new scheme, it will not reach here.
 | ||||
| 					   since it is blocked in main_thread. */ | ||||
| 					priv->needtowakeup = 1; | ||||
| 				} else | ||||
| 					lbs_ps_wakeup(priv, 0); | ||||
| 				} else { | ||||
| 					lbs_set_ps_mode(priv, | ||||
| 							PS_MODE_ACTION_EXIT_PS, | ||||
| 							false); | ||||
| 				} | ||||
| 
 | ||||
| 				ret = 0; | ||||
| 				goto done; | ||||
|  | @ -1400,7 +1324,7 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
| 				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", | ||||
| 				       psm->action); | ||||
| 				if (psm->action != | ||||
| 				    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { | ||||
| 				    cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { | ||||
| 					lbs_deb_host( | ||||
| 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); | ||||
| 					list_del(&cmdnode->list); | ||||
|  | @ -1460,13 +1384,16 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
| 					lbs_deb_host( | ||||
| 					       "EXEC_NEXT_CMD: WPA enabled and GTK_SET" | ||||
| 					       " go back to PS_SLEEP"); | ||||
| 					lbs_ps_sleep(priv, 0); | ||||
| 					lbs_set_ps_mode(priv, | ||||
| 							PS_MODE_ACTION_ENTER_PS, | ||||
| 							false); | ||||
| 				} | ||||
| 			} else { | ||||
| 				lbs_deb_host( | ||||
| 				       "EXEC_NEXT_CMD: cmdpendingq empty, " | ||||
| 				       "go back to PS_SLEEP"); | ||||
| 				lbs_ps_sleep(priv, 0); | ||||
| 				lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, | ||||
| 						false); | ||||
| 			} | ||||
| 		} | ||||
| #endif | ||||
|  | @ -1514,43 +1441,6 @@ out: | |||
| 	lbs_deb_leave(LBS_DEB_HOST); | ||||
| } | ||||
| 
 | ||||
| void lbs_ps_sleep(struct lbs_private *priv, int wait_option) | ||||
| { | ||||
| 	lbs_deb_enter(LBS_DEB_HOST); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * PS is currently supported only in Infrastructure mode | ||||
| 	 * Remove this check if it is to be supported in IBSS mode also | ||||
| 	 */ | ||||
| 
 | ||||
| 	lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, | ||||
| 			      CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_HOST); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function sends Exit_PS command to firmware. | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param wait_option	wait response or not | ||||
|  *  @return 	   	n/a | ||||
|  */ | ||||
| void lbs_ps_wakeup(struct lbs_private *priv, int wait_option) | ||||
| { | ||||
| 	__le32 Localpsmode; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_HOST); | ||||
| 
 | ||||
| 	Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM); | ||||
| 
 | ||||
| 	lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, | ||||
| 			      CMD_SUBCMD_EXIT_PS, | ||||
| 			      wait_option, 0, &Localpsmode); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_HOST); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function checks condition and prepares to | ||||
|  *  send sleep confirm command to firmware if ok. | ||||
|  | @ -1675,12 +1565,18 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, | |||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!lbs_is_cmd_allowed(priv)) { | ||||
| 	/* No commands are allowed in Deep Sleep until we toggle the GPIO
 | ||||
| 	 * to wake up the card and it has signaled that it's ready. | ||||
| 	 */ | ||||
| 	if (!priv->is_auto_deep_sleep_enabled) { | ||||
| 		if (priv->is_deep_sleep) { | ||||
| 			lbs_deb_cmd("command not allowed in deep sleep\n"); | ||||
| 			cmdnode = ERR_PTR(-EBUSY); | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	cmdnode = lbs_get_cmd_ctrl_node(priv); | ||||
| 	cmdnode = lbs_get_free_cmd_node(priv); | ||||
| 	if (cmdnode == NULL) { | ||||
| 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ | |||
| #ifndef _LBS_CMD_H_ | ||||
| #define _LBS_CMD_H_ | ||||
| 
 | ||||
| #include <net/cfg80211.h> | ||||
| 
 | ||||
| #include "host.h" | ||||
| #include "dev.h" | ||||
| 
 | ||||
|  | @ -37,11 +39,6 @@ struct cmd_ctrl_node { | |||
| #define lbs_cmd_with_response(priv, cmdnr, cmd)	\ | ||||
| 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd)) | ||||
| 
 | ||||
| int lbs_prepare_and_send_command(struct lbs_private *priv, | ||||
| 	u16 cmd_no, | ||||
| 	u16 cmd_action, | ||||
| 	u16 wait_option, u32 cmd_oid, void *pdata_buf); | ||||
| 
 | ||||
| void lbs_cmd_async(struct lbs_private *priv, uint16_t command, | ||||
| 	struct cmd_header *in_cmd, int in_cmd_size); | ||||
| 
 | ||||
|  | @ -92,10 +89,6 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | |||
| int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, | ||||
| 				struct sleep_params *sp); | ||||
| 
 | ||||
| void lbs_ps_sleep(struct lbs_private *priv, int wait_option); | ||||
| 
 | ||||
| void lbs_ps_wakeup(struct lbs_private *priv, int wait_option); | ||||
| 
 | ||||
| void lbs_ps_confirm_sleep(struct lbs_private *priv); | ||||
| 
 | ||||
| int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on); | ||||
|  | @ -129,4 +122,18 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep); | |||
| 
 | ||||
| int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep); | ||||
| 
 | ||||
| int lbs_set_monitor_mode(struct lbs_private *priv, int enable); | ||||
| 
 | ||||
| int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf); | ||||
| 
 | ||||
| int lbs_set_11d_domain_info(struct lbs_private *priv, | ||||
| 			    struct regulatory_request *request, | ||||
| 			    struct ieee80211_supported_band **bands); | ||||
| 
 | ||||
| int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value); | ||||
| 
 | ||||
| int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value); | ||||
| 
 | ||||
| int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block); | ||||
| 
 | ||||
| #endif /* _LBS_CMD_H */ | ||||
|  |  | |||
|  | @ -49,171 +49,11 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) | |||
| 	if (priv->psstate != PS_STATE_FULL_POWER) { | ||||
| 		/* make firmware to exit PS mode */ | ||||
| 		lbs_deb_cmd("disconnected, so exit PS mode\n"); | ||||
| 		lbs_ps_wakeup(priv, 0); | ||||
| 		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); | ||||
| 	} | ||||
| 	lbs_deb_leave(LBS_DEB_ASSOC); | ||||
| } | ||||
| 
 | ||||
| static int lbs_ret_reg_access(struct lbs_private *priv, | ||||
| 			       u16 type, struct cmd_ds_command *resp) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	switch (type) { | ||||
| 	case CMD_RET(CMD_MAC_REG_ACCESS): | ||||
| 		{ | ||||
| 			struct cmd_ds_mac_reg_access *reg = &resp->params.macreg; | ||||
| 
 | ||||
| 			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); | ||||
| 			priv->offsetvalue.value = le32_to_cpu(reg->value); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 	case CMD_RET(CMD_BBP_REG_ACCESS): | ||||
| 		{ | ||||
| 			struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg; | ||||
| 
 | ||||
| 			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); | ||||
| 			priv->offsetvalue.value = reg->value; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 	case CMD_RET(CMD_RF_REG_ACCESS): | ||||
| 		{ | ||||
| 			struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg; | ||||
| 
 | ||||
| 			priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); | ||||
| 			priv->offsetvalue.value = reg->value; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 	default: | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function parses countryinfo from AP and download country info to FW | ||||
|  *  @param priv    pointer to struct lbs_private | ||||
|  *  @param resp    pointer to command response buffer | ||||
|  *  @return        0; -1 | ||||
|  */ | ||||
| static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) | ||||
| { | ||||
| 	struct cmd_ds_802_11d_domain_info *domaininfo = | ||||
| 			&resp->params.domaininforesp; | ||||
| 	struct mrvl_ie_domain_param_set *domain = &domaininfo->domain; | ||||
| 	u16 action = le16_to_cpu(domaininfo->action); | ||||
| 	s16 ret = 0; | ||||
| 	u8 nr_triplet = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_11D); | ||||
| 
 | ||||
| 	lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp, | ||||
| 			(int)le16_to_cpu(resp->size)); | ||||
| 
 | ||||
| 	nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / | ||||
| 		sizeof(struct ieee80211_country_ie_triplet); | ||||
| 
 | ||||
| 	lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet); | ||||
| 
 | ||||
| 	if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) { | ||||
| 		lbs_deb_11d("invalid number of triplets returned!!\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	switch (action) { | ||||
| 	case CMD_ACT_SET:	/*Proc set action */ | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_ACT_GET: | ||||
| 		break; | ||||
| 	default: | ||||
| 		lbs_deb_11d("invalid action:%d\n", domaininfo->action); | ||||
| 		ret = -1; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static inline int handle_cmd_response(struct lbs_private *priv, | ||||
| 				      struct cmd_header *cmd_response) | ||||
| { | ||||
| 	struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response; | ||||
| 	int ret = 0; | ||||
| 	unsigned long flags; | ||||
| 	uint16_t respcmd = le16_to_cpu(resp->command); | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_HOST); | ||||
| 
 | ||||
| 	switch (respcmd) { | ||||
| 	case CMD_RET(CMD_MAC_REG_ACCESS): | ||||
| 	case CMD_RET(CMD_BBP_REG_ACCESS): | ||||
| 	case CMD_RET(CMD_RF_REG_ACCESS): | ||||
| 		ret = lbs_ret_reg_access(priv, respcmd, resp); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_802_11_SET_AFC): | ||||
| 	case CMD_RET(CMD_802_11_GET_AFC): | ||||
| 		spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc, | ||||
| 			sizeof(struct cmd_ds_802_11_afc)); | ||||
| 		spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 
 | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_802_11_BEACON_STOP): | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_802_11_RSSI): | ||||
| 		ret = lbs_ret_802_11_rssi(priv, resp); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_802_11D_DOMAIN_INFO): | ||||
| 		ret = lbs_ret_802_11d_domain_info(resp); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_802_11_TPC_CFG): | ||||
| 		spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, | ||||
| 			sizeof(struct cmd_ds_802_11_tpc_cfg)); | ||||
| 		spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 		break; | ||||
| 
 | ||||
| 	case CMD_RET(CMD_BT_ACCESS): | ||||
| 		spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 		if (priv->cur_cmd->callback_arg) | ||||
| 			memcpy((void *)priv->cur_cmd->callback_arg, | ||||
| 			       &resp->params.bt.addr1, 2 * ETH_ALEN); | ||||
| 		spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 		break; | ||||
| 	case CMD_RET(CMD_FWT_ACCESS): | ||||
| 		spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 		if (priv->cur_cmd->callback_arg) | ||||
| 			memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt, | ||||
| 			       sizeof(resp->params.fwt)); | ||||
| 		spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 		break; | ||||
| 	case CMD_RET(CMD_802_11_BEACON_CTRL): | ||||
| 		ret = lbs_ret_802_11_bcn_ctrl(priv, resp); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n", | ||||
| 			   le16_to_cpu(resp->command)); | ||||
| 		break; | ||||
| 	} | ||||
| 	lbs_deb_leave(LBS_DEB_HOST); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | ||||
| { | ||||
| 	uint16_t respcmd, curcmd; | ||||
|  | @ -272,9 +112,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | |||
| 	del_timer(&priv->command_timer); | ||||
| 	priv->cmd_timed_out = 0; | ||||
| 
 | ||||
| 	/* Store the response code to cur_cmd_retcode. */ | ||||
| 	priv->cur_cmd_retcode = result; | ||||
| 
 | ||||
| 	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { | ||||
| 		struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1]; | ||||
| 		u16 action = le16_to_cpu(psmode->action); | ||||
|  | @ -292,9 +129,9 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | |||
| 			 * lbs_execute_next_command(). | ||||
| 			 */ | ||||
| 			if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR && | ||||
| 			    action == CMD_SUBCMD_ENTER_PS) | ||||
| 			    action == PS_MODE_ACTION_ENTER_PS) | ||||
| 				priv->psmode = LBS802_11POWERMODECAM; | ||||
| 		} else if (action == CMD_SUBCMD_ENTER_PS) { | ||||
| 		} else if (action == PS_MODE_ACTION_ENTER_PS) { | ||||
| 			priv->needtowakeup = 0; | ||||
| 			priv->psstate = PS_STATE_AWAKE; | ||||
| 
 | ||||
|  | @ -309,11 +146,12 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | |||
| 
 | ||||
| 				spin_unlock_irqrestore(&priv->driver_lock, flags); | ||||
| 				mutex_unlock(&priv->lock); | ||||
| 				lbs_ps_wakeup(priv, 0); | ||||
| 				lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, | ||||
| 						false); | ||||
| 				mutex_lock(&priv->lock); | ||||
| 				spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 			} | ||||
| 		} else if (action == CMD_SUBCMD_EXIT_PS) { | ||||
| 		} else if (action == PS_MODE_ACTION_EXIT_PS) { | ||||
| 			priv->needtowakeup = 0; | ||||
| 			priv->psstate = PS_STATE_FULL_POWER; | ||||
| 			lbs_deb_host("CMD_RESP: EXIT_PS command response\n"); | ||||
|  | @ -354,8 +192,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | |||
| 	if (priv->cur_cmd && priv->cur_cmd->callback) { | ||||
| 		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, | ||||
| 				resp); | ||||
| 	} else | ||||
| 		ret = handle_cmd_response(priv, resp); | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->driver_lock, flags); | ||||
| 
 | ||||
|  | @ -452,7 +289,7 @@ int lbs_process_event(struct lbs_private *priv, u32 event) | |||
| 			 * in lbs_ps_wakeup() | ||||
| 			 */ | ||||
| 			lbs_deb_cmd("waking up ...\n"); | ||||
| 			lbs_ps_wakeup(priv, 0); | ||||
| 			lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
|  |  | |||
|  | @ -446,30 +446,24 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, | ||||
| 				  size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	ssize_t pos = 0; | ||||
| 	int ret; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	u32 val = 0; | ||||
| 
 | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	offval.offset = priv->mac_offset; | ||||
| 	offval.value = 0; | ||||
| 
 | ||||
| 	ret = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_MAC_REG_ACCESS, 0, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val); | ||||
| 	mdelay(10); | ||||
| 	if (!ret) { | ||||
| 		pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n", | ||||
| 				priv->mac_offset, priv->offsetvalue.value); | ||||
| 
 | ||||
| 		pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n", | ||||
| 				priv->mac_offset, val); | ||||
| 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | ||||
| 	} | ||||
| 	free_page(addr); | ||||
|  | @ -507,7 +501,6 @@ static ssize_t lbs_wrmac_write(struct file *file, | |||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	ssize_t res, buf_size; | ||||
| 	u32 offset, value; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	if (!buf) | ||||
|  | @ -524,11 +517,7 @@ static ssize_t lbs_wrmac_write(struct file *file, | |||
| 		goto out_unlock; | ||||
| 	} | ||||
| 
 | ||||
| 	offval.offset = offset; | ||||
| 	offval.value = value; | ||||
| 	res = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_MAC_REG_ACCESS, 1, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value); | ||||
| 	mdelay(10); | ||||
| 
 | ||||
| 	if (!res) | ||||
|  | @ -542,25 +531,20 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf, | |||
| 				  size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	ssize_t pos = 0; | ||||
| 	int ret; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	offval.offset = priv->bbp_offset; | ||||
| 	offval.value = 0; | ||||
| 
 | ||||
| 	ret = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_BBP_REG_ACCESS, 0, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val); | ||||
| 	mdelay(10); | ||||
| 	if (!ret) { | ||||
| 		pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n", | ||||
| 				priv->bbp_offset, priv->offsetvalue.value); | ||||
| 
 | ||||
| 		pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n", | ||||
| 				priv->bbp_offset, val); | ||||
| 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | ||||
| 	} | ||||
| 	free_page(addr); | ||||
|  | @ -599,7 +583,6 @@ static ssize_t lbs_wrbbp_write(struct file *file, | |||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	ssize_t res, buf_size; | ||||
| 	u32 offset, value; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	if (!buf) | ||||
|  | @ -616,11 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file, | |||
| 		goto out_unlock; | ||||
| 	} | ||||
| 
 | ||||
| 	offval.offset = offset; | ||||
| 	offval.value = value; | ||||
| 	res = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_BBP_REG_ACCESS, 1, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value); | ||||
| 	mdelay(10); | ||||
| 
 | ||||
| 	if (!res) | ||||
|  | @ -634,25 +613,20 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf, | |||
| 				  size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	ssize_t pos = 0; | ||||
| 	int ret; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	offval.offset = priv->rf_offset; | ||||
| 	offval.value = 0; | ||||
| 
 | ||||
| 	ret = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_RF_REG_ACCESS, 0, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val); | ||||
| 	mdelay(10); | ||||
| 	if (!ret) { | ||||
| 		pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n", | ||||
| 				priv->rf_offset, priv->offsetvalue.value); | ||||
| 
 | ||||
| 		pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n", | ||||
| 				priv->rf_offset, val); | ||||
| 		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | ||||
| 	} | ||||
| 	free_page(addr); | ||||
|  | @ -691,7 +665,6 @@ static ssize_t lbs_wrrf_write(struct file *file, | |||
| 	struct lbs_private *priv = file->private_data; | ||||
| 	ssize_t res, buf_size; | ||||
| 	u32 offset, value; | ||||
| 	struct lbs_offset_value offval; | ||||
| 	unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||||
| 	char *buf = (char *)addr; | ||||
| 	if (!buf) | ||||
|  | @ -708,11 +681,7 @@ static ssize_t lbs_wrrf_write(struct file *file, | |||
| 		goto out_unlock; | ||||
| 	} | ||||
| 
 | ||||
| 	offval.offset = offset; | ||||
| 	offval.value = value; | ||||
| 	res = lbs_prepare_and_send_command(priv, | ||||
| 				CMD_RF_REG_ACCESS, 1, | ||||
| 				CMD_OPTION_WAITFORRSP, 0, &offval); | ||||
| 	res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value); | ||||
| 	mdelay(10); | ||||
| 
 | ||||
| 	if (!res) | ||||
|  |  | |||
|  | @ -53,9 +53,4 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv); | |||
| u32 lbs_fw_index_to_data_rate(u8 index); | ||||
| u8 lbs_data_rate_to_fw_index(u32 rate); | ||||
| 
 | ||||
| int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, | ||||
| 		struct cmd_ds_command *cmd, u16 cmdoption); | ||||
| 
 | ||||
| int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -172,11 +172,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| #define MRVDRV_MAX_BSS_DESCRIPTS		16 | ||||
| #define MRVDRV_MAX_REGION_CODE			6 | ||||
| 
 | ||||
| #define MRVDRV_IGNORE_MULTIPLE_DTIM		0xfffe | ||||
| #define MRVDRV_MIN_MULTIPLE_DTIM		1 | ||||
| #define MRVDRV_MAX_MULTIPLE_DTIM		5 | ||||
| #define MRVDRV_DEFAULT_MULTIPLE_DTIM		1 | ||||
| 
 | ||||
| #define MRVDRV_DEFAULT_LISTEN_INTERVAL		10 | ||||
| 
 | ||||
| #define	MRVDRV_CHANNELS_PER_SCAN		4 | ||||
|  | @ -301,19 +296,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| #define	BAND_G			(0x02) | ||||
| #define ALL_802_11_BANDS	(BAND_B | BAND_G) | ||||
| 
 | ||||
| /** MACRO DEFINITIONS */ | ||||
| #define CAL_NF(NF)			((s32)(-(s32)(NF))) | ||||
| #define CAL_RSSI(SNR, NF) 		((s32)((s32)(SNR) + CAL_NF(NF))) | ||||
| #define SCAN_RSSI(RSSI)			(0x100 - ((u8)(RSSI))) | ||||
| 
 | ||||
| #define DEFAULT_BCN_AVG_FACTOR		8 | ||||
| #define DEFAULT_DATA_AVG_FACTOR		8 | ||||
| #define AVG_SCALE			100 | ||||
| #define CAL_AVG_SNR_NF(AVG, SNRNF, N)         \ | ||||
|                         (((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \ | ||||
|                         ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ | ||||
|                         AVG_SCALE))  / N)) | ||||
| 
 | ||||
| #define MAX_RATES			14 | ||||
| 
 | ||||
| #define	MAX_LEDS			8 | ||||
|  |  | |||
|  | @ -60,14 +60,10 @@ struct lbs_private { | |||
| 	struct dentry *regs_dir; | ||||
| 	struct dentry *debugfs_regs_files[6]; | ||||
| 
 | ||||
| 	/** 11D and domain regulatory data */ | ||||
| 	struct lbs_802_11d_domain_reg domain_reg; | ||||
| 
 | ||||
| 	/* Hardware debugging */ | ||||
| 	u32 mac_offset; | ||||
| 	u32 bbp_offset; | ||||
| 	u32 rf_offset; | ||||
| 	struct lbs_offset_value offsetvalue; | ||||
| 
 | ||||
| 	/* Power management */ | ||||
| 	u16 psmode; | ||||
|  | @ -115,12 +111,10 @@ struct lbs_private { | |||
| 	struct cmd_ctrl_node *cur_cmd; | ||||
| 	struct list_head cmdfreeq;    /* free command buffers */ | ||||
| 	struct list_head cmdpendingq; /* pending command buffers */ | ||||
| 	wait_queue_head_t cmd_pending; | ||||
| 	struct timer_list command_timer; | ||||
| 	int cmd_timed_out; | ||||
| 
 | ||||
| 	/* Command responses sent from the hardware to the driver */ | ||||
| 	int cur_cmd_retcode; | ||||
| 	u8 resp_idx; | ||||
| 	u8 resp_buf[2][LBS_UPLD_SIZE]; | ||||
| 	u32 resp_len[2]; | ||||
|  |  | |||
|  | @ -94,11 +94,9 @@ | |||
| #define CMD_802_11_BEACON_CTRL                  0x00b0 | ||||
| 
 | ||||
| /* For the IEEE Power Save */ | ||||
| #define CMD_SUBCMD_ENTER_PS                     0x0030 | ||||
| #define CMD_SUBCMD_EXIT_PS                      0x0031 | ||||
| #define CMD_SUBCMD_SLEEP_CONFIRMED              0x0034 | ||||
| #define CMD_SUBCMD_FULL_POWERDOWN               0x0035 | ||||
| #define CMD_SUBCMD_FULL_POWERUP                 0x0036 | ||||
| #define PS_MODE_ACTION_ENTER_PS                 0x0030 | ||||
| #define PS_MODE_ACTION_EXIT_PS                  0x0031 | ||||
| #define PS_MODE_ACTION_SLEEP_CONFIRMED          0x0034 | ||||
| 
 | ||||
| #define CMD_ENABLE_RSN                          0x0001 | ||||
| #define CMD_DISABLE_RSN                         0x0000 | ||||
|  | @ -163,11 +161,6 @@ | |||
| #define CMD_ACT_SET_TX_FIX_RATE                 0x0001 | ||||
| #define CMD_ACT_GET_TX_RATE                     0x0002 | ||||
| 
 | ||||
| /* Define action or option for CMD_802_11_PS_MODE */ | ||||
| #define CMD_TYPE_CAM                            0x0000 | ||||
| #define CMD_TYPE_MAX_PSP                        0x0001 | ||||
| #define CMD_TYPE_FAST_PSP                       0x0002 | ||||
| 
 | ||||
| /* Options for CMD_802_11_FW_WAKE_METHOD */ | ||||
| #define CMD_WAKE_METHOD_UNCHANGED               0x0000 | ||||
| #define CMD_WAKE_METHOD_COMMAND_INT             0x0001 | ||||
|  | @ -389,30 +382,22 @@ struct lbs_offset_value { | |||
| 	u32 value; | ||||
| } __packed; | ||||
| 
 | ||||
| #define MRVDRV_MAX_TRIPLET_802_11D              83 | ||||
| 
 | ||||
| #define COUNTRY_CODE_LEN                        3 | ||||
| #define MAX_11D_TRIPLETS	83 | ||||
| 
 | ||||
| struct mrvl_ie_domain_param_set { | ||||
| 	struct mrvl_ie_header header; | ||||
| 
 | ||||
| 	u8 countrycode[COUNTRY_CODE_LEN]; | ||||
| 	struct ieee80211_country_ie_triplet triplet[1]; | ||||
| 	u8 country_code[3]; | ||||
| 	struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11d_domain_info { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	struct mrvl_ie_domain_param_set domain; | ||||
| } __packed; | ||||
| 
 | ||||
| struct lbs_802_11d_domain_reg { | ||||
| 	/** Country code*/ | ||||
| 	u8 country_code[COUNTRY_CODE_LEN]; | ||||
| 	/** No. of triplet*/ | ||||
| 	u8 no_triplet; | ||||
| 	struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D]; | ||||
| } __packed; | ||||
| 
 | ||||
| /*
 | ||||
|  * Define data structure for CMD_GET_HW_SPEC | ||||
|  * This structure defines the response for the GET_HW_SPEC command | ||||
|  | @ -575,24 +560,15 @@ struct cmd_ds_802_11_snmp_mib { | |||
| 	u8 value[128]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_mac_reg_access { | ||||
| 	__le16 action; | ||||
| 	__le16 offset; | ||||
| 	__le32 value; | ||||
| } __packed; | ||||
| struct cmd_ds_reg_access { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| struct cmd_ds_bbp_reg_access { | ||||
| 	__le16 action; | ||||
| 	__le16 offset; | ||||
| 	u8 value; | ||||
| 	u8 reserved[3]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_rf_reg_access { | ||||
| 	__le16 action; | ||||
| 	__le16 offset; | ||||
| 	u8 value; | ||||
| 	u8 reserved[3]; | ||||
| 	union { | ||||
| 		u8 bbp_rf;  /* for BBP and RF registers */ | ||||
| 		__le32 mac; /* for MAC registers */ | ||||
| 	} value; | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11_radio_control { | ||||
|  | @ -603,6 +579,8 @@ struct cmd_ds_802_11_radio_control { | |||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11_beacon_control { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le16 beacon_enable; | ||||
| 	__le16 beacon_period; | ||||
|  | @ -644,19 +622,19 @@ struct cmd_ds_802_11_rf_channel { | |||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11_rssi { | ||||
| 	/* weighting factor */ | ||||
| 	__le16 N; | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 reserved_0; | ||||
| 	__le16 reserved_1; | ||||
| 	__le16 reserved_2; | ||||
| } __packed; | ||||
| 	/* request:  number of beacons (N) to average the SNR and NF over
 | ||||
| 	 * response: SNR of most recent beacon | ||||
| 	 */ | ||||
| 	__le16 n_or_snr; | ||||
| 
 | ||||
| struct cmd_ds_802_11_rssi_rsp { | ||||
| 	__le16 SNR; | ||||
| 	__le16 noisefloor; | ||||
| 	__le16 avgSNR; | ||||
| 	__le16 avgnoisefloor; | ||||
| 	/* The following fields are only set in the response.
 | ||||
| 	 * In the request these are reserved and should be set to 0. | ||||
| 	 */ | ||||
| 	__le16 nf;       /* most recent beacon noise floor */ | ||||
| 	__le16 avg_snr;  /* average SNR weighted by N from request */ | ||||
| 	__le16 avg_nf;   /* average noise floor weighted by N from request */ | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11_mac_address { | ||||
|  | @ -675,7 +653,10 @@ struct cmd_ds_802_11_rf_tx_power { | |||
| 	s8 minlevel; | ||||
| } __packed; | ||||
| 
 | ||||
| /* MONITOR_MODE only exists in OLPC v5 firmware */ | ||||
| struct cmd_ds_802_11_monitor_mode { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le16 mode; | ||||
| } __packed; | ||||
|  | @ -695,11 +676,35 @@ struct cmd_ds_802_11_fw_wake_method { | |||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_802_11_ps_mode { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 
 | ||||
| 	/* Interval for keepalive in PS mode:
 | ||||
| 	 * 0x0000 = don't change | ||||
| 	 * 0x001E = firmware default | ||||
| 	 * 0xFFFF = disable | ||||
| 	 */ | ||||
| 	__le16 nullpktinterval; | ||||
| 
 | ||||
| 	/* Number of DTIM intervals to wake up for:
 | ||||
| 	 * 0 = don't change | ||||
| 	 * 1 = firmware default | ||||
| 	 * 5 = max | ||||
| 	 */ | ||||
| 	__le16 multipledtim; | ||||
| 
 | ||||
| 	__le16 reserved; | ||||
| 	__le16 locallisteninterval; | ||||
| 
 | ||||
| 	/* AdHoc awake period (FW v9+ only):
 | ||||
| 	 * 0 = don't change | ||||
| 	 * 1 = always awake (IEEE standard behavior) | ||||
| 	 * 2 - 31 = sleep for (n - 1) periods and awake for 1 period | ||||
| 	 * 32 - 254 = invalid | ||||
| 	 * 255 = sleep at each ATIM | ||||
| 	 */ | ||||
| 	__le16 adhoc_awake_period; | ||||
| } __packed; | ||||
| 
 | ||||
| struct cmd_confirm_sleep { | ||||
|  | @ -882,12 +887,17 @@ struct cmd_ds_802_11_pa_cfg { | |||
| 
 | ||||
| 
 | ||||
| struct cmd_ds_802_11_led_ctrl { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le16 numled; | ||||
| 	u8 data[256]; | ||||
| } __packed; | ||||
| 
 | ||||
| /* Automatic Frequency Control */ | ||||
| struct cmd_ds_802_11_afc { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 afc_auto; | ||||
| 	union { | ||||
| 		struct { | ||||
|  | @ -910,6 +920,8 @@ struct cmd_ds_get_tsf { | |||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_bt_access { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le32 id; | ||||
| 	u8 addr1[ETH_ALEN]; | ||||
|  | @ -917,6 +929,8 @@ struct cmd_ds_bt_access { | |||
| } __packed; | ||||
| 
 | ||||
| struct cmd_ds_fwt_access { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	__le16 action; | ||||
| 	__le32 id; | ||||
| 	u8 valid; | ||||
|  | @ -955,34 +969,4 @@ struct cmd_ds_mesh_access { | |||
| 
 | ||||
| /* Number of stats counters returned by the firmware */ | ||||
| #define MESH_STATS_NUM 8 | ||||
| 
 | ||||
| struct cmd_ds_command { | ||||
| 	/* command header */ | ||||
| 	__le16 command; | ||||
| 	__le16 size; | ||||
| 	__le16 seqnum; | ||||
| 	__le16 result; | ||||
| 
 | ||||
| 	/* command Body */ | ||||
| 	union { | ||||
| 		struct cmd_ds_802_11_ps_mode psmode; | ||||
| 		struct cmd_ds_802_11_monitor_mode monitor; | ||||
| 		struct cmd_ds_802_11_rssi rssi; | ||||
| 		struct cmd_ds_802_11_rssi_rsp rssirsp; | ||||
| 		struct cmd_ds_mac_reg_access macreg; | ||||
| 		struct cmd_ds_bbp_reg_access bbpreg; | ||||
| 		struct cmd_ds_rf_reg_access rfreg; | ||||
| 
 | ||||
| 		struct cmd_ds_802_11d_domain_info domaininfo; | ||||
| 		struct cmd_ds_802_11d_domain_info domaininforesp; | ||||
| 
 | ||||
| 		struct cmd_ds_802_11_tpc_cfg tpccfg; | ||||
| 		struct cmd_ds_802_11_afc afc; | ||||
| 		struct cmd_ds_802_11_led_ctrl ledgpio; | ||||
| 
 | ||||
| 		struct cmd_ds_bt_access bt; | ||||
| 		struct cmd_ds_fwt_access fwt; | ||||
| 		struct cmd_ds_802_11_beacon_control bcn_ctrl; | ||||
| 	} params; | ||||
| } __packed; | ||||
| #endif | ||||
|  |  | |||
|  | @ -433,7 +433,7 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | |||
| 
 | ||||
| static int if_usb_reset_device(struct if_usb_card *cardp) | ||||
| { | ||||
| 	struct cmd_ds_command *cmd = cardp->ep_out_buf + 4; | ||||
| 	struct cmd_header *cmd = cardp->ep_out_buf + 4; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_USB); | ||||
|  | @ -441,7 +441,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
| 	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); | ||||
| 
 | ||||
| 	cmd->command = cpu_to_le16(CMD_802_11_RESET); | ||||
| 	cmd->size = cpu_to_le16(sizeof(struct cmd_header)); | ||||
| 	cmd->size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd->result = cpu_to_le16(0); | ||||
| 	cmd->seqnum = cpu_to_le16(0x5a5a); | ||||
| 	usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header)); | ||||
|  |  | |||
|  | @ -157,12 +157,7 @@ static void lbs_tx_timeout(struct net_device *dev) | |||
| 	   to kick it somehow? */ | ||||
| 	lbs_host_to_card_done(priv); | ||||
| 
 | ||||
| 	/* More often than not, this actually happens because the
 | ||||
| 	   firmware has crapped itself -- rather than just a very | ||||
| 	   busy medium. So send a harmless command, and if/when | ||||
| 	   _that_ times out, we'll kick it in the head. */ | ||||
| 	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, | ||||
| 				     0, 0, NULL); | ||||
| 	/* FIXME: reset the card */ | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_TX); | ||||
| } | ||||
|  | @ -507,12 +502,6 @@ static int lbs_thread(void *data) | |||
| 		if (!priv->dnld_sent && !priv->cur_cmd) | ||||
| 			lbs_execute_next_command(priv); | ||||
| 
 | ||||
| 		/* Wake-up command waiters which can't sleep in
 | ||||
| 		 * lbs_prepare_and_send_command | ||||
| 		 */ | ||||
| 		if (!list_empty(&priv->cmdpendingq)) | ||||
| 			wake_up_all(&priv->cmd_pending); | ||||
| 
 | ||||
| 		spin_lock_irq(&priv->driver_lock); | ||||
| 		if (!priv->dnld_sent && priv->tx_pending_len > 0) { | ||||
| 			int ret = priv->hw_host_to_card(priv, MVMS_DAT, | ||||
|  | @ -538,7 +527,6 @@ static int lbs_thread(void *data) | |||
| 
 | ||||
| 	del_timer(&priv->command_timer); | ||||
| 	del_timer(&priv->auto_deepsleep_timer); | ||||
| 	wake_up_all(&priv->cmd_pending); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_THREAD); | ||||
| 	return 0; | ||||
|  | @ -663,7 +651,6 @@ out: | |||
| static void auto_deepsleep_timer_fn(unsigned long data) | ||||
| { | ||||
| 	struct lbs_private *priv = (struct lbs_private *)data; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
|  | @ -673,12 +660,13 @@ static void auto_deepsleep_timer_fn(unsigned long data) | |||
| 		if (priv->is_auto_deep_sleep_enabled && | ||||
| 		    (!priv->wakeup_dev_required) && | ||||
| 		    (priv->connect_status != LBS_CONNECTED)) { | ||||
| 			struct cmd_header cmd; | ||||
| 
 | ||||
| 			lbs_deb_main("Entering auto deep sleep mode...\n"); | ||||
| 			ret = lbs_prepare_and_send_command(priv, | ||||
| 					CMD_802_11_DEEP_SLEEP, 0, | ||||
| 					0, 0, NULL); | ||||
| 			if (ret) | ||||
| 				lbs_pr_err("Enter Deep Sleep command failed\n"); | ||||
| 			memset(&cmd, 0, sizeof(cmd)); | ||||
| 			cmd.size = cpu_to_le16(sizeof(cmd)); | ||||
| 			lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd, | ||||
| 					sizeof(cmd)); | ||||
| 		} | ||||
| 	} | ||||
| 	mod_timer(&priv->auto_deepsleep_timer , jiffies + | ||||
|  | @ -746,7 +734,6 @@ static int lbs_init_adapter(struct lbs_private *priv) | |||
| 	INIT_LIST_HEAD(&priv->cmdpendingq); | ||||
| 
 | ||||
| 	spin_lock_init(&priv->driver_lock); | ||||
| 	init_waitqueue_head(&priv->cmd_pending); | ||||
| 
 | ||||
| 	/* Allocate the command buffers */ | ||||
| 	if (lbs_allocate_cmd_buffer(priv)) { | ||||
|  | @ -902,7 +889,7 @@ void lbs_remove_card(struct lbs_private *priv) | |||
| 
 | ||||
| 	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { | ||||
| 		priv->psmode = LBS802_11POWERMODECAM; | ||||
| 		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); | ||||
| 		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); | ||||
| 	} | ||||
| 
 | ||||
| 	if (priv->is_deep_sleep) { | ||||
|  | @ -1065,7 +1052,7 @@ static int __init lbs_init_module(void) | |||
| 	memset(&confirm_sleep, 0, sizeof(confirm_sleep)); | ||||
| 	confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE); | ||||
| 	confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep)); | ||||
| 	confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); | ||||
| 	confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED); | ||||
| 	lbs_debugfs_init(); | ||||
| 	lbs_deb_leave(LBS_DEB_MAIN); | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -455,65 +455,189 @@ void lbs_mesh_set_txpd(struct lbs_private *priv, | |||
|  * Mesh command handling | ||||
|  */ | ||||
| 
 | ||||
| int lbs_cmd_bt_access(struct cmd_ds_command *cmd, | ||||
| 			       u16 cmd_action, void *pdata_buf) | ||||
| /**
 | ||||
|  *  @brief Add or delete Mesh Blinding Table entries | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param add  	TRUE to add the entry, FALSE to delete it | ||||
|  *  @param addr1        Destination address to blind or unblind | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) | ||||
| { | ||||
| 	struct cmd_ds_bt_access *bt_access = &cmd->params.bt; | ||||
| 	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); | ||||
| 	struct cmd_ds_bt_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	cmd->command = cpu_to_le16(CMD_BT_ACCESS); | ||||
| 	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + | ||||
| 		sizeof(struct cmd_header)); | ||||
| 	cmd->result = 0; | ||||
| 	bt_access->action = cpu_to_le16(cmd_action); | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	switch (cmd_action) { | ||||
| 	case CMD_ACT_BT_ACCESS_ADD: | ||||
| 		memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); | ||||
| 	BUG_ON(addr1 == NULL); | ||||
| 
 | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	memcpy(cmd.addr1, addr1, ETH_ALEN); | ||||
| 	if (add) { | ||||
| 		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD); | ||||
| 		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", | ||||
| 			bt_access->addr1, 6); | ||||
| 		break; | ||||
| 	case CMD_ACT_BT_ACCESS_DEL: | ||||
| 		memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN); | ||||
| 			addr1, ETH_ALEN); | ||||
| 	} else { | ||||
| 		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL); | ||||
| 		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", | ||||
| 			bt_access->addr1, 6); | ||||
| 		break; | ||||
| 	case CMD_ACT_BT_ACCESS_LIST: | ||||
| 		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); | ||||
| 		break; | ||||
| 	case CMD_ACT_BT_ACCESS_RESET: | ||||
| 		break; | ||||
| 	case CMD_ACT_BT_ACCESS_SET_INVERT: | ||||
| 		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); | ||||
| 		break; | ||||
| 	case CMD_ACT_BT_ACCESS_GET_INVERT: | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	return 0; | ||||
| 			addr1, ETH_ALEN); | ||||
| 	} | ||||
| 
 | ||||
| int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, | ||||
| 			       u16 cmd_action, void *pdata_buf) | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Reset/clear the mesh blinding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_reset(struct lbs_private *priv) | ||||
| { | ||||
| 	struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; | ||||
| 	struct cmd_ds_bt_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Gets the inverted status of the mesh blinding table | ||||
|  * | ||||
|  *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  *  table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  *  the table. | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param invert  	On success, TRUE if the blinding table is inverted, | ||||
|  *                        FALSE if it is not inverted | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) | ||||
| { | ||||
| 	struct cmd_ds_bt_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	BUG_ON(inverted == NULL); | ||||
| 
 | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); | ||||
| 	if (ret == 0) | ||||
| 		*inverted = !!cmd.id; | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Sets the inverted status of the mesh blinding table | ||||
|  * | ||||
|  *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  *  table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  *  the table. | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param invert  	TRUE to invert the blinding table (only traffic from | ||||
|  *                         listed nodes allowed), FALSE to return it | ||||
|  *                         to normal state (listed nodes ignored) | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) | ||||
| { | ||||
| 	struct cmd_ds_bt_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); | ||||
| 	cmd.id = !!inverted; | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief List an entry in the mesh blinding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param id		The ID of the entry to list | ||||
|  *  @param addr1	MAC address associated with the table entry | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) | ||||
| { | ||||
| 	struct cmd_ds_bt_access cmd; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_CMD); | ||||
| 
 | ||||
| 	BUG_ON(addr1 == NULL); | ||||
| 
 | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||||
| 	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); | ||||
| 	cmd.id = cpu_to_le32(id); | ||||
| 
 | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); | ||||
| 	if (ret == 0) | ||||
| 		memcpy(addr1, cmd.addr1, sizeof(cmd.addr1)); | ||||
| 
 | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Access the mesh forwarding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param cmd_action	The forwarding table action to perform | ||||
|  *  @param cmd		The pre-filled FWT_ACCESS command | ||||
|  * | ||||
|  *  @return 	   	0 on success and 'cmd' will be filled with the | ||||
|  *                        firmware's response | ||||
|  */ | ||||
| int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, | ||||
| 			struct cmd_ds_fwt_access *cmd) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); | ||||
| 
 | ||||
| 	cmd->command = cpu_to_le16(CMD_FWT_ACCESS); | ||||
| 	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + | ||||
| 		sizeof(struct cmd_header)); | ||||
| 	cmd->result = 0; | ||||
| 	cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS); | ||||
| 	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)); | ||||
| 	cmd->hdr.result = 0; | ||||
| 	cmd->action = cpu_to_le16(cmd_action); | ||||
| 
 | ||||
| 	if (pdata_buf) | ||||
| 		memcpy(fwt_access, pdata_buf, sizeof(*fwt_access)); | ||||
| 	else | ||||
| 		memset(fwt_access, 0, sizeof(*fwt_access)); | ||||
| 	ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); | ||||
| 
 | ||||
| 	fwt_access->action = cpu_to_le16(cmd_action); | ||||
| 
 | ||||
| 	lbs_deb_leave(LBS_DEB_CMD); | ||||
| 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include <net/iw_handler.h> | ||||
| #include <net/lib80211.h> | ||||
| 
 | ||||
| #include "host.h" | ||||
| 
 | ||||
| #ifdef CONFIG_LIBERTAS_MESH | ||||
| 
 | ||||
|  | @ -51,10 +52,15 @@ struct cmd_ds_command; | |||
| struct cmd_ds_mesh_access; | ||||
| struct cmd_ds_mesh_config; | ||||
| 
 | ||||
| int lbs_cmd_bt_access(struct cmd_ds_command *cmd, | ||||
| 	u16 cmd_action, void *pdata_buf); | ||||
| int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, | ||||
| 	u16 cmd_action, void *pdata_buf); | ||||
| int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1); | ||||
| int lbs_mesh_bt_reset(struct lbs_private *priv); | ||||
| int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); | ||||
| int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); | ||||
| int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); | ||||
| 
 | ||||
| int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, | ||||
| 			struct cmd_ds_fwt_access *cmd); | ||||
| 
 | ||||
| int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, | ||||
| 		    struct cmd_ds_mesh_access *cmd); | ||||
| int lbs_mesh_config_send(struct lbs_private *priv, | ||||
|  |  | |||
|  | @ -180,7 +180,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) | |||
| { | ||||
| 	struct tx_radiotap_hdr *radiotap_hdr; | ||||
| 
 | ||||
| 	if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR || | ||||
| 	if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR || | ||||
| 	    priv->currenttxskb == NULL) | ||||
| 		return; | ||||
| 
 | ||||
|  |  | |||
|  | @ -253,6 +253,9 @@ struct lbtf_private { | |||
| 	u8 fw_ready; | ||||
| 	u8 surpriseremoved; | ||||
| 	struct sk_buff_head bc_ps_buf; | ||||
| 
 | ||||
| 	/* Most recently reported noise in dBm */ | ||||
| 	s8 noise; | ||||
| }; | ||||
| 
 | ||||
| /* 802.11-related definitions */ | ||||
|  |  | |||
|  | @ -525,6 +525,22 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, | |||
| 	lbtf_deb_leave(LBTF_DEB_MACOPS); | ||||
| } | ||||
| 
 | ||||
| static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx, | ||||
| 				struct survey_info *survey) | ||||
| { | ||||
| 	struct lbtf_private *priv = hw->priv; | ||||
| 	struct ieee80211_conf *conf = &hw->conf; | ||||
| 
 | ||||
| 	if (idx != 0) | ||||
| 		return -ENOENT; | ||||
| 
 | ||||
| 	survey->channel = conf->channel; | ||||
| 	survey->filled = SURVEY_INFO_NOISE_DBM; | ||||
| 	survey->noise = priv->noise; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct ieee80211_ops lbtf_ops = { | ||||
| 	.tx			= lbtf_op_tx, | ||||
| 	.start			= lbtf_op_start, | ||||
|  | @ -535,6 +551,7 @@ static const struct ieee80211_ops lbtf_ops = { | |||
| 	.prepare_multicast	= lbtf_op_prepare_multicast, | ||||
| 	.configure_filter	= lbtf_op_configure_filter, | ||||
| 	.bss_info_changed	= lbtf_op_bss_info_changed, | ||||
| 	.get_survey		= lbtf_op_get_survey, | ||||
| }; | ||||
| 
 | ||||
| int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | ||||
|  | @ -555,6 +572,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
| 	stats.freq = priv->cur_freq; | ||||
| 	stats.band = IEEE80211_BAND_2GHZ; | ||||
| 	stats.signal = prxpd->snr; | ||||
| 	priv->noise = prxpd->nf; | ||||
| 	/* Marvell rate index has a hole at value 4 */ | ||||
| 	if (prxpd->rx_rate > 4) | ||||
| 		--prxpd->rx_rate; | ||||
|  |  | |||
|  | @ -486,8 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
| 	struct ieee80211_rx_status rx_status; | ||||
| 
 | ||||
| 	if (data->idle) { | ||||
| 		printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -576,7 +575,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| static int mac80211_hwsim_start(struct ieee80211_hw *hw) | ||||
| { | ||||
| 	struct mac80211_hwsim_data *data = hw->priv; | ||||
| 	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||||
| 	wiphy_debug(hw->wiphy, "%s\n", __func__); | ||||
| 	data->started = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -587,16 +586,15 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) | |||
| 	struct mac80211_hwsim_data *data = hw->priv; | ||||
| 	data->started = 0; | ||||
| 	del_timer(&data->beacon_timer); | ||||
| 	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||||
| 	wiphy_debug(hw->wiphy, "%s\n", __func__); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, | ||||
| 					struct ieee80211_vif *vif) | ||||
| { | ||||
| 	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, vif->type, | ||||
| 	       vif->addr); | ||||
| 	wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", | ||||
| 		    __func__, vif->type, vif->addr); | ||||
| 	hwsim_set_magic(vif); | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -605,9 +603,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, | |||
| static void mac80211_hwsim_remove_interface( | ||||
| 	struct ieee80211_hw *hw, struct ieee80211_vif *vif) | ||||
| { | ||||
| 	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, vif->type, | ||||
| 	       vif->addr); | ||||
| 	wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", | ||||
| 		    __func__, vif->type, vif->addr); | ||||
| 	hwsim_check_magic(vif); | ||||
| 	hwsim_clear_magic(vif); | ||||
| } | ||||
|  | @ -670,8 +667,9 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
| 		[IEEE80211_SMPS_DYNAMIC] = "dynamic", | ||||
| 	}; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, | ||||
| 	wiphy_debug(hw->wiphy, | ||||
| 		    "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", | ||||
| 		    __func__, | ||||
| 		    conf->channel->center_freq, | ||||
| 		    hwsim_chantypes[conf->channel_type], | ||||
| 		    !!(conf->flags & IEEE80211_CONF_IDLE), | ||||
|  | @ -696,7 +694,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, | |||
| { | ||||
| 	struct mac80211_hwsim_data *data = hw->priv; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||||
| 	wiphy_debug(hw->wiphy, "%s\n", __func__); | ||||
| 
 | ||||
| 	data->rx_filter = 0; | ||||
| 	if (*total_flags & FIF_PROMISC_IN_BSS) | ||||
|  | @ -717,26 +715,23 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
| 
 | ||||
| 	hwsim_check_magic(vif); | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s(changed=0x%x)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, changed); | ||||
| 	wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed); | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_BSSID) { | ||||
| 		printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n", | ||||
| 		       wiphy_name(hw->wiphy), __func__, | ||||
| 		       info->bssid); | ||||
| 		wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", | ||||
| 			    __func__, info->bssid); | ||||
| 		memcpy(vp->bssid, info->bssid, ETH_ALEN); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_ASSOC) { | ||||
| 		printk(KERN_DEBUG "  %s: ASSOC: assoc=%d aid=%d\n", | ||||
| 		       wiphy_name(hw->wiphy), info->assoc, info->aid); | ||||
| 		wiphy_debug(hw->wiphy, "  ASSOC: assoc=%d aid=%d\n", | ||||
| 			    info->assoc, info->aid); | ||||
| 		vp->assoc = info->assoc; | ||||
| 		vp->aid = info->aid; | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_BEACON_INT) { | ||||
| 		printk(KERN_DEBUG "  %s: BCNINT: %d\n", | ||||
| 		       wiphy_name(hw->wiphy), info->beacon_int); | ||||
| 		wiphy_debug(hw->wiphy, "  BCNINT: %d\n", info->beacon_int); | ||||
| 		data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; | ||||
| 		if (WARN_ON(!data->beacon_int)) | ||||
| 			data->beacon_int = 1; | ||||
|  | @ -746,30 +741,27 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_ERP_CTS_PROT) { | ||||
| 		printk(KERN_DEBUG "  %s: ERP_CTS_PROT: %d\n", | ||||
| 		       wiphy_name(hw->wiphy), info->use_cts_prot); | ||||
| 		wiphy_debug(hw->wiphy, "  ERP_CTS_PROT: %d\n", | ||||
| 			    info->use_cts_prot); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_ERP_PREAMBLE) { | ||||
| 		printk(KERN_DEBUG "  %s: ERP_PREAMBLE: %d\n", | ||||
| 		       wiphy_name(hw->wiphy), info->use_short_preamble); | ||||
| 		wiphy_debug(hw->wiphy, "  ERP_PREAMBLE: %d\n", | ||||
| 			    info->use_short_preamble); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_ERP_SLOT) { | ||||
| 		printk(KERN_DEBUG "  %s: ERP_SLOT: %d\n", | ||||
| 		       wiphy_name(hw->wiphy), info->use_short_slot); | ||||
| 		wiphy_debug(hw->wiphy, "  ERP_SLOT: %d\n", info->use_short_slot); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_HT) { | ||||
| 		printk(KERN_DEBUG "  %s: HT: op_mode=0x%x, chantype=%s\n", | ||||
| 		       wiphy_name(hw->wiphy), | ||||
| 		wiphy_debug(hw->wiphy, "  HT: op_mode=0x%x, chantype=%s\n", | ||||
| 			    info->ht_operation_mode, | ||||
| 			    hwsim_chantypes[info->channel_type]); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & BSS_CHANGED_BASIC_RATES) { | ||||
| 		printk(KERN_DEBUG "  %s: BASIC_RATES: 0x%llx\n", | ||||
| 		       wiphy_name(hw->wiphy), | ||||
| 		wiphy_debug(hw->wiphy, "  BASIC_RATES: 0x%llx\n", | ||||
| 			    (unsigned long long) info->basic_rates); | ||||
| 	} | ||||
| } | ||||
|  | @ -824,10 +816,11 @@ static int mac80211_hwsim_conf_tx( | |||
| 	struct ieee80211_hw *hw, u16 queue, | ||||
| 	const struct ieee80211_tx_queue_params *params) | ||||
| { | ||||
| 	printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d " | ||||
| 	       "aifs=%d)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, queue, | ||||
| 	       params->txop, params->cw_min, params->cw_max, params->aifs); | ||||
| 	wiphy_debug(hw->wiphy, | ||||
| 		    "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n", | ||||
| 		    __func__, queue, | ||||
| 		    params->txop, params->cw_min, | ||||
| 		    params->cw_max, params->aifs); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -837,8 +830,7 @@ static int mac80211_hwsim_get_survey( | |||
| { | ||||
| 	struct ieee80211_conf *conf = &hw->conf; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s (idx=%d)\n", | ||||
| 	       wiphy_name(hw->wiphy), __func__, idx); | ||||
| 	wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx); | ||||
| 
 | ||||
| 	if (idx != 0) | ||||
| 		return -ENOENT; | ||||
|  | @ -1108,8 +1100,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) | |||
| 	if (!vp->assoc) | ||||
| 		return; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s: send PS-Poll to %pM for aid %d\n", | ||||
| 	       wiphy_name(data->hw->wiphy), __func__, vp->bssid, vp->aid); | ||||
| 	wiphy_debug(data->hw->wiphy, | ||||
| 		    "%s: send PS-Poll to %pM for aid %d\n", | ||||
| 		    __func__, vp->bssid, vp->aid); | ||||
| 
 | ||||
| 	skb = dev_alloc_skb(sizeof(*pspoll)); | ||||
| 	if (!skb) | ||||
|  | @ -1137,8 +1130,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | |||
| 	if (!vp->assoc) | ||||
| 		return; | ||||
| 
 | ||||
| 	printk(KERN_DEBUG "%s:%s: send data::nullfunc to %pM ps=%d\n", | ||||
| 	       wiphy_name(data->hw->wiphy), __func__, vp->bssid, ps); | ||||
| 	wiphy_debug(data->hw->wiphy, | ||||
| 		    "%s: send data::nullfunc to %pM ps=%d\n", | ||||
| 		    __func__, vp->bssid, ps); | ||||
| 
 | ||||
| 	skb = dev_alloc_skb(sizeof(*hdr)); | ||||
| 	if (!skb) | ||||
|  | @ -1473,8 +1467,7 @@ static int __init init_mac80211_hwsim(void) | |||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		printk(KERN_DEBUG "%s: hwaddr %pM registered\n", | ||||
| 		       wiphy_name(hw->wiphy), | ||||
| 		wiphy_debug(hw->wiphy, "hwaddr %pm registered\n", | ||||
| 			    hw->wiphy->perm_addr); | ||||
| 
 | ||||
| 		data->debugfs = debugfs_create_dir("hwsim", | ||||
|  |  | |||
|  | @ -86,7 +86,7 @@ struct rxd_ops { | |||
| 	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); | ||||
| 	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len); | ||||
| 	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status, | ||||
| 			   __le16 *qos); | ||||
| 			   __le16 *qos, s8 *noise); | ||||
| }; | ||||
| 
 | ||||
| struct mwl8k_device_info { | ||||
|  | @ -207,6 +207,9 @@ struct mwl8k_priv { | |||
| 
 | ||||
| 	/* Tasklet to perform RX.  */ | ||||
| 	struct tasklet_struct poll_rx_task; | ||||
| 
 | ||||
| 	/* Most recently reported noise in dBm */ | ||||
| 	s8 noise; | ||||
| }; | ||||
| 
 | ||||
| /* Per interface specific private data */ | ||||
|  | @ -741,7 +744,7 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) | |||
| 
 | ||||
| static int | ||||
| mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, | ||||
| 			  __le16 *qos) | ||||
| 			  __le16 *qos, s8 *noise) | ||||
| { | ||||
| 	struct mwl8k_rxd_8366_ap *rxd = _rxd; | ||||
| 
 | ||||
|  | @ -752,6 +755,7 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, | |||
| 	memset(status, 0, sizeof(*status)); | ||||
| 
 | ||||
| 	status->signal = -rxd->rssi; | ||||
| 	*noise = -rxd->noise_floor; | ||||
| 
 | ||||
| 	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { | ||||
| 		status->flag |= RX_FLAG_HT; | ||||
|  | @ -839,7 +843,7 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) | |||
| 
 | ||||
| static int | ||||
| mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, | ||||
| 		       __le16 *qos) | ||||
| 		       __le16 *qos, s8 *noise) | ||||
| { | ||||
| 	struct mwl8k_rxd_sta *rxd = _rxd; | ||||
| 	u16 rate_info; | ||||
|  | @ -853,6 +857,7 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, | |||
| 	memset(status, 0, sizeof(*status)); | ||||
| 
 | ||||
| 	status->signal = -rxd->rssi; | ||||
| 	*noise = -rxd->noise_level; | ||||
| 	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); | ||||
| 	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); | ||||
| 
 | ||||
|  | @ -905,16 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) | |||
| 
 | ||||
| 	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); | ||||
| 	if (rxq->rxd == NULL) { | ||||
| 		printk(KERN_ERR "%s: failed to alloc RX descriptors\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	memset(rxq->rxd, 0, size); | ||||
| 
 | ||||
| 	rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); | ||||
| 	if (rxq->buf == NULL) { | ||||
| 		printk(KERN_ERR "%s: failed to alloc RX skbuff list\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); | ||||
| 		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | @ -1055,7 +1058,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) | |||
| 
 | ||||
| 		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); | ||||
| 
 | ||||
| 		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos); | ||||
| 		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, | ||||
| 							&priv->noise); | ||||
| 		if (pkt_len < 0) | ||||
| 			break; | ||||
| 
 | ||||
|  | @ -1141,16 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) | |||
| 
 | ||||
| 	txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); | ||||
| 	if (txq->txd == NULL) { | ||||
| 		printk(KERN_ERR "%s: failed to alloc TX descriptors\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	memset(txq->txd, 0, size); | ||||
| 
 | ||||
| 	txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); | ||||
| 	if (txq->skb == NULL) { | ||||
| 		printk(KERN_ERR "%s: failed to alloc TX skbuff list\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); | ||||
| 		pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | @ -1206,9 +1208,10 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw) | |||
| 				unused++; | ||||
| 		} | ||||
| 
 | ||||
| 		printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d " | ||||
| 		wiphy_err(hw->wiphy, | ||||
| 			  "txq[%d] len=%d head=%d tail=%d " | ||||
| 			  "fw_owned=%d drv_owned=%d unused=%d\n", | ||||
| 		       wiphy_name(hw->wiphy), i, | ||||
| 			  i, | ||||
| 			  txq->len, txq->head, txq->tail, | ||||
| 			  fw_owned, drv_owned, unused); | ||||
| 	} | ||||
|  | @ -1254,25 +1257,23 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
| 		if (timeout) { | ||||
| 			WARN_ON(priv->pending_tx_pkts); | ||||
| 			if (retry) { | ||||
| 				printk(KERN_NOTICE "%s: tx rings drained\n", | ||||
| 				       wiphy_name(hw->wiphy)); | ||||
| 				wiphy_notice(hw->wiphy, "tx rings drained\n"); | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (priv->pending_tx_pkts < oldcount) { | ||||
| 			printk(KERN_NOTICE "%s: waiting for tx rings " | ||||
| 			       "to drain (%d -> %d pkts)\n", | ||||
| 			       wiphy_name(hw->wiphy), oldcount, | ||||
| 			       priv->pending_tx_pkts); | ||||
| 			wiphy_notice(hw->wiphy, | ||||
| 				     "waiting for tx rings to drain (%d -> %d pkts)\n", | ||||
| 				     oldcount, priv->pending_tx_pkts); | ||||
| 			retry = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		priv->tx_wait = NULL; | ||||
| 
 | ||||
| 		printk(KERN_ERR "%s: tx rings stuck for %d ms\n", | ||||
| 		       wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS); | ||||
| 		wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", | ||||
| 			  MWL8K_TX_WAIT_TIMEOUT_MS); | ||||
| 		mwl8k_dump_tx_rings(hw); | ||||
| 
 | ||||
| 		rc = -ETIMEDOUT; | ||||
|  | @ -1423,8 +1424,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
| 				skb->len, PCI_DMA_TODEVICE); | ||||
| 
 | ||||
| 	if (pci_dma_mapping_error(priv->pdev, dma)) { | ||||
| 		printk(KERN_DEBUG "%s: failed to dma map skb, " | ||||
| 		       "dropping TX frame.\n", wiphy_name(hw->wiphy)); | ||||
| 		wiphy_debug(hw->wiphy, | ||||
| 			    "failed to dma map skb, dropping TX frame.\n"); | ||||
| 		dev_kfree_skb(skb); | ||||
| 		return NETDEV_TX_OK; | ||||
| 	} | ||||
|  | @ -1572,8 +1573,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
| 					PCI_DMA_BIDIRECTIONAL); | ||||
| 
 | ||||
| 	if (!timeout) { | ||||
| 		printk(KERN_ERR "%s: Command %s timeout after %u ms\n", | ||||
| 		       wiphy_name(hw->wiphy), | ||||
| 		wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", | ||||
| 			  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | ||||
| 			  MWL8K_CMD_TIMEOUT_MS); | ||||
| 		rc = -ETIMEDOUT; | ||||
|  | @ -1584,14 +1584,13 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
| 
 | ||||
| 		rc = cmd->result ? -EINVAL : 0; | ||||
| 		if (rc) | ||||
| 			printk(KERN_ERR "%s: Command %s error 0x%x\n", | ||||
| 			       wiphy_name(hw->wiphy), | ||||
| 			wiphy_err(hw->wiphy, "command %s error 0x%x\n", | ||||
| 				  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | ||||
| 				  le16_to_cpu(cmd->result)); | ||||
| 		else if (ms > 2000) | ||||
| 			printk(KERN_NOTICE "%s: Command %s took %d ms\n", | ||||
| 			       wiphy_name(hw->wiphy), | ||||
| 			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | ||||
| 			wiphy_notice(hw->wiphy, "command %s took %d ms\n", | ||||
| 				     mwl8k_cmd_name(cmd->code, | ||||
| 						    buf, sizeof(buf)), | ||||
| 				     ms); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3192,8 +3191,8 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 	int rc; | ||||
| 
 | ||||
| 	if (!priv->radio_on) { | ||||
| 		printk(KERN_DEBUG "%s: dropped TX frame since radio " | ||||
| 		       "disabled\n", wiphy_name(hw->wiphy)); | ||||
| 		wiphy_debug(hw->wiphy, | ||||
| 			    "dropped TX frame since radio disabled\n"); | ||||
| 		dev_kfree_skb(skb); | ||||
| 		return NETDEV_TX_OK; | ||||
| 	} | ||||
|  | @ -3211,8 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
| 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | ||||
| 			 IRQF_SHARED, MWL8K_NAME, hw); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: failed to register IRQ handler\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to register irq handler\n"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3299,9 +3297,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, | |||
| 	 * mode.  (Sniffer mode is only used on STA firmware.) | ||||
| 	 */ | ||||
| 	if (priv->sniffer_enabled) { | ||||
| 		printk(KERN_INFO "%s: unable to create STA " | ||||
| 		       "interface due to sniffer mode being enabled\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_info(hw->wiphy, | ||||
| 			   "unable to create STA interface because sniffer mode is enabled\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3583,9 +3580,8 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw, | |||
| 	 */ | ||||
| 	if (!list_empty(&priv->vif_list)) { | ||||
| 		if (net_ratelimit()) | ||||
| 			printk(KERN_INFO "%s: not enabling sniffer " | ||||
| 			       "mode because STA interface is active\n", | ||||
| 			       wiphy_name(hw->wiphy)); | ||||
| 			wiphy_info(hw->wiphy, | ||||
| 				   "not enabling sniffer mode because STA interface is active\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3765,6 +3761,22 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw, | |||
| 	return mwl8k_cmd_get_stat(hw, stats); | ||||
| } | ||||
| 
 | ||||
| static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, | ||||
| 				struct survey_info *survey) | ||||
| { | ||||
| 	struct mwl8k_priv *priv = hw->priv; | ||||
| 	struct ieee80211_conf *conf = &hw->conf; | ||||
| 
 | ||||
| 	if (idx != 0) | ||||
| 		return -ENOENT; | ||||
| 
 | ||||
| 	survey->channel = conf->channel; | ||||
| 	survey->filled = SURVEY_INFO_NOISE_DBM; | ||||
| 	survey->noise = priv->noise; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||||
| 		   enum ieee80211_ampdu_mlme_action action, | ||||
|  | @ -3796,6 +3808,7 @@ static const struct ieee80211_ops mwl8k_ops = { | |||
| 	.sta_remove		= mwl8k_sta_remove, | ||||
| 	.conf_tx		= mwl8k_conf_tx, | ||||
| 	.get_stats		= mwl8k_get_stats, | ||||
| 	.get_survey		= mwl8k_get_survey, | ||||
| 	.ampdu_action		= mwl8k_ampdu_action, | ||||
| }; | ||||
| 
 | ||||
|  | @ -3913,8 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 
 | ||||
| 	priv->sram = pci_iomap(pdev, 0, 0x10000); | ||||
| 	if (priv->sram == NULL) { | ||||
| 		printk(KERN_ERR "%s: Cannot map device SRAM\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot map device sram\n"); | ||||
| 		goto err_iounmap; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3926,8 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 	if (priv->regs == NULL) { | ||||
| 		priv->regs = pci_iomap(pdev, 2, 0x10000); | ||||
| 		if (priv->regs == NULL) { | ||||
| 			printk(KERN_ERR "%s: Cannot map device registers\n", | ||||
| 			       wiphy_name(hw->wiphy)); | ||||
| 			wiphy_err(hw->wiphy, "cannot map device registers\n"); | ||||
| 			goto err_iounmap; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -3939,16 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 	/* Ask userland hotplug daemon for the device firmware */ | ||||
| 	rc = mwl8k_request_firmware(priv); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Firmware files not found\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "firmware files not found\n"); | ||||
| 		goto err_stop_firmware; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Load firmware into hardware */ | ||||
| 	rc = mwl8k_load_firmware(hw); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Cannot start firmware\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot start firmware\n"); | ||||
| 		goto err_stop_firmware; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -3959,9 +3968,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 	if (priv->ap_fw) { | ||||
| 		priv->rxd_ops = priv->device_info->ap_rxd_ops; | ||||
| 		if (priv->rxd_ops == NULL) { | ||||
| 			printk(KERN_ERR "%s: Driver does not have AP " | ||||
| 			       "firmware image support for this hardware\n", | ||||
| 			       wiphy_name(hw->wiphy)); | ||||
| 			wiphy_err(hw->wiphy, | ||||
| 				  "Driver does not have AP firmware image support for this hardware\n"); | ||||
| 			goto err_stop_firmware; | ||||
| 		} | ||||
| 	} else { | ||||
|  | @ -4039,8 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | ||||
| 			 IRQF_SHARED, MWL8K_NAME, hw); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: failed to register IRQ handler\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "failed to register irq handler\n"); | ||||
| 		goto err_free_queues; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4060,8 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 		rc = mwl8k_cmd_get_hw_spec_sta(hw); | ||||
| 	} | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Cannot initialise firmware\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot initialise firmware\n"); | ||||
| 		goto err_free_irq; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4075,15 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 	/* Turn radio off */ | ||||
| 	rc = mwl8k_cmd_radio_disable(hw); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot disable\n"); | ||||
| 		goto err_free_irq; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Clear MAC address */ | ||||
| 	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Cannot clear MAC address\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot clear mac address\n"); | ||||
| 		goto err_free_irq; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4093,13 +4098,12 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
| 
 | ||||
| 	rc = ieee80211_register_hw(hw); | ||||
| 	if (rc) { | ||||
| 		printk(KERN_ERR "%s: Cannot register device\n", | ||||
| 		       wiphy_name(hw->wiphy)); | ||||
| 		wiphy_err(hw->wiphy, "cannot register device\n"); | ||||
| 		goto err_free_queues; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", | ||||
| 	       wiphy_name(hw->wiphy), priv->device_info->part_name, | ||||
| 	wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", | ||||
| 		   priv->device_info->part_name, | ||||
| 		   priv->hw_rev, hw->wiphy->perm_addr, | ||||
| 		   priv->ap_fw ? "AP" : "STA", | ||||
| 		   (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, | ||||
|  |  | |||
|  | @ -117,9 +117,8 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev, | |||
| 
 | ||||
| 	case NL80211_IFTYPE_MONITOR: | ||||
| 		if (priv->broken_monitor && !force_monitor) { | ||||
| 			printk(KERN_WARNING "%s: Monitor mode support is " | ||||
| 			       "buggy in this firmware, not enabling\n", | ||||
| 			       wiphy_name(wiphy)); | ||||
| 			wiphy_warn(wiphy, | ||||
| 				   "Monitor mode support is buggy in this firmware, not enabling\n"); | ||||
| 			err = -EINVAL; | ||||
| 		} | ||||
| 		break; | ||||
|  |  | |||
|  | @ -149,9 +149,8 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
| 			continue; | ||||
| 
 | ||||
| 		if (list->channels[i].data != CHAN_HAS_ALL) { | ||||
| 			printk(KERN_ERR "%s:%s%s%s is/are missing for " | ||||
| 					"channel:%d [%d MHz].\n", | ||||
| 			       wiphy_name(dev->wiphy), | ||||
| 			wiphy_err(dev->wiphy, | ||||
| 				  "%s%s%s is/are missing for channel:%d [%d MHz].\n", | ||||
| 				  (list->channels[i].data & CHAN_HAS_CAL ? "" : | ||||
| 				   " [iqauto calibration data]"), | ||||
| 				  (list->channels[i].data & CHAN_HAS_LIMIT ? "" : | ||||
|  | @ -168,9 +167,8 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
| 	} | ||||
| 
 | ||||
| 	if (j == 0) { | ||||
| 		printk(KERN_ERR "%s: Disabling totally damaged %s band.\n", | ||||
| 		       wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ? | ||||
| 		       "2 GHz" : "5 GHz"); | ||||
| 		wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n", | ||||
| 			  (band == IEEE80211_BAND_2GHZ) ? 2 : 5); | ||||
| 
 | ||||
| 		ret = -ENODATA; | ||||
| 		goto err_out; | ||||
|  | @ -244,9 +242,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) | |||
| 
 | ||||
| 	if ((priv->iq_autocal_len != priv->curve_data->entries) || | ||||
| 	    (priv->iq_autocal_len != priv->output_limit->entries)) | ||||
| 		printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. " | ||||
| 				"You may not be able to use all channels.\n", | ||||
| 				wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, | ||||
| 			  "Unsupported or damaged EEPROM detected. " | ||||
| 			  "You may not be able to use all channels.\n"); | ||||
| 
 | ||||
| 	max_channel_num = max_t(unsigned int, priv->output_limit->entries, | ||||
| 				priv->iq_autocal_len); | ||||
|  | @ -419,15 +417,14 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, | |||
| 	int i; | ||||
| 
 | ||||
| 	if (len != (entry_size * num_entries)) { | ||||
| 		printk(KERN_ERR "%s: unknown rssi calibration data packing " | ||||
| 				 " type:(%x) len:%d.\n", | ||||
| 		       wiphy_name(dev->wiphy), type, len); | ||||
| 		wiphy_err(dev->wiphy, | ||||
| 			  "unknown rssi calibration data packing type:(%x) len:%d.\n", | ||||
| 			  type, len); | ||||
| 
 | ||||
| 		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, | ||||
| 				     data, len); | ||||
| 
 | ||||
| 		printk(KERN_ERR "%s: please report this issue.\n", | ||||
| 			wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "please report this issue.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -445,15 +442,14 @@ static void p54_parse_default_country(struct ieee80211_hw *dev, | |||
| 	struct pda_country *country; | ||||
| 
 | ||||
| 	if (len != sizeof(*country)) { | ||||
| 		printk(KERN_ERR "%s: found possible invalid default country " | ||||
| 				"eeprom entry. (entry size: %d)\n", | ||||
| 		       wiphy_name(dev->wiphy), len); | ||||
| 		wiphy_err(dev->wiphy, | ||||
| 			  "found possible invalid default country eeprom entry. (entry size: %d)\n", | ||||
| 			  len); | ||||
| 
 | ||||
| 		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, | ||||
| 				     data, len); | ||||
| 
 | ||||
| 		printk(KERN_ERR "%s: please report this issue.\n", | ||||
| 			wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "please report this issue.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -478,8 +474,8 @@ static int p54_convert_output_limits(struct ieee80211_hw *dev, | |||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (data[0] != 0) { | ||||
| 		printk(KERN_ERR "%s: unknown output power db revision:%x\n", | ||||
| 		       wiphy_name(dev->wiphy), data[0]); | ||||
| 		wiphy_err(dev->wiphy, "unknown output power db revision:%x\n", | ||||
| 			  data[0]); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -587,9 +583,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
| 				err = p54_convert_rev1(dev, curve_data); | ||||
| 				break; | ||||
| 			default: | ||||
| 				printk(KERN_ERR "%s: unknown curve data " | ||||
| 						"revision %d\n", | ||||
| 						wiphy_name(dev->wiphy), | ||||
| 				wiphy_err(dev->wiphy, | ||||
| 					  "unknown curve data revision %d\n", | ||||
| 					  curve_data->cal_method_rev); | ||||
| 				err = -ENODEV; | ||||
| 				break; | ||||
|  | @ -672,8 +667,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
| 
 | ||||
| 	if (!synth || !priv->iq_autocal || !priv->output_limit || | ||||
| 	    !priv->curve_data) { | ||||
| 		printk(KERN_ERR "%s: not all required entries found in eeprom!\n", | ||||
| 			wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, | ||||
| 			  "not all required entries found in eeprom!\n"); | ||||
| 		err = -EINVAL; | ||||
| 		goto err; | ||||
| 	} | ||||
|  | @ -699,14 +694,14 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
| 	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | ||||
| 		u8 perm_addr[ETH_ALEN]; | ||||
| 
 | ||||
| 		printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n", | ||||
| 			wiphy_name(dev->wiphy)); | ||||
| 		wiphy_warn(dev->wiphy, | ||||
| 			   "invalid hwaddr! using randomly generated mac addr\n"); | ||||
| 		random_ether_addr(perm_addr); | ||||
| 		SET_IEEE80211_PERM_ADDR(dev, perm_addr); | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n", | ||||
| 		wiphy_name(dev->wiphy),	dev->wiphy->perm_addr, priv->version, | ||||
| 	wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n", | ||||
| 		   dev->wiphy->perm_addr, priv->version, | ||||
| 		   p54_rf_chips[priv->rxhw]); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | @ -719,8 +714,7 @@ err: | |||
| 	priv->output_limit = NULL; | ||||
| 	priv->curve_data = NULL; | ||||
| 
 | ||||
| 	printk(KERN_ERR "%s: eeprom parse failed!\n", | ||||
| 		wiphy_name(dev->wiphy)); | ||||
| 	wiphy_err(dev->wiphy, "eeprom parse failed!\n"); | ||||
| 	return err; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(p54_parse_eeprom); | ||||
|  |  | |||
|  | @ -62,16 +62,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
| 			case FW_LM20: | ||||
| 			case FW_LM87: { | ||||
| 				char *iftype = (char *)bootrec->data; | ||||
| 				printk(KERN_INFO "%s: p54 detected a LM%c%c " | ||||
| 						 "firmware\n", | ||||
| 					wiphy_name(priv->hw->wiphy), | ||||
| 				wiphy_info(priv->hw->wiphy, | ||||
| 					   "p54 detected a LM%c%c firmware\n", | ||||
| 					   iftype[2], iftype[3]); | ||||
| 				break; | ||||
| 				} | ||||
| 			case FW_FMAC: | ||||
| 			default: | ||||
| 				printk(KERN_ERR "%s: unsupported firmware\n", | ||||
| 					wiphy_name(priv->hw->wiphy)); | ||||
| 				wiphy_err(priv->hw->wiphy, | ||||
| 					  "unsupported firmware\n"); | ||||
| 				return -ENODEV; | ||||
| 			} | ||||
| 			break; | ||||
|  | @ -125,15 +124,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
| 	} | ||||
| 
 | ||||
| 	if (fw_version) | ||||
| 		printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n", | ||||
| 			wiphy_name(priv->hw->wiphy), fw_version, | ||||
| 			priv->fw_var >> 8, priv->fw_var & 0xff); | ||||
| 		wiphy_info(priv->hw->wiphy, | ||||
| 			   "fw rev %s - softmac protocol %x.%x\n", | ||||
| 			   fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); | ||||
| 
 | ||||
| 	if (priv->fw_var < 0x500) | ||||
| 		printk(KERN_INFO "%s: you are using an obsolete firmware. " | ||||
| 		wiphy_info(priv->hw->wiphy, | ||||
| 			   "you are using an obsolete firmware. " | ||||
| 			   "visit http://wireless.kernel.org/en/users/Drivers/p54 " | ||||
| 		       "and grab one for \"kernel >= 2.6.28\"!\n", | ||||
| 			wiphy_name(priv->hw->wiphy)); | ||||
| 			   "and grab one for \"kernel >= 2.6.28\"!\n"); | ||||
| 
 | ||||
| 	if (priv->fw_var >= 0x300) { | ||||
| 		/* Firmware supports QoS, use it! */ | ||||
|  | @ -152,13 +151,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
| 		priv->hw->queues = P54_QUEUE_AC_NUM; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: cryptographic accelerator " | ||||
| 	       "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy), | ||||
| 		(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : | ||||
| 		"no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP | | ||||
| 		BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no", | ||||
| 		(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ? | ||||
| 		"YES" : "no"); | ||||
| 	wiphy_info(priv->hw->wiphy, | ||||
| 		   "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n", | ||||
| 		   (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no", | ||||
| 		   (priv->privacy_caps & | ||||
| 		    (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL)) | ||||
| 		   ? "YES" : "no", | ||||
| 		   (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) | ||||
| 		   ? "YES" : "no"); | ||||
| 
 | ||||
| 	if (priv->rx_keycache_size) { | ||||
| 		/*
 | ||||
|  | @ -247,8 +247,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf, | |||
| 
 | ||||
| 	if (!wait_for_completion_interruptible_timeout( | ||||
| 	     &priv->eeprom_comp, HZ)) { | ||||
| 		printk(KERN_ERR "%s: device does not respond!\n", | ||||
| 		       wiphy_name(priv->hw->wiphy)); | ||||
| 		wiphy_err(priv->hw->wiphy, "device does not respond!\n"); | ||||
| 		ret = -EBUSY; | ||||
| 	} | ||||
| 	priv->eeprom = NULL; | ||||
|  | @ -523,8 +522,8 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
| 	return 0; | ||||
| 
 | ||||
| err: | ||||
| 	printk(KERN_ERR "%s: frequency change to channel %d failed.\n", | ||||
| 	       wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel( | ||||
| 	wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", | ||||
| 		  ieee80211_frequency_to_channel( | ||||
| 			  priv->hw->conf.channel->center_freq)); | ||||
| 
 | ||||
| 	dev_kfree_skb_any(skb); | ||||
|  | @ -676,8 +675,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len, | |||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), algo); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "invalid cryptographic algorithm: %d\n", algo); | ||||
| 		dev_kfree_skb(skb); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  |  | |||
|  | @ -57,8 +57,8 @@ static void p54_update_leds(struct work_struct *work) | |||
| 
 | ||||
| 	err = p54_set_leds(priv); | ||||
| 	if (err && net_ratelimit()) | ||||
| 		printk(KERN_ERR "%s: failed to update LEDs (%d).\n", | ||||
| 			wiphy_name(priv->hw->wiphy), err); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "failed to update leds (%d).\n", err); | ||||
| 
 | ||||
| 	if (rerun) | ||||
| 		ieee80211_queue_delayed_work(priv->hw, &priv->led_work, | ||||
|  | @ -102,8 +102,8 @@ static int p54_register_led(struct p54_common *priv, | |||
| 
 | ||||
| 	err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); | ||||
| 	if (err) | ||||
| 		printk(KERN_ERR "%s: Failed to register %s LED.\n", | ||||
| 			wiphy_name(priv->hw->wiphy), name); | ||||
| 		wiphy_err(priv->hw->wiphy, | ||||
| 			  "failed to register %s led.\n", name); | ||||
| 	else | ||||
| 		led->registered = 1; | ||||
| 
 | ||||
|  |  | |||
|  | @ -507,6 +507,22 @@ out_unlock: | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int p54_get_survey(struct ieee80211_hw *dev, int idx, | ||||
| 				struct survey_info *survey) | ||||
| { | ||||
| 	struct p54_common *priv = dev->priv; | ||||
| 	struct ieee80211_conf *conf = &dev->conf; | ||||
| 
 | ||||
| 	if (idx != 0) | ||||
| 		return -ENOENT; | ||||
| 
 | ||||
| 	survey->channel = conf->channel; | ||||
| 	survey->filled = SURVEY_INFO_NOISE_DBM; | ||||
| 	survey->noise = clamp_t(s8, priv->noise, -128, 127); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct ieee80211_ops p54_ops = { | ||||
| 	.tx			= p54_tx_80211, | ||||
| 	.start			= p54_start, | ||||
|  | @ -523,6 +539,7 @@ static const struct ieee80211_ops p54_ops = { | |||
| 	.configure_filter	= p54_configure_filter, | ||||
| 	.conf_tx		= p54_conf_tx, | ||||
| 	.get_stats		= p54_get_stats, | ||||
| 	.get_survey		= p54_get_survey, | ||||
| }; | ||||
| 
 | ||||
| struct ieee80211_hw *p54_init_common(size_t priv_data_len) | ||||
|  |  | |||
|  | @ -466,8 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev) | |||
| 	P54P_READ(dev_int); | ||||
| 
 | ||||
| 	if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { | ||||
| 		printk(KERN_ERR "%s: Cannot boot firmware!\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "cannot boot firmware!\n"); | ||||
| 		p54p_stop(dev); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
|  |  | |||
|  | @ -38,8 +38,8 @@ static void p54_dump_tx_queue(struct p54_common *priv) | |||
| 	u32 largest_hole = 0, free; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->tx_queue.lock, flags); | ||||
| 	printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n", | ||||
| 	       wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue)); | ||||
| 	wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n", | ||||
| 		    skb_queue_len(&priv->tx_queue)); | ||||
| 
 | ||||
| 	prev_addr = priv->rx_start; | ||||
| 	skb_queue_walk(&priv->tx_queue, skb) { | ||||
|  | @ -48,10 +48,11 @@ static void p54_dump_tx_queue(struct p54_common *priv) | |||
| 		hdr = (void *) skb->data; | ||||
| 
 | ||||
| 		free = range->start_addr - prev_addr; | ||||
| 		printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x " | ||||
| 		wiphy_debug(priv->hw->wiphy, | ||||
| 			    "| [%02d] => [skb:%p skb_len:0x%04x " | ||||
| 			    "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} " | ||||
| 			    "mem:{start:%04x end:%04x, free:%d}]\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), i++, skb, skb->len, | ||||
| 			    i++, skb, skb->len, | ||||
| 			    le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len), | ||||
| 			    le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type), | ||||
| 			    range->start_addr, range->end_addr, free); | ||||
|  | @ -61,8 +62,9 @@ static void p54_dump_tx_queue(struct p54_common *priv) | |||
| 	} | ||||
| 	free = priv->rx_end - prev_addr; | ||||
| 	largest_hole = max(largest_hole, free); | ||||
| 	printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n", | ||||
| 	       wiphy_name(priv->hw->wiphy), free, largest_hole); | ||||
| 	wiphy_debug(priv->hw->wiphy, | ||||
| 		    "\\ --- [free: %d], largest free block: %d ---\n", | ||||
| 		    free, largest_hole); | ||||
| 	spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | ||||
| } | ||||
| #endif /* P54_MM_DEBUG */ | ||||
|  | @ -538,8 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) | |||
| 	case P54_TRAP_BEACON_TX: | ||||
| 		break; | ||||
| 	case P54_TRAP_RADAR: | ||||
| 		printk(KERN_INFO "%s: radar (freq:%d MHz)\n", | ||||
| 			wiphy_name(priv->hw->wiphy), freq); | ||||
| 		wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq); | ||||
| 		break; | ||||
| 	case P54_TRAP_NO_BEACON: | ||||
| 		if (priv->vif) | ||||
|  | @ -558,8 +559,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) | |||
| 		wiphy_rfkill_set_hw_state(priv->hw->wiphy, false); | ||||
| 		break; | ||||
| 	default: | ||||
| 		printk(KERN_INFO "%s: received event:%x freq:%d\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), event, freq); | ||||
| 		wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n", | ||||
| 			   event, freq); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | @ -584,8 +585,9 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb) | |||
| 		p54_rx_eeprom_readback(priv, skb); | ||||
| 		break; | ||||
| 	default: | ||||
| 		printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", | ||||
| 		       wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type)); | ||||
| 		wiphy_debug(priv->hw->wiphy, | ||||
| 			    "not handling 0x%02x type control frame\n", | ||||
| 			    le16_to_cpu(hdr->type)); | ||||
| 		break; | ||||
| 	} | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -350,6 +350,14 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
| 	enum cipher curr_cipher; | ||||
| 
 | ||||
| 	if (crypto->cmd == SET_KEY) { | ||||
| 		/*
 | ||||
| 		 * Disallow to set WEP key other than with index 0, | ||||
| 		 * it is known that not work at least on some hardware. | ||||
| 		 * SW crypto will be used in that case. | ||||
| 		 */ | ||||
| 		if (key->alg == ALG_WEP && key->keyidx != 0) | ||||
| 			return -EOPNOTSUPP; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Pairwise key will always be entry 0, but this | ||||
| 		 * could collide with a shared key on the same | ||||
|  | @ -376,7 +384,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
| 		if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher) | ||||
| 			return -EOPNOTSUPP; | ||||
| 
 | ||||
| 		rt2500usb_register_multiwrite(rt2x00dev, reg, | ||||
| 		rt2500usb_register_multiwrite(rt2x00dev, KEY_ENTRY(key->hw_key_idx), | ||||
| 					      crypto->key, sizeof(crypto->key)); | ||||
| 
 | ||||
| 		/*
 | ||||
|  | @ -817,6 +825,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 	rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg); | ||||
| 
 | ||||
| 	rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||||
| 	rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, CIPHER_NONE); | ||||
| 	rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | ||||
| 	rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0); | ||||
| 	rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||||
|  |  | |||
|  | @ -273,17 +273,24 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
| 	mutex_init(&intf->beacon_skb_mutex); | ||||
| 	intf->beacon = entry; | ||||
| 
 | ||||
| 	if (vif->type == NL80211_IFTYPE_AP) | ||||
| 		memcpy(&intf->bssid, vif->addr, ETH_ALEN); | ||||
| 	memcpy(&intf->mac, vif->addr, ETH_ALEN); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The MAC adddress must be configured after the device | ||||
| 	 * has been initialized. Otherwise the device can reset | ||||
| 	 * the MAC registers. | ||||
| 	 * The BSSID address must only be configured in AP mode, | ||||
| 	 * however we should not send an empty BSSID address for | ||||
| 	 * STA interfaces at this time, since this can cause | ||||
| 	 * invalid behavior in the device. | ||||
| 	 */ | ||||
| 	memcpy(&intf->mac, vif->addr, ETH_ALEN); | ||||
| 	if (vif->type == NL80211_IFTYPE_AP) { | ||||
| 		memcpy(&intf->bssid, vif->addr, ETH_ALEN); | ||||
| 		rt2x00lib_config_intf(rt2x00dev, intf, vif->type, | ||||
| 				      intf->mac, intf->bssid); | ||||
| 	} else { | ||||
| 		rt2x00lib_config_intf(rt2x00dev, intf, vif->type, | ||||
| 				      intf->mac, NULL); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Some filters depend on the current working mode. We can force | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| { | ||||
| 	struct rtl8180_priv *priv = dev->priv; | ||||
| 	unsigned int count = 32; | ||||
| 	u8 signal; | ||||
| 	u8 signal, agc, sq; | ||||
| 
 | ||||
| 	while (count--) { | ||||
| 		struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | ||||
|  | @ -132,12 +132,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 
 | ||||
| 			rx_status.antenna = (flags2 >> 15) & 1; | ||||
| 			rx_status.rate_idx = (flags >> 20) & 0xF; | ||||
| 			/* TODO: improve signal/rssi reporting for !rtl8185 */ | ||||
| 			signal = (flags2 >> 17) & 0x7F; | ||||
| 			agc = (flags2 >> 17) & 0x7F; | ||||
| 			if (priv->r8185) { | ||||
| 				if (rx_status.rate_idx > 3) | ||||
| 				signal = 90 - clamp_t(u8, signal, 25, 90); | ||||
| 					signal = 90 - clamp_t(u8, agc, 25, 90); | ||||
| 				else | ||||
| 				signal = 95 - clamp_t(u8, signal, 30, 95); | ||||
| 					signal = 95 - clamp_t(u8, agc, 30, 95); | ||||
| 			} else { | ||||
| 				sq = flags2 & 0xff; | ||||
| 				signal = priv->rf->calc_rssi(agc, sq); | ||||
| 			} | ||||
| 			rx_status.signal = signal; | ||||
| 			rx_status.freq = dev->conf.channel->center_freq; | ||||
| 			rx_status.band = dev->conf.channel->band; | ||||
|  | @ -357,7 +361,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
| 
 | ||||
| 	/* check success of reset */ | ||||
| 	if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { | ||||
| 		printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "reset timeout!\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -441,8 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | |||
| 					     &priv->rx_ring_dma); | ||||
| 
 | ||||
| 	if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { | ||||
| 		printk(KERN_ERR "%s: Cannot allocate RX ring\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "cannot allocate rx ring\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -499,8 +502,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, | |||
| 
 | ||||
| 	ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); | ||||
| 	if (!ring || (unsigned long)ring & 0xFF) { | ||||
| 		printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n", | ||||
| 		       wiphy_name(dev->wiphy), prio); | ||||
| 		wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n", | ||||
| 			  prio); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -565,8 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
| 	ret = request_irq(priv->pdev->irq, rtl8180_interrupt, | ||||
| 			  IRQF_SHARED, KBUILD_MODNAME, dev); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR "%s: failed to register IRQ handler\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "failed to register irq handler\n"); | ||||
| 		goto err_free_rings; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1103,9 +1105,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
| 		goto err_iounmap; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", | ||||
| 	       wiphy_name(dev->wiphy), mac_addr, | ||||
| 	       chip_name, priv->rf->name); | ||||
| 	wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", | ||||
| 		   mac_addr, chip_name, priv->rf->name); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) | |||
| 	rtl8180_write_phy(dev, 0x10, ant); | ||||
| } | ||||
| 
 | ||||
| static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) | ||||
| { | ||||
| 	if (agc > 60) | ||||
| 		return 65; | ||||
| 
 | ||||
| 	/* TODO(?): just return agc (or agc + 5) to avoid mult / div */ | ||||
| 	return 65 * agc / 60; | ||||
| } | ||||
| 
 | ||||
| static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | ||||
| 				   struct ieee80211_conf *conf) | ||||
| { | ||||
|  | @ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = { | |||
| 	.name		= "GCT", | ||||
| 	.init		= grf5101_rf_init, | ||||
| 	.stop		= grf5101_rf_stop, | ||||
| 	.set_chan	= grf5101_rf_set_channel | ||||
| 	.set_chan	= grf5101_rf_set_channel, | ||||
| 	.calc_rssi	= grf5101_rf_calc_rssi, | ||||
| }; | ||||
|  |  | |||
|  | @ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) | |||
| 	rtl8180_write_phy(dev, 0x10, ant); | ||||
| } | ||||
| 
 | ||||
| static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) | ||||
| { | ||||
| 	bool odd; | ||||
| 
 | ||||
| 	odd = !!(agc & 1); | ||||
| 
 | ||||
| 	agc >>= 1; | ||||
| 	if (odd) | ||||
| 		agc += 76; | ||||
| 	else | ||||
| 		agc += 66; | ||||
| 
 | ||||
| 	/* TODO: change addends above to avoid mult / div below */ | ||||
| 	return 65 * agc / 100; | ||||
| } | ||||
| 
 | ||||
| static void max2820_rf_set_channel(struct ieee80211_hw *dev, | ||||
| 				   struct ieee80211_conf *conf) | ||||
| { | ||||
|  | @ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = { | |||
| 	.name		= "Maxim", | ||||
| 	.init		= max2820_rf_init, | ||||
| 	.stop		= max2820_rf_stop, | ||||
| 	.set_chan	= max2820_rf_set_channel | ||||
| 	.set_chan	= max2820_rf_set_channel, | ||||
| 	.calc_rssi	= max2820_rf_calc_rssi, | ||||
| }; | ||||
|  |  | |||
|  | @ -50,7 +50,10 @@ static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) | |||
| 	udelay(10); | ||||
| 
 | ||||
| 	for (i = 15; i >= 0; i--) { | ||||
| 		u16 reg = reg80 | !!(bangdata & (1 << i)); | ||||
| 		u16 reg = reg80; | ||||
| 
 | ||||
| 		if (bangdata & (1 << i)) | ||||
| 			reg |= 1; | ||||
| 
 | ||||
| 		if (i & 1) | ||||
| 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); | ||||
|  |  | |||
|  | @ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| static u8 sa2400_rf_rssi_map[] = { | ||||
| 	0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, | ||||
| 	0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, | ||||
| 	0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, | ||||
| 	0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, | ||||
| 	0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, | ||||
| 	0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, | ||||
| 	0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, | ||||
| 	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, | ||||
| 	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, | ||||
| 	0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, | ||||
| }; | ||||
| 
 | ||||
| static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) | ||||
| { | ||||
| 	if (sq == 0x80) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if (sq > 78) | ||||
| 		return 32; | ||||
| 
 | ||||
| 	/* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ | ||||
| 	return 65 * sa2400_rf_rssi_map[sq] / 100; | ||||
| } | ||||
| 
 | ||||
| static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | ||||
| 				  struct ieee80211_conf *conf) | ||||
| { | ||||
|  | @ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = { | |||
| 	.name		= "Philips", | ||||
| 	.init		= sa2400_rf_init, | ||||
| 	.stop		= sa2400_rf_stop, | ||||
| 	.set_chan	= sa2400_rf_set_channel | ||||
| 	.set_chan	= sa2400_rf_set_channel, | ||||
| 	.calc_rssi	= sa2400_rf_calc_rssi, | ||||
| }; | ||||
|  |  | |||
|  | @ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) | |||
| 	} while (--i); | ||||
| 
 | ||||
| 	if (!i) { | ||||
| 		printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "reset timeout!\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -589,8 +589,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) | |||
| 	} while (--i); | ||||
| 
 | ||||
| 	if (!i) { | ||||
| 		printk(KERN_ERR "%s: eeprom reset timeout!\n", | ||||
| 		       wiphy_name(dev->wiphy)); | ||||
| 		wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1527,9 +1526,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
| 	mutex_init(&priv->conf_mutex); | ||||
| 	skb_queue_head_init(&priv->b_tx_status.queue); | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", | ||||
| 	       wiphy_name(dev->wiphy), mac_addr, | ||||
| 	       chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); | ||||
| 	wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n", | ||||
| 		   mac_addr, chip_name, priv->asic_rev, priv->rf->name, | ||||
| 		   priv->rfkill_mask); | ||||
| 
 | ||||
| #ifdef CONFIG_RTL8187_LEDS | ||||
| 	eeprom_93cx6_read(&eeprom, 0x3F, ®); | ||||
|  |  | |||
|  | @ -366,8 +366,8 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev) | |||
| 		rtl8225_write(dev, 0x02, 0x044d); | ||||
| 		msleep(100); | ||||
| 		if (!(rtl8225_read(dev, 6) & (1 << 7))) | ||||
| 			printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", | ||||
| 			       wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); | ||||
| 			wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | ||||
| 				   rtl8225_read(dev, 6)); | ||||
| 	} | ||||
| 
 | ||||
| 	rtl8225_write(dev, 0x0, 0x127); | ||||
|  | @ -735,8 +735,8 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev) | |||
| 		rtl8225_write(dev, 0x02, 0x044D); | ||||
| 		msleep(100); | ||||
| 		if (!(rtl8225_read(dev, 6) & (1 << 7))) | ||||
| 			printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", | ||||
| 			       wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); | ||||
| 			wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | ||||
| 				   rtl8225_read(dev, 6)); | ||||
| 	} | ||||
| 
 | ||||
| 	msleep(200); | ||||
|  |  | |||
|  | @ -193,6 +193,7 @@ struct rtl818x_rf_ops { | |||
| 	void (*stop)(struct ieee80211_hw *); | ||||
| 	void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); | ||||
| 	void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *); | ||||
| 	u8 (*calc_rssi)(u8 agc, u8 sq); | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  |  | |||
|  | @ -381,6 +381,9 @@ struct wl1251 { | |||
| 
 | ||||
| 	u32 chip_id; | ||||
| 	char fw_ver[21]; | ||||
| 
 | ||||
| 	/* Most recently reported noise in dBm */ | ||||
| 	s8 noise; | ||||
| }; | ||||
| 
 | ||||
| int wl1251_plt_start(struct wl1251 *wl); | ||||
|  |  | |||
|  | @ -225,7 +225,7 @@ static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag) | |||
| int wl1251_boot_run_firmware(struct wl1251 *wl) | ||||
| { | ||||
| 	int loop, ret; | ||||
| 	u32 chip_id, interrupt; | ||||
| 	u32 chip_id, acx_intr; | ||||
| 
 | ||||
| 	wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); | ||||
| 
 | ||||
|  | @ -242,15 +242,15 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
| 	loop = 0; | ||||
| 	while (loop++ < INIT_LOOP) { | ||||
| 		udelay(INIT_LOOP_DELAY); | ||||
| 		interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); | ||||
| 		acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); | ||||
| 
 | ||||
| 		if (interrupt == 0xffffffff) { | ||||
| 		if (acx_intr == 0xffffffff) { | ||||
| 			wl1251_error("error reading hardware complete " | ||||
| 				     "init indication"); | ||||
| 			return -EIO; | ||||
| 		} | ||||
| 		/* check that ACX_INTR_INIT_COMPLETE is enabled */ | ||||
| 		else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) { | ||||
| 		else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) { | ||||
| 			wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, | ||||
| 					   WL1251_ACX_INTR_INIT_COMPLETE); | ||||
| 			break; | ||||
|  |  | |||
|  | @ -175,8 +175,8 @@ struct cmd_read_write_memory { | |||
| #define WL1251_SCAN_NUM_PROBES 3 | ||||
| 
 | ||||
| struct wl1251_scan_parameters { | ||||
| 	u32 rx_config_options; | ||||
| 	u32 rx_filter_options; | ||||
| 	__le32 rx_config_options; | ||||
| 	__le32 rx_filter_options; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Scan options: | ||||
|  | @ -186,7 +186,7 @@ struct wl1251_scan_parameters { | |||
| 	 * bit 2: voice mode, 0 for normal scan. | ||||
| 	 * bit 3: scan priority, 1 for high priority. | ||||
| 	 */ | ||||
| 	u16 scan_options; | ||||
| 	__le16 scan_options; | ||||
| 
 | ||||
| 	/* Number of channels to scan */ | ||||
| 	u8 num_channels; | ||||
|  | @ -195,7 +195,7 @@ struct wl1251_scan_parameters { | |||
| 	u8 num_probe_requests; | ||||
| 
 | ||||
| 	/* Rate and modulation for probe requests */ | ||||
| 	u16 tx_rate; | ||||
| 	__le16 tx_rate; | ||||
| 
 | ||||
| 	u8 tid_trigger; | ||||
| 	u8 ssid_len; | ||||
|  | @ -204,8 +204,8 @@ struct wl1251_scan_parameters { | |||
| } __packed; | ||||
| 
 | ||||
| struct wl1251_scan_ch_parameters { | ||||
| 	u32 min_duration; /* in TU */ | ||||
| 	u32 max_duration; /* in TU */ | ||||
| 	__le32 min_duration; /* in TU */ | ||||
| 	__le32 max_duration; /* in TU */ | ||||
| 	u32 bssid_lsb; | ||||
| 	u16 bssid_msb; | ||||
| 
 | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 John W. Linville
						John W. Linville