Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John says: -------------------- I apologize for not having sent this sooner. FWIW, I was in a car somewhere between Illinois and North Carolina for most of the day Sunday and Monday... :-) This is (obviously) the last non-fix pull request for wireless bits intended for 3.5. It includes AP support for mwifiex, a variety of HCI and other updates for NFC, some brcmfmac and brcmsmac refactoring, a large batch of ssb and bcma updates, a batch of ath6kl updates, some cfg80211 and mac80211 updates/refactoring from Johannes Berg, a rather large collection of Bluetooth updates by way of Gustavo, and a variety of other bits here and there. -------------------- Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
				commit
				
					
						c3719a1ef5
					
				
			
		
					 173 changed files with 6623 additions and 5504 deletions
				
			
		| 
						 | 
					@ -534,6 +534,18 @@ Who:	Kees Cook <keescook@chromium.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
----------------------------
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:	Removing the pn544 raw driver.
 | 
				
			||||||
 | 
					When:	3.6
 | 
				
			||||||
 | 
					Why:	With the introduction of the NFC HCI and SHDL kernel layers, pn544.c
 | 
				
			||||||
 | 
						is being replaced by pn544_hci.c which is accessible through the netlink
 | 
				
			||||||
 | 
						and socket NFC APIs. Moreover, pn544.c is outdated and does not seem to
 | 
				
			||||||
 | 
						work properly with the latest Android stacks.
 | 
				
			||||||
 | 
						Having 2 drivers for the same hardware is confusing and as such we
 | 
				
			||||||
 | 
						should only keep the one following the kernel NFC APIs.
 | 
				
			||||||
 | 
					Who:	Samuel Ortiz <sameo@linux.intel.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
What:	setitimer accepts user NULL pointer (value)
 | 
					What:	setitimer accepts user NULL pointer (value)
 | 
				
			||||||
When:	3.6
 | 
					When:	3.6
 | 
				
			||||||
Why:	setitimer is not returning -EFAULT if user pointer is NULL. This
 | 
					Why:	setitimer is not returning -EFAULT if user pointer is NULL. This
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +22,9 @@ response to arrive.
 | 
				
			||||||
HCI events can also be received from the host controller. They will be handled
 | 
					HCI events can also be received from the host controller. They will be handled
 | 
				
			||||||
and a translation will be forwarded to NFC Core as needed.
 | 
					and a translation will be forwarded to NFC Core as needed.
 | 
				
			||||||
HCI uses 2 execution contexts:
 | 
					HCI uses 2 execution contexts:
 | 
				
			||||||
- one if for executing commands : nfc_hci_msg_tx_work(). Only one command
 | 
					- one for executing commands : nfc_hci_msg_tx_work(). Only one command
 | 
				
			||||||
can be executing at any given moment.
 | 
					can be executing at any given moment.
 | 
				
			||||||
- one if for dispatching received events and responses : nfc_hci_msg_rx_work()
 | 
					- one for dispatching received events and commands : nfc_hci_msg_rx_work().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HCI Session initialization:
 | 
					HCI Session initialization:
 | 
				
			||||||
---------------------------
 | 
					---------------------------
 | 
				
			||||||
| 
						 | 
					@ -52,18 +52,42 @@ entry points:
 | 
				
			||||||
struct nfc_hci_ops {
 | 
					struct nfc_hci_ops {
 | 
				
			||||||
	int (*open)(struct nfc_hci_dev *hdev);
 | 
						int (*open)(struct nfc_hci_dev *hdev);
 | 
				
			||||||
	void (*close)(struct nfc_hci_dev *hdev);
 | 
						void (*close)(struct nfc_hci_dev *hdev);
 | 
				
			||||||
 | 
						int (*hci_ready) (struct nfc_hci_dev *hdev);
 | 
				
			||||||
	int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
 | 
						int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
 | 
				
			||||||
	int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols);
 | 
						int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols);
 | 
				
			||||||
	int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate,
 | 
						int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate,
 | 
				
			||||||
				struct nfc_target *target);
 | 
									struct nfc_target *target);
 | 
				
			||||||
 | 
						int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
 | 
				
			||||||
 | 
										   struct nfc_target *target);
 | 
				
			||||||
 | 
						int (*data_exchange) (struct nfc_hci_dev *hdev,
 | 
				
			||||||
 | 
								      struct nfc_target *target,
 | 
				
			||||||
 | 
								      struct sk_buff *skb, struct sk_buff **res_skb);
 | 
				
			||||||
 | 
						int (*check_presence)(struct nfc_hci_dev *hdev,
 | 
				
			||||||
 | 
								      struct nfc_target *target);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
open() and close() shall turn the hardware on and off. xmit() shall simply
 | 
					- open() and close() shall turn the hardware on and off.
 | 
				
			||||||
write a frame to the chip. start_poll() is an optional entrypoint that shall
 | 
					- hci_ready() is an optional entry point that is called right after the hci
 | 
				
			||||||
set the hardware in polling mode. This must be implemented only if the hardware
 | 
					session has been set up. The driver can use it to do additional initialization
 | 
				
			||||||
uses proprietary gates or a mechanism slightly different from the HCI standard.
 | 
					that must be performed using HCI commands.
 | 
				
			||||||
target_from_gate() is another optional entrypoint to return the protocols
 | 
					- xmit() shall simply write a frame to the chip.
 | 
				
			||||||
 | 
					- start_poll() is an optional entrypoint that shall set the hardware in polling
 | 
				
			||||||
 | 
					mode. This must be implemented only if the hardware uses proprietary gates or a
 | 
				
			||||||
 | 
					mechanism slightly different from the HCI standard.
 | 
				
			||||||
 | 
					- target_from_gate() is an optional entrypoint to return the nfc protocols
 | 
				
			||||||
corresponding to a proprietary gate.
 | 
					corresponding to a proprietary gate.
 | 
				
			||||||
 | 
					- complete_target_discovered() is an optional entry point to let the driver
 | 
				
			||||||
 | 
					perform additional proprietary processing necessary to auto activate the
 | 
				
			||||||
 | 
					discovered target.
 | 
				
			||||||
 | 
					- data_exchange() must be implemented by the driver if proprietary HCI commands
 | 
				
			||||||
 | 
					are required to send data to the tag. Some tag types will require custom
 | 
				
			||||||
 | 
					commands, others can be written to using the standard HCI commands. The driver
 | 
				
			||||||
 | 
					can check the tag type and either do proprietary processing, or return 1 to ask
 | 
				
			||||||
 | 
					for standard processing.
 | 
				
			||||||
 | 
					- check_presence() is an optional entry point that will be called regularly
 | 
				
			||||||
 | 
					by the core to check that an activated tag is still in the field. If this is
 | 
				
			||||||
 | 
					not implemented, the core will not be able to push tag_lost events to the user
 | 
				
			||||||
 | 
					space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
On the rx path, the driver is responsible to push incoming HCP frames to HCI
 | 
					On the rx path, the driver is responsible to push incoming HCP frames to HCI
 | 
				
			||||||
using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
 | 
					using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
 | 
				
			||||||
| 
						 | 
					@ -99,7 +123,8 @@ fast, cannot sleep. stores incoming frames into an shdlc rx queue
 | 
				
			||||||
handles shdlc rx & tx queues. Dispatches HCI cmd responses.
 | 
					handles shdlc rx & tx queues. Dispatches HCI cmd responses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- HCI Tx Cmd worker (MSGTXWQ)
 | 
					- HCI Tx Cmd worker (MSGTXWQ)
 | 
				
			||||||
Serialize execution of HCI commands. Complete execution in case of resp timeout.
 | 
					Serializes execution of HCI commands. Completes execution in case of response
 | 
				
			||||||
 | 
					timeout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- HCI Rx worker (MSGRXWQ)
 | 
					- HCI Rx worker (MSGRXWQ)
 | 
				
			||||||
Dispatches incoming HCI commands or events.
 | 
					Dispatches incoming HCI commands or events.
 | 
				
			||||||
| 
						 | 
					@ -133,11 +158,11 @@ able to complete the command with a timeout error if no response arrive.
 | 
				
			||||||
SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function
 | 
					SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function
 | 
				
			||||||
handles shdlc framing in and out. It uses the driver xmit to send frames and
 | 
					handles shdlc framing in and out. It uses the driver xmit to send frames and
 | 
				
			||||||
receives incoming frames in an skb queue filled from the driver IRQ handler.
 | 
					receives incoming frames in an skb queue filled from the driver IRQ handler.
 | 
				
			||||||
SHDLC I(nformation) frames payload are HCP fragments. They are agregated to
 | 
					SHDLC I(nformation) frames payload are HCP fragments. They are aggregated to
 | 
				
			||||||
form complete HCI frames, which can be a response, command, or event.
 | 
					form complete HCI frames, which can be a response, command, or event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HCI Responses are dispatched immediately from this context to unblock
 | 
					HCI Responses are dispatched immediately from this context to unblock
 | 
				
			||||||
waiting command execution. Reponse processing involves invoking the completion
 | 
					waiting command execution. Response processing involves invoking the completion
 | 
				
			||||||
callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
 | 
					callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
 | 
				
			||||||
The completion callback will then wake the syscall context.
 | 
					The completion callback will then wake the syscall context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,6 +90,7 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 | 
				
			||||||
	char prefix[10];
 | 
						char prefix[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bus->bustype == SSB_BUSTYPE_PCI) {
 | 
						if (bus->bustype == SSB_BUSTYPE_PCI) {
 | 
				
			||||||
 | 
							memset(out, 0, sizeof(struct ssb_sprom));
 | 
				
			||||||
		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 | 
							snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 | 
				
			||||||
			 bus->host_pci->bus->number + 1,
 | 
								 bus->host_pci->bus->number + 1,
 | 
				
			||||||
			 PCI_SLOT(bus->host_pci->devfn));
 | 
								 PCI_SLOT(bus->host_pci->devfn));
 | 
				
			||||||
| 
						 | 
					@ -109,15 +110,9 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
 | 
				
			||||||
	/* Fill boardinfo structure */
 | 
						/* Fill boardinfo structure */
 | 
				
			||||||
	memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
 | 
						memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
 | 
						bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
 | 
				
			||||||
		iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
 | 
					 | 
				
			||||||
	if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
 | 
					 | 
				
			||||||
		iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
 | 
					 | 
				
			||||||
	if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
 | 
					 | 
				
			||||||
		iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
 | 
				
			||||||
	bcm47xx_fill_sprom(&iv->sprom, NULL);
 | 
						bcm47xx_fill_sprom(&iv->sprom, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 | 
						if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 | 
				
			||||||
| 
						 | 
					@ -166,12 +161,14 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (bus->hosttype) {
 | 
						switch (bus->hosttype) {
 | 
				
			||||||
	case BCMA_HOSTTYPE_PCI:
 | 
						case BCMA_HOSTTYPE_PCI:
 | 
				
			||||||
 | 
							memset(out, 0, sizeof(struct ssb_sprom));
 | 
				
			||||||
		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 | 
							snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
 | 
				
			||||||
			 bus->host_pci->bus->number + 1,
 | 
								 bus->host_pci->bus->number + 1,
 | 
				
			||||||
			 PCI_SLOT(bus->host_pci->devfn));
 | 
								 PCI_SLOT(bus->host_pci->devfn));
 | 
				
			||||||
		bcm47xx_fill_sprom(out, prefix);
 | 
							bcm47xx_fill_sprom(out, prefix);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	case BCMA_HOSTTYPE_SOC:
 | 
						case BCMA_HOSTTYPE_SOC:
 | 
				
			||||||
 | 
							memset(out, 0, sizeof(struct ssb_sprom));
 | 
				
			||||||
		bcm47xx_fill_sprom_ethernet(out, NULL);
 | 
							bcm47xx_fill_sprom_ethernet(out, NULL);
 | 
				
			||||||
		core = bcma_find_core(bus, BCMA_CORE_80211);
 | 
							core = bcma_find_core(bus, BCMA_CORE_80211);
 | 
				
			||||||
		if (core) {
 | 
							if (core) {
 | 
				
			||||||
| 
						 | 
					@ -197,6 +194,8 @@ static void __init bcm47xx_register_bcma(void)
 | 
				
			||||||
	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
 | 
						err = bcma_host_soc_register(&bcm47xx_bus.bcma);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		panic("Failed to initialize BCMA bus (err %d)", err);
 | 
							panic("Failed to initialize BCMA bus (err %d)", err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -165,6 +165,8 @@ static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
 | 
				
			||||||
					const char *prefix)
 | 
										const char *prefix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0);
 | 
						nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0);
 | 
				
			||||||
 | 
						if (!sprom->board_rev)
 | 
				
			||||||
 | 
							nvram_read_u16(NULL, NULL, "boardrev", &sprom->board_rev, 0);
 | 
				
			||||||
	nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0);
 | 
						nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0);
 | 
				
			||||||
	nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff);
 | 
						nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff);
 | 
				
			||||||
	nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff);
 | 
						nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff);
 | 
				
			||||||
| 
						 | 
					@ -555,8 +557,6 @@ void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
 | 
					void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	memset(sprom, 0, sizeof(struct ssb_sprom));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bcm47xx_fill_sprom_ethernet(sprom, prefix);
 | 
						bcm47xx_fill_sprom_ethernet(sprom, prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0);
 | 
						nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0);
 | 
				
			||||||
| 
						 | 
					@ -618,3 +618,27 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
 | 
				
			||||||
		bcm47xx_fill_sprom_r1(sprom, prefix);
 | 
							bcm47xx_fill_sprom_r1(sprom, prefix);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BCM47XX_SSB
 | 
				
			||||||
 | 
					void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
 | 
				
			||||||
 | 
									const char *prefix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0);
 | 
				
			||||||
 | 
						if (!boardinfo->vendor)
 | 
				
			||||||
 | 
							boardinfo->vendor = SSB_BOARDVENDOR_BCM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BCM47XX_BCMA
 | 
				
			||||||
 | 
					void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
 | 
				
			||||||
 | 
									 const char *prefix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0);
 | 
				
			||||||
 | 
						if (!boardinfo->vendor)
 | 
				
			||||||
 | 
							boardinfo->vendor = SSB_BOARDVENDOR_BCM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,4 +47,13 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type;
 | 
				
			||||||
void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
 | 
					void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
 | 
				
			||||||
void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
 | 
					void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BCM47XX_SSB
 | 
				
			||||||
 | 
					void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
 | 
				
			||||||
 | 
									const char *prefix);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_BCM47XX_BCMA
 | 
				
			||||||
 | 
					void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
 | 
				
			||||||
 | 
									 const char *prefix);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __ASM_BCM47XX_H */
 | 
					#endif /* __ASM_BCM47XX_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@ void bcma_core_disable(struct bcma_device *core, u32 flags)
 | 
				
			||||||
	udelay(10);
 | 
						udelay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
 | 
						bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
 | 
				
			||||||
 | 
						bcma_aread32(core, BCMA_RESET_CTL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(bcma_core_disable);
 | 
					EXPORT_SYMBOL_GPL(bcma_core_disable);
 | 
				
			||||||
| 
						 | 
					@ -77,7 +78,7 @@ void bcma_core_set_clockmode(struct bcma_device *core,
 | 
				
			||||||
			pr_err("HT force timeout\n");
 | 
								pr_err("HT force timeout\n");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BCMA_CLKMODE_DYNAMIC:
 | 
						case BCMA_CLKMODE_DYNAMIC:
 | 
				
			||||||
		pr_warn("Dynamic clockmode not supported yet!\n");
 | 
							bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,14 +24,12 @@ u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
 | 
				
			||||||
	return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
 | 
						return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
 | 
					static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
 | 
						pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
 | 
				
			||||||
	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
 | 
						pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
 | 
				
			||||||
	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
 | 
						pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 | 
					static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -170,13 +168,50 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
 | 
				
			||||||
		                     tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
 | 
							                     tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bcma_device *core = pc->core;
 | 
				
			||||||
 | 
						u16 val16, core_index;
 | 
				
			||||||
 | 
						uint regoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
 | 
				
			||||||
 | 
						core_index = (u16)core->core_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val16 = pcicore_read16(pc, regoff);
 | 
				
			||||||
 | 
						if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
 | 
				
			||||||
 | 
						     != core_index) {
 | 
				
			||||||
 | 
							val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
 | 
				
			||||||
 | 
								(val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
 | 
				
			||||||
 | 
							pcicore_write16(pc, regoff, val16);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
 | 
				
			||||||
 | 
					/* Needs to happen when coming out of 'standby'/'hibernate' */
 | 
				
			||||||
 | 
					static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 val16;
 | 
				
			||||||
 | 
						uint regoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val16 = pcicore_read16(pc, regoff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
 | 
				
			||||||
 | 
							val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
 | 
				
			||||||
 | 
							pcicore_write16(pc, regoff, val16);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**************************************************
 | 
					/**************************************************
 | 
				
			||||||
 * Init.
 | 
					 * Init.
 | 
				
			||||||
 **************************************************/
 | 
					 **************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
 | 
					static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						bcma_core_pci_fixcfg(pc);
 | 
				
			||||||
	bcma_pcicore_serdes_workaround(pc);
 | 
						bcma_pcicore_serdes_workaround(pc);
 | 
				
			||||||
 | 
						bcma_core_pci_config_fixup(pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
 | 
					void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
 | 
				
			||||||
| 
						 | 
					@ -224,3 +259,17 @@ out:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
 | 
					EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
 | 
				
			||||||
 | 
						if (extend)
 | 
				
			||||||
 | 
							w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
 | 
				
			||||||
 | 
						bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
 | 
				
			||||||
 | 
						bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +119,7 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
 | 
				
			||||||
		if (unlikely(!addr))
 | 
							if (unlikely(!addr))
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		mmio = ioremap_nocache(addr, len);
 | 
							mmio = ioremap_nocache(addr, sizeof(val));
 | 
				
			||||||
		if (!mmio)
 | 
							if (!mmio)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,7 +171,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
 | 
				
			||||||
			addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
 | 
								addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
 | 
				
			||||||
			addr |= (func << 8);
 | 
								addr |= (func << 8);
 | 
				
			||||||
			addr |= (off & 0xfc);
 | 
								addr |= (off & 0xfc);
 | 
				
			||||||
			mmio = ioremap_nocache(addr, len);
 | 
								mmio = ioremap_nocache(addr, sizeof(val));
 | 
				
			||||||
			if (!mmio)
 | 
								if (!mmio)
 | 
				
			||||||
				goto out;
 | 
									goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -180,7 +180,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
 | 
				
			||||||
		if (unlikely(!addr))
 | 
							if (unlikely(!addr))
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		mmio = ioremap_nocache(addr, len);
 | 
							mmio = ioremap_nocache(addr, sizeof(val));
 | 
				
			||||||
		if (!mmio)
 | 
							if (!mmio)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -491,8 +491,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
 | 
				
			||||||
	/* Ok, ready to run, register it to the system.
 | 
						/* Ok, ready to run, register it to the system.
 | 
				
			||||||
	 * The following needs change, if we want to port hostmode
 | 
						 * The following needs change, if we want to port hostmode
 | 
				
			||||||
	 * to non-MIPS platform. */
 | 
						 * to non-MIPS platform. */
 | 
				
			||||||
	io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
 | 
						io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
 | 
				
			||||||
						     0x04000000);
 | 
											     resource_size(&pc_host->mem_resource));
 | 
				
			||||||
	pc_host->pci_controller.io_map_base = io_map_base;
 | 
						pc_host->pci_controller.io_map_base = io_map_base;
 | 
				
			||||||
	set_io_port_base(pc_host->pci_controller.io_map_base);
 | 
						set_io_port_base(pc_host->pci_controller.io_map_base);
 | 
				
			||||||
	/* Give some time to the PCI controller to configure itself with the new
 | 
						/* Give some time to the PCI controller to configure itself with the new
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,6 +201,9 @@ static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
 | 
				
			||||||
	bus->hosttype = BCMA_HOSTTYPE_PCI;
 | 
						bus->hosttype = BCMA_HOSTTYPE_PCI;
 | 
				
			||||||
	bus->ops = &bcma_host_pci_ops;
 | 
						bus->ops = &bcma_host_pci_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
 | 
				
			||||||
 | 
						bus->boardinfo.type = bus->host_pci->subsystem_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Register */
 | 
						/* Register */
 | 
				
			||||||
	err = bcma_bus_register(bus);
 | 
						err = bcma_bus_register(bus);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
| 
						 | 
					@ -222,7 +225,7 @@ err_kfree_bus:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bcma_host_pci_remove(struct pci_dev *dev)
 | 
					static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bcma_bus *bus = pci_get_drvdata(dev);
 | 
						struct bcma_bus *bus = pci_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -277,7 +280,7 @@ static struct pci_driver bcma_pci_bridge_driver = {
 | 
				
			||||||
	.name = "bcma-pci-bridge",
 | 
						.name = "bcma-pci-bridge",
 | 
				
			||||||
	.id_table = bcma_pci_bridge_tbl,
 | 
						.id_table = bcma_pci_bridge_tbl,
 | 
				
			||||||
	.probe = bcma_host_pci_probe,
 | 
						.probe = bcma_host_pci_probe,
 | 
				
			||||||
	.remove = bcma_host_pci_remove,
 | 
						.remove = __devexit_p(bcma_host_pci_remove),
 | 
				
			||||||
	.driver.pm = BCMA_PM_OPS,
 | 
						.driver.pm = BCMA_PM_OPS,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,14 @@ struct bcma_device_id_name {
 | 
				
			||||||
	u16 id;
 | 
						u16 id;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
struct bcma_device_id_name bcma_device_names[] = {
 | 
					
 | 
				
			||||||
 | 
					static const struct bcma_device_id_name bcma_arm_device_names[] = {
 | 
				
			||||||
 | 
						{ BCMA_CORE_ARM_1176, "ARM 1176" },
 | 
				
			||||||
 | 
						{ BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
 | 
				
			||||||
 | 
						{ BCMA_CORE_ARM_CM3, "ARM CM3" },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct bcma_device_id_name bcma_bcm_device_names[] = {
 | 
				
			||||||
	{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
 | 
						{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
 | 
				
			||||||
	{ BCMA_CORE_INVALID, "Invalid" },
 | 
						{ BCMA_CORE_INVALID, "Invalid" },
 | 
				
			||||||
	{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
 | 
						{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
 | 
				
			||||||
| 
						 | 
					@ -27,7 +34,6 @@ struct bcma_device_id_name bcma_device_names[] = {
 | 
				
			||||||
	{ BCMA_CORE_SRAM, "SRAM" },
 | 
						{ BCMA_CORE_SRAM, "SRAM" },
 | 
				
			||||||
	{ BCMA_CORE_SDRAM, "SDRAM" },
 | 
						{ BCMA_CORE_SDRAM, "SDRAM" },
 | 
				
			||||||
	{ BCMA_CORE_PCI, "PCI" },
 | 
						{ BCMA_CORE_PCI, "PCI" },
 | 
				
			||||||
	{ BCMA_CORE_MIPS, "MIPS" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_ETHERNET, "Fast Ethernet" },
 | 
						{ BCMA_CORE_ETHERNET, "Fast Ethernet" },
 | 
				
			||||||
	{ BCMA_CORE_V90, "V90" },
 | 
						{ BCMA_CORE_V90, "V90" },
 | 
				
			||||||
	{ BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
 | 
						{ BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
 | 
				
			||||||
| 
						 | 
					@ -44,7 +50,6 @@ struct bcma_device_id_name bcma_device_names[] = {
 | 
				
			||||||
	{ BCMA_CORE_PHY_A, "PHY A" },
 | 
						{ BCMA_CORE_PHY_A, "PHY A" },
 | 
				
			||||||
	{ BCMA_CORE_PHY_B, "PHY B" },
 | 
						{ BCMA_CORE_PHY_B, "PHY B" },
 | 
				
			||||||
	{ BCMA_CORE_PHY_G, "PHY G" },
 | 
						{ BCMA_CORE_PHY_G, "PHY G" },
 | 
				
			||||||
	{ BCMA_CORE_MIPS_3302, "MIPS 3302" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
 | 
						{ BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
 | 
				
			||||||
	{ BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
 | 
						{ BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
 | 
				
			||||||
	{ BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
 | 
						{ BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
 | 
				
			||||||
| 
						 | 
					@ -58,15 +63,11 @@ struct bcma_device_id_name bcma_device_names[] = {
 | 
				
			||||||
	{ BCMA_CORE_PHY_N, "PHY N" },
 | 
						{ BCMA_CORE_PHY_N, "PHY N" },
 | 
				
			||||||
	{ BCMA_CORE_SRAM_CTL, "SRAM Controller" },
 | 
						{ BCMA_CORE_SRAM_CTL, "SRAM Controller" },
 | 
				
			||||||
	{ BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
 | 
						{ BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
 | 
				
			||||||
	{ BCMA_CORE_ARM_1176, "ARM 1176" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_PHY_LP, "PHY LP" },
 | 
						{ BCMA_CORE_PHY_LP, "PHY LP" },
 | 
				
			||||||
	{ BCMA_CORE_PMU, "PMU" },
 | 
						{ BCMA_CORE_PMU, "PMU" },
 | 
				
			||||||
	{ BCMA_CORE_PHY_SSN, "PHY SSN" },
 | 
						{ BCMA_CORE_PHY_SSN, "PHY SSN" },
 | 
				
			||||||
	{ BCMA_CORE_SDIO_DEV, "SDIO Device" },
 | 
						{ BCMA_CORE_SDIO_DEV, "SDIO Device" },
 | 
				
			||||||
	{ BCMA_CORE_ARM_CM3, "ARM CM3" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_PHY_HT, "PHY HT" },
 | 
						{ BCMA_CORE_PHY_HT, "PHY HT" },
 | 
				
			||||||
	{ BCMA_CORE_MIPS_74K, "MIPS 74K" },
 | 
					 | 
				
			||||||
	{ BCMA_CORE_MAC_GBIT, "GBit MAC" },
 | 
						{ BCMA_CORE_MAC_GBIT, "GBit MAC" },
 | 
				
			||||||
	{ BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
 | 
						{ BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
 | 
				
			||||||
	{ BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
 | 
						{ BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
 | 
				
			||||||
| 
						 | 
					@ -79,16 +80,41 @@ struct bcma_device_id_name bcma_device_names[] = {
 | 
				
			||||||
	{ BCMA_CORE_SHIM, "SHIM" },
 | 
						{ BCMA_CORE_SHIM, "SHIM" },
 | 
				
			||||||
	{ BCMA_CORE_DEFAULT, "Default" },
 | 
						{ BCMA_CORE_DEFAULT, "Default" },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char *bcma_device_name(struct bcma_device_id *id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (id->manuf == BCMA_MANUF_BCM) {
 | 
					static const struct bcma_device_id_name bcma_mips_device_names[] = {
 | 
				
			||||||
		for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
 | 
						{ BCMA_CORE_MIPS, "MIPS" },
 | 
				
			||||||
			if (bcma_device_names[i].id == id->id)
 | 
						{ BCMA_CORE_MIPS_3302, "MIPS 3302" },
 | 
				
			||||||
				return bcma_device_names[i].name;
 | 
						{ BCMA_CORE_MIPS_74K, "MIPS 74K" },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *bcma_device_name(const struct bcma_device_id *id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct bcma_device_id_name *names;
 | 
				
			||||||
 | 
						int size, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* search manufacturer specific names */
 | 
				
			||||||
 | 
						switch (id->manuf) {
 | 
				
			||||||
 | 
						case BCMA_MANUF_ARM:
 | 
				
			||||||
 | 
							names = bcma_arm_device_names;
 | 
				
			||||||
 | 
							size = ARRAY_SIZE(bcma_arm_device_names);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BCMA_MANUF_BCM:
 | 
				
			||||||
 | 
							names = bcma_bcm_device_names;
 | 
				
			||||||
 | 
							size = ARRAY_SIZE(bcma_bcm_device_names);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BCMA_MANUF_MIPS:
 | 
				
			||||||
 | 
							names = bcma_mips_device_names;
 | 
				
			||||||
 | 
							size = ARRAY_SIZE(bcma_mips_device_names);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return "UNKNOWN";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < size; i++) {
 | 
				
			||||||
 | 
							if (names[i].id == id->id)
 | 
				
			||||||
 | 
								return names[i].name;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return "UNKNOWN";
 | 
						return "UNKNOWN";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,6 +181,22 @@ static int bcma_sprom_valid(const u16 *sprom)
 | 
				
			||||||
#define SPEX(_field, _offset, _mask, _shift)	\
 | 
					#define SPEX(_field, _offset, _mask, _shift)	\
 | 
				
			||||||
	bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
 | 
						bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SPEX32(_field, _offset, _mask, _shift)	\
 | 
				
			||||||
 | 
						bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
 | 
				
			||||||
 | 
									sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SPEX_ARRAY8(_field, _offset, _mask, _shift)	\
 | 
				
			||||||
 | 
						do {	\
 | 
				
			||||||
 | 
							SPEX(_field[0], _offset +  0, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[1], _offset +  2, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[2], _offset +  4, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[3], _offset +  6, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[4], _offset +  8, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[5], _offset + 10, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[6], _offset + 12, _mask, _shift);	\
 | 
				
			||||||
 | 
							SPEX(_field[7], _offset + 14, _mask, _shift);	\
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 | 
					static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 v, o;
 | 
						u16 v, o;
 | 
				
			||||||
| 
						 | 
					@ -243,7 +259,8 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 | 
				
			||||||
	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
 | 
						SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
 | 
				
			||||||
	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
 | 
						SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
 | 
						SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
 | 
				
			||||||
 | 
						SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Extract cores power info info */
 | 
						/* Extract cores power info info */
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
 | 
						for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
 | 
				
			||||||
| 
						 | 
					@ -298,6 +315,136 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 | 
				
			||||||
	     SSB_SROM8_FEM_TR_ISO_SHIFT);
 | 
						     SSB_SROM8_FEM_TR_ISO_SHIFT);
 | 
				
			||||||
	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
 | 
						SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
 | 
				
			||||||
	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
 | 
						     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
 | 
				
			||||||
 | 
						     SSB_SPROM8_ANTAVAIL_A_SHIFT);
 | 
				
			||||||
 | 
						SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
 | 
				
			||||||
 | 
						     SSB_SPROM8_ANTAVAIL_BG_SHIFT);
 | 
				
			||||||
 | 
						SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
 | 
				
			||||||
 | 
						SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
 | 
				
			||||||
 | 
						     SSB_SPROM8_ITSSI_BG_SHIFT);
 | 
				
			||||||
 | 
						SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
 | 
				
			||||||
 | 
						SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
 | 
				
			||||||
 | 
						     SSB_SPROM8_ITSSI_A_SHIFT);
 | 
				
			||||||
 | 
						SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
 | 
				
			||||||
 | 
						SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
 | 
				
			||||||
 | 
						     SSB_SPROM8_MAXP_AL_SHIFT);
 | 
				
			||||||
 | 
						SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
 | 
				
			||||||
 | 
						SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
 | 
				
			||||||
 | 
						     SSB_SPROM8_GPIOA_P1_SHIFT);
 | 
				
			||||||
 | 
						SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
 | 
				
			||||||
 | 
						SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
 | 
				
			||||||
 | 
						     SSB_SPROM8_GPIOB_P3_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
 | 
				
			||||||
 | 
						SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TRI5G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
 | 
				
			||||||
 | 
						SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TRI5GH_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RXPO2G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RXPO5G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
 | 
				
			||||||
 | 
						SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RSSISMC2G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RSSISAV2G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_BXA2G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
 | 
				
			||||||
 | 
						SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RSSISMC5G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RSSISAV5G_SHIFT);
 | 
				
			||||||
 | 
						SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
 | 
				
			||||||
 | 
						     SSB_SPROM8_BXA5G_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Extract the antenna gain values. */
 | 
				
			||||||
 | 
						SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
 | 
				
			||||||
 | 
						     SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
 | 
				
			||||||
 | 
						SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
 | 
				
			||||||
 | 
						     SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
 | 
				
			||||||
 | 
						SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
 | 
				
			||||||
 | 
						     SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
 | 
				
			||||||
 | 
						SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
 | 
				
			||||||
 | 
						     SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
 | 
				
			||||||
 | 
						     SSB_SPROM8_LEDDC_ON_SHIFT);
 | 
				
			||||||
 | 
						SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
 | 
				
			||||||
 | 
						     SSB_SPROM8_LEDDC_OFF_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
 | 
				
			||||||
 | 
						SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
 | 
				
			||||||
 | 
						SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TXRXC_SWITCH_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
 | 
				
			||||||
 | 
						SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
 | 
				
			||||||
 | 
						     SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
 | 
				
			||||||
 | 
						     SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
 | 
				
			||||||
 | 
						     SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
 | 
				
			||||||
 | 
						     SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
 | 
				
			||||||
 | 
						     SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
 | 
				
			||||||
 | 
						     SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
 | 
				
			||||||
 | 
						SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
 | 
				
			||||||
 | 
						     SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
 | 
				
			||||||
 | 
						     SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
 | 
				
			||||||
 | 
						SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
 | 
				
			||||||
 | 
						     SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
 | 
				
			||||||
 | 
						     SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
 | 
				
			||||||
 | 
						SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
 | 
				
			||||||
 | 
						     SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
 | 
				
			||||||
 | 
						SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
 | 
				
			||||||
 | 
						     SSB_SPROM8_THERMAL_TRESH_SHIFT);
 | 
				
			||||||
 | 
						SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
 | 
				
			||||||
 | 
						     SSB_SPROM8_THERMAL_OFFSET_SHIFT);
 | 
				
			||||||
 | 
						SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TEMPDELTA_PHYCAL,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
 | 
				
			||||||
 | 
						SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
 | 
				
			||||||
 | 
						SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TEMPDELTA_HYSTERESIS,
 | 
				
			||||||
 | 
						     SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,6 +81,9 @@ static struct usb_device_id ath3k_table[] = {
 | 
				
			||||||
	/* Atheros AR5BBU12 with sflash firmware */
 | 
						/* Atheros AR5BBU12 with sflash firmware */
 | 
				
			||||||
	{ USB_DEVICE(0x0489, 0xE02C) },
 | 
						{ USB_DEVICE(0x0489, 0xE02C) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Atheros AR5BBU22 with sflash firmware */
 | 
				
			||||||
 | 
						{ USB_DEVICE(0x0489, 0xE03C) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ }	/* Terminating entry */
 | 
						{ }	/* Terminating entry */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +102,9 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 | 
				
			||||||
	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 | 
						{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 | 
				
			||||||
	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 | 
						{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Atheros AR5BBU22 with sflash firmware */
 | 
				
			||||||
 | 
						{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ }	/* Terminating entry */
 | 
						{ }	/* Terminating entry */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,7 @@ struct btmrvl_adapter {
 | 
				
			||||||
	u8 wakeup_tries;
 | 
						u8 wakeup_tries;
 | 
				
			||||||
	wait_queue_head_t cmd_wait_q;
 | 
						wait_queue_head_t cmd_wait_q;
 | 
				
			||||||
	u8 cmd_complete;
 | 
						u8 cmd_complete;
 | 
				
			||||||
 | 
						bool is_suspended;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct btmrvl_private {
 | 
					struct btmrvl_private {
 | 
				
			||||||
| 
						 | 
					@ -139,8 +140,10 @@ void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
 | 
				
			||||||
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
 | 
					int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
 | 
					int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
 | 
				
			||||||
 | 
					int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
 | 
				
			||||||
int btmrvl_enable_ps(struct btmrvl_private *priv);
 | 
					int btmrvl_enable_ps(struct btmrvl_private *priv);
 | 
				
			||||||
int btmrvl_prepare_command(struct btmrvl_private *priv);
 | 
					int btmrvl_prepare_command(struct btmrvl_private *priv);
 | 
				
			||||||
 | 
					int btmrvl_enable_hs(struct btmrvl_private *priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
void btmrvl_debugfs_init(struct hci_dev *hdev);
 | 
					void btmrvl_debugfs_init(struct hci_dev *hdev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,6 +200,36 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 | 
					EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sk_buff *skb;
 | 
				
			||||||
 | 
						struct btmrvl_cmd *cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
 | 
				
			||||||
 | 
						if (!skb) {
 | 
				
			||||||
 | 
							BT_ERR("No free skb");
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
 | 
				
			||||||
 | 
						cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
 | 
				
			||||||
 | 
											   BT_CMD_HOST_SLEEP_CONFIG));
 | 
				
			||||||
 | 
						cmd->length = 2;
 | 
				
			||||||
 | 
						cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
 | 
				
			||||||
 | 
						cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						skb->dev = (void *) priv->btmrvl_dev.hcidev;
 | 
				
			||||||
 | 
						skb_queue_head(&priv->adapter->tx_queue, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", cmd->data[0],
 | 
				
			||||||
 | 
						       cmd->data[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int btmrvl_enable_ps(struct btmrvl_private *priv)
 | 
					int btmrvl_enable_ps(struct btmrvl_private *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb;
 | 
						struct sk_buff *skb;
 | 
				
			||||||
| 
						 | 
					@ -232,7 +262,7 @@ int btmrvl_enable_ps(struct btmrvl_private *priv)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
 | 
					EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int btmrvl_enable_hs(struct btmrvl_private *priv)
 | 
					int btmrvl_enable_hs(struct btmrvl_private *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb;
 | 
						struct sk_buff *skb;
 | 
				
			||||||
	struct btmrvl_cmd *cmd;
 | 
						struct btmrvl_cmd *cmd;
 | 
				
			||||||
| 
						 | 
					@ -268,35 +298,15 @@ static int btmrvl_enable_hs(struct btmrvl_private *priv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int btmrvl_prepare_command(struct btmrvl_private *priv)
 | 
					int btmrvl_prepare_command(struct btmrvl_private *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb = NULL;
 | 
					 | 
				
			||||||
	struct btmrvl_cmd *cmd;
 | 
					 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->btmrvl_dev.hscfgcmd) {
 | 
						if (priv->btmrvl_dev.hscfgcmd) {
 | 
				
			||||||
		priv->btmrvl_dev.hscfgcmd = 0;
 | 
							priv->btmrvl_dev.hscfgcmd = 0;
 | 
				
			||||||
 | 
							btmrvl_send_hscfg_cmd(priv);
 | 
				
			||||||
		skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
 | 
					 | 
				
			||||||
		if (skb == NULL) {
 | 
					 | 
				
			||||||
			BT_ERR("No free skb");
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
 | 
					 | 
				
			||||||
		cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG));
 | 
					 | 
				
			||||||
		cmd->length = 2;
 | 
					 | 
				
			||||||
		cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
 | 
					 | 
				
			||||||
		cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		skb->dev = (void *) priv->btmrvl_dev.hcidev;
 | 
					 | 
				
			||||||
		skb_queue_head(&priv->adapter->tx_queue, skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x",
 | 
					 | 
				
			||||||
						cmd->data[0], cmd->data[1]);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->btmrvl_dev.pscmd) {
 | 
						if (priv->btmrvl_dev.pscmd) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -339,9 +339,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	kfree(tmphlprbuf);
 | 
						kfree(tmphlprbuf);
 | 
				
			||||||
	if (fw_helper)
 | 
					 | 
				
			||||||
	release_firmware(fw_helper);
 | 
						release_firmware(fw_helper);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -484,10 +482,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	kfree(tmpfwbuf);
 | 
						kfree(tmpfwbuf);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (fw_firmware)
 | 
					 | 
				
			||||||
	release_firmware(fw_firmware);
 | 
						release_firmware(fw_firmware);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1013,6 +1008,9 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
 | 
				
			||||||
	priv->btmrvl_dev.psmode = 1;
 | 
						priv->btmrvl_dev.psmode = 1;
 | 
				
			||||||
	btmrvl_enable_ps(priv);
 | 
						btmrvl_enable_ps(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->btmrvl_dev.gpio_gap = 0xffff;
 | 
				
			||||||
 | 
						btmrvl_send_hscfg_cmd(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
disable_host_int:
 | 
					disable_host_int:
 | 
				
			||||||
| 
						 | 
					@ -1048,11 +1046,111 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int btmrvl_sdio_suspend(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sdio_func *func = dev_to_sdio_func(dev);
 | 
				
			||||||
 | 
						struct btmrvl_sdio_card *card;
 | 
				
			||||||
 | 
						struct btmrvl_private *priv;
 | 
				
			||||||
 | 
						mmc_pm_flag_t pm_flags;
 | 
				
			||||||
 | 
						struct hci_dev *hcidev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (func) {
 | 
				
			||||||
 | 
							pm_flags = sdio_get_host_pm_caps(func);
 | 
				
			||||||
 | 
							BT_DBG("%s: suspend: PM flags = 0x%x", sdio_func_id(func),
 | 
				
			||||||
 | 
							       pm_flags);
 | 
				
			||||||
 | 
							if (!(pm_flags & MMC_PM_KEEP_POWER)) {
 | 
				
			||||||
 | 
								BT_ERR("%s: cannot remain alive while suspended",
 | 
				
			||||||
 | 
								       sdio_func_id(func));
 | 
				
			||||||
 | 
								return -ENOSYS;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							card = sdio_get_drvdata(func);
 | 
				
			||||||
 | 
							if (!card || !card->priv) {
 | 
				
			||||||
 | 
								BT_ERR("card or priv structure is not valid");
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							BT_ERR("sdio_func is not specified");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv = card->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->adapter->hs_state != HS_ACTIVATED) {
 | 
				
			||||||
 | 
							if (btmrvl_enable_hs(priv)) {
 | 
				
			||||||
 | 
								BT_ERR("HS not actived, suspend failed!");
 | 
				
			||||||
 | 
								return -EBUSY;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hcidev = priv->btmrvl_dev.hcidev;
 | 
				
			||||||
 | 
						BT_DBG("%s: SDIO suspend", hcidev->name);
 | 
				
			||||||
 | 
						hci_suspend_dev(hcidev);
 | 
				
			||||||
 | 
						skb_queue_purge(&priv->adapter->tx_queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->adapter->is_suspended = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We will keep the power when hs enabled successfully */
 | 
				
			||||||
 | 
						if (priv->adapter->hs_state == HS_ACTIVATED) {
 | 
				
			||||||
 | 
							BT_DBG("suspend with MMC_PM_KEEP_POWER");
 | 
				
			||||||
 | 
							return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							BT_DBG("suspend without MMC_PM_KEEP_POWER");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int btmrvl_sdio_resume(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sdio_func *func = dev_to_sdio_func(dev);
 | 
				
			||||||
 | 
						struct btmrvl_sdio_card *card;
 | 
				
			||||||
 | 
						struct btmrvl_private *priv;
 | 
				
			||||||
 | 
						mmc_pm_flag_t pm_flags;
 | 
				
			||||||
 | 
						struct hci_dev *hcidev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (func) {
 | 
				
			||||||
 | 
							pm_flags = sdio_get_host_pm_caps(func);
 | 
				
			||||||
 | 
							BT_DBG("%s: resume: PM flags = 0x%x", sdio_func_id(func),
 | 
				
			||||||
 | 
							       pm_flags);
 | 
				
			||||||
 | 
							card = sdio_get_drvdata(func);
 | 
				
			||||||
 | 
							if (!card || !card->priv) {
 | 
				
			||||||
 | 
								BT_ERR("card or priv structure is not valid");
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							BT_ERR("sdio_func is not specified");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						priv = card->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!priv->adapter->is_suspended) {
 | 
				
			||||||
 | 
							BT_DBG("device already resumed");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->adapter->is_suspended = false;
 | 
				
			||||||
 | 
						hcidev = priv->btmrvl_dev.hcidev;
 | 
				
			||||||
 | 
						BT_DBG("%s: SDIO resume", hcidev->name);
 | 
				
			||||||
 | 
						hci_resume_dev(hcidev);
 | 
				
			||||||
 | 
						priv->hw_wakeup_firmware(priv);
 | 
				
			||||||
 | 
						priv->adapter->hs_state = HS_DEACTIVATED;
 | 
				
			||||||
 | 
						BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dev_pm_ops btmrvl_sdio_pm_ops = {
 | 
				
			||||||
 | 
						.suspend	= btmrvl_sdio_suspend,
 | 
				
			||||||
 | 
						.resume		= btmrvl_sdio_resume,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sdio_driver bt_mrvl_sdio = {
 | 
					static struct sdio_driver bt_mrvl_sdio = {
 | 
				
			||||||
	.name		= "btmrvl_sdio",
 | 
						.name		= "btmrvl_sdio",
 | 
				
			||||||
	.id_table	= btmrvl_sdio_ids,
 | 
						.id_table	= btmrvl_sdio_ids,
 | 
				
			||||||
	.probe		= btmrvl_sdio_probe,
 | 
						.probe		= btmrvl_sdio_probe,
 | 
				
			||||||
	.remove		= btmrvl_sdio_remove,
 | 
						.remove		= btmrvl_sdio_remove,
 | 
				
			||||||
 | 
						.drv = {
 | 
				
			||||||
 | 
							.owner = THIS_MODULE,
 | 
				
			||||||
 | 
							.pm = &btmrvl_sdio_pm_ops,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init btmrvl_sdio_init_module(void)
 | 
					static int __init btmrvl_sdio_init_module(void)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,6 +143,9 @@ static struct usb_device_id blacklist_table[] = {
 | 
				
			||||||
	/* Atheros AR5BBU12 with sflash firmware */
 | 
						/* Atheros AR5BBU12 with sflash firmware */
 | 
				
			||||||
	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
 | 
						{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Atheros AR5BBU12 with sflash firmware */
 | 
				
			||||||
 | 
						{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Broadcom BCM2035 */
 | 
						/* Broadcom BCM2035 */
 | 
				
			||||||
	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
 | 
						{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
 | 
				
			||||||
	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
 | 
						{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
 | 
				
			||||||
| 
						 | 
					@ -855,6 +858,7 @@ static void btusb_work(struct work_struct *work)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct btusb_data *data = container_of(work, struct btusb_data, work);
 | 
						struct btusb_data *data = container_of(work, struct btusb_data, work);
 | 
				
			||||||
	struct hci_dev *hdev = data->hdev;
 | 
						struct hci_dev *hdev = data->hdev;
 | 
				
			||||||
 | 
						int new_alts;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (hdev->conn_hash.sco_num > 0) {
 | 
						if (hdev->conn_hash.sco_num > 0) {
 | 
				
			||||||
| 
						 | 
					@ -868,11 +872,19 @@ static void btusb_work(struct work_struct *work)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
 | 
								set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (data->isoc_altsetting != 2) {
 | 
					
 | 
				
			||||||
 | 
							if (hdev->voice_setting & 0x0020) {
 | 
				
			||||||
 | 
								static const int alts[3] = { 2, 4, 5 };
 | 
				
			||||||
 | 
								new_alts = alts[hdev->conn_hash.sco_num - 1];
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								new_alts = hdev->conn_hash.sco_num;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (data->isoc_altsetting != new_alts) {
 | 
				
			||||||
			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 | 
								clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 | 
				
			||||||
			usb_kill_anchored_urbs(&data->isoc_anchor);
 | 
								usb_kill_anchored_urbs(&data->isoc_anchor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (__set_isoc_interface(hdev, 2) < 0)
 | 
								if (__set_isoc_interface(hdev, new_alts) < 0)
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -388,7 +388,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 | 
				
			||||||
	hdev->close = hci_uart_close;
 | 
						hdev->close = hci_uart_close;
 | 
				
			||||||
	hdev->flush = hci_uart_flush;
 | 
						hdev->flush = hci_uart_flush;
 | 
				
			||||||
	hdev->send  = hci_uart_send_frame;
 | 
						hdev->send  = hci_uart_send_frame;
 | 
				
			||||||
	hdev->parent = hu->tty->dev;
 | 
						SET_HCIDEV_DEV(hdev, hu->tty->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
 | 
						if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
 | 
				
			||||||
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 | 
							set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,8 +252,9 @@ static int vhci_open(struct inode *inode, struct file *file)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file->private_data = data;
 | 
						file->private_data = data;
 | 
				
			||||||
 | 
						nonseekable_open(inode, file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nonseekable_open(inode, file);
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int vhci_release(struct inode *inode, struct file *file)
 | 
					static int vhci_release(struct inode *inode, struct file *file)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -693,8 +693,8 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 | 
				
			||||||
					  ie, 2 + vif->ssid_len + beacon_ie_len,
 | 
										  ie, 2 + vif->ssid_len + beacon_ie_len,
 | 
				
			||||||
					  0, GFP_KERNEL);
 | 
										  0, GFP_KERNEL);
 | 
				
			||||||
		if (bss)
 | 
							if (bss)
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
 | 
								ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
				   "cfg80211\n", bssid);
 | 
									   "added bss %pM to cfg80211\n", bssid);
 | 
				
			||||||
		kfree(ie);
 | 
							kfree(ie);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 | 
							ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 | 
				
			||||||
| 
						 | 
					@ -882,6 +882,32 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
 | 
				
			||||||
	vif->sme_state = SME_DISCONNECTED;
 | 
						vif->sme_state = SME_DISCONNECTED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ath6kl_set_probed_ssids(struct ath6kl *ar,
 | 
				
			||||||
 | 
									   struct ath6kl_vif *vif,
 | 
				
			||||||
 | 
									   struct cfg80211_ssid *ssids, int n_ssids)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (n_ssids > MAX_PROBED_SSID_INDEX)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < n_ssids; i++) {
 | 
				
			||||||
 | 
							ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 | 
				
			||||||
 | 
										  ssids[i].ssid_len ?
 | 
				
			||||||
 | 
										  SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
 | 
				
			||||||
 | 
										  ssids[i].ssid_len,
 | 
				
			||||||
 | 
										  ssids[i].ssid);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure no old entries are left behind */
 | 
				
			||||||
 | 
						for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) {
 | 
				
			||||||
 | 
							ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 | 
				
			||||||
 | 
										  DISABLE_SSID_FLAG, 0, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 | 
					static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
				struct cfg80211_scan_request *request)
 | 
									struct cfg80211_scan_request *request)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -899,36 +925,25 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ar->usr_bss_filter) {
 | 
						if (!ar->usr_bss_filter) {
 | 
				
			||||||
		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 | 
							clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 | 
				
			||||||
		ret = ath6kl_wmi_bssfilter_cmd(
 | 
							ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
			ar->wmi, vif->fw_vif_idx,
 | 
										       ALL_BSS_FILTER, 0);
 | 
				
			||||||
			(test_bit(CONNECTED, &vif->flags) ?
 | 
					 | 
				
			||||||
			 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
 | 
					 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			ath6kl_err("couldn't set bss filtering\n");
 | 
								ath6kl_err("couldn't set bss filtering\n");
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (request->n_ssids && request->ssids[0].ssid_len) {
 | 
						ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
 | 
				
			||||||
		u8 i;
 | 
									      request->n_ssids);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
		if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
 | 
							return ret;
 | 
				
			||||||
			request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (i = 0; i < request->n_ssids; i++)
 | 
					 | 
				
			||||||
			ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
 | 
					 | 
				
			||||||
						  i + 1, SPECIFIC_SSID_FLAG,
 | 
					 | 
				
			||||||
						  request->ssids[i].ssid_len,
 | 
					 | 
				
			||||||
						  request->ssids[i].ssid);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* this also clears IE in fw if it's not set */
 | 
						/* this also clears IE in fw if it's not set */
 | 
				
			||||||
	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
 | 
						ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
				       WMI_FRAME_PROBE_REQ,
 | 
									       WMI_FRAME_PROBE_REQ,
 | 
				
			||||||
				       request->ie, request->ie_len);
 | 
									       request->ie, request->ie_len);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		ath6kl_err("failed to set Probe Request appie for "
 | 
							ath6kl_err("failed to set Probe Request appie for scan");
 | 
				
			||||||
			   "scan");
 | 
					 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -945,8 +960,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
 | 
							channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
 | 
				
			||||||
		if (channels == NULL) {
 | 
							if (channels == NULL) {
 | 
				
			||||||
			ath6kl_warn("failed to set scan channels, "
 | 
								ath6kl_warn("failed to set scan channels, scan all channels");
 | 
				
			||||||
				    "scan all channels");
 | 
					 | 
				
			||||||
			n_channels = 0;
 | 
								n_channels = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1018,6 +1032,20 @@ out:
 | 
				
			||||||
	vif->scan_req = NULL;
 | 
						vif->scan_req = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
 | 
				
			||||||
 | 
									      enum wmi_phy_mode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum nl80211_channel_type type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
 | 
							   "channel switch notify nw_type %d freq %d mode %d\n",
 | 
				
			||||||
 | 
							   vif->nw_type, freq, mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfg80211_ch_switch_notify(vif->ndev, freq, type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 | 
					static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
				   u8 key_index, bool pairwise,
 | 
									   u8 key_index, bool pairwise,
 | 
				
			||||||
				   const u8 *mac_addr,
 | 
									   const u8 *mac_addr,
 | 
				
			||||||
| 
						 | 
					@ -1111,9 +1139,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
		ar->ap_mode_bkey.key_len = key->key_len;
 | 
							ar->ap_mode_bkey.key_len = key->key_len;
 | 
				
			||||||
		memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
 | 
							memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
 | 
				
			||||||
		if (!test_bit(CONNECTED, &vif->flags)) {
 | 
							if (!test_bit(CONNECTED, &vif->flags)) {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
 | 
								ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
				   "key configuration until AP mode has been "
 | 
									   "Delay initial group key configuration until AP mode has been started\n");
 | 
				
			||||||
				   "started\n");
 | 
					 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * The key will be set in ath6kl_connect_ap_mode() once
 | 
								 * The key will be set in ath6kl_connect_ap_mode() once
 | 
				
			||||||
			 * the connected event is received from the target.
 | 
								 * the connected event is received from the target.
 | 
				
			||||||
| 
						 | 
					@ -1129,8 +1156,8 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 | 
				
			||||||
		 * the AP mode has properly started
 | 
							 * the AP mode has properly started
 | 
				
			||||||
		 * (ath6kl_install_statioc_wep_keys).
 | 
							 * (ath6kl_install_statioc_wep_keys).
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
 | 
							ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
			   "until AP mode has been started\n");
 | 
								   "Delay WEP key configuration until AP mode has been started\n");
 | 
				
			||||||
		vif->wep_key_list[key_index].key_len = key->key_len;
 | 
							vif->wep_key_list[key_index].key_len = key->key_len;
 | 
				
			||||||
		memcpy(vif->wep_key_list[key_index].key, key->key,
 | 
							memcpy(vif->wep_key_list[key_index].key, key->key,
 | 
				
			||||||
		       key->key_len);
 | 
							       key->key_len);
 | 
				
			||||||
| 
						 | 
					@ -1962,8 +1989,7 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
 | 
				
			||||||
				sizeof(discvr_pattern), discvr_offset,
 | 
									sizeof(discvr_pattern), discvr_offset,
 | 
				
			||||||
				discvr_pattern, discvr_mask);
 | 
									discvr_pattern, discvr_mask);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
 | 
								ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
 | 
				
			||||||
				   "pattern\n");
 | 
					 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2031,6 +2057,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 | 
				
			||||||
	u8 index = 0;
 | 
						u8 index = 0;
 | 
				
			||||||
	__be32 ips[MAX_IP_ADDRS];
 | 
						__be32 ips[MAX_IP_ADDRS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The FW currently can't support multi-vif WoW properly. */
 | 
				
			||||||
 | 
						if (ar->num_vif > 1)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vif = ath6kl_vif_first(ar);
 | 
						vif = ath6kl_vif_first(ar);
 | 
				
			||||||
	if (!vif)
 | 
						if (!vif)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					@ -2044,6 +2074,13 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 | 
				
			||||||
	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
 | 
						if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) {
 | 
				
			||||||
 | 
							ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
 | 
				
			||||||
 | 
											vif->fw_vif_idx, false);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear existing WOW patterns */
 | 
						/* Clear existing WOW patterns */
 | 
				
			||||||
	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
 | 
						for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
 | 
				
			||||||
		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
 | 
							ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
| 
						 | 
					@ -2147,8 +2184,8 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
 | 
				
			||||||
	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
 | 
						ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
						 ATH6KL_HOST_MODE_AWAKE);
 | 
											 ATH6KL_HOST_MODE_AWAKE);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		ath6kl_warn("Failed to configure host sleep mode for "
 | 
							ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
 | 
				
			||||||
			    "wow resume: %d\n", ret);
 | 
								    ret);
 | 
				
			||||||
		ar->state = ATH6KL_STATE_WOW;
 | 
							ar->state = ATH6KL_STATE_WOW;
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2172,6 +2209,13 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ar->state = ATH6KL_STATE_ON;
 | 
						ar->state = ATH6KL_STATE_ON;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) {
 | 
				
			||||||
 | 
							ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
 | 
				
			||||||
 | 
										vif->fw_vif_idx, true);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_wake_queue(vif->ndev);
 | 
						netif_wake_queue(vif->ndev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -2186,8 +2230,10 @@ static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
 | 
				
			||||||
	if (!vif)
 | 
						if (!vif)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ath6kl_cfg80211_ready(vif))
 | 
						if (!test_bit(WMI_READY, &ar->flag)) {
 | 
				
			||||||
 | 
							ath6kl_err("deepsleep failed as wmi is not ready\n");
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_cfg80211_stop_all(ar);
 | 
						ath6kl_cfg80211_stop_all(ar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2447,6 +2493,24 @@ static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
 | 
				
			||||||
					band, htcap);
 | 
										band, htcap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wiphy *wiphy = vif->ar->wiphy;
 | 
				
			||||||
 | 
						int band, ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 | 
				
			||||||
 | 
							if (!wiphy->bands[band])
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ret = ath6kl_set_htcap(vif, band,
 | 
				
			||||||
 | 
									wiphy->bands[band]->ht_cap.ht_supported);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool ath6kl_is_p2p_ie(const u8 *pos)
 | 
					static bool ath6kl_is_p2p_ie(const u8 *pos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
 | 
						return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
 | 
				
			||||||
| 
						 | 
					@ -2568,28 +2632,34 @@ static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
 | 
				
			||||||
	/* skip element id and length */
 | 
						/* skip element id and length */
 | 
				
			||||||
	rsn_ie += 2;
 | 
						rsn_ie += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* skip version, group cipher */
 | 
						/* skip version */
 | 
				
			||||||
	if (rsn_ie_len < 6)
 | 
						if (rsn_ie_len < 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	rsn_ie +=  6;
 | 
						rsn_ie +=  2;
 | 
				
			||||||
	rsn_ie_len -= 6;
 | 
						rsn_ie_len -= 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* skip group cipher suite */
 | 
				
			||||||
 | 
						if (rsn_ie_len < 4)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						rsn_ie +=  4;
 | 
				
			||||||
 | 
						rsn_ie_len -= 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* skip pairwise cipher suite */
 | 
						/* skip pairwise cipher suite */
 | 
				
			||||||
	if (rsn_ie_len < 2)
 | 
						if (rsn_ie_len < 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return 0;
 | 
				
			||||||
	cnt = *((u16 *) rsn_ie);
 | 
						cnt = get_unaligned_le16(rsn_ie);
 | 
				
			||||||
	rsn_ie += (2 + cnt * 4);
 | 
						rsn_ie += (2 + cnt * 4);
 | 
				
			||||||
	rsn_ie_len -= (2 + cnt * 4);
 | 
						rsn_ie_len -= (2 + cnt * 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* skip akm suite */
 | 
						/* skip akm suite */
 | 
				
			||||||
	if (rsn_ie_len < 2)
 | 
						if (rsn_ie_len < 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return 0;
 | 
				
			||||||
	cnt = *((u16 *) rsn_ie);
 | 
						cnt = get_unaligned_le16(rsn_ie);
 | 
				
			||||||
	rsn_ie += (2 + cnt * 4);
 | 
						rsn_ie += (2 + cnt * 4);
 | 
				
			||||||
	rsn_ie_len -= (2 + cnt * 4);
 | 
						rsn_ie_len -= (2 + cnt * 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rsn_ie_len < 2)
 | 
						if (rsn_ie_len < 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(rsn_capab, rsn_ie, 2);
 | 
						memcpy(rsn_capab, rsn_ie, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2766,6 +2836,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
 | 
				
			||||||
			return res;
 | 
								return res;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy(&vif->profile, &p, sizeof(p));
 | 
				
			||||||
	res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
 | 
						res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
 | 
				
			||||||
	if (res < 0)
 | 
						if (res < 0)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
| 
						 | 
					@ -2801,13 +2872,7 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 | 
				
			||||||
	clear_bit(CONNECTED, &vif->flags);
 | 
						clear_bit(CONNECTED, &vif->flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Restore ht setting in firmware */
 | 
						/* Restore ht setting in firmware */
 | 
				
			||||||
	if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true))
 | 
						return ath6kl_restore_htcap(vif);
 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true))
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 | 
					static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 | 
				
			||||||
| 
						 | 
					@ -3081,7 +3146,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
 | 
				
			||||||
	struct ath6kl_vif *vif = netdev_priv(dev);
 | 
						struct ath6kl_vif *vif = netdev_priv(dev);
 | 
				
			||||||
	u16 interval;
 | 
						u16 interval;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	u8 i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ar->state != ATH6KL_STATE_ON)
 | 
						if (ar->state != ATH6KL_STATE_ON)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					@ -3089,29 +3153,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
 | 
				
			||||||
	if (vif->sme_state != SME_DISCONNECTED)
 | 
						if (vif->sme_state != SME_DISCONNECTED)
 | 
				
			||||||
		return -EBUSY;
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The FW currently can't support multi-vif WoW properly. */
 | 
				
			||||||
 | 
						if (ar->num_vif > 1)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_cfg80211_scan_complete_event(vif, true);
 | 
						ath6kl_cfg80211_scan_complete_event(vif, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) {
 | 
						ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
 | 
				
			||||||
		ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
 | 
									      request->n_ssids);
 | 
				
			||||||
					  i, DISABLE_SSID_FLAG,
 | 
						if (ret < 0)
 | 
				
			||||||
					  0, NULL);
 | 
							return ret;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* fw uses seconds, also make sure that it's >0 */
 | 
						/* fw uses seconds, also make sure that it's >0 */
 | 
				
			||||||
	interval = max_t(u16, 1, request->interval / 1000);
 | 
						interval = max_t(u16, 1, request->interval / 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
 | 
						ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
				  interval, interval,
 | 
									  interval, interval,
 | 
				
			||||||
				  10, 0, 0, 0, 3, 0, 0, 0);
 | 
									  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (request->n_ssids && request->ssids[0].ssid_len) {
 | 
					 | 
				
			||||||
		for (i = 0; i < request->n_ssids; i++) {
 | 
					 | 
				
			||||||
			ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
 | 
					 | 
				
			||||||
						  i, SPECIFIC_SSID_FLAG,
 | 
					 | 
				
			||||||
						  request->ssids[i].ssid_len,
 | 
					 | 
				
			||||||
						  request->ssids[i].ssid);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
 | 
						ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
					  ATH6KL_WOW_MODE_ENABLE,
 | 
										  ATH6KL_WOW_MODE_ENABLE,
 | 
				
			||||||
| 
						 | 
					@ -3271,8 +3329,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
 | 
				
			||||||
		ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
 | 
							ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
 | 
							if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
 | 
				
			||||||
			ath6kl_warn("ath6kl_deep_sleep_enable: "
 | 
								ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
 | 
				
			||||||
				    "wmi_powermode_cmd failed\n");
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3352,6 +3409,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 | 
				
			||||||
	vif->next_mode = nw_type;
 | 
						vif->next_mode = nw_type;
 | 
				
			||||||
	vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
 | 
						vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
 | 
				
			||||||
	vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
 | 
						vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
 | 
				
			||||||
 | 
						vif->bg_scan_period = 0;
 | 
				
			||||||
	vif->htcap.ht_enable = true;
 | 
						vif->htcap.ht_enable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
 | 
						memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
 | 
				
			||||||
| 
						 | 
					@ -3393,6 +3451,7 @@ err:
 | 
				
			||||||
int ath6kl_cfg80211_init(struct ath6kl *ar)
 | 
					int ath6kl_cfg80211_init(struct ath6kl *ar)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wiphy *wiphy = ar->wiphy;
 | 
						struct wiphy *wiphy = ar->wiphy;
 | 
				
			||||||
 | 
						bool band_2gig = false, band_5gig = false, ht = false;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
 | 
						wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
 | 
				
			||||||
| 
						 | 
					@ -3413,8 +3472,46 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
 | 
				
			||||||
	/* max num of ssids that can be probed during scanning */
 | 
						/* max num of ssids that can be probed during scanning */
 | 
				
			||||||
	wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
 | 
						wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
 | 
				
			||||||
	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
 | 
						wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
 | 
				
			||||||
 | 
						switch (ar->hw.cap) {
 | 
				
			||||||
 | 
						case WMI_11AN_CAP:
 | 
				
			||||||
 | 
							ht = true;
 | 
				
			||||||
 | 
						case WMI_11A_CAP:
 | 
				
			||||||
 | 
							band_5gig = true;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WMI_11GN_CAP:
 | 
				
			||||||
 | 
							ht = true;
 | 
				
			||||||
 | 
						case WMI_11G_CAP:
 | 
				
			||||||
 | 
							band_2gig = true;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WMI_11AGN_CAP:
 | 
				
			||||||
 | 
							ht = true;
 | 
				
			||||||
 | 
						case WMI_11AG_CAP:
 | 
				
			||||||
 | 
							band_2gig = true;
 | 
				
			||||||
 | 
							band_5gig = true;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ath6kl_err("invalid phy capability!\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Even if the fw has HT support, advertise HT cap only when
 | 
				
			||||||
 | 
						 * the firmware has support to override RSN capability, otherwise
 | 
				
			||||||
 | 
						 * 4-way handshake would fail.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!(ht &&
 | 
				
			||||||
 | 
						      test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
 | 
				
			||||||
 | 
							       ar->fw_capabilities))) {
 | 
				
			||||||
 | 
							ath6kl_band_2ghz.ht_cap.cap = 0;
 | 
				
			||||||
 | 
							ath6kl_band_2ghz.ht_cap.ht_supported = false;
 | 
				
			||||||
 | 
							ath6kl_band_5ghz.ht_cap.cap = 0;
 | 
				
			||||||
 | 
							ath6kl_band_5ghz.ht_cap.ht_supported = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (band_2gig)
 | 
				
			||||||
		wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
 | 
							wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
 | 
				
			||||||
 | 
						if (band_5gig)
 | 
				
			||||||
		wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
 | 
							wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 | 
						wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy->cipher_suites = cipher_suites;
 | 
						wiphy->cipher_suites = cipher_suites;
 | 
				
			||||||
| 
						 | 
					@ -3430,7 +3527,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
 | 
				
			||||||
	wiphy->wowlan.pattern_min_len = 1;
 | 
						wiphy->wowlan.pattern_min_len = 1;
 | 
				
			||||||
	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
 | 
						wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy->max_sched_scan_ssids = 10;
 | 
						wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
 | 
						ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
 | 
				
			||||||
			    WIPHY_FLAG_HAVE_AP_SME |
 | 
								    WIPHY_FLAG_HAVE_AP_SME |
 | 
				
			||||||
| 
						 | 
					@ -3447,8 +3544,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
 | 
				
			||||||
	ar->wiphy->probe_resp_offload =
 | 
						ar->wiphy->probe_resp_offload =
 | 
				
			||||||
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
 | 
							NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
 | 
				
			||||||
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
 | 
							NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
 | 
				
			||||||
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
 | 
							NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
 | 
				
			||||||
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = wiphy_register(wiphy);
 | 
						ret = wiphy_register(wiphy);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,8 @@ enum ath6kl_cfg_suspend_mode {
 | 
				
			||||||
struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 | 
					struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 | 
				
			||||||
					enum nl80211_iftype type,
 | 
										enum nl80211_iftype type,
 | 
				
			||||||
					u8 fw_vif_idx, u8 nw_type);
 | 
										u8 fw_vif_idx, u8 nw_type);
 | 
				
			||||||
 | 
					void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
 | 
				
			||||||
 | 
									      enum wmi_phy_mode mode);
 | 
				
			||||||
void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
 | 
					void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 | 
					void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,9 +126,9 @@ struct ath6kl_fw_ie {
 | 
				
			||||||
#define AR6003_HW_2_0_FIRMWARE_FILE		"athwlan.bin.z77"
 | 
					#define AR6003_HW_2_0_FIRMWARE_FILE		"athwlan.bin.z77"
 | 
				
			||||||
#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE	"athtcmd_ram.bin"
 | 
					#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE	"athtcmd_ram.bin"
 | 
				
			||||||
#define AR6003_HW_2_0_PATCH_FILE		"data.patch.bin"
 | 
					#define AR6003_HW_2_0_PATCH_FILE		"data.patch.bin"
 | 
				
			||||||
#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
 | 
					#define AR6003_HW_2_0_BOARD_DATA_FILE AR6003_HW_2_0_FW_DIR "/bdata.bin"
 | 
				
			||||||
#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
 | 
					#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
 | 
				
			||||||
			"ath6k/AR6003/hw2.0/bdata.SD31.bin"
 | 
								AR6003_HW_2_0_FW_DIR "/bdata.SD31.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* AR6003 3.0 definitions */
 | 
					/* AR6003 3.0 definitions */
 | 
				
			||||||
#define AR6003_HW_2_1_1_VERSION                 0x30000582
 | 
					#define AR6003_HW_2_1_1_VERSION                 0x30000582
 | 
				
			||||||
| 
						 | 
					@ -139,25 +139,33 @@ struct ath6kl_fw_ie {
 | 
				
			||||||
#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE	"utf.bin"
 | 
					#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE	"utf.bin"
 | 
				
			||||||
#define AR6003_HW_2_1_1_TESTSCRIPT_FILE	"nullTestFlow.bin"
 | 
					#define AR6003_HW_2_1_1_TESTSCRIPT_FILE	"nullTestFlow.bin"
 | 
				
			||||||
#define AR6003_HW_2_1_1_PATCH_FILE		"data.patch.bin"
 | 
					#define AR6003_HW_2_1_1_PATCH_FILE		"data.patch.bin"
 | 
				
			||||||
#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
 | 
					#define AR6003_HW_2_1_1_BOARD_DATA_FILE AR6003_HW_2_1_1_FW_DIR "/bdata.bin"
 | 
				
			||||||
#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE	\
 | 
					#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE	\
 | 
				
			||||||
			"ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
 | 
								AR6003_HW_2_1_1_FW_DIR "/bdata.SD31.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* AR6004 1.0 definitions */
 | 
					/* AR6004 1.0 definitions */
 | 
				
			||||||
#define AR6004_HW_1_0_VERSION                 0x30000623
 | 
					#define AR6004_HW_1_0_VERSION                 0x30000623
 | 
				
			||||||
#define AR6004_HW_1_0_FW_DIR			"ath6k/AR6004/hw1.0"
 | 
					#define AR6004_HW_1_0_FW_DIR			"ath6k/AR6004/hw1.0"
 | 
				
			||||||
#define AR6004_HW_1_0_FIRMWARE_FILE		"fw.ram.bin"
 | 
					#define AR6004_HW_1_0_FIRMWARE_FILE		"fw.ram.bin"
 | 
				
			||||||
#define AR6004_HW_1_0_BOARD_DATA_FILE         "ath6k/AR6004/hw1.0/bdata.bin"
 | 
					#define AR6004_HW_1_0_BOARD_DATA_FILE         AR6004_HW_1_0_FW_DIR "/bdata.bin"
 | 
				
			||||||
#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
 | 
					#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
 | 
				
			||||||
	"ath6k/AR6004/hw1.0/bdata.DB132.bin"
 | 
						AR6004_HW_1_0_FW_DIR "/bdata.DB132.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* AR6004 1.1 definitions */
 | 
					/* AR6004 1.1 definitions */
 | 
				
			||||||
#define AR6004_HW_1_1_VERSION                 0x30000001
 | 
					#define AR6004_HW_1_1_VERSION                 0x30000001
 | 
				
			||||||
#define AR6004_HW_1_1_FW_DIR			"ath6k/AR6004/hw1.1"
 | 
					#define AR6004_HW_1_1_FW_DIR			"ath6k/AR6004/hw1.1"
 | 
				
			||||||
#define AR6004_HW_1_1_FIRMWARE_FILE		"fw.ram.bin"
 | 
					#define AR6004_HW_1_1_FIRMWARE_FILE		"fw.ram.bin"
 | 
				
			||||||
#define AR6004_HW_1_1_BOARD_DATA_FILE         "ath6k/AR6004/hw1.1/bdata.bin"
 | 
					#define AR6004_HW_1_1_BOARD_DATA_FILE         AR6004_HW_1_1_FW_DIR "/bdata.bin"
 | 
				
			||||||
#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
 | 
					#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
 | 
				
			||||||
	"ath6k/AR6004/hw1.1/bdata.DB132.bin"
 | 
						AR6004_HW_1_1_FW_DIR "/bdata.DB132.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* AR6004 1.2 definitions */
 | 
				
			||||||
 | 
					#define AR6004_HW_1_2_VERSION                 0x300007e8
 | 
				
			||||||
 | 
					#define AR6004_HW_1_2_FW_DIR			"ath6k/AR6004/hw1.2"
 | 
				
			||||||
 | 
					#define AR6004_HW_1_2_FIRMWARE_FILE           "fw.ram.bin"
 | 
				
			||||||
 | 
					#define AR6004_HW_1_2_BOARD_DATA_FILE         AR6004_HW_1_2_FW_DIR "/bdata.bin"
 | 
				
			||||||
 | 
					#define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \
 | 
				
			||||||
 | 
						AR6004_HW_1_2_FW_DIR "/bdata.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Per STA data, used in AP mode */
 | 
					/* Per STA data, used in AP mode */
 | 
				
			||||||
#define STA_PS_AWAKE		BIT(0)
 | 
					#define STA_PS_AWAKE		BIT(0)
 | 
				
			||||||
| 
						 | 
					@ -502,6 +510,8 @@ enum ath6kl_vif_state {
 | 
				
			||||||
	WLAN_ENABLED,
 | 
						WLAN_ENABLED,
 | 
				
			||||||
	STATS_UPDATE_PEND,
 | 
						STATS_UPDATE_PEND,
 | 
				
			||||||
	HOST_SLEEP_MODE_CMD_PROCESSED,
 | 
						HOST_SLEEP_MODE_CMD_PROCESSED,
 | 
				
			||||||
 | 
						NETDEV_MCAST_ALL_ON,
 | 
				
			||||||
 | 
						NETDEV_MCAST_ALL_OFF,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ath6kl_vif {
 | 
					struct ath6kl_vif {
 | 
				
			||||||
| 
						 | 
					@ -549,9 +559,11 @@ struct ath6kl_vif {
 | 
				
			||||||
	u16 assoc_bss_beacon_int;
 | 
						u16 assoc_bss_beacon_int;
 | 
				
			||||||
	u16 listen_intvl_t;
 | 
						u16 listen_intvl_t;
 | 
				
			||||||
	u16 bmiss_time_t;
 | 
						u16 bmiss_time_t;
 | 
				
			||||||
 | 
						u16 bg_scan_period;
 | 
				
			||||||
	u8 assoc_bss_dtim_period;
 | 
						u8 assoc_bss_dtim_period;
 | 
				
			||||||
	struct net_device_stats net_stats;
 | 
						struct net_device_stats net_stats;
 | 
				
			||||||
	struct target_stats target_stats;
 | 
						struct target_stats target_stats;
 | 
				
			||||||
 | 
						struct wmi_connect_cmd profile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct list_head mc_filter;
 | 
						struct list_head mc_filter;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -640,6 +652,7 @@ struct ath6kl {
 | 
				
			||||||
	u8 sta_list_index;
 | 
						u8 sta_list_index;
 | 
				
			||||||
	struct ath6kl_req_key ap_mode_bkey;
 | 
						struct ath6kl_req_key ap_mode_bkey;
 | 
				
			||||||
	struct sk_buff_head mcastpsq;
 | 
						struct sk_buff_head mcastpsq;
 | 
				
			||||||
 | 
						u32 want_ch_switch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * FIXME: protects access to mcastpsq but is actually useless as
 | 
						 * FIXME: protects access to mcastpsq but is actually useless as
 | 
				
			||||||
| 
						 | 
					@ -672,6 +685,7 @@ struct ath6kl {
 | 
				
			||||||
		u32 refclk_hz;
 | 
							u32 refclk_hz;
 | 
				
			||||||
		u32 uarttx_pin;
 | 
							u32 uarttx_pin;
 | 
				
			||||||
		u32 testscript_addr;
 | 
							u32 testscript_addr;
 | 
				
			||||||
 | 
							enum wmi_phy_cap cap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct ath6kl_hw_fw {
 | 
							struct ath6kl_hw_fw {
 | 
				
			||||||
			const char *dir;
 | 
								const char *dir;
 | 
				
			||||||
| 
						 | 
					@ -805,7 +819,8 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn);
 | 
				
			||||||
struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr);
 | 
					struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr);
 | 
				
			||||||
struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
 | 
					struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver);
 | 
					void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
 | 
				
			||||||
 | 
								enum wmi_phy_cap cap);
 | 
				
			||||||
int ath6kl_control_tx(void *devt, struct sk_buff *skb,
 | 
					int ath6kl_control_tx(void *devt, struct sk_buff *skb,
 | 
				
			||||||
		      enum htc_endpoint_id eid);
 | 
							      enum htc_endpoint_id eid);
 | 
				
			||||||
void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
 | 
					void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -401,8 +401,10 @@ static ssize_t ath6kl_fwlog_block_read(struct file *file,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = wait_for_completion_interruptible(
 | 
							ret = wait_for_completion_interruptible(
 | 
				
			||||||
			&ar->debug.fwlog_completion);
 | 
								&ar->debug.fwlog_completion);
 | 
				
			||||||
		if (ret == -ERESTARTSYS)
 | 
							if (ret == -ERESTARTSYS) {
 | 
				
			||||||
 | 
								vfree(buf);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spin_lock(&ar->debug.fwlog_queue.lock);
 | 
							spin_lock(&ar->debug.fwlog_queue.lock);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1570,10 +1572,15 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
 | 
				
			||||||
				size_t count, loff_t *ppos)
 | 
									size_t count, loff_t *ppos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ath6kl *ar = file->private_data;
 | 
						struct ath6kl *ar = file->private_data;
 | 
				
			||||||
 | 
						struct ath6kl_vif *vif;
 | 
				
			||||||
	u16 bgscan_int;
 | 
						u16 bgscan_int;
 | 
				
			||||||
	char buf[32];
 | 
						char buf[32];
 | 
				
			||||||
	ssize_t len;
 | 
						ssize_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vif = ath6kl_vif_first(ar);
 | 
				
			||||||
 | 
						if (!vif)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = min(count, sizeof(buf) - 1);
 | 
						len = min(count, sizeof(buf) - 1);
 | 
				
			||||||
	if (copy_from_user(buf, user_buf, len))
 | 
						if (copy_from_user(buf, user_buf, len))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
| 
						 | 
					@ -1585,6 +1592,8 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
 | 
				
			||||||
	if (bgscan_int == 0)
 | 
						if (bgscan_int == 0)
 | 
				
			||||||
		bgscan_int = 0xffff;
 | 
							bgscan_int = 0xffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vif->bg_scan_period = bgscan_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
 | 
						ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
 | 
				
			||||||
				  0, 0, 0);
 | 
									  0, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1809,6 +1818,7 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
 | 
				
			||||||
void ath6kl_debug_cleanup(struct ath6kl *ar)
 | 
					void ath6kl_debug_cleanup(struct ath6kl *ar)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	skb_queue_purge(&ar->debug.fwlog_queue);
 | 
						skb_queue_purge(&ar->debug.fwlog_queue);
 | 
				
			||||||
 | 
						complete(&ar->debug.fwlog_completion);
 | 
				
			||||||
	kfree(ar->debug.roam_tbl);
 | 
						kfree(ar->debug.roam_tbl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,10 +83,7 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
 | 
				
			||||||
			 * never goes inactive EVER.
 | 
								 * never goes inactive EVER.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
 | 
								cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
 | 
				
			||||||
		} else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
 | 
							}
 | 
				
			||||||
			/* this is the lowest priority data endpoint */
 | 
					 | 
				
			||||||
			/* FIXME: this looks fishy, check */
 | 
					 | 
				
			||||||
			cred_info->lowestpri_ep_dist = cur_ep_dist->list;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Streams have to be created (explicit | implicit) for all
 | 
							 * Streams have to be created (explicit | implicit) for all
 | 
				
			||||||
| 
						 | 
					@ -100,6 +97,13 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * For ath6kl_credit_seek function,
 | 
				
			||||||
 | 
						 * it use list_for_each_entry_reverse to walk around the whole ep list.
 | 
				
			||||||
 | 
						 * Therefore assign this lowestpri_ep_dist after walk around the ep_list
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						cred_info->lowestpri_ep_dist = cur_ep_dist->list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(cred_info->cur_free_credits <= 0);
 | 
						WARN_ON(cred_info->cur_free_credits <= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(cur_ep_dist, ep_list, list) {
 | 
						list_for_each_entry(cur_ep_dist, ep_list, list) {
 | 
				
			||||||
| 
						 | 
					@ -758,7 +762,7 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
 | 
				
			||||||
	u32 txb_mask;
 | 
						u32 txb_mask;
 | 
				
			||||||
	u8 ac = WMM_NUM_AC;
 | 
						u8 ac = WMM_NUM_AC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
 | 
						if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
 | 
				
			||||||
	    (WMI_CONTROL_SVC != endpoint->svc_id))
 | 
						    (WMI_CONTROL_SVC != endpoint->svc_id))
 | 
				
			||||||
		ac = target->dev->ar->ep2ac_map[endpoint->eid];
 | 
							ac = target->dev->ar->ep2ac_map[endpoint->eid];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -793,6 +797,7 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
 | 
				
			||||||
				 * itself
 | 
									 * itself
 | 
				
			||||||
				 */
 | 
									 */
 | 
				
			||||||
				txb_mask = ((1 << ac) - 1);
 | 
									txb_mask = ((1 << ac) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * when the scatter request resources drop below a
 | 
								 * when the scatter request resources drop below a
 | 
				
			||||||
			 * certain threshold, disable Tx bundling for all
 | 
								 * certain threshold, disable Tx bundling for all
 | 
				
			||||||
| 
						 | 
					@ -849,6 +854,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
 | 
				
			||||||
	int bundle_sent;
 | 
						int bundle_sent;
 | 
				
			||||||
	int n_pkts_bundle;
 | 
						int n_pkts_bundle;
 | 
				
			||||||
	u8 ac = WMM_NUM_AC;
 | 
						u8 ac = WMM_NUM_AC;
 | 
				
			||||||
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_bh(&target->tx_lock);
 | 
						spin_lock_bh(&target->tx_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -866,7 +872,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	INIT_LIST_HEAD(&txq);
 | 
						INIT_LIST_HEAD(&txq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
 | 
						if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) &&
 | 
				
			||||||
	    (WMI_CONTROL_SVC != endpoint->svc_id))
 | 
						    (WMI_CONTROL_SVC != endpoint->svc_id))
 | 
				
			||||||
		ac = target->dev->ar->ep2ac_map[endpoint->eid];
 | 
							ac = target->dev->ar->ep2ac_map[endpoint->eid];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -910,7 +916,12 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
 | 
								ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
 | 
				
			||||||
					       0, packet->info.tx.seqno);
 | 
										       0, packet->info.tx.seqno);
 | 
				
			||||||
			ath6kl_htc_tx_issue(target, packet);
 | 
								status = ath6kl_htc_tx_issue(target, packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (status) {
 | 
				
			||||||
 | 
									packet->status = status;
 | 
				
			||||||
 | 
									packet->completion(packet->context, packet);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spin_lock_bh(&target->tx_lock);
 | 
							spin_lock_bh(&target->tx_lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,8 +108,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* get packet at head, but don't remove it */
 | 
							/* get packet at head, but don't remove it */
 | 
				
			||||||
		packet = list_first_entry(&ep->txq, struct htc_packet, list);
 | 
							packet = list_first_entry(&ep->txq, struct htc_packet, list);
 | 
				
			||||||
		if (packet == NULL)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_HTC,
 | 
							ath6kl_dbg(ATH6KL_DBG_HTC,
 | 
				
			||||||
			   "%s: got head packet:0x%p , queue depth: %d\n",
 | 
								   "%s: got head packet:0x%p , queue depth: %d\n",
 | 
				
			||||||
| 
						 | 
					@ -803,8 +801,6 @@ static int htc_send_packets_multiple(struct htc_target *target,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get first packet to find out which ep the packets will go into */
 | 
						/* get first packet to find out which ep the packets will go into */
 | 
				
			||||||
	packet = list_first_entry(pkt_queue, struct htc_packet, list);
 | 
						packet = list_first_entry(pkt_queue, struct htc_packet, list);
 | 
				
			||||||
	if (packet == NULL)
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (packet->endpoint >= ENDPOINT_MAX) {
 | 
						if (packet->endpoint >= ENDPOINT_MAX) {
 | 
				
			||||||
		WARN_ON_ONCE(1);
 | 
							WARN_ON_ONCE(1);
 | 
				
			||||||
| 
						 | 
					@ -1382,6 +1378,9 @@ static int ath6kl_htc_pipe_conn_service(struct htc_target *target,
 | 
				
			||||||
	/* copy all the callbacks */
 | 
						/* copy all the callbacks */
 | 
				
			||||||
	ep->ep_cb = conn_req->ep_cb;
 | 
						ep->ep_cb = conn_req->ep_cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize tx_drop_packet_threshold */
 | 
				
			||||||
 | 
						ep->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ath6kl_hif_pipe_map_service(ar, ep->svc_id,
 | 
						status = ath6kl_hif_pipe_map_service(ar, ep->svc_id,
 | 
				
			||||||
					     &ep->pipe.pipeid_ul,
 | 
										     &ep->pipe.pipeid_ul,
 | 
				
			||||||
					     &ep->pipe.pipeid_dl);
 | 
										     &ep->pipe.pipeid_dl);
 | 
				
			||||||
| 
						 | 
					@ -1636,10 +1635,6 @@ static int ath6kl_htc_pipe_add_rxbuf_multiple(struct htc_target *target,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	first = list_first_entry(pkt_queue, struct htc_packet, list);
 | 
						first = list_first_entry(pkt_queue, struct htc_packet, list);
 | 
				
			||||||
	if (first == NULL) {
 | 
					 | 
				
			||||||
		WARN_ON_ONCE(1);
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (first->endpoint >= ENDPOINT_MAX) {
 | 
						if (first->endpoint >= ENDPOINT_MAX) {
 | 
				
			||||||
		WARN_ON_ONCE(1);
 | 
							WARN_ON_ONCE(1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,6 +119,24 @@ static const struct ath6kl_hw hw_list[] = {
 | 
				
			||||||
		.fw_board		= AR6004_HW_1_1_BOARD_DATA_FILE,
 | 
							.fw_board		= AR6004_HW_1_1_BOARD_DATA_FILE,
 | 
				
			||||||
		.fw_default_board	= AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
 | 
							.fw_default_board	= AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.id				= AR6004_HW_1_2_VERSION,
 | 
				
			||||||
 | 
							.name				= "ar6004 hw 1.2",
 | 
				
			||||||
 | 
							.dataset_patch_addr		= 0x436ecc,
 | 
				
			||||||
 | 
							.app_load_addr			= 0x1234,
 | 
				
			||||||
 | 
							.board_ext_data_addr		= 0x437000,
 | 
				
			||||||
 | 
							.reserved_ram_size		= 9216,
 | 
				
			||||||
 | 
							.board_addr			= 0x435c00,
 | 
				
			||||||
 | 
							.refclk_hz			= 40000000,
 | 
				
			||||||
 | 
							.uarttx_pin			= 11,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.fw = {
 | 
				
			||||||
 | 
								.dir		= AR6004_HW_1_2_FW_DIR,
 | 
				
			||||||
 | 
								.fw		= AR6004_HW_1_2_FIRMWARE_FILE,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.fw_board		= AR6004_HW_1_2_BOARD_DATA_FILE,
 | 
				
			||||||
 | 
							.fw_default_board	= AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -445,9 +463,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
 | 
				
			||||||
					      P2P_FLAG_MACADDR_REQ |
 | 
										      P2P_FLAG_MACADDR_REQ |
 | 
				
			||||||
					      P2P_FLAG_HMODEL_REQ);
 | 
										      P2P_FLAG_HMODEL_REQ);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P "
 | 
								ath6kl_dbg(ATH6KL_DBG_TRC,
 | 
				
			||||||
				   "capabilities (%d) - assuming P2P not "
 | 
									   "failed to request P2P capabilities (%d) - assuming P2P not supported\n",
 | 
				
			||||||
				   "supported\n", ret);
 | 
									   ret);
 | 
				
			||||||
			ar->p2p = false;
 | 
								ar->p2p = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -456,8 +474,9 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
 | 
				
			||||||
		/* Enable Probe Request reporting for P2P */
 | 
							/* Enable Probe Request reporting for P2P */
 | 
				
			||||||
		ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
 | 
							ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe "
 | 
								ath6kl_dbg(ATH6KL_DBG_TRC,
 | 
				
			||||||
				   "Request reporting (%d)\n", ret);
 | 
									   "failed to enable Probe Request reporting (%d)\n",
 | 
				
			||||||
 | 
									   ret);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -421,8 +421,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
 | 
				
			||||||
		if (!ik->valid)
 | 
							if (!ik->valid)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
 | 
							ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
			   "the initial group key for AP mode\n");
 | 
								   "Delayed addkey for the initial group key for AP mode\n");
 | 
				
			||||||
		memset(key_rsc, 0, sizeof(key_rsc));
 | 
							memset(key_rsc, 0, sizeof(key_rsc));
 | 
				
			||||||
		res = ath6kl_wmi_addkey_cmd(
 | 
							res = ath6kl_wmi_addkey_cmd(
 | 
				
			||||||
			ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
 | 
								ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
 | 
				
			||||||
| 
						 | 
					@ -430,12 +430,19 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
 | 
				
			||||||
			ik->key,
 | 
								ik->key,
 | 
				
			||||||
			KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
 | 
								KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
 | 
				
			||||||
		if (res) {
 | 
							if (res) {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
 | 
								ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 | 
				
			||||||
				   "addkey failed: %d\n", res);
 | 
									   "Delayed addkey failed: %d\n", res);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) {
 | 
				
			||||||
 | 
							ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
 | 
				
			||||||
 | 
							/* we actually don't know the phymode, default to HT20 */
 | 
				
			||||||
 | 
							ath6kl_cfg80211_ch_switch_notify(vif, channel,
 | 
				
			||||||
 | 
											 WMI_11G_HT20);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
 | 
						ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
 | 
				
			||||||
	set_bit(CONNECTED, &vif->flags);
 | 
						set_bit(CONNECTED, &vif->flags);
 | 
				
			||||||
	netif_carrier_on(vif->ndev);
 | 
						netif_carrier_on(vif->ndev);
 | 
				
			||||||
| 
						 | 
					@ -541,7 +548,8 @@ void ath6kl_disconnect(struct ath6kl_vif *vif)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* WMI Event handlers */
 | 
					/* WMI Event handlers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
 | 
					void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
 | 
				
			||||||
 | 
								enum wmi_phy_cap cap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ath6kl *ar = devt;
 | 
						struct ath6kl *ar = devt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,6 +559,7 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ar->version.wlan_ver = sw_ver;
 | 
						ar->version.wlan_ver = sw_ver;
 | 
				
			||||||
	ar->version.abi_ver = abi_ver;
 | 
						ar->version.abi_ver = abi_ver;
 | 
				
			||||||
 | 
						ar->hw.cap = cap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(ar->wiphy->fw_version,
 | 
						snprintf(ar->wiphy->fw_version,
 | 
				
			||||||
		 sizeof(ar->wiphy->fw_version),
 | 
							 sizeof(ar->wiphy->fw_version),
 | 
				
			||||||
| 
						 | 
					@ -584,6 +593,45 @@ void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
 | 
						ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ath6kl *ar = vif->ar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vif->next_chan = channel;
 | 
				
			||||||
 | 
						vif->profile.ch = cpu_to_le16(channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (vif->nw_type) {
 | 
				
			||||||
 | 
						case AP_NETWORK:
 | 
				
			||||||
 | 
							return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
 | 
											    &vif->profile);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ath6kl_err("won't switch channels nw_type=%d\n", vif->nw_type);
 | 
				
			||||||
 | 
							return -ENOTSUPP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ath6kl_vif *vif;
 | 
				
			||||||
 | 
						int res = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ar->want_ch_switch)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_bh(&ar->list_lock);
 | 
				
			||||||
 | 
						list_for_each_entry(vif, &ar->vif_list, list) {
 | 
				
			||||||
 | 
							if (ar->want_ch_switch & (1 << vif->fw_vif_idx))
 | 
				
			||||||
 | 
								res = ath6kl_commit_ch_switch(vif, channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (res)
 | 
				
			||||||
 | 
								ath6kl_err("channel switch failed nw_type %d res %d\n",
 | 
				
			||||||
 | 
									   vif->nw_type, res);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						spin_unlock_bh(&ar->list_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 | 
					void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 | 
				
			||||||
			  u16 listen_int, u16 beacon_int,
 | 
								  u16 listen_int, u16 beacon_int,
 | 
				
			||||||
			  enum network_type net_type, u8 beacon_ie_len,
 | 
								  enum network_type net_type, u8 beacon_ie_len,
 | 
				
			||||||
| 
						 | 
					@ -601,9 +649,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 | 
				
			||||||
	memcpy(vif->bssid, bssid, sizeof(vif->bssid));
 | 
						memcpy(vif->bssid, bssid, sizeof(vif->bssid));
 | 
				
			||||||
	vif->bss_ch = channel;
 | 
						vif->bss_ch = channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((vif->nw_type == INFRA_NETWORK))
 | 
						if ((vif->nw_type == INFRA_NETWORK)) {
 | 
				
			||||||
		ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 | 
							ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
					      vif->listen_intvl_t, 0);
 | 
										      vif->listen_intvl_t, 0);
 | 
				
			||||||
 | 
							ath6kl_check_ch_switch(ar, channel);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_wake_queue(vif->ndev);
 | 
						netif_wake_queue(vif->ndev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -926,6 +976,11 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
 | 
				
			||||||
	struct ath6kl *ar = vif->ar;
 | 
						struct ath6kl *ar = vif->ar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vif->nw_type == AP_NETWORK) {
 | 
						if (vif->nw_type == AP_NETWORK) {
 | 
				
			||||||
 | 
							/* disconnect due to other STA vif switching channels */
 | 
				
			||||||
 | 
							if (reason == BSS_DISCONNECTED &&
 | 
				
			||||||
 | 
							    prot_reason_status == WMI_AP_REASON_STA_ROAM)
 | 
				
			||||||
 | 
								ar->want_ch_switch |= 1 << vif->fw_vif_idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
 | 
							if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1090,7 +1145,7 @@ static int ath6kl_set_features(struct net_device *dev,
 | 
				
			||||||
static void ath6kl_set_multicast_list(struct net_device *ndev)
 | 
					static void ath6kl_set_multicast_list(struct net_device *ndev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ath6kl_vif *vif = netdev_priv(ndev);
 | 
						struct ath6kl_vif *vif = netdev_priv(ndev);
 | 
				
			||||||
	bool mc_all_on = false, mc_all_off = false;
 | 
						bool mc_all_on = false;
 | 
				
			||||||
	int mc_count = netdev_mc_count(ndev);
 | 
						int mc_count = netdev_mc_count(ndev);
 | 
				
			||||||
	struct netdev_hw_addr *ha;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	bool found;
 | 
						bool found;
 | 
				
			||||||
| 
						 | 
					@ -1102,24 +1157,41 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
 | 
				
			||||||
	    !test_bit(WLAN_ENABLED, &vif->flags))
 | 
						    !test_bit(WLAN_ENABLED, &vif->flags))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Enable multicast-all filter. */
 | 
				
			||||||
	mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
 | 
						mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
 | 
				
			||||||
		    !!(ndev->flags & IFF_ALLMULTI) ||
 | 
							    !!(ndev->flags & IFF_ALLMULTI) ||
 | 
				
			||||||
		    !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
 | 
							    !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0;
 | 
						if (mc_all_on)
 | 
				
			||||||
 | 
							set_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mc_all_on || mc_all_off) {
 | 
						mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
 | 
				
			||||||
		/* Enable/disable all multicast */
 | 
					
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
 | 
						if (!(ndev->flags & IFF_MULTICAST)) {
 | 
				
			||||||
 | 
							mc_all_on = false;
 | 
				
			||||||
 | 
							set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Enable/disable "multicast-all" filter*/
 | 
				
			||||||
 | 
						ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n",
 | 
				
			||||||
		   mc_all_on ? "enabling" : "disabling");
 | 
							   mc_all_on ? "enabling" : "disabling");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
 | 
						ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
 | 
				
			||||||
						  mc_all_on);
 | 
											  mc_all_on);
 | 
				
			||||||
		if (ret)
 | 
						if (ret) {
 | 
				
			||||||
			ath6kl_warn("Failed to %s multicast receive\n",
 | 
							ath6kl_warn("Failed to %s multicast-all receive\n",
 | 
				
			||||||
			    mc_all_on ? "enable" : "disable");
 | 
								    mc_all_on ? "enable" : "disable");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Keep the driver and firmware mcast list in sync. */
 | 
				
			||||||
	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
 | 
						list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
 | 
				
			||||||
		found = false;
 | 
							found = false;
 | 
				
			||||||
		netdev_for_each_mc_addr(ha, ndev) {
 | 
							netdev_for_each_mc_addr(ha, ndev) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -552,7 +552,7 @@ static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
 | 
						bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!bus_req)
 | 
						if (WARN_ON_ONCE(!bus_req))
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bus_req->address = address;
 | 
						bus_req->address = address;
 | 
				
			||||||
| 
						 | 
					@ -915,6 +915,9 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cut_pwr:
 | 
					cut_pwr:
 | 
				
			||||||
 | 
						if (func->card && func->card->host)
 | 
				
			||||||
 | 
							func->card->host->pm_flags &= ~MMC_PM_KEEP_POWER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
 | 
						return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -985,9 +988,8 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status) {
 | 
						if (status) {
 | 
				
			||||||
		ath6kl_err("%s: failed to write initial bytes of 0x%x "
 | 
							ath6kl_err("%s: failed to write initial bytes of 0x%x to window reg: 0x%X\n",
 | 
				
			||||||
			   "to window reg: 0x%X\n", __func__,
 | 
								   __func__, addr, reg_addr);
 | 
				
			||||||
			   addr, reg_addr);
 | 
					 | 
				
			||||||
		return status;
 | 
							return status;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1076,8 +1078,8 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
 | 
				
			||||||
					 (u8 *)&ar->bmi.cmd_credits, 4,
 | 
										 (u8 *)&ar->bmi.cmd_credits, 4,
 | 
				
			||||||
					 HIF_RD_SYNC_BYTE_INC);
 | 
										 HIF_RD_SYNC_BYTE_INC);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			ath6kl_err("Unable to decrement the command credit "
 | 
								ath6kl_err("Unable to decrement the command credit count register: %d\n",
 | 
				
			||||||
						"count register: %d\n", ret);
 | 
									   ret);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1457,3 +1459,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -362,15 +362,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		   skb, skb->data, skb->len);
 | 
							   skb, skb->data, skb->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If target is not associated */
 | 
						/* If target is not associated */
 | 
				
			||||||
	if (!test_bit(CONNECTED, &vif->flags)) {
 | 
						if (!test_bit(CONNECTED, &vif->flags))
 | 
				
			||||||
		dev_kfree_skb(skb);
 | 
							goto fail_tx;
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) {
 | 
						if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON))
 | 
				
			||||||
		dev_kfree_skb(skb);
 | 
							goto fail_tx;
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!test_bit(WMI_READY, &ar->flag))
 | 
						if (!test_bit(WMI_READY, &ar->flag))
 | 
				
			||||||
		goto fail_tx;
 | 
							goto fail_tx;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1037,6 +1037,14 @@ static void ath6kl_usb_stop(struct ath6kl *ar)
 | 
				
			||||||
	hif_stop(ar);
 | 
						hif_stop(ar);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ath6kl_usb_cleanup_scatter(struct ath6kl *ar)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * USB doesn't support it. Just return.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ath6kl_hif_ops ath6kl_usb_ops = {
 | 
					static const struct ath6kl_hif_ops ath6kl_usb_ops = {
 | 
				
			||||||
	.diag_read32 = ath6kl_usb_diag_read32,
 | 
						.diag_read32 = ath6kl_usb_diag_read32,
 | 
				
			||||||
	.diag_write32 = ath6kl_usb_diag_write32,
 | 
						.diag_write32 = ath6kl_usb_diag_write32,
 | 
				
			||||||
| 
						 | 
					@ -1049,6 +1057,7 @@ static const struct ath6kl_hif_ops ath6kl_usb_ops = {
 | 
				
			||||||
	.pipe_get_default = ath6kl_usb_get_default_pipe,
 | 
						.pipe_get_default = ath6kl_usb_get_default_pipe,
 | 
				
			||||||
	.pipe_map_service = ath6kl_usb_map_service_pipe,
 | 
						.pipe_map_service = ath6kl_usb_map_service_pipe,
 | 
				
			||||||
	.pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number,
 | 
						.pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number,
 | 
				
			||||||
 | 
						.cleanup_scatter = ath6kl_usb_cleanup_scatter,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ath6kl usb driver registered functions */
 | 
					/* ath6kl usb driver registered functions */
 | 
				
			||||||
| 
						 | 
					@ -1207,3 +1216,6 @@ MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 | 
				
			||||||
MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 | 
					MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
 | 
				
			||||||
 | 
					MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/ip.h>
 | 
					#include <linux/ip.h>
 | 
				
			||||||
 | 
					#include <linux/in.h>
 | 
				
			||||||
#include "core.h"
 | 
					#include "core.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
#include "testmode.h"
 | 
					#include "testmode.h"
 | 
				
			||||||
| 
						 | 
					@ -289,6 +290,13 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
 | 
				
			||||||
					layer2_priority);
 | 
										layer2_priority);
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			usr_pri = layer2_priority & 0x7;
 | 
								usr_pri = layer2_priority & 0x7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Queue the EAPOL frames in the same WMM_AC_VO queue
 | 
				
			||||||
 | 
							 * as that of management frames.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (skb->protocol == cpu_to_be16(ETH_P_PAE))
 | 
				
			||||||
 | 
								usr_pri = WMI_VOICE_USER_PRIORITY;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -460,8 +468,9 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
 | 
				
			||||||
		   freq, dur);
 | 
							   freq, dur);
 | 
				
			||||||
	chan = ieee80211_get_channel(ar->wiphy, freq);
 | 
						chan = ieee80211_get_channel(ar->wiphy, freq);
 | 
				
			||||||
	if (!chan) {
 | 
						if (!chan) {
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel "
 | 
							ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
			   "(freq=%u)\n", freq);
 | 
								   "remain_on_chnl: Unknown channel (freq=%u)\n",
 | 
				
			||||||
 | 
								   freq);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	id = vif->last_roc_id;
 | 
						id = vif->last_roc_id;
 | 
				
			||||||
| 
						 | 
					@ -488,12 +497,14 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
 | 
				
			||||||
	ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
 | 
						ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
 | 
				
			||||||
	freq = le32_to_cpu(ev->freq);
 | 
						freq = le32_to_cpu(ev->freq);
 | 
				
			||||||
	dur = le32_to_cpu(ev->duration);
 | 
						dur = le32_to_cpu(ev->duration);
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "status=%u\n", freq, dur, ev->status);
 | 
							   "cancel_remain_on_chnl: freq=%u dur=%u status=%u\n",
 | 
				
			||||||
 | 
							   freq, dur, ev->status);
 | 
				
			||||||
	chan = ieee80211_get_channel(ar->wiphy, freq);
 | 
						chan = ieee80211_get_channel(ar->wiphy, freq);
 | 
				
			||||||
	if (!chan) {
 | 
						if (!chan) {
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown "
 | 
							ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
			   "channel (freq=%u)\n", freq);
 | 
								   "cancel_remain_on_chnl: Unknown channel (freq=%u)\n",
 | 
				
			||||||
 | 
								   freq);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (vif->last_cancel_roc_id &&
 | 
						if (vif->last_cancel_roc_id &&
 | 
				
			||||||
| 
						 | 
					@ -548,12 +559,12 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
 | 
				
			||||||
	freq = le32_to_cpu(ev->freq);
 | 
						freq = le32_to_cpu(ev->freq);
 | 
				
			||||||
	dlen = le16_to_cpu(ev->len);
 | 
						dlen = le16_to_cpu(ev->len);
 | 
				
			||||||
	if (datap + len < ev->data + dlen) {
 | 
						if (datap + len < ev->data + dlen) {
 | 
				
			||||||
		ath6kl_err("invalid wmi_p2p_rx_probe_req_event: "
 | 
							ath6kl_err("invalid wmi_p2p_rx_probe_req_event: len=%d dlen=%u\n",
 | 
				
			||||||
			   "len=%d dlen=%u\n", len, dlen);
 | 
								   len, dlen);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "probe_req_report=%d\n",
 | 
							   "rx_probe_req: len=%u freq=%u probe_req_report=%d\n",
 | 
				
			||||||
		   dlen, freq, vif->probe_req_report);
 | 
							   dlen, freq, vif->probe_req_report);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
 | 
						if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
 | 
				
			||||||
| 
						 | 
					@ -592,8 +603,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
 | 
				
			||||||
	freq = le32_to_cpu(ev->freq);
 | 
						freq = le32_to_cpu(ev->freq);
 | 
				
			||||||
	dlen = le16_to_cpu(ev->len);
 | 
						dlen = le16_to_cpu(ev->len);
 | 
				
			||||||
	if (datap + len < ev->data + dlen) {
 | 
						if (datap + len < ev->data + dlen) {
 | 
				
			||||||
		ath6kl_err("invalid wmi_rx_action_event: "
 | 
							ath6kl_err("invalid wmi_rx_action_event: len=%d dlen=%u\n",
 | 
				
			||||||
			   "len=%d dlen=%u\n", len, dlen);
 | 
								   len, dlen);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
 | 
				
			||||||
| 
						 | 
					@ -687,7 +698,7 @@ static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
 | 
						ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
 | 
				
			||||||
			   le32_to_cpu(ev->sw_version),
 | 
								   le32_to_cpu(ev->sw_version),
 | 
				
			||||||
			   le32_to_cpu(ev->abi_version));
 | 
								   le32_to_cpu(ev->abi_version), ev->phy_cap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -777,16 +788,15 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
 | 
				
			||||||
		/* AP mode start/STA connected event */
 | 
							/* AP mode start/STA connected event */
 | 
				
			||||||
		struct net_device *dev = vif->ndev;
 | 
							struct net_device *dev = vif->ndev;
 | 
				
			||||||
		if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
 | 
							if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM "
 | 
								ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
				   "(AP started)\n",
 | 
									   "%s: freq %d bssid %pM (AP started)\n",
 | 
				
			||||||
				   __func__, le16_to_cpu(ev->u.ap_bss.ch),
 | 
									   __func__, le16_to_cpu(ev->u.ap_bss.ch),
 | 
				
			||||||
				   ev->u.ap_bss.bssid);
 | 
									   ev->u.ap_bss.bssid);
 | 
				
			||||||
			ath6kl_connect_ap_mode_bss(
 | 
								ath6kl_connect_ap_mode_bss(
 | 
				
			||||||
				vif, le16_to_cpu(ev->u.ap_bss.ch));
 | 
									vif, le16_to_cpu(ev->u.ap_bss.ch));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %pM "
 | 
								ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
				   "auth=%u keymgmt=%u cipher=%u apsd_info=%u "
 | 
									   "%s: aid %u mac_addr %pM auth=%u keymgmt=%u cipher=%u apsd_info=%u (STA connected)\n",
 | 
				
			||||||
				   "(STA connected)\n",
 | 
					 | 
				
			||||||
				   __func__, ev->u.ap_sta.aid,
 | 
									   __func__, ev->u.ap_sta.aid,
 | 
				
			||||||
				   ev->u.ap_sta.mac_addr,
 | 
									   ev->u.ap_sta.mac_addr,
 | 
				
			||||||
				   ev->u.ap_sta.auth,
 | 
									   ev->u.ap_sta.auth,
 | 
				
			||||||
| 
						 | 
					@ -1229,8 +1239,9 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
 | 
				
			||||||
	ev = (struct wmi_neighbor_report_event *) datap;
 | 
						ev = (struct wmi_neighbor_report_event *) datap;
 | 
				
			||||||
	if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
 | 
						if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
 | 
				
			||||||
	    > len) {
 | 
						    > len) {
 | 
				
			||||||
		ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event "
 | 
							ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
			   "(num=%d len=%d)\n", ev->num_neighbors, len);
 | 
								   "truncated neighbor event (num=%d len=%d)\n",
 | 
				
			||||||
 | 
								   ev->num_neighbors, len);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < ev->num_neighbors; i++) {
 | 
						for (i = 0; i < ev->num_neighbors; i++) {
 | 
				
			||||||
| 
						 | 
					@ -1814,12 +1825,14 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
 | 
				
			||||||
			     u32 home_dwell_time, u32 force_scan_interval,
 | 
								     u32 home_dwell_time, u32 force_scan_interval,
 | 
				
			||||||
			     s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates)
 | 
								     s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_supported_band *sband;
 | 
				
			||||||
	struct sk_buff *skb;
 | 
						struct sk_buff *skb;
 | 
				
			||||||
	struct wmi_begin_scan_cmd *sc;
 | 
						struct wmi_begin_scan_cmd *sc;
 | 
				
			||||||
	s8 size;
 | 
						s8 size, *supp_rates;
 | 
				
			||||||
	int i, band, ret;
 | 
						int i, band, ret;
 | 
				
			||||||
	struct ath6kl *ar = wmi->parent_dev;
 | 
						struct ath6kl *ar = wmi->parent_dev;
 | 
				
			||||||
	int num_rates;
 | 
						int num_rates;
 | 
				
			||||||
 | 
						u32 ratemask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size = sizeof(struct wmi_begin_scan_cmd);
 | 
						size = sizeof(struct wmi_begin_scan_cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1846,10 +1859,13 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
 | 
				
			||||||
	sc->num_ch = num_chan;
 | 
						sc->num_ch = num_chan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 | 
						for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 | 
				
			||||||
		struct ieee80211_supported_band *sband =
 | 
							sband = ar->wiphy->bands[band];
 | 
				
			||||||
		    ar->wiphy->bands[band];
 | 
					
 | 
				
			||||||
		u32 ratemask = rates[band];
 | 
							if (!sband)
 | 
				
			||||||
		u8 *supp_rates = sc->supp_rates[band].rates;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ratemask = rates[band];
 | 
				
			||||||
 | 
							supp_rates = sc->supp_rates[band].rates;
 | 
				
			||||||
		num_rates = 0;
 | 
							num_rates = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < sband->n_bitrates; i++) {
 | 
							for (i = 0; i < sband->n_bitrates; i++) {
 | 
				
			||||||
| 
						 | 
					@ -2129,8 +2145,8 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
 | 
				
			||||||
	struct wmi_add_cipher_key_cmd *cmd;
 | 
						struct wmi_add_cipher_key_cmd *cmd;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "key_usage=%d key_len=%d key_op_ctrl=%d\n",
 | 
							   "addkey cmd: key_index=%u key_type=%d key_usage=%d key_len=%d key_op_ctrl=%d\n",
 | 
				
			||||||
		   key_index, key_type, key_usage, key_len, key_op_ctrl);
 | 
							   key_index, key_type, key_usage, key_len, key_op_ctrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
 | 
						if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
 | 
				
			||||||
| 
						 | 
					@ -3047,8 +3063,8 @@ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID,
 | 
						res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID,
 | 
				
			||||||
				  NO_SYNC_WMIFLAG);
 | 
									  NO_SYNC_WMIFLAG);
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "ctrl_flags=0x%x-> res=%d\n",
 | 
							   "%s: nw_type=%u auth_mode=%u ch=%u ctrl_flags=0x%x-> res=%d\n",
 | 
				
			||||||
		   __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
 | 
							   __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
 | 
				
			||||||
		   le32_to_cpu(p->ctrl_flags), res);
 | 
							   le32_to_cpu(p->ctrl_flags), res);
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
| 
						 | 
					@ -3208,8 +3224,9 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
 | 
				
			||||||
	if (!skb)
 | 
						if (!skb)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "ie_len=%u\n", mgmt_frm_type, ie_len);
 | 
							   "set_appie_cmd: mgmt_frm_type=%u ie_len=%u\n",
 | 
				
			||||||
 | 
							   mgmt_frm_type, ie_len);
 | 
				
			||||||
	p = (struct wmi_set_appie_cmd *) skb->data;
 | 
						p = (struct wmi_set_appie_cmd *) skb->data;
 | 
				
			||||||
	p->mgmt_frm_type = mgmt_frm_type;
 | 
						p->mgmt_frm_type = mgmt_frm_type;
 | 
				
			||||||
	p->ie_len = ie_len;
 | 
						p->ie_len = ie_len;
 | 
				
			||||||
| 
						 | 
					@ -3310,8 +3327,9 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
 | 
				
			||||||
	wmi->last_mgmt_tx_frame = buf;
 | 
						wmi->last_mgmt_tx_frame = buf;
 | 
				
			||||||
	wmi->last_mgmt_tx_frame_len = data_len;
 | 
						wmi->last_mgmt_tx_frame_len = data_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "len=%u\n", id, freq, wait, data_len);
 | 
							   "send_action_cmd: id=%u freq=%u wait=%u len=%u\n",
 | 
				
			||||||
 | 
							   id, freq, wait, data_len);
 | 
				
			||||||
	p = (struct wmi_send_action_cmd *) skb->data;
 | 
						p = (struct wmi_send_action_cmd *) skb->data;
 | 
				
			||||||
	p->id = cpu_to_le32(id);
 | 
						p->id = cpu_to_le32(id);
 | 
				
			||||||
	p->freq = cpu_to_le32(freq);
 | 
						p->freq = cpu_to_le32(freq);
 | 
				
			||||||
| 
						 | 
					@ -3348,8 +3366,9 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
 | 
				
			||||||
	wmi->last_mgmt_tx_frame = buf;
 | 
						wmi->last_mgmt_tx_frame = buf;
 | 
				
			||||||
	wmi->last_mgmt_tx_frame_len = data_len;
 | 
						wmi->last_mgmt_tx_frame_len = data_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "len=%u\n", id, freq, wait, data_len);
 | 
							   "send_action_cmd: id=%u freq=%u wait=%u len=%u\n",
 | 
				
			||||||
 | 
							   id, freq, wait, data_len);
 | 
				
			||||||
	p = (struct wmi_send_mgmt_cmd *) skb->data;
 | 
						p = (struct wmi_send_mgmt_cmd *) skb->data;
 | 
				
			||||||
	p->id = cpu_to_le32(id);
 | 
						p->id = cpu_to_le32(id);
 | 
				
			||||||
	p->freq = cpu_to_le32(freq);
 | 
						p->freq = cpu_to_le32(freq);
 | 
				
			||||||
| 
						 | 
					@ -3402,8 +3421,9 @@ int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
 | 
				
			||||||
	if (!skb)
 | 
						if (!skb)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%pM "
 | 
						ath6kl_dbg(ATH6KL_DBG_WMI,
 | 
				
			||||||
		   "len=%u\n", freq, dst, data_len);
 | 
							   "send_probe_response_cmd: freq=%u dst=%pM len=%u\n",
 | 
				
			||||||
 | 
							   freq, dst, data_len);
 | 
				
			||||||
	p = (struct wmi_p2p_probe_response_cmd *) skb->data;
 | 
						p = (struct wmi_p2p_probe_response_cmd *) skb->data;
 | 
				
			||||||
	p->freq = cpu_to_le32(freq);
 | 
						p->freq = cpu_to_le32(freq);
 | 
				
			||||||
	memcpy(p->destination_addr, dst, ETH_ALEN);
 | 
						memcpy(p->destination_addr, dst, ETH_ALEN);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,8 @@ struct wmi_data_sync_bufs {
 | 
				
			||||||
#define WMM_AC_VI   2		/* video */
 | 
					#define WMM_AC_VI   2		/* video */
 | 
				
			||||||
#define WMM_AC_VO   3		/* voice */
 | 
					#define WMM_AC_VO   3		/* voice */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WMI_VOICE_USER_PRIORITY		0x7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wmi {
 | 
					struct wmi {
 | 
				
			||||||
	u16 stream_exist_for_ac[WMM_NUM_AC];
 | 
						u16 stream_exist_for_ac[WMM_NUM_AC];
 | 
				
			||||||
	u8 fat_pipe_exist;
 | 
						u8 fat_pipe_exist;
 | 
				
			||||||
| 
						 | 
					@ -1151,6 +1153,7 @@ enum wmi_phy_mode {
 | 
				
			||||||
	WMI_11AG_MODE = 0x3,
 | 
						WMI_11AG_MODE = 0x3,
 | 
				
			||||||
	WMI_11B_MODE = 0x4,
 | 
						WMI_11B_MODE = 0x4,
 | 
				
			||||||
	WMI_11GONLY_MODE = 0x5,
 | 
						WMI_11GONLY_MODE = 0x5,
 | 
				
			||||||
 | 
						WMI_11G_HT20	= 0x6,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define WMI_MAX_CHANNELS        32
 | 
					#define WMI_MAX_CHANNELS        32
 | 
				
			||||||
| 
						 | 
					@ -1416,6 +1419,16 @@ struct wmi_ready_event_2 {
 | 
				
			||||||
	u8 phy_cap;
 | 
						u8 phy_cap;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* WMI_PHY_CAPABILITY */
 | 
				
			||||||
 | 
					enum wmi_phy_cap {
 | 
				
			||||||
 | 
						WMI_11A_CAP = 0x01,
 | 
				
			||||||
 | 
						WMI_11G_CAP = 0x02,
 | 
				
			||||||
 | 
						WMI_11AG_CAP = 0x03,
 | 
				
			||||||
 | 
						WMI_11AN_CAP = 0x04,
 | 
				
			||||||
 | 
						WMI_11GN_CAP = 0x05,
 | 
				
			||||||
 | 
						WMI_11AGN_CAP = 0x06,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Connect Event */
 | 
					/* Connect Event */
 | 
				
			||||||
struct wmi_connect_event {
 | 
					struct wmi_connect_event {
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
| 
						 | 
					@ -1468,6 +1481,17 @@ enum wmi_disconnect_reason {
 | 
				
			||||||
	IBSS_MERGE = 0xe,
 | 
						IBSS_MERGE = 0xe,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* AP mode disconnect proto_reasons */
 | 
				
			||||||
 | 
					enum ap_disconnect_reason {
 | 
				
			||||||
 | 
						WMI_AP_REASON_STA_LEFT		= 101,
 | 
				
			||||||
 | 
						WMI_AP_REASON_FROM_HOST		= 102,
 | 
				
			||||||
 | 
						WMI_AP_REASON_COMM_TIMEOUT	= 103,
 | 
				
			||||||
 | 
						WMI_AP_REASON_MAX_STA		= 104,
 | 
				
			||||||
 | 
						WMI_AP_REASON_ACL		= 105,
 | 
				
			||||||
 | 
						WMI_AP_REASON_STA_ROAM		= 106,
 | 
				
			||||||
 | 
						WMI_AP_REASON_DFS_CHANNEL	= 107,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ATH6KL_COUNTRY_RD_SHIFT        16
 | 
					#define ATH6KL_COUNTRY_RD_SHIFT        16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ath6kl_wmi_regdomain {
 | 
					struct ath6kl_wmi_regdomain {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -892,34 +892,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
 | 
				
			||||||
		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
 | 
							      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct ath9k_rtt_hist *hist;
 | 
					 | 
				
			||||||
	u32 *table;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	bool restore;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!ah->caldata)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hist = &ah->caldata->rtt_hist;
 | 
					 | 
				
			||||||
	if (!hist->num_readings)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ar9003_hw_rtt_enable(ah);
 | 
					 | 
				
			||||||
	ar9003_hw_rtt_set_mask(ah, 0x00);
 | 
					 | 
				
			||||||
	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
 | 
					 | 
				
			||||||
		if (!(ah->rxchainmask & (1 << i)))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		table = &hist->table[i][hist->num_readings][0];
 | 
					 | 
				
			||||||
		ar9003_hw_rtt_load_hist(ah, i, table);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	restore = ar9003_hw_rtt_force_restore(ah);
 | 
					 | 
				
			||||||
	ar9003_hw_rtt_disable(ah);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return restore;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ar9003_hw_init_cal(struct ath_hw *ah,
 | 
					static bool ar9003_hw_init_cal(struct ath_hw *ah,
 | 
				
			||||||
			       struct ath9k_channel *chan)
 | 
								       struct ath9k_channel *chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -942,9 +914,10 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
 | 
				
			||||||
		if (!ar9003_hw_rtt_restore(ah, chan))
 | 
							if (!ar9003_hw_rtt_restore(ah, chan))
 | 
				
			||||||
			run_rtt_cal = true;
 | 
								run_rtt_cal = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ath_dbg(common, CALIBRATE, "RTT restore %s\n",
 | 
							if (run_rtt_cal)
 | 
				
			||||||
			run_rtt_cal ? "failed" : "succeed");
 | 
								ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	run_agc_cal = run_rtt_cal;
 | 
						run_agc_cal = run_rtt_cal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (run_rtt_cal) {
 | 
						if (run_rtt_cal) {
 | 
				
			||||||
| 
						 | 
					@ -1069,17 +1042,14 @@ skip_tx_iqcal:
 | 
				
			||||||
#undef CL_TAB_ENTRY
 | 
					#undef CL_TAB_ENTRY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (run_rtt_cal && caldata) {
 | 
						if (run_rtt_cal && caldata) {
 | 
				
			||||||
		struct ath9k_rtt_hist *hist = &caldata->rtt_hist;
 | 
							if (is_reusable) {
 | 
				
			||||||
		if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
 | 
								if (!ath9k_hw_rfbus_req(ah))
 | 
				
			||||||
			u32 *table;
 | 
									ath_err(ath9k_hw_common(ah),
 | 
				
			||||||
 | 
										"Could not stop baseband\n");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ar9003_hw_rtt_fill_hist(ah);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			hist->num_readings++;
 | 
								ath9k_hw_rfbus_done(ah);
 | 
				
			||||||
			for (i = 0; i < AR9300_MAX_CHAINS; i++) {
 | 
					 | 
				
			||||||
				if (!(ah->rxchainmask & (1 << i)))
 | 
					 | 
				
			||||||
					continue;
 | 
					 | 
				
			||||||
				table = &hist->table[i][hist->num_readings][0];
 | 
					 | 
				
			||||||
				ar9003_hw_rtt_fill_hist(ah, i, table);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ar9003_hw_rtt_disable(ah);
 | 
							ar9003_hw_rtt_disable(ah);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -756,7 +756,7 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 | 
				
			||||||
		if (caldata) {
 | 
							if (caldata) {
 | 
				
			||||||
			caldata->done_txiqcal_once = false;
 | 
								caldata->done_txiqcal_once = false;
 | 
				
			||||||
			caldata->done_txclcal_once = false;
 | 
								caldata->done_txclcal_once = false;
 | 
				
			||||||
			caldata->rtt_hist.num_readings = 0;
 | 
								caldata->rtt_done = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ath9k_hw_init_cal(ah, chan))
 | 
							if (!ath9k_hw_init_cal(ah, chan))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "hw.h"
 | 
					#include "hw.h"
 | 
				
			||||||
 | 
					#include "hw-ops.h"
 | 
				
			||||||
#include "ar9003_phy.h"
 | 
					#include "ar9003_phy.h"
 | 
				
			||||||
#include "ar9003_rtt.h"
 | 
					#include "ar9003_rtt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
 | 
				
			||||||
		      RTT_ACCESS_TIMEOUT);
 | 
							      RTT_ACCESS_TIMEOUT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table)
 | 
					void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int chain, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
 | 
						for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
 | 
				
			||||||
		ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]);
 | 
							if (!(ah->rxchainmask & (1 << chain)))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
 | 
				
			||||||
 | 
								ar9003_hw_rtt_load_hist_entry(ah, chain, i,
 | 
				
			||||||
 | 
										      ah->caldata->rtt_table[chain][i]);
 | 
				
			||||||
 | 
								ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 | 
				
			||||||
 | 
									"Load RTT value at idx %d, chain %d: 0x%x\n",
 | 
				
			||||||
 | 
									i, chain, ah->caldata->rtt_table[chain][i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
 | 
					static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
 | 
				
			||||||
| 
						 | 
					@ -128,27 +138,71 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
 | 
				
			||||||
			   RTT_ACCESS_TIMEOUT))
 | 
								   RTT_ACCESS_TIMEOUT))
 | 
				
			||||||
		return RTT_BAD_VALUE;
 | 
							return RTT_BAD_VALUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain));
 | 
						val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
 | 
				
			||||||
 | 
							 AR_PHY_RTT_SW_RTT_TABLE_DATA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return val;
 | 
						return val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table)
 | 
					void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int chain, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
 | 
						for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
 | 
				
			||||||
		table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
 | 
							if (!(ah->rxchainmask & (1 << chain)))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
 | 
				
			||||||
 | 
								ah->caldata->rtt_table[chain][i] =
 | 
				
			||||||
 | 
									ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
 | 
				
			||||||
 | 
								ath_dbg(ath9k_hw_common(ah), CALIBRATE,
 | 
				
			||||||
 | 
									"RTT value at idx %d, chain %d is: 0x%x\n",
 | 
				
			||||||
 | 
									i, chain, ah->caldata->rtt_table[chain][i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ah->caldata->rtt_done = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
 | 
					void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, j;
 | 
						int chain, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
 | 
						for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
 | 
				
			||||||
		if (!(ah->rxchainmask & (1 << i)))
 | 
							if (!(ah->rxchainmask & (1 << chain)))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++)
 | 
							for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
 | 
				
			||||||
			ar9003_hw_rtt_load_hist_entry(ah, i, j, 0);
 | 
								ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ah->caldata)
 | 
				
			||||||
 | 
							ah->caldata->rtt_done = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool restore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ah->caldata)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ah->caldata->rtt_done)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ar9003_hw_rtt_enable(ah);
 | 
				
			||||||
 | 
						ar9003_hw_rtt_set_mask(ah, 0x10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ath9k_hw_rfbus_req(ah)) {
 | 
				
			||||||
 | 
							ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
 | 
				
			||||||
 | 
							restore = false;
 | 
				
			||||||
 | 
							goto fail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ar9003_hw_rtt_load_hist(ah);
 | 
				
			||||||
 | 
						restore = ar9003_hw_rtt_force_restore(ah);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fail:
 | 
				
			||||||
 | 
						ath9k_hw_rfbus_done(ah);
 | 
				
			||||||
 | 
						ar9003_hw_rtt_disable(ah);
 | 
				
			||||||
 | 
						return restore;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,8 +21,9 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah);
 | 
				
			||||||
void ar9003_hw_rtt_disable(struct ath_hw *ah);
 | 
					void ar9003_hw_rtt_disable(struct ath_hw *ah);
 | 
				
			||||||
void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
 | 
					void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
 | 
				
			||||||
bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
 | 
					bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
 | 
				
			||||||
void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table);
 | 
					void ar9003_hw_rtt_load_hist(struct ath_hw *ah);
 | 
				
			||||||
void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table);
 | 
					void ar9003_hw_rtt_fill_hist(struct ath_hw *ah);
 | 
				
			||||||
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
 | 
					void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
 | 
				
			||||||
 | 
					bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1702,10 +1702,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
 | 
				
			||||||
	 * For AR9462, make sure that calibration data for
 | 
						 * For AR9462, make sure that calibration data for
 | 
				
			||||||
	 * re-using are present.
 | 
						 * re-using are present.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (AR_SREV_9462(ah) && (!ah->caldata ||
 | 
						if (AR_SREV_9462(ah) && (ah->caldata &&
 | 
				
			||||||
				 !ah->caldata->done_txiqcal_once ||
 | 
									 (!ah->caldata->done_txiqcal_once ||
 | 
				
			||||||
				  !ah->caldata->done_txclcal_once ||
 | 
									  !ah->caldata->done_txclcal_once ||
 | 
				
			||||||
				 !ah->caldata->rtt_hist.num_readings))
 | 
									  !ah->caldata->rtt_done)))
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
 | 
						ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
 | 
				
			||||||
| 
						 | 
					@ -1941,7 +1941,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 | 
				
			||||||
	if (caldata) {
 | 
						if (caldata) {
 | 
				
			||||||
		caldata->done_txiqcal_once = false;
 | 
							caldata->done_txiqcal_once = false;
 | 
				
			||||||
		caldata->done_txclcal_once = false;
 | 
							caldata->done_txclcal_once = false;
 | 
				
			||||||
		caldata->rtt_hist.num_readings = 0;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!ath9k_hw_init_cal(ah, chan))
 | 
						if (!ath9k_hw_init_cal(ah, chan))
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -348,12 +348,6 @@ enum ath9k_int {
 | 
				
			||||||
	 CHANNEL_HT40MINUS)
 | 
						 CHANNEL_HT40MINUS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_RTT_TABLE_ENTRY     6
 | 
					#define MAX_RTT_TABLE_ENTRY     6
 | 
				
			||||||
#define RTT_HIST_MAX            3
 | 
					 | 
				
			||||||
struct ath9k_rtt_hist {
 | 
					 | 
				
			||||||
	u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY];
 | 
					 | 
				
			||||||
	u8 num_readings;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_IQCAL_MEASUREMENT	8
 | 
					#define MAX_IQCAL_MEASUREMENT	8
 | 
				
			||||||
#define MAX_CL_TAB_ENTRY	16
 | 
					#define MAX_CL_TAB_ENTRY	16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -363,6 +357,7 @@ struct ath9k_hw_cal_data {
 | 
				
			||||||
	int32_t CalValid;
 | 
						int32_t CalValid;
 | 
				
			||||||
	int8_t iCoff;
 | 
						int8_t iCoff;
 | 
				
			||||||
	int8_t qCoff;
 | 
						int8_t qCoff;
 | 
				
			||||||
 | 
						bool rtt_done;
 | 
				
			||||||
	bool paprd_done;
 | 
						bool paprd_done;
 | 
				
			||||||
	bool nfcal_pending;
 | 
						bool nfcal_pending;
 | 
				
			||||||
	bool nfcal_interference;
 | 
						bool nfcal_interference;
 | 
				
			||||||
| 
						 | 
					@ -373,8 +368,8 @@ struct ath9k_hw_cal_data {
 | 
				
			||||||
	u32 num_measures[AR9300_MAX_CHAINS];
 | 
						u32 num_measures[AR9300_MAX_CHAINS];
 | 
				
			||||||
	int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
 | 
						int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
 | 
				
			||||||
	u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
 | 
						u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
 | 
				
			||||||
 | 
						u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY];
 | 
				
			||||||
	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
 | 
						struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
 | 
				
			||||||
	struct ath9k_rtt_hist rtt_hist;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ath9k_channel {
 | 
					struct ath9k_channel {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,11 +107,9 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
 | 
				
			||||||
	dev->dma_dev = core->dma_dev;
 | 
						dev->dma_dev = core->dma_dev;
 | 
				
			||||||
	dev->irq = core->irq;
 | 
						dev->irq = core->irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	dev->board_vendor = core->bus->boardinfo.vendor;
 | 
						dev->board_vendor = core->bus->boardinfo.vendor;
 | 
				
			||||||
	dev->board_type = core->bus->boardinfo.type;
 | 
						dev->board_type = core->bus->boardinfo.type;
 | 
				
			||||||
	dev->board_rev = core->bus->boardinfo.rev;
 | 
						dev->board_rev = core->bus->sprom.board_rev;
 | 
				
			||||||
	*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->chip_id = core->bus->chipinfo.id;
 | 
						dev->chip_id = core->bus->chipinfo.id;
 | 
				
			||||||
	dev->chip_rev = core->bus->chipinfo.rev;
 | 
						dev->chip_rev = core->bus->chipinfo.rev;
 | 
				
			||||||
| 
						 | 
					@ -210,7 +208,7 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->board_vendor = sdev->bus->boardinfo.vendor;
 | 
						dev->board_vendor = sdev->bus->boardinfo.vendor;
 | 
				
			||||||
	dev->board_type = sdev->bus->boardinfo.type;
 | 
						dev->board_type = sdev->bus->boardinfo.type;
 | 
				
			||||||
	dev->board_rev = sdev->bus->boardinfo.rev;
 | 
						dev->board_rev = sdev->bus->sprom.board_rev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->chip_id = sdev->bus->chip_id;
 | 
						dev->chip_id = sdev->bus->chip_id;
 | 
				
			||||||
	dev->chip_rev = sdev->bus->chip_rev;
 | 
						dev->chip_rev = sdev->bus->chip_rev;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1109,7 +1109,7 @@ static bool b43_dma_translation_in_low_word(struct b43_wldev *dev,
 | 
				
			||||||
#ifdef CONFIG_B43_SSB
 | 
					#ifdef CONFIG_B43_SSB
 | 
				
			||||||
	if (dev->dev->bus_type == B43_BUS_SSB &&
 | 
						if (dev->dev->bus_type == B43_BUS_SSB &&
 | 
				
			||||||
	    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
 | 
						    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
 | 
				
			||||||
	    !(dev->dev->sdev->bus->host_pci->is_pcie &&
 | 
						    !(pci_is_pcie(dev->dev->sdev->bus->host_pci) &&
 | 
				
			||||||
	      ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64))
 | 
						      ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64))
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5243,10 +5243,10 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* boardflags workarounds */
 | 
						/* boardflags workarounds */
 | 
				
			||||||
	if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
 | 
						if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
 | 
				
			||||||
	    bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74)
 | 
						    bus->chip_id == 0x4301 && bus->sprom.board_rev == 0x74)
 | 
				
			||||||
		bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST;
 | 
							bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST;
 | 
				
			||||||
	if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
 | 
						if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
 | 
				
			||||||
	    bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40)
 | 
						    bus->boardinfo.type == 0x4E && bus->sprom.board_rev > 0x40)
 | 
				
			||||||
		bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
 | 
							bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
 | 
				
			||||||
	if (bus->bustype == SSB_BUSTYPE_PCI) {
 | 
						if (bus->bustype == SSB_BUSTYPE_PCI) {
 | 
				
			||||||
		pdev = bus->host_pci;
 | 
							pdev = bus->host_pci;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1573,8 +1573,6 @@ static void b43legacy_request_firmware(struct work_struct *work)
 | 
				
			||||||
	const char *filename;
 | 
						const char *filename;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* do dummy read */
 | 
					 | 
				
			||||||
	ssb_read32(dev->dev, SSB_TMSHIGH);
 | 
					 | 
				
			||||||
	if (!fw->ucode) {
 | 
						if (!fw->ucode) {
 | 
				
			||||||
		if (rev == 2)
 | 
							if (rev == 2)
 | 
				
			||||||
			filename = "ucode2";
 | 
								filename = "ucode2";
 | 
				
			||||||
| 
						 | 
					@ -3781,7 +3779,7 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus)
 | 
				
			||||||
	/* boardflags workarounds */
 | 
						/* boardflags workarounds */
 | 
				
			||||||
	if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
 | 
						if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
 | 
				
			||||||
	    bus->boardinfo.type == 0x4E &&
 | 
						    bus->boardinfo.type == 0x4E &&
 | 
				
			||||||
	    bus->boardinfo.rev > 0x40)
 | 
						    bus->sprom.board_rev > 0x40)
 | 
				
			||||||
		bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
 | 
							bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -408,7 +408,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (is_bcm_board_vendor(dev) &&
 | 
							if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
		    (dev->dev->bus->boardinfo.type == 0x0416) &&
 | 
							    (dev->dev->bus->boardinfo.type == 0x0416) &&
 | 
				
			||||||
		    (dev->dev->bus->boardinfo.rev == 0x0017))
 | 
							    (dev->dev->bus->sprom.board_rev == 0x0017))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		b43legacy_ilt_write(dev, 0x5001, 0x0002);
 | 
							b43legacy_ilt_write(dev, 0x5001, 0x0002);
 | 
				
			||||||
| 
						 | 
					@ -424,7 +424,7 @@ static void b43legacy_phy_setupg(struct b43legacy_wldev *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (is_bcm_board_vendor(dev) &&
 | 
							if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
		    (dev->dev->bus->boardinfo.type == 0x0416) &&
 | 
							    (dev->dev->bus->boardinfo.type == 0x0416) &&
 | 
				
			||||||
		    (dev->dev->bus->boardinfo.rev == 0x0017))
 | 
							    (dev->dev->bus->sprom.board_rev == 0x0017))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		b43legacy_ilt_write(dev, 0x0401, 0x0002);
 | 
							b43legacy_ilt_write(dev, 0x0401, 0x0002);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1998,7 +1998,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
 | 
				
			||||||
			if (phy->type == B43legacy_PHYTYPE_G) {
 | 
								if (phy->type == B43legacy_PHYTYPE_G) {
 | 
				
			||||||
				if (is_bcm_board_vendor(dev) &&
 | 
									if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
									    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.rev >= 30)
 | 
									    dev->dev->bus->sprom.board_rev >= 30)
 | 
				
			||||||
					att = 3;
 | 
										att = 3;
 | 
				
			||||||
				else if (is_bcm_board_vendor(dev) &&
 | 
									else if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
					 dev->dev->bus->boardinfo.type == 0x416)
 | 
										 dev->dev->bus->boardinfo.type == 0x416)
 | 
				
			||||||
| 
						 | 
					@ -2008,7 +2008,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if (is_bcm_board_vendor(dev) &&
 | 
									if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
									    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.rev >= 30)
 | 
									    dev->dev->bus->sprom.board_rev >= 30)
 | 
				
			||||||
					att = 7;
 | 
										att = 7;
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					att = 6;
 | 
										att = 6;
 | 
				
			||||||
| 
						 | 
					@ -2018,7 +2018,7 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
 | 
				
			||||||
			if (phy->type == B43legacy_PHYTYPE_G) {
 | 
								if (phy->type == B43legacy_PHYTYPE_G) {
 | 
				
			||||||
				if (is_bcm_board_vendor(dev) &&
 | 
									if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
									    dev->dev->bus->boardinfo.type == 0x421 &&
 | 
				
			||||||
				    dev->dev->bus->boardinfo.rev >= 30)
 | 
									    dev->dev->bus->sprom.board_rev >= 30)
 | 
				
			||||||
					att = 3;
 | 
										att = 3;
 | 
				
			||||||
				else if (is_bcm_board_vendor(dev) &&
 | 
									else if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
					 dev->dev->bus->boardinfo.type ==
 | 
										 dev->dev->bus->boardinfo.type ==
 | 
				
			||||||
| 
						 | 
					@ -2052,9 +2052,9 @@ u16 b43legacy_default_radio_attenuation(struct b43legacy_wldev *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (is_bcm_board_vendor(dev) &&
 | 
						if (is_bcm_board_vendor(dev) &&
 | 
				
			||||||
	    dev->dev->bus->boardinfo.type == 0x421) {
 | 
						    dev->dev->bus->boardinfo.type == 0x421) {
 | 
				
			||||||
		if (dev->dev->bus->boardinfo.rev < 0x43)
 | 
							if (dev->dev->bus->sprom.board_rev < 0x43)
 | 
				
			||||||
			att = 2;
 | 
								att = 2;
 | 
				
			||||||
		else if (dev->dev->bus->boardinfo.rev < 0x51)
 | 
							else if (dev->dev->bus->sprom.board_rev < 0x51)
 | 
				
			||||||
			att = 3;
 | 
								att = 3;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (att == 0xFFFF)
 | 
						if (att == 0xFFFF)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,18 +85,15 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
	sdiodev->irq_wake = true;
 | 
						sdiodev->irq_wake = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* must configure SDIO_CCCR_IENx to enable irq */
 | 
						/* must configure SDIO_CCCR_IENx to enable irq */
 | 
				
			||||||
	data = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_0,
 | 
						data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
 | 
				
			||||||
				     SDIO_CCCR_IENx, &ret);
 | 
					 | 
				
			||||||
	data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
 | 
						data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx,
 | 
						brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
 | 
				
			||||||
			       data, &ret);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* redirect, configure ane enable io for interrupt signal */
 | 
						/* redirect, configure ane enable io for interrupt signal */
 | 
				
			||||||
	data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
 | 
						data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
 | 
				
			||||||
	if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH)
 | 
						if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH)
 | 
				
			||||||
		data |= SDIO_SEPINT_ACT_HI;
 | 
							data |= SDIO_SEPINT_ACT_HI;
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT,
 | 
						brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
 | 
				
			||||||
			       data, &ret);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -105,9 +102,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	brcmf_dbg(TRACE, "Entering\n");
 | 
						brcmf_dbg(TRACE, "Entering\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT,
 | 
						brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
 | 
				
			||||||
			       0, NULL);
 | 
						brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, 0, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sdiodev->irq_wake) {
 | 
						if (sdiodev->irq_wake) {
 | 
				
			||||||
		disable_irq_wake(sdiodev->irq);
 | 
							disable_irq_wake(sdiodev->irq);
 | 
				
			||||||
| 
						 | 
					@ -158,153 +154,147 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
 | 
					#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
 | 
					int
 | 
				
			||||||
			 int *err)
 | 
					brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						int err = 0, i;
 | 
				
			||||||
 | 
						u8 addr[3];
 | 
				
			||||||
 | 
						s32 retry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
 | 
				
			||||||
 | 
						addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
 | 
				
			||||||
 | 
						addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 3; i++) {
 | 
				
			||||||
 | 
							retry = 0;
 | 
				
			||||||
 | 
							do {
 | 
				
			||||||
 | 
								if (retry)
 | 
				
			||||||
 | 
									usleep_range(1000, 2000);
 | 
				
			||||||
 | 
								err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
 | 
				
			||||||
 | 
										SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
 | 
				
			||||||
 | 
										&addr[i]);
 | 
				
			||||||
 | 
							} while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (err) {
 | 
				
			||||||
 | 
								brcmf_dbg(ERROR, "failed at addr:0x%0x\n",
 | 
				
			||||||
 | 
									  SBSDIO_FUNC1_SBADDRLOW + i);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
 | 
				
			||||||
 | 
								void *data, bool write)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 func_num, reg_size;
 | 
				
			||||||
 | 
						u32 bar;
 | 
				
			||||||
	s32 retry = 0;
 | 
						s32 retry = 0;
 | 
				
			||||||
	u8 data = 0;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * figure out how to read the register based on address range
 | 
				
			||||||
 | 
						 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
 | 
				
			||||||
 | 
						 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
 | 
				
			||||||
 | 
						 * The rest: function 1 silicon backplane core registers
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((addr & ~REG_F0_REG_MASK) == 0) {
 | 
				
			||||||
 | 
							func_num = SDIO_FUNC_0;
 | 
				
			||||||
 | 
							reg_size = 1;
 | 
				
			||||||
 | 
						} else if ((addr & ~REG_F1_MISC_MASK) == 0) {
 | 
				
			||||||
 | 
							func_num = SDIO_FUNC_1;
 | 
				
			||||||
 | 
							reg_size = 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							func_num = SDIO_FUNC_1;
 | 
				
			||||||
 | 
							reg_size = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Set the window for SB core register */
 | 
				
			||||||
 | 
							bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 | 
				
			||||||
 | 
							if (bar != sdiodev->sbwad) {
 | 
				
			||||||
 | 
								ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
 | 
				
			||||||
 | 
								if (ret != 0) {
 | 
				
			||||||
 | 
									memset(data, 0xFF, reg_size);
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sdiodev->sbwad = bar;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							addr &= SBSDIO_SB_OFT_ADDR_MASK;
 | 
				
			||||||
 | 
							addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
 | 
							if (!write)
 | 
				
			||||||
 | 
								memset(data, 0, reg_size);
 | 
				
			||||||
		if (retry)	/* wait for 1 ms till bus get settled down */
 | 
							if (retry)	/* wait for 1 ms till bus get settled down */
 | 
				
			||||||
			udelay(1000);
 | 
								usleep_range(1000, 2000);
 | 
				
			||||||
		status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
 | 
							if (reg_size == 1)
 | 
				
			||||||
						  addr, (u8 *) &data);
 | 
								ret = brcmf_sdioh_request_byte(sdiodev, write,
 | 
				
			||||||
	} while (status != 0
 | 
											       func_num, addr, data);
 | 
				
			||||||
		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
 | 
							else
 | 
				
			||||||
	if (err)
 | 
								ret = brcmf_sdioh_request_word(sdiodev, write,
 | 
				
			||||||
		*err = status;
 | 
											       func_num, addr, data, 4);
 | 
				
			||||||
 | 
						} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
 | 
						if (ret != 0)
 | 
				
			||||||
		  fnc_num, addr, data);
 | 
							brcmf_dbg(ERROR, "failed with %d\n", ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 data;
 | 
				
			||||||
 | 
						int retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						brcmf_dbg(INFO, "addr:0x%08x\n", addr);
 | 
				
			||||||
 | 
						retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
 | 
				
			||||||
 | 
						brcmf_dbg(INFO, "data:0x%02x\n", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							*ret = retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return data;
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 | 
				
			||||||
brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
 | 
					 | 
				
			||||||
		       u8 data, int *err)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						u32 data;
 | 
				
			||||||
	s32 retry = 0;
 | 
						int retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						brcmf_dbg(INFO, "addr:0x%08x\n", addr);
 | 
				
			||||||
		if (retry)	/* wait for 1 ms till bus get settled down */
 | 
						retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
 | 
				
			||||||
			udelay(1000);
 | 
						brcmf_dbg(INFO, "data:0x%08x\n", data);
 | 
				
			||||||
		status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
 | 
					 | 
				
			||||||
						  addr, (u8 *) &data);
 | 
					 | 
				
			||||||
	} while (status != 0
 | 
					 | 
				
			||||||
		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
 | 
					 | 
				
			||||||
	if (err)
 | 
					 | 
				
			||||||
		*err = status;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
 | 
						if (ret)
 | 
				
			||||||
		  fnc_num, addr, data);
 | 
							*ret = retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
 | 
				
			||||||
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 | 
							      u8 data, int *ret)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err = 0;
 | 
						int retval;
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
 | 
					 | 
				
			||||||
			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
 | 
					 | 
				
			||||||
	if (!err)
 | 
					 | 
				
			||||||
		brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
				       SBSDIO_FUNC1_SBADDRMID,
 | 
					 | 
				
			||||||
				       (address >> 16) & SBSDIO_SBADDRMID_MASK,
 | 
					 | 
				
			||||||
				       &err);
 | 
					 | 
				
			||||||
	if (!err)
 | 
					 | 
				
			||||||
		brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
				       SBSDIO_FUNC1_SBADDRHIGH,
 | 
					 | 
				
			||||||
				       (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
 | 
					 | 
				
			||||||
				       &err);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
 | 
				
			||||||
 | 
						retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							*ret = retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size)
 | 
					void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 | 
				
			||||||
 | 
							      u32 data, int *ret)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						int retval;
 | 
				
			||||||
	u32 word = 0;
 | 
					 | 
				
			||||||
	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
 | 
						brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
 | 
				
			||||||
 | 
						retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bar0 != sdiodev->sbwad) {
 | 
						if (ret)
 | 
				
			||||||
		if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
 | 
							*ret = retval;
 | 
				
			||||||
			return 0xFFFFFFFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sdiodev->sbwad = bar0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr &= SBSDIO_SB_OFT_ADDR_MASK;
 | 
					 | 
				
			||||||
	if (size == 4)
 | 
					 | 
				
			||||||
		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
					  addr, &word, size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sdiodev->regfail = (status != 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	brcmf_dbg(INFO, "u32data = 0x%x\n", word);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* if ok, return appropriately masked word */
 | 
					 | 
				
			||||||
	if (status == 0) {
 | 
					 | 
				
			||||||
		switch (size) {
 | 
					 | 
				
			||||||
		case sizeof(u8):
 | 
					 | 
				
			||||||
			return word & 0xff;
 | 
					 | 
				
			||||||
		case sizeof(u16):
 | 
					 | 
				
			||||||
			return word & 0xffff;
 | 
					 | 
				
			||||||
		case sizeof(u32):
 | 
					 | 
				
			||||||
			return word;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			sdiodev->regfail = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* otherwise, bad sdio access or invalid size */
 | 
					 | 
				
			||||||
	brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
 | 
					 | 
				
			||||||
	return 0xFFFFFFFF;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
 | 
					 | 
				
			||||||
			   u32 data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int status;
 | 
					 | 
				
			||||||
	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 | 
					 | 
				
			||||||
	int err = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
 | 
					 | 
				
			||||||
		  addr, size * 8, data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (bar0 != sdiodev->sbwad) {
 | 
					 | 
				
			||||||
		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
 | 
					 | 
				
			||||||
		if (err)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sdiodev->sbwad = bar0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr &= SBSDIO_SB_OFT_ADDR_MASK;
 | 
					 | 
				
			||||||
	if (size == 4)
 | 
					 | 
				
			||||||
		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 | 
					 | 
				
			||||||
	status =
 | 
					 | 
				
			||||||
	    brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
				     addr, &data, size);
 | 
					 | 
				
			||||||
	sdiodev->regfail = (status != 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (status == 0)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n",
 | 
					 | 
				
			||||||
		  data, addr, size);
 | 
					 | 
				
			||||||
	return 0xFFFFFFFF;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return sdiodev->regfail;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
 | 
					static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,43 +346,17 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read client card reg */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
 | 
					 | 
				
			||||||
			 int regsize, u32 *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((func == 0) || (regsize == 1)) {
 | 
					 | 
				
			||||||
		u8 temp = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
 | 
					 | 
				
			||||||
					 &temp);
 | 
					 | 
				
			||||||
		*data = temp;
 | 
					 | 
				
			||||||
		*data &= 0xff;
 | 
					 | 
				
			||||||
		brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
 | 
					 | 
				
			||||||
					 data, regsize);
 | 
					 | 
				
			||||||
		if (regsize == 2)
 | 
					 | 
				
			||||||
			*data &= 0xffff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
 | 
					static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* read 24 bits and return valid 17 bit addr */
 | 
						/* read 24 bits and return valid 17 bit addr */
 | 
				
			||||||
	int i;
 | 
						int i, ret;
 | 
				
			||||||
	u32 scratch, regdata;
 | 
						u32 scratch, regdata;
 | 
				
			||||||
	__le32 scratch_le;
 | 
						__le32 scratch_le;
 | 
				
			||||||
	u8 *ptr = (u8 *)&scratch_le;
 | 
						u8 *ptr = (u8 *)&scratch_le;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < 3; i++) {
 | 
						for (i = 0; i < 3; i++) {
 | 
				
			||||||
		if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
 | 
				
			||||||
				®data)) != SUCCESS)
 | 
							if (ret != 0)
 | 
				
			||||||
			brcmf_dbg(ERROR, "Can't read!\n");
 | 
								brcmf_dbg(ERROR, "Can't read!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		*ptr++ = (u8) regdata;
 | 
							*ptr++ = (u8) regdata;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -629,43 +629,29 @@ static bool data_ok(struct brcmf_sdio *bus)
 | 
				
			||||||
 * Reads a register in the SDIO hardware block. This block occupies a series of
 | 
					 * Reads a register in the SDIO hardware block. This block occupies a series of
 | 
				
			||||||
 * adresses on the 32 bit backplane bus.
 | 
					 * adresses on the 32 bit backplane bus.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void
 | 
					static int
 | 
				
			||||||
r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
 | 
					r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
						u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
				
			||||||
	*retryvar = 0;
 | 
						int ret;
 | 
				
			||||||
	do {
 | 
					
 | 
				
			||||||
		*regvar = brcmf_sdcard_reg_read(bus->sdiodev,
 | 
						*regvar = brcmf_sdio_regrl(bus->sdiodev,
 | 
				
			||||||
				bus->ci->c_inf[idx].base + reg_offset,
 | 
									   bus->ci->c_inf[idx].base + offset, &ret);
 | 
				
			||||||
				sizeof(u32));
 | 
					
 | 
				
			||||||
	} while (brcmf_sdcard_regfail(bus->sdiodev) &&
 | 
						return ret;
 | 
				
			||||||
		 (++(*retryvar) <= retry_limit));
 | 
					 | 
				
			||||||
	if (*retryvar) {
 | 
					 | 
				
			||||||
		bus->regfails += (*retryvar-1);
 | 
					 | 
				
			||||||
		if (*retryvar > retry_limit) {
 | 
					 | 
				
			||||||
			brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset);
 | 
					 | 
				
			||||||
			*regvar = 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static int
 | 
				
			||||||
w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset, u32 *retryvar)
 | 
					w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
						u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
				
			||||||
	*retryvar = 0;
 | 
						int ret;
 | 
				
			||||||
	do {
 | 
					
 | 
				
			||||||
		brcmf_sdcard_reg_write(bus->sdiodev,
 | 
						brcmf_sdio_regwl(bus->sdiodev,
 | 
				
			||||||
			 bus->ci->c_inf[idx].base + reg_offset,
 | 
								 bus->ci->c_inf[idx].base + reg_offset,
 | 
				
			||||||
				       sizeof(u32), regval);
 | 
								 regval, &ret);
 | 
				
			||||||
	} while (brcmf_sdcard_regfail(bus->sdiodev) &&
 | 
					
 | 
				
			||||||
		 (++(*retryvar) <= retry_limit));
 | 
						return ret;
 | 
				
			||||||
	if (*retryvar) {
 | 
					 | 
				
			||||||
		bus->regfails += (*retryvar-1);
 | 
					 | 
				
			||||||
		if (*retryvar > retry_limit)
 | 
					 | 
				
			||||||
			brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n",
 | 
					 | 
				
			||||||
				  reg_offset);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
 | 
					#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
 | 
				
			||||||
| 
						 | 
					@ -697,15 +683,15 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
 | 
				
			||||||
		clkreq =
 | 
							clkreq =
 | 
				
			||||||
		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
 | 
							    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
				       SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
 | 
									 clkreq, &err);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
 | 
								brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
 | 
				
			||||||
			return -EBADE;
 | 
								return -EBADE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Check current status */
 | 
							/* Check current status */
 | 
				
			||||||
		clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
							clkctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
										  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
 | 
								brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
 | 
				
			||||||
| 
						 | 
					@ -715,8 +701,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
 | 
				
			||||||
		/* Go to pending and await interrupt if appropriate */
 | 
							/* Go to pending and await interrupt if appropriate */
 | 
				
			||||||
		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
 | 
							if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
 | 
				
			||||||
			/* Allow only clock-available interrupt */
 | 
								/* Allow only clock-available interrupt */
 | 
				
			||||||
			devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
								devctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						  SBSDIO_DEVICE_CTL, &err);
 | 
											  SBSDIO_DEVICE_CTL, &err);
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
				brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
 | 
									brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
 | 
				
			||||||
| 
						 | 
					@ -725,28 +710,26 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
								devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
				
			||||||
			brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
								brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
 | 
				
			||||||
					       SBSDIO_DEVICE_CTL, devctl, &err);
 | 
										 devctl, &err);
 | 
				
			||||||
			brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
 | 
								brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
 | 
				
			||||||
			bus->clkstate = CLK_PENDING;
 | 
								bus->clkstate = CLK_PENDING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		} else if (bus->clkstate == CLK_PENDING) {
 | 
							} else if (bus->clkstate == CLK_PENDING) {
 | 
				
			||||||
			/* Cancel CA-only interrupt filter */
 | 
								/* Cancel CA-only interrupt filter */
 | 
				
			||||||
			devctl =
 | 
								devctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
			    brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						  SBSDIO_DEVICE_CTL, &err);
 | 
											  SBSDIO_DEVICE_CTL, &err);
 | 
				
			||||||
			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
								devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
				
			||||||
			brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
								brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
 | 
				
			||||||
				SBSDIO_DEVICE_CTL, devctl, &err);
 | 
										 devctl, &err);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Otherwise, wait here (polling) for HT Avail */
 | 
							/* Otherwise, wait here (polling) for HT Avail */
 | 
				
			||||||
		timeout = jiffies +
 | 
							timeout = jiffies +
 | 
				
			||||||
			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
 | 
								  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
 | 
				
			||||||
		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
 | 
							while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
 | 
				
			||||||
			clkctl = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
								clkctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						       SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						  SBSDIO_FUNC1_CHIPCLKCSR,
 | 
											  SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
						  &err);
 | 
											  &err);
 | 
				
			||||||
			if (time_after(jiffies, timeout))
 | 
								if (time_after(jiffies, timeout))
 | 
				
			||||||
| 
						 | 
					@ -781,17 +764,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bus->clkstate == CLK_PENDING) {
 | 
							if (bus->clkstate == CLK_PENDING) {
 | 
				
			||||||
			/* Cancel CA-only interrupt filter */
 | 
								/* Cancel CA-only interrupt filter */
 | 
				
			||||||
			devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
								devctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						  SBSDIO_DEVICE_CTL, &err);
 | 
											  SBSDIO_DEVICE_CTL, &err);
 | 
				
			||||||
			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
								devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
				
			||||||
			brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
								brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
 | 
				
			||||||
				SBSDIO_DEVICE_CTL, devctl, &err);
 | 
										 devctl, &err);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bus->clkstate = CLK_SDONLY;
 | 
							bus->clkstate = CLK_SDONLY;
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
			SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
 | 
									 clkreq, &err);
 | 
				
			||||||
		brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
 | 
							brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
 | 
								brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
 | 
				
			||||||
| 
						 | 
					@ -874,7 +856,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
 | 
					static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint retries = 0;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(INFO, "request %s (currently %s)\n",
 | 
						brcmf_dbg(INFO, "request %s (currently %s)\n",
 | 
				
			||||||
		  sleep ? "SLEEP" : "WAKE",
 | 
							  sleep ? "SLEEP" : "WAKE",
 | 
				
			||||||
| 
						 | 
					@ -894,21 +876,19 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
 | 
				
			||||||
		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
							brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Tell device to start using OOB wakeup */
 | 
							/* Tell device to start using OOB wakeup */
 | 
				
			||||||
		w_sdreg32(bus, SMB_USE_OOB,
 | 
							ret = w_sdreg32(bus, SMB_USE_OOB,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
 | 
									offsetof(struct sdpcmd_regs, tosbmailbox));
 | 
				
			||||||
		if (retries > retry_limit)
 | 
							if (ret != 0)
 | 
				
			||||||
			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
 | 
								brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Turn off our contribution to the HT clock request */
 | 
							/* Turn off our contribution to the HT clock request */
 | 
				
			||||||
		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
 | 
							brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
			SBSDIO_FUNC1_CHIPCLKCSR,
 | 
					 | 
				
			||||||
				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
 | 
									 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Isolate the bus */
 | 
							/* Isolate the bus */
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
 | 
				
			||||||
			SBSDIO_DEVICE_CTL,
 | 
					 | 
				
			||||||
				 SBSDIO_DEVCTL_PADS_ISO, NULL);
 | 
									 SBSDIO_DEVCTL_PADS_ISO, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Change state */
 | 
							/* Change state */
 | 
				
			||||||
| 
						 | 
					@ -917,21 +897,20 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Waking up: bus power up is ok, set local state */
 | 
							/* Waking up: bus power up is ok, set local state */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
			SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
 | 
									 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Make sure the controller has the bus up */
 | 
							/* Make sure the controller has the bus up */
 | 
				
			||||||
		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
							brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Send misc interrupt to indicate OOB not needed */
 | 
							/* Send misc interrupt to indicate OOB not needed */
 | 
				
			||||||
		w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata),
 | 
							ret = w_sdreg32(bus, 0,
 | 
				
			||||||
			  &retries);
 | 
									offsetof(struct sdpcmd_regs, tosbmailboxdata));
 | 
				
			||||||
		if (retries <= retry_limit)
 | 
							if (ret == 0)
 | 
				
			||||||
			w_sdreg32(bus, SMB_DEV_INT,
 | 
								ret = w_sdreg32(bus, SMB_DEV_INT,
 | 
				
			||||||
				  offsetof(struct sdpcmd_regs, tosbmailbox),
 | 
									offsetof(struct sdpcmd_regs, tosbmailbox));
 | 
				
			||||||
				  &retries);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (retries > retry_limit)
 | 
							if (ret != 0)
 | 
				
			||||||
			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
 | 
								brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Make sure we have SD bus access */
 | 
							/* Make sure we have SD bus access */
 | 
				
			||||||
| 
						 | 
					@ -955,17 +934,17 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
 | 
				
			||||||
	u32 intstatus = 0;
 | 
						u32 intstatus = 0;
 | 
				
			||||||
	u32 hmb_data;
 | 
						u32 hmb_data;
 | 
				
			||||||
	u8 fcbits;
 | 
						u8 fcbits;
 | 
				
			||||||
	uint retries = 0;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(TRACE, "Enter\n");
 | 
						brcmf_dbg(TRACE, "Enter\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Read mailbox data and ack that we did so */
 | 
						/* Read mailbox data and ack that we did so */
 | 
				
			||||||
	r_sdreg32(bus, &hmb_data,
 | 
						ret = r_sdreg32(bus, &hmb_data,
 | 
				
			||||||
		  offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries);
 | 
								offsetof(struct sdpcmd_regs, tohostmailboxdata));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (retries <= retry_limit)
 | 
						if (ret == 0)
 | 
				
			||||||
		w_sdreg32(bus, SMB_INT_ACK,
 | 
							w_sdreg32(bus, SMB_INT_ACK,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
 | 
								  offsetof(struct sdpcmd_regs, tosbmailbox));
 | 
				
			||||||
	bus->f1regdata += 2;
 | 
						bus->f1regdata += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Dongle recomposed rx frames, accept them again */
 | 
						/* Dongle recomposed rx frames, accept them again */
 | 
				
			||||||
| 
						 | 
					@ -1040,17 +1019,16 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 | 
				
			||||||
	if (abort)
 | 
						if (abort)
 | 
				
			||||||
		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
							brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
 | 
				
			||||||
			       SBSDIO_FUNC1_FRAMECTRL,
 | 
					 | 
				
			||||||
			 SFC_RF_TERM, &err);
 | 
								 SFC_RF_TERM, &err);
 | 
				
			||||||
	bus->f1regdata++;
 | 
						bus->f1regdata++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wait until the packet has been flushed (device/FIFO stable) */
 | 
						/* Wait until the packet has been flushed (device/FIFO stable) */
 | 
				
			||||||
	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
 | 
						for (lastrbc = retries = 0xffff; retries > 0; retries--) {
 | 
				
			||||||
		hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
							hi = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					   SBSDIO_FUNC1_RFRAMEBCHI, NULL);
 | 
									      SBSDIO_FUNC1_RFRAMEBCHI, &err);
 | 
				
			||||||
		lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
							lo = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					   SBSDIO_FUNC1_RFRAMEBCLO, NULL);
 | 
									      SBSDIO_FUNC1_RFRAMEBCLO, &err);
 | 
				
			||||||
		bus->f1regdata += 2;
 | 
							bus->f1regdata += 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((hi == 0) && (lo == 0))
 | 
							if ((hi == 0) && (lo == 0))
 | 
				
			||||||
| 
						 | 
					@ -1070,11 +1048,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rtx) {
 | 
						if (rtx) {
 | 
				
			||||||
		bus->rxrtx++;
 | 
							bus->rxrtx++;
 | 
				
			||||||
		w_sdreg32(bus, SMB_NAK,
 | 
							err = w_sdreg32(bus, SMB_NAK,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
 | 
									offsetof(struct sdpcmd_regs, tosbmailbox));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bus->f1regdata++;
 | 
							bus->f1regdata++;
 | 
				
			||||||
		if (retries <= retry_limit)
 | 
							if (err == 0)
 | 
				
			||||||
			bus->rxskip = true;
 | 
								bus->rxskip = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1082,7 +1060,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 | 
				
			||||||
	bus->nextlen = 0;
 | 
						bus->nextlen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If we can't reach the device, signal failure */
 | 
						/* If we can't reach the device, signal failure */
 | 
				
			||||||
	if (err || brcmf_sdcard_regfail(bus->sdiodev))
 | 
						if (err)
 | 
				
			||||||
		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
							bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2178,21 +2156,16 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
 | 
				
			||||||
		bus->tx_sderrs++;
 | 
							bus->tx_sderrs++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
							brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
 | 
				
			||||||
				 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
 | 
									 SFC_WF_TERM, NULL);
 | 
				
			||||||
				 NULL);
 | 
					 | 
				
			||||||
		bus->f1regdata++;
 | 
							bus->f1regdata++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < 3; i++) {
 | 
							for (i = 0; i < 3; i++) {
 | 
				
			||||||
			u8 hi, lo;
 | 
								u8 hi, lo;
 | 
				
			||||||
			hi = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
								hi = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					     SDIO_FUNC_1,
 | 
										      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
 | 
				
			||||||
					     SBSDIO_FUNC1_WFRAMEBCHI,
 | 
								lo = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					     NULL);
 | 
										      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
 | 
				
			||||||
			lo = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
					 | 
				
			||||||
					     SDIO_FUNC_1,
 | 
					 | 
				
			||||||
					     SBSDIO_FUNC1_WFRAMEBCLO,
 | 
					 | 
				
			||||||
					     NULL);
 | 
					 | 
				
			||||||
			bus->f1regdata += 2;
 | 
								bus->f1regdata += 2;
 | 
				
			||||||
			if ((hi == 0) && (lo == 0))
 | 
								if ((hi == 0) && (lo == 0))
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -2219,7 +2192,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *pkt;
 | 
						struct sk_buff *pkt;
 | 
				
			||||||
	u32 intstatus = 0;
 | 
						u32 intstatus = 0;
 | 
				
			||||||
	uint retries = 0;
 | 
					 | 
				
			||||||
	int ret = 0, prec_out;
 | 
						int ret = 0, prec_out;
 | 
				
			||||||
	uint cnt = 0;
 | 
						uint cnt = 0;
 | 
				
			||||||
	uint datalen;
 | 
						uint datalen;
 | 
				
			||||||
| 
						 | 
					@ -2249,11 +2221,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 | 
				
			||||||
		/* In poll mode, need to check for other events */
 | 
							/* In poll mode, need to check for other events */
 | 
				
			||||||
		if (!bus->intr && cnt) {
 | 
							if (!bus->intr && cnt) {
 | 
				
			||||||
			/* Check device status, signal pending interrupt */
 | 
								/* Check device status, signal pending interrupt */
 | 
				
			||||||
			r_sdreg32(bus, &intstatus,
 | 
								ret = r_sdreg32(bus, &intstatus,
 | 
				
			||||||
				  offsetof(struct sdpcmd_regs, intstatus),
 | 
										offsetof(struct sdpcmd_regs,
 | 
				
			||||||
				  &retries);
 | 
											 intstatus));
 | 
				
			||||||
			bus->f2txdata++;
 | 
								bus->f2txdata++;
 | 
				
			||||||
			if (brcmf_sdcard_regfail(bus->sdiodev))
 | 
								if (ret != 0)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			if (intstatus & bus->hostintmask)
 | 
								if (intstatus & bus->hostintmask)
 | 
				
			||||||
				bus->ipend = true;
 | 
									bus->ipend = true;
 | 
				
			||||||
| 
						 | 
					@ -2275,7 +2247,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 local_hostintmask;
 | 
						u32 local_hostintmask;
 | 
				
			||||||
	u8 saveclk;
 | 
						u8 saveclk;
 | 
				
			||||||
	uint retries;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 | 
						struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 | 
				
			||||||
	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 | 
						struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 | 
				
			||||||
| 
						 | 
					@ -2303,7 +2274,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
 | 
				
			||||||
	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
						brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Disable and clear interrupts at the chip level also */
 | 
						/* Disable and clear interrupts at the chip level also */
 | 
				
			||||||
	w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries);
 | 
						w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
 | 
				
			||||||
	local_hostintmask = bus->hostintmask;
 | 
						local_hostintmask = bus->hostintmask;
 | 
				
			||||||
	bus->hostintmask = 0;
 | 
						bus->hostintmask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2311,11 +2282,10 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
 | 
				
			||||||
	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
						bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Force clocks on backplane to be sure F2 interrupt propagates */
 | 
						/* Force clocks on backplane to be sure F2 interrupt propagates */
 | 
				
			||||||
	saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
						saveclk = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
									   SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
				
			||||||
	if (!err) {
 | 
						if (!err) {
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
				       SBSDIO_FUNC1_CHIPCLKCSR,
 | 
					 | 
				
			||||||
				 (saveclk | SBSDIO_FORCE_HT), &err);
 | 
									 (saveclk | SBSDIO_FORCE_HT), &err);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
| 
						 | 
					@ -2323,12 +2293,12 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Turn off the bus (F2), free any pending packets */
 | 
						/* Turn off the bus (F2), free any pending packets */
 | 
				
			||||||
	brcmf_dbg(INTR, "disable SDIO interrupts\n");
 | 
						brcmf_dbg(INTR, "disable SDIO interrupts\n");
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
 | 
				
			||||||
			 SDIO_FUNC_ENABLE_1, NULL);
 | 
								 NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear any pending interrupts now that F2 is disabled */
 | 
						/* Clear any pending interrupts now that F2 is disabled */
 | 
				
			||||||
	w_sdreg32(bus, local_hostintmask,
 | 
						w_sdreg32(bus, local_hostintmask,
 | 
				
			||||||
		  offsetof(struct sdpcmd_regs, intstatus), &retries);
 | 
							  offsetof(struct sdpcmd_regs, intstatus));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Turn off the backplane clock (only) */
 | 
						/* Turn off the backplane clock (only) */
 | 
				
			||||||
	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
 | 
						brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
 | 
				
			||||||
| 
						 | 
					@ -2373,12 +2343,12 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
 | 
				
			||||||
static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
					static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 intstatus, newstatus = 0;
 | 
						u32 intstatus, newstatus = 0;
 | 
				
			||||||
	uint retries = 0;
 | 
					 | 
				
			||||||
	uint rxlimit = bus->rxbound;	/* Rx frames to read before resched */
 | 
						uint rxlimit = bus->rxbound;	/* Rx frames to read before resched */
 | 
				
			||||||
	uint txlimit = bus->txbound;	/* Tx frames to send before resched */
 | 
						uint txlimit = bus->txbound;	/* Tx frames to send before resched */
 | 
				
			||||||
	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
 | 
						uint framecnt = 0;	/* Temporary counter of tx/rx frames */
 | 
				
			||||||
	bool rxdone = true;	/* Flag for no more read data */
 | 
						bool rxdone = true;	/* Flag for no more read data */
 | 
				
			||||||
	bool resched = false;	/* Flag indicating resched wanted */
 | 
						bool resched = false;	/* Flag indicating resched wanted */
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_dbg(TRACE, "Enter\n");
 | 
						brcmf_dbg(TRACE, "Enter\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2389,12 +2359,11 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If waiting for HTAVAIL, check status */
 | 
						/* If waiting for HTAVAIL, check status */
 | 
				
			||||||
	if (bus->clkstate == CLK_PENDING) {
 | 
						if (bus->clkstate == CLK_PENDING) {
 | 
				
			||||||
		int err;
 | 
					 | 
				
			||||||
		u8 clkctl, devctl = 0;
 | 
							u8 clkctl, devctl = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
		/* Check for inconsistent device control */
 | 
							/* Check for inconsistent device control */
 | 
				
			||||||
		devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
							devctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					  SBSDIO_DEVICE_CTL, &err);
 | 
										  SBSDIO_DEVICE_CTL, &err);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
 | 
								brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
 | 
				
			||||||
| 
						 | 
					@ -2403,7 +2372,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
#endif				/* DEBUG */
 | 
					#endif				/* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Read CSR, if clock on switch to AVAIL, else ignore */
 | 
							/* Read CSR, if clock on switch to AVAIL, else ignore */
 | 
				
			||||||
		clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
							clkctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
										  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			brcmf_dbg(ERROR, "error reading CSR: %d\n",
 | 
								brcmf_dbg(ERROR, "error reading CSR: %d\n",
 | 
				
			||||||
| 
						 | 
					@ -2415,8 +2384,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
			  devctl, clkctl);
 | 
								  devctl, clkctl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (SBSDIO_HTAV(clkctl)) {
 | 
							if (SBSDIO_HTAV(clkctl)) {
 | 
				
			||||||
			devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
								devctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						       SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						  SBSDIO_DEVICE_CTL, &err);
 | 
											  SBSDIO_DEVICE_CTL, &err);
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
				brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
 | 
									brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
 | 
				
			||||||
| 
						 | 
					@ -2424,8 +2392,8 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
									bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
								devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
 | 
				
			||||||
			brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
								brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
 | 
				
			||||||
				SBSDIO_DEVICE_CTL, devctl, &err);
 | 
										 devctl, &err);
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
				brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
 | 
									brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
 | 
				
			||||||
					  err);
 | 
										  err);
 | 
				
			||||||
| 
						 | 
					@ -2447,17 +2415,17 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
	/* Pending interrupt indicates new device status */
 | 
						/* Pending interrupt indicates new device status */
 | 
				
			||||||
	if (bus->ipend) {
 | 
						if (bus->ipend) {
 | 
				
			||||||
		bus->ipend = false;
 | 
							bus->ipend = false;
 | 
				
			||||||
		r_sdreg32(bus, &newstatus,
 | 
							err = r_sdreg32(bus, &newstatus,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, intstatus), &retries);
 | 
									offsetof(struct sdpcmd_regs, intstatus));
 | 
				
			||||||
		bus->f1regdata++;
 | 
							bus->f1regdata++;
 | 
				
			||||||
		if (brcmf_sdcard_regfail(bus->sdiodev))
 | 
							if (err != 0)
 | 
				
			||||||
			newstatus = 0;
 | 
								newstatus = 0;
 | 
				
			||||||
		newstatus &= bus->hostintmask;
 | 
							newstatus &= bus->hostintmask;
 | 
				
			||||||
		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
 | 
							bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
 | 
				
			||||||
		if (newstatus) {
 | 
							if (newstatus) {
 | 
				
			||||||
			w_sdreg32(bus, newstatus,
 | 
								err = w_sdreg32(bus, newstatus,
 | 
				
			||||||
				  offsetof(struct sdpcmd_regs, intstatus),
 | 
										offsetof(struct sdpcmd_regs,
 | 
				
			||||||
				  &retries);
 | 
											 intstatus));
 | 
				
			||||||
			bus->f1regdata++;
 | 
								bus->f1regdata++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2472,11 +2440,11 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (intstatus & I_HMB_FC_CHANGE) {
 | 
						if (intstatus & I_HMB_FC_CHANGE) {
 | 
				
			||||||
		intstatus &= ~I_HMB_FC_CHANGE;
 | 
							intstatus &= ~I_HMB_FC_CHANGE;
 | 
				
			||||||
		w_sdreg32(bus, I_HMB_FC_CHANGE,
 | 
							err = w_sdreg32(bus, I_HMB_FC_CHANGE,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, intstatus), &retries);
 | 
									offsetof(struct sdpcmd_regs, intstatus));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		r_sdreg32(bus, &newstatus,
 | 
							err = r_sdreg32(bus, &newstatus,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, intstatus), &retries);
 | 
									offsetof(struct sdpcmd_regs, intstatus));
 | 
				
			||||||
		bus->f1regdata += 2;
 | 
							bus->f1regdata += 2;
 | 
				
			||||||
		bus->fcstate =
 | 
							bus->fcstate =
 | 
				
			||||||
		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
 | 
							    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
 | 
				
			||||||
| 
						 | 
					@ -2546,21 +2514,18 @@ clkwait:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
								brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
								brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
 | 
				
			||||||
					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
 | 
										 SFC_WF_TERM, &err);
 | 
				
			||||||
					 NULL);
 | 
					 | 
				
			||||||
			bus->f1regdata++;
 | 
								bus->f1regdata++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (i = 0; i < 3; i++) {
 | 
								for (i = 0; i < 3; i++) {
 | 
				
			||||||
				u8 hi, lo;
 | 
									u8 hi, lo;
 | 
				
			||||||
				hi = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
									hi = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						     SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						      SBSDIO_FUNC1_WFRAMEBCHI,
 | 
											      SBSDIO_FUNC1_WFRAMEBCHI,
 | 
				
			||||||
						     NULL);
 | 
											      &err);
 | 
				
			||||||
				lo = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
									lo = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						     SDIO_FUNC_1,
 | 
					 | 
				
			||||||
						      SBSDIO_FUNC1_WFRAMEBCLO,
 | 
											      SBSDIO_FUNC1_WFRAMEBCLO,
 | 
				
			||||||
						     NULL);
 | 
											      &err);
 | 
				
			||||||
				bus->f1regdata += 2;
 | 
									bus->f1regdata += 2;
 | 
				
			||||||
				if ((hi == 0) && (lo == 0))
 | 
									if ((hi == 0) && (lo == 0))
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
| 
						 | 
					@ -2587,10 +2552,8 @@ clkwait:
 | 
				
			||||||
		 else await next interrupt */
 | 
							 else await next interrupt */
 | 
				
			||||||
	/* On failed register access, all bets are off:
 | 
						/* On failed register access, all bets are off:
 | 
				
			||||||
		 no resched or interrupts */
 | 
							 no resched or interrupts */
 | 
				
			||||||
	if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) ||
 | 
						if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
 | 
				
			||||||
	    brcmf_sdcard_regfail(bus->sdiodev)) {
 | 
							brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
 | 
				
			||||||
		brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n",
 | 
					 | 
				
			||||||
			  brcmf_sdcard_regfail(bus->sdiodev));
 | 
					 | 
				
			||||||
		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
							bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
				
			||||||
		bus->intstatus = 0;
 | 
							bus->intstatus = 0;
 | 
				
			||||||
	} else if (bus->clkstate == CLK_PENDING) {
 | 
						} else if (bus->clkstate == CLK_PENDING) {
 | 
				
			||||||
| 
						 | 
					@ -2886,19 +2849,16 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
							brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
 | 
				
			||||||
				       SBSDIO_FUNC1_FRAMECTRL,
 | 
					 | 
				
			||||||
				 SFC_WF_TERM, NULL);
 | 
									 SFC_WF_TERM, NULL);
 | 
				
			||||||
		bus->f1regdata++;
 | 
							bus->f1regdata++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < 3; i++) {
 | 
							for (i = 0; i < 3; i++) {
 | 
				
			||||||
			u8 hi, lo;
 | 
								u8 hi, lo;
 | 
				
			||||||
			hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
								hi = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						   SBSDIO_FUNC1_WFRAMEBCHI,
 | 
										      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
 | 
				
			||||||
						   NULL);
 | 
								lo = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
			lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
										      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
 | 
				
			||||||
						   SBSDIO_FUNC1_WFRAMEBCLO,
 | 
					 | 
				
			||||||
						   NULL);
 | 
					 | 
				
			||||||
			bus->f1regdata += 2;
 | 
								bus->f1regdata += 2;
 | 
				
			||||||
			if (hi == 0 && lo == 0)
 | 
								if (hi == 0 && lo == 0)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -3188,7 +3148,6 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
 | 
					static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint retries;
 | 
					 | 
				
			||||||
	int bcmerror = 0;
 | 
						int bcmerror = 0;
 | 
				
			||||||
	struct chip_info *ci = bus->ci;
 | 
						struct chip_info *ci = bus->ci;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3222,7 +3181,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		w_sdreg32(bus, 0xFFFFFFFF,
 | 
							w_sdreg32(bus, 0xFFFFFFFF,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, intstatus), &retries);
 | 
								  offsetof(struct sdpcmd_regs, intstatus));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
 | 
							ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3444,7 +3403,6 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
 | 
				
			||||||
	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 | 
						struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 | 
				
			||||||
	struct brcmf_sdio *bus = sdiodev->bus;
 | 
						struct brcmf_sdio *bus = sdiodev->bus;
 | 
				
			||||||
	unsigned long timeout;
 | 
						unsigned long timeout;
 | 
				
			||||||
	uint retries = 0;
 | 
					 | 
				
			||||||
	u8 ready, enable;
 | 
						u8 ready, enable;
 | 
				
			||||||
	int err, ret = 0;
 | 
						int err, ret = 0;
 | 
				
			||||||
	u8 saveclk;
 | 
						u8 saveclk;
 | 
				
			||||||
| 
						 | 
					@ -3472,12 +3430,10 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
 | 
				
			||||||
		goto exit;
 | 
							goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Force clocks on backplane to be sure F2 interrupt propagates */
 | 
						/* Force clocks on backplane to be sure F2 interrupt propagates */
 | 
				
			||||||
	saveclk =
 | 
						saveclk = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
	    brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
									   SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
				
			||||||
	if (!err) {
 | 
						if (!err) {
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
				       SBSDIO_FUNC1_CHIPCLKCSR,
 | 
					 | 
				
			||||||
				 (saveclk | SBSDIO_FORCE_HT), &err);
 | 
									 (saveclk | SBSDIO_FORCE_HT), &err);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
| 
						 | 
					@ -3487,16 +3443,15 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Enable function 2 (frame transfers) */
 | 
						/* Enable function 2 (frame transfers) */
 | 
				
			||||||
	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
 | 
						w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
 | 
				
			||||||
		  offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries);
 | 
							  offsetof(struct sdpcmd_regs, tosbmailboxdata));
 | 
				
			||||||
	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
 | 
						enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
 | 
				
			||||||
			       enable, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
 | 
						timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
 | 
				
			||||||
	ready = 0;
 | 
						ready = 0;
 | 
				
			||||||
	while (enable != ready) {
 | 
						while (enable != ready) {
 | 
				
			||||||
		ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0,
 | 
							ready = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
					 SDIO_CCCR_IORx, NULL);
 | 
										 SDIO_CCCR_IORx, NULL);
 | 
				
			||||||
		if (time_after(jiffies, timeout))
 | 
							if (time_after(jiffies, timeout))
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -3512,21 +3467,18 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
 | 
				
			||||||
		/* Set up the interrupt mask and enable interrupts */
 | 
							/* Set up the interrupt mask and enable interrupts */
 | 
				
			||||||
		bus->hostintmask = HOSTINTMASK;
 | 
							bus->hostintmask = HOSTINTMASK;
 | 
				
			||||||
		w_sdreg32(bus, bus->hostintmask,
 | 
							w_sdreg32(bus, bus->hostintmask,
 | 
				
			||||||
			  offsetof(struct sdpcmd_regs, hostintmask), &retries);
 | 
								  offsetof(struct sdpcmd_regs, hostintmask));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
 | 
				
			||||||
				       SBSDIO_WATERMARK, 8, &err);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Disable F2 again */
 | 
							/* Disable F2 again */
 | 
				
			||||||
		enable = SDIO_FUNC_ENABLE_1;
 | 
							enable = SDIO_FUNC_ENABLE_1;
 | 
				
			||||||
		brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
 | 
							brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
 | 
				
			||||||
				       SDIO_CCCR_IOEx, enable, NULL);
 | 
					 | 
				
			||||||
		ret = -ENODEV;
 | 
							ret = -ENODEV;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Restore previous clock setting */
 | 
						/* Restore previous clock setting */
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
 | 
				
			||||||
			       SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == 0) {
 | 
						if (ret == 0) {
 | 
				
			||||||
		ret = brcmf_sdio_intr_register(bus->sdiodev);
 | 
							ret = brcmf_sdio_intr_register(bus->sdiodev);
 | 
				
			||||||
| 
						 | 
					@ -3606,8 +3558,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!bus->dpc_sched) {
 | 
								if (!bus->dpc_sched) {
 | 
				
			||||||
				u8 devpend;
 | 
									u8 devpend;
 | 
				
			||||||
				devpend = brcmf_sdcard_cfg_read(bus->sdiodev,
 | 
									devpend = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
						SDIO_FUNC_0, SDIO_CCCR_INTx,
 | 
												   SDIO_CCCR_INTx,
 | 
				
			||||||
							   NULL);
 | 
												   NULL);
 | 
				
			||||||
				intstatus =
 | 
									intstatus =
 | 
				
			||||||
				    devpend & (INTR_STATUS_FUNC1 |
 | 
									    devpend & (INTR_STATUS_FUNC1 |
 | 
				
			||||||
| 
						 | 
					@ -3732,24 +3684,18 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bus->alp_only = true;
 | 
						bus->alp_only = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Return the window to backplane enumeration space for core access */
 | 
					 | 
				
			||||||
	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
 | 
					 | 
				
			||||||
		brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pr_debug("F1 signature read @0x18000000=0x%4x\n",
 | 
						pr_debug("F1 signature read @0x18000000=0x%4x\n",
 | 
				
			||||||
		 brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
 | 
							 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Force PLL off until brcmf_sdio_chip_attach()
 | 
						 * Force PLL off until brcmf_sdio_chip_attach()
 | 
				
			||||||
	 * programs PLL control regs
 | 
						 * programs PLL control regs
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
 | 
				
			||||||
			       SBSDIO_FUNC1_CHIPCLKCSR,
 | 
					 | 
				
			||||||
			 BRCMF_INIT_CLKCTL1, &err);
 | 
								 BRCMF_INIT_CLKCTL1, &err);
 | 
				
			||||||
	if (!err)
 | 
						if (!err)
 | 
				
			||||||
		clkctl =
 | 
							clkctl = brcmf_sdio_regrb(bus->sdiodev,
 | 
				
			||||||
		    brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 | 
					 | 
				
			||||||
					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
										  SBSDIO_FUNC1_CHIPCLKCSR, &err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
 | 
						if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
 | 
				
			||||||
| 
						 | 
					@ -3782,9 +3728,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
						idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
 | 
				
			||||||
	reg_addr = bus->ci->c_inf[idx].base +
 | 
						reg_addr = bus->ci->c_inf[idx].base +
 | 
				
			||||||
		   offsetof(struct sdpcmd_regs, corecontrol);
 | 
							   offsetof(struct sdpcmd_regs, corecontrol);
 | 
				
			||||||
	reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32));
 | 
						reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
 | 
				
			||||||
	brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32),
 | 
						brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
 | 
				
			||||||
			       reg_val | CC_BPRESEN);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
 | 
						brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3809,7 +3754,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
 | 
				
			||||||
	brcmf_dbg(TRACE, "Enter\n");
 | 
						brcmf_dbg(TRACE, "Enter\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Disable F2 to clear any intermediate frame state on the dongle */
 | 
						/* Disable F2 to clear any intermediate frame state on the dongle */
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
 | 
				
			||||||
			 SDIO_FUNC_ENABLE_1, NULL);
 | 
								 SDIO_FUNC_ENABLE_1, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
						bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 | 
				
			||||||
| 
						 | 
					@ -3817,8 +3762,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
 | 
				
			||||||
	bus->rxflow = false;
 | 
						bus->rxflow = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Done with backplane-dependent accesses, can drop clock... */
 | 
						/* Done with backplane-dependent accesses, can drop clock... */
 | 
				
			||||||
	brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
 | 
				
			||||||
			       SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ...and initialize clock/power states */
 | 
						/* ...and initialize clock/power states */
 | 
				
			||||||
	bus->clkstate = CLK_SDONLY;
 | 
						bus->clkstate = CLK_SDONLY;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,8 +93,9 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
						idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbidhigh), 4);
 | 
									   CORE_SB(ci->c_inf[idx].base, sbidhigh),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	return SBCOREREV(regdata);
 | 
						return SBCOREREV(regdata);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,8 +119,9 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
						idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
									   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
 | 
						regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
 | 
				
			||||||
		    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
 | 
							    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
 | 
				
			||||||
	return (SSB_TMSLOW_CLOCK == regdata);
 | 
						return (SSB_TMSLOW_CLOCK == regdata);
 | 
				
			||||||
| 
						 | 
					@ -135,13 +137,13 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
						idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
					ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
 | 
									   NULL);
 | 
				
			||||||
	ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
 | 
						ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
									   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
				
			||||||
					4);
 | 
									   NULL);
 | 
				
			||||||
	ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
 | 
						ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -151,84 +153,85 @@ static void
 | 
				
			||||||
brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
 | 
					brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
			  struct chip_info *ci, u16 coreid)
 | 
								  struct chip_info *ci, u16 coreid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 regdata;
 | 
						u32 regdata, base;
 | 
				
			||||||
	u8 idx;
 | 
						u8 idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
						idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
				
			||||||
 | 
						base = ci->c_inf[idx].base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
 | 
				
			||||||
		CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
					 | 
				
			||||||
	if (regdata & SSB_TMSLOW_RESET)
 | 
						if (regdata & SSB_TMSLOW_RESET)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
 | 
				
			||||||
		CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
					 | 
				
			||||||
	if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
 | 
						if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * set target reject and spin until busy is clear
 | 
							 * set target reject and spin until busy is clear
 | 
				
			||||||
		 * (preserve core-specific bits)
 | 
							 * (preserve core-specific bits)
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
										   NULL);
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
									 regdata | SSB_TMSLOW_REJECT, NULL);
 | 
				
			||||||
				4, regdata | SSB_TMSLOW_REJECT);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
										   NULL);
 | 
				
			||||||
		udelay(1);
 | 
							udelay(1);
 | 
				
			||||||
		SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
 | 
							SPINWAIT((brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) &
 | 
										   CORE_SB(base, sbtmstatehigh),
 | 
				
			||||||
 | 
										   NULL) &
 | 
				
			||||||
			SSB_TMSHIGH_BUSY), 100000);
 | 
								SSB_TMSHIGH_BUSY), 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4);
 | 
										   CORE_SB(base, sbtmstatehigh),
 | 
				
			||||||
 | 
										   NULL);
 | 
				
			||||||
		if (regdata & SSB_TMSHIGH_BUSY)
 | 
							if (regdata & SSB_TMSHIGH_BUSY)
 | 
				
			||||||
			brcmf_dbg(ERROR, "core state still busy\n");
 | 
								brcmf_dbg(ERROR, "core state still busy\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbidlow), 4);
 | 
										   NULL);
 | 
				
			||||||
		if (regdata & SSB_IDLOW_INITIATOR) {
 | 
							if (regdata & SSB_IDLOW_INITIATOR) {
 | 
				
			||||||
			regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
								regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4) |
 | 
											   CORE_SB(base, sbimstate),
 | 
				
			||||||
				SSB_IMSTATE_REJECT;
 | 
											   NULL);
 | 
				
			||||||
			brcmf_sdcard_reg_write(sdiodev,
 | 
								regdata |= SSB_IMSTATE_REJECT;
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
 | 
								brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
 | 
				
			||||||
				regdata);
 | 
										 regdata, NULL);
 | 
				
			||||||
			regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
								regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4);
 | 
											   CORE_SB(base, sbimstate),
 | 
				
			||||||
 | 
											   NULL);
 | 
				
			||||||
			udelay(1);
 | 
								udelay(1);
 | 
				
			||||||
			SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
 | 
								SPINWAIT((brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4) &
 | 
											   CORE_SB(base, sbimstate),
 | 
				
			||||||
 | 
											   NULL) &
 | 
				
			||||||
				SSB_IMSTATE_BUSY), 100000);
 | 
									SSB_IMSTATE_BUSY), 100000);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* set reset and reject while enabling the clocks */
 | 
							/* set reset and reject while enabling the clocks */
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
 | 
								  SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
 | 
				
			||||||
			(SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
 | 
							brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
			SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
 | 
									 regdata, NULL);
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
										   NULL);
 | 
				
			||||||
		udelay(10);
 | 
							udelay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* clear the initiator reject bit */
 | 
							/* clear the initiator reject bit */
 | 
				
			||||||
		regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
							regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbidlow), 4);
 | 
										   NULL);
 | 
				
			||||||
		if (regdata & SSB_IDLOW_INITIATOR) {
 | 
							if (regdata & SSB_IDLOW_INITIATOR) {
 | 
				
			||||||
			regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
								regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4) &
 | 
											   CORE_SB(base, sbimstate),
 | 
				
			||||||
				~SSB_IMSTATE_REJECT;
 | 
											   NULL);
 | 
				
			||||||
			brcmf_sdcard_reg_write(sdiodev,
 | 
								regdata &= ~SSB_IMSTATE_REJECT;
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
 | 
								brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
 | 
				
			||||||
				regdata);
 | 
										 regdata, NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* leave reset and reject asserted */
 | 
						/* leave reset and reject asserted */
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
 | 
				
			||||||
		CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
 | 
								 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
 | 
				
			||||||
		(SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
 | 
					 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,20 +245,19 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
						idx = brcmf_sdio_chip_getinfidx(ci, coreid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* if core is already in reset, just return */
 | 
						/* if core is already in reset, just return */
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
									   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
				
			||||||
					4);
 | 
									   NULL);
 | 
				
			||||||
	if ((regdata & BCMA_RESET_CTL_RESET) != 0)
 | 
						if ((regdata & BCMA_RESET_CTL_RESET) != 0)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
						brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL);
 | 
				
			||||||
			       4, 0);
 | 
						regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
									   NULL);
 | 
				
			||||||
					ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
 | 
					 | 
				
			||||||
	udelay(10);
 | 
						udelay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
						brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
				
			||||||
			       4, BCMA_RESET_CTL_RESET);
 | 
								 BCMA_RESET_CTL_RESET, NULL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -279,41 +281,47 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	 * set reset while enabling the clock and
 | 
						 * set reset while enabling the clock and
 | 
				
			||||||
	 * forcing them on throughout the core
 | 
						 * forcing them on throughout the core
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
 | 
								 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
			SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET);
 | 
								 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
								 NULL);
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
 | 
									   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear any serror */
 | 
						/* clear any serror */
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4);
 | 
									   CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	if (regdata & SSB_TMSHIGH_SERR)
 | 
						if (regdata & SSB_TMSHIGH_SERR)
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							brcmf_sdio_regwl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0);
 | 
									 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
 | 
				
			||||||
 | 
									 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4);
 | 
									   CORE_SB(ci->c_inf[idx].base, sbimstate),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
 | 
						if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							brcmf_sdio_regwl(sdiodev,
 | 
				
			||||||
			CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
 | 
									 CORE_SB(ci->c_inf[idx].base, sbimstate),
 | 
				
			||||||
			regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO));
 | 
									 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
 | 
				
			||||||
 | 
									 NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear reset and allow it to propagate throughout the core */
 | 
						/* clear reset and allow it to propagate throughout the core */
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
		CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
 | 
								 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
 | 
				
			||||||
		SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
									   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
									   NULL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* leave clock enabled */
 | 
						/* leave clock enabled */
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
 | 
								 SSB_TMSLOW_CLOCK, NULL);
 | 
				
			||||||
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
									   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
 | 
				
			||||||
			       4, SSB_TMSLOW_CLOCK);
 | 
									   NULL);
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
					 | 
				
			||||||
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
 | 
					 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,18 +338,18 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
 | 
						brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* now do initialization sequence */
 | 
						/* now do initialization sequence */
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
						brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
			       4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
 | 
								 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
					ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
 | 
									   NULL);
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
						brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
 | 
				
			||||||
			       4, 0);
 | 
								 0, NULL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
						brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
			       4, BCMA_IOCTL_CLK);
 | 
								 BCMA_IOCTL_CLK, NULL);
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
 | 
				
			||||||
					ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
 | 
									   NULL);
 | 
				
			||||||
	udelay(1);
 | 
						udelay(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -358,8 +366,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
 | 
						ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
 | 
				
			||||||
	ci->c_inf[0].base = regs;
 | 
						ci->c_inf[0].base = regs;
 | 
				
			||||||
	regdata = brcmf_sdcard_reg_read(sdiodev,
 | 
						regdata = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_CC_REG(ci->c_inf[0].base, chipid), 4);
 | 
									   CORE_CC_REG(ci->c_inf[0].base, chipid),
 | 
				
			||||||
 | 
									   NULL);
 | 
				
			||||||
	ci->chip = regdata & CID_ID_MASK;
 | 
						ci->chip = regdata & CID_ID_MASK;
 | 
				
			||||||
	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
 | 
						ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
 | 
				
			||||||
	ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 | 
						ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 | 
				
			||||||
| 
						 | 
					@ -428,8 +437,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Try forcing SDIO core to do ALPAvail request only */
 | 
						/* Try forcing SDIO core to do ALPAvail request only */
 | 
				
			||||||
	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
 | 
						clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
 | 
				
			||||||
			       SBSDIO_FUNC1_CHIPCLKCSR,	clkset, &err);
 | 
					 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		brcmf_dbg(ERROR, "error writing for HT off\n");
 | 
							brcmf_dbg(ERROR, "error writing for HT off\n");
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
| 
						 | 
					@ -437,7 +445,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If register supported, wait for ALPAvail and then force ALP */
 | 
						/* If register supported, wait for ALPAvail and then force ALP */
 | 
				
			||||||
	/* This may take up to 15 milliseconds */
 | 
						/* This may take up to 15 milliseconds */
 | 
				
			||||||
	clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
 | 
						clkval = brcmf_sdio_regrb(sdiodev,
 | 
				
			||||||
				  SBSDIO_FUNC1_CHIPCLKCSR, NULL);
 | 
									  SBSDIO_FUNC1_CHIPCLKCSR, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((clkval & ~SBSDIO_AVBITS) != clkset) {
 | 
						if ((clkval & ~SBSDIO_AVBITS) != clkset) {
 | 
				
			||||||
| 
						 | 
					@ -446,7 +454,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
		return -EACCES;
 | 
							return -EACCES;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
 | 
						SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
 | 
				
			||||||
					     SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
 | 
										     SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
 | 
				
			||||||
			!SBSDIO_ALPAV(clkval)),
 | 
								!SBSDIO_ALPAV(clkval)),
 | 
				
			||||||
			PMU_MAX_TRANSITION_DLY);
 | 
								PMU_MAX_TRANSITION_DLY);
 | 
				
			||||||
| 
						 | 
					@ -457,13 +465,11 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
 | 
						clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
 | 
				
			||||||
			       SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
 | 
					 | 
				
			||||||
	udelay(65);
 | 
						udelay(65);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Also, disable the extra SDIO pull-ups */
 | 
						/* Also, disable the extra SDIO pull-ups */
 | 
				
			||||||
	brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
 | 
						brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
 | 
				
			||||||
			       SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -472,18 +478,22 @@ static void
 | 
				
			||||||
brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
 | 
					brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
			     struct chip_info *ci)
 | 
								     struct chip_info *ci)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						u32 base = ci->c_inf[0].base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get chipcommon rev */
 | 
						/* get chipcommon rev */
 | 
				
			||||||
	ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
 | 
						ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get chipcommon capabilites */
 | 
						/* get chipcommon capabilites */
 | 
				
			||||||
	ci->c_inf[0].caps =
 | 
						ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
		brcmf_sdcard_reg_read(sdiodev,
 | 
										     CORE_CC_REG(base, capabilities),
 | 
				
			||||||
		CORE_CC_REG(ci->c_inf[0].base, capabilities), 4);
 | 
										     NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get pmu caps & rev */
 | 
						/* get pmu caps & rev */
 | 
				
			||||||
	if (ci->c_inf[0].caps & CC_CAP_PMU) {
 | 
						if (ci->c_inf[0].caps & CC_CAP_PMU) {
 | 
				
			||||||
		ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
 | 
							ci->pmucaps =
 | 
				
			||||||
			CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4);
 | 
								brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
 | 
										 CORE_CC_REG(base, pmucapabilities),
 | 
				
			||||||
 | 
										 NULL);
 | 
				
			||||||
		ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
 | 
							ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -523,10 +533,10 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdio_chip_buscoresetup(sdiodev, ci);
 | 
						brcmf_sdio_chip_buscoresetup(sdiodev, ci);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
 | 
				
			||||||
		CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0);
 | 
								 0, NULL);
 | 
				
			||||||
	brcmf_sdcard_reg_write(sdiodev,
 | 
						brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
 | 
				
			||||||
		CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0);
 | 
								 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*ci_ptr = ci;
 | 
						*ci_ptr = ci;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -562,6 +572,7 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
	u32 str_mask = 0;
 | 
						u32 str_mask = 0;
 | 
				
			||||||
	u32 str_shift = 0;
 | 
						u32 str_shift = 0;
 | 
				
			||||||
	char chn[8];
 | 
						char chn[8];
 | 
				
			||||||
 | 
						u32 base = ci->c_inf[0].base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(ci->c_inf[0].caps & CC_CAP_PMU))
 | 
						if (!(ci->c_inf[0].caps & CC_CAP_PMU))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -591,17 +602,17 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
 | 
				
			||||||
			CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
 | 
									 1, NULL);
 | 
				
			||||||
			4, 1);
 | 
							cc_data_temp =
 | 
				
			||||||
		cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
 | 
								brcmf_sdio_regrl(sdiodev,
 | 
				
			||||||
			CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4);
 | 
										 CORE_CC_REG(base, chipcontrol_addr),
 | 
				
			||||||
 | 
										 NULL);
 | 
				
			||||||
		cc_data_temp &= ~str_mask;
 | 
							cc_data_temp &= ~str_mask;
 | 
				
			||||||
		drivestrength_sel <<= str_shift;
 | 
							drivestrength_sel <<= str_shift;
 | 
				
			||||||
		cc_data_temp |= drivestrength_sel;
 | 
							cc_data_temp |= drivestrength_sel;
 | 
				
			||||||
		brcmf_sdcard_reg_write(sdiodev,
 | 
							brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
 | 
				
			||||||
			CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
 | 
									 cc_data_temp, NULL);
 | 
				
			||||||
			4, cc_data_temp);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
 | 
							brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
 | 
				
			||||||
			  drivestrength, cc_data_temp);
 | 
								  drivestrength, cc_data_temp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,10 @@
 | 
				
			||||||
/* Maximum number of I/O funcs */
 | 
					/* Maximum number of I/O funcs */
 | 
				
			||||||
#define SDIOD_MAX_IOFUNCS	7
 | 
					#define SDIOD_MAX_IOFUNCS	7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mask of register map */
 | 
				
			||||||
 | 
					#define REG_F0_REG_MASK		0x7FF
 | 
				
			||||||
 | 
					#define REG_F1_MISC_MASK	0x1FFFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* as of sdiod rev 0, supports 3 functions */
 | 
					/* as of sdiod rev 0, supports 3 functions */
 | 
				
			||||||
#define SBSDIO_NUM_FUNCTION		3
 | 
					#define SBSDIO_NUM_FUNCTION		3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +146,6 @@ struct brcmf_sdio_dev {
 | 
				
			||||||
	u8 num_funcs;			/* Supported funcs on client */
 | 
						u8 num_funcs;			/* Supported funcs on client */
 | 
				
			||||||
	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
 | 
						u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
 | 
				
			||||||
	u32 sbwad;			/* Save backplane window address */
 | 
						u32 sbwad;			/* Save backplane window address */
 | 
				
			||||||
	bool regfail;			/* status of last reg_r/w call */
 | 
					 | 
				
			||||||
	void *bus;
 | 
						void *bus;
 | 
				
			||||||
	atomic_t suspend;		/* suspend flag */
 | 
						atomic_t suspend;		/* suspend flag */
 | 
				
			||||||
	wait_queue_head_t request_byte_wait;
 | 
						wait_queue_head_t request_byte_wait;
 | 
				
			||||||
| 
						 | 
					@ -164,31 +167,13 @@ struct brcmf_sdio_dev {
 | 
				
			||||||
extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
 | 
					extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
 | 
				
			||||||
extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
 | 
					extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
 | 
					/* sdio device register access interface */
 | 
				
			||||||
 *   fn:   function number
 | 
					extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
 | 
				
			||||||
 *   addr: unmodified SDIO-space address
 | 
					extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
 | 
				
			||||||
 *   data: data byte to write
 | 
					extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
 | 
				
			||||||
 *   err:  pointer to error code (or NULL)
 | 
								     u8 data, int *ret);
 | 
				
			||||||
 */
 | 
					extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 | 
				
			||||||
extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func,
 | 
								     u32 data, int *ret);
 | 
				
			||||||
				u32 addr, int *err);
 | 
					 | 
				
			||||||
extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func,
 | 
					 | 
				
			||||||
				   u32 addr, u8 data, int *err);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Synchronous access to device (client) core registers via CMD53 to F1.
 | 
					 | 
				
			||||||
 *   addr: backplane address (i.e. >= regsva from attach)
 | 
					 | 
				
			||||||
 *   size: register width in bytes (2 or 4)
 | 
					 | 
				
			||||||
 *   data: data for register write
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
extern u32
 | 
					 | 
				
			||||||
brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern u32
 | 
					 | 
				
			||||||
brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
 | 
					 | 
				
			||||||
		       u32 data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Indicate if last reg read/write failed */
 | 
					 | 
				
			||||||
extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Buffer transfer to/from device (client) core via cmd53.
 | 
					/* Buffer transfer to/from device (client) core via cmd53.
 | 
				
			||||||
 *   fn:       function number
 | 
					 *   fn:       function number
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,10 +39,7 @@ BRCMSMAC_OFILES := \
 | 
				
			||||||
	phy/phytbl_lcn.o \
 | 
						phy/phytbl_lcn.o \
 | 
				
			||||||
	phy/phytbl_n.o \
 | 
						phy/phytbl_n.o \
 | 
				
			||||||
	phy/phy_qmath.o \
 | 
						phy/phy_qmath.o \
 | 
				
			||||||
	otp.o \
 | 
					 | 
				
			||||||
	srom.o \
 | 
					 | 
				
			||||||
	dma.o \
 | 
						dma.o \
 | 
				
			||||||
	nicpci.o \
 | 
					 | 
				
			||||||
	brcms_trace_events.o
 | 
						brcms_trace_events.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULEPFX := brcmsmac
 | 
					MODULEPFX := brcmsmac
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,6 @@
 | 
				
			||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 | 
					#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/delay.h>
 | 
					#include <linux/delay.h>
 | 
				
			||||||
#include <linux/pci.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <chipcommon.h>
 | 
					#include <chipcommon.h>
 | 
				
			||||||
| 
						 | 
					@ -29,8 +28,6 @@
 | 
				
			||||||
#include "types.h"
 | 
					#include "types.h"
 | 
				
			||||||
#include "pub.h"
 | 
					#include "pub.h"
 | 
				
			||||||
#include "pmu.h"
 | 
					#include "pmu.h"
 | 
				
			||||||
#include "srom.h"
 | 
					 | 
				
			||||||
#include "nicpci.h"
 | 
					 | 
				
			||||||
#include "aiutils.h"
 | 
					#include "aiutils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* slow_clk_ctl */
 | 
					/* slow_clk_ctl */
 | 
				
			||||||
| 
						 | 
					@ -321,7 +318,6 @@
 | 
				
			||||||
#define	IS_SIM(chippkg)	\
 | 
					#define	IS_SIM(chippkg)	\
 | 
				
			||||||
	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
 | 
						((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PCI(sih)	(ai_get_buscoretype(sih) == PCI_CORE_ID)
 | 
					 | 
				
			||||||
#define PCIE(sih)	(ai_get_buscoretype(sih) == PCIE_CORE_ID)
 | 
					#define PCIE(sih)	(ai_get_buscoretype(sih) == PCIE_CORE_ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
 | 
					#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
 | 
				
			||||||
| 
						 | 
					@ -454,36 +450,9 @@ struct aidmp {
 | 
				
			||||||
	u32 componentid3;	/* 0xffc */
 | 
						u32 componentid3;	/* 0xffc */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* return true if PCIE capability exists in the pci config space */
 | 
					 | 
				
			||||||
static bool ai_ispcie(struct si_info *sii)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u8 cap_ptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cap_ptr =
 | 
					 | 
				
			||||||
	    pcicore_find_pci_capability(sii->pcibus, PCI_CAP_ID_EXP, NULL,
 | 
					 | 
				
			||||||
					NULL);
 | 
					 | 
				
			||||||
	if (!cap_ptr)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ai_buscore_prep(struct si_info *sii)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* kludge to enable the clock on the 4306 which lacks a slowclock */
 | 
					 | 
				
			||||||
	if (!ai_ispcie(sii))
 | 
					 | 
				
			||||||
		ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
 | 
					ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bcma_device *pci = NULL;
 | 
					 | 
				
			||||||
	struct bcma_device *pcie = NULL;
 | 
					 | 
				
			||||||
	struct bcma_device *core;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* no cores found, bail out */
 | 
						/* no cores found, bail out */
 | 
				
			||||||
	if (cc->bus->nr_cores == 0)
 | 
						if (cc->bus->nr_cores == 0)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -492,7 +461,6 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
 | 
				
			||||||
	sii->pub.ccrev = cc->id.rev;
 | 
						sii->pub.ccrev = cc->id.rev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get chipcommon chipstatus */
 | 
						/* get chipcommon chipstatus */
 | 
				
			||||||
	if (ai_get_ccrev(&sii->pub) >= 11)
 | 
					 | 
				
			||||||
	sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
 | 
						sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get chipcommon capabilites */
 | 
						/* get chipcommon capabilites */
 | 
				
			||||||
| 
						 | 
					@ -506,64 +474,18 @@ ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* figure out buscore */
 | 
						/* figure out buscore */
 | 
				
			||||||
	list_for_each_entry(core, &cc->bus->cores, list) {
 | 
						sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0);
 | 
				
			||||||
		uint cid, crev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cid = core->id.id;
 | 
					 | 
				
			||||||
		crev = core->id.rev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (cid == PCI_CORE_ID) {
 | 
					 | 
				
			||||||
			pci = core;
 | 
					 | 
				
			||||||
		} else if (cid == PCIE_CORE_ID) {
 | 
					 | 
				
			||||||
			pcie = core;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pci && pcie) {
 | 
					 | 
				
			||||||
		if (ai_ispcie(sii))
 | 
					 | 
				
			||||||
			pci = NULL;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			pcie = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (pci) {
 | 
					 | 
				
			||||||
		sii->buscore = pci;
 | 
					 | 
				
			||||||
	} else if (pcie) {
 | 
					 | 
				
			||||||
		sii->buscore = pcie;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* fixup necessary chip/core configurations */
 | 
					 | 
				
			||||||
	if (!sii->pch) {
 | 
					 | 
				
			||||||
		sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci.core);
 | 
					 | 
				
			||||||
		if (sii->pch == NULL)
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (ai_pci_fixcfg(&sii->pub))
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * get boardtype and boardrev
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static __used void ai_nvram_process(struct si_info *sii)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint w = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* do a pci config read to get subsystem id and subvendor id */
 | 
					 | 
				
			||||||
	pci_read_config_dword(sii->pcibus, PCI_SUBSYSTEM_VENDOR_ID, &w);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii->pub.boardvendor = w & 0xffff;
 | 
					 | 
				
			||||||
	sii->pub.boardtype = (w >> 16) & 0xffff;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct si_info *ai_doattach(struct si_info *sii,
 | 
					static struct si_info *ai_doattach(struct si_info *sii,
 | 
				
			||||||
				   struct bcma_bus *pbus)
 | 
									   struct bcma_bus *pbus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_pub *sih = &sii->pub;
 | 
						struct si_pub *sih = &sii->pub;
 | 
				
			||||||
	u32 w, savewin;
 | 
						u32 w, savewin;
 | 
				
			||||||
	struct bcma_device *cc;
 | 
						struct bcma_device *cc;
 | 
				
			||||||
	uint socitype;
 | 
						struct ssb_sprom *sprom = &pbus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	savewin = 0;
 | 
						savewin = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -573,38 +495,15 @@ static struct si_info *ai_doattach(struct si_info *sii,
 | 
				
			||||||
	/* switch to Chipcommon core */
 | 
						/* switch to Chipcommon core */
 | 
				
			||||||
	cc = pbus->drv_cc.core;
 | 
						cc = pbus->drv_cc.core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* bus/core/clk setup for register access */
 | 
						sih->chip = pbus->chipinfo.id;
 | 
				
			||||||
	if (!ai_buscore_prep(sii))
 | 
						sih->chiprev = pbus->chipinfo.rev;
 | 
				
			||||||
		return NULL;
 | 
						sih->chippkg = pbus->chipinfo.pkg;
 | 
				
			||||||
 | 
						sih->boardvendor = pbus->boardinfo.vendor;
 | 
				
			||||||
 | 
						sih->boardtype = pbus->boardinfo.type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * ChipID recognition.
 | 
					 | 
				
			||||||
	 *   We assume we can read chipid at offset 0 from the regs arg.
 | 
					 | 
				
			||||||
	 *   If we add other chiptypes (or if we need to support old sdio
 | 
					 | 
				
			||||||
	 *   hosts w/o chipcommon), some way of recognizing them needs to
 | 
					 | 
				
			||||||
	 *   be added here.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	w = bcma_read32(cc, CHIPCREGOFFS(chipid));
 | 
					 | 
				
			||||||
	socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 | 
					 | 
				
			||||||
	/* Might as wll fill in chip id rev & pkg */
 | 
					 | 
				
			||||||
	sih->chip = w & CID_ID_MASK;
 | 
					 | 
				
			||||||
	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
 | 
					 | 
				
			||||||
	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* scan for cores */
 | 
					 | 
				
			||||||
	if (socitype != SOCI_AI)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SI_MSG("Found chip type AI (0x%08x)\n", w);
 | 
					 | 
				
			||||||
	if (!ai_buscore_setup(sii, cc))
 | 
						if (!ai_buscore_setup(sii, cc))
 | 
				
			||||||
		goto exit;
 | 
							goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Init nvram from sprom/otp if they exist */
 | 
					 | 
				
			||||||
	if (srom_var_init(&sii->pub))
 | 
					 | 
				
			||||||
		goto exit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ai_nvram_process(sii);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* === NVRAM, clock is ready === */
 | 
						/* === NVRAM, clock is ready === */
 | 
				
			||||||
	bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
 | 
						bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
 | 
				
			||||||
	bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
 | 
						bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
 | 
				
			||||||
| 
						 | 
					@ -617,15 +516,13 @@ static struct si_info *ai_doattach(struct si_info *sii,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* setup the GPIO based LED powersave register */
 | 
						/* setup the GPIO based LED powersave register */
 | 
				
			||||||
	w = getintvar(sih, BRCMS_SROM_LEDDC);
 | 
						w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
 | 
				
			||||||
 | 
							 (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT);
 | 
				
			||||||
	if (w == 0)
 | 
						if (w == 0)
 | 
				
			||||||
		w = DEFAULT_GPIOTIMERVAL;
 | 
							w = DEFAULT_GPIOTIMERVAL;
 | 
				
			||||||
	ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
 | 
						ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
 | 
				
			||||||
		  ~0, w);
 | 
							  ~0, w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PCIE(sih))
 | 
					 | 
				
			||||||
		pcicore_attach(sii->pch, SI_DOATTACH);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
 | 
						if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * enable 12 mA drive strenth for 43224 and
 | 
							 * enable 12 mA drive strenth for 43224 and
 | 
				
			||||||
| 
						 | 
					@ -659,9 +556,6 @@ static struct si_info *ai_doattach(struct si_info *sii,
 | 
				
			||||||
	return sii;
 | 
						return sii;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 exit:
 | 
					 exit:
 | 
				
			||||||
	if (sii->pch)
 | 
					 | 
				
			||||||
		pcicore_deinit(sii->pch);
 | 
					 | 
				
			||||||
	sii->pch = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -700,11 +594,6 @@ void ai_detach(struct si_pub *sih)
 | 
				
			||||||
	if (sii == NULL)
 | 
						if (sii == NULL)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sii->pch)
 | 
					 | 
				
			||||||
		pcicore_deinit(sii->pch);
 | 
					 | 
				
			||||||
	sii->pch = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srom_free_vars(sih);
 | 
					 | 
				
			||||||
	kfree(sii);
 | 
						kfree(sii);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -755,20 +644,6 @@ uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
 | 
				
			||||||
/* return the slow clock source - LPO, XTAL, or PCI */
 | 
					/* return the slow clock source - LPO, XTAL, or PCI */
 | 
				
			||||||
static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
 | 
					static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	u32 val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(&sii->pub) < 6) {
 | 
					 | 
				
			||||||
		pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT,
 | 
					 | 
				
			||||||
				      &val);
 | 
					 | 
				
			||||||
		if (val & PCI_CFG_GPIO_SCS)
 | 
					 | 
				
			||||||
			return SCC_SS_PCI;
 | 
					 | 
				
			||||||
		return SCC_SS_XTAL;
 | 
					 | 
				
			||||||
	} else if (ai_get_ccrev(&sii->pub) < 10) {
 | 
					 | 
				
			||||||
		return bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) &
 | 
					 | 
				
			||||||
		       SCC_SS_MASK;
 | 
					 | 
				
			||||||
	} else			/* Insta-clock */
 | 
					 | 
				
			||||||
	return SCC_SS_XTAL;
 | 
						return SCC_SS_XTAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -779,36 +654,12 @@ static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
 | 
				
			||||||
static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
 | 
					static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
 | 
				
			||||||
			    struct bcma_device *cc)
 | 
								    struct bcma_device *cc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 slowclk;
 | 
					 | 
				
			||||||
	uint div;
 | 
						uint div;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slowclk = ai_slowclk_src(sih, cc);
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(sih) < 6) {
 | 
					 | 
				
			||||||
		if (slowclk == SCC_SS_PCI)
 | 
					 | 
				
			||||||
			return max_freq ? (PCIMAXFREQ / 64)
 | 
					 | 
				
			||||||
				: (PCIMINFREQ / 64);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			return max_freq ? (XTALMAXFREQ / 32)
 | 
					 | 
				
			||||||
				: (XTALMINFREQ / 32);
 | 
					 | 
				
			||||||
	} else if (ai_get_ccrev(sih) < 10) {
 | 
					 | 
				
			||||||
		div = 4 *
 | 
					 | 
				
			||||||
		    (((bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl)) &
 | 
					 | 
				
			||||||
		      SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
 | 
					 | 
				
			||||||
		if (slowclk == SCC_SS_LPO)
 | 
					 | 
				
			||||||
			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
 | 
					 | 
				
			||||||
		else if (slowclk == SCC_SS_XTAL)
 | 
					 | 
				
			||||||
			return max_freq ? (XTALMAXFREQ / div)
 | 
					 | 
				
			||||||
				: (XTALMINFREQ / div);
 | 
					 | 
				
			||||||
		else if (slowclk == SCC_SS_PCI)
 | 
					 | 
				
			||||||
			return max_freq ? (PCIMAXFREQ / div)
 | 
					 | 
				
			||||||
				: (PCIMINFREQ / div);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	/* Chipc rev 10 is InstaClock */
 | 
						/* Chipc rev 10 is InstaClock */
 | 
				
			||||||
	div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
 | 
						div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
 | 
				
			||||||
	div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
 | 
						div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
 | 
				
			||||||
	return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
 | 
						return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -831,8 +682,7 @@ ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Starting with 4318 it is ILP that is used for the delays */
 | 
						/* Starting with 4318 it is ILP that is used for the delays */
 | 
				
			||||||
	slowmaxfreq =
 | 
						slowmaxfreq =
 | 
				
			||||||
	    ai_slowclk_freq(sih,
 | 
						    ai_slowclk_freq(sih, false, cc);
 | 
				
			||||||
			    (ai_get_ccrev(sih) >= 10) ? false : true, cc);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
 | 
						pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
 | 
				
			||||||
	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
 | 
						fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
 | 
				
			||||||
| 
						 | 
					@ -854,7 +704,6 @@ void ai_clkctl_init(struct si_pub *sih)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set all Instaclk chip ILP to 1 MHz */
 | 
						/* set all Instaclk chip ILP to 1 MHz */
 | 
				
			||||||
	if (ai_get_ccrev(sih) >= 10)
 | 
					 | 
				
			||||||
	bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
 | 
						bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
 | 
				
			||||||
		       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
 | 
							       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -891,140 +740,6 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
 | 
				
			||||||
	return fpdelay;
 | 
						return fpdelay;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* turn primary xtal and/or pll off/on */
 | 
					 | 
				
			||||||
int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	u32 in, out, outen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pcie core doesn't have any mapping to control the xtal pu */
 | 
					 | 
				
			||||||
	if (PCIE(sih))
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_dword(sii->pcibus, PCI_GPIO_IN, &in);
 | 
					 | 
				
			||||||
	pci_read_config_dword(sii->pcibus, PCI_GPIO_OUT, &out);
 | 
					 | 
				
			||||||
	pci_read_config_dword(sii->pcibus, PCI_GPIO_OUTEN, &outen);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Avoid glitching the clock if GPRS is already using it.
 | 
					 | 
				
			||||||
	 * We can't actually read the state of the PLLPD so we infer it
 | 
					 | 
				
			||||||
	 * by the value of XTAL_PU which *is* readable via gpioin.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (on && (in & PCI_CFG_GPIO_XTAL))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (what & XTAL)
 | 
					 | 
				
			||||||
		outen |= PCI_CFG_GPIO_XTAL;
 | 
					 | 
				
			||||||
	if (what & PLL)
 | 
					 | 
				
			||||||
		outen |= PCI_CFG_GPIO_PLL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (on) {
 | 
					 | 
				
			||||||
		/* turn primary xtal on */
 | 
					 | 
				
			||||||
		if (what & XTAL) {
 | 
					 | 
				
			||||||
			out |= PCI_CFG_GPIO_XTAL;
 | 
					 | 
				
			||||||
			if (what & PLL)
 | 
					 | 
				
			||||||
				out |= PCI_CFG_GPIO_PLL;
 | 
					 | 
				
			||||||
			pci_write_config_dword(sii->pcibus,
 | 
					 | 
				
			||||||
					       PCI_GPIO_OUT, out);
 | 
					 | 
				
			||||||
			pci_write_config_dword(sii->pcibus,
 | 
					 | 
				
			||||||
					       PCI_GPIO_OUTEN, outen);
 | 
					 | 
				
			||||||
			udelay(XTAL_ON_DELAY);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* turn pll on */
 | 
					 | 
				
			||||||
		if (what & PLL) {
 | 
					 | 
				
			||||||
			out &= ~PCI_CFG_GPIO_PLL;
 | 
					 | 
				
			||||||
			pci_write_config_dword(sii->pcibus,
 | 
					 | 
				
			||||||
					       PCI_GPIO_OUT, out);
 | 
					 | 
				
			||||||
			mdelay(2);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (what & XTAL)
 | 
					 | 
				
			||||||
			out &= ~PCI_CFG_GPIO_XTAL;
 | 
					 | 
				
			||||||
		if (what & PLL)
 | 
					 | 
				
			||||||
			out |= PCI_CFG_GPIO_PLL;
 | 
					 | 
				
			||||||
		pci_write_config_dword(sii->pcibus,
 | 
					 | 
				
			||||||
				       PCI_GPIO_OUT, out);
 | 
					 | 
				
			||||||
		pci_write_config_dword(sii->pcibus,
 | 
					 | 
				
			||||||
				       PCI_GPIO_OUTEN, outen);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* clk control mechanism through chipcommon, no policy checking */
 | 
					 | 
				
			||||||
static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bcma_device *cc;
 | 
					 | 
				
			||||||
	u32 scc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* chipcommon cores prior to rev6 don't support dynamic clock control */
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(&sii->pub) < 6)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!(ai_get_cccaps(&sii->pub) & CC_CAP_PWR_CTL) &&
 | 
					 | 
				
			||||||
	    (ai_get_ccrev(&sii->pub) < 20))
 | 
					 | 
				
			||||||
		return mode == CLK_FAST;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (mode) {
 | 
					 | 
				
			||||||
	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
 | 
					 | 
				
			||||||
		if (ai_get_ccrev(&sii->pub) < 10) {
 | 
					 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * don't forget to force xtal back
 | 
					 | 
				
			||||||
			 * on before we clear SCC_DYN_XTAL..
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			ai_clkctl_xtal(&sii->pub, XTAL, ON);
 | 
					 | 
				
			||||||
			bcma_maskset32(cc, CHIPCREGOFFS(slow_clk_ctl),
 | 
					 | 
				
			||||||
				       (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
 | 
					 | 
				
			||||||
		} else if (ai_get_ccrev(&sii->pub) < 20) {
 | 
					 | 
				
			||||||
			bcma_set32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_HR);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			bcma_set32(cc, CHIPCREGOFFS(clk_ctl_st), CCS_FORCEHT);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* wait for the PLL */
 | 
					 | 
				
			||||||
		if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
 | 
					 | 
				
			||||||
			u32 htavail = CCS_HTAVAIL;
 | 
					 | 
				
			||||||
			SPINWAIT(((bcma_read32(cc, CHIPCREGOFFS(clk_ctl_st)) &
 | 
					 | 
				
			||||||
				   htavail) == 0), PMU_MAX_TRANSITION_DLY);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			udelay(PLL_DELAY);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case CLK_DYNAMIC:	/* enable dynamic clock control */
 | 
					 | 
				
			||||||
		if (ai_get_ccrev(&sii->pub) < 10) {
 | 
					 | 
				
			||||||
			scc = bcma_read32(cc, CHIPCREGOFFS(slow_clk_ctl));
 | 
					 | 
				
			||||||
			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
 | 
					 | 
				
			||||||
			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
 | 
					 | 
				
			||||||
				scc |= SCC_XC;
 | 
					 | 
				
			||||||
			bcma_write32(cc, CHIPCREGOFFS(slow_clk_ctl), scc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * for dynamic control, we have to
 | 
					 | 
				
			||||||
			 * release our xtal_pu "force on"
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			if (scc & SCC_XC)
 | 
					 | 
				
			||||||
				ai_clkctl_xtal(&sii->pub, XTAL, OFF);
 | 
					 | 
				
			||||||
		} else if (ai_get_ccrev(&sii->pub) < 20) {
 | 
					 | 
				
			||||||
			/* Instaclock */
 | 
					 | 
				
			||||||
			bcma_mask32(cc, CHIPCREGOFFS(system_clk_ctl), ~SYCC_HR);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			bcma_mask32(cc, CHIPCREGOFFS(clk_ctl_st), ~CCS_FORCEHT);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mode == CLK_FAST;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *  clock control policy function throught chipcommon
 | 
					 *  clock control policy function throught chipcommon
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1033,133 +748,53 @@ static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
 | 
				
			||||||
 *    this is a wrapper over the next internal function
 | 
					 *    this is a wrapper over the next internal function
 | 
				
			||||||
 *      to allow flexible policy settings for outside caller
 | 
					 *      to allow flexible policy settings for outside caller
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool ai_clkctl_cc(struct si_pub *sih, uint mode)
 | 
					bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_info *sii;
 | 
						struct si_info *sii;
 | 
				
			||||||
 | 
						struct bcma_device *cc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
						sii = (struct si_info *)sih;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* chipcommon cores prior to rev6 don't support dynamic clock control */
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(sih) < 6)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (PCI_FORCEHT(sih))
 | 
						if (PCI_FORCEHT(sih))
 | 
				
			||||||
		return mode == CLK_FAST;
 | 
							return mode == BCMA_CLKMODE_FAST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return _ai_clkctl_cc(sii, mode);
 | 
						cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
 | 
				
			||||||
 | 
						bcma_core_set_clockmode(cc, mode);
 | 
				
			||||||
 | 
						return mode == BCMA_CLKMODE_FAST;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ai_pci_up(struct si_pub *sih)
 | 
					void ai_pci_up(struct si_pub *sih)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_info *sii;
 | 
						struct si_info *sii;
 | 
				
			||||||
 | 
						struct bcma_device *cc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
						sii = (struct si_info *)sih;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PCI_FORCEHT(sih))
 | 
						if (PCI_FORCEHT(sih)) {
 | 
				
			||||||
		_ai_clkctl_cc(sii, CLK_FAST);
 | 
							cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
 | 
				
			||||||
 | 
							bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PCIE(sih))
 | 
						if (PCIE(sih))
 | 
				
			||||||
		pcicore_up(sii->pch, SI_PCIUP);
 | 
							bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Unconfigure and/or apply various WARs when system is going to sleep mode */
 | 
					 | 
				
			||||||
void ai_pci_sleep(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcicore_sleep(sii->pch);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Unconfigure and/or apply various WARs when going down */
 | 
					/* Unconfigure and/or apply various WARs when going down */
 | 
				
			||||||
void ai_pci_down(struct si_pub *sih)
 | 
					void ai_pci_down(struct si_pub *sih)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_info *sii;
 | 
						struct si_info *sii;
 | 
				
			||||||
 | 
						struct bcma_device *cc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
						sii = (struct si_info *)sih;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* release FORCEHT since chip is going to "down" state */
 | 
						/* release FORCEHT since chip is going to "down" state */
 | 
				
			||||||
	if (PCI_FORCEHT(sih))
 | 
						if (PCI_FORCEHT(sih)) {
 | 
				
			||||||
		_ai_clkctl_cc(sii, CLK_DYNAMIC);
 | 
							cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
 | 
				
			||||||
 | 
							bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC);
 | 
				
			||||||
	pcicore_down(sii->pch, SI_PCIDOWN);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Configure the pci core for pci client (NIC) action
 | 
					 | 
				
			||||||
 * coremask is the bitvec of cores by index to be enabled.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void ai_pci_setup(struct si_pub *sih, uint coremask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Enable sb->pci interrupts.  Assume
 | 
					 | 
				
			||||||
	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (PCIE(sih) || (PCI(sih) && (ai_get_buscorerev(sih) >= 6))) {
 | 
					 | 
				
			||||||
		/* pci config write to set this core bit in PCIIntMask */
 | 
					 | 
				
			||||||
		pci_read_config_dword(sii->pcibus, PCI_INT_MASK, &w);
 | 
					 | 
				
			||||||
		w |= (coremask << PCI_SBIM_SHIFT);
 | 
					 | 
				
			||||||
		pci_write_config_dword(sii->pcibus, PCI_INT_MASK, w);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PCI(sih)) {
 | 
						if (PCIE(sih))
 | 
				
			||||||
		pcicore_pci_setup(sii->pch);
 | 
							bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Fixup SROMless PCI device's configuration.
 | 
					 | 
				
			||||||
 * The current core may be changed upon return.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int ai_pci_fixcfg(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
 | 
					 | 
				
			||||||
	/* check 'pi' is correct and fix it if not */
 | 
					 | 
				
			||||||
	pcicore_fixcfg(sii->pch);
 | 
					 | 
				
			||||||
	pcicore_hwup(sii->pch);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* mask&set gpiocontrol bits */
 | 
					 | 
				
			||||||
u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint regoff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	regoff = offsetof(struct chipcregs, gpiocontrol);
 | 
					 | 
				
			||||||
	return ai_cc_reg(sih, regoff, mask, val);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ai_chipcontrl_epa4331(struct si_pub *sih, bool on)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bcma_device *cc;
 | 
					 | 
				
			||||||
	u32 val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cc = ai_findcore(sih, CC_CORE_ID, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (on) {
 | 
					 | 
				
			||||||
		if (ai_get_chippkg(sih) == 9 || ai_get_chippkg(sih) == 0xb)
 | 
					 | 
				
			||||||
			/* Ext PA Controls for 4331 12x9 Package */
 | 
					 | 
				
			||||||
			bcma_set32(cc, CHIPCREGOFFS(chipcontrol),
 | 
					 | 
				
			||||||
				   CCTRL4331_EXTPA_EN |
 | 
					 | 
				
			||||||
				   CCTRL4331_EXTPA_ON_GPIO2_5);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			/* Ext PA Controls for 4331 12x12 Package */
 | 
					 | 
				
			||||||
			bcma_set32(cc, CHIPCREGOFFS(chipcontrol),
 | 
					 | 
				
			||||||
				   CCTRL4331_EXTPA_EN);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
 | 
					 | 
				
			||||||
		bcma_mask32(cc, CHIPCREGOFFS(chipcontrol),
 | 
					 | 
				
			||||||
			    ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Enable BT-COEX & Ex-PA for 4313 */
 | 
					/* Enable BT-COEX & Ex-PA for 4313 */
 | 
				
			||||||
| 
						 | 
					@ -1181,6 +816,9 @@ bool ai_deviceremoved(struct si_pub *sih)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
						sii = (struct si_info *)sih;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
 | 
						pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
 | 
				
			||||||
	if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
 | 
						if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
| 
						 | 
					@ -1188,45 +826,6 @@ bool ai_deviceremoved(struct si_pub *sih)
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ai_is_sprom_available(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(sih) >= 31) {
 | 
					 | 
				
			||||||
		struct bcma_device *cc;
 | 
					 | 
				
			||||||
		u32 sromctrl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ((ai_get_cccaps(sih) & CC_CAP_SROM) == 0)
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
 | 
					 | 
				
			||||||
		sromctrl = bcma_read32(cc, CHIPCREGOFFS(sromcontrol));
 | 
					 | 
				
			||||||
		return sromctrl & SRC_PRESENT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (ai_get_chip_id(sih)) {
 | 
					 | 
				
			||||||
	case BCM4313_CHIP_ID:
 | 
					 | 
				
			||||||
		return (sii->chipst & CST4313_SPROM_PRESENT) != 0;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ai_is_otp_disabled(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (ai_get_chip_id(sih)) {
 | 
					 | 
				
			||||||
	case BCM4313_CHIP_ID:
 | 
					 | 
				
			||||||
		return (sii->chipst & CST4313_OTP_PRESENT) == 0;
 | 
					 | 
				
			||||||
		/* These chips always have their OTP on */
 | 
					 | 
				
			||||||
	case BCM43224_CHIP_ID:
 | 
					 | 
				
			||||||
	case BCM43225_CHIP_ID:
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint ai_get_buscoretype(struct si_pub *sih)
 | 
					uint ai_get_buscoretype(struct si_pub *sih)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct si_info *sii = (struct si_info *)sih;
 | 
						struct si_info *sii = (struct si_info *)sih;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,10 +113,6 @@
 | 
				
			||||||
#define	XTAL			0x1	/* primary crystal oscillator (2050) */
 | 
					#define	XTAL			0x1	/* primary crystal oscillator (2050) */
 | 
				
			||||||
#define	PLL			0x2	/* main chip pll */
 | 
					#define	PLL			0x2	/* main chip pll */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* clkctl clk mode */
 | 
					 | 
				
			||||||
#define	CLK_FAST		0	/* force fast (pll) clock */
 | 
					 | 
				
			||||||
#define	CLK_DYNAMIC		2	/* enable dynamic clock control */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* GPIO usage priorities */
 | 
					/* GPIO usage priorities */
 | 
				
			||||||
#define GPIO_DRV_PRIORITY	0	/* Driver */
 | 
					#define GPIO_DRV_PRIORITY	0	/* Driver */
 | 
				
			||||||
#define GPIO_APP_PRIORITY	1	/* Application */
 | 
					#define GPIO_APP_PRIORITY	1	/* Application */
 | 
				
			||||||
| 
						 | 
					@ -172,9 +168,7 @@ struct si_info {
 | 
				
			||||||
	struct si_pub pub;	/* back plane public state (must be first) */
 | 
						struct si_pub pub;	/* back plane public state (must be first) */
 | 
				
			||||||
	struct bcma_bus *icbus;	/* handle to soc interconnect bus */
 | 
						struct bcma_bus *icbus;	/* handle to soc interconnect bus */
 | 
				
			||||||
	struct pci_dev *pcibus;	/* handle to pci bus */
 | 
						struct pci_dev *pcibus;	/* handle to pci bus */
 | 
				
			||||||
	struct pcicore_info *pch; /* PCI/E core handle */
 | 
					 | 
				
			||||||
	struct bcma_device *buscore;
 | 
						struct bcma_device *buscore;
 | 
				
			||||||
	struct list_head var_list; /* list of srom variables */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u32 chipst;		/* chip status */
 | 
						u32 chipst;		/* chip status */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -197,38 +191,20 @@ extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
 | 
				
			||||||
extern struct si_pub *ai_attach(struct bcma_bus *pbus);
 | 
					extern struct si_pub *ai_attach(struct bcma_bus *pbus);
 | 
				
			||||||
extern void ai_detach(struct si_pub *sih);
 | 
					extern void ai_detach(struct si_pub *sih);
 | 
				
			||||||
extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
 | 
					extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
 | 
				
			||||||
extern void ai_pci_setup(struct si_pub *sih, uint coremask);
 | 
					 | 
				
			||||||
extern void ai_clkctl_init(struct si_pub *sih);
 | 
					extern void ai_clkctl_init(struct si_pub *sih);
 | 
				
			||||||
extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
 | 
					extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
 | 
				
			||||||
extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
 | 
					extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
 | 
				
			||||||
extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
 | 
					 | 
				
			||||||
extern bool ai_deviceremoved(struct si_pub *sih);
 | 
					extern bool ai_deviceremoved(struct si_pub *sih);
 | 
				
			||||||
extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
 | 
					 | 
				
			||||||
			     u8 priority);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* OTP status */
 | 
					 | 
				
			||||||
extern bool ai_is_otp_disabled(struct si_pub *sih);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SPROM availability */
 | 
					 | 
				
			||||||
extern bool ai_is_sprom_available(struct si_pub *sih);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void ai_pci_sleep(struct si_pub *sih);
 | 
					 | 
				
			||||||
extern void ai_pci_down(struct si_pub *sih);
 | 
					extern void ai_pci_down(struct si_pub *sih);
 | 
				
			||||||
extern void ai_pci_up(struct si_pub *sih);
 | 
					extern void ai_pci_up(struct si_pub *sih);
 | 
				
			||||||
extern int ai_pci_fixcfg(struct si_pub *sih);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
 | 
					 | 
				
			||||||
/* Enable Ex-PA for 4313 */
 | 
					/* Enable Ex-PA for 4313 */
 | 
				
			||||||
extern void ai_epa_4313war(struct si_pub *sih);
 | 
					extern void ai_epa_4313war(struct si_pub *sih);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern uint ai_get_buscoretype(struct si_pub *sih);
 | 
					extern uint ai_get_buscoretype(struct si_pub *sih);
 | 
				
			||||||
extern uint ai_get_buscorerev(struct si_pub *sih);
 | 
					extern uint ai_get_buscorerev(struct si_pub *sih);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int ai_get_ccrev(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return sih->ccrev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline u32 ai_get_cccaps(struct si_pub *sih)
 | 
					static inline u32 ai_get_cccaps(struct si_pub *sih)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return sih->cccaps;
 | 
						return sih->cccaps;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
 | 
				
			||||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
 | 
					struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct antsel_info *asi;
 | 
						struct antsel_info *asi;
 | 
				
			||||||
	struct si_pub *sih = wlc->hw->sih;
 | 
						struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
 | 
						asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
 | 
				
			||||||
	if (!asi)
 | 
						if (!asi)
 | 
				
			||||||
| 
						 | 
					@ -118,7 +118,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
	asi->pub = wlc->pub;
 | 
						asi->pub = wlc->pub;
 | 
				
			||||||
	asi->antsel_type = ANTSEL_NA;
 | 
						asi->antsel_type = ANTSEL_NA;
 | 
				
			||||||
	asi->antsel_avail = false;
 | 
						asi->antsel_avail = false;
 | 
				
			||||||
	asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH);
 | 
						asi->antsel_antswitch = sprom->antswitch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
 | 
						if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
 | 
				
			||||||
		switch (asi->antsel_antswitch) {
 | 
							switch (asi->antsel_antswitch) {
 | 
				
			||||||
| 
						 | 
					@ -128,12 +128,12 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
			/* 4321/2 board with 2x3 switch logic */
 | 
								/* 4321/2 board with 2x3 switch logic */
 | 
				
			||||||
			asi->antsel_type = ANTSEL_2x3;
 | 
								asi->antsel_type = ANTSEL_2x3;
 | 
				
			||||||
			/* Antenna selection availability */
 | 
								/* Antenna selection availability */
 | 
				
			||||||
			if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) ||
 | 
								if ((sprom->ant_available_bg == 7) ||
 | 
				
			||||||
			    ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) {
 | 
								    (sprom->ant_available_a == 7)) {
 | 
				
			||||||
				asi->antsel_avail = true;
 | 
									asi->antsel_avail = true;
 | 
				
			||||||
			} else if (
 | 
								} else if (
 | 
				
			||||||
				(u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 ||
 | 
									sprom->ant_available_bg == 3 ||
 | 
				
			||||||
				(u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) {
 | 
									sprom->ant_available_a == 3) {
 | 
				
			||||||
				asi->antsel_avail = false;
 | 
									asi->antsel_avail = false;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				asi->antsel_avail = false;
 | 
									asi->antsel_avail = false;
 | 
				
			||||||
| 
						 | 
					@ -146,8 +146,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if ((asi->pub->sromrev == 4) &&
 | 
						} else if ((asi->pub->sromrev == 4) &&
 | 
				
			||||||
		   ((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) &&
 | 
							   (sprom->ant_available_bg == 7) &&
 | 
				
			||||||
		   ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) {
 | 
							   (sprom->ant_available_a == 0)) {
 | 
				
			||||||
		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
 | 
							/* hack to match old 4321CB2 cards with 2of3 antenna switch */
 | 
				
			||||||
		asi->antsel_type = ANTSEL_2x3;
 | 
							asi->antsel_type = ANTSEL_2x3;
 | 
				
			||||||
		asi->antsel_avail = true;
 | 
							asi->antsel_avail = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1110,7 +1110,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
	char country_abbrev[BRCM_CNTRY_BUF_SZ];
 | 
						char country_abbrev[BRCM_CNTRY_BUF_SZ];
 | 
				
			||||||
	const struct country_info *country;
 | 
						const struct country_info *country;
 | 
				
			||||||
	struct brcms_pub *pub = wlc->pub;
 | 
						struct brcms_pub *pub = wlc->pub;
 | 
				
			||||||
	char *ccode;
 | 
						struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 | 
						BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1122,9 +1122,8 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
 | 
				
			||||||
	wlc->cmi = wlc_cm;
 | 
						wlc->cmi = wlc_cm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* store the country code for passing up as a regulatory hint */
 | 
						/* store the country code for passing up as a regulatory hint */
 | 
				
			||||||
	ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE);
 | 
						if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2))
 | 
				
			||||||
	if (ccode && brcms_c_country_valid(ccode))
 | 
							strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2));
 | 
				
			||||||
		strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * internal country information which must match
 | 
						 * internal country information which must match
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,6 @@
 | 
				
			||||||
#include <linux/bcma/bcma.h>
 | 
					#include <linux/bcma/bcma.h>
 | 
				
			||||||
#include <net/mac80211.h>
 | 
					#include <net/mac80211.h>
 | 
				
			||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include "nicpci.h"
 | 
					 | 
				
			||||||
#include "phy/phy_int.h"
 | 
					#include "phy/phy_int.h"
 | 
				
			||||||
#include "d11.h"
 | 
					#include "d11.h"
 | 
				
			||||||
#include "channel.h"
 | 
					#include "channel.h"
 | 
				
			||||||
| 
						 | 
					@ -770,7 +769,7 @@ void brcms_dpc(unsigned long data)
 | 
				
			||||||
 * Precondition: Since this function is called in brcms_pci_probe() context,
 | 
					 * Precondition: Since this function is called in brcms_pci_probe() context,
 | 
				
			||||||
 * no locking is required.
 | 
					 * no locking is required.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev)
 | 
					static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
	struct device *device = &pdev->dev;
 | 
						struct device *device = &pdev->dev;
 | 
				
			||||||
| 
						 | 
					@ -1022,7 +1021,7 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
 | 
				
			||||||
	spin_lock_init(&wl->isr_lock);
 | 
						spin_lock_init(&wl->isr_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* prepare ucode */
 | 
						/* prepare ucode */
 | 
				
			||||||
	if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) {
 | 
						if (brcms_request_fw(wl, pdev) < 0) {
 | 
				
			||||||
		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
 | 
							wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
 | 
				
			||||||
			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
 | 
								  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
 | 
				
			||||||
		brcms_release_fw(wl);
 | 
							brcms_release_fw(wl);
 | 
				
			||||||
| 
						 | 
					@ -1043,12 +1042,12 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
 | 
				
			||||||
	wl->pub->ieee_hw = hw;
 | 
						wl->pub->ieee_hw = hw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* register our interrupt handler */
 | 
						/* register our interrupt handler */
 | 
				
			||||||
	if (request_irq(pdev->bus->host_pci->irq, brcms_isr,
 | 
						if (request_irq(pdev->irq, brcms_isr,
 | 
				
			||||||
			IRQF_SHARED, KBUILD_MODNAME, wl)) {
 | 
								IRQF_SHARED, KBUILD_MODNAME, wl)) {
 | 
				
			||||||
		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
 | 
							wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wl->irq = pdev->bus->host_pci->irq;
 | 
						wl->irq = pdev->irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* register module */
 | 
						/* register module */
 | 
				
			||||||
	brcms_c_module_register(wl->pub, "linux", wl, NULL);
 | 
						brcms_c_module_register(wl->pub, "linux", wl, NULL);
 | 
				
			||||||
| 
						 | 
					@ -1098,7 +1097,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
 | 
						dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
 | 
				
			||||||
		 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
 | 
							 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
 | 
				
			||||||
		 pdev->bus->host_pci->irq);
 | 
							 pdev->irq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
 | 
						if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
 | 
				
			||||||
	    (pdev->id.id != BCMA_CORE_80211))
 | 
						    (pdev->id.id != BCMA_CORE_80211))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1219,7 +1219,7 @@ static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* control chip clock to save power, enable dynamic clock or force fast clock */
 | 
					/* control chip clock to save power, enable dynamic clock or force fast clock */
 | 
				
			||||||
static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
 | 
					static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
 | 
						if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
 | 
				
			||||||
		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock
 | 
							/* new chips with PMU, CCS_FORCEHT will distribute the HT clock
 | 
				
			||||||
| 
						 | 
					@ -1229,7 +1229,7 @@ static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (wlc_hw->clk) {
 | 
							if (wlc_hw->clk) {
 | 
				
			||||||
			if (mode == CLK_FAST) {
 | 
								if (mode == BCMA_CLKMODE_FAST) {
 | 
				
			||||||
				bcma_set32(wlc_hw->d11core,
 | 
									bcma_set32(wlc_hw->d11core,
 | 
				
			||||||
					   D11REGOFFS(clk_ctl_st),
 | 
										   D11REGOFFS(clk_ctl_st),
 | 
				
			||||||
					   CCS_FORCEHT);
 | 
										   CCS_FORCEHT);
 | 
				
			||||||
| 
						 | 
					@ -1260,7 +1260,7 @@ static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
 | 
				
			||||||
					~CCS_FORCEHT);
 | 
										~CCS_FORCEHT);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		wlc_hw->forcefastclk = (mode == CLK_FAST);
 | 
							wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* old chips w/o PMU, force HT through cc,
 | 
							/* old chips w/o PMU, force HT through cc,
 | 
				
			||||||
| 
						 | 
					@ -1567,7 +1567,7 @@ void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
 | 
				
			||||||
	/* request FAST clock if not on */
 | 
						/* request FAST clock if not on */
 | 
				
			||||||
	fastclk = wlc_hw->forcefastclk;
 | 
						fastclk = wlc_hw->forcefastclk;
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
 | 
						wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1576,7 +1576,7 @@ void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* restore the clk */
 | 
						/* restore the clk */
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
 | 
					static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
| 
						 | 
					@ -1882,27 +1882,20 @@ static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw)
 | 
					static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum brcms_srom_id var_id = BRCMS_SROM_MACADDR;
 | 
						struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
 | 
				
			||||||
	char *macaddr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
 | 
						/* If macaddr exists, use it (Sromrev4, CIS, ...). */
 | 
				
			||||||
	macaddr = getvar(wlc_hw->sih, var_id);
 | 
						if (!is_zero_ether_addr(sprom->il0mac)) {
 | 
				
			||||||
	if (macaddr != NULL)
 | 
							memcpy(etheraddr, sprom->il0mac, 6);
 | 
				
			||||||
		return macaddr;
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlc_hw->_nbands > 1)
 | 
						if (wlc_hw->_nbands > 1)
 | 
				
			||||||
		var_id = BRCMS_SROM_ET1MACADDR;
 | 
							memcpy(etheraddr, sprom->et1mac, 6);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		var_id = BRCMS_SROM_IL0MACADDR;
 | 
							memcpy(etheraddr, sprom->il0mac, 6);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	macaddr = getvar(wlc_hw->sih, var_id);
 | 
					 | 
				
			||||||
	if (macaddr == NULL)
 | 
					 | 
				
			||||||
		wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
 | 
					 | 
				
			||||||
			  "getvar(%d) not found\n", wlc_hw->unit, var_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return macaddr;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* power both the pll and external oscillator on/off */
 | 
					/* power both the pll and external oscillator on/off */
 | 
				
			||||||
| 
						 | 
					@ -1917,9 +1910,6 @@ static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
 | 
				
			||||||
	if (!want && wlc_hw->pllreq)
 | 
						if (!want && wlc_hw->pllreq)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlc_hw->sih)
 | 
					 | 
				
			||||||
		ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wlc_hw->sbclk = want;
 | 
						wlc_hw->sbclk = want;
 | 
				
			||||||
	if (!wlc_hw->sbclk) {
 | 
						if (!wlc_hw->sbclk) {
 | 
				
			||||||
		wlc_hw->clk = false;
 | 
							wlc_hw->clk = false;
 | 
				
			||||||
| 
						 | 
					@ -2004,7 +1994,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
 | 
				
			||||||
	/* request FAST clock if not on  */
 | 
						/* request FAST clock if not on  */
 | 
				
			||||||
	fastclk = wlc_hw->forcefastclk;
 | 
						fastclk = wlc_hw->forcefastclk;
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reset the dma engines except first time thru */
 | 
						/* reset the dma engines except first time thru */
 | 
				
			||||||
	if (bcma_core_is_enabled(wlc_hw->d11core)) {
 | 
						if (bcma_core_is_enabled(wlc_hw->d11core)) {
 | 
				
			||||||
| 
						 | 
					@ -2053,7 +2043,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
 | 
				
			||||||
	brcms_c_mctrl_reset(wlc_hw);
 | 
						brcms_c_mctrl_reset(wlc_hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
 | 
						if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcms_b_phy_reset(wlc_hw);
 | 
						brcms_b_phy_reset(wlc_hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2065,7 +2055,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* restore the clk setting */
 | 
						/* restore the clk setting */
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* txfifo sizes needs to be modified(increased) since the newer cores
 | 
					/* txfifo sizes needs to be modified(increased) since the newer cores
 | 
				
			||||||
| 
						 | 
					@ -2218,7 +2208,7 @@ static void brcms_c_gpio_init(struct brcms_c_info *wlc)
 | 
				
			||||||
		gm |= gc |= BOARD_GPIO_PACTRL;
 | 
							gm |= gc |= BOARD_GPIO_PACTRL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* apply to gpiocontrol register */
 | 
						/* apply to gpiocontrol register */
 | 
				
			||||||
	ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
 | 
						bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
 | 
					static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
 | 
				
			||||||
| 
						 | 
					@ -3371,7 +3361,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
 | 
				
			||||||
	/* request FAST clock if not on */
 | 
						/* request FAST clock if not on */
 | 
				
			||||||
	fastclk = wlc_hw->forcefastclk;
 | 
						fastclk = wlc_hw->forcefastclk;
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* disable interrupts */
 | 
						/* disable interrupts */
 | 
				
			||||||
	macintmask = brcms_intrsoff(wlc->wl);
 | 
						macintmask = brcms_intrsoff(wlc->wl);
 | 
				
			||||||
| 
						 | 
					@ -3405,7 +3395,7 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* restore the clk */
 | 
						/* restore the clk */
 | 
				
			||||||
	if (!fastclk)
 | 
						if (!fastclk)
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
 | 
					static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
 | 
				
			||||||
| 
						 | 
					@ -4436,17 +4426,22 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
			  uint unit, bool piomode)
 | 
								  uint unit, bool piomode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct brcms_hardware *wlc_hw;
 | 
						struct brcms_hardware *wlc_hw;
 | 
				
			||||||
	char *macaddr = NULL;
 | 
					 | 
				
			||||||
	uint err = 0;
 | 
						uint err = 0;
 | 
				
			||||||
	uint j;
 | 
						uint j;
 | 
				
			||||||
	bool wme = false;
 | 
						bool wme = false;
 | 
				
			||||||
	struct shared_phy_params sha_params;
 | 
						struct shared_phy_params sha_params;
 | 
				
			||||||
	struct wiphy *wiphy = wlc->wiphy;
 | 
						struct wiphy *wiphy = wlc->wiphy;
 | 
				
			||||||
	struct pci_dev *pcidev = core->bus->host_pci;
 | 
						struct pci_dev *pcidev = core->bus->host_pci;
 | 
				
			||||||
 | 
						struct ssb_sprom *sprom = &core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
 | 
				
			||||||
		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
 | 
							BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
 | 
				
			||||||
		       pcidev->vendor,
 | 
							       pcidev->vendor,
 | 
				
			||||||
		       pcidev->device);
 | 
							       pcidev->device);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
 | 
				
			||||||
 | 
							       core->bus->boardinfo.vendor,
 | 
				
			||||||
 | 
							       core->bus->boardinfo.type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wme = true;
 | 
						wme = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4472,7 +4467,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* verify again the device is supported */
 | 
						/* verify again the device is supported */
 | 
				
			||||||
	if (!brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
 | 
						if (core->bus->hosttype == BCMA_HOSTTYPE_PCI &&
 | 
				
			||||||
 | 
						    !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
 | 
				
			||||||
		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
 | 
							wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
 | 
				
			||||||
			"vendor/device (0x%x/0x%x)\n",
 | 
								"vendor/device (0x%x/0x%x)\n",
 | 
				
			||||||
			 unit, pcidev->vendor, pcidev->device);
 | 
								 unit, pcidev->vendor, pcidev->device);
 | 
				
			||||||
| 
						 | 
					@ -4480,8 +4476,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
 | 
				
			||||||
		wlc_hw->vendorid = pcidev->vendor;
 | 
							wlc_hw->vendorid = pcidev->vendor;
 | 
				
			||||||
		wlc_hw->deviceid = pcidev->device;
 | 
							wlc_hw->deviceid = pcidev->device;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlc_hw->vendorid = core->bus->boardinfo.vendor;
 | 
				
			||||||
 | 
							wlc_hw->deviceid = core->bus->boardinfo.type;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlc_hw->d11core = core;
 | 
						wlc_hw->d11core = core;
 | 
				
			||||||
	wlc_hw->corerev = core->id.rev;
 | 
						wlc_hw->corerev = core->id.rev;
 | 
				
			||||||
| 
						 | 
					@ -4501,7 +4502,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
	 *   is still false; But it will be called again inside wlc_corereset,
 | 
						 *   is still false; But it will be called again inside wlc_corereset,
 | 
				
			||||||
	 *   after d11 is out of reset.
 | 
						 *   after d11 is out of reset.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
						brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
 | 
						brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!brcms_b_validate_chip_access(wlc_hw)) {
 | 
						if (!brcms_b_validate_chip_access(wlc_hw)) {
 | 
				
			||||||
| 
						 | 
					@ -4512,7 +4513,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get the board rev, used just below */
 | 
						/* get the board rev, used just below */
 | 
				
			||||||
	j = getintvar(wlc_hw->sih, BRCMS_SROM_BOARDREV);
 | 
						j = sprom->board_rev;
 | 
				
			||||||
	/* promote srom boardrev of 0xFF to 1 */
 | 
						/* promote srom boardrev of 0xFF to 1 */
 | 
				
			||||||
	if (j == BOARDREV_PROMOTABLE)
 | 
						if (j == BOARDREV_PROMOTABLE)
 | 
				
			||||||
		j = BOARDREV_PROMOTED;
 | 
							j = BOARDREV_PROMOTED;
 | 
				
			||||||
| 
						 | 
					@ -4525,11 +4526,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
		err = 15;
 | 
							err = 15;
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlc_hw->sromrev = (u8) getintvar(wlc_hw->sih, BRCMS_SROM_REV);
 | 
						wlc_hw->sromrev = sprom->revision;
 | 
				
			||||||
	wlc_hw->boardflags = (u32) getintvar(wlc_hw->sih,
 | 
						wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
 | 
				
			||||||
					     BRCMS_SROM_BOARDFLAGS);
 | 
						wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
 | 
				
			||||||
	wlc_hw->boardflags2 = (u32) getintvar(wlc_hw->sih,
 | 
					 | 
				
			||||||
					      BRCMS_SROM_BOARDFLAGS2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
 | 
						if (wlc_hw->boardflags & BFL_NOPLLDOWN)
 | 
				
			||||||
		brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
 | 
							brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
 | 
				
			||||||
| 
						 | 
					@ -4702,25 +4701,18 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* init etheraddr state variables */
 | 
						/* init etheraddr state variables */
 | 
				
			||||||
	macaddr = brcms_c_get_macaddr(wlc_hw);
 | 
						brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
 | 
				
			||||||
	if (macaddr == NULL) {
 | 
					
 | 
				
			||||||
		wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n",
 | 
						if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
 | 
				
			||||||
			  unit);
 | 
					 | 
				
			||||||
		err = 21;
 | 
					 | 
				
			||||||
		goto fail;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!mac_pton(macaddr, wlc_hw->etheraddr) ||
 | 
					 | 
				
			||||||
	    is_broadcast_ether_addr(wlc_hw->etheraddr) ||
 | 
					 | 
				
			||||||
	    is_zero_ether_addr(wlc_hw->etheraddr)) {
 | 
						    is_zero_ether_addr(wlc_hw->etheraddr)) {
 | 
				
			||||||
		wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n",
 | 
							wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
 | 
				
			||||||
			  unit, macaddr);
 | 
								  unit);
 | 
				
			||||||
		err = 22;
 | 
							err = 22;
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
 | 
						BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
 | 
				
			||||||
	       wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih),
 | 
						       wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
 | 
				
			||||||
	       macaddr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4770,16 +4762,16 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
 | 
				
			||||||
	int aa;
 | 
						int aa;
 | 
				
			||||||
	uint unit;
 | 
						uint unit;
 | 
				
			||||||
	int bandtype;
 | 
						int bandtype;
 | 
				
			||||||
	struct si_pub *sih = wlc->hw->sih;
 | 
						struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unit = wlc->pub->unit;
 | 
						unit = wlc->pub->unit;
 | 
				
			||||||
	bandtype = wlc->band->bandtype;
 | 
						bandtype = wlc->band->bandtype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get antennas available */
 | 
						/* get antennas available */
 | 
				
			||||||
	if (bandtype == BRCM_BAND_5G)
 | 
						if (bandtype == BRCM_BAND_5G)
 | 
				
			||||||
		aa = (s8) getintvar(sih, BRCMS_SROM_AA5G);
 | 
							aa = sprom->ant_available_a;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		aa = (s8) getintvar(sih, BRCMS_SROM_AA2G);
 | 
							aa = sprom->ant_available_bg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((aa < 1) || (aa > 15)) {
 | 
						if ((aa < 1) || (aa > 15)) {
 | 
				
			||||||
		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
 | 
							wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
 | 
				
			||||||
| 
						 | 
					@ -4799,9 +4791,9 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Compute Antenna Gain */
 | 
						/* Compute Antenna Gain */
 | 
				
			||||||
	if (bandtype == BRCM_BAND_5G)
 | 
						if (bandtype == BRCM_BAND_5G)
 | 
				
			||||||
		wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG1);
 | 
							wlc->band->antgain = sprom->antenna_gain.a1;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG0);
 | 
							wlc->band->antgain = sprom->antenna_gain.a0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	brcms_c_attach_antgain_init(wlc);
 | 
						brcms_c_attach_antgain_init(wlc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4952,15 +4944,6 @@ static int brcms_b_detach(struct brcms_c_info *wlc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	callbacks = 0;
 | 
						callbacks = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlc_hw->sih) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * detach interrupt sync mechanism since interrupt is disabled
 | 
					 | 
				
			||||||
		 * and per-port interrupt object may has been freed. this must
 | 
					 | 
				
			||||||
		 * be done before sb core switch
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		ai_pci_sleep(wlc_hw->sih);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	brcms_b_detach_dmapio(wlc_hw);
 | 
						brcms_b_detach_dmapio(wlc_hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	band = wlc_hw->band;
 | 
						band = wlc_hw->band;
 | 
				
			||||||
| 
						 | 
					@ -5047,9 +5030,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	brcms_b_xtal(wlc_hw, ON);
 | 
						brcms_b_xtal(wlc_hw, ON);
 | 
				
			||||||
	ai_clkctl_init(wlc_hw->sih);
 | 
						ai_clkctl_init(wlc_hw->sih);
 | 
				
			||||||
	brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
						brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ai_pci_fixcfg(wlc_hw->sih);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * TODO: test suspend/resume
 | 
						 * TODO: test suspend/resume
 | 
				
			||||||
| 
						 | 
					@ -5078,8 +5059,6 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
 | 
					static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint coremask;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 | 
						BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -5088,15 +5067,14 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	brcms_b_xtal(wlc_hw, ON);
 | 
						brcms_b_xtal(wlc_hw, ON);
 | 
				
			||||||
	ai_clkctl_init(wlc_hw->sih);
 | 
						ai_clkctl_init(wlc_hw->sih);
 | 
				
			||||||
	brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
						brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Configure pci/pcmcia here instead of in brcms_c_attach()
 | 
						 * Configure pci/pcmcia here instead of in brcms_c_attach()
 | 
				
			||||||
	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
 | 
						 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	coremask = (1 << wlc_hw->wlc->core->coreidx);
 | 
						bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
 | 
				
			||||||
 | 
								      true);
 | 
				
			||||||
	ai_pci_setup(wlc_hw->sih, coremask);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Need to read the hwradio status here to cover the case where the
 | 
						 * Need to read the hwradio status here to cover the case where the
 | 
				
			||||||
| 
						 | 
					@ -5126,7 +5104,7 @@ static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
 | 
						wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FULLY enable dynamic power control and d11 core interrupt */
 | 
						/* FULLY enable dynamic power control and d11 core interrupt */
 | 
				
			||||||
	brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
 | 
						brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
 | 
				
			||||||
	brcms_intrson(wlc_hw->wlc->wl);
 | 
						brcms_intrson(wlc_hw->wlc->wl);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5267,7 +5245,7 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
 | 
				
			||||||
		brcms_intrsoff(wlc_hw->wlc->wl);
 | 
							brcms_intrsoff(wlc_hw->wlc->wl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* ensure we're running on the pll clock again */
 | 
							/* ensure we're running on the pll clock again */
 | 
				
			||||||
		brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
 | 
							brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* down phy at the last of this stage */
 | 
						/* down phy at the last of this stage */
 | 
				
			||||||
	callbacks += wlc_phy_down(wlc_hw->band->pi);
 | 
						callbacks += wlc_phy_down(wlc_hw->band->pi);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,826 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/slab.h>
 | 
					 | 
				
			||||||
#include <linux/delay.h>
 | 
					 | 
				
			||||||
#include <linux/pci.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <defs.h>
 | 
					 | 
				
			||||||
#include <soc.h>
 | 
					 | 
				
			||||||
#include <chipcommon.h>
 | 
					 | 
				
			||||||
#include "aiutils.h"
 | 
					 | 
				
			||||||
#include "pub.h"
 | 
					 | 
				
			||||||
#include "nicpci.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SPROM offsets */
 | 
					 | 
				
			||||||
#define SRSH_ASPM_OFFSET		4	/* word 4 */
 | 
					 | 
				
			||||||
#define SRSH_ASPM_ENB			0x18	/* bit 3, 4 */
 | 
					 | 
				
			||||||
#define SRSH_ASPM_L1_ENB		0x10	/* bit 4 */
 | 
					 | 
				
			||||||
#define SRSH_ASPM_L0s_ENB		0x8	/* bit 3 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SRSH_PCIE_MISC_CONFIG		5	/* word 5 */
 | 
					 | 
				
			||||||
#define SRSH_L23READY_EXIT_NOPERST	0x8000	/* bit 15 */
 | 
					 | 
				
			||||||
#define SRSH_CLKREQ_OFFSET_REV5		20	/* word 20 for srom rev <= 5 */
 | 
					 | 
				
			||||||
#define SRSH_CLKREQ_ENB			0x0800	/* bit 11 */
 | 
					 | 
				
			||||||
#define SRSH_BD_OFFSET                  6	/* word 6 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* chipcontrol */
 | 
					 | 
				
			||||||
#define CHIPCTRL_4321_PLL_DOWN		0x800000/* serdes PLL down override */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* MDIO control */
 | 
					 | 
				
			||||||
#define MDIOCTL_DIVISOR_MASK		0x7f	/* clock to be used on MDIO */
 | 
					 | 
				
			||||||
#define MDIOCTL_DIVISOR_VAL		0x2
 | 
					 | 
				
			||||||
#define MDIOCTL_PREAM_EN		0x80	/* Enable preamble sequnce */
 | 
					 | 
				
			||||||
#define MDIOCTL_ACCESS_DONE		0x100	/* Transaction complete */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* MDIO Data */
 | 
					 | 
				
			||||||
#define MDIODATA_MASK			0x0000ffff	/* data 2 bytes */
 | 
					 | 
				
			||||||
#define MDIODATA_TA			0x00020000	/* Turnaround */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MDIODATA_REGADDR_SHF		18		/* Regaddr shift */
 | 
					 | 
				
			||||||
#define MDIODATA_REGADDR_MASK		0x007c0000	/* Regaddr Mask */
 | 
					 | 
				
			||||||
#define MDIODATA_DEVADDR_SHF		23	/* Physmedia devaddr shift */
 | 
					 | 
				
			||||||
#define MDIODATA_DEVADDR_MASK		0x0f800000
 | 
					 | 
				
			||||||
						/* Physmedia devaddr Mask */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* MDIO Data for older revisions < 10 */
 | 
					 | 
				
			||||||
#define MDIODATA_REGADDR_SHF_OLD	18	/* Regaddr shift */
 | 
					 | 
				
			||||||
#define MDIODATA_REGADDR_MASK_OLD	0x003c0000
 | 
					 | 
				
			||||||
						/* Regaddr Mask */
 | 
					 | 
				
			||||||
#define MDIODATA_DEVADDR_SHF_OLD	22	/* Physmedia devaddr shift  */
 | 
					 | 
				
			||||||
#define MDIODATA_DEVADDR_MASK_OLD	0x0fc00000
 | 
					 | 
				
			||||||
						/* Physmedia devaddr Mask */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Transactions flags */
 | 
					 | 
				
			||||||
#define MDIODATA_WRITE			0x10000000
 | 
					 | 
				
			||||||
#define MDIODATA_READ			0x20000000
 | 
					 | 
				
			||||||
#define MDIODATA_START			0x40000000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MDIODATA_DEV_ADDR		0x0	/* dev address for serdes */
 | 
					 | 
				
			||||||
#define	MDIODATA_BLK_ADDR		0x1F	/* blk address for serdes */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* serdes regs (rev < 10) */
 | 
					 | 
				
			||||||
#define MDIODATA_DEV_PLL		0x1d	/* SERDES PLL Dev */
 | 
					 | 
				
			||||||
#define MDIODATA_DEV_TX			0x1e	/* SERDES TX Dev */
 | 
					 | 
				
			||||||
#define MDIODATA_DEV_RX			0x1f	/* SERDES RX Dev */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SERDES RX registers */
 | 
					 | 
				
			||||||
#define SERDES_RX_CTRL			1	/* Rx cntrl */
 | 
					 | 
				
			||||||
#define SERDES_RX_TIMER1		2	/* Rx Timer1 */
 | 
					 | 
				
			||||||
#define SERDES_RX_CDR			6	/* CDR */
 | 
					 | 
				
			||||||
#define SERDES_RX_CDRBW			7	/* CDR BW */
 | 
					 | 
				
			||||||
/* SERDES RX control register */
 | 
					 | 
				
			||||||
#define SERDES_RX_CTRL_FORCE		0x80	/* rxpolarity_force */
 | 
					 | 
				
			||||||
#define SERDES_RX_CTRL_POLARITY		0x40	/* rxpolarity_value */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SERDES PLL registers */
 | 
					 | 
				
			||||||
#define SERDES_PLL_CTRL                 1	/* PLL control reg */
 | 
					 | 
				
			||||||
#define PLL_CTRL_FREQDET_EN             0x4000	/* bit 14 is FREQDET on */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Linkcontrol reg offset in PCIE Cap */
 | 
					 | 
				
			||||||
#define PCIE_CAP_LINKCTRL_OFFSET	16	/* offset in pcie cap */
 | 
					 | 
				
			||||||
#define PCIE_CAP_LCREG_ASPML0s		0x01	/* ASPM L0s in linkctrl */
 | 
					 | 
				
			||||||
#define PCIE_CAP_LCREG_ASPML1		0x02	/* ASPM L1 in linkctrl */
 | 
					 | 
				
			||||||
#define PCIE_CLKREQ_ENAB		0x100	/* CLKREQ Enab in linkctrl */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PCIE_ASPM_ENAB			3	/* ASPM L0s & L1 in linkctrl */
 | 
					 | 
				
			||||||
#define PCIE_ASPM_L1_ENAB		2	/* ASPM L0s & L1 in linkctrl */
 | 
					 | 
				
			||||||
#define PCIE_ASPM_L0s_ENAB		1	/* ASPM L0s & L1 in linkctrl */
 | 
					 | 
				
			||||||
#define PCIE_ASPM_DISAB			0	/* ASPM L0s & L1 in linkctrl */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Power management threshold */
 | 
					 | 
				
			||||||
#define PCIE_L1THRESHOLDTIME_MASK       0xFF00	/* bits 8 - 15 */
 | 
					 | 
				
			||||||
#define PCIE_L1THRESHOLDTIME_SHIFT      8	/* PCIE_L1THRESHOLDTIME_SHIFT */
 | 
					 | 
				
			||||||
#define PCIE_L1THRESHOLD_WARVAL         0x72	/* WAR value */
 | 
					 | 
				
			||||||
#define PCIE_ASPMTIMER_EXTEND		0x01000000
 | 
					 | 
				
			||||||
						/* > rev7:
 | 
					 | 
				
			||||||
						 * enable extend ASPM timer
 | 
					 | 
				
			||||||
						 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* different register spaces to access thru pcie indirect access */
 | 
					 | 
				
			||||||
#define PCIE_CONFIGREGS		1	/* Access to config space */
 | 
					 | 
				
			||||||
#define PCIE_PCIEREGS		2	/* Access to pcie registers */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCIE protocol PHY diagnostic registers */
 | 
					 | 
				
			||||||
#define	PCIE_PLP_STATUSREG		0x204	/* Status */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Status reg PCIE_PLP_STATUSREG */
 | 
					 | 
				
			||||||
#define PCIE_PLP_POLARITYINV_STAT	0x10
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCIE protocol DLLP diagnostic registers */
 | 
					 | 
				
			||||||
#define PCIE_DLLP_LCREG			0x100	/* Link Control */
 | 
					 | 
				
			||||||
#define PCIE_DLLP_PMTHRESHREG		0x128	/* Power Management Threshold */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCIE protocol TLP diagnostic registers */
 | 
					 | 
				
			||||||
#define PCIE_TLP_WORKAROUNDSREG		0x004	/* TLP Workarounds */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Sonics to PCI translation types */
 | 
					 | 
				
			||||||
#define	SBTOPCI_PREF	0x4		/* prefetch enable */
 | 
					 | 
				
			||||||
#define	SBTOPCI_BURST	0x8		/* burst enable */
 | 
					 | 
				
			||||||
#define	SBTOPCI_RC_READMULTI	0x20	/* memory read multiple */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PCI_CLKRUN_DSBL	0x8000	/* Bit 15 forceClkrun */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCI core index in SROM shadow area */
 | 
					 | 
				
			||||||
#define SRSH_PI_OFFSET	0	/* first word */
 | 
					 | 
				
			||||||
#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
 | 
					 | 
				
			||||||
#define SRSH_PI_SHIFT	12	/* bit 15:12 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PCIREGOFFS(field)	offsetof(struct sbpciregs, field)
 | 
					 | 
				
			||||||
#define PCIEREGOFFS(field)	offsetof(struct sbpcieregs, field)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Sonics side: PCI core and host control registers */
 | 
					 | 
				
			||||||
struct sbpciregs {
 | 
					 | 
				
			||||||
	u32 control;		/* PCI control */
 | 
					 | 
				
			||||||
	u32 PAD[3];
 | 
					 | 
				
			||||||
	u32 arbcontrol;		/* PCI arbiter control */
 | 
					 | 
				
			||||||
	u32 clkrun;		/* Clkrun Control (>=rev11) */
 | 
					 | 
				
			||||||
	u32 PAD[2];
 | 
					 | 
				
			||||||
	u32 intstatus;		/* Interrupt status */
 | 
					 | 
				
			||||||
	u32 intmask;		/* Interrupt mask */
 | 
					 | 
				
			||||||
	u32 sbtopcimailbox;	/* Sonics to PCI mailbox */
 | 
					 | 
				
			||||||
	u32 PAD[9];
 | 
					 | 
				
			||||||
	u32 bcastaddr;		/* Sonics broadcast address */
 | 
					 | 
				
			||||||
	u32 bcastdata;		/* Sonics broadcast data */
 | 
					 | 
				
			||||||
	u32 PAD[2];
 | 
					 | 
				
			||||||
	u32 gpioin;		/* ro: gpio input (>=rev2) */
 | 
					 | 
				
			||||||
	u32 gpioout;		/* rw: gpio output (>=rev2) */
 | 
					 | 
				
			||||||
	u32 gpioouten;		/* rw: gpio output enable (>= rev2) */
 | 
					 | 
				
			||||||
	u32 gpiocontrol;	/* rw: gpio control (>= rev2) */
 | 
					 | 
				
			||||||
	u32 PAD[36];
 | 
					 | 
				
			||||||
	u32 sbtopci0;		/* Sonics to PCI translation 0 */
 | 
					 | 
				
			||||||
	u32 sbtopci1;		/* Sonics to PCI translation 1 */
 | 
					 | 
				
			||||||
	u32 sbtopci2;		/* Sonics to PCI translation 2 */
 | 
					 | 
				
			||||||
	u32 PAD[189];
 | 
					 | 
				
			||||||
	u32 pcicfg[4][64];	/* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
 | 
					 | 
				
			||||||
	u16 sprom[36];		/* SPROM shadow Area */
 | 
					 | 
				
			||||||
	u32 PAD[46];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SB side: PCIE core and host control registers */
 | 
					 | 
				
			||||||
struct sbpcieregs {
 | 
					 | 
				
			||||||
	u32 control;		/* host mode only */
 | 
					 | 
				
			||||||
	u32 PAD[2];
 | 
					 | 
				
			||||||
	u32 biststatus;		/* bist Status: 0x00C */
 | 
					 | 
				
			||||||
	u32 gpiosel;		/* PCIE gpio sel: 0x010 */
 | 
					 | 
				
			||||||
	u32 gpioouten;		/* PCIE gpio outen: 0x14 */
 | 
					 | 
				
			||||||
	u32 PAD[2];
 | 
					 | 
				
			||||||
	u32 intstatus;		/* Interrupt status: 0x20 */
 | 
					 | 
				
			||||||
	u32 intmask;		/* Interrupt mask: 0x24 */
 | 
					 | 
				
			||||||
	u32 sbtopcimailbox;	/* sb to pcie mailbox: 0x028 */
 | 
					 | 
				
			||||||
	u32 PAD[53];
 | 
					 | 
				
			||||||
	u32 sbtopcie0;		/* sb to pcie translation 0: 0x100 */
 | 
					 | 
				
			||||||
	u32 sbtopcie1;		/* sb to pcie translation 1: 0x104 */
 | 
					 | 
				
			||||||
	u32 sbtopcie2;		/* sb to pcie translation 2: 0x108 */
 | 
					 | 
				
			||||||
	u32 PAD[5];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pcie core supports in direct access to config space */
 | 
					 | 
				
			||||||
	u32 configaddr;	/* pcie config space access: Address field: 0x120 */
 | 
					 | 
				
			||||||
	u32 configdata;	/* pcie config space access: Data field: 0x124 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* mdio access to serdes */
 | 
					 | 
				
			||||||
	u32 mdiocontrol;	/* controls the mdio access: 0x128 */
 | 
					 | 
				
			||||||
	u32 mdiodata;		/* Data to the mdio access: 0x12c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pcie protocol phy/dllp/tlp register indirect access mechanism */
 | 
					 | 
				
			||||||
	u32 pcieindaddr;	/* indirect access to
 | 
					 | 
				
			||||||
				 * the internal register: 0x130
 | 
					 | 
				
			||||||
				 */
 | 
					 | 
				
			||||||
	u32 pcieinddata;	/* Data to/from the internal regsiter: 0x134 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 clkreqenctrl;	/* >= rev 6, Clkreq rdma control : 0x138 */
 | 
					 | 
				
			||||||
	u32 PAD[177];
 | 
					 | 
				
			||||||
	u32 pciecfg[4][64];	/* 0x400 - 0x7FF, PCIE Cfg Space */
 | 
					 | 
				
			||||||
	u16 sprom[64];		/* SPROM shadow Area */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct pcicore_info {
 | 
					 | 
				
			||||||
	struct bcma_device *core;
 | 
					 | 
				
			||||||
	struct si_pub *sih;	/* System interconnect handle */
 | 
					 | 
				
			||||||
	struct pci_dev *dev;
 | 
					 | 
				
			||||||
	u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
 | 
					 | 
				
			||||||
				 * in the config space
 | 
					 | 
				
			||||||
				 */
 | 
					 | 
				
			||||||
	bool pcie_pr42767;
 | 
					 | 
				
			||||||
	u8 pcie_polarity;
 | 
					 | 
				
			||||||
	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u8 pmecap_offset;	/* PM Capability offset in the config space */
 | 
					 | 
				
			||||||
	bool pmecap;		/* Capable of generating PME */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PCIE_ASPM(sih)							\
 | 
					 | 
				
			||||||
	((ai_get_buscoretype(sih) == PCIE_CORE_ID) &&			\
 | 
					 | 
				
			||||||
	 ((ai_get_buscorerev(sih) >= 3) &&				\
 | 
					 | 
				
			||||||
	  (ai_get_buscorerev(sih) <= 5)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* delay needed between the mdio control/ mdiodata register data access */
 | 
					 | 
				
			||||||
static void pr28829_delay(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	udelay(10);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Initialize the PCI core.
 | 
					 | 
				
			||||||
 * It's caller's responsibility to make sure that this is done only once
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pcicore_info *pi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* alloc struct pcicore_info */
 | 
					 | 
				
			||||||
	pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
 | 
					 | 
				
			||||||
	if (pi == NULL)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pi->sih = sih;
 | 
					 | 
				
			||||||
	pi->dev = core->bus->host_pci;
 | 
					 | 
				
			||||||
	pi->core = core;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (core->id.id == PCIE_CORE_ID) {
 | 
					 | 
				
			||||||
		u8 cap_ptr;
 | 
					 | 
				
			||||||
		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
 | 
					 | 
				
			||||||
						      NULL, NULL);
 | 
					 | 
				
			||||||
		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return pi;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pcicore_deinit(struct pcicore_info *pch)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	kfree(pch);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* return cap_offset if requested capability exists in the PCI config space */
 | 
					 | 
				
			||||||
/* Note that it's caller's responsibility to make sure it's a pci bus */
 | 
					 | 
				
			||||||
u8
 | 
					 | 
				
			||||||
pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
 | 
					 | 
				
			||||||
			    unsigned char *buf, u32 *buflen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u8 cap_id;
 | 
					 | 
				
			||||||
	u8 cap_ptr = 0;
 | 
					 | 
				
			||||||
	u32 bufsize;
 | 
					 | 
				
			||||||
	u8 byte_val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* check for Header type 0 */
 | 
					 | 
				
			||||||
	pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
 | 
					 | 
				
			||||||
	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
 | 
					 | 
				
			||||||
		goto end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* check if the capability pointer field exists */
 | 
					 | 
				
			||||||
	pci_read_config_byte(dev, PCI_STATUS, &byte_val);
 | 
					 | 
				
			||||||
	if (!(byte_val & PCI_STATUS_CAP_LIST))
 | 
					 | 
				
			||||||
		goto end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
 | 
					 | 
				
			||||||
	/* check if the capability pointer is 0x00 */
 | 
					 | 
				
			||||||
	if (cap_ptr == 0x00)
 | 
					 | 
				
			||||||
		goto end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* loop thru the capability list
 | 
					 | 
				
			||||||
	 * and see if the pcie capability exists
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_byte(dev, cap_ptr, &cap_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while (cap_id != req_cap_id) {
 | 
					 | 
				
			||||||
		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
 | 
					 | 
				
			||||||
		if (cap_ptr == 0x00)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		pci_read_config_byte(dev, cap_ptr, &cap_id);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (cap_id != req_cap_id)
 | 
					 | 
				
			||||||
		goto end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* found the caller requested capability */
 | 
					 | 
				
			||||||
	if (buf != NULL && buflen != NULL) {
 | 
					 | 
				
			||||||
		u8 cap_data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bufsize = *buflen;
 | 
					 | 
				
			||||||
		if (!bufsize)
 | 
					 | 
				
			||||||
			goto end;
 | 
					 | 
				
			||||||
		*buflen = 0;
 | 
					 | 
				
			||||||
		/* copy the capability data excluding cap ID and next ptr */
 | 
					 | 
				
			||||||
		cap_data = cap_ptr + 2;
 | 
					 | 
				
			||||||
		if ((bufsize + cap_data) > PCI_SZPCR)
 | 
					 | 
				
			||||||
			bufsize = PCI_SZPCR - cap_data;
 | 
					 | 
				
			||||||
		*buflen = bufsize;
 | 
					 | 
				
			||||||
		while (bufsize--) {
 | 
					 | 
				
			||||||
			pci_read_config_byte(dev, cap_data, buf);
 | 
					 | 
				
			||||||
			cap_data++;
 | 
					 | 
				
			||||||
			buf++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
end:
 | 
					 | 
				
			||||||
	return cap_ptr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ***** Register Access API */
 | 
					 | 
				
			||||||
static uint
 | 
					 | 
				
			||||||
pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint retval = 0xFFFFFFFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (addrtype) {
 | 
					 | 
				
			||||||
	case PCIE_CONFIGREGS:
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
 | 
					 | 
				
			||||||
		(void)bcma_read32(core, PCIEREGOFFS(configaddr));
 | 
					 | 
				
			||||||
		retval = bcma_read32(core, PCIEREGOFFS(configdata));
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case PCIE_PCIEREGS:
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
 | 
					 | 
				
			||||||
		(void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
 | 
					 | 
				
			||||||
		retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return retval;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint pcie_writereg(struct bcma_device *core, uint addrtype,
 | 
					 | 
				
			||||||
			  uint offset, uint val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (addrtype) {
 | 
					 | 
				
			||||||
	case PCIE_CONFIGREGS:
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(configdata), val);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case PCIE_PCIEREGS:
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
 | 
					 | 
				
			||||||
		bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint mdiodata, i = 0;
 | 
					 | 
				
			||||||
	uint pcie_serdes_spinwait = 200;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
 | 
					 | 
				
			||||||
		    (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
 | 
					 | 
				
			||||||
		    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
 | 
					 | 
				
			||||||
		    (blk << 4));
 | 
					 | 
				
			||||||
	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pr28829_delay();
 | 
					 | 
				
			||||||
	/* retry till the transaction is complete */
 | 
					 | 
				
			||||||
	while (i < pcie_serdes_spinwait) {
 | 
					 | 
				
			||||||
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
 | 
					 | 
				
			||||||
		    MDIOCTL_ACCESS_DONE)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		udelay(1000);
 | 
					 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (i >= pcie_serdes_spinwait)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
 | 
					 | 
				
			||||||
	    uint *val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint mdiodata;
 | 
					 | 
				
			||||||
	uint i = 0;
 | 
					 | 
				
			||||||
	uint pcie_serdes_spinwait = 10;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* enable mdio access to SERDES */
 | 
					 | 
				
			||||||
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
 | 
					 | 
				
			||||||
		     MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_buscorerev(pi->sih) >= 10) {
 | 
					 | 
				
			||||||
		/* new serdes is slower in rw,
 | 
					 | 
				
			||||||
		 * using two layers of reg address mapping
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (!pcie_mdiosetblock(pi, physmedia))
 | 
					 | 
				
			||||||
			return 1;
 | 
					 | 
				
			||||||
		mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
 | 
					 | 
				
			||||||
			    (regaddr << MDIODATA_REGADDR_SHF));
 | 
					 | 
				
			||||||
		pcie_serdes_spinwait *= 20;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
 | 
					 | 
				
			||||||
			    (regaddr << MDIODATA_REGADDR_SHF_OLD));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!write)
 | 
					 | 
				
			||||||
		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
 | 
					 | 
				
			||||||
			     *val);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pr28829_delay();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* retry till the transaction is complete */
 | 
					 | 
				
			||||||
	while (i < pcie_serdes_spinwait) {
 | 
					 | 
				
			||||||
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
 | 
					 | 
				
			||||||
		    MDIOCTL_ACCESS_DONE) {
 | 
					 | 
				
			||||||
			if (!write) {
 | 
					 | 
				
			||||||
				pr28829_delay();
 | 
					 | 
				
			||||||
				*val = (bcma_read32(pi->core,
 | 
					 | 
				
			||||||
						    PCIEREGOFFS(mdiodata)) &
 | 
					 | 
				
			||||||
					MDIODATA_MASK);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			/* Disable mdio access to SERDES */
 | 
					 | 
				
			||||||
			bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		udelay(1000);
 | 
					 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Timed out. Disable mdio access to SERDES. */
 | 
					 | 
				
			||||||
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* use the mdio interface to read from mdio slaves */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
 | 
					 | 
				
			||||||
	      uint *regval)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* use the mdio interface to write to mdio slaves */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ***** Support functions ***** */
 | 
					 | 
				
			||||||
static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 reg_val;
 | 
					 | 
				
			||||||
	u8 offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	offset = pi->pciecap_lcreg_offset;
 | 
					 | 
				
			||||||
	if (!offset)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_dword(pi->dev, offset, ®_val);
 | 
					 | 
				
			||||||
	/* set operation */
 | 
					 | 
				
			||||||
	if (mask) {
 | 
					 | 
				
			||||||
		if (val)
 | 
					 | 
				
			||||||
			reg_val |= PCIE_CLKREQ_ENAB;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			reg_val &= ~PCIE_CLKREQ_ENAB;
 | 
					 | 
				
			||||||
		pci_write_config_dword(pi->dev, offset, reg_val);
 | 
					 | 
				
			||||||
		pci_read_config_dword(pi->dev, offset, ®_val);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (reg_val & PCIE_CLKREQ_ENAB)
 | 
					 | 
				
			||||||
		return 1;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
	struct si_pub *sih = pi->sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_buscoretype(sih) != PCIE_CORE_ID ||
 | 
					 | 
				
			||||||
	    ai_get_buscorerev(sih) < 7)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
 | 
					 | 
				
			||||||
	if (extend)
 | 
					 | 
				
			||||||
		w |= PCIE_ASPMTIMER_EXTEND;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		w &= ~PCIE_ASPMTIMER_EXTEND;
 | 
					 | 
				
			||||||
	pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
 | 
					 | 
				
			||||||
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* centralized clkreq control policy */
 | 
					 | 
				
			||||||
static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_pub *sih = pi->sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (state) {
 | 
					 | 
				
			||||||
	case SI_DOATTACH:
 | 
					 | 
				
			||||||
		if (PCIE_ASPM(sih))
 | 
					 | 
				
			||||||
			pcie_clkreq(pi, 1, 0);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SI_PCIDOWN:
 | 
					 | 
				
			||||||
		/* turn on serdes PLL down */
 | 
					 | 
				
			||||||
		if (ai_get_buscorerev(sih) == 6) {
 | 
					 | 
				
			||||||
			ai_cc_reg(sih,
 | 
					 | 
				
			||||||
				  offsetof(struct chipcregs, chipcontrol_addr),
 | 
					 | 
				
			||||||
				  ~0, 0);
 | 
					 | 
				
			||||||
			ai_cc_reg(sih,
 | 
					 | 
				
			||||||
				  offsetof(struct chipcregs, chipcontrol_data),
 | 
					 | 
				
			||||||
				  ~0x40, 0);
 | 
					 | 
				
			||||||
		} else if (pi->pcie_pr42767) {
 | 
					 | 
				
			||||||
			pcie_clkreq(pi, 1, 1);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SI_PCIUP:
 | 
					 | 
				
			||||||
		/* turn off serdes PLL down */
 | 
					 | 
				
			||||||
		if (ai_get_buscorerev(sih) == 6) {
 | 
					 | 
				
			||||||
			ai_cc_reg(sih,
 | 
					 | 
				
			||||||
				  offsetof(struct chipcregs, chipcontrol_addr),
 | 
					 | 
				
			||||||
				  ~0, 0);
 | 
					 | 
				
			||||||
			ai_cc_reg(sih,
 | 
					 | 
				
			||||||
				  offsetof(struct chipcregs, chipcontrol_data),
 | 
					 | 
				
			||||||
				  ~0x40, 0x40);
 | 
					 | 
				
			||||||
		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
 | 
					 | 
				
			||||||
			pcie_clkreq(pi, 1, 0);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ***** PCI core WARs ***** */
 | 
					 | 
				
			||||||
/* Done only once at attach time */
 | 
					 | 
				
			||||||
static void pcie_war_polarity(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pi->pcie_polarity != 0)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Detect the current polarity at attach and force that polarity and
 | 
					 | 
				
			||||||
	 * disable changing the polarity
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
 | 
					 | 
				
			||||||
		pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
 | 
					 | 
				
			||||||
				     SERDES_RX_CTRL_POLARITY);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* enable ASPM and CLKREQ if srom doesn't have it */
 | 
					 | 
				
			||||||
/* Needs to happen when update to shadow SROM is needed
 | 
					 | 
				
			||||||
 *   : Coming out of 'standby'/'hibernate'
 | 
					 | 
				
			||||||
 *   : If pcie_war_aspm_ovr state changed
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_pub *sih = pi->sih;
 | 
					 | 
				
			||||||
	u16 val16;
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PCIE_ASPM(sih))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* bypass this on QT or VSIM */
 | 
					 | 
				
			||||||
	val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val16 &= ~SRSH_ASPM_ENB;
 | 
					 | 
				
			||||||
	if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
 | 
					 | 
				
			||||||
		val16 |= SRSH_ASPM_ENB;
 | 
					 | 
				
			||||||
	else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
 | 
					 | 
				
			||||||
		val16 |= SRSH_ASPM_L1_ENB;
 | 
					 | 
				
			||||||
	else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
 | 
					 | 
				
			||||||
		val16 |= SRSH_ASPM_L0s_ENB;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
 | 
					 | 
				
			||||||
	w &= ~PCIE_ASPM_ENAB;
 | 
					 | 
				
			||||||
	w |= pi->pcie_war_aspm_ovr;
 | 
					 | 
				
			||||||
	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val16 = bcma_read16(pi->core,
 | 
					 | 
				
			||||||
			    PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
 | 
					 | 
				
			||||||
		val16 |= SRSH_CLKREQ_ENB;
 | 
					 | 
				
			||||||
		pi->pcie_pr42767 = true;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		val16 &= ~SRSH_CLKREQ_ENB;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]),
 | 
					 | 
				
			||||||
		     val16);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Apply the polarity determined at the start */
 | 
					 | 
				
			||||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
 | 
					 | 
				
			||||||
static void pcie_war_serdes(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 w = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pi->pcie_polarity != 0)
 | 
					 | 
				
			||||||
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
 | 
					 | 
				
			||||||
			       pi->pcie_polarity);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
 | 
					 | 
				
			||||||
	if (w & PLL_CTRL_FREQDET_EN) {
 | 
					 | 
				
			||||||
		w &= ~PLL_CTRL_FREQDET_EN;
 | 
					 | 
				
			||||||
		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
 | 
					 | 
				
			||||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
 | 
					 | 
				
			||||||
static void pcie_misc_config_fixup(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u16 val16;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val16 = bcma_read16(pi->core,
 | 
					 | 
				
			||||||
			    PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
 | 
					 | 
				
			||||||
		val16 |= SRSH_L23READY_EXIT_NOPERST;
 | 
					 | 
				
			||||||
		bcma_write16(pi->core,
 | 
					 | 
				
			||||||
			     PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* quick hack for testing */
 | 
					 | 
				
			||||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
 | 
					 | 
				
			||||||
static void pcie_war_noplldown(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* turn off serdes PLL down */
 | 
					 | 
				
			||||||
	ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol),
 | 
					 | 
				
			||||||
		  CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* clear srom shadow backdoor */
 | 
					 | 
				
			||||||
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
 | 
					 | 
				
			||||||
static void pcie_war_pci_setup(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_pub *sih = pi->sih;
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) {
 | 
					 | 
				
			||||||
		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
 | 
					 | 
				
			||||||
				 PCIE_TLP_WORKAROUNDSREG);
 | 
					 | 
				
			||||||
		w |= 0x8;
 | 
					 | 
				
			||||||
		pcie_writereg(pi->core, PCIE_PCIEREGS,
 | 
					 | 
				
			||||||
			      PCIE_TLP_WORKAROUNDSREG, w);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_buscorerev(sih) == 1) {
 | 
					 | 
				
			||||||
		w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
 | 
					 | 
				
			||||||
		w |= 0x40;
 | 
					 | 
				
			||||||
		pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_get_buscorerev(sih) == 0) {
 | 
					 | 
				
			||||||
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
 | 
					 | 
				
			||||||
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
 | 
					 | 
				
			||||||
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
 | 
					 | 
				
			||||||
	} else if (PCIE_ASPM(sih)) {
 | 
					 | 
				
			||||||
		/* Change the L1 threshold for better performance */
 | 
					 | 
				
			||||||
		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
 | 
					 | 
				
			||||||
				 PCIE_DLLP_PMTHRESHREG);
 | 
					 | 
				
			||||||
		w &= ~PCIE_L1THRESHOLDTIME_MASK;
 | 
					 | 
				
			||||||
		w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
 | 
					 | 
				
			||||||
		pcie_writereg(pi->core, PCIE_PCIEREGS,
 | 
					 | 
				
			||||||
			      PCIE_DLLP_PMTHRESHREG, w);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pcie_war_serdes(pi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pcie_war_aspm_clkreq(pi);
 | 
					 | 
				
			||||||
	} else if (ai_get_buscorerev(pi->sih) == 7)
 | 
					 | 
				
			||||||
		pcie_war_noplldown(pi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Note that the fix is actually in the SROM,
 | 
					 | 
				
			||||||
	 * that's why this is open-ended
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (ai_get_buscorerev(pi->sih) >= 6)
 | 
					 | 
				
			||||||
		pcie_misc_config_fixup(pi);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ***** Functions called during driver state changes ***** */
 | 
					 | 
				
			||||||
void pcicore_attach(struct pcicore_info *pi, int state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_pub *sih = pi->sih;
 | 
					 | 
				
			||||||
	u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Determine if this board needs override */
 | 
					 | 
				
			||||||
	if (PCIE_ASPM(sih)) {
 | 
					 | 
				
			||||||
		if (bfl2 & BFL2_PCIEWAR_OVR)
 | 
					 | 
				
			||||||
			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* These need to happen in this order only */
 | 
					 | 
				
			||||||
	pcie_war_polarity(pi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_war_serdes(pi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_war_aspm_clkreq(pi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_clkreq_upd(pi, state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pcicore_hwup(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_war_pci_setup(pi);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pcicore_up(struct pcicore_info *pi, int state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Restore L1 timer for better performance */
 | 
					 | 
				
			||||||
	pcie_extendL1timer(pi, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_clkreq_upd(pi, state);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* When the device is going to enter D3 state
 | 
					 | 
				
			||||||
 * (or the system is going to enter S3/S4 states)
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void pcicore_sleep(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 w;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!pi || !PCIE_ASPM(pi->sih))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
 | 
					 | 
				
			||||||
	w &= ~PCIE_CAP_LCREG_ASPML1;
 | 
					 | 
				
			||||||
	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pi->pcie_pr42767 = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pcicore_down(struct pcicore_info *pi, int state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pcie_clkreq_upd(pi, state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Reduce L1 timer for better power savings */
 | 
					 | 
				
			||||||
	pcie_extendL1timer(pi, false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void pcicore_fixcfg(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bcma_device *core = pi->core;
 | 
					 | 
				
			||||||
	u16 val16;
 | 
					 | 
				
			||||||
	uint regoff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (pi->core->id.id) {
 | 
					 | 
				
			||||||
	case BCMA_CORE_PCI:
 | 
					 | 
				
			||||||
		regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case BCMA_CORE_PCIE:
 | 
					 | 
				
			||||||
		regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val16 = bcma_read16(pi->core, regoff);
 | 
					 | 
				
			||||||
	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
 | 
					 | 
				
			||||||
	    (u16)core->core_index) {
 | 
					 | 
				
			||||||
		val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
 | 
					 | 
				
			||||||
			(val16 & ~SRSH_PI_MASK);
 | 
					 | 
				
			||||||
		bcma_write16(pi->core, regoff, val16);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* precondition: current core is pci core */
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
pcicore_pci_setup(struct pcicore_info *pi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
 | 
					 | 
				
			||||||
		   SBTOPCI_PREF | SBTOPCI_BURST);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pi->core->id.rev >= 11) {
 | 
					 | 
				
			||||||
		bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
 | 
					 | 
				
			||||||
			   SBTOPCI_RC_READMULTI);
 | 
					 | 
				
			||||||
		bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL);
 | 
					 | 
				
			||||||
		(void)bcma_read32(pi->core, PCIREGOFFS(clkrun));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,77 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef	_BRCM_NICPCI_H_
 | 
					 | 
				
			||||||
#define	_BRCM_NICPCI_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "types.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCI configuration address space size */
 | 
					 | 
				
			||||||
#define PCI_SZPCR		256
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Brcm PCI configuration registers */
 | 
					 | 
				
			||||||
/* backplane address space accessed by BAR0 */
 | 
					 | 
				
			||||||
#define PCI_BAR0_WIN		0x80
 | 
					 | 
				
			||||||
/* sprom property control */
 | 
					 | 
				
			||||||
#define PCI_SPROM_CONTROL	0x88
 | 
					 | 
				
			||||||
/* mask of PCI and other cores interrupts */
 | 
					 | 
				
			||||||
#define PCI_INT_MASK		0x94
 | 
					 | 
				
			||||||
/* backplane core interrupt mask bits offset */
 | 
					 | 
				
			||||||
#define  PCI_SBIM_SHIFT		8
 | 
					 | 
				
			||||||
/* backplane address space accessed by second 4KB of BAR0 */
 | 
					 | 
				
			||||||
#define PCI_BAR0_WIN2		0xac
 | 
					 | 
				
			||||||
/* pci config space gpio input (>=rev3) */
 | 
					 | 
				
			||||||
#define PCI_GPIO_IN		0xb0
 | 
					 | 
				
			||||||
/* pci config space gpio output (>=rev3) */
 | 
					 | 
				
			||||||
#define PCI_GPIO_OUT		0xb4
 | 
					 | 
				
			||||||
/* pci config space gpio output enable (>=rev3) */
 | 
					 | 
				
			||||||
#define PCI_GPIO_OUTEN		0xb8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* bar0 + 4K accesses external sprom */
 | 
					 | 
				
			||||||
#define PCI_BAR0_SPROM_OFFSET	(4 * 1024)
 | 
					 | 
				
			||||||
/* bar0 + 6K accesses pci core registers */
 | 
					 | 
				
			||||||
#define PCI_BAR0_PCIREGS_OFFSET	(6 * 1024)
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * pci core SB registers are at the end of the
 | 
					 | 
				
			||||||
 * 8KB window, so their address is the "regular"
 | 
					 | 
				
			||||||
 * address plus 4K
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define PCI_BAR0_PCISBR_OFFSET	(4 * 1024)
 | 
					 | 
				
			||||||
/* bar0 window size Match with corerev 13 */
 | 
					 | 
				
			||||||
#define PCI_BAR0_WINSZ		(16 * 1024)
 | 
					 | 
				
			||||||
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
 | 
					 | 
				
			||||||
/* bar0 + 8K accesses pci/pcie core registers */
 | 
					 | 
				
			||||||
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
 | 
					 | 
				
			||||||
/* bar0 + 12K accesses chipc core registers */
 | 
					 | 
				
			||||||
#define PCI_16KB0_CCREGS_OFFSET	(12 * 1024)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sbpciregs;
 | 
					 | 
				
			||||||
struct sbpcieregs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct pcicore_info *pcicore_init(struct si_pub *sih,
 | 
					 | 
				
			||||||
					 struct bcma_device *core);
 | 
					 | 
				
			||||||
extern void pcicore_deinit(struct pcicore_info *pch);
 | 
					 | 
				
			||||||
extern void pcicore_attach(struct pcicore_info *pch, int state);
 | 
					 | 
				
			||||||
extern void pcicore_hwup(struct pcicore_info *pch);
 | 
					 | 
				
			||||||
extern void pcicore_up(struct pcicore_info *pch, int state);
 | 
					 | 
				
			||||||
extern void pcicore_sleep(struct pcicore_info *pch);
 | 
					 | 
				
			||||||
extern void pcicore_down(struct pcicore_info *pch, int state);
 | 
					 | 
				
			||||||
extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
 | 
					 | 
				
			||||||
				      unsigned char *buf, u32 *buflen);
 | 
					 | 
				
			||||||
extern void pcicore_fixcfg(struct pcicore_info *pch);
 | 
					 | 
				
			||||||
extern void pcicore_pci_setup(struct pcicore_info *pch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _BRCM_NICPCI_H_ */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,410 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/io.h>
 | 
					 | 
				
			||||||
#include <linux/errno.h>
 | 
					 | 
				
			||||||
#include <linux/string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <brcm_hw_ids.h>
 | 
					 | 
				
			||||||
#include <chipcommon.h>
 | 
					 | 
				
			||||||
#include "aiutils.h"
 | 
					 | 
				
			||||||
#include "otp.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OTPS_GUP_MASK		0x00000f00
 | 
					 | 
				
			||||||
#define OTPS_GUP_SHIFT		8
 | 
					 | 
				
			||||||
/* h/w subregion is programmed */
 | 
					 | 
				
			||||||
#define OTPS_GUP_HW		0x00000100
 | 
					 | 
				
			||||||
/* s/w subregion is programmed */
 | 
					 | 
				
			||||||
#define OTPS_GUP_SW		0x00000200
 | 
					 | 
				
			||||||
/* chipid/pkgopt subregion is programmed */
 | 
					 | 
				
			||||||
#define OTPS_GUP_CI		0x00000400
 | 
					 | 
				
			||||||
/* fuse subregion is programmed */
 | 
					 | 
				
			||||||
#define OTPS_GUP_FUSE		0x00000800
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Fields in otpprog in rev >= 21 */
 | 
					 | 
				
			||||||
#define OTPP_COL_MASK		0x000000ff
 | 
					 | 
				
			||||||
#define OTPP_COL_SHIFT		0
 | 
					 | 
				
			||||||
#define OTPP_ROW_MASK		0x0000ff00
 | 
					 | 
				
			||||||
#define OTPP_ROW_SHIFT		8
 | 
					 | 
				
			||||||
#define OTPP_OC_MASK		0x0f000000
 | 
					 | 
				
			||||||
#define OTPP_OC_SHIFT		24
 | 
					 | 
				
			||||||
#define OTPP_READERR		0x10000000
 | 
					 | 
				
			||||||
#define OTPP_VALUE_MASK		0x20000000
 | 
					 | 
				
			||||||
#define OTPP_VALUE_SHIFT	29
 | 
					 | 
				
			||||||
#define OTPP_START_BUSY		0x80000000
 | 
					 | 
				
			||||||
#define	OTPP_READ		0x40000000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Opcodes for OTPP_OC field */
 | 
					 | 
				
			||||||
#define OTPPOC_READ		0
 | 
					 | 
				
			||||||
#define OTPPOC_BIT_PROG		1
 | 
					 | 
				
			||||||
#define OTPPOC_VERIFY		3
 | 
					 | 
				
			||||||
#define OTPPOC_INIT		4
 | 
					 | 
				
			||||||
#define OTPPOC_SET		5
 | 
					 | 
				
			||||||
#define OTPPOC_RESET		6
 | 
					 | 
				
			||||||
#define OTPPOC_OCST		7
 | 
					 | 
				
			||||||
#define OTPPOC_ROW_LOCK		8
 | 
					 | 
				
			||||||
#define OTPPOC_PRESCN_TEST	9
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OTPP_TRIES	10000000	/* # of tries for OTPP */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Fixed size subregions sizes in words */
 | 
					 | 
				
			||||||
#define OTPGU_CI_SZ		2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct otpinfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* OTP function struct */
 | 
					 | 
				
			||||||
struct otp_fn_s {
 | 
					 | 
				
			||||||
	int (*init)(struct si_pub *sih, struct otpinfo *oi);
 | 
					 | 
				
			||||||
	int (*read_region)(struct otpinfo *oi, int region, u16 *data,
 | 
					 | 
				
			||||||
			   uint *wlen);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct otpinfo {
 | 
					 | 
				
			||||||
	struct bcma_device *core; /* chipc core */
 | 
					 | 
				
			||||||
	const struct otp_fn_s *fn;	/* OTP functions */
 | 
					 | 
				
			||||||
	struct si_pub *sih;		/* Saved sb handle */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* IPX OTP section */
 | 
					 | 
				
			||||||
	u16 wsize;		/* Size of otp in words */
 | 
					 | 
				
			||||||
	u16 rows;		/* Geometry */
 | 
					 | 
				
			||||||
	u16 cols;		/* Geometry */
 | 
					 | 
				
			||||||
	u32 status;		/* Flag bits (lock/prog/rv).
 | 
					 | 
				
			||||||
				 * (Reflected only when OTP is power cycled)
 | 
					 | 
				
			||||||
				 */
 | 
					 | 
				
			||||||
	u16 hwbase;		/* hardware subregion offset */
 | 
					 | 
				
			||||||
	u16 hwlim;		/* hardware subregion boundary */
 | 
					 | 
				
			||||||
	u16 swbase;		/* software subregion offset */
 | 
					 | 
				
			||||||
	u16 swlim;		/* software subregion boundary */
 | 
					 | 
				
			||||||
	u16 fbase;		/* fuse subregion offset */
 | 
					 | 
				
			||||||
	u16 flim;		/* fuse subregion boundary */
 | 
					 | 
				
			||||||
	int otpgu_base;		/* offset to General Use Region */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* OTP layout */
 | 
					 | 
				
			||||||
/* CC revs 21, 24 and 27 OTP General Use Region word offset */
 | 
					 | 
				
			||||||
#define REVA4_OTPGU_BASE	12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
 | 
					 | 
				
			||||||
#define REVB8_OTPGU_BASE	20
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* CC rev 36 OTP General Use Region word offset */
 | 
					 | 
				
			||||||
#define REV36_OTPGU_BASE	12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Subregion word offsets in General Use region */
 | 
					 | 
				
			||||||
#define OTPGU_HSB_OFF		0
 | 
					 | 
				
			||||||
#define OTPGU_SFB_OFF		1
 | 
					 | 
				
			||||||
#define OTPGU_CI_OFF		2
 | 
					 | 
				
			||||||
#define OTPGU_P_OFF		3
 | 
					 | 
				
			||||||
#define OTPGU_SROM_OFF		4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Flag bit offsets in General Use region  */
 | 
					 | 
				
			||||||
#define OTPGU_HWP_OFF		60
 | 
					 | 
				
			||||||
#define OTPGU_SWP_OFF		61
 | 
					 | 
				
			||||||
#define OTPGU_CIP_OFF		62
 | 
					 | 
				
			||||||
#define OTPGU_FUSEP_OFF		63
 | 
					 | 
				
			||||||
#define OTPGU_CIP_MSK		0x4000
 | 
					 | 
				
			||||||
#define OTPGU_P_MSK		0xf000
 | 
					 | 
				
			||||||
#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* OTP Size */
 | 
					 | 
				
			||||||
#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
 | 
					 | 
				
			||||||
#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
 | 
					 | 
				
			||||||
#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
 | 
					 | 
				
			||||||
#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
 | 
					 | 
				
			||||||
#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
 | 
					 | 
				
			||||||
#define OTP4315_SWREG_SZ	178	/* 178 bytes */
 | 
					 | 
				
			||||||
#define OTP_SZ_FU_144		(144/8)	/* 144 bits */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static u16
 | 
					 | 
				
			||||||
ipxotp_otpr(struct otpinfo *oi, uint wn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return bcma_read16(oi->core,
 | 
					 | 
				
			||||||
			   CHIPCREGOFFS(sromotp[wn]));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Calculate max HW/SW region byte size by subtracting fuse region
 | 
					 | 
				
			||||||
 * and checksum size, osizew is oi->wsize (OTP size - GU size) in words
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (ai_get_chip_id(sih)) {
 | 
					 | 
				
			||||||
	case BCM43224_CHIP_ID:
 | 
					 | 
				
			||||||
	case BCM43225_CHIP_ID:
 | 
					 | 
				
			||||||
		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case BCM4313_CHIP_ID:
 | 
					 | 
				
			||||||
		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;	/* Don't know about this chip */
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void _ipxotp_init(struct otpinfo *oi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint k;
 | 
					 | 
				
			||||||
	u32 otpp, st;
 | 
					 | 
				
			||||||
	int ccrev = ai_get_ccrev(oi->sih);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * record word offset of General Use Region
 | 
					 | 
				
			||||||
	 * for various chipcommon revs
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (ccrev == 21 || ccrev == 24
 | 
					 | 
				
			||||||
	    || ccrev == 27) {
 | 
					 | 
				
			||||||
		oi->otpgu_base = REVA4_OTPGU_BASE;
 | 
					 | 
				
			||||||
	} else if (ccrev == 36) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * OTP size greater than equal to 2KB (128 words),
 | 
					 | 
				
			||||||
		 * otpgu_base is similar to rev23
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (oi->wsize >= 128)
 | 
					 | 
				
			||||||
			oi->otpgu_base = REVB8_OTPGU_BASE;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			oi->otpgu_base = REV36_OTPGU_BASE;
 | 
					 | 
				
			||||||
	} else if (ccrev == 23 || ccrev >= 25) {
 | 
					 | 
				
			||||||
		oi->otpgu_base = REVB8_OTPGU_BASE;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* First issue an init command so the status is up to date */
 | 
					 | 
				
			||||||
	otpp =
 | 
					 | 
				
			||||||
	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bcma_write32(oi->core, CHIPCREGOFFS(otpprog), otpp);
 | 
					 | 
				
			||||||
	st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
 | 
					 | 
				
			||||||
	for (k = 0; (st & OTPP_START_BUSY) && (k < OTPP_TRIES); k++)
 | 
					 | 
				
			||||||
		st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
 | 
					 | 
				
			||||||
	if (k >= OTPP_TRIES)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Read OTP lock bits and subregion programmed indication bits */
 | 
					 | 
				
			||||||
	oi->status = bcma_read32(oi->core, CHIPCREGOFFS(otpstatus));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((ai_get_chip_id(oi->sih) == BCM43224_CHIP_ID)
 | 
					 | 
				
			||||||
	    || (ai_get_chip_id(oi->sih) == BCM43225_CHIP_ID)) {
 | 
					 | 
				
			||||||
		u32 p_bits;
 | 
					 | 
				
			||||||
		p_bits = (ipxotp_otpr(oi, oi->otpgu_base + OTPGU_P_OFF) &
 | 
					 | 
				
			||||||
			  OTPGU_P_MSK) >> OTPGU_P_SHIFT;
 | 
					 | 
				
			||||||
		oi->status |= (p_bits << OTPS_GUP_SHIFT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * h/w region base and fuse region limit are fixed to
 | 
					 | 
				
			||||||
	 * the top and the bottom of the general use region.
 | 
					 | 
				
			||||||
	 * Everything else can be flexible.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
 | 
					 | 
				
			||||||
	oi->hwlim = oi->wsize;
 | 
					 | 
				
			||||||
	if (oi->status & OTPS_GUP_HW) {
 | 
					 | 
				
			||||||
		oi->hwlim =
 | 
					 | 
				
			||||||
		    ipxotp_otpr(oi, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
 | 
					 | 
				
			||||||
		oi->swbase = oi->hwlim;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		oi->swbase = oi->hwbase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* subtract fuse and checksum from beginning */
 | 
					 | 
				
			||||||
	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (oi->status & OTPS_GUP_SW) {
 | 
					 | 
				
			||||||
		oi->swlim =
 | 
					 | 
				
			||||||
		    ipxotp_otpr(oi, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
 | 
					 | 
				
			||||||
		oi->fbase = oi->swlim;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		oi->fbase = oi->swbase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oi->flim = oi->wsize;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* Make sure we're running IPX OTP */
 | 
					 | 
				
			||||||
	if (!OTPTYPE_IPX(ai_get_ccrev(sih)))
 | 
					 | 
				
			||||||
		return -EBADE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Make sure OTP is not disabled */
 | 
					 | 
				
			||||||
	if (ai_is_otp_disabled(sih))
 | 
					 | 
				
			||||||
		return -EBADE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Check for otp size */
 | 
					 | 
				
			||||||
	switch ((ai_get_cccaps(sih) & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		/* Nothing there */
 | 
					 | 
				
			||||||
		return -EBADE;
 | 
					 | 
				
			||||||
	case 1:		/* 32x64 */
 | 
					 | 
				
			||||||
		oi->rows = 32;
 | 
					 | 
				
			||||||
		oi->cols = 64;
 | 
					 | 
				
			||||||
		oi->wsize = 128;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 2:		/* 64x64 */
 | 
					 | 
				
			||||||
		oi->rows = 64;
 | 
					 | 
				
			||||||
		oi->cols = 64;
 | 
					 | 
				
			||||||
		oi->wsize = 256;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 5:		/* 96x64 */
 | 
					 | 
				
			||||||
		oi->rows = 96;
 | 
					 | 
				
			||||||
		oi->cols = 64;
 | 
					 | 
				
			||||||
		oi->wsize = 384;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 7:		/* 16x64 *//* 1024 bits */
 | 
					 | 
				
			||||||
		oi->rows = 16;
 | 
					 | 
				
			||||||
		oi->cols = 64;
 | 
					 | 
				
			||||||
		oi->wsize = 64;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		/* Don't know the geometry */
 | 
					 | 
				
			||||||
		return -EBADE;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Retrieve OTP region info */
 | 
					 | 
				
			||||||
	_ipxotp_init(oi);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint base, i, sz;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Validate region selection */
 | 
					 | 
				
			||||||
	switch (region) {
 | 
					 | 
				
			||||||
	case OTP_HW_RGN:
 | 
					 | 
				
			||||||
		sz = (uint) oi->hwlim - oi->hwbase;
 | 
					 | 
				
			||||||
		if (!(oi->status & OTPS_GUP_HW)) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (*wlen < sz) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		base = oi->hwbase;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case OTP_SW_RGN:
 | 
					 | 
				
			||||||
		sz = ((uint) oi->swlim - oi->swbase);
 | 
					 | 
				
			||||||
		if (!(oi->status & OTPS_GUP_SW)) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (*wlen < sz) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		base = oi->swbase;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case OTP_CI_RGN:
 | 
					 | 
				
			||||||
		sz = OTPGU_CI_SZ;
 | 
					 | 
				
			||||||
		if (!(oi->status & OTPS_GUP_CI)) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (*wlen < sz) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		base = oi->otpgu_base + OTPGU_CI_OFF;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case OTP_FUSE_RGN:
 | 
					 | 
				
			||||||
		sz = (uint) oi->flim - oi->fbase;
 | 
					 | 
				
			||||||
		if (!(oi->status & OTPS_GUP_FUSE)) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (*wlen < sz) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		base = oi->fbase;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case OTP_ALL_RGN:
 | 
					 | 
				
			||||||
		sz = ((uint) oi->flim - oi->hwbase);
 | 
					 | 
				
			||||||
		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (*wlen < sz) {
 | 
					 | 
				
			||||||
			*wlen = sz;
 | 
					 | 
				
			||||||
			return -EOVERFLOW;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		base = oi->hwbase;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Read the data */
 | 
					 | 
				
			||||||
	for (i = 0; i < sz; i++)
 | 
					 | 
				
			||||||
		data[i] = ipxotp_otpr(oi, base + i);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*wlen = sz;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct otp_fn_s ipxotp_fn = {
 | 
					 | 
				
			||||||
	(int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init,
 | 
					 | 
				
			||||||
	(int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int otp_init(struct si_pub *sih, struct otpinfo *oi)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(oi, 0, sizeof(struct otpinfo));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oi->core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (OTPTYPE_IPX(ai_get_ccrev(sih)))
 | 
					 | 
				
			||||||
		oi->fn = &ipxotp_fn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (oi->fn == NULL)
 | 
					 | 
				
			||||||
		return -EBADE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oi->sih = sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = (oi->fn->init)(sih, oi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
 | 
					 | 
				
			||||||
	struct otpinfo otpinfo;
 | 
					 | 
				
			||||||
	struct otpinfo *oi = &otpinfo;
 | 
					 | 
				
			||||||
	int err = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ai_is_otp_disabled(sih)) {
 | 
					 | 
				
			||||||
		err = -EPERM;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = otp_init(sih, oi);
 | 
					 | 
				
			||||||
	if (err)
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = ((oi)->fn->read_region)(oi, region, data, wlen);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 out:
 | 
					 | 
				
			||||||
	return err;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,36 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef	_BRCM_OTP_H_
 | 
					 | 
				
			||||||
#define	_BRCM_OTP_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "types.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* OTP regions */
 | 
					 | 
				
			||||||
#define OTP_HW_RGN	1
 | 
					 | 
				
			||||||
#define OTP_SW_RGN	2
 | 
					 | 
				
			||||||
#define OTP_CI_RGN	4
 | 
					 | 
				
			||||||
#define OTP_FUSE_RGN	8
 | 
					 | 
				
			||||||
/* From h/w region to end of OTP including checksum */
 | 
					 | 
				
			||||||
#define OTP_ALL_RGN	0xf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* OTP Size */
 | 
					 | 
				
			||||||
#define OTP_SZ_MAX		(6144/8)	/* maximum bytes in one CIS */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
 | 
					 | 
				
			||||||
			   uint *wlen);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif				/* _BRCM_OTP_H_ */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -4817,28 +4817,23 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
	s8 txpwr = 0;
 | 
						s8 txpwr = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
 | 
						struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
 | 
				
			||||||
	struct phy_shim_info *shim = pi->sh->physhim;
 | 
						struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (CHSPEC_IS2G(pi->radio_chanspec)) {
 | 
						if (CHSPEC_IS2G(pi->radio_chanspec)) {
 | 
				
			||||||
		u16 cckpo = 0;
 | 
							u16 cckpo = 0;
 | 
				
			||||||
		u32 offset_ofdm, offset_mcs;
 | 
							u32 offset_ofdm, offset_mcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi_lcn->lcnphy_tr_isolation_mid =
 | 
							pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso;
 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_TRISO2G);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi_lcn->lcnphy_rx_power_offset =
 | 
							pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g;
 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_RXPO2G);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi->txpa_2g[0] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B0);
 | 
							pi->txpa_2g[0] = sprom->pa0b0;
 | 
				
			||||||
		pi->txpa_2g[1] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B1);
 | 
							pi->txpa_2g[1] = sprom->pa0b1;
 | 
				
			||||||
		pi->txpa_2g[2] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B2);
 | 
							pi->txpa_2g[2] = sprom->pa0b2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_vf =
 | 
							pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g;
 | 
				
			||||||
				(u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMF2G);
 | 
							pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g;
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_vc =
 | 
							pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g;
 | 
				
			||||||
				(u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMC2G);
 | 
					 | 
				
			||||||
		pi_lcn->lcnphy_rssi_gs =
 | 
					 | 
				
			||||||
				(u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISAV2G);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
 | 
							pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
 | 
							pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
 | 
				
			||||||
| 
						 | 
					@ -4848,7 +4843,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
 | 
							pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
 | 
				
			||||||
		pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
 | 
							pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		txpwr = (s8)wlapi_getintvar(shim, BRCMS_SROM_MAXP2GA0);
 | 
							txpwr = sprom->core_pwr_info[0].maxpwr_2g;
 | 
				
			||||||
		pi->tx_srom_max_2g = txpwr;
 | 
							pi->tx_srom_max_2g = txpwr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
 | 
							for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
 | 
				
			||||||
| 
						 | 
					@ -4856,8 +4851,8 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
 | 
								pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cckpo = (u16)wlapi_getintvar(shim, BRCMS_SROM_CCK2GPO);
 | 
							cckpo = sprom->cck2gpo;
 | 
				
			||||||
		offset_ofdm = (u32)wlapi_getintvar(shim, BRCMS_SROM_OFDM2GPO);
 | 
							offset_ofdm = sprom->ofdm2gpo;
 | 
				
			||||||
		if (cckpo) {
 | 
							if (cckpo) {
 | 
				
			||||||
			uint max_pwr_chan = txpwr;
 | 
								uint max_pwr_chan = txpwr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4876,7 +4871,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			u8 opo = 0;
 | 
								u8 opo = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			opo = (u8)wlapi_getintvar(shim, BRCMS_SROM_OPO);
 | 
								opo = sprom->opo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
 | 
								for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
 | 
				
			||||||
				pi->tx_srom_max_rate_2g[i] = txpwr;
 | 
									pi->tx_srom_max_rate_2g[i] = txpwr;
 | 
				
			||||||
| 
						 | 
					@ -4886,12 +4881,8 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
						((offset_ofdm & 0xf) * 2);
 | 
											((offset_ofdm & 0xf) * 2);
 | 
				
			||||||
				offset_ofdm >>= 4;
 | 
									offset_ofdm >>= 4;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			offset_mcs =
 | 
								offset_mcs = sprom->mcs2gpo[1] << 16;
 | 
				
			||||||
				wlapi_getintvar(shim,
 | 
								offset_mcs |= sprom->mcs2gpo[0];
 | 
				
			||||||
						BRCMS_SROM_MCS2GPO1) << 16;
 | 
					 | 
				
			||||||
			offset_mcs |=
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO0);
 | 
					 | 
				
			||||||
			pi_lcn->lcnphy_mcs20_po = offset_mcs;
 | 
								pi_lcn->lcnphy_mcs20_po = offset_mcs;
 | 
				
			||||||
			for (i = TXP_FIRST_SISO_MCS_20;
 | 
								for (i = TXP_FIRST_SISO_MCS_20;
 | 
				
			||||||
			     i <= TXP_LAST_SISO_MCS_20; i++) {
 | 
								     i <= TXP_LAST_SISO_MCS_20; i++) {
 | 
				
			||||||
| 
						 | 
					@ -4901,25 +4892,17 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pi_lcn->lcnphy_rawtempsense =
 | 
							pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense;
 | 
				
			||||||
			(u16)wlapi_getintvar(shim, BRCMS_SROM_RAWTEMPSENSE);
 | 
							pi_lcn->lcnphy_measPower = sprom->measpower;
 | 
				
			||||||
		pi_lcn->lcnphy_measPower =
 | 
							pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope;
 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_MEASPOWER);
 | 
							pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en;
 | 
				
			||||||
		pi_lcn->lcnphy_tempsense_slope =
 | 
							pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis;
 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_SLOPE);
 | 
							pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx;
 | 
				
			||||||
		pi_lcn->lcnphy_hw_iqcal_en =
 | 
							pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option;
 | 
				
			||||||
			(bool)wlapi_getintvar(shim, BRCMS_SROM_HW_IQCAL_EN);
 | 
							pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr;
 | 
				
			||||||
		pi_lcn->lcnphy_iqcal_swp_dis =
 | 
							if (sprom->ant_available_bg > 1)
 | 
				
			||||||
			(bool)wlapi_getintvar(shim, BRCMS_SROM_IQCAL_SWP_DIS);
 | 
					 | 
				
			||||||
		pi_lcn->lcnphy_tempcorrx =
 | 
					 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPCORRX);
 | 
					 | 
				
			||||||
		pi_lcn->lcnphy_tempsense_option =
 | 
					 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_OPTION);
 | 
					 | 
				
			||||||
		pi_lcn->lcnphy_freqoffset_corr =
 | 
					 | 
				
			||||||
			(u8)wlapi_getintvar(shim, BRCMS_SROM_FREQOFFSET_CORR);
 | 
					 | 
				
			||||||
		if ((u8)wlapi_getintvar(shim, BRCMS_SROM_AA2G) > 1)
 | 
					 | 
				
			||||||
			wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
 | 
								wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
 | 
				
			||||||
				(u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G));
 | 
									sprom->ant_available_bg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pi_lcn->lcnphy_cck_dig_filt_type = -1;
 | 
						pi_lcn->lcnphy_cck_dig_filt_type = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14386,30 +14386,30 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 bw40po, cddpo, stbcpo, bwduppo;
 | 
						u16 bw40po, cddpo, stbcpo, bwduppo;
 | 
				
			||||||
	uint band_num;
 | 
						uint band_num;
 | 
				
			||||||
	struct phy_shim_info *shim = pi->sh->physhim;
 | 
						struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pi->sh->sromrev >= 9)
 | 
						if (pi->sh->sromrev >= 9)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bw40po = (u16) wlapi_getintvar(shim, BRCMS_SROM_BW40PO);
 | 
						bw40po = sprom->bw40po;
 | 
				
			||||||
	pi->bw402gpo = bw40po & 0xf;
 | 
						pi->bw402gpo = bw40po & 0xf;
 | 
				
			||||||
	pi->bw405gpo = (bw40po & 0xf0) >> 4;
 | 
						pi->bw405gpo = (bw40po & 0xf0) >> 4;
 | 
				
			||||||
	pi->bw405glpo = (bw40po & 0xf00) >> 8;
 | 
						pi->bw405glpo = (bw40po & 0xf00) >> 8;
 | 
				
			||||||
	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
 | 
						pi->bw405ghpo = (bw40po & 0xf000) >> 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cddpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_CDDPO);
 | 
						cddpo = sprom->cddpo;
 | 
				
			||||||
	pi->cdd2gpo = cddpo & 0xf;
 | 
						pi->cdd2gpo = cddpo & 0xf;
 | 
				
			||||||
	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
 | 
						pi->cdd5gpo = (cddpo & 0xf0) >> 4;
 | 
				
			||||||
	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
 | 
						pi->cdd5glpo = (cddpo & 0xf00) >> 8;
 | 
				
			||||||
	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
 | 
						pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stbcpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_STBCPO);
 | 
						stbcpo = sprom->stbcpo;
 | 
				
			||||||
	pi->stbc2gpo = stbcpo & 0xf;
 | 
						pi->stbc2gpo = stbcpo & 0xf;
 | 
				
			||||||
	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
 | 
						pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
 | 
				
			||||||
	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
 | 
						pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
 | 
				
			||||||
	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
 | 
						pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bwduppo = (u16) wlapi_getintvar(shim, BRCMS_SROM_BWDUPPO);
 | 
						bwduppo = sprom->bwduppo;
 | 
				
			||||||
	pi->bwdup2gpo = bwduppo & 0xf;
 | 
						pi->bwdup2gpo = bwduppo & 0xf;
 | 
				
			||||||
	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
 | 
						pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
 | 
				
			||||||
	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
 | 
						pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
 | 
				
			||||||
| 
						 | 
					@ -14419,242 +14419,137 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
 | 
				
			||||||
	     band_num++) {
 | 
						     band_num++) {
 | 
				
			||||||
		switch (band_num) {
 | 
							switch (band_num) {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].maxpwr_2g;
 | 
				
			||||||
						     BRCMS_SROM_MAXP2GA0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].maxpwr_2g;
 | 
				
			||||||
						     BRCMS_SROM_MAXP2GA1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_2g[0];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW0A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_2g[0];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW0A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_2g[1];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW1A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_2g[1];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW1A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_2g[2];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW2A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_2g[2];
 | 
				
			||||||
						      BRCMS_SROM_PA2GW2A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA0);
 | 
									sprom->core_pwr_info[0].itssi_2g;
 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA1);
 | 
									sprom->core_pwr_info[1].itssi_2g;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->cck2gpo = (u16) wlapi_getintvar(shim,
 | 
								pi->cck2gpo = sprom->cck2gpo;
 | 
				
			||||||
							    BRCMS_SROM_CCK2GPO);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->ofdm2gpo =
 | 
								pi->ofdm2gpo = sprom->ofdm2gpo;
 | 
				
			||||||
				(u32) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_OFDM2GPO);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->mcs2gpo[0] =
 | 
								pi->mcs2gpo[0] = sprom->mcs2gpo[0];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs2gpo[1] = sprom->mcs2gpo[1];
 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO0);
 | 
								pi->mcs2gpo[2] = sprom->mcs2gpo[2];
 | 
				
			||||||
			pi->mcs2gpo[1] =
 | 
								pi->mcs2gpo[3] = sprom->mcs2gpo[3];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs2gpo[4] = sprom->mcs2gpo[4];
 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO1);
 | 
								pi->mcs2gpo[5] = sprom->mcs2gpo[5];
 | 
				
			||||||
			pi->mcs2gpo[2] =
 | 
								pi->mcs2gpo[6] = sprom->mcs2gpo[6];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs2gpo[7] = sprom->mcs2gpo[7];
 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO2);
 | 
					 | 
				
			||||||
			pi->mcs2gpo[3] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO3);
 | 
					 | 
				
			||||||
			pi->mcs2gpo[4] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO4);
 | 
					 | 
				
			||||||
			pi->mcs2gpo[5] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO5);
 | 
					 | 
				
			||||||
			pi->mcs2gpo[6] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO6);
 | 
					 | 
				
			||||||
			pi->mcs2gpo[7] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS2GPO7);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0);
 | 
									sprom->core_pwr_info[0].maxpwr_5g;
 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].maxpwr_5g;
 | 
				
			||||||
						     BRCMS_SROM_MAXP5GA1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5g[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW0A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5g[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW0A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5g[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW1A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5g[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW1A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5g[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW2A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5g[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GW2A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA0);
 | 
									sprom->core_pwr_info[0].itssi_5g;
 | 
				
			||||||
			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
 | 
								pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA1);
 | 
									sprom->core_pwr_info[1].itssi_5g;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->ofdm5gpo =
 | 
								pi->ofdm5gpo = sprom->ofdm5gpo;
 | 
				
			||||||
				(u32) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_OFDM5GPO);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->mcs5gpo[0] =
 | 
								pi->mcs5gpo[0] = sprom->mcs5gpo[0];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5gpo[1] = sprom->mcs5gpo[1];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO0);
 | 
								pi->mcs5gpo[2] = sprom->mcs5gpo[2];
 | 
				
			||||||
			pi->mcs5gpo[1] =
 | 
								pi->mcs5gpo[3] = sprom->mcs5gpo[3];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5gpo[4] = sprom->mcs5gpo[4];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO1);
 | 
								pi->mcs5gpo[5] = sprom->mcs5gpo[5];
 | 
				
			||||||
			pi->mcs5gpo[2] =
 | 
								pi->mcs5gpo[6] = sprom->mcs5gpo[6];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5gpo[7] = sprom->mcs5gpo[7];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO2);
 | 
					 | 
				
			||||||
			pi->mcs5gpo[3] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO3);
 | 
					 | 
				
			||||||
			pi->mcs5gpo[4] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO4);
 | 
					 | 
				
			||||||
			pi->mcs5gpo[5] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO5);
 | 
					 | 
				
			||||||
			pi->mcs5gpo[6] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO6);
 | 
					 | 
				
			||||||
			pi->mcs5gpo[7] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GPO7);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
 | 
								pi->nphy_pwrctrl_info[0].max_pwr_5gl =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].maxpwr_5gl;
 | 
				
			||||||
						     BRCMS_SROM_MAXP5GLA0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
 | 
								pi->nphy_pwrctrl_info[1].max_pwr_5gl =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].maxpwr_5gl;
 | 
				
			||||||
						     BRCMS_SROM_MAXP5GLA1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gl[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW0A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gl[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW0A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gl[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW1A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gl[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW1A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gl[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW2A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gl[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GLW2A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
 | 
								pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
 | 
								pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->ofdm5glpo =
 | 
								pi->ofdm5glpo = sprom->ofdm5glpo;
 | 
				
			||||||
				(u32) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_OFDM5GLPO);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->mcs5glpo[0] =
 | 
								pi->mcs5glpo[0] = sprom->mcs5glpo[0];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5glpo[1] = sprom->mcs5glpo[1];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO0);
 | 
								pi->mcs5glpo[2] = sprom->mcs5glpo[2];
 | 
				
			||||||
			pi->mcs5glpo[1] =
 | 
								pi->mcs5glpo[3] = sprom->mcs5glpo[3];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5glpo[4] = sprom->mcs5glpo[4];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO1);
 | 
								pi->mcs5glpo[5] = sprom->mcs5glpo[5];
 | 
				
			||||||
			pi->mcs5glpo[2] =
 | 
								pi->mcs5glpo[6] = sprom->mcs5glpo[6];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5glpo[7] = sprom->mcs5glpo[7];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO2);
 | 
					 | 
				
			||||||
			pi->mcs5glpo[3] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO3);
 | 
					 | 
				
			||||||
			pi->mcs5glpo[4] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO4);
 | 
					 | 
				
			||||||
			pi->mcs5glpo[5] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO5);
 | 
					 | 
				
			||||||
			pi->mcs5glpo[6] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO6);
 | 
					 | 
				
			||||||
			pi->mcs5glpo[7] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GLPO7);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 3:
 | 
							case 3:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
 | 
								pi->nphy_pwrctrl_info[0].max_pwr_5gh =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].maxpwr_5gh;
 | 
				
			||||||
						     BRCMS_SROM_MAXP5GHA0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
 | 
								pi->nphy_pwrctrl_info[1].max_pwr_5gh =
 | 
				
			||||||
				(s8) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].maxpwr_5gh;
 | 
				
			||||||
						     BRCMS_SROM_MAXP5GHA1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gh[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW0A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gh[0];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW0A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gh[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW1A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gh[1];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW1A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
 | 
								pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[0].pa_5gh[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW2A0);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
 | 
								pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
 | 
				
			||||||
				(s16) wlapi_getintvar(shim,
 | 
									sprom->core_pwr_info[1].pa_5gh[2];
 | 
				
			||||||
						      BRCMS_SROM_PA5GHW2A1);
 | 
					 | 
				
			||||||
			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
 | 
								pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
 | 
				
			||||||
			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
 | 
								pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->ofdm5ghpo =
 | 
								pi->ofdm5ghpo = sprom->ofdm5ghpo;
 | 
				
			||||||
				(u32) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_OFDM5GHPO);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pi->mcs5ghpo[0] =
 | 
								pi->mcs5ghpo[0] = sprom->mcs5ghpo[0];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5ghpo[1] = sprom->mcs5ghpo[1];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO0);
 | 
								pi->mcs5ghpo[2] = sprom->mcs5ghpo[2];
 | 
				
			||||||
			pi->mcs5ghpo[1] =
 | 
								pi->mcs5ghpo[3] = sprom->mcs5ghpo[3];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5ghpo[4] = sprom->mcs5ghpo[4];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO1);
 | 
								pi->mcs5ghpo[5] = sprom->mcs5ghpo[5];
 | 
				
			||||||
			pi->mcs5ghpo[2] =
 | 
								pi->mcs5ghpo[6] = sprom->mcs5ghpo[6];
 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
								pi->mcs5ghpo[7] = sprom->mcs5ghpo[7];
 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO2);
 | 
					 | 
				
			||||||
			pi->mcs5ghpo[3] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO3);
 | 
					 | 
				
			||||||
			pi->mcs5ghpo[4] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO4);
 | 
					 | 
				
			||||||
			pi->mcs5ghpo[5] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO5);
 | 
					 | 
				
			||||||
			pi->mcs5ghpo[6] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO6);
 | 
					 | 
				
			||||||
			pi->mcs5ghpo[7] =
 | 
					 | 
				
			||||||
				(u16) wlapi_getintvar(shim,
 | 
					 | 
				
			||||||
						      BRCMS_SROM_MCS5GHPO7);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -14664,45 +14559,34 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
 | 
					static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct phy_shim_info *shim = pi->sh->physhim;
 | 
						struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->antswitch = (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWITCH);
 | 
						pi->antswitch = sprom->antswitch;
 | 
				
			||||||
	pi->aa2g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G);
 | 
						pi->aa2g = sprom->ant_available_bg;
 | 
				
			||||||
	pi->aa5g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA5G);
 | 
						pi->aa5g = sprom->ant_available_a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->srom_fem2g.tssipos = (u8) wlapi_getintvar(shim,
 | 
						pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos;
 | 
				
			||||||
						      BRCMS_SROM_TSSIPOS2G);
 | 
						pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain;
 | 
				
			||||||
	pi->srom_fem2g.extpagain = (u8) wlapi_getintvar(shim,
 | 
						pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range;
 | 
				
			||||||
							BRCMS_SROM_EXTPAGAIN2G);
 | 
						pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso;
 | 
				
			||||||
	pi->srom_fem2g.pdetrange = (u8) wlapi_getintvar(shim,
 | 
						pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut;
 | 
				
			||||||
							BRCMS_SROM_PDETRANGE2G);
 | 
					 | 
				
			||||||
	pi->srom_fem2g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO2G);
 | 
					 | 
				
			||||||
	pi->srom_fem2g.antswctrllut =
 | 
					 | 
				
			||||||
			(u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->srom_fem5g.tssipos = (u8) wlapi_getintvar(shim,
 | 
						pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos;
 | 
				
			||||||
						      BRCMS_SROM_TSSIPOS5G);
 | 
						pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain;
 | 
				
			||||||
	pi->srom_fem5g.extpagain = (u8) wlapi_getintvar(shim,
 | 
						pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range;
 | 
				
			||||||
							BRCMS_SROM_EXTPAGAIN5G);
 | 
						pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso;
 | 
				
			||||||
	pi->srom_fem5g.pdetrange = (u8) wlapi_getintvar(shim,
 | 
						if (sprom->fem.ghz5.antswlut)
 | 
				
			||||||
							BRCMS_SROM_PDETRANGE5G);
 | 
							pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut;
 | 
				
			||||||
	pi->srom_fem5g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO5G);
 | 
					 | 
				
			||||||
	if (wlapi_getvar(shim, BRCMS_SROM_ANTSWCTL5G))
 | 
					 | 
				
			||||||
		pi->srom_fem5g.antswctrllut =
 | 
					 | 
				
			||||||
			(u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL5G);
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		pi->srom_fem5g.antswctrllut =
 | 
							pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut;
 | 
				
			||||||
			(u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlc_phy_txpower_ipa_upd(pi);
 | 
						wlc_phy_txpower_ipa_upd(pi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->phy_txcore_disable_temp =
 | 
						pi->phy_txcore_disable_temp = sprom->tempthresh;
 | 
				
			||||||
			(s16) wlapi_getintvar(shim, BRCMS_SROM_TEMPTHRESH);
 | 
					 | 
				
			||||||
	if (pi->phy_txcore_disable_temp == 0)
 | 
						if (pi->phy_txcore_disable_temp == 0)
 | 
				
			||||||
		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
 | 
							pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->phy_tempsense_offset = (s8) wlapi_getintvar(shim,
 | 
						pi->phy_tempsense_offset = sprom->tempoffset;
 | 
				
			||||||
							BRCMS_SROM_TEMPOFFSET);
 | 
					 | 
				
			||||||
	if (pi->phy_tempsense_offset != 0) {
 | 
						if (pi->phy_tempsense_offset != 0) {
 | 
				
			||||||
		if (pi->phy_tempsense_offset >
 | 
							if (pi->phy_tempsense_offset >
 | 
				
			||||||
		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
 | 
							    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
 | 
				
			||||||
| 
						 | 
					@ -14717,8 +14601,7 @@ static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
 | 
				
			||||||
	pi->phy_txcore_enable_temp =
 | 
						pi->phy_txcore_enable_temp =
 | 
				
			||||||
		pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
 | 
							pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pi->phycal_tempdelta =
 | 
						pi->phycal_tempdelta = sprom->phycal_tempdelta;
 | 
				
			||||||
			(u8) wlapi_getintvar(shim, BRCMS_SROM_PHYCAL_TEMPDELTA);
 | 
					 | 
				
			||||||
	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
 | 
						if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
 | 
				
			||||||
		pi->phycal_tempdelta = 0;
 | 
							pi->phycal_tempdelta = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21460,7 +21343,7 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
 | 
				
			||||||
		write_phy_reg(pi, 0xc8, 0x0);
 | 
							write_phy_reg(pi, 0xc8, 0x0);
 | 
				
			||||||
		write_phy_reg(pi, 0xc9, 0x0);
 | 
							write_phy_reg(pi, 0xc9, 0x0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
 | 
							bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
 | 
							mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
 | 
				
			||||||
		mc &= ~MCTL_GPOUT_SEL_MASK;
 | 
							mc &= ~MCTL_GPOUT_SEL_MASK;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -214,12 +214,3 @@ wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
 | 
						brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return getvar(physhim->wlc_hw->sih, id);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return getintvar(physhim->wlc_hw->sih, id);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,8 +175,5 @@ extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
 | 
				
			||||||
extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
 | 
					extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
 | 
				
			||||||
				       u32 phy_mode);
 | 
									       u32 phy_mode);
 | 
				
			||||||
extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
 | 
					extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
 | 
				
			||||||
extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id);
 | 
					 | 
				
			||||||
extern int wlapi_getintvar(struct phy_shim_info *physhim,
 | 
					 | 
				
			||||||
			   enum brcms_srom_id id);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif				/* _BRCM_PHY_SHIM_H_ */
 | 
					#endif				/* _BRCM_PHY_SHIM_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,232 +22,6 @@
 | 
				
			||||||
#include "types.h"
 | 
					#include "types.h"
 | 
				
			||||||
#include "defs.h"
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum brcms_srom_id {
 | 
					 | 
				
			||||||
	BRCMS_SROM_NULL,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CONT,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AA2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AA5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AG0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AG1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AG2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_AG3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ANTSWCTL2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ANTSWCTL5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ANTSWITCH,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BOARDFLAGS2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BOARDFLAGS,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BOARDNUM,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BOARDREV,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BOARDTYPE,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BW40PO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BWDUPPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BXA2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_BXA5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CC,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CCK2GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CCKBW202GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CCKBW20UL2GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CCODE,
 | 
					 | 
				
			||||||
	BRCMS_SROM_CDDPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_DEVID,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ET1MACADDR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_EXTPAGAIN2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_EXTPAGAIN5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_FREQOFFSET_CORR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_HW_IQCAL_EN,
 | 
					 | 
				
			||||||
	BRCMS_SROM_IL0MACADDR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_IQCAL_SWP_DIS,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEDBH0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEDBH1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEDBH2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEDBH3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEDDC,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDM40DUPPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW202GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW205GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW205GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW205GMPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW20UL2GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW20UL5GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW20UL5GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_LEGOFDMBW20UL5GMPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MACADDR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO4,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO5,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO6,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS2GPO7,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS32PO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO4,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO5,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO6,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GHPO7,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO4,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO5,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO6,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GLPO7,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO4,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO5,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO6,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCS5GPO7,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW202GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW205GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW205GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW205GMPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW20UL2GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW20UL5GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW20UL5GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW20UL5GMPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW402GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW405GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW405GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MCSBW405GMPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MEASPOWER,
 | 
					 | 
				
			||||||
	BRCMS_SROM_OFDM2GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_OFDM5GHPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_OFDM5GLPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_OFDM5GPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_OPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA0B0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA0B1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA0B2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA0ITSSIT,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA0MAXPWR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1B0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1B1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1B2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1HIB0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1HIB1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1HIB2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1HIMAXPWR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1ITSSIT,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1LOB0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1LOB1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1LOB2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1LOMAXPWR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA1MAXPWR,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PDETRANGE2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PDETRANGE5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PHYCAL_TEMPDELTA,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RAWTEMPSENSE,
 | 
					 | 
				
			||||||
	BRCMS_SROM_REGREV,
 | 
					 | 
				
			||||||
	BRCMS_SROM_REV,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISAV2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISAV5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISMC2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISMC5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISMF2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RSSISMF5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RXCHAIN,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RXPO2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_RXPO5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_STBCPO,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TEMPCORRX,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TEMPOFFSET,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TEMPSENSE_OPTION,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TEMPSENSE_SLOPE,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TEMPTHRESH,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRI2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRI5GH,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRI5GL,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRI5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRISO2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TRISO5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TSSIPOS2G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TSSIPOS5G,
 | 
					 | 
				
			||||||
	BRCMS_SROM_TXCHAIN,
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * per-path identifiers (see srom.c)
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT2GA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT2GA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT2GA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT2GA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT5GA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT5GA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT5GA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_ITT5GA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP2GA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP2GA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP2GA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP2GA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GHA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GHA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GHA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GHA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GLA0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GLA1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GLA2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_MAXP5GLA3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW0A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW0A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW0A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW0A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW1A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW1A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW1A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW1A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW2A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW2A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW2A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA2GW2A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW0A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW0A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW0A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW0A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW1A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW1A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW1A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW1A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW2A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW2A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW2A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GHW2A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW0A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW0A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW0A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW0A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW1A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW1A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW1A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW1A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW2A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW2A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW2A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GLW2A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW0A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW0A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW0A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW0A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW1A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW1A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW1A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW1A3,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW2A0,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW2A1,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW2A2,
 | 
					 | 
				
			||||||
	BRCMS_SROM_PA5GW2A3,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	BRCMS_NUMRATES	16	/* max # of rates in a rateset */
 | 
					#define	BRCMS_NUMRATES	16	/* max # of rates in a rateset */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* phy types */
 | 
					/* phy types */
 | 
				
			||||||
| 
						 | 
					@ -565,8 +339,6 @@ extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
 | 
				
			||||||
			    struct ieee80211_sta *sta, u16 tid);
 | 
								    struct ieee80211_sta *sta, u16 tid);
 | 
				
			||||||
extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
 | 
					extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
 | 
				
			||||||
					 u8 ba_wsize, uint max_rx_ampdu_bytes);
 | 
										 u8 ba_wsize, uint max_rx_ampdu_bytes);
 | 
				
			||||||
extern char *getvar(struct si_pub *sih, enum brcms_srom_id id);
 | 
					 | 
				
			||||||
extern int getintvar(struct si_pub *sih, enum brcms_srom_id id);
 | 
					 | 
				
			||||||
extern int brcms_c_module_register(struct brcms_pub *pub,
 | 
					extern int brcms_c_module_register(struct brcms_pub *pub,
 | 
				
			||||||
				   const char *name, struct brcms_info *hdl,
 | 
									   const char *name, struct brcms_info *hdl,
 | 
				
			||||||
				   int (*down_fn)(void *handle));
 | 
									   int (*down_fn)(void *handle));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,980 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/kernel.h>
 | 
					 | 
				
			||||||
#include <linux/string.h>
 | 
					 | 
				
			||||||
#include <linux/io.h>
 | 
					 | 
				
			||||||
#include <linux/etherdevice.h>
 | 
					 | 
				
			||||||
#include <linux/crc8.h>
 | 
					 | 
				
			||||||
#include <stdarg.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <chipcommon.h>
 | 
					 | 
				
			||||||
#include <brcmu_utils.h>
 | 
					 | 
				
			||||||
#include "pub.h"
 | 
					 | 
				
			||||||
#include "nicpci.h"
 | 
					 | 
				
			||||||
#include "aiutils.h"
 | 
					 | 
				
			||||||
#include "otp.h"
 | 
					 | 
				
			||||||
#include "srom.h"
 | 
					 | 
				
			||||||
#include "soc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * SROM CRC8 polynomial value:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * x^8 + x^7 +x^6 + x^4 + x^2 + 1
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SROM_CRC8_POLY		0xAB
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Maximum srom: 6 Kilobits == 768 bytes */
 | 
					 | 
				
			||||||
#define	SROM_MAX		768
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PCI fields */
 | 
					 | 
				
			||||||
#define PCI_F0DEVID		48
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WORDS		64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_SSID		2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL1LHMAXP		29
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL1LPAB0		30
 | 
					 | 
				
			||||||
#define	SROM_WL1LPAB1		31
 | 
					 | 
				
			||||||
#define	SROM_WL1LPAB2		32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL1HPAB0		33
 | 
					 | 
				
			||||||
#define	SROM_WL1HPAB1		34
 | 
					 | 
				
			||||||
#define	SROM_WL1HPAB2		35
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_MACHI_IL0		36
 | 
					 | 
				
			||||||
#define	SROM_MACMID_IL0		37
 | 
					 | 
				
			||||||
#define	SROM_MACLO_IL0		38
 | 
					 | 
				
			||||||
#define	SROM_MACHI_ET1		42
 | 
					 | 
				
			||||||
#define	SROM_MACMID_ET1		43
 | 
					 | 
				
			||||||
#define	SROM_MACLO_ET1		44
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_BXARSSI2G		40
 | 
					 | 
				
			||||||
#define	SROM_BXARSSI5G		41
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_TRI52G		42
 | 
					 | 
				
			||||||
#define	SROM_TRI5GHL		43
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_RXPO52G		45
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_AABREV		46
 | 
					 | 
				
			||||||
/* Fields in AABREV */
 | 
					 | 
				
			||||||
#define	SROM_BR_MASK		0x00ff
 | 
					 | 
				
			||||||
#define	SROM_CC_MASK		0x0f00
 | 
					 | 
				
			||||||
#define	SROM_CC_SHIFT		8
 | 
					 | 
				
			||||||
#define	SROM_AA0_MASK		0x3000
 | 
					 | 
				
			||||||
#define	SROM_AA0_SHIFT		12
 | 
					 | 
				
			||||||
#define	SROM_AA1_MASK		0xc000
 | 
					 | 
				
			||||||
#define	SROM_AA1_SHIFT		14
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL0PAB0		47
 | 
					 | 
				
			||||||
#define	SROM_WL0PAB1		48
 | 
					 | 
				
			||||||
#define	SROM_WL0PAB2		49
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_LEDBH10		50
 | 
					 | 
				
			||||||
#define	SROM_LEDBH32		51
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL10MAXP		52
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_WL1PAB0		53
 | 
					 | 
				
			||||||
#define	SROM_WL1PAB1		54
 | 
					 | 
				
			||||||
#define	SROM_WL1PAB2		55
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_ITT		56
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_BFL		57
 | 
					 | 
				
			||||||
#define	SROM_BFL2		28
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_AG10		58
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_CCODE		59
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_OPO		60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM_CRCREV		63
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM4_WORDS		220
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM4_TXCHAIN_MASK	0x000f
 | 
					 | 
				
			||||||
#define SROM4_RXCHAIN_MASK	0x00f0
 | 
					 | 
				
			||||||
#define SROM4_SWITCH_MASK	0xff00
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Per-path fields */
 | 
					 | 
				
			||||||
#define	MAX_PATH_SROM		4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM4_CRCREV		219
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
 | 
					 | 
				
			||||||
 * This is acombined srom for both MIMO and SISO boards, usable in
 | 
					 | 
				
			||||||
 * the .130 4Kilobit OTP with hardware redundancy.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define	SROM8_BREV		65
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_BFL0		66
 | 
					 | 
				
			||||||
#define	SROM8_BFL1		67
 | 
					 | 
				
			||||||
#define	SROM8_BFL2		68
 | 
					 | 
				
			||||||
#define	SROM8_BFL3		69
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_MACHI		70
 | 
					 | 
				
			||||||
#define	SROM8_MACMID		71
 | 
					 | 
				
			||||||
#define	SROM8_MACLO		72
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_CCODE		73
 | 
					 | 
				
			||||||
#define	SROM8_REGREV		74
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_LEDBH10		75
 | 
					 | 
				
			||||||
#define	SROM8_LEDBH32		76
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_LEDDC		77
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_AA		78
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_AG10		79
 | 
					 | 
				
			||||||
#define	SROM8_AG32		80
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_TXRXC		81
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_BXARSSI2G		82
 | 
					 | 
				
			||||||
#define	SROM8_BXARSSI5G		83
 | 
					 | 
				
			||||||
#define	SROM8_TRI52G		84
 | 
					 | 
				
			||||||
#define	SROM8_TRI5GHL		85
 | 
					 | 
				
			||||||
#define	SROM8_RXPO52G		86
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM8_FEM2G		87
 | 
					 | 
				
			||||||
#define SROM8_FEM5G		88
 | 
					 | 
				
			||||||
#define SROM8_FEM_ANTSWLUT_MASK		0xf800
 | 
					 | 
				
			||||||
#define SROM8_FEM_ANTSWLUT_SHIFT	11
 | 
					 | 
				
			||||||
#define SROM8_FEM_TR_ISO_MASK		0x0700
 | 
					 | 
				
			||||||
#define SROM8_FEM_TR_ISO_SHIFT		8
 | 
					 | 
				
			||||||
#define SROM8_FEM_PDET_RANGE_MASK	0x00f8
 | 
					 | 
				
			||||||
#define SROM8_FEM_PDET_RANGE_SHIFT	3
 | 
					 | 
				
			||||||
#define SROM8_FEM_EXTPA_GAIN_MASK	0x0006
 | 
					 | 
				
			||||||
#define SROM8_FEM_EXTPA_GAIN_SHIFT	1
 | 
					 | 
				
			||||||
#define SROM8_FEM_TSSIPOS_MASK		0x0001
 | 
					 | 
				
			||||||
#define SROM8_FEM_TSSIPOS_SHIFT		0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM8_THERMAL		89
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Temp sense related entries */
 | 
					 | 
				
			||||||
#define SROM8_MPWR_RAWTS		90
 | 
					 | 
				
			||||||
#define SROM8_TS_SLP_OPT_CORRX	91
 | 
					 | 
				
			||||||
/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable,
 | 
					 | 
				
			||||||
 * IQSWP: IQ CAL swap disable */
 | 
					 | 
				
			||||||
#define SROM8_FOC_HWIQ_IQSWP	92
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Temperature delta for PHY calibration */
 | 
					 | 
				
			||||||
#define SROM8_PHYCAL_TEMPDELTA	93
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Per-path offsets & fields */
 | 
					 | 
				
			||||||
#define	SROM8_PATH0		96
 | 
					 | 
				
			||||||
#define	SROM8_PATH1		112
 | 
					 | 
				
			||||||
#define	SROM8_PATH2		128
 | 
					 | 
				
			||||||
#define	SROM8_PATH3		144
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_2G_ITT_MAXP	0
 | 
					 | 
				
			||||||
#define	SROM8_2G_PA		1
 | 
					 | 
				
			||||||
#define	SROM8_5G_ITT_MAXP	4
 | 
					 | 
				
			||||||
#define	SROM8_5GLH_MAXP		5
 | 
					 | 
				
			||||||
#define	SROM8_5G_PA		6
 | 
					 | 
				
			||||||
#define	SROM8_5GL_PA		9
 | 
					 | 
				
			||||||
#define	SROM8_5GH_PA		12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* All the miriad power offsets */
 | 
					 | 
				
			||||||
#define	SROM8_2G_CCKPO		160
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_2G_OFDMPO		161
 | 
					 | 
				
			||||||
#define	SROM8_5G_OFDMPO		163
 | 
					 | 
				
			||||||
#define	SROM8_5GL_OFDMPO	165
 | 
					 | 
				
			||||||
#define	SROM8_5GH_OFDMPO	167
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_2G_MCSPO		169
 | 
					 | 
				
			||||||
#define	SROM8_5G_MCSPO		177
 | 
					 | 
				
			||||||
#define	SROM8_5GL_MCSPO		185
 | 
					 | 
				
			||||||
#define	SROM8_5GH_MCSPO		193
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define	SROM8_CDDPO		201
 | 
					 | 
				
			||||||
#define	SROM8_STBCPO		202
 | 
					 | 
				
			||||||
#define	SROM8_BW40PO		203
 | 
					 | 
				
			||||||
#define	SROM8_BWDUPPO		204
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SISO PA parameters are in the path0 spaces */
 | 
					 | 
				
			||||||
#define	SROM8_SISO		96
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Legacy names for SISO PA paramters */
 | 
					 | 
				
			||||||
#define	SROM8_W0_ITTMAXP	(SROM8_SISO + SROM8_2G_ITT_MAXP)
 | 
					 | 
				
			||||||
#define	SROM8_W0_PAB0		(SROM8_SISO + SROM8_2G_PA)
 | 
					 | 
				
			||||||
#define	SROM8_W0_PAB1		(SROM8_SISO + SROM8_2G_PA + 1)
 | 
					 | 
				
			||||||
#define	SROM8_W0_PAB2		(SROM8_SISO + SROM8_2G_PA + 2)
 | 
					 | 
				
			||||||
#define	SROM8_W1_ITTMAXP	(SROM8_SISO + SROM8_5G_ITT_MAXP)
 | 
					 | 
				
			||||||
#define	SROM8_W1_MAXP_LCHC	(SROM8_SISO + SROM8_5GLH_MAXP)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB0		(SROM8_SISO + SROM8_5G_PA)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB1		(SROM8_SISO + SROM8_5G_PA + 1)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB2		(SROM8_SISO + SROM8_5G_PA + 2)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB0_LC	(SROM8_SISO + SROM8_5GL_PA)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB1_LC	(SROM8_SISO + SROM8_5GL_PA + 1)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB2_LC	(SROM8_SISO + SROM8_5GL_PA + 2)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB0_HC	(SROM8_SISO + SROM8_5GH_PA)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB1_HC	(SROM8_SISO + SROM8_5GH_PA + 1)
 | 
					 | 
				
			||||||
#define	SROM8_W1_PAB2_HC	(SROM8_SISO + SROM8_5GH_PA + 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SROM REV 9 */
 | 
					 | 
				
			||||||
#define SROM9_2GPO_CCKBW20	160
 | 
					 | 
				
			||||||
#define SROM9_2GPO_CCKBW20UL	161
 | 
					 | 
				
			||||||
#define SROM9_2GPO_LOFDMBW20	162
 | 
					 | 
				
			||||||
#define SROM9_2GPO_LOFDMBW20UL	164
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM9_5GLPO_LOFDMBW20	166
 | 
					 | 
				
			||||||
#define SROM9_5GLPO_LOFDMBW20UL	168
 | 
					 | 
				
			||||||
#define SROM9_5GMPO_LOFDMBW20	170
 | 
					 | 
				
			||||||
#define SROM9_5GMPO_LOFDMBW20UL	172
 | 
					 | 
				
			||||||
#define SROM9_5GHPO_LOFDMBW20	174
 | 
					 | 
				
			||||||
#define SROM9_5GHPO_LOFDMBW20UL	176
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM9_2GPO_MCSBW20	178
 | 
					 | 
				
			||||||
#define SROM9_2GPO_MCSBW20UL	180
 | 
					 | 
				
			||||||
#define SROM9_2GPO_MCSBW40	182
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM9_5GLPO_MCSBW20	184
 | 
					 | 
				
			||||||
#define SROM9_5GLPO_MCSBW20UL	186
 | 
					 | 
				
			||||||
#define SROM9_5GLPO_MCSBW40	188
 | 
					 | 
				
			||||||
#define SROM9_5GMPO_MCSBW20	190
 | 
					 | 
				
			||||||
#define SROM9_5GMPO_MCSBW20UL	192
 | 
					 | 
				
			||||||
#define SROM9_5GMPO_MCSBW40	194
 | 
					 | 
				
			||||||
#define SROM9_5GHPO_MCSBW20	196
 | 
					 | 
				
			||||||
#define SROM9_5GHPO_MCSBW20UL	198
 | 
					 | 
				
			||||||
#define SROM9_5GHPO_MCSBW40	200
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SROM9_PO_MCS32		202
 | 
					 | 
				
			||||||
#define SROM9_PO_LOFDM40DUP	203
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SROM flags (see sromvar_t) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* value continues as described by the next entry */
 | 
					 | 
				
			||||||
#define SRFL_MORE	1
 | 
					 | 
				
			||||||
#define	SRFL_NOFFS	2	/* value bits can't be all one's */
 | 
					 | 
				
			||||||
#define	SRFL_PRHEX	4	/* value is in hexdecimal format */
 | 
					 | 
				
			||||||
#define	SRFL_PRSIGN	8	/* value is in signed decimal format */
 | 
					 | 
				
			||||||
#define	SRFL_CCODE	0x10	/* value is in country code format */
 | 
					 | 
				
			||||||
#define	SRFL_ETHADDR	0x20	/* value is an Ethernet address */
 | 
					 | 
				
			||||||
#define SRFL_LEDDC	0x40	/* value is an LED duty cycle */
 | 
					 | 
				
			||||||
/* do not generate a nvram param, entry is for mfgc */
 | 
					 | 
				
			||||||
#define SRFL_NOVAR	0x80
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Max. nvram variable table size */
 | 
					 | 
				
			||||||
#define	MAXSZ_NVRAM_VARS	4096
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * indicates type of value.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum brcms_srom_var_type {
 | 
					 | 
				
			||||||
	BRCMS_SROM_STRING,
 | 
					 | 
				
			||||||
	BRCMS_SROM_SNUMBER,
 | 
					 | 
				
			||||||
	BRCMS_SROM_UNUMBER
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * storage type for srom variable.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * var_list: for linked list operations.
 | 
					 | 
				
			||||||
 * varid: identifier of the variable.
 | 
					 | 
				
			||||||
 * var_type: type of variable.
 | 
					 | 
				
			||||||
 * buf: variable value when var_type == BRCMS_SROM_STRING.
 | 
					 | 
				
			||||||
 * uval: unsigned variable value when var_type == BRCMS_SROM_UNUMBER.
 | 
					 | 
				
			||||||
 * sval: signed variable value when var_type == BRCMS_SROM_SNUMBER.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct brcms_srom_list_head {
 | 
					 | 
				
			||||||
	struct list_head var_list;
 | 
					 | 
				
			||||||
	enum brcms_srom_id varid;
 | 
					 | 
				
			||||||
	enum brcms_srom_var_type var_type;
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		char buf[0];
 | 
					 | 
				
			||||||
		u32 uval;
 | 
					 | 
				
			||||||
		s32 sval;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct brcms_sromvar {
 | 
					 | 
				
			||||||
	enum brcms_srom_id varid;
 | 
					 | 
				
			||||||
	u32 revmask;
 | 
					 | 
				
			||||||
	u32 flags;
 | 
					 | 
				
			||||||
	u16 off;
 | 
					 | 
				
			||||||
	u16 mask;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct brcms_varbuf {
 | 
					 | 
				
			||||||
	char *base;		/* pointer to buffer base */
 | 
					 | 
				
			||||||
	char *buf;		/* pointer to current position */
 | 
					 | 
				
			||||||
	unsigned int size;	/* current (residual) size in bytes */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Assumptions:
 | 
					 | 
				
			||||||
 * - Ethernet address spans across 3 consecutive words
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Table rules:
 | 
					 | 
				
			||||||
 * - Add multiple entries next to each other if a value spans across multiple
 | 
					 | 
				
			||||||
 *   words (even multiple fields in the same word) with each entry except the
 | 
					 | 
				
			||||||
 *   last having it's SRFL_MORE bit set.
 | 
					 | 
				
			||||||
 * - Ethernet address entry does not follow above rule and must not have
 | 
					 | 
				
			||||||
 *   SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
 | 
					 | 
				
			||||||
 * - The last entry's name field must be NULL to indicate the end of the table.
 | 
					 | 
				
			||||||
 *   Other entries must have non-NULL name.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct brcms_sromvar pci_sromvars[] = {
 | 
					 | 
				
			||||||
	{BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1LOB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1LOB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1LOB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1HIB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1HIB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1HIB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1ITSSIT, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
 | 
					 | 
				
			||||||
	 SROM4_TXCHAIN_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
 | 
					 | 
				
			||||||
	 SROM4_RXCHAIN_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_ANTSWITCH, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
 | 
					 | 
				
			||||||
	 SROM4_SWITCH_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TSSIPOS2G, 0xffffff00, 0, SROM8_FEM2G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_TSSIPOS_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_EXTPAGAIN2G, 0xffffff00, 0, SROM8_FEM2G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_EXTPA_GAIN_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PDETRANGE2G, 0xffffff00, 0, SROM8_FEM2G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_PDET_RANGE_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRISO2G, 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_ANTSWCTL2G, 0xffffff00, 0, SROM8_FEM2G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_ANTSWLUT_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TSSIPOS5G, 0xffffff00, 0, SROM8_FEM5G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_TSSIPOS_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_EXTPAGAIN5G, 0xffffff00, 0, SROM8_FEM5G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_EXTPA_GAIN_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PDETRANGE5G, 0xffffff00, 0, SROM8_FEM5G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_PDET_RANGE_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TRISO5G, 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_ANTSWCTL5G, 0xffffff00, 0, SROM8_FEM5G,
 | 
					 | 
				
			||||||
	 SROM8_FEM_ANTSWLUT_MASK},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
 | 
					 | 
				
			||||||
	 0x01ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
 | 
					 | 
				
			||||||
	 0xfe00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TEMPSENSE_SLOPE, 0xffffff00, SRFL_PRHEX,
 | 
					 | 
				
			||||||
	 SROM8_TS_SLP_OPT_CORRX, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TEMPCORRX, 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
 | 
					 | 
				
			||||||
	 0xfc00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_TEMPSENSE_OPTION, 0xffffff00, SRFL_PRHEX,
 | 
					 | 
				
			||||||
	 SROM8_TS_SLP_OPT_CORRX, 0x0300},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_FREQOFFSET_CORR, 0xffffff00, SRFL_PRHEX,
 | 
					 | 
				
			||||||
	 SROM8_FOC_HWIQ_IQSWP, 0x000f},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_IQCAL_SWP_DIS, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
 | 
					 | 
				
			||||||
	 0x0010},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_HW_IQCAL_EN, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
 | 
					 | 
				
			||||||
	 0x0020},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA,
 | 
					 | 
				
			||||||
	 0x00ff},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_OFDM5GLPO, 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO3, 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO4, 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO5, 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO6, 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS2GPO7, 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO0, 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO1, 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO2, 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO3, 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO4, 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO5, 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO6, 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GPO7, 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO0, 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO1, 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO2, 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO3, 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO4, 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO5, 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO6, 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GLPO7, 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO0, 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO1, 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO2, 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO3, 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO4, 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_BWDUPPO, 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* power per rate from sromrev 9 */
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CCKBW202GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CCKBW20UL2GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW202GPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_2GPO_LOFDMBW20, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW20UL2GPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_2GPO_LOFDMBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW205GLPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GLPO_LOFDMBW20, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GLPO_LOFDMBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW205GMPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GMPO_LOFDMBW20, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GMPO_LOFDMBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW205GHPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GHPO_LOFDMBW20, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDMBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GHPO_LOFDMBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW202GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW20UL2GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW402GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW205GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GLPO_MCSBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW405GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW205GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GMPO_MCSBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW405GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW205GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
 | 
					 | 
				
			||||||
	 SROM9_5GHPO_MCSBW20UL, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCSBW405GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MCS32PO, 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_LEGOFDM40DUPPO, 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	{BRCMS_SROM_NULL, 0, 0, 0, 0}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct brcms_sromvar perpath_pci_sromvars[] = {
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA2GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA2GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA2GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MAXP5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MAXP5GHA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_MAXP5GLA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GLW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GLW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GLW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GHW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GHW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_PA5GHW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2,
 | 
					 | 
				
			||||||
	 0xffff},
 | 
					 | 
				
			||||||
	{BRCMS_SROM_NULL, 0, 0, 0, 0}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* crc table has the same contents for every device instance, so it can be
 | 
					 | 
				
			||||||
 * shared between devices. */
 | 
					 | 
				
			||||||
static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint mask_shift(u16 mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint i;
 | 
					 | 
				
			||||||
	for (i = 0; i < (sizeof(mask) << 3); i++) {
 | 
					 | 
				
			||||||
		if (mask & (1 << i))
 | 
					 | 
				
			||||||
			return i;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint mask_width(u16 mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
 | 
					 | 
				
			||||||
		if (mask & (1 << i))
 | 
					 | 
				
			||||||
			return (uint) (i - mask_shift(mask) + 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void le16_to_cpu_buf(u16 *buf, uint nwords)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (nwords--)
 | 
					 | 
				
			||||||
		*(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void cpu_to_le16_buf(u16 *buf, uint nwords)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (nwords--)
 | 
					 | 
				
			||||||
		*(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * convert binary srom data into linked list of srom variable items.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct brcms_srom_list_head *entry;
 | 
					 | 
				
			||||||
	enum brcms_srom_id id;
 | 
					 | 
				
			||||||
	u16 w;
 | 
					 | 
				
			||||||
	u32 val = 0;
 | 
					 | 
				
			||||||
	const struct brcms_sromvar *srv;
 | 
					 | 
				
			||||||
	uint width;
 | 
					 | 
				
			||||||
	uint flags;
 | 
					 | 
				
			||||||
	u32 sr = (1 << sromrev);
 | 
					 | 
				
			||||||
	uint p;
 | 
					 | 
				
			||||||
	uint pb =  SROM8_PATH0;
 | 
					 | 
				
			||||||
	const uint psz = SROM8_PATH1 - SROM8_PATH0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* first store the srom revision */
 | 
					 | 
				
			||||||
	entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!entry)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	entry->varid = BRCMS_SROM_REV;
 | 
					 | 
				
			||||||
	entry->var_type = BRCMS_SROM_UNUMBER;
 | 
					 | 
				
			||||||
	entry->uval = sromrev;
 | 
					 | 
				
			||||||
	list_add(&entry->var_list, var_list);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (srv = pci_sromvars; srv->varid != BRCMS_SROM_NULL; srv++) {
 | 
					 | 
				
			||||||
		enum brcms_srom_var_type type;
 | 
					 | 
				
			||||||
		u8 ea[ETH_ALEN];
 | 
					 | 
				
			||||||
		u8 extra_space = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ((srv->revmask & sr) == 0)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		flags = srv->flags;
 | 
					 | 
				
			||||||
		id = srv->varid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* This entry is for mfgc only. Don't generate param for it, */
 | 
					 | 
				
			||||||
		if (flags & SRFL_NOVAR)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (flags & SRFL_ETHADDR) {
 | 
					 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * stored in string format XX:XX:XX:XX:XX:XX (17 chars)
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			ea[0] = (srom[srv->off] >> 8) & 0xff;
 | 
					 | 
				
			||||||
			ea[1] = srom[srv->off] & 0xff;
 | 
					 | 
				
			||||||
			ea[2] = (srom[srv->off + 1] >> 8) & 0xff;
 | 
					 | 
				
			||||||
			ea[3] = srom[srv->off + 1] & 0xff;
 | 
					 | 
				
			||||||
			ea[4] = (srom[srv->off + 2] >> 8) & 0xff;
 | 
					 | 
				
			||||||
			ea[5] = srom[srv->off + 2] & 0xff;
 | 
					 | 
				
			||||||
			/* 17 characters + string terminator - union size */
 | 
					 | 
				
			||||||
			extra_space = 18 - sizeof(s32);
 | 
					 | 
				
			||||||
			type = BRCMS_SROM_STRING;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			w = srom[srv->off];
 | 
					 | 
				
			||||||
			val = (w & srv->mask) >> mask_shift(srv->mask);
 | 
					 | 
				
			||||||
			width = mask_width(srv->mask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			while (srv->flags & SRFL_MORE) {
 | 
					 | 
				
			||||||
				srv++;
 | 
					 | 
				
			||||||
				if (srv->off == 0)
 | 
					 | 
				
			||||||
					continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				w = srom[srv->off];
 | 
					 | 
				
			||||||
				val +=
 | 
					 | 
				
			||||||
				    ((w & srv->mask) >> mask_shift(srv->
 | 
					 | 
				
			||||||
								   mask)) <<
 | 
					 | 
				
			||||||
				    width;
 | 
					 | 
				
			||||||
				width += mask_width(srv->mask);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ((flags & SRFL_NOFFS)
 | 
					 | 
				
			||||||
			    && ((int)val == (1 << width) - 1))
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (flags & SRFL_CCODE) {
 | 
					 | 
				
			||||||
				type = BRCMS_SROM_STRING;
 | 
					 | 
				
			||||||
			} else if (flags & SRFL_LEDDC) {
 | 
					 | 
				
			||||||
				/* LED Powersave duty cycle has to be scaled:
 | 
					 | 
				
			||||||
				 *(oncount >> 24) (offcount >> 8)
 | 
					 | 
				
			||||||
				 */
 | 
					 | 
				
			||||||
				u32 w32 = /* oncount */
 | 
					 | 
				
			||||||
					  (((val >> 8) & 0xff) << 24) |
 | 
					 | 
				
			||||||
					  /* offcount */
 | 
					 | 
				
			||||||
					  (((val & 0xff)) << 8);
 | 
					 | 
				
			||||||
				type = BRCMS_SROM_UNUMBER;
 | 
					 | 
				
			||||||
				val = w32;
 | 
					 | 
				
			||||||
			} else if ((flags & SRFL_PRSIGN)
 | 
					 | 
				
			||||||
				 && (val & (1 << (width - 1)))) {
 | 
					 | 
				
			||||||
				type = BRCMS_SROM_SNUMBER;
 | 
					 | 
				
			||||||
				val |= ~0 << width;
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				type = BRCMS_SROM_UNUMBER;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		entry = kzalloc(sizeof(struct brcms_srom_list_head) +
 | 
					 | 
				
			||||||
				extra_space, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!entry)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
		entry->varid = id;
 | 
					 | 
				
			||||||
		entry->var_type = type;
 | 
					 | 
				
			||||||
		if (flags & SRFL_ETHADDR) {
 | 
					 | 
				
			||||||
			snprintf(entry->buf, 18, "%pM", ea);
 | 
					 | 
				
			||||||
		} else if (flags & SRFL_CCODE) {
 | 
					 | 
				
			||||||
			if (val == 0)
 | 
					 | 
				
			||||||
				entry->buf[0] = '\0';
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				snprintf(entry->buf, 3, "%c%c",
 | 
					 | 
				
			||||||
					 (val >> 8), (val & 0xff));
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			entry->uval = val;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		list_add(&entry->var_list, var_list);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (p = 0; p < MAX_PATH_SROM; p++) {
 | 
					 | 
				
			||||||
		for (srv = perpath_pci_sromvars;
 | 
					 | 
				
			||||||
		     srv->varid != BRCMS_SROM_NULL; srv++) {
 | 
					 | 
				
			||||||
			if ((srv->revmask & sr) == 0)
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (srv->flags & SRFL_NOVAR)
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			w = srom[pb + srv->off];
 | 
					 | 
				
			||||||
			val = (w & srv->mask) >> mask_shift(srv->mask);
 | 
					 | 
				
			||||||
			width = mask_width(srv->mask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Cheating: no per-path var is more than
 | 
					 | 
				
			||||||
			 * 1 word */
 | 
					 | 
				
			||||||
			if ((srv->flags & SRFL_NOFFS)
 | 
					 | 
				
			||||||
			    && ((int)val == (1 << width) - 1))
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			entry =
 | 
					 | 
				
			||||||
			    kzalloc(sizeof(struct brcms_srom_list_head),
 | 
					 | 
				
			||||||
				    GFP_KERNEL);
 | 
					 | 
				
			||||||
			if (!entry)
 | 
					 | 
				
			||||||
				return -ENOMEM;
 | 
					 | 
				
			||||||
			entry->varid = srv->varid+p;
 | 
					 | 
				
			||||||
			entry->var_type = BRCMS_SROM_UNUMBER;
 | 
					 | 
				
			||||||
			entry->uval = val;
 | 
					 | 
				
			||||||
			list_add(&entry->var_list, var_list);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		pb += psz;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * The crc check is done on a little-endian array, we need
 | 
					 | 
				
			||||||
 * to switch the bytes around before checking crc (and
 | 
					 | 
				
			||||||
 * then switch it back).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int do_crc_check(u16 *buf, unsigned nwords)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u8 crc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cpu_to_le16_buf(buf, nwords);
 | 
					 | 
				
			||||||
	crc = crc8(brcms_srom_crc8_table, (void *)buf, nwords << 1, CRC8_INIT_VALUE);
 | 
					 | 
				
			||||||
	le16_to_cpu_buf(buf, nwords);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return crc == CRC8_GOOD_VALUE(brcms_srom_crc8_table);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Read in and validate sprom.
 | 
					 | 
				
			||||||
 * Return 0 on success, nonzero on error.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
sprom_read_pci(struct si_pub *sih, u16 *buf, uint nwords, bool check_crc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int err = 0;
 | 
					 | 
				
			||||||
	uint i;
 | 
					 | 
				
			||||||
	struct bcma_device *core;
 | 
					 | 
				
			||||||
	uint sprom_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* determine core to read */
 | 
					 | 
				
			||||||
	if (ai_get_ccrev(sih) < 32) {
 | 
					 | 
				
			||||||
		core = ai_findcore(sih, BCMA_CORE_80211, 0);
 | 
					 | 
				
			||||||
		sprom_offset = PCI_BAR0_SPROM_OFFSET;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
 | 
					 | 
				
			||||||
		sprom_offset = CHIPCREGOFFS(sromotp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* read the sprom */
 | 
					 | 
				
			||||||
	for (i = 0; i < nwords; i++)
 | 
					 | 
				
			||||||
		buf[i] = bcma_read16(core, sprom_offset+i*2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (buf[0] == 0xffff)
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * The hardware thinks that an srom that starts with
 | 
					 | 
				
			||||||
		 * 0xffff is blank, regardless of the rest of the
 | 
					 | 
				
			||||||
		 * content, so declare it bad.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		return -ENODATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (check_crc && !do_crc_check(buf, nwords))
 | 
					 | 
				
			||||||
		err = -EIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u8 *otp;
 | 
					 | 
				
			||||||
	uint sz = OTP_SZ_MAX / 2;	/* size in words */
 | 
					 | 
				
			||||||
	int err = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
 | 
					 | 
				
			||||||
	if (otp == NULL)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sz = min_t(uint, sz, nwords);
 | 
					 | 
				
			||||||
	memcpy(buf, otp, sz * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	kfree(otp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Check CRC */
 | 
					 | 
				
			||||||
	if (buf[0] == 0xffff)
 | 
					 | 
				
			||||||
		/* The hardware thinks that an srom that starts with 0xffff
 | 
					 | 
				
			||||||
		 * is blank, regardless of the rest of the content, so declare
 | 
					 | 
				
			||||||
		 * it bad.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		return -ENODATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* fixup the endianness so crc8 will pass */
 | 
					 | 
				
			||||||
	cpu_to_le16_buf(buf, sz);
 | 
					 | 
				
			||||||
	if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2,
 | 
					 | 
				
			||||||
		 CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table))
 | 
					 | 
				
			||||||
		err = -EIO;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		/* now correct the endianness of the byte array */
 | 
					 | 
				
			||||||
		le16_to_cpu_buf(buf, sz);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Initialize nonvolatile variable table from sprom.
 | 
					 | 
				
			||||||
 * Return 0 on success, nonzero on error.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int srom_var_init(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u16 *srom;
 | 
					 | 
				
			||||||
	u8 sromrev = 0;
 | 
					 | 
				
			||||||
	u32 sr;
 | 
					 | 
				
			||||||
	int err = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Apply CRC over SROM content regardless SROM is present or not.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	srom = kmalloc(SROM_MAX, GFP_ATOMIC);
 | 
					 | 
				
			||||||
	if (!srom)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
 | 
					 | 
				
			||||||
	if (ai_is_sprom_available(sih)) {
 | 
					 | 
				
			||||||
		err = sprom_read_pci(sih, srom, SROM4_WORDS, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (err == 0)
 | 
					 | 
				
			||||||
			/* srom read and passed crc */
 | 
					 | 
				
			||||||
			/* top word of sprom contains version and crc8 */
 | 
					 | 
				
			||||||
			sromrev = srom[SROM4_CRCREV] & 0xff;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		/* Use OTP if SPROM not available */
 | 
					 | 
				
			||||||
		err = otp_read_pci(sih, srom, SROM4_WORDS);
 | 
					 | 
				
			||||||
		if (err == 0)
 | 
					 | 
				
			||||||
			/* OTP only contain SROM rev8/rev9 for now */
 | 
					 | 
				
			||||||
			sromrev = srom[SROM4_CRCREV] & 0xff;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!err) {
 | 
					 | 
				
			||||||
		struct si_info *sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Bitmask for the sromrev */
 | 
					 | 
				
			||||||
		sr = 1 << sromrev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * srom version check: Current valid versions: 8, 9
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if ((sr & 0x300) == 0) {
 | 
					 | 
				
			||||||
			err = -EINVAL;
 | 
					 | 
				
			||||||
			goto errout;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		INIT_LIST_HEAD(&sii->var_list);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* parse SROM into name=value pairs. */
 | 
					 | 
				
			||||||
		err = _initvars_srom_pci(sromrev, srom, &sii->var_list);
 | 
					 | 
				
			||||||
		if (err)
 | 
					 | 
				
			||||||
			srom_free_vars(sih);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
errout:
 | 
					 | 
				
			||||||
	kfree(srom);
 | 
					 | 
				
			||||||
	return err;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void srom_free_vars(struct si_pub *sih)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	struct brcms_srom_list_head *entry, *next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
	list_for_each_entry_safe(entry, next, &sii->var_list, var_list) {
 | 
					 | 
				
			||||||
		list_del(&entry->var_list);
 | 
					 | 
				
			||||||
		kfree(entry);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Search the name=value vars for a specific one and return its value.
 | 
					 | 
				
			||||||
 * Returns NULL if not found.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
char *getvar(struct si_pub *sih, enum brcms_srom_id id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	struct brcms_srom_list_head *entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	list_for_each_entry(entry, &sii->var_list, var_list)
 | 
					 | 
				
			||||||
		if (entry->varid == id)
 | 
					 | 
				
			||||||
			return &entry->buf[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* nothing found */
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Search the vars for a specific one and return its value as
 | 
					 | 
				
			||||||
 * an integer. Returns 0 if not found.-
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int getintvar(struct si_pub *sih, enum brcms_srom_id id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct si_info *sii;
 | 
					 | 
				
			||||||
	struct brcms_srom_list_head *entry;
 | 
					 | 
				
			||||||
	unsigned long res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sii = (struct si_info *)sih;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	list_for_each_entry(entry, &sii->var_list, var_list)
 | 
					 | 
				
			||||||
		if (entry->varid == id) {
 | 
					 | 
				
			||||||
			if (entry->var_type == BRCMS_SROM_SNUMBER ||
 | 
					 | 
				
			||||||
			    entry->var_type == BRCMS_SROM_UNUMBER)
 | 
					 | 
				
			||||||
				return (int)entry->sval;
 | 
					 | 
				
			||||||
			else if (!kstrtoul(&entry->buf[0], 0, &res))
 | 
					 | 
				
			||||||
				return (int)res;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,29 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2010 Broadcom Corporation
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
					 | 
				
			||||||
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
					 | 
				
			||||||
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
					 | 
				
			||||||
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef	_BRCM_SROM_H_
 | 
					 | 
				
			||||||
#define	_BRCM_SROM_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "types.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Prototypes */
 | 
					 | 
				
			||||||
extern int srom_var_init(struct si_pub *sih);
 | 
					 | 
				
			||||||
extern void srom_free_vars(struct si_pub *sih);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
 | 
					 | 
				
			||||||
		     uint byteoff, uint nbytes, u16 *buf, bool check_crc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif				/* _BRCM_SROM_H_ */
 | 
					 | 
				
			||||||
| 
						 | 
					@ -370,9 +370,11 @@ void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
 | 
					void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get available rx/tx chains */
 | 
						/* get available rx/tx chains */
 | 
				
			||||||
	wlc->stf->hw_txchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_TXCHAIN);
 | 
						wlc->stf->hw_txchain = sprom->txchain;
 | 
				
			||||||
	wlc->stf->hw_rxchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_RXCHAIN);
 | 
						wlc->stf->hw_rxchain = sprom->rxchain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* these parameter are intended to be used for all PHY types */
 | 
						/* these parameter are intended to be used for all PHY types */
 | 
				
			||||||
	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
 | 
						if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/init.h>
 | 
					#include <linux/init.h>
 | 
				
			||||||
#include <linux/sched.h>
 | 
					#include <linux/sched.h>
 | 
				
			||||||
 | 
					#include <net/mac80211.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "iwl-dev.h"
 | 
					#include "iwl-dev.h"
 | 
				
			||||||
#include "iwl-io.h"
 | 
					#include "iwl-io.h"
 | 
				
			||||||
| 
						 | 
					@ -273,9 +274,20 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Possible situations when BT needs to take over for receive,
 | 
				
			||||||
 | 
						 * at the same time where STA needs to response to AP's frame(s),
 | 
				
			||||||
 | 
						 * reduce the tx power of the required response frames, by that,
 | 
				
			||||||
 | 
						 * allow the concurrent BT receive & WiFi transmit
 | 
				
			||||||
 | 
						 * (BT - ANT A, WiFi -ANT B), without interference to one another
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Reduced tx power apply to control frames only (ACK/Back/CTS)
 | 
				
			||||||
 | 
						 * when indicated by the BT config command
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	basic.kill_ack_mask = priv->kill_ack_mask;
 | 
						basic.kill_ack_mask = priv->kill_ack_mask;
 | 
				
			||||||
	basic.kill_cts_mask = priv->kill_cts_mask;
 | 
						basic.kill_cts_mask = priv->kill_cts_mask;
 | 
				
			||||||
	basic.reduce_txpower = priv->reduced_txpower;
 | 
						if (priv->reduced_txpower)
 | 
				
			||||||
 | 
							basic.reduce_txpower = IWLAGN_BT_REDUCED_TX_PWR;
 | 
				
			||||||
	basic.valid = priv->bt_valid;
 | 
						basic.valid = priv->bt_valid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -589,13 +601,31 @@ static bool iwlagn_set_kill_msk(struct iwl_priv *priv,
 | 
				
			||||||
	return need_update;
 | 
						return need_update;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Upon RSSI changes, sends a bt config command with following changes
 | 
				
			||||||
 | 
					 *  1. enable/disable "reduced control frames tx power
 | 
				
			||||||
 | 
					 *  2. update the "kill)ack_mask" and "kill_cts_mask"
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If "reduced tx power" is enabled, uCode shall
 | 
				
			||||||
 | 
					 *  1. ACK/Back/CTS rate shall reduced to 6Mbps
 | 
				
			||||||
 | 
					 *  2. not use duplciate 20/40MHz mode
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
 | 
					static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
 | 
				
			||||||
				struct iwl_bt_uart_msg *uart_msg)
 | 
									struct iwl_bt_uart_msg *uart_msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool need_update = false;
 | 
						bool need_update = false;
 | 
				
			||||||
 | 
						struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 | 
				
			||||||
 | 
						int ave_rssi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ave_rssi = ieee80211_ave_rssi(ctx->vif);
 | 
				
			||||||
 | 
						if (!ave_rssi) {
 | 
				
			||||||
 | 
							/* no rssi data, no changes to reduce tx power */
 | 
				
			||||||
 | 
							IWL_DEBUG_COEX(priv, "no rssi data available\n");
 | 
				
			||||||
 | 
							return need_update;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (!priv->reduced_txpower &&
 | 
						if (!priv->reduced_txpower &&
 | 
				
			||||||
	    !iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
 | 
						    !iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
 | 
				
			||||||
 | 
						    (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) &&
 | 
				
			||||||
	    (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
 | 
						    (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
 | 
				
			||||||
	    BT_UART_MSG_FRAME3OBEX_MSK)) &&
 | 
						    BT_UART_MSG_FRAME3OBEX_MSK)) &&
 | 
				
			||||||
	    !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
 | 
						    !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
 | 
				
			||||||
| 
						 | 
					@ -606,13 +636,14 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
 | 
				
			||||||
		need_update = true;
 | 
							need_update = true;
 | 
				
			||||||
	} else if (priv->reduced_txpower &&
 | 
						} else if (priv->reduced_txpower &&
 | 
				
			||||||
		   (iwl_is_associated(priv, IWL_RXON_CTX_PAN) ||
 | 
							   (iwl_is_associated(priv, IWL_RXON_CTX_PAN) ||
 | 
				
			||||||
 | 
							   (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) ||
 | 
				
			||||||
		   (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
 | 
							   (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
 | 
				
			||||||
		   BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) ||
 | 
							   BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) ||
 | 
				
			||||||
		   !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
 | 
							   !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
 | 
				
			||||||
		   BT_UART_MSG_FRAME3OBEX_MSK)))) {
 | 
							   BT_UART_MSG_FRAME3OBEX_MSK)))) {
 | 
				
			||||||
		/* disable reduced tx power */
 | 
							/* disable reduced tx power */
 | 
				
			||||||
		priv->reduced_txpower = false;
 | 
							priv->reduced_txpower = false;
 | 
				
			||||||
		priv->bt_valid &= ~IWLAGN_BT_VALID_REDUCED_TX_PWR;
 | 
							priv->bt_valid |= IWLAGN_BT_VALID_REDUCED_TX_PWR;
 | 
				
			||||||
		need_update = true;
 | 
							need_update = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,10 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
 | 
				
			||||||
						  RXON_FILTER_ACCEPT_GRP_MSK;
 | 
											  RXON_FILTER_ACCEPT_GRP_MSK;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case NL80211_IFTYPE_MONITOR:
 | 
				
			||||||
 | 
							ctx->staging.dev_type = RXON_DEV_TYPE_SNIFFER;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		IWL_ERR(priv, "Unsupported interface type %d\n",
 | 
							IWL_ERR(priv, "Unsupported interface type %d\n",
 | 
				
			||||||
			ctx->vif->type);
 | 
								ctx->vif->type);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -590,11 +590,17 @@ turn_off:
 | 
				
			||||||
	spin_unlock_bh(&priv->sta_lock);
 | 
						spin_unlock_bh(&priv->sta_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (test_bit(txq_id, priv->agg_q_alloc)) {
 | 
						if (test_bit(txq_id, priv->agg_q_alloc)) {
 | 
				
			||||||
		/* If the transport didn't know that we wanted to start
 | 
							/*
 | 
				
			||||||
		 * agreggation, don't tell it that we want to stop them
 | 
							 * If the transport didn't know that we wanted to start
 | 
				
			||||||
 | 
							 * agreggation, don't tell it that we want to stop them.
 | 
				
			||||||
 | 
							 * This can happen when we don't get the addBA response on
 | 
				
			||||||
 | 
							 * time, or we hadn't time to drain the AC queues.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (agg_state != IWL_AGG_STARTING)
 | 
							if (agg_state == IWL_AGG_ON)
 | 
				
			||||||
			iwl_trans_tx_agg_disable(priv->trans, txq_id);
 | 
								iwl_trans_tx_agg_disable(priv->trans, txq_id);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
 | 
				
			||||||
 | 
										    agg_state);
 | 
				
			||||||
		iwlagn_dealloc_agg_txq(priv, txq_id);
 | 
							iwlagn_dealloc_agg_txq(priv, txq_id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1300,10 +1306,11 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 | 
				
			||||||
			   (u8 *) &ba_resp->sta_addr_lo32,
 | 
								   (u8 *) &ba_resp->sta_addr_lo32,
 | 
				
			||||||
			   ba_resp->sta_id);
 | 
								   ba_resp->sta_id);
 | 
				
			||||||
	IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, "
 | 
						IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, "
 | 
				
			||||||
			   "scd_flow = %d, scd_ssn = %d\n",
 | 
								   "scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n",
 | 
				
			||||||
			   ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl),
 | 
								   ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl),
 | 
				
			||||||
			   (unsigned long long)le64_to_cpu(ba_resp->bitmap),
 | 
								   (unsigned long long)le64_to_cpu(ba_resp->bitmap),
 | 
				
			||||||
			   scd_flow, ba_resp_scd_ssn);
 | 
								   scd_flow, ba_resp_scd_ssn, ba_resp->txed,
 | 
				
			||||||
 | 
								   ba_resp->txed_2_done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Mark that the expected block-ack response arrived */
 | 
						/* Mark that the expected block-ack response arrived */
 | 
				
			||||||
	agg->wait_for_ba = false;
 | 
						agg->wait_for_ba = false;
 | 
				
			||||||
| 
						 | 
					@ -1319,8 +1326,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		ba_resp->txed = ba_resp->txed_2_done;
 | 
							ba_resp->txed = ba_resp->txed_2_done;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
 | 
					 | 
				
			||||||
			ba_resp->txed, ba_resp->txed_2_done);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn;
 | 
						priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -603,7 +603,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
 | 
				
			||||||
	priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
 | 
						priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
 | 
				
			||||||
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 | 
						priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 | 
				
			||||||
	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
 | 
						priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
 | 
				
			||||||
		BIT(NL80211_IFTYPE_ADHOC);
 | 
							BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MONITOR);
 | 
				
			||||||
	priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
 | 
						priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
 | 
				
			||||||
		BIT(NL80211_IFTYPE_STATION);
 | 
							BIT(NL80211_IFTYPE_STATION);
 | 
				
			||||||
	priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
 | 
						priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1910,6 +1910,8 @@ enum iwl_bt_kill_idx {
 | 
				
			||||||
					IWLAGN_BT_VALID_REDUCED_TX_PWR | \
 | 
										IWLAGN_BT_VALID_REDUCED_TX_PWR | \
 | 
				
			||||||
					IWLAGN_BT_VALID_3W_LUT)
 | 
										IWLAGN_BT_VALID_3W_LUT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IWLAGN_BT_REDUCED_TX_PWR	BIT(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IWLAGN_BT_DECISION_LUT_SIZE	12
 | 
					#define IWLAGN_BT_DECISION_LUT_SIZE	12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct iwl_basic_bt_cmd {
 | 
					struct iwl_basic_bt_cmd {
 | 
				
			||||||
| 
						 | 
					@ -1923,6 +1925,10 @@ struct iwl_basic_bt_cmd {
 | 
				
			||||||
	u8 bt3_timer_t2_value;
 | 
						u8 bt3_timer_t2_value;
 | 
				
			||||||
	__le16 bt4_reaction_time; /* unused */
 | 
						__le16 bt4_reaction_time; /* unused */
 | 
				
			||||||
	__le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE];
 | 
						__le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE];
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * bit 0: use reduced tx power for control frame
 | 
				
			||||||
 | 
						 * bit 1 - 7: reserved
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	u8 reduce_txpower;
 | 
						u8 reduce_txpower;
 | 
				
			||||||
	u8 reserved;
 | 
						u8 reserved;
 | 
				
			||||||
	__le16 valid;
 | 
						__le16 valid;
 | 
				
			||||||
| 
						 | 
					@ -2272,7 +2278,6 @@ struct iwl_ssid_ie {
 | 
				
			||||||
#define IWL_GOOD_CRC_TH_DISABLED	0
 | 
					#define IWL_GOOD_CRC_TH_DISABLED	0
 | 
				
			||||||
#define IWL_GOOD_CRC_TH_DEFAULT		cpu_to_le16(1)
 | 
					#define IWL_GOOD_CRC_TH_DEFAULT		cpu_to_le16(1)
 | 
				
			||||||
#define IWL_GOOD_CRC_TH_NEVER		cpu_to_le16(0xffff)
 | 
					#define IWL_GOOD_CRC_TH_NEVER		cpu_to_le16(0xffff)
 | 
				
			||||||
#define IWL_MAX_SCAN_SIZE 1024
 | 
					 | 
				
			||||||
#define IWL_MAX_CMD_SIZE 4096
 | 
					#define IWL_MAX_CMD_SIZE 4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 | 
				
			||||||
		    IEEE80211_HW_QUEUE_CONTROL |
 | 
							    IEEE80211_HW_QUEUE_CONTROL |
 | 
				
			||||||
		    IEEE80211_HW_SUPPORTS_PS |
 | 
							    IEEE80211_HW_SUPPORTS_PS |
 | 
				
			||||||
		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
 | 
							    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
 | 
				
			||||||
 | 
							    IEEE80211_HW_WANT_MONITOR_VIF |
 | 
				
			||||||
		    IEEE80211_HW_SCAN_WHILE_IDLE;
 | 
							    IEEE80211_HW_SCAN_WHILE_IDLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
 | 
						hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
 | 
				
			||||||
| 
						 | 
					@ -223,8 +224,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 | 
				
			||||||
		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 | 
							hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 | 
						hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 | 
				
			||||||
	/* we create the 802.11 header and a zero-length SSID element */
 | 
						/* we create the 802.11 header and a max-length SSID element */
 | 
				
			||||||
	hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2;
 | 
						hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 34;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We don't use all queues: 4 and 9 are unused and any
 | 
						 * We don't use all queues: 4 and 9 are unused and any
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,6 +253,8 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n",
 | 
						IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n",
 | 
				
			||||||
			skip, period);
 | 
								skip, period);
 | 
				
			||||||
 | 
						/* The power level here is 0-4 (used as array index), but user expects
 | 
				
			||||||
 | 
						to see 1-5 (according to spec). */
 | 
				
			||||||
	IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
 | 
						IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,10 +310,12 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
 | 
				
			||||||
				     priv->power_data.debug_sleep_level_override,
 | 
									     priv->power_data.debug_sleep_level_override,
 | 
				
			||||||
				     dtimper);
 | 
									     dtimper);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
 | 
							/* Note that the user parameter is 1-5 (according to spec),
 | 
				
			||||||
 | 
							but we pass 0-4 because it acts as an array index. */
 | 
				
			||||||
		if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 &&
 | 
							if (iwlwifi_mod_params.power_level > IWL_POWER_INDEX_1 &&
 | 
				
			||||||
		    iwlwifi_mod_params.power_level <= IWL_POWER_INDEX_5)
 | 
							    iwlwifi_mod_params.power_level <= IWL_POWER_NUM)
 | 
				
			||||||
			iwl_static_sleep_cmd(priv, cmd,
 | 
								iwl_static_sleep_cmd(priv, cmd,
 | 
				
			||||||
				iwlwifi_mod_params.power_level, dtimper);
 | 
									iwlwifi_mod_params.power_level - 1, dtimper);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			iwl_static_sleep_cmd(priv, cmd,
 | 
								iwl_static_sleep_cmd(priv, cmd,
 | 
				
			||||||
				IWL_POWER_INDEX_1, dtimper);
 | 
									IWL_POWER_INDEX_1, dtimper);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +52,7 @@
 | 
				
			||||||
#define IWL_PASSIVE_DWELL_TIME_52   (10)
 | 
					#define IWL_PASSIVE_DWELL_TIME_52   (10)
 | 
				
			||||||
#define IWL_PASSIVE_DWELL_BASE      (100)
 | 
					#define IWL_PASSIVE_DWELL_BASE      (100)
 | 
				
			||||||
#define IWL_CHANNEL_TUNE_TIME       5
 | 
					#define IWL_CHANNEL_TUNE_TIME       5
 | 
				
			||||||
 | 
					#define MAX_SCAN_CHANNEL	    50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int iwl_send_scan_abort(struct iwl_priv *priv)
 | 
					static int iwl_send_scan_abort(struct iwl_priv *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -616,7 +617,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
 | 
					static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
 | 
				
			||||||
			      const u8 *ies, int ie_len, int left)
 | 
								      const u8 *ies, int ie_len, const u8 *ssid,
 | 
				
			||||||
 | 
								      u8 ssid_len, int left)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int len = 0;
 | 
						int len = 0;
 | 
				
			||||||
	u8 *pos = NULL;
 | 
						u8 *pos = NULL;
 | 
				
			||||||
| 
						 | 
					@ -638,14 +640,18 @@ static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
 | 
				
			||||||
	/* ...next IE... */
 | 
						/* ...next IE... */
 | 
				
			||||||
	pos = &frame->u.probe_req.variable[0];
 | 
						pos = &frame->u.probe_req.variable[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* fill in our indirect SSID IE */
 | 
						/* fill in our SSID IE */
 | 
				
			||||||
	left -= 2;
 | 
						left -= ssid_len + 2;
 | 
				
			||||||
	if (left < 0)
 | 
						if (left < 0)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	*pos++ = WLAN_EID_SSID;
 | 
						*pos++ = WLAN_EID_SSID;
 | 
				
			||||||
	*pos++ = 0;
 | 
						*pos++ = ssid_len;
 | 
				
			||||||
 | 
						if (ssid && ssid_len) {
 | 
				
			||||||
 | 
							memcpy(pos, ssid, ssid_len);
 | 
				
			||||||
 | 
							pos += ssid_len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len += 2;
 | 
						len += ssid_len + 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON(left < ie_len))
 | 
						if (WARN_ON(left < ie_len))
 | 
				
			||||||
		return len;
 | 
							return len;
 | 
				
			||||||
| 
						 | 
					@ -679,6 +685,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
	u8 active_chains;
 | 
						u8 active_chains;
 | 
				
			||||||
	u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
 | 
						u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
						int scan_cmd_size = sizeof(struct iwl_scan_cmd) +
 | 
				
			||||||
 | 
								    MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) +
 | 
				
			||||||
 | 
								    priv->fw->ucode_capa.max_probe_length;
 | 
				
			||||||
 | 
						const u8 *ssid = NULL;
 | 
				
			||||||
 | 
						u8 ssid_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (WARN_ON_ONCE(priv->scan_request &&
 | 
				
			||||||
 | 
								 priv->scan_request->n_channels > MAX_SCAN_CHANNEL))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_held(&priv->mutex);
 | 
						lockdep_assert_held(&priv->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -686,8 +701,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
		ctx = iwl_rxon_ctx_from_vif(vif);
 | 
							ctx = iwl_rxon_ctx_from_vif(vif);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!priv->scan_cmd) {
 | 
						if (!priv->scan_cmd) {
 | 
				
			||||||
		priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
 | 
							priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL);
 | 
				
			||||||
					 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!priv->scan_cmd) {
 | 
							if (!priv->scan_cmd) {
 | 
				
			||||||
			IWL_DEBUG_SCAN(priv,
 | 
								IWL_DEBUG_SCAN(priv,
 | 
				
			||||||
				       "fail to allocate memory for scan\n");
 | 
									       "fail to allocate memory for scan\n");
 | 
				
			||||||
| 
						 | 
					@ -695,7 +709,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	scan = priv->scan_cmd;
 | 
						scan = priv->scan_cmd;
 | 
				
			||||||
	memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
 | 
						memset(scan, 0, scan_cmd_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
 | 
						scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
 | 
				
			||||||
	scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 | 
						scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 | 
				
			||||||
| 
						 | 
					@ -746,10 +760,18 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
		if (priv->scan_request->n_ssids) {
 | 
							if (priv->scan_request->n_ssids) {
 | 
				
			||||||
			int i, p = 0;
 | 
								int i, p = 0;
 | 
				
			||||||
			IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
 | 
								IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
 | 
				
			||||||
			for (i = 0; i < priv->scan_request->n_ssids; i++) {
 | 
								/*
 | 
				
			||||||
				/* always does wildcard anyway */
 | 
								 * The highest priority SSID is inserted to the
 | 
				
			||||||
				if (!priv->scan_request->ssids[i].ssid_len)
 | 
								 * probe request template.
 | 
				
			||||||
					continue;
 | 
								 */
 | 
				
			||||||
 | 
								ssid_len = priv->scan_request->ssids[0].ssid_len;
 | 
				
			||||||
 | 
								ssid = priv->scan_request->ssids[0].ssid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Invert the order of ssids, the firmware will invert
 | 
				
			||||||
 | 
								 * it back.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								for (i = priv->scan_request->n_ssids - 1; i >= 1; i--) {
 | 
				
			||||||
				scan->direct_scan[p].id = WLAN_EID_SSID;
 | 
									scan->direct_scan[p].id = WLAN_EID_SSID;
 | 
				
			||||||
				scan->direct_scan[p].len =
 | 
									scan->direct_scan[p].len =
 | 
				
			||||||
					priv->scan_request->ssids[i].ssid_len;
 | 
										priv->scan_request->ssids[i].ssid_len;
 | 
				
			||||||
| 
						 | 
					@ -883,7 +905,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
					vif->addr,
 | 
										vif->addr,
 | 
				
			||||||
					priv->scan_request->ie,
 | 
										priv->scan_request->ie,
 | 
				
			||||||
					priv->scan_request->ie_len,
 | 
										priv->scan_request->ie_len,
 | 
				
			||||||
					IWL_MAX_SCAN_SIZE - sizeof(*scan));
 | 
										ssid, ssid_len,
 | 
				
			||||||
 | 
										scan_cmd_size - sizeof(*scan));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IWL_SCAN_RADIO_RESET:
 | 
						case IWL_SCAN_RADIO_RESET:
 | 
				
			||||||
	case IWL_SCAN_ROC:
 | 
						case IWL_SCAN_ROC:
 | 
				
			||||||
| 
						 | 
					@ -891,7 +914,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 | 
				
			||||||
		cmd_len = iwl_fill_probe_req(
 | 
							cmd_len = iwl_fill_probe_req(
 | 
				
			||||||
					(struct ieee80211_mgmt *)scan->data,
 | 
										(struct ieee80211_mgmt *)scan->data,
 | 
				
			||||||
					iwl_bcast_addr, NULL, 0,
 | 
										iwl_bcast_addr, NULL, 0,
 | 
				
			||||||
					IWL_MAX_SCAN_SIZE - sizeof(*scan));
 | 
										NULL, 0,
 | 
				
			||||||
 | 
										scan_cmd_size - sizeof(*scan));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -746,6 +746,11 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 | 
				
			||||||
		hwsim_check_sta_magic(txi->control.sta);
 | 
							hwsim_check_sta_magic(txi->control.sta);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_tx_info_clear_status(txi);
 | 
						ieee80211_tx_info_clear_status(txi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* frame was transmitted at most favorable rate at first attempt */
 | 
				
			||||||
 | 
						txi->control.rates[0].count = 1;
 | 
				
			||||||
 | 
						txi->control.rates[1].idx = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
 | 
						if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
 | 
				
			||||||
		txi->flags |= IEEE80211_TX_STAT_ACK;
 | 
							txi->flags |= IEEE80211_TX_STAT_ACK;
 | 
				
			||||||
	ieee80211_tx_status_irqsafe(hw, skb);
 | 
						ieee80211_tx_status_irqsafe(hw, skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,8 @@ mwifiex-y += scan.o
 | 
				
			||||||
mwifiex-y += join.o
 | 
					mwifiex-y += join.o
 | 
				
			||||||
mwifiex-y += sta_ioctl.o
 | 
					mwifiex-y += sta_ioctl.o
 | 
				
			||||||
mwifiex-y += sta_cmd.o
 | 
					mwifiex-y += sta_cmd.o
 | 
				
			||||||
 | 
					mwifiex-y += uap_cmd.o
 | 
				
			||||||
 | 
					mwifiex-y += ie.o
 | 
				
			||||||
mwifiex-y += sta_cmdresp.o
 | 
					mwifiex-y += sta_cmdresp.o
 | 
				
			||||||
mwifiex-y += sta_event.o
 | 
					mwifiex-y += sta_event.o
 | 
				
			||||||
mwifiex-y += sta_tx.o
 | 
					mwifiex-y += sta_tx.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,23 @@
 | 
				
			||||||
#include "cfg80211.h"
 | 
					#include "cfg80211.h"
 | 
				
			||||||
#include "main.h"
 | 
					#include "main.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.max = 1, .types = BIT(NL80211_IFTYPE_STATION),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.max = 1, .types = BIT(NL80211_IFTYPE_AP),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
 | 
				
			||||||
 | 
						.limits = mwifiex_ap_sta_limits,
 | 
				
			||||||
 | 
						.num_different_channels = 1,
 | 
				
			||||||
 | 
						.n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
 | 
				
			||||||
 | 
						.max_interfaces = MWIFIEX_MAX_BSS_NUM,
 | 
				
			||||||
 | 
						.beacon_int_infra_match = true,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This function maps the nl802.11 channel type into driver channel type.
 | 
					 * This function maps the nl802.11 channel type into driver channel type.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -67,7 +84,7 @@ mwifiex_is_alg_wep(u32 cipher)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This function retrieves the private structure from kernel wiphy structure.
 | 
					 * This function retrieves the private structure from kernel wiphy structure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy)
 | 
					static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (void *) (*(unsigned long *) wiphy_priv(wiphy));
 | 
						return (void *) (*(unsigned long *) wiphy_priv(wiphy));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -80,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
				
			||||||
			 u8 key_index, bool pairwise, const u8 *mac_addr)
 | 
								 u8 key_index, bool pairwise, const u8 *mac_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 | 
						struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 | 
				
			||||||
 | 
						const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 | 
				
			||||||
 | 
						const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
 | 
						if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) {
 | 
				
			||||||
		wiphy_err(wiphy, "deleting the crypto keys\n");
 | 
							wiphy_err(wiphy, "deleting the crypto keys\n");
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -98,7 +117,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
 | 
				
			||||||
			      enum nl80211_tx_power_setting type,
 | 
								      enum nl80211_tx_power_setting type,
 | 
				
			||||||
			      int mbm)
 | 
								      int mbm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
						struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 | 
				
			||||||
 | 
						struct mwifiex_private *priv;
 | 
				
			||||||
	struct mwifiex_power_cfg power_cfg;
 | 
						struct mwifiex_power_cfg power_cfg;
 | 
				
			||||||
	int dbm = MBM_TO_DBM(mbm);
 | 
						int dbm = MBM_TO_DBM(mbm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,6 +129,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
 | 
				
			||||||
		power_cfg.is_power_auto = 1;
 | 
							power_cfg.is_power_auto = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mwifiex_set_tx_power(priv, &power_cfg);
 | 
						return mwifiex_set_tx_power(priv, &power_cfg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
				
			||||||
	if (!priv->sec_info.wep_enabled)
 | 
						if (!priv->sec_info.wep_enabled)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) {
 | 
						if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
 | 
				
			||||||
		wiphy_err(wiphy, "set default Tx key index\n");
 | 
							wiphy_err(wiphy, "set default Tx key index\n");
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -165,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
				
			||||||
			 struct key_params *params)
 | 
								 struct key_params *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 | 
						struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 | 
				
			||||||
 | 
						const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 | 
				
			||||||
 | 
						const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mwifiex_set_encode(priv, params->key, params->key_len,
 | 
						if (mwifiex_set_encode(priv, params->key, params->key_len,
 | 
				
			||||||
			       key_index, 0)) {
 | 
								       key_index, peer_mac, 0)) {
 | 
				
			||||||
		wiphy_err(wiphy, "crypto keys added\n");
 | 
							wiphy_err(wiphy, "crypto keys added\n");
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -192,13 +216,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 | 
				
			||||||
	enum ieee80211_band band;
 | 
						enum ieee80211_band band;
 | 
				
			||||||
	struct ieee80211_supported_band *sband;
 | 
						struct ieee80211_supported_band *sband;
 | 
				
			||||||
	struct ieee80211_channel *ch;
 | 
						struct ieee80211_channel *ch;
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
						struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 | 
				
			||||||
	struct mwifiex_adapter *adapter = priv->adapter;
 | 
						struct mwifiex_private *priv;
 | 
				
			||||||
	struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
 | 
						struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set country code */
 | 
						/* Set country code */
 | 
				
			||||||
	domain_info->country_code[0] = priv->country_code[0];
 | 
						domain_info->country_code[0] = adapter->country_code[0];
 | 
				
			||||||
	domain_info->country_code[1] = priv->country_code[1];
 | 
						domain_info->country_code[1] = adapter->country_code[1];
 | 
				
			||||||
	domain_info->country_code[2] = ' ';
 | 
						domain_info->country_code[2] = ' ';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	band = mwifiex_band_to_radio_type(adapter->config_bands);
 | 
						band = mwifiex_band_to_radio_type(adapter->config_bands);
 | 
				
			||||||
| 
						 | 
					@ -250,6 +274,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	domain_info->no_of_triplet = no_of_triplet;
 | 
						domain_info->no_of_triplet = no_of_triplet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
 | 
						if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
 | 
				
			||||||
				   HostCmd_ACT_GEN_SET, 0, NULL)) {
 | 
									   HostCmd_ACT_GEN_SET, 0, NULL)) {
 | 
				
			||||||
		wiphy_err(wiphy, "11D: setting domain info in FW\n");
 | 
							wiphy_err(wiphy, "11D: setting domain info in FW\n");
 | 
				
			||||||
| 
						 | 
					@ -272,12 +298,12 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 | 
				
			||||||
static int mwifiex_reg_notifier(struct wiphy *wiphy,
 | 
					static int mwifiex_reg_notifier(struct wiphy *wiphy,
 | 
				
			||||||
				struct regulatory_request *request)
 | 
									struct regulatory_request *request)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
						struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain"
 | 
						wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
 | 
				
			||||||
			" %c%c\n", request->alpha2[0], request->alpha2[1]);
 | 
							  request->alpha2[0], request->alpha2[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
 | 
						memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (request->initiator) {
 | 
						switch (request->initiator) {
 | 
				
			||||||
	case NL80211_REGDOM_SET_BY_DRIVER:
 | 
						case NL80211_REGDOM_SET_BY_DRIVER:
 | 
				
			||||||
| 
						 | 
					@ -361,33 +387,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
 | 
				
			||||||
	if (mwifiex_bss_set_channel(priv, &cfp))
 | 
						if (mwifiex_bss_set_channel(priv, &cfp))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
 | 
				
			||||||
		return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
 | 
							return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * CFG802.11 operation handler to set channel.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This function can only be used when station is not connected.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 | 
					 | 
				
			||||||
			     struct ieee80211_channel *chan,
 | 
					 | 
				
			||||||
			     enum nl80211_channel_type channel_type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct mwifiex_private *priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (dev)
 | 
					 | 
				
			||||||
		priv = mwifiex_netdev_get_priv(dev);
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
							return mwifiex_uap_set_channel(priv, cfp.channel);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (priv->media_connected) {
 | 
					 | 
				
			||||||
		wiphy_err(wiphy, "This setting is valid only when station "
 | 
					 | 
				
			||||||
				"is not connected\n");
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mwifiex_set_rf_channel(priv, chan, channel_type);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -399,18 +402,13 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
 | 
					mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
 | 
						if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
 | 
				
			||||||
	    frag_thr > MWIFIEX_FRAG_MAX_VALUE)
 | 
						    frag_thr > MWIFIEX_FRAG_MAX_VALUE)
 | 
				
			||||||
		return -EINVAL;
 | 
							frag_thr = MWIFIEX_FRAG_MAX_VALUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Send request to firmware */
 | 
						return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
 | 
				
			||||||
	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
 | 
					 | 
				
			||||||
				     HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
 | 
									     HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
 | 
				
			||||||
				     &frag_thr);
 | 
									     &frag_thr);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -439,19 +437,85 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 | 
					mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
						struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 | 
				
			||||||
	int ret = 0;
 | 
						struct mwifiex_private *priv;
 | 
				
			||||||
 | 
						struct mwifiex_uap_bss_param *bss_cfg;
 | 
				
			||||||
 | 
						int ret, bss_started, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
 | 
						for (i = 0; i < adapter->priv_num; i++) {
 | 
				
			||||||
		ret = mwifiex_set_rts(priv, wiphy->rts_threshold);
 | 
							priv = adapter->priv[i];
 | 
				
			||||||
		if (ret)
 | 
					
 | 
				
			||||||
 | 
							switch (priv->bss_role) {
 | 
				
			||||||
 | 
							case MWIFIEX_BSS_ROLE_UAP:
 | 
				
			||||||
 | 
								bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
 | 
				
			||||||
 | 
										  GFP_KERNEL);
 | 
				
			||||||
 | 
								if (!bss_cfg)
 | 
				
			||||||
 | 
									return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								mwifiex_set_sys_config_invalid_data(bss_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (changed & WIPHY_PARAM_RTS_THRESHOLD)
 | 
				
			||||||
 | 
									bss_cfg->rts_threshold = wiphy->rts_threshold;
 | 
				
			||||||
 | 
								if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
 | 
				
			||||||
 | 
									bss_cfg->frag_threshold = wiphy->frag_threshold;
 | 
				
			||||||
 | 
								if (changed & WIPHY_PARAM_RETRY_LONG)
 | 
				
			||||||
 | 
									bss_cfg->retry_limit = wiphy->retry_long;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								bss_started = priv->bss_started;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ret = mwifiex_send_cmd_sync(priv,
 | 
				
			||||||
 | 
											    HostCmd_CMD_UAP_BSS_STOP,
 | 
				
			||||||
 | 
											    HostCmd_ACT_GEN_SET, 0,
 | 
				
			||||||
 | 
											    NULL);
 | 
				
			||||||
 | 
								if (ret) {
 | 
				
			||||||
 | 
									wiphy_err(wiphy, "Failed to stop the BSS\n");
 | 
				
			||||||
 | 
									kfree(bss_cfg);
 | 
				
			||||||
				return ret;
 | 
									return ret;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
 | 
								ret = mwifiex_send_cmd_async(priv,
 | 
				
			||||||
		ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
 | 
											     HostCmd_CMD_UAP_SYS_CONFIG,
 | 
				
			||||||
 | 
											     HostCmd_ACT_GEN_SET,
 | 
				
			||||||
 | 
											     UAP_BSS_PARAMS_I, bss_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								kfree(bss_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (ret) {
 | 
				
			||||||
 | 
									wiphy_err(wiphy, "Failed to set bss config\n");
 | 
				
			||||||
				return ret;
 | 
									return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!bss_started)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ret = mwifiex_send_cmd_async(priv,
 | 
				
			||||||
 | 
											     HostCmd_CMD_UAP_BSS_START,
 | 
				
			||||||
 | 
											     HostCmd_ACT_GEN_SET, 0,
 | 
				
			||||||
 | 
											     NULL);
 | 
				
			||||||
 | 
								if (ret) {
 | 
				
			||||||
 | 
									wiphy_err(wiphy, "Failed to start BSS\n");
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case MWIFIEX_BSS_ROLE_STA:
 | 
				
			||||||
 | 
								if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
 | 
				
			||||||
 | 
									ret = mwifiex_set_rts(priv,
 | 
				
			||||||
 | 
											      wiphy->rts_threshold);
 | 
				
			||||||
 | 
									if (ret)
 | 
				
			||||||
 | 
										return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
 | 
				
			||||||
 | 
									ret = mwifiex_set_frag(priv,
 | 
				
			||||||
 | 
											       wiphy->frag_threshold);
 | 
				
			||||||
 | 
									if (ret)
 | 
				
			||||||
 | 
										return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -466,31 +530,59 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 | 
						struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->bss_mode == type) {
 | 
						switch (dev->ieee80211_ptr->iftype) {
 | 
				
			||||||
		wiphy_warn(wiphy, "already set to required type\n");
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	priv->bss_mode = type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (type) {
 | 
					 | 
				
			||||||
	case NL80211_IFTYPE_ADHOC:
 | 
						case NL80211_IFTYPE_ADHOC:
 | 
				
			||||||
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
 | 
							switch (type) {
 | 
				
			||||||
		wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
		case NL80211_IFTYPE_STATION:
 | 
							case NL80211_IFTYPE_STATION:
 | 
				
			||||||
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
 | 
					 | 
				
			||||||
		wiphy_dbg(wiphy, "info: setting interface type to managed\n");
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case NL80211_IFTYPE_UNSPECIFIED:
 | 
							case NL80211_IFTYPE_UNSPECIFIED:
 | 
				
			||||||
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
 | 
								wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
 | 
				
			||||||
		wiphy_dbg(wiphy, "info: setting interface type to auto\n");
 | 
							case NL80211_IFTYPE_ADHOC:	/* This shouldn't happen */
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_AP:
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
		wiphy_err(wiphy, "unknown interface type: %d\n", type);
 | 
								wiphy_err(wiphy, "%s: changing to %d not supported\n",
 | 
				
			||||||
		return -EINVAL;
 | 
									  dev->name, type);
 | 
				
			||||||
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NL80211_IFTYPE_STATION:
 | 
				
			||||||
 | 
							switch (type) {
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_ADHOC:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_UNSPECIFIED:
 | 
				
			||||||
 | 
								wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_STATION:	/* This shouldn't happen */
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_AP:
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								wiphy_err(wiphy, "%s: changing to %d not supported\n",
 | 
				
			||||||
 | 
									  dev->name, type);
 | 
				
			||||||
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NL80211_IFTYPE_AP:
 | 
				
			||||||
 | 
							switch (type) {
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_UNSPECIFIED:
 | 
				
			||||||
 | 
								wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_AP:		/* This shouldn't happen */
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_ADHOC:
 | 
				
			||||||
 | 
							case NL80211_IFTYPE_STATION:
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								wiphy_err(wiphy, "%s: changing to %d not supported\n",
 | 
				
			||||||
 | 
									  dev->name, type);
 | 
				
			||||||
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "%s: unknown iftype: %d\n",
 | 
				
			||||||
 | 
								  dev->name, dev->ieee80211_ptr->iftype);
 | 
				
			||||||
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev->ieee80211_ptr->iftype = type;
 | 
				
			||||||
 | 
						priv->bss_mode = type;
 | 
				
			||||||
	mwifiex_deauthenticate(priv, NULL);
 | 
						mwifiex_deauthenticate(priv, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
 | 
						priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
 | 
				
			||||||
| 
						 | 
					@ -804,6 +896,90 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* cfg80211 operation handler for stop ap.
 | 
				
			||||||
 | 
					 * Function stops BSS running at uAP interface.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_del_mgmt_ies(priv))
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
 | 
				
			||||||
 | 
									  HostCmd_ACT_GEN_SET, 0, NULL)) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to stop the BSS\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* cfg80211 operation handler for start_ap.
 | 
				
			||||||
 | 
					 * Function sets beacon period, DTIM period, SSID and security into
 | 
				
			||||||
 | 
					 * AP config structure.
 | 
				
			||||||
 | 
					 * AP is configured with these settings and BSS is started.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
 | 
				
			||||||
 | 
									     struct net_device *dev,
 | 
				
			||||||
 | 
									     struct cfg80211_ap_settings *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_uap_bss_param *bss_cfg;
 | 
				
			||||||
 | 
						struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if (mwifiex_set_mgmt_ies(priv, params))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!bss_cfg)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mwifiex_set_sys_config_invalid_data(bss_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->beacon_interval)
 | 
				
			||||||
 | 
							bss_cfg->beacon_period = params->beacon_interval;
 | 
				
			||||||
 | 
						if (params->dtim_period)
 | 
				
			||||||
 | 
							bss_cfg->dtim_period = params->dtim_period;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->ssid && params->ssid_len) {
 | 
				
			||||||
 | 
							memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
 | 
				
			||||||
 | 
							bss_cfg->ssid.ssid_len = params->ssid_len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
 | 
				
			||||||
 | 
							kfree(bss_cfg);
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
 | 
				
			||||||
 | 
									  HostCmd_ACT_GEN_SET, 0, NULL)) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to stop the BSS\n");
 | 
				
			||||||
 | 
							kfree(bss_cfg);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
 | 
				
			||||||
 | 
									   HostCmd_ACT_GEN_SET,
 | 
				
			||||||
 | 
									   UAP_BSS_PARAMS_I, bss_cfg)) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to set the SSID\n");
 | 
				
			||||||
 | 
							kfree(bss_cfg);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(bss_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START,
 | 
				
			||||||
 | 
									   HostCmd_ACT_GEN_SET, 0, NULL)) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to start the BSS\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * CFG802.11 operation handler for disconnection request.
 | 
					 * CFG802.11 operation handler for disconnection request.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -923,7 +1099,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
 | 
				
			||||||
	priv->wep_key_curr_index = 0;
 | 
						priv->wep_key_curr_index = 0;
 | 
				
			||||||
	priv->sec_info.encryption_mode = 0;
 | 
						priv->sec_info.encryption_mode = 0;
 | 
				
			||||||
	priv->sec_info.is_authtype_auto = 0;
 | 
						priv->sec_info.is_authtype_auto = 0;
 | 
				
			||||||
	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
 | 
						ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mode == NL80211_IFTYPE_ADHOC) {
 | 
						if (mode == NL80211_IFTYPE_ADHOC) {
 | 
				
			||||||
		/* "privacy" is set only for ad-hoc mode */
 | 
							/* "privacy" is set only for ad-hoc mode */
 | 
				
			||||||
| 
						 | 
					@ -971,7 +1147,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
 | 
				
			||||||
				" with key len %d\n", sme->key_len);
 | 
									" with key len %d\n", sme->key_len);
 | 
				
			||||||
			priv->wep_key_curr_index = sme->key_idx;
 | 
								priv->wep_key_curr_index = sme->key_idx;
 | 
				
			||||||
			ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
 | 
								ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
 | 
				
			||||||
							sme->key_idx, 0);
 | 
											 sme->key_idx, NULL, 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
| 
						 | 
					@ -1050,6 +1226,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->bss_mode == NL80211_IFTYPE_AP) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "skip association request for AP interface\n");
 | 
				
			||||||
 | 
							goto done;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
 | 
						wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
 | 
				
			||||||
		  (char *) sme->ssid, sme->bssid);
 | 
							  (char *) sme->ssid, sme->bssid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1283,15 +1464,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
					    u32 *flags,
 | 
										    u32 *flags,
 | 
				
			||||||
					    struct vif_params *params)
 | 
										    struct vif_params *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 | 
						struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 | 
				
			||||||
	struct mwifiex_adapter *adapter;
 | 
						struct mwifiex_private *priv;
 | 
				
			||||||
	struct net_device *dev;
 | 
						struct net_device *dev;
 | 
				
			||||||
	void *mdev_priv;
 | 
						void *mdev_priv;
 | 
				
			||||||
 | 
						struct wireless_dev *wdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!priv)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	adapter = priv->adapter;
 | 
					 | 
				
			||||||
	if (!adapter)
 | 
						if (!adapter)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1299,12 +1477,21 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
	case NL80211_IFTYPE_UNSPECIFIED:
 | 
						case NL80211_IFTYPE_UNSPECIFIED:
 | 
				
			||||||
	case NL80211_IFTYPE_STATION:
 | 
						case NL80211_IFTYPE_STATION:
 | 
				
			||||||
	case NL80211_IFTYPE_ADHOC:
 | 
						case NL80211_IFTYPE_ADHOC:
 | 
				
			||||||
 | 
							priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
 | 
				
			||||||
		if (priv->bss_mode) {
 | 
							if (priv->bss_mode) {
 | 
				
			||||||
			wiphy_err(wiphy, "cannot create multiple"
 | 
								wiphy_err(wiphy,
 | 
				
			||||||
					" station/adhoc interfaces\n");
 | 
									  "cannot create multiple sta/adhoc ifaces\n");
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!wdev)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wdev->wiphy = wiphy;
 | 
				
			||||||
 | 
							priv->wdev = wdev;
 | 
				
			||||||
 | 
							wdev->iftype = NL80211_IFTYPE_STATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (type == NL80211_IFTYPE_UNSPECIFIED)
 | 
							if (type == NL80211_IFTYPE_UNSPECIFIED)
 | 
				
			||||||
			priv->bss_mode = NL80211_IFTYPE_STATION;
 | 
								priv->bss_mode = NL80211_IFTYPE_STATION;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -1312,10 +1499,35 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		priv->bss_type = MWIFIEX_BSS_TYPE_STA;
 | 
							priv->bss_type = MWIFIEX_BSS_TYPE_STA;
 | 
				
			||||||
		priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
 | 
							priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
 | 
				
			||||||
		priv->bss_priority = 0;
 | 
							priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
 | 
				
			||||||
		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
 | 
							priv->bss_role = MWIFIEX_BSS_ROLE_STA;
 | 
				
			||||||
		priv->bss_num = 0;
 | 
							priv->bss_num = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NL80211_IFTYPE_AP:
 | 
				
			||||||
 | 
							priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (priv->bss_mode) {
 | 
				
			||||||
 | 
								wiphy_err(wiphy, "Can't create multiple AP interfaces");
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!wdev)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							priv->wdev = wdev;
 | 
				
			||||||
 | 
							wdev->wiphy = wiphy;
 | 
				
			||||||
 | 
							wdev->iftype = NL80211_IFTYPE_AP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
 | 
				
			||||||
 | 
							priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
 | 
				
			||||||
 | 
							priv->bss_priority = MWIFIEX_BSS_ROLE_UAP;
 | 
				
			||||||
 | 
							priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
 | 
				
			||||||
 | 
							priv->bss_started = 0;
 | 
				
			||||||
 | 
							priv->bss_num = 0;
 | 
				
			||||||
 | 
							priv->bss_mode = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		wiphy_err(wiphy, "type not supported\n");
 | 
							wiphy_err(wiphy, "type not supported\n");
 | 
				
			||||||
| 
						 | 
					@ -1329,6 +1541,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mwifiex_init_priv_params(priv, dev);
 | 
				
			||||||
 | 
						priv->netdev = dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adapter->config_bands & BAND_A)
 | 
				
			||||||
 | 
							mwifiex_setup_ht_caps(
 | 
				
			||||||
 | 
								&wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_net_set(dev, wiphy_net(wiphy));
 | 
						dev_net_set(dev, wiphy_net(wiphy));
 | 
				
			||||||
	dev->ieee80211_ptr = priv->wdev;
 | 
						dev->ieee80211_ptr = priv->wdev;
 | 
				
			||||||
	dev->ieee80211_ptr->iftype = priv->bss_mode;
 | 
						dev->ieee80211_ptr->iftype = priv->bss_mode;
 | 
				
			||||||
| 
						 | 
					@ -1343,9 +1564,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
	mdev_priv = netdev_priv(dev);
 | 
						mdev_priv = netdev_priv(dev);
 | 
				
			||||||
	*((unsigned long *) mdev_priv) = (unsigned long) priv;
 | 
						*((unsigned long *) mdev_priv) = (unsigned long) priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->netdev = dev;
 | 
					 | 
				
			||||||
	mwifiex_init_priv_params(priv, dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SET_NETDEV_DEV(dev, adapter->dev);
 | 
						SET_NETDEV_DEV(dev, adapter->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Register network device */
 | 
						/* Register network device */
 | 
				
			||||||
| 
						 | 
					@ -1417,7 +1635,6 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 | 
				
			||||||
	.get_station = mwifiex_cfg80211_get_station,
 | 
						.get_station = mwifiex_cfg80211_get_station,
 | 
				
			||||||
	.dump_station = mwifiex_cfg80211_dump_station,
 | 
						.dump_station = mwifiex_cfg80211_dump_station,
 | 
				
			||||||
	.set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
 | 
						.set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
 | 
				
			||||||
	.set_channel = mwifiex_cfg80211_set_channel,
 | 
					 | 
				
			||||||
	.join_ibss = mwifiex_cfg80211_join_ibss,
 | 
						.join_ibss = mwifiex_cfg80211_join_ibss,
 | 
				
			||||||
	.leave_ibss = mwifiex_cfg80211_leave_ibss,
 | 
						.leave_ibss = mwifiex_cfg80211_leave_ibss,
 | 
				
			||||||
	.add_key = mwifiex_cfg80211_add_key,
 | 
						.add_key = mwifiex_cfg80211_add_key,
 | 
				
			||||||
| 
						 | 
					@ -1426,6 +1643,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 | 
				
			||||||
	.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
 | 
						.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
 | 
				
			||||||
	.set_tx_power = mwifiex_cfg80211_set_tx_power,
 | 
						.set_tx_power = mwifiex_cfg80211_set_tx_power,
 | 
				
			||||||
	.set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
 | 
						.set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
 | 
				
			||||||
 | 
						.start_ap = mwifiex_cfg80211_start_ap,
 | 
				
			||||||
 | 
						.stop_ap = mwifiex_cfg80211_stop_ap,
 | 
				
			||||||
	.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
 | 
						.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1436,82 +1655,67 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 | 
				
			||||||
 * default parameters and handler function pointers, and finally
 | 
					 * default parameters and handler function pointers, and finally
 | 
				
			||||||
 * registers the device.
 | 
					 * registers the device.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int mwifiex_register_cfg80211(struct mwifiex_private *priv)
 | 
					
 | 
				
			||||||
 | 
					int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	void *wdev_priv;
 | 
						void *wdev_priv;
 | 
				
			||||||
	struct wireless_dev *wdev;
 | 
						struct wiphy *wiphy;
 | 
				
			||||||
	struct ieee80211_sta_ht_cap *ht_info;
 | 
						struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
 | 
				
			||||||
	u8 *country_code;
 | 
						u8 *country_code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
 | 
						/* create a new wiphy for use with cfg80211 */
 | 
				
			||||||
	if (!wdev) {
 | 
						wiphy = wiphy_new(&mwifiex_cfg80211_ops,
 | 
				
			||||||
		dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
 | 
								  sizeof(struct mwifiex_adapter *));
 | 
				
			||||||
			__func__);
 | 
						if (!wiphy) {
 | 
				
			||||||
 | 
							dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wdev->wiphy =
 | 
						wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
 | 
				
			||||||
		wiphy_new(&mwifiex_cfg80211_ops,
 | 
						wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
 | 
				
			||||||
			  sizeof(struct mwifiex_private *));
 | 
						wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 | 
				
			||||||
	if (!wdev->wiphy) {
 | 
									 BIT(NL80211_IFTYPE_ADHOC) |
 | 
				
			||||||
		kfree(wdev);
 | 
									 BIT(NL80211_IFTYPE_AP);
 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	wdev->iftype = NL80211_IFTYPE_STATION;
 | 
					 | 
				
			||||||
	wdev->wiphy->max_scan_ssids = 10;
 | 
					 | 
				
			||||||
	wdev->wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
 | 
					 | 
				
			||||||
	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 | 
					 | 
				
			||||||
				       BIT(NL80211_IFTYPE_ADHOC);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
 | 
						wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
 | 
				
			||||||
	ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap;
 | 
						if (adapter->config_bands & BAND_A)
 | 
				
			||||||
	mwifiex_setup_ht_caps(ht_info, priv);
 | 
							wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->adapter->config_bands & BAND_A) {
 | 
						wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
 | 
				
			||||||
		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
 | 
						wiphy->n_iface_combinations = 1;
 | 
				
			||||||
		ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap;
 | 
					 | 
				
			||||||
		mwifiex_setup_ht_caps(ht_info, priv);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Initialize cipher suits */
 | 
						/* Initialize cipher suits */
 | 
				
			||||||
	wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
 | 
						wiphy->cipher_suites = mwifiex_cipher_suites;
 | 
				
			||||||
	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
 | 
						wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
 | 
						memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
 | 
				
			||||||
	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 | 
						wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 | 
				
			||||||
 | 
						wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Reserve space for mwifiex specific private data for BSS */
 | 
						/* Reserve space for mwifiex specific private data for BSS */
 | 
				
			||||||
	wdev->wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
 | 
						wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
 | 
						wiphy->reg_notifier = mwifiex_reg_notifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set struct mwifiex_private pointer in wiphy_priv */
 | 
						/* Set struct mwifiex_adapter pointer in wiphy_priv */
 | 
				
			||||||
	wdev_priv = wiphy_priv(wdev->wiphy);
 | 
						wdev_priv = wiphy_priv(wiphy);
 | 
				
			||||||
 | 
						*(unsigned long *)wdev_priv = (unsigned long)adapter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*(unsigned long *) wdev_priv = (unsigned long) priv;
 | 
						set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev);
 | 
						ret = wiphy_register(wiphy);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = wiphy_register(wdev->wiphy);
 | 
					 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
 | 
							dev_err(adapter->dev,
 | 
				
			||||||
			__func__);
 | 
								"%s: wiphy_register failed: %d\n", __func__, ret);
 | 
				
			||||||
		wiphy_free(wdev->wiphy);
 | 
							wiphy_free(wiphy);
 | 
				
			||||||
		kfree(wdev);
 | 
					 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		dev_dbg(priv->adapter->dev,
 | 
					 | 
				
			||||||
			"info: successfully registered wiphy device\n");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
 | 
						country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
 | 
				
			||||||
	if (country_code && regulatory_hint(wdev->wiphy, country_code))
 | 
						if (country_code && regulatory_hint(wiphy, country_code))
 | 
				
			||||||
		dev_err(priv->adapter->dev,
 | 
							dev_err(adapter->dev, "regulatory_hint() failed\n");
 | 
				
			||||||
			"%s: regulatory_hint failed\n", __func__);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	priv->wdev = wdev;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adapter->wiphy = wiphy;
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "main.h"
 | 
					#include "main.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mwifiex_register_cfg80211(struct mwifiex_private *);
 | 
					int mwifiex_register_cfg80211(struct mwifiex_adapter *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -440,6 +440,11 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
 | 
				
			||||||
		do_gettimeofday(&tstamp);
 | 
							do_gettimeofday(&tstamp);
 | 
				
			||||||
		dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
 | 
							dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
 | 
				
			||||||
			tstamp.tv_sec, tstamp.tv_usec, eventcause);
 | 
								tstamp.tv_sec, tstamp.tv_usec, eventcause);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/* Handle PS_SLEEP/AWAKE events on STA */
 | 
				
			||||||
 | 
							priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
 | 
				
			||||||
 | 
							if (!priv)
 | 
				
			||||||
 | 
								priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = mwifiex_process_sta_event(priv);
 | 
						ret = mwifiex_process_sta_event(priv);
 | 
				
			||||||
| 
						 | 
					@ -540,8 +545,20 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Prepare command */
 | 
						/* Prepare command */
 | 
				
			||||||
	if (cmd_no) {
 | 
						if (cmd_no) {
 | 
				
			||||||
 | 
							switch (cmd_no) {
 | 
				
			||||||
 | 
							case HostCmd_CMD_UAP_SYS_CONFIG:
 | 
				
			||||||
 | 
							case HostCmd_CMD_UAP_BSS_START:
 | 
				
			||||||
 | 
							case HostCmd_CMD_UAP_BSS_STOP:
 | 
				
			||||||
 | 
								ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
 | 
				
			||||||
 | 
											      cmd_oid, data_buf,
 | 
				
			||||||
 | 
											      cmd_ptr);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
			ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
 | 
								ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
 | 
				
			||||||
					      cmd_oid, data_buf, cmd_ptr);
 | 
											      cmd_oid, data_buf,
 | 
				
			||||||
 | 
											      cmd_ptr);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
 | 
							ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
 | 
				
			||||||
		cmd_node->cmd_flag |= CMD_F_HOSTCMD;
 | 
							cmd_node->cmd_flag |= CMD_F_HOSTCMD;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@
 | 
				
			||||||
#include <linux/ieee80211.h>
 | 
					#include <linux/ieee80211.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_MAX_BSS_NUM         (1)
 | 
					#define MWIFIEX_MAX_BSS_NUM         (2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_MIN_DATA_HEADER_LEN 36	/* sizeof(mwifiex_txpd)
 | 
					#define MWIFIEX_MIN_DATA_HEADER_LEN 36	/* sizeof(mwifiex_txpd)
 | 
				
			||||||
					 *   + 4 byte alignment
 | 
										 *   + 4 byte alignment
 | 
				
			||||||
| 
						 | 
					@ -55,11 +55,17 @@
 | 
				
			||||||
#define MWIFIEX_RX_DATA_BUF_SIZE     (4 * 1024)
 | 
					#define MWIFIEX_RX_DATA_BUF_SIZE     (4 * 1024)
 | 
				
			||||||
#define MWIFIEX_RX_CMD_BUF_SIZE	     (2 * 1024)
 | 
					#define MWIFIEX_RX_CMD_BUF_SIZE	     (2 * 1024)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_BEACON_PERIOD                  (4000)
 | 
				
			||||||
 | 
					#define MIN_BEACON_PERIOD                  (50)
 | 
				
			||||||
 | 
					#define MAX_DTIM_PERIOD                    (100)
 | 
				
			||||||
 | 
					#define MIN_DTIM_PERIOD                    (1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_RTS_MIN_VALUE              (0)
 | 
					#define MWIFIEX_RTS_MIN_VALUE              (0)
 | 
				
			||||||
#define MWIFIEX_RTS_MAX_VALUE              (2347)
 | 
					#define MWIFIEX_RTS_MAX_VALUE              (2347)
 | 
				
			||||||
#define MWIFIEX_FRAG_MIN_VALUE             (256)
 | 
					#define MWIFIEX_FRAG_MIN_VALUE             (256)
 | 
				
			||||||
#define MWIFIEX_FRAG_MAX_VALUE             (2346)
 | 
					#define MWIFIEX_FRAG_MAX_VALUE             (2346)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MWIFIEX_RETRY_LIMIT                14
 | 
				
			||||||
#define MWIFIEX_SDIO_BLOCK_SIZE            256
 | 
					#define MWIFIEX_SDIO_BLOCK_SIZE            256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_BUF_FLAG_REQUEUED_PKT      BIT(0)
 | 
					#define MWIFIEX_BUF_FLAG_REQUEUED_PKT      BIT(0)
 | 
				
			||||||
| 
						 | 
					@ -92,6 +98,11 @@ struct mwifiex_fw_image {
 | 
				
			||||||
	u32 fw_len;
 | 
						u32 fw_len;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mwifiex_802_11_ssid {
 | 
				
			||||||
 | 
						u32 ssid_len;
 | 
				
			||||||
 | 
						u8 ssid[IEEE80211_MAX_SSID_LEN];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mwifiex_wait_queue {
 | 
					struct mwifiex_wait_queue {
 | 
				
			||||||
	wait_queue_head_t wait;
 | 
						wait_queue_head_t wait;
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,20 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAL_SNR(RSSI, NF)		((s16)((s16)(RSSI)-(s16)(NF)))
 | 
					#define CAL_SNR(RSSI, NF)		((s16)((s16)(RSSI)-(s16)(NF)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UAP_BSS_PARAMS_I			0
 | 
				
			||||||
 | 
					#define UAP_CUSTOM_IE_I				1
 | 
				
			||||||
 | 
					#define MWIFIEX_AUTO_IDX_MASK			0xffff
 | 
				
			||||||
 | 
					#define MWIFIEX_DELETE_MASK			0x0000
 | 
				
			||||||
 | 
					#define MGMT_MASK_ASSOC_REQ			0x01
 | 
				
			||||||
 | 
					#define MGMT_MASK_REASSOC_REQ			0x04
 | 
				
			||||||
 | 
					#define MGMT_MASK_ASSOC_RESP			0x02
 | 
				
			||||||
 | 
					#define MGMT_MASK_REASSOC_RESP			0x08
 | 
				
			||||||
 | 
					#define MGMT_MASK_PROBE_REQ			0x10
 | 
				
			||||||
 | 
					#define MGMT_MASK_PROBE_RESP			0x20
 | 
				
			||||||
 | 
					#define MGMT_MASK_BEACON			0x100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_SSID			0x0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PROPRIETARY_TLV_BASE_ID                 0x0100
 | 
					#define PROPRIETARY_TLV_BASE_ID                 0x0100
 | 
				
			||||||
#define TLV_TYPE_KEY_MATERIAL       (PROPRIETARY_TLV_BASE_ID + 0)
 | 
					#define TLV_TYPE_KEY_MATERIAL       (PROPRIETARY_TLV_BASE_ID + 0)
 | 
				
			||||||
#define TLV_TYPE_CHANLIST           (PROPRIETARY_TLV_BASE_ID + 1)
 | 
					#define TLV_TYPE_CHANLIST           (PROPRIETARY_TLV_BASE_ID + 1)
 | 
				
			||||||
| 
						 | 
					@ -104,14 +118,26 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 | 
				
			||||||
#define TLV_TYPE_TSFTIMESTAMP       (PROPRIETARY_TLV_BASE_ID + 19)
 | 
					#define TLV_TYPE_TSFTIMESTAMP       (PROPRIETARY_TLV_BASE_ID + 19)
 | 
				
			||||||
#define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
 | 
					#define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
 | 
				
			||||||
#define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
 | 
					#define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
 | 
				
			||||||
 | 
					#define TLV_TYPE_STA_MAC_ADDR       (PROPRIETARY_TLV_BASE_ID + 32)
 | 
				
			||||||
#define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
 | 
					#define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_BEACON_PERIOD  (PROPRIETARY_TLV_BASE_ID + 44)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_DTIM_PERIOD    (PROPRIETARY_TLV_BASE_ID + 45)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_RTS_THRESHOLD  (PROPRIETARY_TLV_BASE_ID + 51)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_AKMP           (PROPRIETARY_TLV_BASE_ID + 65)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_FRAG_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 70)
 | 
				
			||||||
#define TLV_TYPE_RATE_DROP_CONTROL  (PROPRIETARY_TLV_BASE_ID + 82)
 | 
					#define TLV_TYPE_RATE_DROP_CONTROL  (PROPRIETARY_TLV_BASE_ID + 82)
 | 
				
			||||||
#define TLV_TYPE_RATE_SCOPE         (PROPRIETARY_TLV_BASE_ID + 83)
 | 
					#define TLV_TYPE_RATE_SCOPE         (PROPRIETARY_TLV_BASE_ID + 83)
 | 
				
			||||||
#define TLV_TYPE_POWER_GROUP        (PROPRIETARY_TLV_BASE_ID + 84)
 | 
					#define TLV_TYPE_POWER_GROUP        (PROPRIETARY_TLV_BASE_ID + 84)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_RETRY_LIMIT    (PROPRIETARY_TLV_BASE_ID + 93)
 | 
				
			||||||
#define TLV_TYPE_WAPI_IE            (PROPRIETARY_TLV_BASE_ID + 94)
 | 
					#define TLV_TYPE_WAPI_IE            (PROPRIETARY_TLV_BASE_ID + 94)
 | 
				
			||||||
 | 
					#define TLV_TYPE_UAP_MGMT_FRAME     (PROPRIETARY_TLV_BASE_ID + 104)
 | 
				
			||||||
#define TLV_TYPE_MGMT_IE            (PROPRIETARY_TLV_BASE_ID + 105)
 | 
					#define TLV_TYPE_MGMT_IE            (PROPRIETARY_TLV_BASE_ID + 105)
 | 
				
			||||||
#define TLV_TYPE_AUTO_DS_PARAM      (PROPRIETARY_TLV_BASE_ID + 113)
 | 
					#define TLV_TYPE_AUTO_DS_PARAM      (PROPRIETARY_TLV_BASE_ID + 113)
 | 
				
			||||||
#define TLV_TYPE_PS_PARAM           (PROPRIETARY_TLV_BASE_ID + 114)
 | 
					#define TLV_TYPE_PS_PARAM           (PROPRIETARY_TLV_BASE_ID + 114)
 | 
				
			||||||
 | 
					#define TLV_TYPE_PWK_CIPHER         (PROPRIETARY_TLV_BASE_ID + 145)
 | 
				
			||||||
 | 
					#define TLV_TYPE_GWK_CIPHER         (PROPRIETARY_TLV_BASE_ID + 146)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_TX_DATA_BUF_SIZE_2K        2048
 | 
					#define MWIFIEX_TX_DATA_BUF_SIZE_2K        2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,6 +235,9 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 | 
				
			||||||
#define HostCmd_CMD_RSSI_INFO                         0x00a4
 | 
					#define HostCmd_CMD_RSSI_INFO                         0x00a4
 | 
				
			||||||
#define HostCmd_CMD_FUNC_INIT                         0x00a9
 | 
					#define HostCmd_CMD_FUNC_INIT                         0x00a9
 | 
				
			||||||
#define HostCmd_CMD_FUNC_SHUTDOWN                     0x00aa
 | 
					#define HostCmd_CMD_FUNC_SHUTDOWN                     0x00aa
 | 
				
			||||||
 | 
					#define HostCmd_CMD_UAP_SYS_CONFIG                    0x00b0
 | 
				
			||||||
 | 
					#define HostCmd_CMD_UAP_BSS_START                     0x00b1
 | 
				
			||||||
 | 
					#define HostCmd_CMD_UAP_BSS_STOP                      0x00b2
 | 
				
			||||||
#define HostCmd_CMD_11N_CFG                           0x00cd
 | 
					#define HostCmd_CMD_11N_CFG                           0x00cd
 | 
				
			||||||
#define HostCmd_CMD_11N_ADDBA_REQ                     0x00ce
 | 
					#define HostCmd_CMD_11N_ADDBA_REQ                     0x00ce
 | 
				
			||||||
#define HostCmd_CMD_11N_ADDBA_RSP                     0x00cf
 | 
					#define HostCmd_CMD_11N_ADDBA_RSP                     0x00cf
 | 
				
			||||||
| 
						 | 
					@ -223,6 +252,19 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 | 
				
			||||||
#define HostCmd_CMD_SET_BSS_MODE                      0x00f7
 | 
					#define HostCmd_CMD_SET_BSS_MODE                      0x00f7
 | 
				
			||||||
#define HostCmd_CMD_PCIE_DESC_DETAILS                 0x00fa
 | 
					#define HostCmd_CMD_PCIE_DESC_DETAILS                 0x00fa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PROTOCOL_NO_SECURITY        0x01
 | 
				
			||||||
 | 
					#define PROTOCOL_STATIC_WEP         0x02
 | 
				
			||||||
 | 
					#define PROTOCOL_WPA                0x08
 | 
				
			||||||
 | 
					#define PROTOCOL_WPA2               0x20
 | 
				
			||||||
 | 
					#define PROTOCOL_WPA2_MIXED         0x28
 | 
				
			||||||
 | 
					#define PROTOCOL_EAP                0x40
 | 
				
			||||||
 | 
					#define KEY_MGMT_NONE               0x04
 | 
				
			||||||
 | 
					#define KEY_MGMT_PSK                0x02
 | 
				
			||||||
 | 
					#define KEY_MGMT_EAP                0x01
 | 
				
			||||||
 | 
					#define CIPHER_TKIP                 0x04
 | 
				
			||||||
 | 
					#define CIPHER_AES_CCMP             0x08
 | 
				
			||||||
 | 
					#define VALID_CIPHER_BITMAP         0x0c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum ENH_PS_MODES {
 | 
					enum ENH_PS_MODES {
 | 
				
			||||||
	EN_PS = 1,
 | 
						EN_PS = 1,
 | 
				
			||||||
	DIS_PS = 2,
 | 
						DIS_PS = 2,
 | 
				
			||||||
| 
						 | 
					@ -313,15 +355,20 @@ enum ENH_PS_MODES {
 | 
				
			||||||
#define EVENT_DATA_SNR_HIGH             0x00000027
 | 
					#define EVENT_DATA_SNR_HIGH             0x00000027
 | 
				
			||||||
#define EVENT_LINK_QUALITY              0x00000028
 | 
					#define EVENT_LINK_QUALITY              0x00000028
 | 
				
			||||||
#define EVENT_PORT_RELEASE              0x0000002b
 | 
					#define EVENT_PORT_RELEASE              0x0000002b
 | 
				
			||||||
 | 
					#define EVENT_UAP_STA_DEAUTH            0x0000002c
 | 
				
			||||||
 | 
					#define EVENT_UAP_STA_ASSOC             0x0000002d
 | 
				
			||||||
 | 
					#define EVENT_UAP_BSS_START             0x0000002e
 | 
				
			||||||
#define EVENT_PRE_BEACON_LOST           0x00000031
 | 
					#define EVENT_PRE_BEACON_LOST           0x00000031
 | 
				
			||||||
#define EVENT_ADDBA                     0x00000033
 | 
					#define EVENT_ADDBA                     0x00000033
 | 
				
			||||||
#define EVENT_DELBA                     0x00000034
 | 
					#define EVENT_DELBA                     0x00000034
 | 
				
			||||||
#define EVENT_BA_STREAM_TIEMOUT         0x00000037
 | 
					#define EVENT_BA_STREAM_TIEMOUT         0x00000037
 | 
				
			||||||
#define EVENT_AMSDU_AGGR_CTRL           0x00000042
 | 
					#define EVENT_AMSDU_AGGR_CTRL           0x00000042
 | 
				
			||||||
 | 
					#define EVENT_UAP_BSS_IDLE              0x00000043
 | 
				
			||||||
 | 
					#define EVENT_UAP_BSS_ACTIVE            0x00000044
 | 
				
			||||||
#define EVENT_WEP_ICV_ERR               0x00000046
 | 
					#define EVENT_WEP_ICV_ERR               0x00000046
 | 
				
			||||||
#define EVENT_HS_ACT_REQ                0x00000047
 | 
					#define EVENT_HS_ACT_REQ                0x00000047
 | 
				
			||||||
#define EVENT_BW_CHANGE                 0x00000048
 | 
					#define EVENT_BW_CHANGE                 0x00000048
 | 
				
			||||||
 | 
					#define EVENT_UAP_MIC_COUNTERMEASURES   0x0000004c
 | 
				
			||||||
#define EVENT_HOSTWAKE_STAIE		0x0000004d
 | 
					#define EVENT_HOSTWAKE_STAIE		0x0000004d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EVENT_ID_MASK                   0xffff
 | 
					#define EVENT_ID_MASK                   0xffff
 | 
				
			||||||
| 
						 | 
					@ -1103,6 +1150,101 @@ struct host_cmd_ds_802_11_eeprom_access {
 | 
				
			||||||
	u8 value;
 | 
						u8 value;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv {
 | 
				
			||||||
 | 
						__le16 type;
 | 
				
			||||||
 | 
						__le16 len;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mwifiex_assoc_event {
 | 
				
			||||||
 | 
						u8 sta_addr[ETH_ALEN];
 | 
				
			||||||
 | 
						__le16 type;
 | 
				
			||||||
 | 
						__le16 len;
 | 
				
			||||||
 | 
						__le16 frame_control;
 | 
				
			||||||
 | 
						__le16 cap_info;
 | 
				
			||||||
 | 
						__le16 listen_interval;
 | 
				
			||||||
 | 
						u8 data[0];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_ds_sys_config {
 | 
				
			||||||
 | 
						__le16 action;
 | 
				
			||||||
 | 
						u8 tlv[0];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_akmp {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 key_mgmt;
 | 
				
			||||||
 | 
						__le16 key_mgmt_operation;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_pwk_cipher {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 proto;
 | 
				
			||||||
 | 
						u8 cipher;
 | 
				
			||||||
 | 
						u8 reserved;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_gwk_cipher {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 cipher;
 | 
				
			||||||
 | 
						u8 reserved;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_passphrase {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 passphrase[0];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_auth_type {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 auth_type;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_encrypt_protocol {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 proto;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_ssid {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 ssid[0];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_beacon_period {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 period;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_dtim_period {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 period;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_frag_threshold {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 frag_thr;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_rts_threshold {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						__le16 rts_thr;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_retry_limit {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 limit;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_mac_addr {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 mac_addr[ETH_ALEN];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct host_cmd_tlv_channel_band {
 | 
				
			||||||
 | 
						struct host_cmd_tlv tlv;
 | 
				
			||||||
 | 
						u8 band_config;
 | 
				
			||||||
 | 
						u8 channel;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct host_cmd_ds_802_11_rf_channel {
 | 
					struct host_cmd_ds_802_11_rf_channel {
 | 
				
			||||||
	__le16 action;
 | 
						__le16 action;
 | 
				
			||||||
	__le16 current_channel;
 | 
						__le16 current_channel;
 | 
				
			||||||
| 
						 | 
					@ -1167,6 +1309,20 @@ struct host_cmd_ds_802_11_subsc_evt {
 | 
				
			||||||
	__le16 events;
 | 
						__le16 events;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mwifiex_ie {
 | 
				
			||||||
 | 
						__le16 ie_index;
 | 
				
			||||||
 | 
						__le16 mgmt_subtype_mask;
 | 
				
			||||||
 | 
						__le16 ie_length;
 | 
				
			||||||
 | 
						u8 ie_buffer[IEEE_MAX_IE_SIZE];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_MGMT_IE_INDEX	16
 | 
				
			||||||
 | 
					struct mwifiex_ie_list {
 | 
				
			||||||
 | 
						__le16 type;
 | 
				
			||||||
 | 
						__le16 len;
 | 
				
			||||||
 | 
						struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct host_cmd_ds_command {
 | 
					struct host_cmd_ds_command {
 | 
				
			||||||
	__le16 command;
 | 
						__le16 command;
 | 
				
			||||||
	__le16 size;
 | 
						__le16 size;
 | 
				
			||||||
| 
						 | 
					@ -1217,6 +1373,7 @@ struct host_cmd_ds_command {
 | 
				
			||||||
		struct host_cmd_ds_pcie_details pcie_host_spec;
 | 
							struct host_cmd_ds_pcie_details pcie_host_spec;
 | 
				
			||||||
		struct host_cmd_ds_802_11_eeprom_access eeprom;
 | 
							struct host_cmd_ds_802_11_eeprom_access eeprom;
 | 
				
			||||||
		struct host_cmd_ds_802_11_subsc_evt subsc_evt;
 | 
							struct host_cmd_ds_802_11_subsc_evt subsc_evt;
 | 
				
			||||||
 | 
							struct host_cmd_ds_sys_config uap_sys_config;
 | 
				
			||||||
	} params;
 | 
						} params;
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										396
									
								
								drivers/net/wireless/mwifiex/ie.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								drivers/net/wireless/mwifiex/ie.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,396 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Marvell Wireless LAN device driver: management IE handling- setting and
 | 
				
			||||||
 | 
					 * deleting IE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2012, Marvell International Ltd.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This software file (the "File") is distributed by Marvell International
 | 
				
			||||||
 | 
					 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 | 
				
			||||||
 | 
					 * (the "License").  You may use, redistribute and/or modify this File in
 | 
				
			||||||
 | 
					 * accordance with the terms and conditions of the License, a copy of which
 | 
				
			||||||
 | 
					 * is available by writing to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 | 
				
			||||||
 | 
					 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 | 
				
			||||||
 | 
					 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 | 
				
			||||||
 | 
					 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 | 
				
			||||||
 | 
					 * this warranty disclaimer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "main.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function checks if current IE index is used by any on other interface.
 | 
				
			||||||
 | 
					 * Return: -1: yes, current IE index is used by someone else.
 | 
				
			||||||
 | 
					 *          0: no, current IE index is NOT used by other interface.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_ie_index_used_by_other_intf(struct mwifiex_private *priv, u16 idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						struct mwifiex_adapter *adapter = priv->adapter;
 | 
				
			||||||
 | 
						struct mwifiex_ie *ie;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < adapter->priv_num; i++) {
 | 
				
			||||||
 | 
							if (adapter->priv[i] != priv) {
 | 
				
			||||||
 | 
								ie = &adapter->priv[i]->mgmt_ie[idx];
 | 
				
			||||||
 | 
								if (ie->mgmt_subtype_mask && ie->ie_length)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get unused IE index. This index will be used for setting new IE */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_ie_get_autoidx(struct mwifiex_private *priv, u16 subtype_mask,
 | 
				
			||||||
 | 
							       struct mwifiex_ie *ie, u16 *index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 mask, len, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < priv->adapter->max_mgmt_ie_index; i++) {
 | 
				
			||||||
 | 
							mask = le16_to_cpu(priv->mgmt_ie[i].mgmt_subtype_mask);
 | 
				
			||||||
 | 
							len = le16_to_cpu(priv->mgmt_ie[i].ie_length) +
 | 
				
			||||||
 | 
							      le16_to_cpu(ie->ie_length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mask == MWIFIEX_AUTO_IDX_MASK)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mask == subtype_mask) {
 | 
				
			||||||
 | 
								if (len > IEEE_MAX_IE_SIZE)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*index = i;
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!priv->mgmt_ie[i].ie_length) {
 | 
				
			||||||
 | 
								if (mwifiex_ie_index_used_by_other_intf(priv, i))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*index = i;
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function prepares IE data buffer for command to be sent to FW */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								     struct mwifiex_ie_list *ie_list)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 travel_len, index, mask;
 | 
				
			||||||
 | 
						s16 input_len;
 | 
				
			||||||
 | 
						struct mwifiex_ie *ie;
 | 
				
			||||||
 | 
						u8 *tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						input_len = le16_to_cpu(ie_list->len);
 | 
				
			||||||
 | 
						travel_len = sizeof(struct host_cmd_tlv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ie_list->len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (input_len > 0) {
 | 
				
			||||||
 | 
							ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len);
 | 
				
			||||||
 | 
							input_len -= le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE;
 | 
				
			||||||
 | 
							travel_len += le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							index = le16_to_cpu(ie->ie_index);
 | 
				
			||||||
 | 
							mask = le16_to_cpu(ie->mgmt_subtype_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (index == MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
								/* automatic addition */
 | 
				
			||||||
 | 
								if (mwifiex_ie_get_autoidx(priv, mask, ie, &index))
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								if (index == MWIFIEX_AUTO_IDX_MASK)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								tmp = (u8 *)&priv->mgmt_ie[index].ie_buffer;
 | 
				
			||||||
 | 
								tmp += le16_to_cpu(priv->mgmt_ie[index].ie_length);
 | 
				
			||||||
 | 
								memcpy(tmp, &ie->ie_buffer, le16_to_cpu(ie->ie_length));
 | 
				
			||||||
 | 
								le16_add_cpu(&priv->mgmt_ie[index].ie_length,
 | 
				
			||||||
 | 
									     le16_to_cpu(ie->ie_length));
 | 
				
			||||||
 | 
								priv->mgmt_ie[index].ie_index = cpu_to_le16(index);
 | 
				
			||||||
 | 
								priv->mgmt_ie[index].mgmt_subtype_mask =
 | 
				
			||||||
 | 
												cpu_to_le16(mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ie->ie_index = cpu_to_le16(index);
 | 
				
			||||||
 | 
								ie->ie_length = priv->mgmt_ie[index].ie_length;
 | 
				
			||||||
 | 
								memcpy(&ie->ie_buffer, &priv->mgmt_ie[index].ie_buffer,
 | 
				
			||||||
 | 
								       le16_to_cpu(priv->mgmt_ie[index].ie_length));
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (mask != MWIFIEX_DELETE_MASK)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Check if this index is being used on any
 | 
				
			||||||
 | 
								 * other interface.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (mwifiex_ie_index_used_by_other_intf(priv, index))
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ie->ie_length = 0;
 | 
				
			||||||
 | 
								memcpy(&priv->mgmt_ie[index], ie,
 | 
				
			||||||
 | 
								       sizeof(struct mwifiex_ie));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							le16_add_cpu(&ie_list->len,
 | 
				
			||||||
 | 
								     le16_to_cpu(priv->mgmt_ie[index].ie_length) +
 | 
				
			||||||
 | 
								     MWIFIEX_IE_HDR_SIZE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
 | 
				
			||||||
 | 
							return mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
 | 
				
			||||||
 | 
										      HostCmd_ACT_GEN_SET,
 | 
				
			||||||
 | 
										      UAP_CUSTOM_IE_I, ie_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copy individual custom IEs for beacon, probe response and assoc response
 | 
				
			||||||
 | 
					 * and prepare single structure for IE setting.
 | 
				
			||||||
 | 
					 * This function also updates allocated IE indices from driver.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								     struct mwifiex_ie *beacon_ie, u16 *beacon_idx,
 | 
				
			||||||
 | 
								     struct mwifiex_ie *pr_ie, u16 *probe_idx,
 | 
				
			||||||
 | 
								     struct mwifiex_ie *ar_ie, u16 *assoc_idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_ie_list *ap_custom_ie;
 | 
				
			||||||
 | 
						u8 *pos;
 | 
				
			||||||
 | 
						u16 len;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ap_custom_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!ap_custom_ie)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ap_custom_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
 | 
				
			||||||
 | 
						pos = (u8 *)ap_custom_ie->ie_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (beacon_ie) {
 | 
				
			||||||
 | 
							len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
 | 
				
			||||||
 | 
							      le16_to_cpu(beacon_ie->ie_length);
 | 
				
			||||||
 | 
							memcpy(pos, beacon_ie, len);
 | 
				
			||||||
 | 
							pos += len;
 | 
				
			||||||
 | 
							le16_add_cpu(&ap_custom_ie->len, len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (pr_ie) {
 | 
				
			||||||
 | 
							len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
 | 
				
			||||||
 | 
							      le16_to_cpu(pr_ie->ie_length);
 | 
				
			||||||
 | 
							memcpy(pos, pr_ie, len);
 | 
				
			||||||
 | 
							pos += len;
 | 
				
			||||||
 | 
							le16_add_cpu(&ap_custom_ie->len, len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (ar_ie) {
 | 
				
			||||||
 | 
							len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
 | 
				
			||||||
 | 
							      le16_to_cpu(ar_ie->ie_length);
 | 
				
			||||||
 | 
							memcpy(pos, ar_ie, len);
 | 
				
			||||||
 | 
							pos += len;
 | 
				
			||||||
 | 
							le16_add_cpu(&ap_custom_ie->len, len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = mwifiex_update_autoindex_ies(priv, ap_custom_ie);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pos = (u8 *)(&ap_custom_ie->ie_list[0].ie_index);
 | 
				
			||||||
 | 
						if (beacon_ie && *beacon_idx == MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							/* save beacon ie index after auto-indexing */
 | 
				
			||||||
 | 
							*beacon_idx = le16_to_cpu(ap_custom_ie->ie_list[0].ie_index);
 | 
				
			||||||
 | 
							len = sizeof(*beacon_ie) - IEEE_MAX_IE_SIZE +
 | 
				
			||||||
 | 
							      le16_to_cpu(beacon_ie->ie_length);
 | 
				
			||||||
 | 
							pos += len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (pr_ie && le16_to_cpu(pr_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							/* save probe resp ie index after auto-indexing */
 | 
				
			||||||
 | 
							*probe_idx = *((u16 *)pos);
 | 
				
			||||||
 | 
							len = sizeof(*pr_ie) - IEEE_MAX_IE_SIZE +
 | 
				
			||||||
 | 
							      le16_to_cpu(pr_ie->ie_length);
 | 
				
			||||||
 | 
							pos += len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (ar_ie && le16_to_cpu(ar_ie->ie_index) == MWIFIEX_AUTO_IDX_MASK)
 | 
				
			||||||
 | 
							/* save assoc resp ie index after auto-indexing */
 | 
				
			||||||
 | 
							*assoc_idx = *((u16 *)pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function parses different IEs- Tail IEs, beacon IEs, probe response IEs,
 | 
				
			||||||
 | 
					 * association response IEs from cfg80211_ap_settings function and sets these IE
 | 
				
			||||||
 | 
					 * to FW.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								 struct cfg80211_ap_settings *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
 | 
				
			||||||
 | 
						struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL;
 | 
				
			||||||
 | 
						struct ieee_types_header *ie = NULL;
 | 
				
			||||||
 | 
						u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						u16 mask;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->beacon.tail && params->beacon.tail_len) {
 | 
				
			||||||
 | 
							ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail,
 | 
				
			||||||
 | 
										      params->beacon.tail_len);
 | 
				
			||||||
 | 
							if (ie) {
 | 
				
			||||||
 | 
								rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
								if (!rsn_ie)
 | 
				
			||||||
 | 
									return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rsn_ie->ie_index = cpu_to_le16(rsn_idx);
 | 
				
			||||||
 | 
								mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP |
 | 
				
			||||||
 | 
								       MGMT_MASK_ASSOC_RESP;
 | 
				
			||||||
 | 
								rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask);
 | 
				
			||||||
 | 
								rsn_ie->ie_length = cpu_to_le16(ie->len + 2);
 | 
				
			||||||
 | 
								memcpy(rsn_ie->ie_buffer, ie, ie->len + 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx,
 | 
				
			||||||
 | 
												 NULL, NULL,
 | 
				
			||||||
 | 
												 NULL, NULL)) {
 | 
				
			||||||
 | 
									ret = -1;
 | 
				
			||||||
 | 
									goto done;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								priv->rsn_idx = rsn_idx;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->beacon.beacon_ies && params->beacon.beacon_ies_len) {
 | 
				
			||||||
 | 
							beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!beacon_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							beacon_ie->ie_index = cpu_to_le16(beacon_idx);
 | 
				
			||||||
 | 
							beacon_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON);
 | 
				
			||||||
 | 
							beacon_ie->ie_length =
 | 
				
			||||||
 | 
									cpu_to_le16(params->beacon.beacon_ies_len);
 | 
				
			||||||
 | 
							memcpy(beacon_ie->ie_buffer, params->beacon.beacon_ies,
 | 
				
			||||||
 | 
							       params->beacon.beacon_ies_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->beacon.proberesp_ies && params->beacon.proberesp_ies_len) {
 | 
				
			||||||
 | 
							pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!pr_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pr_ie->ie_index = cpu_to_le16(pr_idx);
 | 
				
			||||||
 | 
							pr_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_PROBE_RESP);
 | 
				
			||||||
 | 
							pr_ie->ie_length =
 | 
				
			||||||
 | 
									cpu_to_le16(params->beacon.proberesp_ies_len);
 | 
				
			||||||
 | 
							memcpy(pr_ie->ie_buffer, params->beacon.proberesp_ies,
 | 
				
			||||||
 | 
							       params->beacon.proberesp_ies_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->beacon.assocresp_ies && params->beacon.assocresp_ies_len) {
 | 
				
			||||||
 | 
							ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!ar_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ar_ie->ie_index = cpu_to_le16(ar_idx);
 | 
				
			||||||
 | 
							mask = MGMT_MASK_ASSOC_RESP | MGMT_MASK_REASSOC_RESP;
 | 
				
			||||||
 | 
							ar_ie->mgmt_subtype_mask = cpu_to_le16(mask);
 | 
				
			||||||
 | 
							ar_ie->ie_length =
 | 
				
			||||||
 | 
									cpu_to_le16(params->beacon.assocresp_ies_len);
 | 
				
			||||||
 | 
							memcpy(ar_ie->ie_buffer, params->beacon.assocresp_ies,
 | 
				
			||||||
 | 
							       params->beacon.assocresp_ies_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (beacon_ie || pr_ie || ar_ie) {
 | 
				
			||||||
 | 
							ret = mwifiex_update_uap_custom_ie(priv, beacon_ie,
 | 
				
			||||||
 | 
											   &beacon_idx, pr_ie,
 | 
				
			||||||
 | 
											   &pr_idx, ar_ie, &ar_idx);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->beacon_idx = beacon_idx;
 | 
				
			||||||
 | 
						priv->proberesp_idx = pr_idx;
 | 
				
			||||||
 | 
						priv->assocresp_idx = ar_idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
						kfree(beacon_ie);
 | 
				
			||||||
 | 
						kfree(pr_ie);
 | 
				
			||||||
 | 
						kfree(ar_ie);
 | 
				
			||||||
 | 
						kfree(rsn_ie);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function removes management IE set */
 | 
				
			||||||
 | 
					int mwifiex_del_mgmt_ies(struct mwifiex_private *priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
 | 
				
			||||||
 | 
						struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->rsn_idx != MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!rsn_ie)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rsn_ie->ie_index = cpu_to_le16(priv->rsn_idx);
 | 
				
			||||||
 | 
							rsn_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
 | 
				
			||||||
 | 
							rsn_ie->ie_length = 0;
 | 
				
			||||||
 | 
							if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &priv->rsn_idx,
 | 
				
			||||||
 | 
											 NULL, &priv->proberesp_idx,
 | 
				
			||||||
 | 
											 NULL, &priv->assocresp_idx)) {
 | 
				
			||||||
 | 
								ret = -1;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!beacon_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							beacon_ie->ie_index = cpu_to_le16(priv->beacon_idx);
 | 
				
			||||||
 | 
							beacon_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
 | 
				
			||||||
 | 
							beacon_ie->ie_length = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (priv->proberesp_idx != MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!pr_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pr_ie->ie_index = cpu_to_le16(priv->proberesp_idx);
 | 
				
			||||||
 | 
							pr_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
 | 
				
			||||||
 | 
							pr_ie->ie_length = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (priv->assocresp_idx != MWIFIEX_AUTO_IDX_MASK) {
 | 
				
			||||||
 | 
							ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!ar_ie) {
 | 
				
			||||||
 | 
								ret = -ENOMEM;
 | 
				
			||||||
 | 
								goto done;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ar_ie->ie_index = cpu_to_le16(priv->assocresp_idx);
 | 
				
			||||||
 | 
							ar_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
 | 
				
			||||||
 | 
							ar_ie->ie_length = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (beacon_ie || pr_ie || ar_ie)
 | 
				
			||||||
 | 
							ret = mwifiex_update_uap_custom_ie(priv,
 | 
				
			||||||
 | 
											   beacon_ie, &priv->beacon_idx,
 | 
				
			||||||
 | 
											   pr_ie, &priv->proberesp_idx,
 | 
				
			||||||
 | 
											   ar_ie, &priv->assocresp_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
						kfree(beacon_ie);
 | 
				
			||||||
 | 
						kfree(pr_ie);
 | 
				
			||||||
 | 
						kfree(ar_ie);
 | 
				
			||||||
 | 
						kfree(rsn_ie);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -279,6 +279,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
 | 
				
			||||||
	memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
 | 
						memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
 | 
				
			||||||
	adapter->arp_filter_size = 0;
 | 
						adapter->arp_filter_size = 0;
 | 
				
			||||||
	adapter->channel_type = NL80211_CHAN_HT20;
 | 
						adapter->channel_type = NL80211_CHAN_HT20;
 | 
				
			||||||
 | 
						adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,36 @@ enum {
 | 
				
			||||||
	BAND_AN = 16,
 | 
						BAND_AN = 16,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MWIFIEX_WPA_PASSHPHRASE_LEN 64
 | 
				
			||||||
 | 
					struct wpa_param {
 | 
				
			||||||
 | 
						u8 pairwise_cipher_wpa;
 | 
				
			||||||
 | 
						u8 pairwise_cipher_wpa2;
 | 
				
			||||||
 | 
						u8 group_cipher;
 | 
				
			||||||
 | 
						u32 length;
 | 
				
			||||||
 | 
						u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define KEY_MGMT_ON_HOST        0x03
 | 
				
			||||||
 | 
					#define MWIFIEX_AUTH_MODE_AUTO  0xFF
 | 
				
			||||||
 | 
					#define BAND_CONFIG_MANUAL      0x00
 | 
				
			||||||
 | 
					struct mwifiex_uap_bss_param {
 | 
				
			||||||
 | 
						u8 channel;
 | 
				
			||||||
 | 
						u8 band_cfg;
 | 
				
			||||||
 | 
						u16 rts_threshold;
 | 
				
			||||||
 | 
						u16 frag_threshold;
 | 
				
			||||||
 | 
						u8 retry_limit;
 | 
				
			||||||
 | 
						struct mwifiex_802_11_ssid ssid;
 | 
				
			||||||
 | 
						u8 bcast_ssid_ctl;
 | 
				
			||||||
 | 
						u8 radio_ctl;
 | 
				
			||||||
 | 
						u8 dtim_period;
 | 
				
			||||||
 | 
						u16 beacon_period;
 | 
				
			||||||
 | 
						u16 auth_mode;
 | 
				
			||||||
 | 
						u16 protocol;
 | 
				
			||||||
 | 
						u16 key_mgmt;
 | 
				
			||||||
 | 
						u16 key_mgmt_operation;
 | 
				
			||||||
 | 
						struct wpa_param wpa_cfg;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	ADHOC_IDLE,
 | 
						ADHOC_IDLE,
 | 
				
			||||||
	ADHOC_STARTED,
 | 
						ADHOC_STARTED,
 | 
				
			||||||
| 
						 | 
					@ -269,6 +299,8 @@ struct mwifiex_ds_read_eeprom {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IEEE_MAX_IE_SIZE		256
 | 
					#define IEEE_MAX_IE_SIZE		256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MWIFIEX_IE_HDR_SIZE	(sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mwifiex_ds_misc_gen_ie {
 | 
					struct mwifiex_ds_misc_gen_ie {
 | 
				
			||||||
	u32 type;
 | 
						u32 type;
 | 
				
			||||||
	u32 len;
 | 
						u32 len;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1374,22 +1374,28 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * In case of infra made, it sends deauthentication request, and
 | 
					 * In case of infra made, it sends deauthentication request, and
 | 
				
			||||||
 * in case of ad-hoc mode, a stop network request is sent to the firmware.
 | 
					 * in case of ad-hoc mode, a stop network request is sent to the firmware.
 | 
				
			||||||
 | 
					 * In AP mode, a command to stop bss is sent to firmware.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
 | 
					int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = 0;
 | 
						if (!priv->media_connected)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->media_connected) {
 | 
						switch (priv->bss_mode) {
 | 
				
			||||||
		if (priv->bss_mode == NL80211_IFTYPE_STATION) {
 | 
						case NL80211_IFTYPE_STATION:
 | 
				
			||||||
			ret = mwifiex_deauthenticate_infra(priv, mac);
 | 
							return mwifiex_deauthenticate_infra(priv, mac);
 | 
				
			||||||
		} else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
 | 
						case NL80211_IFTYPE_ADHOC:
 | 
				
			||||||
			ret = mwifiex_send_cmd_sync(priv,
 | 
							return mwifiex_send_cmd_sync(priv,
 | 
				
			||||||
					     HostCmd_CMD_802_11_AD_HOC_STOP,
 | 
										     HostCmd_CMD_802_11_AD_HOC_STOP,
 | 
				
			||||||
					     HostCmd_ACT_GEN_SET, 0, NULL);
 | 
										     HostCmd_ACT_GEN_SET, 0, NULL);
 | 
				
			||||||
		}
 | 
						case NL80211_IFTYPE_AP:
 | 
				
			||||||
 | 
							return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
 | 
				
			||||||
 | 
										     HostCmd_ACT_GEN_SET, 0, NULL);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
 | 
					EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,17 +64,17 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adapter->priv_num = 0;
 | 
						adapter->priv_num = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
 | 
				
			||||||
		/* Allocate memory for private structure */
 | 
							/* Allocate memory for private structure */
 | 
				
			||||||
	adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
 | 
							adapter->priv[i] =
 | 
				
			||||||
	if (!adapter->priv[0]) {
 | 
								kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
 | 
				
			||||||
		dev_err(adapter->dev,
 | 
							if (!adapter->priv[i])
 | 
				
			||||||
			"%s: failed to alloc priv[0]\n", __func__);
 | 
					 | 
				
			||||||
			goto error;
 | 
								goto error;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adapter->priv[i]->adapter = adapter;
 | 
				
			||||||
 | 
							adapter->priv[i]->bss_priority = i;
 | 
				
			||||||
		adapter->priv_num++;
 | 
							adapter->priv_num++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	adapter->priv[0]->adapter = adapter;
 | 
					 | 
				
			||||||
	mwifiex_init_lock_list(adapter);
 | 
						mwifiex_init_lock_list(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_timer(&adapter->cmd_timer);
 | 
						init_timer(&adapter->cmd_timer);
 | 
				
			||||||
| 
						 | 
					@ -349,19 +349,26 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 | 
				
			||||||
	if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
 | 
						if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv = adapter->priv[0];
 | 
						priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
 | 
				
			||||||
	if (mwifiex_register_cfg80211(priv) != 0) {
 | 
						if (mwifiex_register_cfg80211(adapter)) {
 | 
				
			||||||
		dev_err(adapter->dev, "cannot register with cfg80211\n");
 | 
							dev_err(adapter->dev, "cannot register with cfg80211\n");
 | 
				
			||||||
		goto err_init_fw;
 | 
							goto err_init_fw;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_lock();
 | 
						rtnl_lock();
 | 
				
			||||||
	/* Create station interface by default */
 | 
						/* Create station interface by default */
 | 
				
			||||||
	if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
 | 
						if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
 | 
				
			||||||
				      NL80211_IFTYPE_STATION, NULL, NULL)) {
 | 
									      NL80211_IFTYPE_STATION, NULL, NULL)) {
 | 
				
			||||||
		dev_err(adapter->dev, "cannot create default STA interface\n");
 | 
							dev_err(adapter->dev, "cannot create default STA interface\n");
 | 
				
			||||||
		goto err_add_intf;
 | 
							goto err_add_intf;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create AP interface by default */
 | 
				
			||||||
 | 
						if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d",
 | 
				
			||||||
 | 
									      NL80211_IFTYPE_AP, NULL, NULL)) {
 | 
				
			||||||
 | 
							dev_err(adapter->dev, "cannot create default AP interface\n");
 | 
				
			||||||
 | 
							goto err_add_intf;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
 | 
						mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
 | 
				
			||||||
| 
						 | 
					@ -369,7 +376,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 | 
				
			||||||
	goto done;
 | 
						goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_add_intf:
 | 
					err_add_intf:
 | 
				
			||||||
	mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
 | 
						mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev);
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
err_init_fw:
 | 
					err_init_fw:
 | 
				
			||||||
	pr_debug("info: %s: unregister device\n", __func__);
 | 
						pr_debug("info: %s: unregister device\n", __func__);
 | 
				
			||||||
| 
						 | 
					@ -633,6 +640,12 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
 | 
				
			||||||
	priv->current_key_index = 0;
 | 
						priv->current_key_index = 0;
 | 
				
			||||||
	priv->media_connected = false;
 | 
						priv->media_connected = false;
 | 
				
			||||||
	memset(&priv->nick_name, 0, sizeof(priv->nick_name));
 | 
						memset(&priv->nick_name, 0, sizeof(priv->nick_name));
 | 
				
			||||||
 | 
						memset(priv->mgmt_ie, 0,
 | 
				
			||||||
 | 
						       sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX);
 | 
				
			||||||
 | 
						priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
 | 
						priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
 | 
				
			||||||
	priv->num_tx_timeout = 0;
 | 
						priv->num_tx_timeout = 0;
 | 
				
			||||||
	memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 | 
						memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -830,18 +843,20 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rtnl_lock();
 | 
							rtnl_lock();
 | 
				
			||||||
		if (priv->wdev && priv->netdev)
 | 
							if (priv->wdev && priv->netdev)
 | 
				
			||||||
			mwifiex_del_virtual_intf(priv->wdev->wiphy,
 | 
								mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev);
 | 
				
			||||||
						 priv->netdev);
 | 
					 | 
				
			||||||
		rtnl_unlock();
 | 
							rtnl_unlock();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv = adapter->priv[0];
 | 
						priv = adapter->priv[0];
 | 
				
			||||||
	if (!priv)
 | 
						if (!priv || !priv->wdev)
 | 
				
			||||||
		goto exit_remove;
 | 
							goto exit_remove;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->wdev) {
 | 
					 | 
				
			||||||
	wiphy_unregister(priv->wdev->wiphy);
 | 
						wiphy_unregister(priv->wdev->wiphy);
 | 
				
			||||||
	wiphy_free(priv->wdev->wiphy);
 | 
						wiphy_free(priv->wdev->wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < adapter->priv_num; i++) {
 | 
				
			||||||
 | 
							priv = adapter->priv[i];
 | 
				
			||||||
 | 
							if (priv)
 | 
				
			||||||
			kfree(priv->wdev);
 | 
								kfree(priv->wdev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,6 +116,7 @@ enum {
 | 
				
			||||||
#define MAX_FREQUENCY_BAND_BG   2484
 | 
					#define MAX_FREQUENCY_BAND_BG   2484
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_EVENT_HEADER_LEN           4
 | 
					#define MWIFIEX_EVENT_HEADER_LEN           4
 | 
				
			||||||
 | 
					#define MWIFIEX_UAP_EVENT_EXTRA_HEADER	   2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MWIFIEX_TYPE_LEN			4
 | 
					#define MWIFIEX_TYPE_LEN			4
 | 
				
			||||||
#define MWIFIEX_USB_TYPE_CMD			0xF00DFACE
 | 
					#define MWIFIEX_USB_TYPE_CMD			0xF00DFACE
 | 
				
			||||||
| 
						 | 
					@ -370,6 +371,7 @@ struct mwifiex_private {
 | 
				
			||||||
	u8 bss_role;
 | 
						u8 bss_role;
 | 
				
			||||||
	u8 bss_priority;
 | 
						u8 bss_priority;
 | 
				
			||||||
	u8 bss_num;
 | 
						u8 bss_num;
 | 
				
			||||||
 | 
						u8 bss_started;
 | 
				
			||||||
	u8 frame_type;
 | 
						u8 frame_type;
 | 
				
			||||||
	u8 curr_addr[ETH_ALEN];
 | 
						u8 curr_addr[ETH_ALEN];
 | 
				
			||||||
	u8 media_connected;
 | 
						u8 media_connected;
 | 
				
			||||||
| 
						 | 
					@ -470,12 +472,16 @@ struct mwifiex_private {
 | 
				
			||||||
	struct cfg80211_scan_request *scan_request;
 | 
						struct cfg80211_scan_request *scan_request;
 | 
				
			||||||
	struct mwifiex_user_scan_cfg *user_scan_cfg;
 | 
						struct mwifiex_user_scan_cfg *user_scan_cfg;
 | 
				
			||||||
	u8 cfg_bssid[6];
 | 
						u8 cfg_bssid[6];
 | 
				
			||||||
	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
 | 
					 | 
				
			||||||
	struct wps wps;
 | 
						struct wps wps;
 | 
				
			||||||
	u8 scan_block;
 | 
						u8 scan_block;
 | 
				
			||||||
	s32 cqm_rssi_thold;
 | 
						s32 cqm_rssi_thold;
 | 
				
			||||||
	u32 cqm_rssi_hyst;
 | 
						u32 cqm_rssi_hyst;
 | 
				
			||||||
	u8 subsc_evt_rssi_state;
 | 
						u8 subsc_evt_rssi_state;
 | 
				
			||||||
 | 
						struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX];
 | 
				
			||||||
 | 
						u16 beacon_idx;
 | 
				
			||||||
 | 
						u16 proberesp_idx;
 | 
				
			||||||
 | 
						u16 assocresp_idx;
 | 
				
			||||||
 | 
						u16 rsn_idx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum mwifiex_ba_status {
 | 
					enum mwifiex_ba_status {
 | 
				
			||||||
| 
						 | 
					@ -571,6 +577,7 @@ struct mwifiex_adapter {
 | 
				
			||||||
	char fw_name[32];
 | 
						char fw_name[32];
 | 
				
			||||||
	int winner;
 | 
						int winner;
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
 | 
						struct wiphy *wiphy;
 | 
				
			||||||
	bool surprise_removed;
 | 
						bool surprise_removed;
 | 
				
			||||||
	u32 fw_release_number;
 | 
						u32 fw_release_number;
 | 
				
			||||||
	u16 init_wait_q_woken;
 | 
						u16 init_wait_q_woken;
 | 
				
			||||||
| 
						 | 
					@ -677,6 +684,8 @@ struct mwifiex_adapter {
 | 
				
			||||||
	struct cmd_ctrl_node *cmd_queued;
 | 
						struct cmd_ctrl_node *cmd_queued;
 | 
				
			||||||
	spinlock_t queue_lock;		/* lock for tx queues */
 | 
						spinlock_t queue_lock;		/* lock for tx queues */
 | 
				
			||||||
	struct completion fw_load;
 | 
						struct completion fw_load;
 | 
				
			||||||
 | 
						u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
 | 
				
			||||||
 | 
						u16 max_mgmt_ie_index;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
 | 
					int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
 | 
				
			||||||
| 
						 | 
					@ -760,6 +769,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
 | 
				
			||||||
int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
 | 
					int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
 | 
				
			||||||
			    u16 cmd_action, u32 cmd_oid,
 | 
								    u16 cmd_action, u32 cmd_oid,
 | 
				
			||||||
			    void *data_buf, void *cmd_buf);
 | 
								    void *data_buf, void *cmd_buf);
 | 
				
			||||||
 | 
					int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
 | 
				
			||||||
 | 
								    u16 cmd_action, u32 cmd_oid,
 | 
				
			||||||
 | 
								    void *data_buf, void *cmd_buf);
 | 
				
			||||||
int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
 | 
					int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
 | 
				
			||||||
				struct host_cmd_ds_command *resp);
 | 
									struct host_cmd_ds_command *resp);
 | 
				
			||||||
int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
 | 
					int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
 | 
				
			||||||
| 
						 | 
					@ -820,6 +832,9 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
 | 
				
			||||||
int is_command_pending(struct mwifiex_adapter *adapter);
 | 
					int is_command_pending(struct mwifiex_adapter *adapter);
 | 
				
			||||||
void mwifiex_init_priv_params(struct mwifiex_private *priv,
 | 
					void mwifiex_init_priv_params(struct mwifiex_private *priv,
 | 
				
			||||||
						struct net_device *dev);
 | 
											struct net_device *dev);
 | 
				
			||||||
 | 
					int mwifiex_set_secure_params(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								      struct mwifiex_uap_bss_param *bss_config,
 | 
				
			||||||
 | 
								      struct cfg80211_ap_settings *params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This function checks if the queuing is RA based or not.
 | 
					 * This function checks if the queuing is RA based or not.
 | 
				
			||||||
| 
						 | 
					@ -933,7 +948,8 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
 | 
				
			||||||
int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
 | 
					int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
 | 
					int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
 | 
				
			||||||
		       int key_len, u8 key_index, int disable);
 | 
							       int key_len, u8 key_index, const u8 *mac_addr,
 | 
				
			||||||
 | 
							       int disable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
 | 
					int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -969,6 +985,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mwifiex_main_process(struct mwifiex_adapter *);
 | 
					int mwifiex_main_process(struct mwifiex_adapter *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel);
 | 
				
			||||||
int mwifiex_bss_set_channel(struct mwifiex_private *,
 | 
					int mwifiex_bss_set_channel(struct mwifiex_private *,
 | 
				
			||||||
			    struct mwifiex_chan_freq_power *cfp);
 | 
								    struct mwifiex_chan_freq_power *cfp);
 | 
				
			||||||
int mwifiex_get_bss_info(struct mwifiex_private *,
 | 
					int mwifiex_get_bss_info(struct mwifiex_private *,
 | 
				
			||||||
| 
						 | 
					@ -986,6 +1003,11 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 | 
				
			||||||
					u32 *flags, struct vif_params *params);
 | 
										u32 *flags, struct vif_params *params);
 | 
				
			||||||
int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
 | 
					int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								 struct cfg80211_ap_settings *params);
 | 
				
			||||||
 | 
					int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
 | 
				
			||||||
u8 *mwifiex_11d_code_2_region(u8 code);
 | 
					u8 *mwifiex_11d_code_2_region(u8 code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -498,7 +498,8 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct host_cmd_ds_802_11_key_material *key_material =
 | 
						struct host_cmd_ds_802_11_key_material *key_material =
 | 
				
			||||||
		&cmd->params.key_material;
 | 
							&cmd->params.key_material;
 | 
				
			||||||
	u16 key_param_len = 0;
 | 
						struct host_cmd_tlv_mac_addr *tlv_mac;
 | 
				
			||||||
 | 
						u16 key_param_len = 0, cmd_size;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 | 
						const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -614,11 +615,26 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
 | 
				
			||||||
			cpu_to_le16((u16) enc_key->key_len +
 | 
								cpu_to_le16((u16) enc_key->key_len +
 | 
				
			||||||
				    KEYPARAMSET_FIXED_LEN);
 | 
									    KEYPARAMSET_FIXED_LEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
 | 
							key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
 | 
				
			||||||
				+ sizeof(struct mwifiex_ie_types_header);
 | 
									+ sizeof(struct mwifiex_ie_types_header);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
 | 
							cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
 | 
				
			||||||
					+ key_param_len);
 | 
										+ key_param_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
 | 
				
			||||||
 | 
								tlv_mac = (void *)((u8 *)&key_material->key_param_set +
 | 
				
			||||||
 | 
										   key_param_len);
 | 
				
			||||||
 | 
								tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
 | 
				
			||||||
 | 
								tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
 | 
				
			||||||
 | 
								memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
 | 
				
			||||||
 | 
								cmd_size = key_param_len + S_DS_GEN +
 | 
				
			||||||
 | 
									   sizeof(key_material->action) +
 | 
				
			||||||
 | 
									   sizeof(struct host_cmd_tlv_mac_addr);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								cmd_size = key_param_len + S_DS_GEN +
 | 
				
			||||||
 | 
									   sizeof(key_material->action);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cmd->size = cpu_to_le16(cmd_size);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -1248,14 +1264,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
 | 
				
			||||||
			/* Enable IEEE PS by default */
 | 
								/* Enable IEEE PS by default */
 | 
				
			||||||
			priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
 | 
								priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
 | 
				
			||||||
		ret = mwifiex_send_cmd_async(priv,
 | 
								ret = mwifiex_send_cmd_async(
 | 
				
			||||||
					     HostCmd_CMD_802_11_PS_MODE_ENH,
 | 
										priv, HostCmd_CMD_802_11_PS_MODE_ENH,
 | 
				
			||||||
					EN_AUTO_PS, BITMAP_STA_PS, NULL);
 | 
										EN_AUTO_PS, BITMAP_STA_PS, NULL);
 | 
				
			||||||
			if (ret)
 | 
								if (ret)
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get tx rate */
 | 
						/* get tx rate */
 | 
				
			||||||
	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
 | 
						ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
 | 
				
			||||||
| 
						 | 
					@ -1270,12 +1288,14 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
 | 
				
			||||||
		/* set ibss coalescing_status */
 | 
							/* set ibss coalescing_status */
 | 
				
			||||||
	ret = mwifiex_send_cmd_async(priv,
 | 
							ret = mwifiex_send_cmd_async(
 | 
				
			||||||
				     HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
 | 
									priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
 | 
				
			||||||
				HostCmd_ACT_GEN_SET, 0, &enable);
 | 
									HostCmd_ACT_GEN_SET, 0, &enable);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
 | 
						memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
 | 
				
			||||||
	amsdu_aggr_ctrl.enable = true;
 | 
						amsdu_aggr_ctrl.enable = true;
 | 
				
			||||||
| 
						 | 
					@ -1293,7 +1313,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (first_sta && (priv->adapter->iface_type != MWIFIEX_USB)) {
 | 
						if (first_sta && priv->adapter->iface_type != MWIFIEX_USB &&
 | 
				
			||||||
 | 
						    priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
 | 
				
			||||||
		/* Enable auto deep sleep */
 | 
							/* Enable auto deep sleep */
 | 
				
			||||||
		auto_ds.auto_ds = DEEP_SLEEP_ON;
 | 
							auto_ds.auto_ds = DEEP_SLEEP_ON;
 | 
				
			||||||
		auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
 | 
							auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
 | 
				
			||||||
| 
						 | 
					@ -1305,12 +1326,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
 | 
				
			||||||
		/* Send cmd to FW to enable/disable 11D function */
 | 
							/* Send cmd to FW to enable/disable 11D function */
 | 
				
			||||||
		state_11d = ENABLE_11D;
 | 
							state_11d = ENABLE_11D;
 | 
				
			||||||
		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
 | 
							ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
 | 
				
			||||||
				     HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d);
 | 
										     HostCmd_ACT_GEN_SET, DOT11D_I,
 | 
				
			||||||
 | 
										     &state_11d);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
		dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
 | 
								dev_err(priv->adapter->dev,
 | 
				
			||||||
 | 
									"11D: failed to enable 11D\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Send cmd to FW to configure 11n specific configuration
 | 
						/* Send cmd to FW to configure 11n specific configuration
 | 
				
			||||||
	 * (Short GI, Channel BW, Green field support etc.) for transmit
 | 
						 * (Short GI, Channel BW, Green field support etc.) for transmit
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -944,6 +944,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
 | 
				
			||||||
	case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
 | 
						case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
 | 
				
			||||||
		ret = mwifiex_ret_subsc_evt(priv, resp, data_buf);
 | 
							ret = mwifiex_ret_subsc_evt(priv, resp, data_buf);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_SYS_CONFIG:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_BSS_START:
 | 
				
			||||||
 | 
							priv->bss_started = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_BSS_STOP:
 | 
				
			||||||
 | 
							priv->bss_started = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
 | 
							dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
 | 
				
			||||||
			resp->command);
 | 
								resp->command);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,8 +184,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
 | 
				
			||||||
int mwifiex_process_sta_event(struct mwifiex_private *priv)
 | 
					int mwifiex_process_sta_event(struct mwifiex_private *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_adapter *adapter = priv->adapter;
 | 
						struct mwifiex_adapter *adapter = priv->adapter;
 | 
				
			||||||
	int ret = 0;
 | 
						int len, ret = 0;
 | 
				
			||||||
	u32 eventcause = adapter->event_cause;
 | 
						u32 eventcause = adapter->event_cause;
 | 
				
			||||||
 | 
						struct station_info sinfo;
 | 
				
			||||||
 | 
						struct mwifiex_assoc_event *event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (eventcause) {
 | 
						switch (eventcause) {
 | 
				
			||||||
	case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
 | 
						case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
 | 
				
			||||||
| 
						 | 
					@ -402,6 +404,53 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
 | 
				
			||||||
	case EVENT_HOSTWAKE_STAIE:
 | 
						case EVENT_HOSTWAKE_STAIE:
 | 
				
			||||||
		dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
 | 
							dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case EVENT_UAP_STA_ASSOC:
 | 
				
			||||||
 | 
							skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER);
 | 
				
			||||||
 | 
							memset(&sinfo, 0, sizeof(sinfo));
 | 
				
			||||||
 | 
							event = (struct mwifiex_assoc_event *)adapter->event_skb->data;
 | 
				
			||||||
 | 
							if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
 | 
				
			||||||
 | 
								len = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (ieee80211_is_assoc_req(event->frame_control))
 | 
				
			||||||
 | 
									len = 0;
 | 
				
			||||||
 | 
								else if (ieee80211_is_reassoc_req(event->frame_control))
 | 
				
			||||||
 | 
									/* There will be ETH_ALEN bytes of
 | 
				
			||||||
 | 
									 * current_ap_addr before the re-assoc ies.
 | 
				
			||||||
 | 
									 */
 | 
				
			||||||
 | 
									len = ETH_ALEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (len != -1) {
 | 
				
			||||||
 | 
									sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
 | 
				
			||||||
 | 
									sinfo.assoc_req_ies = (u8 *)&event->data[len];
 | 
				
			||||||
 | 
									len = (u8 *)sinfo.assoc_req_ies -
 | 
				
			||||||
 | 
									      (u8 *)&event->frame_control;
 | 
				
			||||||
 | 
									sinfo.assoc_req_ies_len =
 | 
				
			||||||
 | 
										le16_to_cpu(event->len) - (u16)len;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo,
 | 
				
			||||||
 | 
									 GFP_KERNEL);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EVENT_UAP_STA_DEAUTH:
 | 
				
			||||||
 | 
							skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER);
 | 
				
			||||||
 | 
							cfg80211_del_sta(priv->netdev, adapter->event_skb->data,
 | 
				
			||||||
 | 
									 GFP_KERNEL);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EVENT_UAP_BSS_IDLE:
 | 
				
			||||||
 | 
							priv->media_connected = false;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EVENT_UAP_BSS_ACTIVE:
 | 
				
			||||||
 | 
							priv->media_connected = true;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EVENT_UAP_BSS_START:
 | 
				
			||||||
 | 
							dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
 | 
				
			||||||
 | 
							memcpy(priv->netdev->dev_addr, adapter->event_body+2, ETH_ALEN);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EVENT_UAP_MIC_COUNTERMEASURES:
 | 
				
			||||||
 | 
							/* For future development */
 | 
				
			||||||
 | 
							dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
 | 
							dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
 | 
				
			||||||
			eventcause);
 | 
								eventcause);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -462,7 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info->bss_chan = bss_desc->channel;
 | 
						info->bss_chan = bss_desc->channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(info->country_code, priv->country_code,
 | 
						memcpy(info->country_code, adapter->country_code,
 | 
				
			||||||
	       IEEE80211_COUNTRY_STRING_LEN);
 | 
						       IEEE80211_COUNTRY_STRING_LEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info->media_connected = priv->media_connected;
 | 
						info->media_connected = priv->media_connected;
 | 
				
			||||||
| 
						 | 
					@ -1219,7 +1219,8 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
 | 
				
			||||||
 * with requisite parameters and calls the IOCTL handler.
 | 
					 * with requisite parameters and calls the IOCTL handler.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
 | 
					int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
 | 
				
			||||||
			int key_len, u8 key_index, int disable)
 | 
								int key_len, u8 key_index,
 | 
				
			||||||
 | 
								const u8 *mac_addr, int disable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mwifiex_ds_encrypt_key encrypt_key;
 | 
						struct mwifiex_ds_encrypt_key encrypt_key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1229,8 +1230,12 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
 | 
				
			||||||
		encrypt_key.key_index = key_index;
 | 
							encrypt_key.key_index = key_index;
 | 
				
			||||||
		if (key_len)
 | 
							if (key_len)
 | 
				
			||||||
			memcpy(encrypt_key.key_material, key, key_len);
 | 
								memcpy(encrypt_key.key_material, key, key_len);
 | 
				
			||||||
 | 
							if (mac_addr)
 | 
				
			||||||
 | 
								memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		encrypt_key.key_disable = true;
 | 
							encrypt_key.key_disable = true;
 | 
				
			||||||
 | 
							if (mac_addr)
 | 
				
			||||||
 | 
								memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
 | 
						return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										432
									
								
								drivers/net/wireless/mwifiex/uap_cmd.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								drivers/net/wireless/mwifiex/uap_cmd.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,432 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Marvell Wireless LAN device driver: AP specific command handling
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2012, Marvell International Ltd.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This software file (the "File") is distributed by Marvell International
 | 
				
			||||||
 | 
					 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 | 
				
			||||||
 | 
					 * (the "License").  You may use, redistribute and/or modify this File in
 | 
				
			||||||
 | 
					 * accordance with the terms and conditions of the License, a copy of which
 | 
				
			||||||
 | 
					 * is available by writing to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 | 
				
			||||||
 | 
					 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 | 
				
			||||||
 | 
					 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 | 
				
			||||||
 | 
					 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 | 
				
			||||||
 | 
					 * this warranty disclaimer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "main.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function parses security related parameters from cfg80211_ap_settings
 | 
				
			||||||
 | 
					 * and sets into FW understandable bss_config structure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int mwifiex_set_secure_params(struct mwifiex_private *priv,
 | 
				
			||||||
 | 
								      struct mwifiex_uap_bss_param *bss_config,
 | 
				
			||||||
 | 
								      struct cfg80211_ap_settings *params) {
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (params->auth_type) {
 | 
				
			||||||
 | 
						case NL80211_AUTHTYPE_OPEN_SYSTEM:
 | 
				
			||||||
 | 
							bss_config->auth_mode = WLAN_AUTH_OPEN;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NL80211_AUTHTYPE_SHARED_KEY:
 | 
				
			||||||
 | 
							bss_config->auth_mode = WLAN_AUTH_SHARED_KEY;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NL80211_AUTHTYPE_NETWORK_EAP:
 | 
				
			||||||
 | 
							bss_config->auth_mode = WLAN_AUTH_LEAP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							bss_config->auth_mode = MWIFIEX_AUTH_MODE_AUTO;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bss_config->key_mgmt_operation |= KEY_MGMT_ON_HOST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < params->crypto.n_akm_suites; i++) {
 | 
				
			||||||
 | 
							switch (params->crypto.akm_suites[i]) {
 | 
				
			||||||
 | 
							case WLAN_AKM_SUITE_8021X:
 | 
				
			||||||
 | 
								if (params->crypto.wpa_versions &
 | 
				
			||||||
 | 
								    NL80211_WPA_VERSION_1) {
 | 
				
			||||||
 | 
									bss_config->protocol = PROTOCOL_WPA;
 | 
				
			||||||
 | 
									bss_config->key_mgmt = KEY_MGMT_EAP;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (params->crypto.wpa_versions &
 | 
				
			||||||
 | 
								    NL80211_WPA_VERSION_2) {
 | 
				
			||||||
 | 
									bss_config->protocol = PROTOCOL_WPA2;
 | 
				
			||||||
 | 
									bss_config->key_mgmt = KEY_MGMT_EAP;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case WLAN_AKM_SUITE_PSK:
 | 
				
			||||||
 | 
								if (params->crypto.wpa_versions &
 | 
				
			||||||
 | 
								    NL80211_WPA_VERSION_1) {
 | 
				
			||||||
 | 
									bss_config->protocol = PROTOCOL_WPA;
 | 
				
			||||||
 | 
									bss_config->key_mgmt = KEY_MGMT_PSK;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (params->crypto.wpa_versions &
 | 
				
			||||||
 | 
								    NL80211_WPA_VERSION_2) {
 | 
				
			||||||
 | 
									bss_config->protocol = PROTOCOL_WPA2;
 | 
				
			||||||
 | 
									bss_config->key_mgmt = KEY_MGMT_PSK;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (i = 0; i < params->crypto.n_ciphers_pairwise; i++) {
 | 
				
			||||||
 | 
							switch (params->crypto.ciphers_pairwise[i]) {
 | 
				
			||||||
 | 
							case WLAN_CIPHER_SUITE_WEP40:
 | 
				
			||||||
 | 
							case WLAN_CIPHER_SUITE_WEP104:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case WLAN_CIPHER_SUITE_TKIP:
 | 
				
			||||||
 | 
								bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case WLAN_CIPHER_SUITE_CCMP:
 | 
				
			||||||
 | 
								bss_config->wpa_cfg.pairwise_cipher_wpa2 =
 | 
				
			||||||
 | 
													CIPHER_AES_CCMP;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (params->crypto.cipher_group) {
 | 
				
			||||||
 | 
						case WLAN_CIPHER_SUITE_WEP40:
 | 
				
			||||||
 | 
						case WLAN_CIPHER_SUITE_WEP104:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WLAN_CIPHER_SUITE_TKIP:
 | 
				
			||||||
 | 
							bss_config->wpa_cfg.group_cipher = CIPHER_TKIP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WLAN_CIPHER_SUITE_CCMP:
 | 
				
			||||||
 | 
							bss_config->wpa_cfg.group_cipher = CIPHER_AES_CCMP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function initializes some of mwifiex_uap_bss_param variables.
 | 
				
			||||||
 | 
					 * This helps FW in ignoring invalid values. These values may or may not
 | 
				
			||||||
 | 
					 * be get updated to valid ones at later stage.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						config->bcast_ssid_ctl = 0x7F;
 | 
				
			||||||
 | 
						config->radio_ctl = 0x7F;
 | 
				
			||||||
 | 
						config->dtim_period = 0x7F;
 | 
				
			||||||
 | 
						config->beacon_period = 0x7FFF;
 | 
				
			||||||
 | 
						config->auth_mode = 0x7F;
 | 
				
			||||||
 | 
						config->rts_threshold = 0x7FFF;
 | 
				
			||||||
 | 
						config->frag_threshold = 0x7FFF;
 | 
				
			||||||
 | 
						config->retry_limit = 0x7F;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function parses BSS related parameters from structure
 | 
				
			||||||
 | 
					 * and prepares TLVs. These TLVs are appended to command buffer.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct host_cmd_tlv_dtim_period *dtim_period;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_beacon_period *beacon_period;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_ssid *ssid;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_channel_band *chan_band;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_frag_threshold *frag_threshold;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_rts_threshold *rts_threshold;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_retry_limit *retry_limit;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_pwk_cipher *pwk_cipher;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_gwk_cipher *gwk_cipher;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_auth_type *auth_type;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_passphrase *passphrase;
 | 
				
			||||||
 | 
						struct host_cmd_tlv_akmp *tlv_akmp;
 | 
				
			||||||
 | 
						struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
 | 
				
			||||||
 | 
						u16 cmd_size = *param_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bss_cfg->ssid.ssid_len) {
 | 
				
			||||||
 | 
							ssid = (struct host_cmd_tlv_ssid *)tlv;
 | 
				
			||||||
 | 
							ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
 | 
				
			||||||
 | 
							ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
 | 
				
			||||||
 | 
							memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv) +
 | 
				
			||||||
 | 
								    bss_cfg->ssid.ssid_len;
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
 | 
				
			||||||
 | 
							chan_band = (struct host_cmd_tlv_channel_band *)tlv;
 | 
				
			||||||
 | 
							chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
 | 
				
			||||||
 | 
							chan_band->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							chan_band->band_config = bss_cfg->band_cfg;
 | 
				
			||||||
 | 
							chan_band->channel = bss_cfg->channel;
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_channel_band);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_channel_band);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD &&
 | 
				
			||||||
 | 
						    bss_cfg->beacon_period <= MAX_BEACON_PERIOD) {
 | 
				
			||||||
 | 
							beacon_period = (struct host_cmd_tlv_beacon_period *)tlv;
 | 
				
			||||||
 | 
							beacon_period->tlv.type =
 | 
				
			||||||
 | 
										cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
 | 
				
			||||||
 | 
							beacon_period->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							beacon_period->period = cpu_to_le16(bss_cfg->beacon_period);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_beacon_period);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_beacon_period);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD &&
 | 
				
			||||||
 | 
						    bss_cfg->dtim_period <= MAX_DTIM_PERIOD) {
 | 
				
			||||||
 | 
							dtim_period = (struct host_cmd_tlv_dtim_period *)tlv;
 | 
				
			||||||
 | 
							dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
 | 
				
			||||||
 | 
							dtim_period->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							dtim_period->period = bss_cfg->dtim_period;
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_dtim_period);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_dtim_period);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
 | 
				
			||||||
 | 
							rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
 | 
				
			||||||
 | 
							rts_threshold->tlv.type =
 | 
				
			||||||
 | 
										cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
 | 
				
			||||||
 | 
							rts_threshold->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_frag_threshold);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
 | 
				
			||||||
 | 
						    (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
 | 
				
			||||||
 | 
							frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
 | 
				
			||||||
 | 
							frag_threshold->tlv.type =
 | 
				
			||||||
 | 
									cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
 | 
				
			||||||
 | 
							frag_threshold->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_frag_threshold);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
 | 
				
			||||||
 | 
							retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
 | 
				
			||||||
 | 
							retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
 | 
				
			||||||
 | 
							retry_limit->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
 | 
				
			||||||
 | 
									    sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							retry_limit->limit = (u8)bss_cfg->retry_limit;
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_retry_limit);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ((bss_cfg->protocol & PROTOCOL_WPA) ||
 | 
				
			||||||
 | 
						    (bss_cfg->protocol & PROTOCOL_WPA2) ||
 | 
				
			||||||
 | 
						    (bss_cfg->protocol & PROTOCOL_EAP)) {
 | 
				
			||||||
 | 
							tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
 | 
				
			||||||
 | 
							tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
 | 
				
			||||||
 | 
							tlv_akmp->tlv.len =
 | 
				
			||||||
 | 
							    cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							tlv_akmp->key_mgmt_operation =
 | 
				
			||||||
 | 
								cpu_to_le16(bss_cfg->key_mgmt_operation);
 | 
				
			||||||
 | 
							tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_akmp);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_akmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (bss_cfg->wpa_cfg.pairwise_cipher_wpa &
 | 
				
			||||||
 | 
									VALID_CIPHER_BITMAP) {
 | 
				
			||||||
 | 
								pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
 | 
				
			||||||
 | 
								pwk_cipher->tlv.type =
 | 
				
			||||||
 | 
									cpu_to_le16(TLV_TYPE_PWK_CIPHER);
 | 
				
			||||||
 | 
								pwk_cipher->tlv.len = cpu_to_le16(
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv_pwk_cipher) -
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
								pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
 | 
				
			||||||
 | 
								pwk_cipher->cipher =
 | 
				
			||||||
 | 
									bss_cfg->wpa_cfg.pairwise_cipher_wpa;
 | 
				
			||||||
 | 
								cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
 | 
				
			||||||
 | 
								tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 &
 | 
				
			||||||
 | 
									VALID_CIPHER_BITMAP) {
 | 
				
			||||||
 | 
								pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
 | 
				
			||||||
 | 
								pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
 | 
				
			||||||
 | 
								pwk_cipher->tlv.len = cpu_to_le16(
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv_pwk_cipher) -
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
								pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
 | 
				
			||||||
 | 
								pwk_cipher->cipher =
 | 
				
			||||||
 | 
									bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
 | 
				
			||||||
 | 
								cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
 | 
				
			||||||
 | 
								tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
 | 
				
			||||||
 | 
								gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
 | 
				
			||||||
 | 
								gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
 | 
				
			||||||
 | 
								gwk_cipher->tlv.len = cpu_to_le16(
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv_gwk_cipher) -
 | 
				
			||||||
 | 
									sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
								gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
 | 
				
			||||||
 | 
								cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
 | 
				
			||||||
 | 
								tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (bss_cfg->wpa_cfg.length) {
 | 
				
			||||||
 | 
								passphrase = (struct host_cmd_tlv_passphrase *)tlv;
 | 
				
			||||||
 | 
								passphrase->tlv.type =
 | 
				
			||||||
 | 
									cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
 | 
				
			||||||
 | 
								passphrase->tlv.len =
 | 
				
			||||||
 | 
									cpu_to_le16(bss_cfg->wpa_cfg.length);
 | 
				
			||||||
 | 
								memcpy(passphrase->passphrase,
 | 
				
			||||||
 | 
								       bss_cfg->wpa_cfg.passphrase,
 | 
				
			||||||
 | 
								       bss_cfg->wpa_cfg.length);
 | 
				
			||||||
 | 
								cmd_size += sizeof(struct host_cmd_tlv) +
 | 
				
			||||||
 | 
									    bss_cfg->wpa_cfg.length;
 | 
				
			||||||
 | 
								tlv += sizeof(struct host_cmd_tlv) +
 | 
				
			||||||
 | 
								       bss_cfg->wpa_cfg.length;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
 | 
				
			||||||
 | 
						    (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
 | 
				
			||||||
 | 
							auth_type = (struct host_cmd_tlv_auth_type *)tlv;
 | 
				
			||||||
 | 
							auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
 | 
				
			||||||
 | 
							auth_type->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) -
 | 
				
			||||||
 | 
								sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							auth_type->auth_type = (u8)bss_cfg->auth_mode;
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_auth_type);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_auth_type);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (bss_cfg->protocol) {
 | 
				
			||||||
 | 
							encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv;
 | 
				
			||||||
 | 
							encrypt_protocol->tlv.type =
 | 
				
			||||||
 | 
								cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL);
 | 
				
			||||||
 | 
							encrypt_protocol->tlv.len =
 | 
				
			||||||
 | 
								cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol)
 | 
				
			||||||
 | 
								- sizeof(struct host_cmd_tlv));
 | 
				
			||||||
 | 
							encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol);
 | 
				
			||||||
 | 
							cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol);
 | 
				
			||||||
 | 
							tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*param_size = cmd_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function parses custom IEs from IE list and prepares command buffer */
 | 
				
			||||||
 | 
					static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_ie_list *ap_ie = cmd_buf;
 | 
				
			||||||
 | 
						struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ap_ie || !ap_ie->len || !ap_ie->ie_list)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
 | 
				
			||||||
 | 
						tlv_ie->len = ap_ie->len;
 | 
				
			||||||
 | 
						tlv += sizeof(struct host_cmd_tlv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Parse AP config structure and prepare TLV based command structure
 | 
				
			||||||
 | 
					 * to be sent to FW for uAP configuration
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
 | 
				
			||||||
 | 
								   u32 type, void *cmd_buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 *tlv;
 | 
				
			||||||
 | 
						u16 cmd_size, param_size, ie_size;
 | 
				
			||||||
 | 
						struct host_cmd_ds_sys_config *sys_cfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd->command = cpu_to_le16(HostCmd_CMD_UAP_SYS_CONFIG);
 | 
				
			||||||
 | 
						cmd_size = (u16)(sizeof(struct host_cmd_ds_sys_config) + S_DS_GEN);
 | 
				
			||||||
 | 
						sys_cfg = (struct host_cmd_ds_sys_config *)&cmd->params.uap_sys_config;
 | 
				
			||||||
 | 
						sys_cfg->action = cpu_to_le16(cmd_action);
 | 
				
			||||||
 | 
						tlv = sys_cfg->tlv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case UAP_BSS_PARAMS_I:
 | 
				
			||||||
 | 
							param_size = cmd_size;
 | 
				
			||||||
 | 
							if (mwifiex_uap_bss_param_prepare(tlv, cmd_buf, ¶m_size))
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							cmd->size = cpu_to_le16(param_size);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case UAP_CUSTOM_IE_I:
 | 
				
			||||||
 | 
							ie_size = cmd_size;
 | 
				
			||||||
 | 
							if (mwifiex_uap_custom_ie_prepare(tlv, cmd_buf, &ie_size))
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							cmd->size = cpu_to_le16(ie_size);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function prepares the AP specific commands before sending them
 | 
				
			||||||
 | 
					 * to the firmware.
 | 
				
			||||||
 | 
					 * This is a generic function which calls specific command preparation
 | 
				
			||||||
 | 
					 * routines based upon the command number.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
 | 
				
			||||||
 | 
								    u16 cmd_action, u32 type,
 | 
				
			||||||
 | 
								    void *data_buf, void *cmd_buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct host_cmd_ds_command *cmd = cmd_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (cmd_no) {
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_SYS_CONFIG:
 | 
				
			||||||
 | 
							if (mwifiex_cmd_uap_sys_config(cmd, cmd_action, type, data_buf))
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_BSS_START:
 | 
				
			||||||
 | 
						case HostCmd_CMD_UAP_BSS_STOP:
 | 
				
			||||||
 | 
							cmd->command = cpu_to_le16(cmd_no);
 | 
				
			||||||
 | 
							cmd->size = cpu_to_le16(S_DS_GEN);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							dev_err(priv->adapter->dev,
 | 
				
			||||||
 | 
								"PREP_CMD: unknown cmd %#x\n", cmd_no);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function sets the RF channel for AP.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function populates channel information in AP config structure
 | 
				
			||||||
 | 
					 * and sends command to configure channel information in AP.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mwifiex_uap_bss_param *bss_cfg;
 | 
				
			||||||
 | 
						struct wiphy *wiphy = priv->wdev->wiphy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!bss_cfg)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
 | 
				
			||||||
 | 
						bss_cfg->channel = channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
 | 
				
			||||||
 | 
									   HostCmd_ACT_GEN_SET,
 | 
				
			||||||
 | 
									   UAP_BSS_PARAMS_I, bss_cfg)) {
 | 
				
			||||||
 | 
							wiphy_err(wiphy, "Failed to set the uAP channel\n");
 | 
				
			||||||
 | 
							kfree(bss_cfg);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(bss_cfg);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -885,6 +885,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
 | 
				
			||||||
				tid_ptr = &(priv_tmp)->wmm.
 | 
									tid_ptr = &(priv_tmp)->wmm.
 | 
				
			||||||
					tid_tbl_ptr[tos_to_tid[i]];
 | 
										tid_tbl_ptr[tos_to_tid[i]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									/* For non-STA ra_list_curr may be NULL */
 | 
				
			||||||
 | 
									if (!tid_ptr->ra_list_curr)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
 | 
									spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
 | 
				
			||||||
						  flags);
 | 
											  flags);
 | 
				
			||||||
				is_list_empty =
 | 
									is_list_empty =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -505,9 +505,6 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
 | 
					static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
 | 
					 | 
				
			||||||
	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
					static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
				
			||||||
			 u8 key_index, bool pairwise, const u8 *mac_addr,
 | 
								 u8 key_index, bool pairwise, const u8 *mac_addr,
 | 
				
			||||||
			 struct key_params *params);
 | 
								 struct key_params *params);
 | 
				
			||||||
| 
						 | 
					@ -549,7 +546,6 @@ static const struct cfg80211_ops rndis_config_ops = {
 | 
				
			||||||
	.disconnect = rndis_disconnect,
 | 
						.disconnect = rndis_disconnect,
 | 
				
			||||||
	.join_ibss = rndis_join_ibss,
 | 
						.join_ibss = rndis_join_ibss,
 | 
				
			||||||
	.leave_ibss = rndis_leave_ibss,
 | 
						.leave_ibss = rndis_leave_ibss,
 | 
				
			||||||
	.set_channel = rndis_set_channel,
 | 
					 | 
				
			||||||
	.add_key = rndis_add_key,
 | 
						.add_key = rndis_add_key,
 | 
				
			||||||
	.del_key = rndis_del_key,
 | 
						.del_key = rndis_del_key,
 | 
				
			||||||
	.set_default_key = rndis_set_default_key,
 | 
						.set_default_key = rndis_set_default_key,
 | 
				
			||||||
| 
						 | 
					@ -2398,16 +2394,6 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 | 
				
			||||||
	return deauthenticate(usbdev);
 | 
						return deauthenticate(usbdev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
 | 
					 | 
				
			||||||
	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 | 
					 | 
				
			||||||
	struct usbnet *usbdev = priv->usbdev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return set_channel(usbdev,
 | 
					 | 
				
			||||||
			ieee80211_frequency_to_channel(chan->center_freq));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
					static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
 | 
				
			||||||
			 u8 key_index, bool pairwise, const u8 *mac_addr,
 | 
								 u8 key_index, bool pairwise, const u8 *mac_addr,
 | 
				
			||||||
			 struct key_params *params)
 | 
								 struct key_params *params)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1192,6 +1192,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
 | 
				
			||||||
	{ PCI_DEVICE(0x1814, 0x5390) },
 | 
						{ PCI_DEVICE(0x1814, 0x5390) },
 | 
				
			||||||
	{ PCI_DEVICE(0x1814, 0x5392) },
 | 
						{ PCI_DEVICE(0x1814, 0x5392) },
 | 
				
			||||||
	{ PCI_DEVICE(0x1814, 0x539a) },
 | 
						{ PCI_DEVICE(0x1814, 0x539a) },
 | 
				
			||||||
 | 
						{ PCI_DEVICE(0x1814, 0x539b) },
 | 
				
			||||||
	{ PCI_DEVICE(0x1814, 0x539f) },
 | 
						{ PCI_DEVICE(0x1814, 0x539f) },
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	{ 0, }
 | 
						{ 0, }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
config WL12XX
 | 
					config WL12XX
 | 
				
			||||||
       tristate "TI wl12xx support"
 | 
					       tristate "TI wl12xx support"
 | 
				
			||||||
 | 
						depends on MAC80211
 | 
				
			||||||
       select WLCORE
 | 
					       select WLCORE
 | 
				
			||||||
       ---help---
 | 
					       ---help---
 | 
				
			||||||
	  This module adds support for wireless adapters based on TI wl1271,
 | 
						  This module adds support for wireless adapters based on TI wl1271,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
config WLCORE
 | 
					config WLCORE
 | 
				
			||||||
	tristate "TI wlcore support"
 | 
						tristate "TI wlcore support"
 | 
				
			||||||
	depends on WL_TI && GENERIC_HARDIRQS
 | 
						depends on WL_TI && GENERIC_HARDIRQS && MAC80211
 | 
				
			||||||
	depends on INET
 | 
						depends on INET
 | 
				
			||||||
	select FW_LOADER
 | 
						select FW_LOADER
 | 
				
			||||||
	---help---
 | 
						---help---
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1714,3 +1714,83 @@ out:
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set the global behaviour of RX filters - On/Off + default action */
 | 
				
			||||||
 | 
					int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
 | 
				
			||||||
 | 
										enum rx_filter_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acx_default_rx_filter *acx;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d",
 | 
				
			||||||
 | 
							     enable, action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!acx)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acx->enable = enable;
 | 
				
			||||||
 | 
						acx->default_action = action;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx,
 | 
				
			||||||
 | 
									   sizeof(*acx));
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							wl1271_warning("acx default rx filter enable failed: %d", ret);
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						kfree(acx);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Configure or disable a specific RX filter pattern */
 | 
				
			||||||
 | 
					int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
 | 
				
			||||||
 | 
								     struct wl12xx_rx_filter *filter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acx_rx_filter_cfg *acx;
 | 
				
			||||||
 | 
						int fields_size = 0;
 | 
				
			||||||
 | 
						int acx_size;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WARN_ON(enable && !filter);
 | 
				
			||||||
 | 
						WARN_ON(index >= WL1271_MAX_RX_FILTERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl1271_debug(DEBUG_ACX,
 | 
				
			||||||
 | 
							     "acx set rx filter idx: %d enable: %d filter: %p",
 | 
				
			||||||
 | 
							     index, enable, filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							fields_size = wl1271_rx_filter_get_fields_size(filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wl1271_debug(DEBUG_ACX, "act: %d num_fields: %d field_size: %d",
 | 
				
			||||||
 | 
							      filter->action, filter->num_fields, fields_size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acx_size = ALIGN(sizeof(*acx) + fields_size, 4);
 | 
				
			||||||
 | 
						acx = kzalloc(acx_size, GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!acx)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acx->enable = enable;
 | 
				
			||||||
 | 
						acx->index = index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							acx->num_fields = filter->num_fields;
 | 
				
			||||||
 | 
							acx->action = filter->action;
 | 
				
			||||||
 | 
							wl1271_rx_filter_flatten_fields(filter, acx->fields);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl1271_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx, acx_size);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							wl1271_warning("setting rx filter failed: %d", ret);
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						kfree(acx);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1147,6 +1147,32 @@ struct wl12xx_acx_config_hangover {
 | 
				
			||||||
	u8 padding[2];
 | 
						u8 padding[2];
 | 
				
			||||||
} __packed;
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct acx_default_rx_filter {
 | 
				
			||||||
 | 
						struct acx_header header;
 | 
				
			||||||
 | 
						u8 enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* action of type FILTER_XXX */
 | 
				
			||||||
 | 
						u8 default_action;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 pad[2];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct acx_rx_filter_cfg {
 | 
				
			||||||
 | 
						struct acx_header header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 0 - WL1271_MAX_RX_FILTERS-1 */
 | 
				
			||||||
 | 
						u8 index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 action;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 num_fields;
 | 
				
			||||||
 | 
						u8 fields[0];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	ACX_WAKE_UP_CONDITIONS           = 0x0000,
 | 
						ACX_WAKE_UP_CONDITIONS           = 0x0000,
 | 
				
			||||||
	ACX_MEM_CFG                      = 0x0001,
 | 
						ACX_MEM_CFG                      = 0x0001,
 | 
				
			||||||
| 
						 | 
					@ -1304,5 +1330,9 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
 | 
				
			||||||
int wl1271_acx_fm_coex(struct wl1271 *wl);
 | 
					int wl1271_acx_fm_coex(struct wl1271 *wl);
 | 
				
			||||||
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
 | 
					int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
 | 
				
			||||||
int wl12xx_acx_config_hangover(struct wl1271 *wl);
 | 
					int wl12xx_acx_config_hangover(struct wl1271 *wl);
 | 
				
			||||||
 | 
					int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
 | 
				
			||||||
 | 
										enum rx_filter_action action);
 | 
				
			||||||
 | 
					int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
 | 
				
			||||||
 | 
								     struct wl12xx_rx_filter *filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __WL1271_ACX_H__ */
 | 
					#endif /* __WL1271_ACX_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue