diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-11-17 13:11:43 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-17 13:11:43 -0500 |
commit | e11c259f745889b55bc5596ca78271f2f5cf08d2 (patch) | |
tree | 5025f0bf9093e84d0643beb9097249c176dbbea7 /drivers | |
parent | 8d26784cf0d04c1238e906efdd5de76439cb0a1e (diff) | |
parent | b4487c2d0edaf1332d7a9f11b5661044955ef5e2 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
include/net/bluetooth/bluetooth.h
Diffstat (limited to 'drivers')
114 files changed, 4706 insertions, 4811 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 106beb194f3c..1622772f802d 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | 31 | ||
32 | #define VERSION "1.0" | 32 | #define VERSION "1.0" |
33 | #define ATH3K_FIRMWARE "ath3k-1.fw" | ||
33 | 34 | ||
34 | #define ATH3K_DNLOAD 0x01 | 35 | #define ATH3K_DNLOAD 0x01 |
35 | #define ATH3K_GETSTATE 0x05 | 36 | #define ATH3K_GETSTATE 0x05 |
@@ -400,9 +401,15 @@ static int ath3k_probe(struct usb_interface *intf, | |||
400 | return 0; | 401 | return 0; |
401 | } | 402 | } |
402 | 403 | ||
403 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | 404 | ret = request_firmware(&firmware, ATH3K_FIRMWARE, &udev->dev); |
404 | BT_ERR("Error loading firmware"); | 405 | if (ret < 0) { |
405 | return -EIO; | 406 | if (ret == -ENOENT) |
407 | BT_ERR("Firmware file \"%s\" not found", | ||
408 | ATH3K_FIRMWARE); | ||
409 | else | ||
410 | BT_ERR("Firmware file \"%s\" request failed (err=%d)", | ||
411 | ATH3K_FIRMWARE, ret); | ||
412 | return ret; | ||
406 | } | 413 | } |
407 | 414 | ||
408 | ret = ath3k_load_firmware(udev, firmware); | 415 | ret = ath3k_load_firmware(udev, firmware); |
@@ -441,4 +448,4 @@ MODULE_AUTHOR("Atheros Communications"); | |||
441 | MODULE_DESCRIPTION("Atheros AR30xx firmware driver"); | 448 | MODULE_DESCRIPTION("Atheros AR30xx firmware driver"); |
442 | MODULE_VERSION(VERSION); | 449 | MODULE_VERSION(VERSION); |
443 | MODULE_LICENSE("GPL"); | 450 | MODULE_LICENSE("GPL"); |
444 | MODULE_FIRMWARE("ath3k-1.fw"); | 451 | MODULE_FIRMWARE(ATH3K_FIRMWARE); |
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 61b591470a90..a936763b8c3d 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c | |||
@@ -751,9 +751,7 @@ static void bfusb_disconnect(struct usb_interface *intf) | |||
751 | 751 | ||
752 | bfusb_close(hdev); | 752 | bfusb_close(hdev); |
753 | 753 | ||
754 | if (hci_unregister_dev(hdev) < 0) | 754 | hci_unregister_dev(hdev); |
755 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
756 | |||
757 | hci_free_dev(hdev); | 755 | hci_free_dev(hdev); |
758 | } | 756 | } |
759 | 757 | ||
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index aed1904ea67b..c6a0c6103743 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -844,9 +844,7 @@ static int bluecard_close(bluecard_info_t *info) | |||
844 | /* Turn FPGA off */ | 844 | /* Turn FPGA off */ |
845 | outb(0x80, iobase + 0x30); | 845 | outb(0x80, iobase + 0x30); |
846 | 846 | ||
847 | if (hci_unregister_dev(hdev) < 0) | 847 | hci_unregister_dev(hdev); |
848 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
849 | |||
850 | hci_free_dev(hdev); | 848 | hci_free_dev(hdev); |
851 | 849 | ||
852 | return 0; | 850 | return 0; |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 4fc01949d399..0c97e5d514b6 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -636,9 +636,7 @@ static int bt3c_close(bt3c_info_t *info) | |||
636 | 636 | ||
637 | bt3c_hci_close(hdev); | 637 | bt3c_hci_close(hdev); |
638 | 638 | ||
639 | if (hci_unregister_dev(hdev) < 0) | 639 | hci_unregister_dev(hdev); |
640 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
641 | |||
642 | hci_free_dev(hdev); | 640 | hci_free_dev(hdev); |
643 | 641 | ||
644 | return 0; | 642 | return 0; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 526b61807d94..200b3a2877d6 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -565,9 +565,7 @@ static int btuart_close(btuart_info_t *info) | |||
565 | 565 | ||
566 | spin_unlock_irqrestore(&(info->lock), flags); | 566 | spin_unlock_irqrestore(&(info->lock), flags); |
567 | 567 | ||
568 | if (hci_unregister_dev(hdev) < 0) | 568 | hci_unregister_dev(hdev); |
569 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
570 | |||
571 | hci_free_dev(hdev); | 569 | hci_free_dev(hdev); |
572 | 570 | ||
573 | return 0; | 571 | return 0; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f9b726091ad0..2bd87d45f1c2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = { | |||
100 | /* Canyon CN-BTU1 with HID interfaces */ | 100 | /* Canyon CN-BTU1 with HID interfaces */ |
101 | { USB_DEVICE(0x0c10, 0x0000) }, | 101 | { USB_DEVICE(0x0c10, 0x0000) }, |
102 | 102 | ||
103 | /* Broadcom BCM20702A0 */ | ||
104 | { USB_DEVICE(0x413c, 0x8197) }, | ||
105 | |||
103 | { } /* Terminating entry */ | 106 | { } /* Terminating entry */ |
104 | }; | 107 | }; |
105 | 108 | ||
@@ -312,7 +315,8 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
312 | 315 | ||
313 | err = usb_submit_urb(urb, mem_flags); | 316 | err = usb_submit_urb(urb, mem_flags); |
314 | if (err < 0) { | 317 | if (err < 0) { |
315 | BT_ERR("%s urb %p submission failed (%d)", | 318 | if (err != -EPERM && err != -ENODEV) |
319 | BT_ERR("%s urb %p submission failed (%d)", | ||
316 | hdev->name, urb, -err); | 320 | hdev->name, urb, -err); |
317 | usb_unanchor_urb(urb); | 321 | usb_unanchor_urb(urb); |
318 | } | 322 | } |
@@ -397,7 +401,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
397 | 401 | ||
398 | err = usb_submit_urb(urb, mem_flags); | 402 | err = usb_submit_urb(urb, mem_flags); |
399 | if (err < 0) { | 403 | if (err < 0) { |
400 | BT_ERR("%s urb %p submission failed (%d)", | 404 | if (err != -EPERM && err != -ENODEV) |
405 | BT_ERR("%s urb %p submission failed (%d)", | ||
401 | hdev->name, urb, -err); | 406 | hdev->name, urb, -err); |
402 | usb_unanchor_urb(urb); | 407 | usb_unanchor_urb(urb); |
403 | } | 408 | } |
@@ -520,7 +525,8 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
520 | 525 | ||
521 | err = usb_submit_urb(urb, mem_flags); | 526 | err = usb_submit_urb(urb, mem_flags); |
522 | if (err < 0) { | 527 | if (err < 0) { |
523 | BT_ERR("%s urb %p submission failed (%d)", | 528 | if (err != -EPERM && err != -ENODEV) |
529 | BT_ERR("%s urb %p submission failed (%d)", | ||
524 | hdev->name, urb, -err); | 530 | hdev->name, urb, -err); |
525 | usb_unanchor_urb(urb); | 531 | usb_unanchor_urb(urb); |
526 | } | 532 | } |
@@ -724,6 +730,9 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
724 | usb_fill_bulk_urb(urb, data->udev, pipe, | 730 | usb_fill_bulk_urb(urb, data->udev, pipe, |
725 | skb->data, skb->len, btusb_tx_complete, skb); | 731 | skb->data, skb->len, btusb_tx_complete, skb); |
726 | 732 | ||
733 | if (skb->priority >= HCI_PRIO_MAX - 1) | ||
734 | urb->transfer_flags = URB_ISO_ASAP; | ||
735 | |||
727 | hdev->stat.acl_tx++; | 736 | hdev->stat.acl_tx++; |
728 | break; | 737 | break; |
729 | 738 | ||
@@ -767,7 +776,9 @@ skip_waking: | |||
767 | 776 | ||
768 | err = usb_submit_urb(urb, GFP_ATOMIC); | 777 | err = usb_submit_urb(urb, GFP_ATOMIC); |
769 | if (err < 0) { | 778 | if (err < 0) { |
770 | BT_ERR("%s urb %p submission failed", hdev->name, urb); | 779 | if (err != -EPERM && err != -ENODEV) |
780 | BT_ERR("%s urb %p submission failed (%d)", | ||
781 | hdev->name, urb, -err); | ||
771 | kfree(urb->setup_packet); | 782 | kfree(urb->setup_packet); |
772 | usb_unanchor_urb(urb); | 783 | usb_unanchor_urb(urb); |
773 | } else { | 784 | } else { |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 5e4c2de9fc3f..969bb22e493f 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -551,9 +551,7 @@ static int dtl1_close(dtl1_info_t *info) | |||
551 | 551 | ||
552 | spin_unlock_irqrestore(&(info->lock), flags); | 552 | spin_unlock_irqrestore(&(info->lock), flags); |
553 | 553 | ||
554 | if (hci_unregister_dev(hdev) < 0) | 554 | hci_unregister_dev(hdev); |
555 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
556 | |||
557 | hci_free_dev(hdev); | 555 | hci_free_dev(hdev); |
558 | 556 | ||
559 | return 0; | 557 | return 0; |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 67c180c2c1e0..2e302a11ab55 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -264,10 +264,7 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
264 | struct vhci_data *data = file->private_data; | 264 | struct vhci_data *data = file->private_data; |
265 | struct hci_dev *hdev = data->hdev; | 265 | struct hci_dev *hdev = data->hdev; |
266 | 266 | ||
267 | if (hci_unregister_dev(hdev) < 0) { | 267 | hci_unregister_dev(hdev); |
268 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
269 | } | ||
270 | |||
271 | hci_free_dev(hdev); | 268 | hci_free_dev(hdev); |
272 | 269 | ||
273 | file->private_data = NULL; | 270 | file->private_data = NULL; |
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 0a304b060b6c..c1c0678b1fb6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile | |||
@@ -58,6 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ | |||
58 | obj-$(CONFIG_IWM) += iwmc3200wifi/ | 58 | obj-$(CONFIG_IWM) += iwmc3200wifi/ |
59 | 59 | ||
60 | obj-$(CONFIG_MWIFIEX) += mwifiex/ | 60 | obj-$(CONFIG_MWIFIEX) += mwifiex/ |
61 | obj-$(CONFIG_BRCMFMAC) += brcm80211/ | 61 | |
62 | obj-$(CONFIG_BRCMUMAC) += brcm80211/ | 62 | obj-$(CONFIG_BRCMFMAC) += brcm80211/ |
63 | obj-$(CONFIG_BRCMSMAC) += brcm80211/ | 63 | obj-$(CONFIG_BRCMSMAC) += brcm80211/ |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 0f9ee46cfc97..4596c33a7a69 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -239,6 +239,7 @@ enum ATH_DEBUG { | |||
239 | ATH_DBG_BTCOEX = 0x00002000, | 239 | ATH_DBG_BTCOEX = 0x00002000, |
240 | ATH_DBG_WMI = 0x00004000, | 240 | ATH_DBG_WMI = 0x00004000, |
241 | ATH_DBG_BSTUCK = 0x00008000, | 241 | ATH_DBG_BSTUCK = 0x00008000, |
242 | ATH_DBG_MCI = 0x00010000, | ||
242 | ATH_DBG_ANY = 0xffffffff | 243 | ATH_DBG_ANY = 0xffffffff |
243 | }; | 244 | }; |
244 | 245 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f517eb8f7b44..5ac2bc2ebee6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1734,7 +1734,8 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1734 | struct ieee80211_channel *chan, bool offchan, | 1734 | struct ieee80211_channel *chan, bool offchan, |
1735 | enum nl80211_channel_type channel_type, | 1735 | enum nl80211_channel_type channel_type, |
1736 | bool channel_type_valid, unsigned int wait, | 1736 | bool channel_type_valid, unsigned int wait, |
1737 | const u8 *buf, size_t len, bool no_cck, u64 *cookie) | 1737 | const u8 *buf, size_t len, bool no_cck, |
1738 | bool dont_wait_for_ack, u64 *cookie) | ||
1738 | { | 1739 | { |
1739 | struct ath6kl *ar = ath6kl_priv(dev); | 1740 | struct ath6kl *ar = ath6kl_priv(dev); |
1740 | u32 id; | 1741 | u32 id; |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index c1d2366704b5..81e0031012ca 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -1548,7 +1548,8 @@ static int ath6kl_init(struct net_device *dev) | |||
1548 | ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | | 1548 | ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | |
1549 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; | 1549 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; |
1550 | 1550 | ||
1551 | ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; | 1551 | ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | |
1552 | WIPHY_FLAG_HAVE_AP_SME; | ||
1552 | 1553 | ||
1553 | status = ath6kl_target_config_wlan_params(ar); | 1554 | status = ath6kl_target_config_wlan_params(ar); |
1554 | if (!status) | 1555 | if (!status) |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index d9c08c619a3a..7b4c074e12fa 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -25,6 +25,7 @@ config ATH9K | |||
25 | 25 | ||
26 | config ATH9K_PCI | 26 | config ATH9K_PCI |
27 | bool "Atheros ath9k PCI/PCIe bus support" | 27 | bool "Atheros ath9k PCI/PCIe bus support" |
28 | default y | ||
28 | depends on ATH9K && PCI | 29 | depends on ATH9K && PCI |
29 | ---help--- | 30 | ---help--- |
30 | This option enables the PCI bus support in ath9k. | 31 | This option enables the PCI bus support in ath9k. |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 36ed3c46fec6..49d3f25f509d 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -4,6 +4,7 @@ ath9k-y += beacon.o \ | |||
4 | main.o \ | 4 | main.o \ |
5 | recv.o \ | 5 | recv.o \ |
6 | xmit.o \ | 6 | xmit.o \ |
7 | mci.o \ | ||
7 | 8 | ||
8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 9 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
9 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o | 10 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 3b262ba6b172..a93bd63ad23b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -121,10 +121,8 @@ static const struct ar9300_eeprom ar9300_default = { | |||
121 | * if the register is per chain | 121 | * if the register is per chain |
122 | */ | 122 | */ |
123 | .noiseFloorThreshCh = {-1, 0, 0}, | 123 | .noiseFloorThreshCh = {-1, 0, 0}, |
124 | .ob = {1, 1, 1},/* 3 chain */ | 124 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
125 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 125 | .quick_drop = 0, |
126 | .db_stage3 = {0, 0, 0}, | ||
127 | .db_stage4 = {0, 0, 0}, | ||
128 | .xpaBiasLvl = 0, | 126 | .xpaBiasLvl = 0, |
129 | .txFrameToDataStart = 0x0e, | 127 | .txFrameToDataStart = 0x0e, |
130 | .txFrameToPaOn = 0x0e, | 128 | .txFrameToPaOn = 0x0e, |
@@ -144,7 +142,7 @@ static const struct ar9300_eeprom ar9300_default = { | |||
144 | }, | 142 | }, |
145 | .base_ext1 = { | 143 | .base_ext1 = { |
146 | .ant_div_control = 0, | 144 | .ant_div_control = 0, |
147 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 145 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
148 | }, | 146 | }, |
149 | .calFreqPier2G = { | 147 | .calFreqPier2G = { |
150 | FREQ2FBIN(2412, 1), | 148 | FREQ2FBIN(2412, 1), |
@@ -323,10 +321,8 @@ static const struct ar9300_eeprom ar9300_default = { | |||
323 | .spurChans = {0, 0, 0, 0, 0}, | 321 | .spurChans = {0, 0, 0, 0, 0}, |
324 | /* noiseFloorThreshCh Check if the register is per chain */ | 322 | /* noiseFloorThreshCh Check if the register is per chain */ |
325 | .noiseFloorThreshCh = {-1, 0, 0}, | 323 | .noiseFloorThreshCh = {-1, 0, 0}, |
326 | .ob = {3, 3, 3}, /* 3 chain */ | 324 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
327 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 325 | .quick_drop = 0, |
328 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
329 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
330 | .xpaBiasLvl = 0, | 326 | .xpaBiasLvl = 0, |
331 | .txFrameToDataStart = 0x0e, | 327 | .txFrameToDataStart = 0x0e, |
332 | .txFrameToPaOn = 0x0e, | 328 | .txFrameToPaOn = 0x0e, |
@@ -698,10 +694,8 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
698 | * if the register is per chain | 694 | * if the register is per chain |
699 | */ | 695 | */ |
700 | .noiseFloorThreshCh = {-1, 0, 0}, | 696 | .noiseFloorThreshCh = {-1, 0, 0}, |
701 | .ob = {1, 1, 1},/* 3 chain */ | 697 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
702 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 698 | .quick_drop = 0, |
703 | .db_stage3 = {0, 0, 0}, | ||
704 | .db_stage4 = {0, 0, 0}, | ||
705 | .xpaBiasLvl = 0, | 699 | .xpaBiasLvl = 0, |
706 | .txFrameToDataStart = 0x0e, | 700 | .txFrameToDataStart = 0x0e, |
707 | .txFrameToPaOn = 0x0e, | 701 | .txFrameToPaOn = 0x0e, |
@@ -721,7 +715,7 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
721 | }, | 715 | }, |
722 | .base_ext1 = { | 716 | .base_ext1 = { |
723 | .ant_div_control = 0, | 717 | .ant_div_control = 0, |
724 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 718 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
725 | }, | 719 | }, |
726 | .calFreqPier2G = { | 720 | .calFreqPier2G = { |
727 | FREQ2FBIN(2412, 1), | 721 | FREQ2FBIN(2412, 1), |
@@ -900,10 +894,8 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
900 | .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, | 894 | .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, |
901 | /* noiseFloorThreshCh Check if the register is per chain */ | 895 | /* noiseFloorThreshCh Check if the register is per chain */ |
902 | .noiseFloorThreshCh = {-1, 0, 0}, | 896 | .noiseFloorThreshCh = {-1, 0, 0}, |
903 | .ob = {3, 3, 3}, /* 3 chain */ | 897 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
904 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 898 | .quick_drop = 0, |
905 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
906 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
907 | .xpaBiasLvl = 0xf, | 899 | .xpaBiasLvl = 0xf, |
908 | .txFrameToDataStart = 0x0e, | 900 | .txFrameToDataStart = 0x0e, |
909 | .txFrameToPaOn = 0x0e, | 901 | .txFrameToPaOn = 0x0e, |
@@ -1276,10 +1268,8 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1276 | * if the register is per chain | 1268 | * if the register is per chain |
1277 | */ | 1269 | */ |
1278 | .noiseFloorThreshCh = {-1, 0, 0}, | 1270 | .noiseFloorThreshCh = {-1, 0, 0}, |
1279 | .ob = {1, 1, 1},/* 3 chain */ | 1271 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1280 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 1272 | .quick_drop = 0, |
1281 | .db_stage3 = {0, 0, 0}, | ||
1282 | .db_stage4 = {0, 0, 0}, | ||
1283 | .xpaBiasLvl = 0, | 1273 | .xpaBiasLvl = 0, |
1284 | .txFrameToDataStart = 0x0e, | 1274 | .txFrameToDataStart = 0x0e, |
1285 | .txFrameToPaOn = 0x0e, | 1275 | .txFrameToPaOn = 0x0e, |
@@ -1291,20 +1281,20 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1291 | .txEndToRxOn = 0x2, | 1281 | .txEndToRxOn = 0x2, |
1292 | .txFrameToXpaOn = 0xe, | 1282 | .txFrameToXpaOn = 0xe, |
1293 | .thresh62 = 28, | 1283 | .thresh62 = 28, |
1294 | .papdRateMaskHt20 = LE32(0x80c080), | 1284 | .papdRateMaskHt20 = LE32(0x0c80c080), |
1295 | .papdRateMaskHt40 = LE32(0x80c080), | 1285 | .papdRateMaskHt40 = LE32(0x0080c080), |
1296 | .futureModal = { | 1286 | .futureModal = { |
1297 | 0, 0, 0, 0, 0, 0, 0, 0, | 1287 | 0, 0, 0, 0, 0, 0, 0, 0, |
1298 | }, | 1288 | }, |
1299 | }, | 1289 | }, |
1300 | .base_ext1 = { | 1290 | .base_ext1 = { |
1301 | .ant_div_control = 0, | 1291 | .ant_div_control = 0, |
1302 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 1292 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
1303 | }, | 1293 | }, |
1304 | .calFreqPier2G = { | 1294 | .calFreqPier2G = { |
1305 | FREQ2FBIN(2412, 1), | 1295 | FREQ2FBIN(2412, 1), |
1306 | FREQ2FBIN(2437, 1), | 1296 | FREQ2FBIN(2437, 1), |
1307 | FREQ2FBIN(2472, 1), | 1297 | FREQ2FBIN(2462, 1), |
1308 | }, | 1298 | }, |
1309 | /* ar9300_cal_data_per_freq_op_loop 2g */ | 1299 | /* ar9300_cal_data_per_freq_op_loop 2g */ |
1310 | .calPierData2G = { | 1300 | .calPierData2G = { |
@@ -1314,7 +1304,7 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1314 | }, | 1304 | }, |
1315 | .calTarget_freqbin_Cck = { | 1305 | .calTarget_freqbin_Cck = { |
1316 | FREQ2FBIN(2412, 1), | 1306 | FREQ2FBIN(2412, 1), |
1317 | FREQ2FBIN(2484, 1), | 1307 | FREQ2FBIN(2472, 1), |
1318 | }, | 1308 | }, |
1319 | .calTarget_freqbin_2G = { | 1309 | .calTarget_freqbin_2G = { |
1320 | FREQ2FBIN(2412, 1), | 1310 | FREQ2FBIN(2412, 1), |
@@ -1478,10 +1468,8 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1478 | .spurChans = {0, 0, 0, 0, 0}, | 1468 | .spurChans = {0, 0, 0, 0, 0}, |
1479 | /* noiseFloorThreshCh Check if the register is per chain */ | 1469 | /* noiseFloorThreshCh Check if the register is per chain */ |
1480 | .noiseFloorThreshCh = {-1, 0, 0}, | 1470 | .noiseFloorThreshCh = {-1, 0, 0}, |
1481 | .ob = {3, 3, 3}, /* 3 chain */ | 1471 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1482 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 1472 | .quick_drop = 0, |
1483 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
1484 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
1485 | .xpaBiasLvl = 0, | 1473 | .xpaBiasLvl = 0, |
1486 | .txFrameToDataStart = 0x0e, | 1474 | .txFrameToDataStart = 0x0e, |
1487 | .txFrameToPaOn = 0x0e, | 1475 | .txFrameToPaOn = 0x0e, |
@@ -1515,7 +1503,7 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1515 | FREQ2FBIN(5500, 0), | 1503 | FREQ2FBIN(5500, 0), |
1516 | FREQ2FBIN(5600, 0), | 1504 | FREQ2FBIN(5600, 0), |
1517 | FREQ2FBIN(5700, 0), | 1505 | FREQ2FBIN(5700, 0), |
1518 | FREQ2FBIN(5825, 0) | 1506 | FREQ2FBIN(5785, 0) |
1519 | }, | 1507 | }, |
1520 | .calPierData5G = { | 1508 | .calPierData5G = { |
1521 | { | 1509 | { |
@@ -1854,10 +1842,8 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
1854 | * if the register is per chain | 1842 | * if the register is per chain |
1855 | */ | 1843 | */ |
1856 | .noiseFloorThreshCh = {-1, 0, 0}, | 1844 | .noiseFloorThreshCh = {-1, 0, 0}, |
1857 | .ob = {1, 1, 1},/* 3 chain */ | 1845 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1858 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 1846 | .quick_drop = 0, |
1859 | .db_stage3 = {0, 0, 0}, | ||
1860 | .db_stage4 = {0, 0, 0}, | ||
1861 | .xpaBiasLvl = 0, | 1847 | .xpaBiasLvl = 0, |
1862 | .txFrameToDataStart = 0x0e, | 1848 | .txFrameToDataStart = 0x0e, |
1863 | .txFrameToPaOn = 0x0e, | 1849 | .txFrameToPaOn = 0x0e, |
@@ -1877,7 +1863,7 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
1877 | }, | 1863 | }, |
1878 | .base_ext1 = { | 1864 | .base_ext1 = { |
1879 | .ant_div_control = 0, | 1865 | .ant_div_control = 0, |
1880 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 1866 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
1881 | }, | 1867 | }, |
1882 | .calFreqPier2G = { | 1868 | .calFreqPier2G = { |
1883 | FREQ2FBIN(2412, 1), | 1869 | FREQ2FBIN(2412, 1), |
@@ -2056,10 +2042,8 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
2056 | .spurChans = {0, 0, 0, 0, 0}, | 2042 | .spurChans = {0, 0, 0, 0, 0}, |
2057 | /* noiseFloorThreshch check if the register is per chain */ | 2043 | /* noiseFloorThreshch check if the register is per chain */ |
2058 | .noiseFloorThreshCh = {-1, 0, 0}, | 2044 | .noiseFloorThreshCh = {-1, 0, 0}, |
2059 | .ob = {3, 3, 3}, /* 3 chain */ | 2045 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2060 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 2046 | .quick_drop = 0, |
2061 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
2062 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
2063 | .xpaBiasLvl = 0, | 2047 | .xpaBiasLvl = 0, |
2064 | .txFrameToDataStart = 0x0e, | 2048 | .txFrameToDataStart = 0x0e, |
2065 | .txFrameToPaOn = 0x0e, | 2049 | .txFrameToPaOn = 0x0e, |
@@ -2431,10 +2415,8 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2431 | * if the register is per chain | 2415 | * if the register is per chain |
2432 | */ | 2416 | */ |
2433 | .noiseFloorThreshCh = {-1, 0, 0}, | 2417 | .noiseFloorThreshCh = {-1, 0, 0}, |
2434 | .ob = {1, 1, 1},/* 3 chain */ | 2418 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2435 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 2419 | .quick_drop = 0, |
2436 | .db_stage3 = {0, 0, 0}, | ||
2437 | .db_stage4 = {0, 0, 0}, | ||
2438 | .xpaBiasLvl = 0, | 2420 | .xpaBiasLvl = 0, |
2439 | .txFrameToDataStart = 0x0e, | 2421 | .txFrameToDataStart = 0x0e, |
2440 | .txFrameToPaOn = 0x0e, | 2422 | .txFrameToPaOn = 0x0e, |
@@ -2454,12 +2436,12 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2454 | }, | 2436 | }, |
2455 | .base_ext1 = { | 2437 | .base_ext1 = { |
2456 | .ant_div_control = 0, | 2438 | .ant_div_control = 0, |
2457 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 2439 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
2458 | }, | 2440 | }, |
2459 | .calFreqPier2G = { | 2441 | .calFreqPier2G = { |
2460 | FREQ2FBIN(2412, 1), | 2442 | FREQ2FBIN(2412, 1), |
2461 | FREQ2FBIN(2437, 1), | 2443 | FREQ2FBIN(2437, 1), |
2462 | FREQ2FBIN(2472, 1), | 2444 | FREQ2FBIN(2462, 1), |
2463 | }, | 2445 | }, |
2464 | /* ar9300_cal_data_per_freq_op_loop 2g */ | 2446 | /* ar9300_cal_data_per_freq_op_loop 2g */ |
2465 | .calPierData2G = { | 2447 | .calPierData2G = { |
@@ -2633,10 +2615,8 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2633 | .spurChans = {0, 0, 0, 0, 0}, | 2615 | .spurChans = {0, 0, 0, 0, 0}, |
2634 | /* noiseFloorThreshCh Check if the register is per chain */ | 2616 | /* noiseFloorThreshCh Check if the register is per chain */ |
2635 | .noiseFloorThreshCh = {-1, 0, 0}, | 2617 | .noiseFloorThreshCh = {-1, 0, 0}, |
2636 | .ob = {3, 3, 3}, /* 3 chain */ | 2618 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2637 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 2619 | .quick_drop = 0, |
2638 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
2639 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
2640 | .xpaBiasLvl = 0, | 2620 | .xpaBiasLvl = 0, |
2641 | .txFrameToDataStart = 0x0e, | 2621 | .txFrameToDataStart = 0x0e, |
2642 | .txFrameToPaOn = 0x0e, | 2622 | .txFrameToPaOn = 0x0e, |
@@ -2663,7 +2643,7 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2663 | .xatten1MarginHigh = {0, 0, 0} | 2643 | .xatten1MarginHigh = {0, 0, 0} |
2664 | }, | 2644 | }, |
2665 | .calFreqPier5G = { | 2645 | .calFreqPier5G = { |
2666 | FREQ2FBIN(5180, 0), | 2646 | FREQ2FBIN(5160, 0), |
2667 | FREQ2FBIN(5220, 0), | 2647 | FREQ2FBIN(5220, 0), |
2668 | FREQ2FBIN(5320, 0), | 2648 | FREQ2FBIN(5320, 0), |
2669 | FREQ2FBIN(5400, 0), | 2649 | FREQ2FBIN(5400, 0), |
@@ -3023,6 +3003,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | |||
3023 | return eep->modalHeader5G.antennaGain; | 3003 | return eep->modalHeader5G.antennaGain; |
3024 | case EEP_ANTENNA_GAIN_2G: | 3004 | case EEP_ANTENNA_GAIN_2G: |
3025 | return eep->modalHeader2G.antennaGain; | 3005 | return eep->modalHeader2G.antennaGain; |
3006 | case EEP_QUICK_DROP: | ||
3007 | return pBase->miscConfiguration & BIT(1); | ||
3026 | default: | 3008 | default: |
3027 | return 0; | 3009 | return 0; |
3028 | } | 3010 | } |
@@ -3428,25 +3410,14 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size, | |||
3428 | PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); | 3410 | PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); |
3429 | PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]); | 3411 | PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]); |
3430 | PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]); | 3412 | PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]); |
3413 | PR_EEP("Quick Drop", modal_hdr->quick_drop); | ||
3414 | PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff); | ||
3431 | PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); | 3415 | PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); |
3432 | PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); | 3416 | PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); |
3433 | PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); | 3417 | PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); |
3434 | PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); | 3418 | PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); |
3435 | PR_EEP("txClip", modal_hdr->txClip); | 3419 | PR_EEP("txClip", modal_hdr->txClip); |
3436 | PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); | 3420 | PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); |
3437 | PR_EEP("Chain0 ob", modal_hdr->ob[0]); | ||
3438 | PR_EEP("Chain1 ob", modal_hdr->ob[1]); | ||
3439 | PR_EEP("Chain2 ob", modal_hdr->ob[2]); | ||
3440 | |||
3441 | PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]); | ||
3442 | PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]); | ||
3443 | PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]); | ||
3444 | PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]); | ||
3445 | PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]); | ||
3446 | PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]); | ||
3447 | PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]); | ||
3448 | PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]); | ||
3449 | PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]); | ||
3450 | 3421 | ||
3451 | return len; | 3422 | return len; |
3452 | } | 3423 | } |
@@ -3503,6 +3474,7 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
3503 | PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4))); | 3474 | PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4))); |
3504 | PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5))); | 3475 | PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5))); |
3505 | PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0))); | 3476 | PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0))); |
3477 | PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1))); | ||
3506 | PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1); | 3478 | PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1); |
3507 | PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio); | 3479 | PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio); |
3508 | PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio); | 3480 | PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio); |
@@ -3965,6 +3937,40 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) | |||
3965 | } | 3937 | } |
3966 | } | 3938 | } |
3967 | 3939 | ||
3940 | static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) | ||
3941 | { | ||
3942 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3943 | int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP); | ||
3944 | s32 t[3], f[3] = {5180, 5500, 5785}; | ||
3945 | |||
3946 | if (!quick_drop) | ||
3947 | return; | ||
3948 | |||
3949 | if (freq < 4000) | ||
3950 | quick_drop = eep->modalHeader2G.quick_drop; | ||
3951 | else { | ||
3952 | t[0] = eep->base_ext1.quick_drop_low; | ||
3953 | t[1] = eep->modalHeader5G.quick_drop; | ||
3954 | t[2] = eep->base_ext1.quick_drop_high; | ||
3955 | quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); | ||
3956 | } | ||
3957 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); | ||
3958 | } | ||
3959 | |||
3960 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq) | ||
3961 | { | ||
3962 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3963 | u32 value; | ||
3964 | |||
3965 | value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff : | ||
3966 | eep->modalHeader5G.txEndToXpaOff; | ||
3967 | |||
3968 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3969 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); | ||
3970 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3971 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); | ||
3972 | } | ||
3973 | |||
3968 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | 3974 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, |
3969 | struct ath9k_channel *chan) | 3975 | struct ath9k_channel *chan) |
3970 | { | 3976 | { |
@@ -3972,10 +3978,12 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
3972 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3978 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); |
3973 | ar9003_hw_drive_strength_apply(ah); | 3979 | ar9003_hw_drive_strength_apply(ah); |
3974 | ar9003_hw_atten_apply(ah, chan); | 3980 | ar9003_hw_atten_apply(ah, chan); |
3981 | ar9003_hw_quick_drop_apply(ah, chan->channel); | ||
3975 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) | 3982 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) |
3976 | ar9003_hw_internal_regulator_apply(ah); | 3983 | ar9003_hw_internal_regulator_apply(ah); |
3977 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) | 3984 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
3978 | ar9003_hw_apply_tuning_caps(ah); | 3985 | ar9003_hw_apply_tuning_caps(ah); |
3986 | ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel); | ||
3979 | } | 3987 | } |
3980 | 3988 | ||
3981 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, | 3989 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, |
@@ -5051,6 +5059,8 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
5051 | regulatory->max_power_level = targetPowerValT2[i]; | 5059 | regulatory->max_power_level = targetPowerValT2[i]; |
5052 | } | 5060 | } |
5053 | 5061 | ||
5062 | ath9k_hw_update_regulatory_maxpower(ah); | ||
5063 | |||
5054 | if (test) | 5064 | if (test) |
5055 | return; | 5065 | return; |
5056 | 5066 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 6335a867527e..bb223fe82816 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -216,10 +216,8 @@ struct ar9300_modal_eep_header { | |||
216 | u8 spurChans[AR_EEPROM_MODAL_SPURS]; | 216 | u8 spurChans[AR_EEPROM_MODAL_SPURS]; |
217 | /* 3 Check if the register is per chain */ | 217 | /* 3 Check if the register is per chain */ |
218 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; | 218 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; |
219 | u8 ob[AR9300_MAX_CHAINS]; | 219 | u8 reserved[11]; |
220 | u8 db_stage2[AR9300_MAX_CHAINS]; | 220 | int8_t quick_drop; |
221 | u8 db_stage3[AR9300_MAX_CHAINS]; | ||
222 | u8 db_stage4[AR9300_MAX_CHAINS]; | ||
223 | u8 xpaBiasLvl; | 221 | u8 xpaBiasLvl; |
224 | u8 txFrameToDataStart; | 222 | u8 txFrameToDataStart; |
225 | u8 txFrameToPaOn; | 223 | u8 txFrameToPaOn; |
@@ -269,7 +267,9 @@ struct cal_ctl_data_5g { | |||
269 | 267 | ||
270 | struct ar9300_BaseExtension_1 { | 268 | struct ar9300_BaseExtension_1 { |
271 | u8 ant_div_control; | 269 | u8 ant_div_control; |
272 | u8 future[13]; | 270 | u8 future[11]; |
271 | int8_t quick_drop_low; | ||
272 | int8_t quick_drop_high; | ||
273 | } __packed; | 273 | } __packed; |
274 | 274 | ||
275 | struct ar9300_BaseExtension_2 { | 275 | struct ar9300_BaseExtension_2 { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2330e7ede199..e41d26939ab8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -199,12 +199,14 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
199 | synth_freq = chan->channel; | 199 | synth_freq = chan->channel; |
200 | } | 200 | } |
201 | } else { | 201 | } else { |
202 | range = 10; | 202 | range = AR_SREV_9462(ah) ? 5 : 10; |
203 | max_spur_cnts = 4; | 203 | max_spur_cnts = 4; |
204 | synth_freq = chan->channel; | 204 | synth_freq = chan->channel; |
205 | } | 205 | } |
206 | 206 | ||
207 | for (i = 0; i < max_spur_cnts; i++) { | 207 | for (i = 0; i < max_spur_cnts; i++) { |
208 | if (AR_SREV_9462(ah) && (i == 0 || i == 3)) | ||
209 | continue; | ||
208 | negative = 0; | 210 | negative = 0; |
209 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) | 211 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) |
210 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 212 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 4114fe752c6b..497d7461838a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -389,6 +389,8 @@ | |||
389 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | 389 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 |
390 | 390 | ||
391 | #define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 | 391 | #define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 |
392 | #define AR_PHY_AGC_QUICK_DROP 0x03c00000 | ||
393 | #define AR_PHY_AGC_QUICK_DROP_S 22 | ||
392 | #define AR_PHY_AGC_COARSE_LOW 0x00007F80 | 394 | #define AR_PHY_AGC_COARSE_LOW 0x00007F80 |
393 | #define AR_PHY_AGC_COARSE_LOW_S 7 | 395 | #define AR_PHY_AGC_COARSE_LOW_S 7 |
394 | #define AR_PHY_AGC_COARSE_HIGH 0x003F8000 | 396 | #define AR_PHY_AGC_COARSE_HIGH 0x003F8000 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 9c51b395b4ff..259a6f312afb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -43,16 +43,16 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | 44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, |
45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | 45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, |
46 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | 46 | {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x5ac640de}, |
47 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | 47 | {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x0796be89}, |
48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | 48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, |
49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | 49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, |
50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, | 50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, |
51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, | 51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, |
52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | 52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, |
53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | 53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, |
54 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, | 54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x92c84d2e}, |
55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3039605e, 0x33795d5e}, | 55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, |
56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
@@ -688,8 +688,8 @@ static const u32 ar9462_2p0_mac_postamble_emulation[][5] = { | |||
688 | static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { | 688 | static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { |
689 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 689 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
690 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, | 690 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, |
691 | {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 691 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
692 | {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 692 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
693 | }; | 693 | }; |
694 | 694 | ||
695 | static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { | 695 | static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { |
@@ -717,8 +717,8 @@ static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { | |||
717 | static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { | 717 | static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { |
718 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 718 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
719 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, | 719 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, |
720 | {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 720 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
721 | {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 721 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
722 | }; | 722 | }; |
723 | 723 | ||
724 | static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { | 724 | static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { |
@@ -1059,7 +1059,7 @@ static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { | |||
1059 | 1059 | ||
1060 | static const u32 ar9462_2p0_soc_postamble[][5] = { | 1060 | static const u32 ar9462_2p0_soc_postamble[][5] = { |
1061 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1061 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1062 | {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, | 1062 | {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, |
1063 | }; | 1063 | }; |
1064 | 1064 | ||
1065 | static const u32 ar9462_2p0_baseband_core[][2] = { | 1065 | static const u32 ar9462_2p0_baseband_core[][2] = { |
@@ -1257,8 +1257,8 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { | |||
1257 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | 1257 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
1258 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | 1258 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
1259 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | 1259 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
1260 | {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, | 1260 | {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, |
1261 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | 1261 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, |
1262 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | 1262 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
1263 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | 1263 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
1264 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | 1264 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
@@ -1850,8 +1850,8 @@ static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = { | |||
1850 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | 1850 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
1851 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | 1851 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
1852 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | 1852 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
1853 | {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, | 1853 | {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, |
1854 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | 1854 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, |
1855 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | 1855 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
1856 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | 1856 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
1857 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | 1857 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 1c269f50822b..93b45b4b3033 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "common.h" | 27 | #include "common.h" |
28 | #include "mci.h" | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Header for the ath9k.ko driver core *only* -- hw code nor any other driver | 31 | * Header for the ath9k.ko driver core *only* -- hw code nor any other driver |
@@ -252,6 +253,7 @@ struct ath_node { | |||
252 | #ifdef CONFIG_ATH9K_DEBUGFS | 253 | #ifdef CONFIG_ATH9K_DEBUGFS |
253 | struct list_head list; /* for sc->nodes */ | 254 | struct list_head list; /* for sc->nodes */ |
254 | struct ieee80211_sta *sta; /* station struct we're part of */ | 255 | struct ieee80211_sta *sta; /* station struct we're part of */ |
256 | struct ieee80211_vif *vif; /* interface with which we're associated */ | ||
255 | #endif | 257 | #endif |
256 | struct ath_atx_tid tid[WME_NUM_TID]; | 258 | struct ath_atx_tid tid[WME_NUM_TID]; |
257 | struct ath_atx_ac ac[WME_NUM_AC]; | 259 | struct ath_atx_ac ac[WME_NUM_AC]; |
@@ -443,7 +445,9 @@ struct ath_btcoex { | |||
443 | u32 btcoex_no_stomp; /* in usec */ | 445 | u32 btcoex_no_stomp; /* in usec */ |
444 | u32 btcoex_period; /* in usec */ | 446 | u32 btcoex_period; /* in usec */ |
445 | u32 btscan_no_stomp; /* in usec */ | 447 | u32 btscan_no_stomp; /* in usec */ |
448 | u32 duty_cycle; | ||
446 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 449 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
450 | struct ath_mci_profile mci; | ||
447 | }; | 451 | }; |
448 | 452 | ||
449 | int ath_init_btcoex_timer(struct ath_softc *sc); | 453 | int ath_init_btcoex_timer(struct ath_softc *sc); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 2741203e803f..6fb719d85b37 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -709,24 +709,29 @@ static ssize_t read_file_stations(struct file *file, char __user *user_buf, | |||
709 | 709 | ||
710 | len += snprintf(buf + len, size - len, | 710 | len += snprintf(buf + len, size - len, |
711 | "Stations:\n" | 711 | "Stations:\n" |
712 | " tid: addr sched paused buf_q-empty an ac\n" | 712 | " tid: addr sched paused buf_q-empty an ac baw\n" |
713 | " ac: addr sched tid_q-empty txq\n"); | 713 | " ac: addr sched tid_q-empty txq\n"); |
714 | 714 | ||
715 | spin_lock(&sc->nodes_lock); | 715 | spin_lock(&sc->nodes_lock); |
716 | list_for_each_entry(an, &sc->nodes, list) { | 716 | list_for_each_entry(an, &sc->nodes, list) { |
717 | unsigned short ma = an->maxampdu; | ||
718 | if (ma == 0) | ||
719 | ma = 65535; /* see ath_lookup_rate */ | ||
717 | len += snprintf(buf + len, size - len, | 720 | len += snprintf(buf + len, size - len, |
718 | "%pM\n", an->sta->addr); | 721 | "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n", |
722 | an->vif->addr, an->sta->addr, ma, | ||
723 | (unsigned int)(an->mpdudensity)); | ||
719 | if (len >= size) | 724 | if (len >= size) |
720 | goto done; | 725 | goto done; |
721 | 726 | ||
722 | for (q = 0; q < WME_NUM_TID; q++) { | 727 | for (q = 0; q < WME_NUM_TID; q++) { |
723 | struct ath_atx_tid *tid = &(an->tid[q]); | 728 | struct ath_atx_tid *tid = &(an->tid[q]); |
724 | len += snprintf(buf + len, size - len, | 729 | len += snprintf(buf + len, size - len, |
725 | " tid: %p %s %s %i %p %p\n", | 730 | " tid: %p %s %s %i %p %p %hu\n", |
726 | tid, tid->sched ? "sched" : "idle", | 731 | tid, tid->sched ? "sched" : "idle", |
727 | tid->paused ? "paused" : "running", | 732 | tid->paused ? "paused" : "running", |
728 | skb_queue_empty(&tid->buf_q), | 733 | skb_queue_empty(&tid->buf_q), |
729 | tid->an, tid->ac); | 734 | tid->an, tid->ac, tid->baw_size); |
730 | if (len >= size) | 735 | if (len >= size) |
731 | goto done; | 736 | goto done; |
732 | } | 737 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 49abd34be741..5ff7ab965120 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -249,7 +249,8 @@ enum eeprom_param { | |||
249 | EEP_ANT_DIV_CTL1, | 249 | EEP_ANT_DIV_CTL1, |
250 | EEP_CHAIN_MASK_REDUCE, | 250 | EEP_CHAIN_MASK_REDUCE, |
251 | EEP_ANTENNA_GAIN_2G, | 251 | EEP_ANTENNA_GAIN_2G, |
252 | EEP_ANTENNA_GAIN_5G | 252 | EEP_ANTENNA_GAIN_5G, |
253 | EEP_QUICK_DROP | ||
253 | }; | 254 | }; |
254 | 255 | ||
255 | enum ar5416_rates { | 256 | enum ar5416_rates { |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 655576c8fdab..2c279dcaf4ba 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -189,8 +189,8 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
189 | bool is_btscan; | 189 | bool is_btscan; |
190 | 190 | ||
191 | ath9k_ps_wakeup(sc); | 191 | ath9k_ps_wakeup(sc); |
192 | ath_detect_bt_priority(sc); | 192 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
193 | 193 | ath_detect_bt_priority(sc); | |
194 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 194 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
195 | 195 | ||
196 | spin_lock_bh(&btcoex->btcoex_lock); | 196 | spin_lock_bh(&btcoex->btcoex_lock); |
@@ -212,8 +212,9 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
212 | } | 212 | } |
213 | 213 | ||
214 | ath9k_ps_restore(sc); | 214 | ath9k_ps_restore(sc); |
215 | timer_period = btcoex->btcoex_period / 1000; | ||
215 | mod_timer(&btcoex->period_timer, jiffies + | 216 | mod_timer(&btcoex->period_timer, jiffies + |
216 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | 217 | msecs_to_jiffies(timer_period)); |
217 | } | 218 | } |
218 | 219 | ||
219 | /* | 220 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2f91acccb7db..662ab7e9a0f0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2335,7 +2335,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2335 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | 2335 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; |
2336 | } | 2336 | } |
2337 | if (AR_SREV_9462(ah)) | 2337 | if (AR_SREV_9462(ah)) |
2338 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | 2338 | pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; |
2339 | 2339 | ||
2340 | return 0; | 2340 | return 0; |
2341 | } | 2341 | } |
@@ -2583,7 +2583,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) | |||
2583 | struct ath9k_channel *chan = ah->curchan; | 2583 | struct ath9k_channel *chan = ah->curchan; |
2584 | struct ieee80211_channel *channel = chan->chan; | 2584 | struct ieee80211_channel *channel = chan->chan; |
2585 | 2585 | ||
2586 | reg->power_limit = min_t(int, limit, MAX_RATE_POWER); | 2586 | reg->power_limit = min_t(u32, limit, MAX_RATE_POWER); |
2587 | if (test) | 2587 | if (test) |
2588 | channel->max_power = MAX_RATE_POWER / 2; | 2588 | channel->max_power = MAX_RATE_POWER / 2; |
2589 | 2589 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f389b3c93cf3..33e8f2f9d425 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -203,6 +203,7 @@ enum ath9k_hw_caps { | |||
203 | ATH9K_HW_CAP_5GHZ = BIT(14), | 203 | ATH9K_HW_CAP_5GHZ = BIT(14), |
204 | ATH9K_HW_CAP_APM = BIT(15), | 204 | ATH9K_HW_CAP_APM = BIT(15), |
205 | ATH9K_HW_CAP_RTT = BIT(16), | 205 | ATH9K_HW_CAP_RTT = BIT(16), |
206 | ATH9K_HW_CAP_MCI = BIT(17), | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | struct ath9k_hw_capabilities { | 209 | struct ath9k_hw_capabilities { |
@@ -419,6 +420,16 @@ enum ath9k_rx_qtype { | |||
419 | ATH9K_RX_QUEUE_MAX, | 420 | ATH9K_RX_QUEUE_MAX, |
420 | }; | 421 | }; |
421 | 422 | ||
423 | enum ath_mci_gpm_coex_profile_type { | ||
424 | MCI_GPM_COEX_PROFILE_UNKNOWN, | ||
425 | MCI_GPM_COEX_PROFILE_RFCOMM, | ||
426 | MCI_GPM_COEX_PROFILE_A2DP, | ||
427 | MCI_GPM_COEX_PROFILE_HID, | ||
428 | MCI_GPM_COEX_PROFILE_BNEP, | ||
429 | MCI_GPM_COEX_PROFILE_VOICE, | ||
430 | MCI_GPM_COEX_PROFILE_MAX | ||
431 | }; | ||
432 | |||
422 | struct ath9k_beacon_state { | 433 | struct ath9k_beacon_state { |
423 | u32 bs_nexttbtt; | 434 | u32 bs_nexttbtt; |
424 | u32 bs_nextdtim; | 435 | u32 bs_nextdtim; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d4c909f8e474..e046de94836a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -424,6 +424,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc) | |||
424 | txq = sc->tx.txq_map[WME_AC_BE]; | 424 | txq = sc->tx.txq_map[WME_AC_BE]; |
425 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); | 425 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
426 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 426 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
427 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
428 | INIT_LIST_HEAD(&sc->btcoex.mci.info); | ||
427 | break; | 429 | break; |
428 | default: | 430 | default: |
429 | WARN_ON(1); | 431 | WARN_ON(1); |
@@ -695,6 +697,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
695 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 697 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
696 | 698 | ||
697 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 699 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
700 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | ||
698 | 701 | ||
699 | hw->queues = 4; | 702 | hw->queues = 4; |
700 | hw->max_rates = 4; | 703 | hw->max_rates = 4; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93fbe6f40898..e43c41cff25b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -630,7 +630,8 @@ set_timer: | |||
630 | } | 630 | } |
631 | } | 631 | } |
632 | 632 | ||
633 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 633 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, |
634 | struct ieee80211_vif *vif) | ||
634 | { | 635 | { |
635 | struct ath_node *an; | 636 | struct ath_node *an; |
636 | an = (struct ath_node *)sta->drv_priv; | 637 | an = (struct ath_node *)sta->drv_priv; |
@@ -640,6 +641,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
640 | list_add(&an->list, &sc->nodes); | 641 | list_add(&an->list, &sc->nodes); |
641 | spin_unlock(&sc->nodes_lock); | 642 | spin_unlock(&sc->nodes_lock); |
642 | an->sta = sta; | 643 | an->sta = sta; |
644 | an->vif = vif; | ||
643 | #endif | 645 | #endif |
644 | if (sc->sc_flags & SC_OP_TXAGGR) { | 646 | if (sc->sc_flags & SC_OP_TXAGGR) { |
645 | ath_tx_node_init(sc, an); | 647 | ath_tx_node_init(sc, an); |
@@ -1133,8 +1135,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1133 | 1135 | ||
1134 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && | 1136 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && |
1135 | !ah->btcoex_hw.enabled) { | 1137 | !ah->btcoex_hw.enabled) { |
1136 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 1138 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
1137 | AR_STOMP_LOW_WLAN_WGHT); | 1139 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1140 | AR_STOMP_LOW_WLAN_WGHT); | ||
1138 | ath9k_hw_btcoex_enable(ah); | 1141 | ath9k_hw_btcoex_enable(ah); |
1139 | 1142 | ||
1140 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1143 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
@@ -1237,6 +1240,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1237 | ath9k_hw_btcoex_disable(ah); | 1240 | ath9k_hw_btcoex_disable(ah); |
1238 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1241 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1239 | ath9k_btcoex_timer_pause(sc); | 1242 | ath9k_btcoex_timer_pause(sc); |
1243 | ath_mci_flush_profile(&sc->btcoex.mci); | ||
1240 | } | 1244 | } |
1241 | 1245 | ||
1242 | spin_lock_bh(&sc->sc_pcu_lock); | 1246 | spin_lock_bh(&sc->sc_pcu_lock); |
@@ -1798,7 +1802,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1798 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | 1802 | struct ath_node *an = (struct ath_node *) sta->drv_priv; |
1799 | struct ieee80211_key_conf ps_key = { }; | 1803 | struct ieee80211_key_conf ps_key = { }; |
1800 | 1804 | ||
1801 | ath_node_attach(sc, sta); | 1805 | ath_node_attach(sc, sta, vif); |
1802 | 1806 | ||
1803 | if (vif->type != NL80211_IFTYPE_AP && | 1807 | if (vif->type != NL80211_IFTYPE_AP && |
1804 | vif->type != NL80211_IFTYPE_AP_VLAN) | 1808 | vif->type != NL80211_IFTYPE_AP_VLAN) |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c new file mode 100644 index 000000000000..0fbb141bc302 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | #include "mci.h" | ||
19 | |||
20 | u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; | ||
21 | |||
22 | static struct ath_mci_profile_info* | ||
23 | ath_mci_find_profile(struct ath_mci_profile *mci, | ||
24 | struct ath_mci_profile_info *info) | ||
25 | { | ||
26 | struct ath_mci_profile_info *entry; | ||
27 | |||
28 | list_for_each_entry(entry, &mci->info, list) { | ||
29 | if (entry->conn_handle == info->conn_handle) | ||
30 | break; | ||
31 | } | ||
32 | return entry; | ||
33 | } | ||
34 | |||
35 | static bool ath_mci_add_profile(struct ath_common *common, | ||
36 | struct ath_mci_profile *mci, | ||
37 | struct ath_mci_profile_info *info) | ||
38 | { | ||
39 | struct ath_mci_profile_info *entry; | ||
40 | |||
41 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && | ||
42 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { | ||
43 | ath_dbg(common, ATH_DBG_MCI, | ||
44 | "Too many SCO profile, failed to add new profile\n"); | ||
45 | return false; | ||
46 | } | ||
47 | |||
48 | if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && | ||
49 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { | ||
50 | ath_dbg(common, ATH_DBG_MCI, | ||
51 | "Too many ACL profile, failed to add new profile\n"); | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | entry = ath_mci_find_profile(mci, info); | ||
56 | |||
57 | if (entry) | ||
58 | memcpy(entry, info, 10); | ||
59 | else { | ||
60 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
61 | if (!entry) | ||
62 | return false; | ||
63 | |||
64 | memcpy(entry, info, 10); | ||
65 | INC_PROF(mci, info); | ||
66 | list_add_tail(&info->list, &mci->info); | ||
67 | } | ||
68 | return true; | ||
69 | } | ||
70 | |||
71 | static void ath_mci_del_profile(struct ath_common *common, | ||
72 | struct ath_mci_profile *mci, | ||
73 | struct ath_mci_profile_info *info) | ||
74 | { | ||
75 | struct ath_mci_profile_info *entry; | ||
76 | |||
77 | entry = ath_mci_find_profile(mci, info); | ||
78 | |||
79 | if (!entry) { | ||
80 | ath_dbg(common, ATH_DBG_MCI, | ||
81 | "Profile to be deleted not found\n"); | ||
82 | return; | ||
83 | } | ||
84 | DEC_PROF(mci, entry); | ||
85 | list_del(&entry->list); | ||
86 | kfree(entry); | ||
87 | } | ||
88 | |||
89 | void ath_mci_flush_profile(struct ath_mci_profile *mci) | ||
90 | { | ||
91 | struct ath_mci_profile_info *info, *tinfo; | ||
92 | |||
93 | list_for_each_entry_safe(info, tinfo, &mci->info, list) { | ||
94 | list_del(&info->list); | ||
95 | DEC_PROF(mci, info); | ||
96 | kfree(info); | ||
97 | } | ||
98 | mci->aggr_limit = 0; | ||
99 | } | ||
100 | |||
101 | static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) | ||
102 | { | ||
103 | struct ath_mci_profile *mci = &btcoex->mci; | ||
104 | u32 wlan_airtime = btcoex->btcoex_period * | ||
105 | (100 - btcoex->duty_cycle) / 100; | ||
106 | |||
107 | /* | ||
108 | * Scale: wlan_airtime is in ms, aggr_limit is in 0.25 ms. | ||
109 | * When wlan_airtime is less than 4ms, aggregation limit has to be | ||
110 | * adjusted half of wlan_airtime to ensure that the aggregation can fit | ||
111 | * without collision with BT traffic. | ||
112 | */ | ||
113 | if ((wlan_airtime <= 4) && | ||
114 | (!mci->aggr_limit || (mci->aggr_limit > (2 * wlan_airtime)))) | ||
115 | mci->aggr_limit = 2 * wlan_airtime; | ||
116 | } | ||
117 | |||
118 | static void ath_mci_update_scheme(struct ath_softc *sc) | ||
119 | { | ||
120 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
121 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
122 | struct ath_mci_profile *mci = &btcoex->mci; | ||
123 | struct ath_mci_profile_info *info; | ||
124 | u32 num_profile = NUM_PROF(mci); | ||
125 | |||
126 | if (num_profile == 1) { | ||
127 | info = list_first_entry(&mci->info, | ||
128 | struct ath_mci_profile_info, | ||
129 | list); | ||
130 | if (mci->num_sco && info->T == 12) { | ||
131 | mci->aggr_limit = 8; | ||
132 | ath_dbg(common, ATH_DBG_MCI, | ||
133 | "Single SCO, aggregation limit 2 ms\n"); | ||
134 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && | ||
135 | !info->master) { | ||
136 | btcoex->btcoex_period = 60; | ||
137 | ath_dbg(common, ATH_DBG_MCI, | ||
138 | "Single slave PAN/FTP, bt period 60 ms\n"); | ||
139 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && | ||
140 | (info->T > 0 && info->T < 50) && | ||
141 | (info->A > 1 || info->W > 1)) { | ||
142 | btcoex->duty_cycle = 30; | ||
143 | mci->aggr_limit = 8; | ||
144 | ath_dbg(common, ATH_DBG_MCI, | ||
145 | "Multiple attempt/timeout single HID " | ||
146 | "aggregation limit 2 ms dutycycle 30%%\n"); | ||
147 | } | ||
148 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { | ||
149 | btcoex->duty_cycle = 30; | ||
150 | mci->aggr_limit = 8; | ||
151 | ath_dbg(common, ATH_DBG_MCI, | ||
152 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); | ||
153 | } else if (num_profile > 3) { | ||
154 | mci->aggr_limit = 6; | ||
155 | ath_dbg(common, ATH_DBG_MCI, | ||
156 | "Three or more profiles aggregation limit 1.5 ms\n"); | ||
157 | } | ||
158 | |||
159 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { | ||
160 | if (IS_CHAN_HT(sc->sc_ah->curchan)) | ||
161 | ath_mci_adjust_aggr_limit(btcoex); | ||
162 | else | ||
163 | btcoex->btcoex_period >>= 1; | ||
164 | } | ||
165 | |||
166 | ath9k_hw_btcoex_disable(sc->sc_ah); | ||
167 | ath9k_btcoex_timer_pause(sc); | ||
168 | |||
169 | if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) | ||
170 | return; | ||
171 | |||
172 | btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); | ||
173 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) | ||
174 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; | ||
175 | |||
176 | btcoex->btcoex_period *= 1000; | ||
177 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * | ||
178 | (100 - btcoex->duty_cycle) / 100; | ||
179 | |||
180 | ath9k_hw_btcoex_enable(sc->sc_ah); | ||
181 | ath9k_btcoex_timer_resume(sc); | ||
182 | } | ||
183 | |||
184 | void ath_mci_process_profile(struct ath_softc *sc, | ||
185 | struct ath_mci_profile_info *info) | ||
186 | { | ||
187 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
188 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
189 | struct ath_mci_profile *mci = &btcoex->mci; | ||
190 | |||
191 | if (info->start) { | ||
192 | if (!ath_mci_add_profile(common, mci, info)) | ||
193 | return; | ||
194 | } else | ||
195 | ath_mci_del_profile(common, mci, info); | ||
196 | |||
197 | btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; | ||
198 | mci->aggr_limit = mci->num_sco ? 6 : 0; | ||
199 | if (NUM_PROF(mci)) { | ||
200 | btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
201 | btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; | ||
202 | } else { | ||
203 | btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : | ||
204 | ATH_BTCOEX_STOMP_LOW; | ||
205 | btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
206 | } | ||
207 | |||
208 | ath_mci_update_scheme(sc); | ||
209 | } | ||
210 | |||
211 | void ath_mci_process_status(struct ath_softc *sc, | ||
212 | struct ath_mci_profile_status *status) | ||
213 | { | ||
214 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
215 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
216 | struct ath_mci_profile *mci = &btcoex->mci; | ||
217 | struct ath_mci_profile_info info; | ||
218 | int i = 0, old_num_mgmt = mci->num_mgmt; | ||
219 | |||
220 | /* Link status type are not handled */ | ||
221 | if (status->is_link) { | ||
222 | ath_dbg(common, ATH_DBG_MCI, | ||
223 | "Skip link type status update\n"); | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | memset(&info, 0, sizeof(struct ath_mci_profile_info)); | ||
228 | |||
229 | info.conn_handle = status->conn_handle; | ||
230 | if (ath_mci_find_profile(mci, &info)) { | ||
231 | ath_dbg(common, ATH_DBG_MCI, | ||
232 | "Skip non link state update for existing profile %d\n", | ||
233 | status->conn_handle); | ||
234 | return; | ||
235 | } | ||
236 | if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { | ||
237 | ath_dbg(common, ATH_DBG_MCI, | ||
238 | "Ignore too many non-link update\n"); | ||
239 | return; | ||
240 | } | ||
241 | if (status->is_critical) | ||
242 | __set_bit(status->conn_handle, mci->status); | ||
243 | else | ||
244 | __clear_bit(status->conn_handle, mci->status); | ||
245 | |||
246 | mci->num_mgmt = 0; | ||
247 | do { | ||
248 | if (test_bit(i, mci->status)) | ||
249 | mci->num_mgmt++; | ||
250 | } while (++i < ATH_MCI_MAX_PROFILE); | ||
251 | |||
252 | if (old_num_mgmt != mci->num_mgmt) | ||
253 | ath_mci_update_scheme(sc); | ||
254 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h new file mode 100644 index 000000000000..9590c61822d1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef MCI_H | ||
18 | #define MCI_H | ||
19 | |||
20 | #define ATH_MCI_DEF_BT_PERIOD 40 | ||
21 | #define ATH_MCI_BDR_DUTY_CYCLE 20 | ||
22 | #define ATH_MCI_MAX_DUTY_CYCLE 90 | ||
23 | |||
24 | #define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */ | ||
25 | #define ATH_MCI_MAX_ACL_PROFILE 7 | ||
26 | #define ATH_MCI_MAX_SCO_PROFILE 1 | ||
27 | #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ | ||
28 | ATH_MCI_MAX_SCO_PROFILE) | ||
29 | |||
30 | #define INC_PROF(_mci, _info) do { \ | ||
31 | switch (_info->type) { \ | ||
32 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ | ||
33 | _mci->num_other_acl++; \ | ||
34 | break; \ | ||
35 | case MCI_GPM_COEX_PROFILE_A2DP: \ | ||
36 | _mci->num_a2dp++; \ | ||
37 | if (!_info->edr) \ | ||
38 | _mci->num_bdr++; \ | ||
39 | break; \ | ||
40 | case MCI_GPM_COEX_PROFILE_HID: \ | ||
41 | _mci->num_hid++; \ | ||
42 | break; \ | ||
43 | case MCI_GPM_COEX_PROFILE_BNEP: \ | ||
44 | _mci->num_pan++; \ | ||
45 | break; \ | ||
46 | case MCI_GPM_COEX_PROFILE_VOICE: \ | ||
47 | _mci->num_sco++; \ | ||
48 | break; \ | ||
49 | default: \ | ||
50 | break; \ | ||
51 | } \ | ||
52 | } while (0) | ||
53 | |||
54 | #define DEC_PROF(_mci, _info) do { \ | ||
55 | switch (_info->type) { \ | ||
56 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ | ||
57 | _mci->num_other_acl--; \ | ||
58 | break; \ | ||
59 | case MCI_GPM_COEX_PROFILE_A2DP: \ | ||
60 | _mci->num_a2dp--; \ | ||
61 | if (!_info->edr) \ | ||
62 | _mci->num_bdr--; \ | ||
63 | break; \ | ||
64 | case MCI_GPM_COEX_PROFILE_HID: \ | ||
65 | _mci->num_hid--; \ | ||
66 | break; \ | ||
67 | case MCI_GPM_COEX_PROFILE_BNEP: \ | ||
68 | _mci->num_pan--; \ | ||
69 | break; \ | ||
70 | case MCI_GPM_COEX_PROFILE_VOICE: \ | ||
71 | _mci->num_sco--; \ | ||
72 | break; \ | ||
73 | default: \ | ||
74 | break; \ | ||
75 | } \ | ||
76 | } while (0) | ||
77 | |||
78 | #define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \ | ||
79 | _mci->num_hid + _mci->num_pan + _mci->num_sco) | ||
80 | |||
81 | struct ath_mci_profile_info { | ||
82 | u8 type; | ||
83 | u8 conn_handle; | ||
84 | bool start; | ||
85 | bool master; | ||
86 | bool edr; | ||
87 | u8 voice_type; | ||
88 | u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */ | ||
89 | u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */ | ||
90 | u8 A; /* HID: Sniff attempt, in slots */ | ||
91 | struct list_head list; | ||
92 | }; | ||
93 | |||
94 | struct ath_mci_profile_status { | ||
95 | bool is_critical; | ||
96 | bool is_link; | ||
97 | u8 conn_handle; | ||
98 | }; | ||
99 | |||
100 | struct ath_mci_profile { | ||
101 | struct list_head info; | ||
102 | DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE); | ||
103 | u16 aggr_limit; | ||
104 | u8 num_mgmt; | ||
105 | u8 num_sco; | ||
106 | u8 num_a2dp; | ||
107 | u8 num_hid; | ||
108 | u8 num_pan; | ||
109 | u8 num_other_acl; | ||
110 | u8 num_bdr; | ||
111 | }; | ||
112 | |||
113 | void ath_mci_flush_profile(struct ath_mci_profile *mci); | ||
114 | void ath_mci_process_profile(struct ath_softc *sc, | ||
115 | struct ath_mci_profile_info *info); | ||
116 | void ath_mci_process_status(struct ath_softc *sc, | ||
117 | struct ath_mci_profile_status *status); | ||
118 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 03b0a651a591..55d077e7135d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -601,6 +601,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
601 | struct sk_buff *skb; | 601 | struct sk_buff *skb; |
602 | struct ieee80211_tx_info *tx_info; | 602 | struct ieee80211_tx_info *tx_info; |
603 | struct ieee80211_tx_rate *rates; | 603 | struct ieee80211_tx_rate *rates; |
604 | struct ath_mci_profile *mci = &sc->btcoex.mci; | ||
604 | u32 max_4ms_framelen, frmlen; | 605 | u32 max_4ms_framelen, frmlen; |
605 | u16 aggr_limit, legacy = 0; | 606 | u16 aggr_limit, legacy = 0; |
606 | int i; | 607 | int i; |
@@ -645,7 +646,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
645 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) | 646 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) |
646 | return 0; | 647 | return 0; |
647 | 648 | ||
648 | if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | 649 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) |
650 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; | ||
651 | else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | ||
649 | aggr_limit = min((max_4ms_framelen * 3) / 8, | 652 | aggr_limit = min((max_4ms_framelen * 3) / 8, |
650 | (u32)ATH_AMPDU_LIMIT_MAX); | 653 | (u32)ATH_AMPDU_LIMIT_MAX); |
651 | else | 654 | else |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 85fa9cc73502..65ecb5bab25a 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -254,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
254 | int r; | 254 | int r; |
255 | 255 | ||
256 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; | 256 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; |
257 | if (!sband) | ||
258 | return; | ||
257 | 259 | ||
258 | /* | 260 | /* |
259 | * If no country IE has been received always enable active scan | 261 | * If no country IE has been received always enable active scan |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 58ea0e5fabfd..5f77cbe0b6aa 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | /* TODO: verify if needed for SSLPN or LCN */ | ||
178 | static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) | 179 | static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) |
179 | { | 180 | { |
180 | const struct b43_phy *phy = &dev->phy; | 181 | const struct b43_phy *phy = &dev->phy; |
@@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
256 | unsigned int plcp_fragment_len; | 257 | unsigned int plcp_fragment_len; |
257 | u32 mac_ctl = 0; | 258 | u32 mac_ctl = 0; |
258 | u16 phy_ctl = 0; | 259 | u16 phy_ctl = 0; |
260 | bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP || | ||
261 | phy->type == B43_PHYTYPE_N || | ||
262 | phy->type == B43_PHYTYPE_HT); | ||
259 | u8 extra_ft = 0; | 263 | u8 extra_ft = 0; |
260 | struct ieee80211_rate *txrate; | 264 | struct ieee80211_rate *txrate; |
261 | struct ieee80211_tx_rate *rates; | 265 | struct ieee80211_tx_rate *rates; |
@@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
531 | extra_ft |= B43_TXH_EFT_RTSFB_CCK; | 535 | extra_ft |= B43_TXH_EFT_RTSFB_CCK; |
532 | 536 | ||
533 | if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && | 537 | if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && |
534 | phy->type == B43_PHYTYPE_N) { | 538 | fill_phy_ctl1) { |
535 | txhdr->phy_ctl1_rts = cpu_to_le16( | 539 | txhdr->phy_ctl1_rts = cpu_to_le16( |
536 | b43_generate_tx_phy_ctl1(dev, rts_rate)); | 540 | b43_generate_tx_phy_ctl1(dev, rts_rate)); |
537 | txhdr->phy_ctl1_rts_fb = cpu_to_le16( | 541 | txhdr->phy_ctl1_rts_fb = cpu_to_le16( |
@@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
552 | break; | 556 | break; |
553 | } | 557 | } |
554 | 558 | ||
555 | if (phy->type == B43_PHYTYPE_N) { | 559 | if (fill_phy_ctl1) { |
556 | txhdr->phy_ctl1 = | 560 | txhdr->phy_ctl1 = |
557 | cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); | 561 | cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); |
558 | txhdr->phy_ctl1_fb = | 562 | txhdr->phy_ctl1_fb = |
@@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
736 | 740 | ||
737 | /* Link quality statistics */ | 741 | /* Link quality statistics */ |
738 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { | 742 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { |
743 | case B43_PHYTYPE_HT: | ||
744 | /* TODO: is max the right choice? */ | ||
745 | status.signal = max_t(__s8, | ||
746 | max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1), | ||
747 | rxhdr->phy_ht_power2); | ||
748 | break; | ||
739 | case B43_PHYTYPE_N: | 749 | case B43_PHYTYPE_N: |
750 | /* Broadcom has code for min and avg, but always uses max */ | ||
740 | if (rxhdr->power0 == 16 || rxhdr->power0 == 32) | 751 | if (rxhdr->power0 == 16 || rxhdr->power0 == 32) |
741 | status.signal = max(rxhdr->power1, rxhdr->power2); | 752 | status.signal = max(rxhdr->power1, rxhdr->power2); |
742 | else | 753 | else |
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 16c514d54afa..98d90747836a 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 { | |||
249 | } __packed; | 249 | } __packed; |
250 | } __packed; | 250 | } __packed; |
251 | union { | 251 | union { |
252 | /* HT-PHY */ | ||
253 | struct { | ||
254 | PAD_BYTES(1); | ||
255 | __s8 phy_ht_power0; | ||
256 | } __packed; | ||
257 | |||
252 | /* RSSI for N-PHYs */ | 258 | /* RSSI for N-PHYs */ |
253 | struct { | 259 | struct { |
254 | __s8 power2; | 260 | __s8 power2; |
@@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 { | |||
257 | 263 | ||
258 | __le16 phy_status2; /* PHY RX Status 2 */ | 264 | __le16 phy_status2; /* PHY RX Status 2 */ |
259 | } __packed; | 265 | } __packed; |
260 | __le16 phy_status3; /* PHY RX Status 3 */ | 266 | union { |
267 | /* HT-PHY */ | ||
268 | struct { | ||
269 | __s8 phy_ht_power1; | ||
270 | __s8 phy_ht_power2; | ||
271 | } __packed; | ||
272 | |||
273 | __le16 phy_status3; /* PHY RX Status 3 */ | ||
274 | } __packed; | ||
261 | union { | 275 | union { |
262 | /* Tested with 598.314, 644.1001 and 666.2 */ | 276 | /* Tested with 598.314, 644.1001 and 666.2 */ |
263 | struct { | 277 | struct { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index b44e3094588a..d58aa1b0a932 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -26,7 +26,8 @@ DHDOFILES = \ | |||
26 | dhd_sdio.o \ | 26 | dhd_sdio.o \ |
27 | dhd_linux.o \ | 27 | dhd_linux.o \ |
28 | bcmsdh.o \ | 28 | bcmsdh.o \ |
29 | bcmsdh_sdmmc.o | 29 | bcmsdh_sdmmc.o \ |
30 | sdio_chip.o | ||
30 | 31 | ||
31 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | 32 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o |
32 | brcmfmac-objs += $(DHDOFILES) | 33 | brcmfmac-objs += $(DHDOFILES) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h index d7d3afd5a10f..cecb5e5f412b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h | |||
@@ -18,13 +18,6 @@ | |||
18 | #define _bcmchip_h_ | 18 | #define _bcmchip_h_ |
19 | 19 | ||
20 | /* bcm4329 */ | 20 | /* bcm4329 */ |
21 | /* SDIO device core, ID 0x829 */ | ||
22 | #define BCM4329_CORE_BUS_BASE 0x18011000 | ||
23 | /* internal memory core, ID 0x80e */ | ||
24 | #define BCM4329_CORE_SOCRAM_BASE 0x18003000 | ||
25 | /* ARM Cortex M3 core, ID 0x82a */ | ||
26 | #define BCM4329_CORE_ARM_BASE 0x18002000 | ||
27 | #define BCM4329_RAMSIZE 0x48000 | ||
28 | /* firmware name */ | 21 | /* firmware name */ |
29 | #define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" | 22 | #define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" |
30 | #define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" | 23 | #define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 4645766b4070..6da519e7578f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -87,7 +87,7 @@ | |||
87 | #define TOE_TX_CSUM_OL 0x00000001 | 87 | #define TOE_TX_CSUM_OL 0x00000001 |
88 | #define TOE_RX_CSUM_OL 0x00000002 | 88 | #define TOE_RX_CSUM_OL 0x00000002 |
89 | 89 | ||
90 | #define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */ | 90 | #define BRCMF_BSS_INFO_VERSION 108 /* curr ver of brcmf_bss_info_le struct */ |
91 | 91 | ||
92 | /* size of brcmf_scan_params not including variable length array */ | 92 | /* size of brcmf_scan_params not including variable length array */ |
93 | #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 | 93 | #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 |
@@ -122,8 +122,6 @@ | |||
122 | 122 | ||
123 | /* For supporting multiple interfaces */ | 123 | /* For supporting multiple interfaces */ |
124 | #define BRCMF_MAX_IFS 16 | 124 | #define BRCMF_MAX_IFS 16 |
125 | #define BRCMF_DEL_IF -0xe | ||
126 | #define BRCMF_BAD_IF -0xf | ||
127 | 125 | ||
128 | #define DOT11_BSSTYPE_ANY 2 | 126 | #define DOT11_BSSTYPE_ANY 2 |
129 | #define DOT11_MAX_DEFAULT_KEYS 4 | 127 | #define DOT11_MAX_DEFAULT_KEYS 4 |
@@ -365,7 +363,7 @@ struct brcmf_pkt_filter_enable_le { | |||
365 | * Applications MUST CHECK ie_offset field and length field to access IEs and | 363 | * Applications MUST CHECK ie_offset field and length field to access IEs and |
366 | * next bss_info structure in a vector (in struct brcmf_scan_results) | 364 | * next bss_info structure in a vector (in struct brcmf_scan_results) |
367 | */ | 365 | */ |
368 | struct brcmf_bss_info { | 366 | struct brcmf_bss_info_le { |
369 | __le32 version; /* version field */ | 367 | __le32 version; /* version field */ |
370 | __le32 length; /* byte length of data in this record, | 368 | __le32 length; /* byte length of data in this record, |
371 | * starting at version and including IEs | 369 | * starting at version and including IEs |
@@ -466,14 +464,13 @@ struct brcmf_scan_results { | |||
466 | u32 buflen; | 464 | u32 buflen; |
467 | u32 version; | 465 | u32 version; |
468 | u32 count; | 466 | u32 count; |
469 | struct brcmf_bss_info bss_info[1]; | 467 | struct brcmf_bss_info_le bss_info_le[]; |
470 | }; | 468 | }; |
471 | 469 | ||
472 | struct brcmf_scan_results_le { | 470 | struct brcmf_scan_results_le { |
473 | __le32 buflen; | 471 | __le32 buflen; |
474 | __le32 version; | 472 | __le32 version; |
475 | __le32 count; | 473 | __le32 count; |
476 | struct brcmf_bss_info bss_info[1]; | ||
477 | }; | 474 | }; |
478 | 475 | ||
479 | /* used for association with a specific BSSID and chanspec list */ | 476 | /* used for association with a specific BSSID and chanspec list */ |
@@ -493,10 +490,6 @@ struct brcmf_join_params { | |||
493 | struct brcmf_assoc_params_le params_le; | 490 | struct brcmf_assoc_params_le params_le; |
494 | }; | 491 | }; |
495 | 492 | ||
496 | /* size of brcmf_scan_results not including variable length array */ | ||
497 | #define BRCMF_SCAN_RESULTS_FIXED_SIZE \ | ||
498 | (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info)) | ||
499 | |||
500 | /* incremental scan results struct */ | 493 | /* incremental scan results struct */ |
501 | struct brcmf_iscan_results { | 494 | struct brcmf_iscan_results { |
502 | union { | 495 | union { |
@@ -511,7 +504,7 @@ struct brcmf_iscan_results { | |||
511 | 504 | ||
512 | /* size of brcmf_iscan_results not including variable length array */ | 505 | /* size of brcmf_iscan_results not including variable length array */ |
513 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ | 506 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ |
514 | (BRCMF_SCAN_RESULTS_FIXED_SIZE + \ | 507 | (sizeof(struct brcmf_scan_results) + \ |
515 | offsetof(struct brcmf_iscan_results, results)) | 508 | offsetof(struct brcmf_iscan_results, results)) |
516 | 509 | ||
517 | struct brcmf_wsec_key { | 510 | struct brcmf_wsec_key { |
@@ -734,8 +727,7 @@ extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, | |||
734 | extern void brcmf_c_init(void); | 727 | extern void brcmf_c_init(void); |
735 | 728 | ||
736 | extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, | 729 | extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, |
737 | struct net_device *ndev, char *name, u8 *mac_addr, | 730 | char *name, u8 *mac_addr); |
738 | u32 flags, u8 bssidx); | ||
739 | extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); | 731 | extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); |
740 | 732 | ||
741 | /* Send packet to dongle via data channel */ | 733 | /* Send packet to dongle via data channel */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 891826197f96..40928e58b6a6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -488,10 +488,9 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |||
488 | 488 | ||
489 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | 489 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { |
490 | if (ifevent->action == BRCMF_E_IF_ADD) | 490 | if (ifevent->action == BRCMF_E_IF_ADD) |
491 | brcmf_add_if(drvr_priv, ifevent->ifidx, NULL, | 491 | brcmf_add_if(drvr_priv, ifevent->ifidx, |
492 | event->ifname, | 492 | event->ifname, |
493 | pvt_data->eth.h_dest, | 493 | pvt_data->eth.h_dest); |
494 | ifevent->flags, ifevent->bssidx); | ||
495 | else | 494 | else |
496 | brcmf_del_if(drvr_priv, ifevent->ifidx); | 495 | brcmf_del_if(drvr_priv, ifevent->ifidx); |
497 | } else { | 496 | } else { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 4acbac5a74c6..719fd9397eb6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -58,7 +58,6 @@ struct brcmf_if { | |||
58 | struct net_device *ndev; | 58 | struct net_device *ndev; |
59 | struct net_device_stats stats; | 59 | struct net_device_stats stats; |
60 | int idx; /* iface idx in dongle */ | 60 | int idx; /* iface idx in dongle */ |
61 | int state; /* interface state */ | ||
62 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ | 61 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ |
63 | }; | 62 | }; |
64 | 63 | ||
@@ -80,20 +79,6 @@ struct brcmf_info { | |||
80 | /* Error bits */ | 79 | /* Error bits */ |
81 | module_param(brcmf_msg_level, int, 0); | 80 | module_param(brcmf_msg_level, int, 0); |
82 | 81 | ||
83 | |||
84 | static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev) | ||
85 | { | ||
86 | int i = 0; | ||
87 | |||
88 | while (i < BRCMF_MAX_IFS) { | ||
89 | if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev) | ||
90 | return i; | ||
91 | i++; | ||
92 | } | ||
93 | |||
94 | return BRCMF_BAD_IF; | ||
95 | } | ||
96 | |||
97 | int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | 82 | int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) |
98 | { | 83 | { |
99 | int i = BRCMF_MAX_IFS; | 84 | int i = BRCMF_MAX_IFS; |
@@ -285,14 +270,9 @@ _brcmf_set_mac_address(struct work_struct *work) | |||
285 | 270 | ||
286 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | 271 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) |
287 | { | 272 | { |
288 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 273 | struct brcmf_if *ifp = netdev_priv(ndev); |
289 | netdev_priv(ndev); | 274 | struct brcmf_info *drvr_priv = ifp->info; |
290 | struct sockaddr *sa = (struct sockaddr *)addr; | 275 | struct sockaddr *sa = (struct sockaddr *)addr; |
291 | int ifidx; | ||
292 | |||
293 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
294 | if (ifidx == BRCMF_BAD_IF) | ||
295 | return -1; | ||
296 | 276 | ||
297 | memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); | 277 | memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); |
298 | schedule_work(&drvr_priv->setmacaddr_work); | 278 | schedule_work(&drvr_priv->setmacaddr_work); |
@@ -301,13 +281,8 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | |||
301 | 281 | ||
302 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | 282 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) |
303 | { | 283 | { |
304 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 284 | struct brcmf_if *ifp = netdev_priv(ndev); |
305 | netdev_priv(ndev); | 285 | struct brcmf_info *drvr_priv = ifp->info; |
306 | int ifidx; | ||
307 | |||
308 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
309 | if (ifidx == BRCMF_BAD_IF) | ||
310 | return; | ||
311 | 286 | ||
312 | schedule_work(&drvr_priv->multicast_work); | 287 | schedule_work(&drvr_priv->multicast_work); |
313 | } | 288 | } |
@@ -341,9 +316,8 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) | |||
341 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 316 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
342 | { | 317 | { |
343 | int ret; | 318 | int ret; |
344 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 319 | struct brcmf_if *ifp = netdev_priv(ndev); |
345 | netdev_priv(ndev); | 320 | struct brcmf_info *drvr_priv = ifp->info; |
346 | int ifidx; | ||
347 | 321 | ||
348 | brcmf_dbg(TRACE, "Enter\n"); | 322 | brcmf_dbg(TRACE, "Enter\n"); |
349 | 323 | ||
@@ -355,9 +329,8 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
355 | return -ENODEV; | 329 | return -ENODEV; |
356 | } | 330 | } |
357 | 331 | ||
358 | ifidx = brcmf_net2idx(drvr_priv, ndev); | 332 | if (!drvr_priv->iflist[ifp->idx]) { |
359 | if (ifidx == BRCMF_BAD_IF) { | 333 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); |
360 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx); | ||
361 | netif_stop_queue(ndev); | 334 | netif_stop_queue(ndev); |
362 | return -ENODEV; | 335 | return -ENODEV; |
363 | } | 336 | } |
@@ -367,20 +340,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
367 | struct sk_buff *skb2; | 340 | struct sk_buff *skb2; |
368 | 341 | ||
369 | brcmf_dbg(INFO, "%s: insufficient headroom\n", | 342 | brcmf_dbg(INFO, "%s: insufficient headroom\n", |
370 | brcmf_ifname(&drvr_priv->pub, ifidx)); | 343 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); |
371 | drvr_priv->pub.tx_realloc++; | 344 | drvr_priv->pub.tx_realloc++; |
372 | skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); | 345 | skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); |
373 | dev_kfree_skb(skb); | 346 | dev_kfree_skb(skb); |
374 | skb = skb2; | 347 | skb = skb2; |
375 | if (skb == NULL) { | 348 | if (skb == NULL) { |
376 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", | 349 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", |
377 | brcmf_ifname(&drvr_priv->pub, ifidx)); | 350 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); |
378 | ret = -ENOMEM; | 351 | ret = -ENOMEM; |
379 | goto done; | 352 | goto done; |
380 | } | 353 | } |
381 | } | 354 | } |
382 | 355 | ||
383 | ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); | 356 | ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb); |
384 | 357 | ||
385 | done: | 358 | done: |
386 | if (ret) | 359 | if (ret) |
@@ -482,12 +455,10 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, | |||
482 | skb_mac_header(skb), | 455 | skb_mac_header(skb), |
483 | &event, &data); | 456 | &event, &data); |
484 | 457 | ||
485 | if (drvr_priv->iflist[ifidx] && | 458 | if (drvr_priv->iflist[ifidx]) { |
486 | !drvr_priv->iflist[ifidx]->state) | ||
487 | ifp = drvr_priv->iflist[ifidx]; | 459 | ifp = drvr_priv->iflist[ifidx]; |
488 | |||
489 | if (ifp->ndev) | ||
490 | ifp->ndev->last_rx = jiffies; | 460 | ifp->ndev->last_rx = jiffies; |
461 | } | ||
491 | 462 | ||
492 | drvr->dstats.rx_bytes += skb->len; | 463 | drvr->dstats.rx_bytes += skb->len; |
493 | drvr->rx_packets++; /* Local count */ | 464 | drvr->rx_packets++; /* Local count */ |
@@ -524,19 +495,11 @@ void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) | |||
524 | 495 | ||
525 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 496 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) |
526 | { | 497 | { |
527 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 498 | struct brcmf_if *ifp = netdev_priv(ndev); |
528 | netdev_priv(ndev); | 499 | struct brcmf_info *drvr_priv = ifp->info; |
529 | struct brcmf_if *ifp; | ||
530 | int ifidx; | ||
531 | 500 | ||
532 | brcmf_dbg(TRACE, "Enter\n"); | 501 | brcmf_dbg(TRACE, "Enter\n"); |
533 | 502 | ||
534 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
535 | if (ifidx == BRCMF_BAD_IF) | ||
536 | return NULL; | ||
537 | |||
538 | ifp = drvr_priv->iflist[ifidx]; | ||
539 | |||
540 | if (drvr_priv->pub.up) | 503 | if (drvr_priv->pub.up) |
541 | /* Use the protocol to get dongle stats */ | 504 | /* Use the protocol to get dongle stats */ |
542 | brcmf_proto_dstats(&drvr_priv->pub); | 505 | brcmf_proto_dstats(&drvr_priv->pub); |
@@ -637,8 +600,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | |||
637 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, | 600 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, |
638 | struct ethtool_drvinfo *info) | 601 | struct ethtool_drvinfo *info) |
639 | { | 602 | { |
640 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 603 | struct brcmf_if *ifp = netdev_priv(ndev); |
641 | netdev_priv(ndev); | 604 | struct brcmf_info *drvr_priv = ifp->info; |
642 | 605 | ||
643 | sprintf(info->driver, KBUILD_MODNAME); | 606 | sprintf(info->driver, KBUILD_MODNAME); |
644 | sprintf(info->version, "%lu", drvr_priv->pub.drv_version); | 607 | sprintf(info->version, "%lu", drvr_priv->pub.drv_version); |
@@ -765,14 +728,12 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
765 | static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, | 728 | static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, |
766 | int cmd) | 729 | int cmd) |
767 | { | 730 | { |
768 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 731 | struct brcmf_if *ifp = netdev_priv(ndev); |
769 | netdev_priv(ndev); | 732 | struct brcmf_info *drvr_priv = ifp->info; |
770 | int ifidx; | ||
771 | 733 | ||
772 | ifidx = brcmf_net2idx(drvr_priv, ndev); | 734 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); |
773 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd); | ||
774 | 735 | ||
775 | if (ifidx == BRCMF_BAD_IF) | 736 | if (!drvr_priv->iflist[ifp->idx]) |
776 | return -1; | 737 | return -1; |
777 | 738 | ||
778 | if (cmd == SIOCETHTOOL) | 739 | if (cmd == SIOCETHTOOL) |
@@ -788,17 +749,14 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
788 | s32 err = 0; | 749 | s32 err = 0; |
789 | int buflen = 0; | 750 | int buflen = 0; |
790 | bool is_set_key_cmd; | 751 | bool is_set_key_cmd; |
791 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 752 | struct brcmf_if *ifp = netdev_priv(ndev); |
792 | netdev_priv(ndev); | 753 | struct brcmf_info *drvr_priv = ifp->info; |
793 | int ifidx; | ||
794 | 754 | ||
795 | memset(&dcmd, 0, sizeof(dcmd)); | 755 | memset(&dcmd, 0, sizeof(dcmd)); |
796 | dcmd.cmd = cmd; | 756 | dcmd.cmd = cmd; |
797 | dcmd.buf = arg; | 757 | dcmd.buf = arg; |
798 | dcmd.len = len; | 758 | dcmd.len = len; |
799 | 759 | ||
800 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
801 | |||
802 | if (dcmd.buf != NULL) | 760 | if (dcmd.buf != NULL) |
803 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); | 761 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); |
804 | 762 | ||
@@ -826,7 +784,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
826 | if (is_set_key_cmd) | 784 | if (is_set_key_cmd) |
827 | brcmf_netdev_wait_pend8021x(ndev); | 785 | brcmf_netdev_wait_pend8021x(ndev); |
828 | 786 | ||
829 | err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen); | 787 | err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen); |
830 | 788 | ||
831 | done: | 789 | done: |
832 | if (err > 0) | 790 | if (err > 0) |
@@ -837,7 +795,8 @@ done: | |||
837 | 795 | ||
838 | static int brcmf_netdev_stop(struct net_device *ndev) | 796 | static int brcmf_netdev_stop(struct net_device *ndev) |
839 | { | 797 | { |
840 | struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev); | 798 | struct brcmf_if *ifp = netdev_priv(ndev); |
799 | struct brcmf_pub *drvr = &ifp->info->pub; | ||
841 | 800 | ||
842 | brcmf_dbg(TRACE, "Enter\n"); | 801 | brcmf_dbg(TRACE, "Enter\n"); |
843 | brcmf_cfg80211_down(drvr->config); | 802 | brcmf_cfg80211_down(drvr->config); |
@@ -853,16 +812,14 @@ static int brcmf_netdev_stop(struct net_device *ndev) | |||
853 | 812 | ||
854 | static int brcmf_netdev_open(struct net_device *ndev) | 813 | static int brcmf_netdev_open(struct net_device *ndev) |
855 | { | 814 | { |
856 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 815 | struct brcmf_if *ifp = netdev_priv(ndev); |
857 | netdev_priv(ndev); | 816 | struct brcmf_info *drvr_priv = ifp->info; |
858 | u32 toe_ol; | 817 | u32 toe_ol; |
859 | int ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
860 | s32 ret = 0; | 818 | s32 ret = 0; |
861 | 819 | ||
862 | brcmf_dbg(TRACE, "ifidx %d\n", ifidx); | 820 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); |
863 | |||
864 | if (ifidx == 0) { /* do it only for primary eth0 */ | ||
865 | 821 | ||
822 | if (ifp->idx == 0) { /* do it only for primary eth0 */ | ||
866 | /* try to bring up bus */ | 823 | /* try to bring up bus */ |
867 | ret = brcmf_bus_start(&drvr_priv->pub); | 824 | ret = brcmf_bus_start(&drvr_priv->pub); |
868 | if (ret != 0) { | 825 | if (ret != 0) { |
@@ -874,12 +831,12 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
874 | memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); | 831 | memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); |
875 | 832 | ||
876 | /* Get current TOE mode from dongle */ | 833 | /* Get current TOE mode from dongle */ |
877 | if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 | 834 | if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0 |
878 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 835 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
879 | drvr_priv->iflist[ifidx]->ndev->features |= | 836 | drvr_priv->iflist[ifp->idx]->ndev->features |= |
880 | NETIF_F_IP_CSUM; | 837 | NETIF_F_IP_CSUM; |
881 | else | 838 | else |
882 | drvr_priv->iflist[ifidx]->ndev->features &= | 839 | drvr_priv->iflist[ifp->idx]->ndev->features &= |
883 | ~NETIF_F_IP_CSUM; | 840 | ~NETIF_F_IP_CSUM; |
884 | } | 841 | } |
885 | /* Allow transmit calls */ | 842 | /* Allow transmit calls */ |
@@ -893,75 +850,62 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
893 | return ret; | 850 | return ret; |
894 | } | 851 | } |
895 | 852 | ||
853 | static const struct net_device_ops brcmf_netdev_ops_pri = { | ||
854 | .ndo_open = brcmf_netdev_open, | ||
855 | .ndo_stop = brcmf_netdev_stop, | ||
856 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
857 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
858 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
859 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
860 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
861 | }; | ||
862 | |||
896 | int | 863 | int |
897 | brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev, | 864 | brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) |
898 | char *name, u8 *mac_addr, u32 flags, u8 bssidx) | ||
899 | { | 865 | { |
900 | struct brcmf_if *ifp; | 866 | struct brcmf_if *ifp; |
901 | int ret = 0, err = 0; | 867 | struct net_device *ndev; |
902 | 868 | ||
903 | brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev); | 869 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
904 | 870 | ||
905 | ifp = drvr_priv->iflist[ifidx]; | 871 | ifp = drvr_priv->iflist[ifidx]; |
906 | if (!ifp) { | 872 | /* |
907 | ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); | 873 | * Delete the existing interface before overwriting it |
908 | if (!ifp) | 874 | * in case we missed the BRCMF_E_IF_DEL event. |
909 | return -ENOMEM; | 875 | */ |
876 | if (ifp) { | ||
877 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | ||
878 | ifp->ndev->name); | ||
879 | netif_stop_queue(ifp->ndev); | ||
880 | unregister_netdev(ifp->ndev); | ||
881 | free_netdev(ifp->ndev); | ||
882 | drvr_priv->iflist[ifidx] = NULL; | ||
883 | } | ||
884 | |||
885 | /* Allocate netdev, including space for private structure */ | ||
886 | ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); | ||
887 | if (!ndev) { | ||
888 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
889 | return -ENOMEM; | ||
910 | } | 890 | } |
911 | 891 | ||
912 | memset(ifp, 0, sizeof(struct brcmf_if)); | 892 | ifp = netdev_priv(ndev); |
893 | ifp->ndev = ndev; | ||
913 | ifp->info = drvr_priv; | 894 | ifp->info = drvr_priv; |
914 | drvr_priv->iflist[ifidx] = ifp; | 895 | drvr_priv->iflist[ifidx] = ifp; |
896 | ifp->idx = ifidx; | ||
915 | if (mac_addr != NULL) | 897 | if (mac_addr != NULL) |
916 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | 898 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); |
917 | 899 | ||
918 | if (ndev == NULL) { | 900 | if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) { |
919 | ifp->state = BRCMF_E_IF_ADD; | 901 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); |
920 | ifp->idx = ifidx; | 902 | free_netdev(ifp->ndev); |
921 | /* | 903 | drvr_priv->iflist[ifidx] = NULL; |
922 | * Delete the existing interface before overwriting it | 904 | return -EOPNOTSUPP; |
923 | * in case we missed the BRCMF_E_IF_DEL event. | 905 | } |
924 | */ | ||
925 | if (ifp->ndev != NULL) { | ||
926 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | ||
927 | ifp->ndev->name); | ||
928 | netif_stop_queue(ifp->ndev); | ||
929 | unregister_netdev(ifp->ndev); | ||
930 | free_netdev(ifp->ndev); | ||
931 | } | ||
932 | |||
933 | /* Allocate netdev, including space for private structure */ | ||
934 | ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", | ||
935 | ether_setup); | ||
936 | if (!ifp->ndev) { | ||
937 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
938 | ret = -ENOMEM; | ||
939 | } | ||
940 | |||
941 | if (ret == 0) { | ||
942 | memcpy(netdev_priv(ifp->ndev), &drvr_priv, | ||
943 | sizeof(drvr_priv)); | ||
944 | err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); | ||
945 | if (err != 0) { | ||
946 | brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n", | ||
947 | err); | ||
948 | ret = -EOPNOTSUPP; | ||
949 | } else { | ||
950 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", | ||
951 | current->pid, ifp->ndev->name); | ||
952 | ifp->state = 0; | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (ret < 0) { | ||
957 | if (ifp->ndev) | ||
958 | free_netdev(ifp->ndev); | ||
959 | 906 | ||
960 | drvr_priv->iflist[ifp->idx] = NULL; | 907 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", |
961 | kfree(ifp); | 908 | current->pid, ifp->ndev->name); |
962 | } | ||
963 | } else | ||
964 | ifp->ndev = ndev; | ||
965 | 909 | ||
966 | return 0; | 910 | return 0; |
967 | } | 911 | } |
@@ -977,47 +921,36 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) | |||
977 | brcmf_dbg(ERROR, "Null interface\n"); | 921 | brcmf_dbg(ERROR, "Null interface\n"); |
978 | return; | 922 | return; |
979 | } | 923 | } |
924 | if (ifp->ndev) { | ||
925 | if (ifidx == 0) { | ||
926 | if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | ||
927 | rtnl_lock(); | ||
928 | brcmf_netdev_stop(ifp->ndev); | ||
929 | rtnl_unlock(); | ||
930 | } | ||
931 | } else { | ||
932 | netif_stop_queue(ifp->ndev); | ||
933 | } | ||
980 | 934 | ||
981 | ifp->state = BRCMF_E_IF_DEL; | ||
982 | ifp->idx = ifidx; | ||
983 | if (ifp->ndev != NULL) { | ||
984 | netif_stop_queue(ifp->ndev); | ||
985 | unregister_netdev(ifp->ndev); | 935 | unregister_netdev(ifp->ndev); |
986 | free_netdev(ifp->ndev); | ||
987 | drvr_priv->iflist[ifidx] = NULL; | 936 | drvr_priv->iflist[ifidx] = NULL; |
988 | kfree(ifp); | 937 | if (ifidx == 0) |
938 | brcmf_cfg80211_detach(drvr_priv->pub.config); | ||
939 | free_netdev(ifp->ndev); | ||
989 | } | 940 | } |
990 | } | 941 | } |
991 | 942 | ||
992 | struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) | 943 | struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) |
993 | { | 944 | { |
994 | struct brcmf_info *drvr_priv = NULL; | 945 | struct brcmf_info *drvr_priv = NULL; |
995 | struct net_device *ndev; | ||
996 | 946 | ||
997 | brcmf_dbg(TRACE, "Enter\n"); | 947 | brcmf_dbg(TRACE, "Enter\n"); |
998 | 948 | ||
999 | /* Allocate netdev, including space for private structure */ | ||
1000 | ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup); | ||
1001 | if (!ndev) { | ||
1002 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
1003 | goto fail; | ||
1004 | } | ||
1005 | |||
1006 | /* Allocate primary brcmf_info */ | 949 | /* Allocate primary brcmf_info */ |
1007 | drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); | 950 | drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); |
1008 | if (!drvr_priv) | 951 | if (!drvr_priv) |
1009 | goto fail; | 952 | goto fail; |
1010 | 953 | ||
1011 | /* | ||
1012 | * Save the brcmf_info into the priv | ||
1013 | */ | ||
1014 | memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); | ||
1015 | |||
1016 | if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) == | ||
1017 | BRCMF_BAD_IF) | ||
1018 | goto fail; | ||
1019 | |||
1020 | ndev->netdev_ops = NULL; | ||
1021 | mutex_init(&drvr_priv->proto_block); | 954 | mutex_init(&drvr_priv->proto_block); |
1022 | 955 | ||
1023 | /* Link to info module */ | 956 | /* Link to info module */ |
@@ -1033,29 +966,12 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) | |||
1033 | goto fail; | 966 | goto fail; |
1034 | } | 967 | } |
1035 | 968 | ||
1036 | /* Attach and link in the cfg80211 */ | ||
1037 | drvr_priv->pub.config = | ||
1038 | brcmf_cfg80211_attach(ndev, | ||
1039 | brcmf_bus_get_device(bus), | ||
1040 | &drvr_priv->pub); | ||
1041 | if (drvr_priv->pub.config == NULL) { | ||
1042 | brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); | ||
1043 | goto fail; | ||
1044 | } | ||
1045 | |||
1046 | INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); | 969 | INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); |
1047 | INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); | 970 | INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); |
1048 | 971 | ||
1049 | /* | ||
1050 | * Save the brcmf_info into the priv | ||
1051 | */ | ||
1052 | memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); | ||
1053 | |||
1054 | return &drvr_priv->pub; | 972 | return &drvr_priv->pub; |
1055 | 973 | ||
1056 | fail: | 974 | fail: |
1057 | if (ndev) | ||
1058 | free_netdev(ndev); | ||
1059 | if (drvr_priv) | 975 | if (drvr_priv) |
1060 | brcmf_detach(&drvr_priv->pub); | 976 | brcmf_detach(&drvr_priv->pub); |
1061 | 977 | ||
@@ -1123,16 +1039,6 @@ int brcmf_bus_start(struct brcmf_pub *drvr) | |||
1123 | return 0; | 1039 | return 0; |
1124 | } | 1040 | } |
1125 | 1041 | ||
1126 | static struct net_device_ops brcmf_netdev_ops_pri = { | ||
1127 | .ndo_open = brcmf_netdev_open, | ||
1128 | .ndo_stop = brcmf_netdev_stop, | ||
1129 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
1130 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
1131 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
1132 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
1133 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
1134 | }; | ||
1135 | |||
1136 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | 1042 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) |
1137 | { | 1043 | { |
1138 | struct brcmf_info *drvr_priv = drvr->info; | 1044 | struct brcmf_info *drvr_priv = drvr->info; |
@@ -1169,6 +1075,18 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | |||
1169 | 1075 | ||
1170 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 1076 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); |
1171 | 1077 | ||
1078 | /* attach to cfg80211 for primary interface */ | ||
1079 | if (!ifidx) { | ||
1080 | drvr->config = | ||
1081 | brcmf_cfg80211_attach(ndev, | ||
1082 | brcmf_bus_get_device(drvr->bus), | ||
1083 | drvr); | ||
1084 | if (drvr->config == NULL) { | ||
1085 | brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); | ||
1086 | goto fail; | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1172 | if (register_netdev(ndev) != 0) { | 1090 | if (register_netdev(ndev) != 0) { |
1173 | brcmf_dbg(ERROR, "couldn't register the net device\n"); | 1091 | brcmf_dbg(ERROR, "couldn't register the net device\n"); |
1174 | goto fail; | 1092 | goto fail; |
@@ -1210,21 +1128,13 @@ void brcmf_detach(struct brcmf_pub *drvr) | |||
1210 | if (drvr) { | 1128 | if (drvr) { |
1211 | drvr_priv = drvr->info; | 1129 | drvr_priv = drvr->info; |
1212 | if (drvr_priv) { | 1130 | if (drvr_priv) { |
1213 | struct brcmf_if *ifp; | ||
1214 | int i; | 1131 | int i; |
1215 | 1132 | ||
1216 | for (i = 1; i < BRCMF_MAX_IFS; i++) | 1133 | /* make sure primary interface removed last */ |
1134 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||
1217 | if (drvr_priv->iflist[i]) | 1135 | if (drvr_priv->iflist[i]) |
1218 | brcmf_del_if(drvr_priv, i); | 1136 | brcmf_del_if(drvr_priv, i); |
1219 | 1137 | ||
1220 | ifp = drvr_priv->iflist[0]; | ||
1221 | if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | ||
1222 | rtnl_lock(); | ||
1223 | brcmf_netdev_stop(ifp->ndev); | ||
1224 | rtnl_unlock(); | ||
1225 | unregister_netdev(ifp->ndev); | ||
1226 | } | ||
1227 | |||
1228 | cancel_work_sync(&drvr_priv->setmacaddr_work); | 1138 | cancel_work_sync(&drvr_priv->setmacaddr_work); |
1229 | cancel_work_sync(&drvr_priv->multicast_work); | 1139 | cancel_work_sync(&drvr_priv->multicast_work); |
1230 | 1140 | ||
@@ -1233,10 +1143,6 @@ void brcmf_detach(struct brcmf_pub *drvr) | |||
1233 | if (drvr->prot) | 1143 | if (drvr->prot) |
1234 | brcmf_proto_detach(drvr); | 1144 | brcmf_proto_detach(drvr); |
1235 | 1145 | ||
1236 | brcmf_cfg80211_detach(drvr->config); | ||
1237 | |||
1238 | free_netdev(ifp->ndev); | ||
1239 | kfree(ifp); | ||
1240 | kfree(drvr_priv); | 1146 | kfree(drvr_priv); |
1241 | } | 1147 | } |
1242 | } | 1148 | } |
@@ -1302,7 +1208,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) | |||
1302 | 1208 | ||
1303 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 1209 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
1304 | { | 1210 | { |
1305 | struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev); | 1211 | struct brcmf_if *ifp = netdev_priv(ndev); |
1212 | struct brcmf_info *drvr_priv = ifp->info; | ||
1306 | int timeout = 10 * HZ / 1000; | 1213 | int timeout = 10 * HZ / 1000; |
1307 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 1214 | int ntimes = MAX_WAIT_FOR_8021X_TX; |
1308 | int pend = brcmf_get_pend_8021x_cnt(drvr_priv); | 1215 | int pend = brcmf_get_pend_8021x_cnt(drvr_priv); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 313b8bf592d1..22913af26db8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/semaphore.h> | 28 | #include <linux/semaphore.h> |
29 | #include <linux/firmware.h> | 29 | #include <linux/firmware.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/bcma/bcma.h> | ||
31 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
32 | #include <defs.h> | 33 | #include <defs.h> |
33 | #include <brcmu_wifi.h> | 34 | #include <brcmu_wifi.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <brcm_hw_ids.h> | 36 | #include <brcm_hw_ids.h> |
36 | #include <soc.h> | 37 | #include <soc.h> |
37 | #include "sdio_host.h" | 38 | #include "sdio_host.h" |
39 | #include "sdio_chip.h" | ||
38 | 40 | ||
39 | #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ | 41 | #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ |
40 | 42 | ||
@@ -134,33 +136,6 @@ struct rte_console { | |||
134 | /* Force no backplane reset */ | 136 | /* Force no backplane reset */ |
135 | #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 | 137 | #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 |
136 | 138 | ||
137 | /* SBSDIO_FUNC1_CHIPCLKCSR */ | ||
138 | |||
139 | /* Force ALP request to backplane */ | ||
140 | #define SBSDIO_FORCE_ALP 0x01 | ||
141 | /* Force HT request to backplane */ | ||
142 | #define SBSDIO_FORCE_HT 0x02 | ||
143 | /* Force ILP request to backplane */ | ||
144 | #define SBSDIO_FORCE_ILP 0x04 | ||
145 | /* Make ALP ready (power up xtal) */ | ||
146 | #define SBSDIO_ALP_AVAIL_REQ 0x08 | ||
147 | /* Make HT ready (power up PLL) */ | ||
148 | #define SBSDIO_HT_AVAIL_REQ 0x10 | ||
149 | /* Squelch clock requests from HW */ | ||
150 | #define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 | ||
151 | /* Status: ALP is ready */ | ||
152 | #define SBSDIO_ALP_AVAIL 0x40 | ||
153 | /* Status: HT is ready */ | ||
154 | #define SBSDIO_HT_AVAIL 0x80 | ||
155 | |||
156 | #define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) | ||
157 | #define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) | ||
158 | #define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) | ||
159 | #define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) | ||
160 | |||
161 | #define SBSDIO_CLKAV(regval, alponly) \ | ||
162 | (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) | ||
163 | |||
164 | /* direct(mapped) cis space */ | 139 | /* direct(mapped) cis space */ |
165 | 140 | ||
166 | /* MAPPED common CIS address */ | 141 | /* MAPPED common CIS address */ |
@@ -335,50 +310,6 @@ struct rte_console { | |||
335 | /* Flags for SDH calls */ | 310 | /* Flags for SDH calls */ |
336 | #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) | 311 | #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) |
337 | 312 | ||
338 | /* sbimstate */ | ||
339 | #define SBIM_IBE 0x20000 /* inbanderror */ | ||
340 | #define SBIM_TO 0x40000 /* timeout */ | ||
341 | #define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ | ||
342 | #define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ | ||
343 | |||
344 | /* sbtmstatelow */ | ||
345 | |||
346 | /* reset */ | ||
347 | #define SBTML_RESET 0x0001 | ||
348 | /* reject field */ | ||
349 | #define SBTML_REJ_MASK 0x0006 | ||
350 | /* reject */ | ||
351 | #define SBTML_REJ 0x0002 | ||
352 | /* temporary reject, for error recovery */ | ||
353 | #define SBTML_TMPREJ 0x0004 | ||
354 | |||
355 | /* Shift to locate the SI control flags in sbtml */ | ||
356 | #define SBTML_SICF_SHIFT 16 | ||
357 | |||
358 | /* sbtmstatehigh */ | ||
359 | #define SBTMH_SERR 0x0001 /* serror */ | ||
360 | #define SBTMH_INT 0x0002 /* interrupt */ | ||
361 | #define SBTMH_BUSY 0x0004 /* busy */ | ||
362 | #define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ | ||
363 | |||
364 | /* Shift to locate the SI status flags in sbtmh */ | ||
365 | #define SBTMH_SISF_SHIFT 16 | ||
366 | |||
367 | /* sbidlow */ | ||
368 | #define SBIDL_INIT 0x80 /* initiator */ | ||
369 | |||
370 | /* sbidhigh */ | ||
371 | #define SBIDH_RC_MASK 0x000f /* revision code */ | ||
372 | #define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ | ||
373 | #define SBIDH_RCE_SHIFT 8 | ||
374 | #define SBCOREREV(sbidh) \ | ||
375 | ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \ | ||
376 | ((sbidh) & SBIDH_RC_MASK)) | ||
377 | #define SBIDH_CC_MASK 0x8ff0 /* core code */ | ||
378 | #define SBIDH_CC_SHIFT 4 | ||
379 | #define SBIDH_VC_MASK 0xffff0000 /* vendor code */ | ||
380 | #define SBIDH_VC_SHIFT 16 | ||
381 | |||
382 | /* | 313 | /* |
383 | * Conversion of 802.1D priority to precedence level | 314 | * Conversion of 802.1D priority to precedence level |
384 | */ | 315 | */ |
@@ -388,17 +319,6 @@ static uint prio2prec(u32 prio) | |||
388 | (prio^2) : prio; | 319 | (prio^2) : prio; |
389 | } | 320 | } |
390 | 321 | ||
391 | /* | ||
392 | * Core reg address translation. | ||
393 | * Both macro's returns a 32 bits byte address on the backplane bus. | ||
394 | */ | ||
395 | #define CORE_CC_REG(base, field) \ | ||
396 | (base + offsetof(struct chipcregs, field)) | ||
397 | #define CORE_BUS_REG(base, field) \ | ||
398 | (base + offsetof(struct sdpcmd_regs, field)) | ||
399 | #define CORE_SB(base, field) \ | ||
400 | (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) | ||
401 | |||
402 | /* core registers */ | 322 | /* core registers */ |
403 | struct sdpcmd_regs { | 323 | struct sdpcmd_regs { |
404 | u32 corecontrol; /* 0x00, rev8 */ | 324 | u32 corecontrol; /* 0x00, rev8 */ |
@@ -524,21 +444,6 @@ struct sdpcm_shared_le { | |||
524 | 444 | ||
525 | 445 | ||
526 | /* misc chip info needed by some of the routines */ | 446 | /* misc chip info needed by some of the routines */ |
527 | struct chip_info { | ||
528 | u32 chip; | ||
529 | u32 chiprev; | ||
530 | u32 cccorebase; | ||
531 | u32 ccrev; | ||
532 | u32 cccaps; | ||
533 | u32 buscorebase; /* 32 bits backplane bus address */ | ||
534 | u32 buscorerev; | ||
535 | u32 buscoretype; | ||
536 | u32 ramcorebase; | ||
537 | u32 armcorebase; | ||
538 | u32 pmurev; | ||
539 | u32 ramsize; | ||
540 | }; | ||
541 | |||
542 | /* Private data for SDIO bus interaction */ | 447 | /* Private data for SDIO bus interaction */ |
543 | struct brcmf_bus { | 448 | struct brcmf_bus { |
544 | struct brcmf_pub *drvr; | 449 | struct brcmf_pub *drvr; |
@@ -574,7 +479,7 @@ struct brcmf_bus { | |||
574 | uint txminmax; | 479 | uint txminmax; |
575 | 480 | ||
576 | struct sk_buff *glomd; /* Packet containing glomming descriptor */ | 481 | struct sk_buff *glomd; /* Packet containing glomming descriptor */ |
577 | struct sk_buff *glom; /* Packet chain for glommed superframe */ | 482 | struct sk_buff_head glom; /* Packet list for glommed superframe */ |
578 | uint glomerr; /* Glom packet read errors */ | 483 | uint glomerr; /* Glom packet read errors */ |
579 | 484 | ||
580 | u8 *rxbuf; /* Buffer for receiving control packets */ | 485 | u8 *rxbuf; /* Buffer for receiving control packets */ |
@@ -663,46 +568,6 @@ struct brcmf_bus { | |||
663 | u32 fw_ptr; | 568 | u32 fw_ptr; |
664 | }; | 569 | }; |
665 | 570 | ||
666 | struct sbconfig { | ||
667 | u32 PAD[2]; | ||
668 | u32 sbipsflag; /* initiator port ocp slave flag */ | ||
669 | u32 PAD[3]; | ||
670 | u32 sbtpsflag; /* target port ocp slave flag */ | ||
671 | u32 PAD[11]; | ||
672 | u32 sbtmerrloga; /* (sonics >= 2.3) */ | ||
673 | u32 PAD; | ||
674 | u32 sbtmerrlog; /* (sonics >= 2.3) */ | ||
675 | u32 PAD[3]; | ||
676 | u32 sbadmatch3; /* address match3 */ | ||
677 | u32 PAD; | ||
678 | u32 sbadmatch2; /* address match2 */ | ||
679 | u32 PAD; | ||
680 | u32 sbadmatch1; /* address match1 */ | ||
681 | u32 PAD[7]; | ||
682 | u32 sbimstate; /* initiator agent state */ | ||
683 | u32 sbintvec; /* interrupt mask */ | ||
684 | u32 sbtmstatelow; /* target state */ | ||
685 | u32 sbtmstatehigh; /* target state */ | ||
686 | u32 sbbwa0; /* bandwidth allocation table0 */ | ||
687 | u32 PAD; | ||
688 | u32 sbimconfiglow; /* initiator configuration */ | ||
689 | u32 sbimconfighigh; /* initiator configuration */ | ||
690 | u32 sbadmatch0; /* address match0 */ | ||
691 | u32 PAD; | ||
692 | u32 sbtmconfiglow; /* target configuration */ | ||
693 | u32 sbtmconfighigh; /* target configuration */ | ||
694 | u32 sbbconfig; /* broadcast configuration */ | ||
695 | u32 PAD; | ||
696 | u32 sbbstate; /* broadcast state */ | ||
697 | u32 PAD[3]; | ||
698 | u32 sbactcnfg; /* activate configuration */ | ||
699 | u32 PAD[3]; | ||
700 | u32 sbflagst; /* current sbflags */ | ||
701 | u32 PAD[3]; | ||
702 | u32 sbidlow; /* identification */ | ||
703 | u32 sbidhigh; /* identification */ | ||
704 | }; | ||
705 | |||
706 | /* clkstate */ | 571 | /* clkstate */ |
707 | #define CLK_NONE 0 | 572 | #define CLK_NONE 0 |
708 | #define CLK_SDONLY 1 | 573 | #define CLK_SDONLY 1 |
@@ -750,10 +615,12 @@ static bool data_ok(struct brcmf_bus *bus) | |||
750 | static void | 615 | static void |
751 | r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) | 616 | r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) |
752 | { | 617 | { |
618 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | ||
753 | *retryvar = 0; | 619 | *retryvar = 0; |
754 | do { | 620 | do { |
755 | *regvar = brcmf_sdcard_reg_read(bus->sdiodev, | 621 | *regvar = brcmf_sdcard_reg_read(bus->sdiodev, |
756 | bus->ci->buscorebase + reg_offset, sizeof(u32)); | 622 | bus->ci->c_inf[idx].base + reg_offset, |
623 | sizeof(u32)); | ||
757 | } while (brcmf_sdcard_regfail(bus->sdiodev) && | 624 | } while (brcmf_sdcard_regfail(bus->sdiodev) && |
758 | (++(*retryvar) <= retry_limit)); | 625 | (++(*retryvar) <= retry_limit)); |
759 | if (*retryvar) { | 626 | if (*retryvar) { |
@@ -768,10 +635,11 @@ r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) | |||
768 | static void | 635 | static void |
769 | w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) | 636 | w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) |
770 | { | 637 | { |
638 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | ||
771 | *retryvar = 0; | 639 | *retryvar = 0; |
772 | do { | 640 | do { |
773 | brcmf_sdcard_reg_write(bus->sdiodev, | 641 | brcmf_sdcard_reg_write(bus->sdiodev, |
774 | bus->ci->buscorebase + reg_offset, | 642 | bus->ci->c_inf[idx].base + reg_offset, |
775 | sizeof(u32), regval); | 643 | sizeof(u32), regval); |
776 | } while (brcmf_sdcard_regfail(bus->sdiodev) && | 644 | } while (brcmf_sdcard_regfail(bus->sdiodev) && |
777 | (++(*retryvar) <= retry_limit)); | 645 | (++(*retryvar) <= retry_limit)); |
@@ -812,10 +680,6 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) | |||
812 | clkreq = | 680 | clkreq = |
813 | bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; | 681 | bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; |
814 | 682 | ||
815 | if ((bus->ci->chip == BCM4329_CHIP_ID) | ||
816 | && (bus->ci->chiprev == 0)) | ||
817 | clkreq |= SBSDIO_FORCE_ALP; | ||
818 | |||
819 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 683 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
820 | SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); | 684 | SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); |
821 | if (err) { | 685 | if (err) { |
@@ -823,14 +687,6 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) | |||
823 | return -EBADE; | 687 | return -EBADE; |
824 | } | 688 | } |
825 | 689 | ||
826 | if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) | ||
827 | && (bus->ci->buscorerev == 9))) { | ||
828 | u32 dummy, retries; | ||
829 | r_sdreg32(bus, &dummy, | ||
830 | offsetof(struct sdpcmd_regs, clockctlstatus), | ||
831 | &retries); | ||
832 | } | ||
833 | |||
834 | /* Check current status */ | 690 | /* Check current status */ |
835 | clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | 691 | clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, |
836 | SBSDIO_FUNC1_CHIPCLKCSR, &err); | 692 | SBSDIO_FUNC1_CHIPCLKCSR, &err); |
@@ -1034,11 +890,9 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) | |||
1034 | SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); | 890 | SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); |
1035 | 891 | ||
1036 | /* Isolate the bus */ | 892 | /* Isolate the bus */ |
1037 | if (bus->ci->chip != BCM4329_CHIP_ID) { | 893 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
1038 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 894 | SBSDIO_DEVICE_CTL, |
1039 | SBSDIO_DEVICE_CTL, | 895 | SBSDIO_DEVCTL_PADS_ISO, NULL); |
1040 | SBSDIO_DEVCTL_PADS_ISO, NULL); | ||
1041 | } | ||
1042 | 896 | ||
1043 | /* Change state */ | 897 | /* Change state */ |
1044 | bus->sleeping = true; | 898 | bus->sleeping = true; |
@@ -1049,13 +903,6 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) | |||
1049 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 903 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
1050 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | 904 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |
1051 | 905 | ||
1052 | /* Force pad isolation off if possible | ||
1053 | (in case power never toggled) */ | ||
1054 | if ((bus->ci->buscoretype == PCMCIA_CORE_ID) | ||
1055 | && (bus->ci->buscorerev >= 10)) | ||
1056 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
1057 | SBSDIO_DEVICE_CTL, 0, NULL); | ||
1058 | |||
1059 | /* Make sure the controller has the bus up */ | 906 | /* Make sure the controller has the bus up */ |
1060 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 907 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
1061 | 908 | ||
@@ -1222,6 +1069,51 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) | |||
1222 | bus->drvr->busstate = BRCMF_BUS_DOWN; | 1069 | bus->drvr->busstate = BRCMF_BUS_DOWN; |
1223 | } | 1070 | } |
1224 | 1071 | ||
1072 | /* copy a buffer into a pkt buffer chain */ | ||
1073 | static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_bus *bus, uint len) | ||
1074 | { | ||
1075 | uint n, ret = 0; | ||
1076 | struct sk_buff *p; | ||
1077 | u8 *buf; | ||
1078 | |||
1079 | buf = bus->dataptr; | ||
1080 | |||
1081 | /* copy the data */ | ||
1082 | skb_queue_walk(&bus->glom, p) { | ||
1083 | n = min_t(uint, p->len, len); | ||
1084 | memcpy(p->data, buf, n); | ||
1085 | buf += n; | ||
1086 | len -= n; | ||
1087 | ret += n; | ||
1088 | if (!len) | ||
1089 | break; | ||
1090 | } | ||
1091 | |||
1092 | return ret; | ||
1093 | } | ||
1094 | |||
1095 | /* return total length of buffer chain */ | ||
1096 | static uint brcmf_sdbrcm_glom_len(struct brcmf_bus *bus) | ||
1097 | { | ||
1098 | struct sk_buff *p; | ||
1099 | uint total; | ||
1100 | |||
1101 | total = 0; | ||
1102 | skb_queue_walk(&bus->glom, p) | ||
1103 | total += p->len; | ||
1104 | return total; | ||
1105 | } | ||
1106 | |||
1107 | static void brcmf_sdbrcm_free_glom(struct brcmf_bus *bus) | ||
1108 | { | ||
1109 | struct sk_buff *cur, *next; | ||
1110 | |||
1111 | skb_queue_walk_safe(&bus->glom, cur, next) { | ||
1112 | skb_unlink(cur, &bus->glom); | ||
1113 | brcmu_pkt_buf_free_skb(cur); | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1225 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | 1117 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) |
1226 | { | 1118 | { |
1227 | u16 dlen, totlen; | 1119 | u16 dlen, totlen; |
@@ -1240,7 +1132,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1240 | /* If packets, issue read(s) and send up packet chain */ | 1132 | /* If packets, issue read(s) and send up packet chain */ |
1241 | /* Return sequence numbers consumed? */ | 1133 | /* Return sequence numbers consumed? */ |
1242 | 1134 | ||
1243 | brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom); | 1135 | brcmf_dbg(TRACE, "start: glomd %p glom %p\n", |
1136 | bus->glomd, skb_peek(&bus->glom)); | ||
1244 | 1137 | ||
1245 | /* If there's a descriptor, generate the packet chain */ | 1138 | /* If there's a descriptor, generate the packet chain */ |
1246 | if (bus->glomd) { | 1139 | if (bus->glomd) { |
@@ -1287,12 +1180,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1287 | num, sublen); | 1180 | num, sublen); |
1288 | break; | 1181 | break; |
1289 | } | 1182 | } |
1290 | if (!pfirst) { | 1183 | skb_queue_tail(&bus->glom, pnext); |
1291 | pfirst = plast = pnext; | ||
1292 | } else { | ||
1293 | plast->next = pnext; | ||
1294 | plast = pnext; | ||
1295 | } | ||
1296 | 1184 | ||
1297 | /* Adhere to start alignment requirements */ | 1185 | /* Adhere to start alignment requirements */ |
1298 | pkt_align(pnext, sublen, BRCMF_SDALIGN); | 1186 | pkt_align(pnext, sublen, BRCMF_SDALIGN); |
@@ -1308,12 +1196,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1308 | brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", | 1196 | brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", |
1309 | bus->nextlen, totlen, rxseq); | 1197 | bus->nextlen, totlen, rxseq); |
1310 | } | 1198 | } |
1311 | bus->glom = pfirst; | ||
1312 | pfirst = pnext = NULL; | 1199 | pfirst = pnext = NULL; |
1313 | } else { | 1200 | } else { |
1314 | if (pfirst) | 1201 | brcmf_sdbrcm_free_glom(bus); |
1315 | brcmu_pkt_buf_free_skb(pfirst); | ||
1316 | bus->glom = NULL; | ||
1317 | num = 0; | 1202 | num = 0; |
1318 | } | 1203 | } |
1319 | 1204 | ||
@@ -1325,18 +1210,18 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1325 | 1210 | ||
1326 | /* Ok -- either we just generated a packet chain, | 1211 | /* Ok -- either we just generated a packet chain, |
1327 | or had one from before */ | 1212 | or had one from before */ |
1328 | if (bus->glom) { | 1213 | if (!skb_queue_empty(&bus->glom)) { |
1329 | if (BRCMF_GLOM_ON()) { | 1214 | if (BRCMF_GLOM_ON()) { |
1330 | brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); | 1215 | brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); |
1331 | for (pnext = bus->glom; pnext; pnext = pnext->next) { | 1216 | skb_queue_walk(&bus->glom, pnext) { |
1332 | brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", | 1217 | brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", |
1333 | pnext, (u8 *) (pnext->data), | 1218 | pnext, (u8 *) (pnext->data), |
1334 | pnext->len, pnext->len); | 1219 | pnext->len, pnext->len); |
1335 | } | 1220 | } |
1336 | } | 1221 | } |
1337 | 1222 | ||
1338 | pfirst = bus->glom; | 1223 | pfirst = skb_peek(&bus->glom); |
1339 | dlen = (u16) brcmu_pkttotlen(pfirst); | 1224 | dlen = (u16) brcmf_sdbrcm_glom_len(bus); |
1340 | 1225 | ||
1341 | /* Do an SDIO read for the superframe. Configurable iovar to | 1226 | /* Do an SDIO read for the superframe. Configurable iovar to |
1342 | * read directly into the chained packet, or allocate a large | 1227 | * read directly into the chained packet, or allocate a large |
@@ -1354,8 +1239,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1354 | SDIO_FUNC_2, | 1239 | SDIO_FUNC_2, |
1355 | F2SYNC, bus->dataptr, dlen, | 1240 | F2SYNC, bus->dataptr, dlen, |
1356 | NULL); | 1241 | NULL); |
1357 | sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen, | 1242 | sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen); |
1358 | bus->dataptr); | ||
1359 | if (sublen != dlen) { | 1243 | if (sublen != dlen) { |
1360 | brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", | 1244 | brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", |
1361 | dlen, sublen); | 1245 | dlen, sublen); |
@@ -1380,9 +1264,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1380 | } else { | 1264 | } else { |
1381 | bus->glomerr = 0; | 1265 | bus->glomerr = 0; |
1382 | brcmf_sdbrcm_rxfail(bus, true, false); | 1266 | brcmf_sdbrcm_rxfail(bus, true, false); |
1383 | brcmu_pkt_buf_free_skb(bus->glom); | ||
1384 | bus->rxglomfail++; | 1267 | bus->rxglomfail++; |
1385 | bus->glom = NULL; | 1268 | brcmf_sdbrcm_free_glom(bus); |
1386 | } | 1269 | } |
1387 | return 0; | 1270 | return 0; |
1388 | } | 1271 | } |
@@ -1503,9 +1386,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1503 | } else { | 1386 | } else { |
1504 | bus->glomerr = 0; | 1387 | bus->glomerr = 0; |
1505 | brcmf_sdbrcm_rxfail(bus, true, false); | 1388 | brcmf_sdbrcm_rxfail(bus, true, false); |
1506 | brcmu_pkt_buf_free_skb(bus->glom); | ||
1507 | bus->rxglomfail++; | 1389 | bus->rxglomfail++; |
1508 | bus->glom = NULL; | 1390 | brcmf_sdbrcm_free_glom(bus); |
1509 | } | 1391 | } |
1510 | bus->nextlen = 0; | 1392 | bus->nextlen = 0; |
1511 | return 0; | 1393 | return 0; |
@@ -1513,7 +1395,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1513 | 1395 | ||
1514 | /* Basic SD framing looks ok - process each packet (header) */ | 1396 | /* Basic SD framing looks ok - process each packet (header) */ |
1515 | save_pfirst = pfirst; | 1397 | save_pfirst = pfirst; |
1516 | bus->glom = NULL; | ||
1517 | plast = NULL; | 1398 | plast = NULL; |
1518 | 1399 | ||
1519 | for (num = 0; pfirst; rxseq++, pfirst = pnext) { | 1400 | for (num = 0; pfirst; rxseq++, pfirst = pnext) { |
@@ -1850,10 +1731,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) | |||
1850 | rxseq++, rxleft--) { | 1731 | rxseq++, rxleft--) { |
1851 | 1732 | ||
1852 | /* Handle glomming separately */ | 1733 | /* Handle glomming separately */ |
1853 | if (bus->glom || bus->glomd) { | 1734 | if (bus->glomd || !skb_queue_empty(&bus->glom)) { |
1854 | u8 cnt; | 1735 | u8 cnt; |
1855 | brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", | 1736 | brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", |
1856 | bus->glomd, bus->glom); | 1737 | bus->glomd, skb_peek(&bus->glom)); |
1857 | cnt = brcmf_sdbrcm_rxglom(bus, rxseq); | 1738 | cnt = brcmf_sdbrcm_rxglom(bus, rxseq); |
1858 | brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); | 1739 | brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); |
1859 | rxseq += cnt - 1; | 1740 | rxseq += cnt - 1; |
@@ -3210,135 +3091,11 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) | |||
3210 | return bcmerror; | 3091 | return bcmerror; |
3211 | } | 3092 | } |
3212 | 3093 | ||
3213 | static void | ||
3214 | brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase) | ||
3215 | { | ||
3216 | u32 regdata; | ||
3217 | |||
3218 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3219 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3220 | if (regdata & SBTML_RESET) | ||
3221 | return; | ||
3222 | |||
3223 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3224 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3225 | if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) { | ||
3226 | /* | ||
3227 | * set target reject and spin until busy is clear | ||
3228 | * (preserve core-specific bits) | ||
3229 | */ | ||
3230 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3231 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3232 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), | ||
3233 | 4, regdata | SBTML_REJ); | ||
3234 | |||
3235 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3236 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3237 | udelay(1); | ||
3238 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
3239 | CORE_SB(corebase, sbtmstatehigh), 4) & | ||
3240 | SBTMH_BUSY), 100000); | ||
3241 | |||
3242 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3243 | CORE_SB(corebase, sbtmstatehigh), 4); | ||
3244 | if (regdata & SBTMH_BUSY) | ||
3245 | brcmf_dbg(ERROR, "ARM core still busy\n"); | ||
3246 | |||
3247 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3248 | CORE_SB(corebase, sbidlow), 4); | ||
3249 | if (regdata & SBIDL_INIT) { | ||
3250 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3251 | CORE_SB(corebase, sbimstate), 4) | | ||
3252 | SBIM_RJ; | ||
3253 | brcmf_sdcard_reg_write(sdiodev, | ||
3254 | CORE_SB(corebase, sbimstate), 4, | ||
3255 | regdata); | ||
3256 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3257 | CORE_SB(corebase, sbimstate), 4); | ||
3258 | udelay(1); | ||
3259 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
3260 | CORE_SB(corebase, sbimstate), 4) & | ||
3261 | SBIM_BY), 100000); | ||
3262 | } | ||
3263 | |||
3264 | /* set reset and reject while enabling the clocks */ | ||
3265 | brcmf_sdcard_reg_write(sdiodev, | ||
3266 | CORE_SB(corebase, sbtmstatelow), 4, | ||
3267 | (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | | ||
3268 | SBTML_REJ | SBTML_RESET)); | ||
3269 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3270 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3271 | udelay(10); | ||
3272 | |||
3273 | /* clear the initiator reject bit */ | ||
3274 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3275 | CORE_SB(corebase, sbidlow), 4); | ||
3276 | if (regdata & SBIDL_INIT) { | ||
3277 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3278 | CORE_SB(corebase, sbimstate), 4) & | ||
3279 | ~SBIM_RJ; | ||
3280 | brcmf_sdcard_reg_write(sdiodev, | ||
3281 | CORE_SB(corebase, sbimstate), 4, | ||
3282 | regdata); | ||
3283 | } | ||
3284 | } | ||
3285 | |||
3286 | /* leave reset and reject asserted */ | ||
3287 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3288 | (SBTML_REJ | SBTML_RESET)); | ||
3289 | udelay(1); | ||
3290 | } | ||
3291 | |||
3292 | static void | ||
3293 | brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase) | ||
3294 | { | ||
3295 | u32 regdata; | ||
3296 | |||
3297 | /* | ||
3298 | * Must do the disable sequence first to work for | ||
3299 | * arbitrary current core state. | ||
3300 | */ | ||
3301 | brcmf_sdbrcm_chip_disablecore(sdiodev, corebase); | ||
3302 | |||
3303 | /* | ||
3304 | * Now do the initialization sequence. | ||
3305 | * set reset while enabling the clock and | ||
3306 | * forcing them on throughout the core | ||
3307 | */ | ||
3308 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3309 | ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | | ||
3310 | SBTML_RESET); | ||
3311 | udelay(1); | ||
3312 | |||
3313 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3314 | CORE_SB(corebase, sbtmstatehigh), 4); | ||
3315 | if (regdata & SBTMH_SERR) | ||
3316 | brcmf_sdcard_reg_write(sdiodev, | ||
3317 | CORE_SB(corebase, sbtmstatehigh), 4, 0); | ||
3318 | |||
3319 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3320 | CORE_SB(corebase, sbimstate), 4); | ||
3321 | if (regdata & (SBIM_IBE | SBIM_TO)) | ||
3322 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4, | ||
3323 | regdata & ~(SBIM_IBE | SBIM_TO)); | ||
3324 | |||
3325 | /* clear reset and allow it to propagate throughout the core */ | ||
3326 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3327 | (SICF_FGC << SBTML_SICF_SHIFT) | | ||
3328 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3329 | udelay(1); | ||
3330 | |||
3331 | /* leave clock enabled */ | ||
3332 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3333 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3334 | udelay(1); | ||
3335 | } | ||
3336 | |||
3337 | static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | 3094 | static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) |
3338 | { | 3095 | { |
3339 | uint retries; | 3096 | uint retries; |
3340 | u32 regdata; | ||
3341 | int bcmerror = 0; | 3097 | int bcmerror = 0; |
3098 | struct chip_info *ci = bus->ci; | ||
3342 | 3099 | ||
3343 | /* To enter download state, disable ARM and reset SOCRAM. | 3100 | /* To enter download state, disable ARM and reset SOCRAM. |
3344 | * To exit download state, simply reset ARM (default is RAM boot). | 3101 | * To exit download state, simply reset ARM (default is RAM boot). |
@@ -3346,10 +3103,9 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3346 | if (enter) { | 3103 | if (enter) { |
3347 | bus->alp_only = true; | 3104 | bus->alp_only = true; |
3348 | 3105 | ||
3349 | brcmf_sdbrcm_chip_disablecore(bus->sdiodev, | 3106 | ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); |
3350 | bus->ci->armcorebase); | ||
3351 | 3107 | ||
3352 | brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase); | 3108 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM); |
3353 | 3109 | ||
3354 | /* Clear the top bit of memory */ | 3110 | /* Clear the top bit of memory */ |
3355 | if (bus->ramsize) { | 3111 | if (bus->ramsize) { |
@@ -3358,11 +3114,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3358 | (u8 *)&zeros, 4); | 3114 | (u8 *)&zeros, 4); |
3359 | } | 3115 | } |
3360 | } else { | 3116 | } else { |
3361 | regdata = brcmf_sdcard_reg_read(bus->sdiodev, | 3117 | if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { |
3362 | CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4); | ||
3363 | regdata &= (SBTML_RESET | SBTML_REJ_MASK | | ||
3364 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3365 | if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) { | ||
3366 | brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); | 3118 | brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); |
3367 | bcmerror = -EBADE; | 3119 | bcmerror = -EBADE; |
3368 | goto fail; | 3120 | goto fail; |
@@ -3377,7 +3129,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3377 | w_sdreg32(bus, 0xFFFFFFFF, | 3129 | w_sdreg32(bus, 0xFFFFFFFF, |
3378 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 3130 | offsetof(struct sdpcmd_regs, intstatus), &retries); |
3379 | 3131 | ||
3380 | brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->armcorebase); | 3132 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); |
3381 | 3133 | ||
3382 | /* Allow HT Clock now that the ARM is running. */ | 3134 | /* Allow HT Clock now that the ARM is running. */ |
3383 | bus->alp_only = false; | 3135 | bus->alp_only = false; |
@@ -3661,11 +3413,7 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) | |||
3661 | /* Clear any held glomming stuff */ | 3413 | /* Clear any held glomming stuff */ |
3662 | if (bus->glomd) | 3414 | if (bus->glomd) |
3663 | brcmu_pkt_buf_free_skb(bus->glomd); | 3415 | brcmu_pkt_buf_free_skb(bus->glomd); |
3664 | 3416 | brcmf_sdbrcm_free_glom(bus); | |
3665 | if (bus->glom) | ||
3666 | brcmu_pkt_buf_free_skb(bus->glom); | ||
3667 | |||
3668 | bus->glom = bus->glomd = NULL; | ||
3669 | 3417 | ||
3670 | /* Clear rx control and wake any waiters */ | 3418 | /* Clear rx control and wake any waiters */ |
3671 | bus->rxlen = 0; | 3419 | bus->rxlen = 0; |
@@ -3950,269 +3698,6 @@ fail: | |||
3950 | return false; | 3698 | return false; |
3951 | } | 3699 | } |
3952 | 3700 | ||
3953 | /* SDIO Pad drive strength to select value mappings */ | ||
3954 | struct sdiod_drive_str { | ||
3955 | u8 strength; /* Pad Drive Strength in mA */ | ||
3956 | u8 sel; /* Chip-specific select value */ | ||
3957 | }; | ||
3958 | |||
3959 | /* SDIO Drive Strength to sel value table for PMU Rev 1 */ | ||
3960 | static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = { | ||
3961 | { | ||
3962 | 4, 0x2}, { | ||
3963 | 2, 0x3}, { | ||
3964 | 1, 0x0}, { | ||
3965 | 0, 0x0} | ||
3966 | }; | ||
3967 | |||
3968 | /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ | ||
3969 | static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = { | ||
3970 | { | ||
3971 | 12, 0x7}, { | ||
3972 | 10, 0x6}, { | ||
3973 | 8, 0x5}, { | ||
3974 | 6, 0x4}, { | ||
3975 | 4, 0x2}, { | ||
3976 | 2, 0x1}, { | ||
3977 | 0, 0x0} | ||
3978 | }; | ||
3979 | |||
3980 | /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ | ||
3981 | static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { | ||
3982 | { | ||
3983 | 32, 0x7}, { | ||
3984 | 26, 0x6}, { | ||
3985 | 22, 0x5}, { | ||
3986 | 16, 0x4}, { | ||
3987 | 12, 0x3}, { | ||
3988 | 8, 0x2}, { | ||
3989 | 4, 0x1}, { | ||
3990 | 0, 0x0} | ||
3991 | }; | ||
3992 | |||
3993 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | ||
3994 | |||
3995 | static char *brcmf_chipname(uint chipid, char *buf, uint len) | ||
3996 | { | ||
3997 | const char *fmt; | ||
3998 | |||
3999 | fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; | ||
4000 | snprintf(buf, len, fmt, chipid); | ||
4001 | return buf; | ||
4002 | } | ||
4003 | |||
4004 | static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, | ||
4005 | u32 drivestrength) { | ||
4006 | struct sdiod_drive_str *str_tab = NULL; | ||
4007 | u32 str_mask = 0; | ||
4008 | u32 str_shift = 0; | ||
4009 | char chn[8]; | ||
4010 | |||
4011 | if (!(bus->ci->cccaps & CC_CAP_PMU)) | ||
4012 | return; | ||
4013 | |||
4014 | switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) { | ||
4015 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): | ||
4016 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1; | ||
4017 | str_mask = 0x30000000; | ||
4018 | str_shift = 28; | ||
4019 | break; | ||
4020 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): | ||
4021 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): | ||
4022 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2; | ||
4023 | str_mask = 0x00003800; | ||
4024 | str_shift = 11; | ||
4025 | break; | ||
4026 | case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): | ||
4027 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3; | ||
4028 | str_mask = 0x00003800; | ||
4029 | str_shift = 11; | ||
4030 | break; | ||
4031 | default: | ||
4032 | brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | ||
4033 | brcmf_chipname(bus->ci->chip, chn, 8), | ||
4034 | bus->ci->chiprev, bus->ci->pmurev); | ||
4035 | break; | ||
4036 | } | ||
4037 | |||
4038 | if (str_tab != NULL) { | ||
4039 | u32 drivestrength_sel = 0; | ||
4040 | u32 cc_data_temp; | ||
4041 | int i; | ||
4042 | |||
4043 | for (i = 0; str_tab[i].strength != 0; i++) { | ||
4044 | if (drivestrength >= str_tab[i].strength) { | ||
4045 | drivestrength_sel = str_tab[i].sel; | ||
4046 | break; | ||
4047 | } | ||
4048 | } | ||
4049 | |||
4050 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4051 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), | ||
4052 | 4, 1); | ||
4053 | cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev, | ||
4054 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4); | ||
4055 | cc_data_temp &= ~str_mask; | ||
4056 | drivestrength_sel <<= str_shift; | ||
4057 | cc_data_temp |= drivestrength_sel; | ||
4058 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4059 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), | ||
4060 | 4, cc_data_temp); | ||
4061 | |||
4062 | brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", | ||
4063 | drivestrength, cc_data_temp); | ||
4064 | } | ||
4065 | } | ||
4066 | |||
4067 | static int | ||
4068 | brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_dev *sdiodev, | ||
4069 | struct chip_info *ci, u32 regs) | ||
4070 | { | ||
4071 | u32 regdata; | ||
4072 | |||
4073 | /* | ||
4074 | * Get CC core rev | ||
4075 | * Chipid is assume to be at offset 0 from regs arg | ||
4076 | * For different chiptypes or old sdio hosts w/o chipcommon, | ||
4077 | * other ways of recognition should be added here. | ||
4078 | */ | ||
4079 | ci->cccorebase = regs; | ||
4080 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4081 | CORE_CC_REG(ci->cccorebase, chipid), 4); | ||
4082 | ci->chip = regdata & CID_ID_MASK; | ||
4083 | ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; | ||
4084 | |||
4085 | brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); | ||
4086 | |||
4087 | /* Address of cores for new chips should be added here */ | ||
4088 | switch (ci->chip) { | ||
4089 | case BCM4329_CHIP_ID: | ||
4090 | ci->buscorebase = BCM4329_CORE_BUS_BASE; | ||
4091 | ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE; | ||
4092 | ci->armcorebase = BCM4329_CORE_ARM_BASE; | ||
4093 | ci->ramsize = BCM4329_RAMSIZE; | ||
4094 | break; | ||
4095 | default: | ||
4096 | brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); | ||
4097 | return -ENODEV; | ||
4098 | } | ||
4099 | |||
4100 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4101 | CORE_SB(ci->cccorebase, sbidhigh), 4); | ||
4102 | ci->ccrev = SBCOREREV(regdata); | ||
4103 | |||
4104 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4105 | CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); | ||
4106 | ci->pmurev = regdata & PCAP_REV_MASK; | ||
4107 | |||
4108 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4109 | CORE_SB(ci->buscorebase, sbidhigh), 4); | ||
4110 | ci->buscorerev = SBCOREREV(regdata); | ||
4111 | ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; | ||
4112 | |||
4113 | brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", | ||
4114 | ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype); | ||
4115 | |||
4116 | /* get chipcommon capabilites */ | ||
4117 | ci->cccaps = brcmf_sdcard_reg_read(sdiodev, | ||
4118 | CORE_CC_REG(ci->cccorebase, capabilities), 4); | ||
4119 | |||
4120 | return 0; | ||
4121 | } | ||
4122 | |||
4123 | static int | ||
4124 | brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs) | ||
4125 | { | ||
4126 | struct chip_info *ci; | ||
4127 | int err; | ||
4128 | u8 clkval, clkset; | ||
4129 | |||
4130 | brcmf_dbg(TRACE, "Enter\n"); | ||
4131 | |||
4132 | /* alloc chip_info_t */ | ||
4133 | ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); | ||
4134 | if (NULL == ci) | ||
4135 | return -ENOMEM; | ||
4136 | |||
4137 | /* bus/core/clk setup for register access */ | ||
4138 | /* Try forcing SDIO core to do ALPAvail request only */ | ||
4139 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; | ||
4140 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4141 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
4142 | if (err) { | ||
4143 | brcmf_dbg(ERROR, "error writing for HT off\n"); | ||
4144 | goto fail; | ||
4145 | } | ||
4146 | |||
4147 | /* If register supported, wait for ALPAvail and then force ALP */ | ||
4148 | /* This may take up to 15 milliseconds */ | ||
4149 | clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4150 | SBSDIO_FUNC1_CHIPCLKCSR, NULL); | ||
4151 | if ((clkval & ~SBSDIO_AVBITS) == clkset) { | ||
4152 | SPINWAIT(((clkval = | ||
4153 | brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4154 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
4155 | NULL)), | ||
4156 | !SBSDIO_ALPAV(clkval)), | ||
4157 | PMU_MAX_TRANSITION_DLY); | ||
4158 | if (!SBSDIO_ALPAV(clkval)) { | ||
4159 | brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n", | ||
4160 | clkval); | ||
4161 | err = -EBUSY; | ||
4162 | goto fail; | ||
4163 | } | ||
4164 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | | ||
4165 | SBSDIO_FORCE_ALP; | ||
4166 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4167 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
4168 | clkset, &err); | ||
4169 | udelay(65); | ||
4170 | } else { | ||
4171 | brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", | ||
4172 | clkset, clkval); | ||
4173 | err = -EACCES; | ||
4174 | goto fail; | ||
4175 | } | ||
4176 | |||
4177 | /* Also, disable the extra SDIO pull-ups */ | ||
4178 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4179 | SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); | ||
4180 | |||
4181 | err = brcmf_sdbrcm_chip_recognition(bus->sdiodev, ci, regs); | ||
4182 | if (err) | ||
4183 | goto fail; | ||
4184 | |||
4185 | /* | ||
4186 | * Make sure any on-chip ARM is off (in case strapping is wrong), | ||
4187 | * or downloaded code was already running. | ||
4188 | */ | ||
4189 | brcmf_sdbrcm_chip_disablecore(bus->sdiodev, ci->armcorebase); | ||
4190 | |||
4191 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4192 | CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); | ||
4193 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4194 | CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); | ||
4195 | |||
4196 | /* Disable F2 to clear any intermediate frame state on the dongle */ | ||
4197 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, | ||
4198 | SDIO_FUNC_ENABLE_1, NULL); | ||
4199 | |||
4200 | /* WAR: cmd52 backplane read so core HW will drop ALPReq */ | ||
4201 | clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4202 | 0, NULL); | ||
4203 | |||
4204 | /* Done with backplane-dependent accesses, can drop clock... */ | ||
4205 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4206 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | ||
4207 | |||
4208 | bus->ci = ci; | ||
4209 | return 0; | ||
4210 | fail: | ||
4211 | bus->ci = NULL; | ||
4212 | kfree(ci); | ||
4213 | return err; | ||
4214 | } | ||
4215 | |||
4216 | static bool | 3701 | static bool |
4217 | brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | 3702 | brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) |
4218 | { | 3703 | { |
@@ -4220,6 +3705,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4220 | int err = 0; | 3705 | int err = 0; |
4221 | int reg_addr; | 3706 | int reg_addr; |
4222 | u32 reg_val; | 3707 | u32 reg_val; |
3708 | u8 idx; | ||
4223 | 3709 | ||
4224 | bus->alp_only = true; | 3710 | bus->alp_only = true; |
4225 | 3711 | ||
@@ -4234,7 +3720,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4234 | #endif /* BCMDBG */ | 3720 | #endif /* BCMDBG */ |
4235 | 3721 | ||
4236 | /* | 3722 | /* |
4237 | * Force PLL off until brcmf_sdbrcm_chip_attach() | 3723 | * Force PLL off until brcmf_sdio_chip_attach() |
4238 | * programs PLL control regs | 3724 | * programs PLL control regs |
4239 | */ | 3725 | */ |
4240 | 3726 | ||
@@ -4252,8 +3738,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4252 | goto fail; | 3738 | goto fail; |
4253 | } | 3739 | } |
4254 | 3740 | ||
4255 | if (brcmf_sdbrcm_chip_attach(bus, regsva)) { | 3741 | if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) { |
4256 | brcmf_dbg(ERROR, "brcmf_sdbrcm_chip_attach failed!\n"); | 3742 | brcmf_dbg(ERROR, "brcmf_sdio_chip_attach failed!\n"); |
4257 | goto fail; | 3743 | goto fail; |
4258 | } | 3744 | } |
4259 | 3745 | ||
@@ -4262,11 +3748,10 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4262 | goto fail; | 3748 | goto fail; |
4263 | } | 3749 | } |
4264 | 3750 | ||
4265 | brcmf_sdbrcm_sdiod_drive_strength_init(bus, SDIO_DRIVE_STRENGTH); | 3751 | brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, |
3752 | SDIO_DRIVE_STRENGTH); | ||
4266 | 3753 | ||
4267 | /* Get info on the ARM and SOCRAM cores... */ | 3754 | /* Get info on the SOCRAM cores... */ |
4268 | brcmf_sdcard_reg_read(bus->sdiodev, | ||
4269 | CORE_SB(bus->ci->armcorebase, sbidhigh), 4); | ||
4270 | bus->ramsize = bus->ci->ramsize; | 3755 | bus->ramsize = bus->ci->ramsize; |
4271 | if (!(bus->ramsize)) { | 3756 | if (!(bus->ramsize)) { |
4272 | brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n"); | 3757 | brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n"); |
@@ -4274,7 +3759,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4274 | } | 3759 | } |
4275 | 3760 | ||
4276 | /* Set core control so an SDIO reset does a backplane reset */ | 3761 | /* Set core control so an SDIO reset does a backplane reset */ |
4277 | reg_addr = bus->ci->buscorebase + | 3762 | idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); |
3763 | reg_addr = bus->ci->c_inf[idx].base + | ||
4278 | offsetof(struct sdpcmd_regs, corecontrol); | 3764 | offsetof(struct sdpcmd_regs, corecontrol); |
4279 | reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); | 3765 | reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); |
4280 | brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), | 3766 | brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), |
@@ -4364,15 +3850,6 @@ brcmf_sdbrcm_watchdog(unsigned long data) | |||
4364 | } | 3850 | } |
4365 | } | 3851 | } |
4366 | 3852 | ||
4367 | static void | ||
4368 | brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus) | ||
4369 | { | ||
4370 | brcmf_dbg(TRACE, "Enter\n"); | ||
4371 | |||
4372 | kfree(bus->ci); | ||
4373 | bus->ci = NULL; | ||
4374 | } | ||
4375 | |||
4376 | static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) | 3853 | static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) |
4377 | { | 3854 | { |
4378 | brcmf_dbg(TRACE, "Enter\n"); | 3855 | brcmf_dbg(TRACE, "Enter\n"); |
@@ -4380,7 +3857,7 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) | |||
4380 | if (bus->ci) { | 3857 | if (bus->ci) { |
4381 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3858 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
4382 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3859 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
4383 | brcmf_sdbrcm_chip_detach(bus); | 3860 | brcmf_sdio_chip_detach(&bus->ci); |
4384 | if (bus->vars && bus->varsz) | 3861 | if (bus->vars && bus->varsz) |
4385 | kfree(bus->vars); | 3862 | kfree(bus->vars); |
4386 | bus->vars = NULL; | 3863 | bus->vars = NULL; |
@@ -4440,6 +3917,7 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, | |||
4440 | 3917 | ||
4441 | bus->sdiodev = sdiodev; | 3918 | bus->sdiodev = sdiodev; |
4442 | sdiodev->bus = bus; | 3919 | sdiodev->bus = bus; |
3920 | skb_queue_head_init(&bus->glom); | ||
4443 | bus->txbound = BRCMF_TXBOUND; | 3921 | bus->txbound = BRCMF_TXBOUND; |
4444 | bus->rxbound = BRCMF_RXBOUND; | 3922 | bus->rxbound = BRCMF_RXBOUND; |
4445 | bus->txminmax = BRCMF_TXMINMAX; | 3923 | bus->txminmax = BRCMF_TXMINMAX; |
@@ -4521,9 +3999,10 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, | |||
4521 | goto fail; | 3999 | goto fail; |
4522 | } | 4000 | } |
4523 | } | 4001 | } |
4524 | /* Ok, have the per-port tell the stack we're open for business */ | 4002 | |
4525 | if (brcmf_net_attach(bus->drvr, 0) != 0) { | 4003 | /* add interface and open for business */ |
4526 | brcmf_dbg(ERROR, "Net attach failed!!\n"); | 4004 | if (brcmf_add_if((struct brcmf_info *)bus->drvr, 0, "wlan%d", NULL)) { |
4005 | brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); | ||
4527 | goto fail; | 4006 | goto fail; |
4528 | } | 4007 | } |
4529 | 4008 | ||
@@ -4554,10 +4033,6 @@ struct device *brcmf_bus_get_device(struct brcmf_bus *bus) | |||
4554 | void | 4033 | void |
4555 | brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) | 4034 | brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) |
4556 | { | 4035 | { |
4557 | /* don't start the wd until fw is loaded */ | ||
4558 | if (bus->drvr->busstate == BRCMF_BUS_DOWN) | ||
4559 | return; | ||
4560 | |||
4561 | /* Totally stop the timer */ | 4036 | /* Totally stop the timer */ |
4562 | if (!wdtick && bus->wd_timer_valid == true) { | 4037 | if (!wdtick && bus->wd_timer_valid == true) { |
4563 | del_timer_sync(&bus->timer); | 4038 | del_timer_sync(&bus->timer); |
@@ -4566,6 +4041,10 @@ brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) | |||
4566 | return; | 4041 | return; |
4567 | } | 4042 | } |
4568 | 4043 | ||
4044 | /* don't start the wd until fw is loaded */ | ||
4045 | if (bus->drvr->busstate == BRCMF_BUS_DOWN) | ||
4046 | return; | ||
4047 | |||
4569 | if (wdtick) { | 4048 | if (wdtick) { |
4570 | if (bus->save_ms != BRCMF_WD_POLL_MS) { | 4049 | if (bus->save_ms != BRCMF_WD_POLL_MS) { |
4571 | if (bus->wd_timer_valid == true) | 4050 | if (bus->wd_timer_valid == true) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c new file mode 100644 index 000000000000..f6b1822031fe --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -0,0 +1,622 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | /* ***** SDIO interface chip backplane handle functions ***** */ | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/netdevice.h> | ||
20 | #include <linux/mmc/card.h> | ||
21 | #include <linux/ssb/ssb_regs.h> | ||
22 | #include <linux/bcma/bcma.h> | ||
23 | |||
24 | #include <chipcommon.h> | ||
25 | #include <brcm_hw_ids.h> | ||
26 | #include <brcmu_wifi.h> | ||
27 | #include <brcmu_utils.h> | ||
28 | #include <soc.h> | ||
29 | #include "dhd.h" | ||
30 | #include "dhd_dbg.h" | ||
31 | #include "sdio_host.h" | ||
32 | #include "sdio_chip.h" | ||
33 | |||
34 | /* chip core base & ramsize */ | ||
35 | /* bcm4329 */ | ||
36 | /* SDIO device core, ID 0x829 */ | ||
37 | #define BCM4329_CORE_BUS_BASE 0x18011000 | ||
38 | /* internal memory core, ID 0x80e */ | ||
39 | #define BCM4329_CORE_SOCRAM_BASE 0x18003000 | ||
40 | /* ARM Cortex M3 core, ID 0x82a */ | ||
41 | #define BCM4329_CORE_ARM_BASE 0x18002000 | ||
42 | #define BCM4329_RAMSIZE 0x48000 | ||
43 | |||
44 | #define SBCOREREV(sbidh) \ | ||
45 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ | ||
46 | ((sbidh) & SSB_IDHIGH_RCLO)) | ||
47 | |||
48 | /* SOC Interconnect types (aka chip types) */ | ||
49 | #define SOCI_SB 0 | ||
50 | #define SOCI_AI 1 | ||
51 | |||
52 | /* EROM CompIdentB */ | ||
53 | #define CIB_REV_MASK 0xff000000 | ||
54 | #define CIB_REV_SHIFT 24 | ||
55 | |||
56 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | ||
57 | /* SDIO Pad drive strength to select value mappings */ | ||
58 | struct sdiod_drive_str { | ||
59 | u8 strength; /* Pad Drive Strength in mA */ | ||
60 | u8 sel; /* Chip-specific select value */ | ||
61 | }; | ||
62 | /* SDIO Drive Strength to sel value table for PMU Rev 1 */ | ||
63 | static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = { | ||
64 | { | ||
65 | 4, 0x2}, { | ||
66 | 2, 0x3}, { | ||
67 | 1, 0x0}, { | ||
68 | 0, 0x0} | ||
69 | }; | ||
70 | /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ | ||
71 | static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = { | ||
72 | { | ||
73 | 12, 0x7}, { | ||
74 | 10, 0x6}, { | ||
75 | 8, 0x5}, { | ||
76 | 6, 0x4}, { | ||
77 | 4, 0x2}, { | ||
78 | 2, 0x1}, { | ||
79 | 0, 0x0} | ||
80 | }; | ||
81 | /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ | ||
82 | static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { | ||
83 | { | ||
84 | 32, 0x7}, { | ||
85 | 26, 0x6}, { | ||
86 | 22, 0x5}, { | ||
87 | 16, 0x4}, { | ||
88 | 12, 0x3}, { | ||
89 | 8, 0x2}, { | ||
90 | 4, 0x1}, { | ||
91 | 0, 0x0} | ||
92 | }; | ||
93 | |||
94 | u8 | ||
95 | brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) | ||
96 | { | ||
97 | u8 idx; | ||
98 | |||
99 | for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++) | ||
100 | if (coreid == ci->c_inf[idx].id) | ||
101 | return idx; | ||
102 | |||
103 | return BRCMF_MAX_CORENUM; | ||
104 | } | ||
105 | |||
106 | static u32 | ||
107 | brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, | ||
108 | struct chip_info *ci, u16 coreid) | ||
109 | { | ||
110 | u32 regdata; | ||
111 | u8 idx; | ||
112 | |||
113 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
114 | |||
115 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
116 | CORE_SB(ci->c_inf[idx].base, sbidhigh), 4); | ||
117 | return SBCOREREV(regdata); | ||
118 | } | ||
119 | |||
120 | static u32 | ||
121 | brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, | ||
122 | struct chip_info *ci, u16 coreid) | ||
123 | { | ||
124 | u8 idx; | ||
125 | |||
126 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
127 | |||
128 | return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT; | ||
129 | } | ||
130 | |||
131 | static bool | ||
132 | brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, | ||
133 | struct chip_info *ci, u16 coreid) | ||
134 | { | ||
135 | u32 regdata; | ||
136 | u8 idx; | ||
137 | |||
138 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
139 | |||
140 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
141 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
142 | regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | | ||
143 | SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); | ||
144 | return (SSB_TMSLOW_CLOCK == regdata); | ||
145 | } | ||
146 | |||
147 | static bool | ||
148 | brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | ||
149 | struct chip_info *ci, u16 coreid) | ||
150 | { | ||
151 | u32 regdata; | ||
152 | u8 idx; | ||
153 | bool ret; | ||
154 | |||
155 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
156 | |||
157 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
158 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
159 | ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; | ||
160 | |||
161 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
162 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
163 | 4); | ||
164 | ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | ||
171 | struct chip_info *ci, u16 coreid) | ||
172 | { | ||
173 | u32 regdata; | ||
174 | u8 idx; | ||
175 | |||
176 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
177 | |||
178 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
179 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
180 | if (regdata & SSB_TMSLOW_RESET) | ||
181 | return; | ||
182 | |||
183 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
184 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
185 | if ((regdata & SSB_TMSLOW_CLOCK) != 0) { | ||
186 | /* | ||
187 | * set target reject and spin until busy is clear | ||
188 | * (preserve core-specific bits) | ||
189 | */ | ||
190 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
191 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
192 | brcmf_sdcard_reg_write(sdiodev, | ||
193 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), | ||
194 | 4, regdata | SSB_TMSLOW_REJECT); | ||
195 | |||
196 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
197 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
198 | udelay(1); | ||
199 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
200 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) & | ||
201 | SSB_TMSHIGH_BUSY), 100000); | ||
202 | |||
203 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
204 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); | ||
205 | if (regdata & SSB_TMSHIGH_BUSY) | ||
206 | brcmf_dbg(ERROR, "core state still busy\n"); | ||
207 | |||
208 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
209 | CORE_SB(ci->c_inf[idx].base, sbidlow), 4); | ||
210 | if (regdata & SSB_IDLOW_INITIATOR) { | ||
211 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
212 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) | | ||
213 | SSB_IMSTATE_REJECT; | ||
214 | brcmf_sdcard_reg_write(sdiodev, | ||
215 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
216 | regdata); | ||
217 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
218 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4); | ||
219 | udelay(1); | ||
220 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
221 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & | ||
222 | SSB_IMSTATE_BUSY), 100000); | ||
223 | } | ||
224 | |||
225 | /* set reset and reject while enabling the clocks */ | ||
226 | brcmf_sdcard_reg_write(sdiodev, | ||
227 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
228 | (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | | ||
229 | SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); | ||
230 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
231 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
232 | udelay(10); | ||
233 | |||
234 | /* clear the initiator reject bit */ | ||
235 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
236 | CORE_SB(ci->c_inf[idx].base, sbidlow), 4); | ||
237 | if (regdata & SSB_IDLOW_INITIATOR) { | ||
238 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
239 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & | ||
240 | ~SSB_IMSTATE_REJECT; | ||
241 | brcmf_sdcard_reg_write(sdiodev, | ||
242 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
243 | regdata); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* leave reset and reject asserted */ | ||
248 | brcmf_sdcard_reg_write(sdiodev, | ||
249 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
250 | (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); | ||
251 | udelay(1); | ||
252 | } | ||
253 | |||
254 | static void | ||
255 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | ||
256 | struct chip_info *ci, u16 coreid) | ||
257 | { | ||
258 | u8 idx; | ||
259 | u32 regdata; | ||
260 | |||
261 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
262 | |||
263 | /* if core is already in reset, just return */ | ||
264 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
265 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
266 | 4); | ||
267 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | ||
268 | return; | ||
269 | |||
270 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
271 | 4, 0); | ||
272 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
273 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
274 | udelay(10); | ||
275 | |||
276 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
277 | 4, BCMA_RESET_CTL_RESET); | ||
278 | udelay(1); | ||
279 | } | ||
280 | |||
281 | static void | ||
282 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | ||
283 | struct chip_info *ci, u16 coreid) | ||
284 | { | ||
285 | u32 regdata; | ||
286 | u8 idx; | ||
287 | |||
288 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
289 | |||
290 | /* | ||
291 | * Must do the disable sequence first to work for | ||
292 | * arbitrary current core state. | ||
293 | */ | ||
294 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid); | ||
295 | |||
296 | /* | ||
297 | * Now do the initialization sequence. | ||
298 | * set reset while enabling the clock and | ||
299 | * forcing them on throughout the core | ||
300 | */ | ||
301 | brcmf_sdcard_reg_write(sdiodev, | ||
302 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
303 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET); | ||
304 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
305 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
306 | udelay(1); | ||
307 | |||
308 | /* clear any serror */ | ||
309 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
310 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); | ||
311 | if (regdata & SSB_TMSHIGH_SERR) | ||
312 | brcmf_sdcard_reg_write(sdiodev, | ||
313 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0); | ||
314 | |||
315 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
316 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4); | ||
317 | if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) | ||
318 | brcmf_sdcard_reg_write(sdiodev, | ||
319 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
320 | regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO)); | ||
321 | |||
322 | /* clear reset and allow it to propagate throughout the core */ | ||
323 | brcmf_sdcard_reg_write(sdiodev, | ||
324 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
325 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK); | ||
326 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
327 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
328 | udelay(1); | ||
329 | |||
330 | /* leave clock enabled */ | ||
331 | brcmf_sdcard_reg_write(sdiodev, | ||
332 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), | ||
333 | 4, SSB_TMSLOW_CLOCK); | ||
334 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
335 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
336 | udelay(1); | ||
337 | } | ||
338 | |||
339 | static void | ||
340 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | ||
341 | struct chip_info *ci, u16 coreid) | ||
342 | { | ||
343 | u8 idx; | ||
344 | u32 regdata; | ||
345 | |||
346 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
347 | |||
348 | /* must disable first to work for arbitrary current core state */ | ||
349 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); | ||
350 | |||
351 | /* now do initialization sequence */ | ||
352 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
353 | 4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); | ||
354 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
355 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
356 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
357 | 4, 0); | ||
358 | udelay(1); | ||
359 | |||
360 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
361 | 4, BCMA_IOCTL_CLK); | ||
362 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
363 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
364 | udelay(1); | ||
365 | } | ||
366 | |||
367 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | ||
368 | struct chip_info *ci, u32 regs) | ||
369 | { | ||
370 | u32 regdata; | ||
371 | |||
372 | /* | ||
373 | * Get CC core rev | ||
374 | * Chipid is assume to be at offset 0 from regs arg | ||
375 | * For different chiptypes or old sdio hosts w/o chipcommon, | ||
376 | * other ways of recognition should be added here. | ||
377 | */ | ||
378 | ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; | ||
379 | ci->c_inf[0].base = regs; | ||
380 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
381 | CORE_CC_REG(ci->c_inf[0].base, chipid), 4); | ||
382 | ci->chip = regdata & CID_ID_MASK; | ||
383 | ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; | ||
384 | ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; | ||
385 | |||
386 | brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); | ||
387 | |||
388 | /* Address of cores for new chips should be added here */ | ||
389 | switch (ci->chip) { | ||
390 | case BCM4329_CHIP_ID: | ||
391 | ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; | ||
392 | ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; | ||
393 | ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; | ||
394 | ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; | ||
395 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; | ||
396 | ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; | ||
397 | ci->ramsize = BCM4329_RAMSIZE; | ||
398 | break; | ||
399 | default: | ||
400 | brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); | ||
401 | return -ENODEV; | ||
402 | } | ||
403 | |||
404 | switch (ci->socitype) { | ||
405 | case SOCI_SB: | ||
406 | ci->iscoreup = brcmf_sdio_sb_iscoreup; | ||
407 | ci->corerev = brcmf_sdio_sb_corerev; | ||
408 | ci->coredisable = brcmf_sdio_sb_coredisable; | ||
409 | ci->resetcore = brcmf_sdio_sb_resetcore; | ||
410 | break; | ||
411 | case SOCI_AI: | ||
412 | ci->iscoreup = brcmf_sdio_ai_iscoreup; | ||
413 | ci->corerev = brcmf_sdio_ai_corerev; | ||
414 | ci->coredisable = brcmf_sdio_ai_coredisable; | ||
415 | ci->resetcore = brcmf_sdio_ai_resetcore; | ||
416 | break; | ||
417 | default: | ||
418 | brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype); | ||
419 | return -ENODEV; | ||
420 | } | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int | ||
426 | brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) | ||
427 | { | ||
428 | int err = 0; | ||
429 | u8 clkval, clkset; | ||
430 | |||
431 | /* Try forcing SDIO core to do ALPAvail request only */ | ||
432 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; | ||
433 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
434 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
435 | if (err) { | ||
436 | brcmf_dbg(ERROR, "error writing for HT off\n"); | ||
437 | return err; | ||
438 | } | ||
439 | |||
440 | /* If register supported, wait for ALPAvail and then force ALP */ | ||
441 | /* This may take up to 15 milliseconds */ | ||
442 | clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, | ||
443 | SBSDIO_FUNC1_CHIPCLKCSR, NULL); | ||
444 | |||
445 | if ((clkval & ~SBSDIO_AVBITS) != clkset) { | ||
446 | brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", | ||
447 | clkset, clkval); | ||
448 | return -EACCES; | ||
449 | } | ||
450 | |||
451 | SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, | ||
452 | SBSDIO_FUNC1_CHIPCLKCSR, NULL)), | ||
453 | !SBSDIO_ALPAV(clkval)), | ||
454 | PMU_MAX_TRANSITION_DLY); | ||
455 | if (!SBSDIO_ALPAV(clkval)) { | ||
456 | brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n", | ||
457 | clkval); | ||
458 | return -EBUSY; | ||
459 | } | ||
460 | |||
461 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; | ||
462 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
463 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
464 | udelay(65); | ||
465 | |||
466 | /* Also, disable the extra SDIO pull-ups */ | ||
467 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
468 | SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static void | ||
474 | brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | ||
475 | struct chip_info *ci) | ||
476 | { | ||
477 | /* get chipcommon rev */ | ||
478 | ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); | ||
479 | |||
480 | /* get chipcommon capabilites */ | ||
481 | ci->c_inf[0].caps = | ||
482 | brcmf_sdcard_reg_read(sdiodev, | ||
483 | CORE_CC_REG(ci->c_inf[0].base, capabilities), 4); | ||
484 | |||
485 | /* get pmu caps & rev */ | ||
486 | if (ci->c_inf[0].caps & CC_CAP_PMU) { | ||
487 | ci->pmucaps = brcmf_sdcard_reg_read(sdiodev, | ||
488 | CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4); | ||
489 | ci->pmurev = ci->pmucaps & PCAP_REV_MASK; | ||
490 | } | ||
491 | |||
492 | ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id); | ||
493 | |||
494 | brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", | ||
495 | ci->c_inf[0].rev, ci->pmurev, | ||
496 | ci->c_inf[1].rev, ci->c_inf[1].id); | ||
497 | |||
498 | /* | ||
499 | * Make sure any on-chip ARM is off (in case strapping is wrong), | ||
500 | * or downloaded code was already running. | ||
501 | */ | ||
502 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); | ||
503 | } | ||
504 | |||
505 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | ||
506 | struct chip_info **ci_ptr, u32 regs) | ||
507 | { | ||
508 | int ret; | ||
509 | struct chip_info *ci; | ||
510 | |||
511 | brcmf_dbg(TRACE, "Enter\n"); | ||
512 | |||
513 | /* alloc chip_info_t */ | ||
514 | ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); | ||
515 | if (!ci) | ||
516 | return -ENOMEM; | ||
517 | |||
518 | ret = brcmf_sdio_chip_buscoreprep(sdiodev); | ||
519 | if (ret != 0) | ||
520 | goto err; | ||
521 | |||
522 | ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs); | ||
523 | if (ret != 0) | ||
524 | goto err; | ||
525 | |||
526 | brcmf_sdio_chip_buscoresetup(sdiodev, ci); | ||
527 | |||
528 | brcmf_sdcard_reg_write(sdiodev, | ||
529 | CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0); | ||
530 | brcmf_sdcard_reg_write(sdiodev, | ||
531 | CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0); | ||
532 | |||
533 | *ci_ptr = ci; | ||
534 | return 0; | ||
535 | |||
536 | err: | ||
537 | kfree(ci); | ||
538 | return ret; | ||
539 | } | ||
540 | |||
541 | void | ||
542 | brcmf_sdio_chip_detach(struct chip_info **ci_ptr) | ||
543 | { | ||
544 | brcmf_dbg(TRACE, "Enter\n"); | ||
545 | |||
546 | kfree(*ci_ptr); | ||
547 | *ci_ptr = NULL; | ||
548 | } | ||
549 | |||
550 | static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len) | ||
551 | { | ||
552 | const char *fmt; | ||
553 | |||
554 | fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; | ||
555 | snprintf(buf, len, fmt, chipid); | ||
556 | return buf; | ||
557 | } | ||
558 | |||
559 | void | ||
560 | brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | ||
561 | struct chip_info *ci, u32 drivestrength) | ||
562 | { | ||
563 | struct sdiod_drive_str *str_tab = NULL; | ||
564 | u32 str_mask = 0; | ||
565 | u32 str_shift = 0; | ||
566 | char chn[8]; | ||
567 | |||
568 | if (!(ci->c_inf[0].caps & CC_CAP_PMU)) | ||
569 | return; | ||
570 | |||
571 | switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { | ||
572 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): | ||
573 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1; | ||
574 | str_mask = 0x30000000; | ||
575 | str_shift = 28; | ||
576 | break; | ||
577 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): | ||
578 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): | ||
579 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2; | ||
580 | str_mask = 0x00003800; | ||
581 | str_shift = 11; | ||
582 | break; | ||
583 | case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): | ||
584 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3; | ||
585 | str_mask = 0x00003800; | ||
586 | str_shift = 11; | ||
587 | break; | ||
588 | default: | ||
589 | brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | ||
590 | brcmf_sdio_chip_name(ci->chip, chn, 8), | ||
591 | ci->chiprev, ci->pmurev); | ||
592 | break; | ||
593 | } | ||
594 | |||
595 | if (str_tab != NULL) { | ||
596 | u32 drivestrength_sel = 0; | ||
597 | u32 cc_data_temp; | ||
598 | int i; | ||
599 | |||
600 | for (i = 0; str_tab[i].strength != 0; i++) { | ||
601 | if (drivestrength >= str_tab[i].strength) { | ||
602 | drivestrength_sel = str_tab[i].sel; | ||
603 | break; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | brcmf_sdcard_reg_write(sdiodev, | ||
608 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), | ||
609 | 4, 1); | ||
610 | cc_data_temp = brcmf_sdcard_reg_read(sdiodev, | ||
611 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4); | ||
612 | cc_data_temp &= ~str_mask; | ||
613 | drivestrength_sel <<= str_shift; | ||
614 | cc_data_temp |= drivestrength_sel; | ||
615 | brcmf_sdcard_reg_write(sdiodev, | ||
616 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), | ||
617 | 4, cc_data_temp); | ||
618 | |||
619 | brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", | ||
620 | drivestrength, cc_data_temp); | ||
621 | } | ||
622 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h new file mode 100644 index 000000000000..ce974d76bd92 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef _BRCMFMAC_SDIO_CHIP_H_ | ||
18 | #define _BRCMFMAC_SDIO_CHIP_H_ | ||
19 | |||
20 | /* | ||
21 | * Core reg address translation. | ||
22 | * Both macro's returns a 32 bits byte address on the backplane bus. | ||
23 | */ | ||
24 | #define CORE_CC_REG(base, field) \ | ||
25 | (base + offsetof(struct chipcregs, field)) | ||
26 | #define CORE_BUS_REG(base, field) \ | ||
27 | (base + offsetof(struct sdpcmd_regs, field)) | ||
28 | #define CORE_SB(base, field) \ | ||
29 | (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) | ||
30 | |||
31 | /* SDIO function 1 register CHIPCLKCSR */ | ||
32 | /* Force ALP request to backplane */ | ||
33 | #define SBSDIO_FORCE_ALP 0x01 | ||
34 | /* Force HT request to backplane */ | ||
35 | #define SBSDIO_FORCE_HT 0x02 | ||
36 | /* Force ILP request to backplane */ | ||
37 | #define SBSDIO_FORCE_ILP 0x04 | ||
38 | /* Make ALP ready (power up xtal) */ | ||
39 | #define SBSDIO_ALP_AVAIL_REQ 0x08 | ||
40 | /* Make HT ready (power up PLL) */ | ||
41 | #define SBSDIO_HT_AVAIL_REQ 0x10 | ||
42 | /* Squelch clock requests from HW */ | ||
43 | #define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 | ||
44 | /* Status: ALP is ready */ | ||
45 | #define SBSDIO_ALP_AVAIL 0x40 | ||
46 | /* Status: HT is ready */ | ||
47 | #define SBSDIO_HT_AVAIL 0x80 | ||
48 | #define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) | ||
49 | #define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) | ||
50 | #define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) | ||
51 | #define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) | ||
52 | #define SBSDIO_CLKAV(regval, alponly) \ | ||
53 | (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) | ||
54 | |||
55 | #define BRCMF_MAX_CORENUM 6 | ||
56 | |||
57 | struct chip_core_info { | ||
58 | u16 id; | ||
59 | u16 rev; | ||
60 | u32 base; | ||
61 | u32 wrapbase; | ||
62 | u32 caps; | ||
63 | u32 cib; | ||
64 | }; | ||
65 | |||
66 | struct chip_info { | ||
67 | u32 chip; | ||
68 | u32 chiprev; | ||
69 | u32 socitype; | ||
70 | /* core info */ | ||
71 | /* always put chipcommon core at 0, bus core at 1 */ | ||
72 | struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; | ||
73 | u32 pmurev; | ||
74 | u32 pmucaps; | ||
75 | u32 ramsize; | ||
76 | |||
77 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
78 | u16 coreid); | ||
79 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
80 | u16 coreid); | ||
81 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, | ||
82 | struct chip_info *ci, u16 coreid); | ||
83 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, | ||
84 | struct chip_info *ci, u16 coreid); | ||
85 | }; | ||
86 | |||
87 | struct sbconfig { | ||
88 | u32 PAD[2]; | ||
89 | u32 sbipsflag; /* initiator port ocp slave flag */ | ||
90 | u32 PAD[3]; | ||
91 | u32 sbtpsflag; /* target port ocp slave flag */ | ||
92 | u32 PAD[11]; | ||
93 | u32 sbtmerrloga; /* (sonics >= 2.3) */ | ||
94 | u32 PAD; | ||
95 | u32 sbtmerrlog; /* (sonics >= 2.3) */ | ||
96 | u32 PAD[3]; | ||
97 | u32 sbadmatch3; /* address match3 */ | ||
98 | u32 PAD; | ||
99 | u32 sbadmatch2; /* address match2 */ | ||
100 | u32 PAD; | ||
101 | u32 sbadmatch1; /* address match1 */ | ||
102 | u32 PAD[7]; | ||
103 | u32 sbimstate; /* initiator agent state */ | ||
104 | u32 sbintvec; /* interrupt mask */ | ||
105 | u32 sbtmstatelow; /* target state */ | ||
106 | u32 sbtmstatehigh; /* target state */ | ||
107 | u32 sbbwa0; /* bandwidth allocation table0 */ | ||
108 | u32 PAD; | ||
109 | u32 sbimconfiglow; /* initiator configuration */ | ||
110 | u32 sbimconfighigh; /* initiator configuration */ | ||
111 | u32 sbadmatch0; /* address match0 */ | ||
112 | u32 PAD; | ||
113 | u32 sbtmconfiglow; /* target configuration */ | ||
114 | u32 sbtmconfighigh; /* target configuration */ | ||
115 | u32 sbbconfig; /* broadcast configuration */ | ||
116 | u32 PAD; | ||
117 | u32 sbbstate; /* broadcast state */ | ||
118 | u32 PAD[3]; | ||
119 | u32 sbactcnfg; /* activate configuration */ | ||
120 | u32 PAD[3]; | ||
121 | u32 sbflagst; /* current sbflags */ | ||
122 | u32 PAD[3]; | ||
123 | u32 sbidlow; /* identification */ | ||
124 | u32 sbidhigh; /* identification */ | ||
125 | }; | ||
126 | |||
127 | extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | ||
128 | struct chip_info **ci_ptr, u32 regs); | ||
129 | extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); | ||
130 | extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | ||
131 | struct chip_info *ci, | ||
132 | u32 drivestrength); | ||
133 | extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); | ||
134 | |||
135 | |||
136 | #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 5eddabe5228a..cc19a733ac65 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1997,7 +1997,7 @@ done: | |||
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | 1999 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, |
2000 | struct brcmf_bss_info *bi) | 2000 | struct brcmf_bss_info_le *bi) |
2001 | { | 2001 | { |
2002 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); | 2002 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); |
2003 | struct ieee80211_channel *notify_channel; | 2003 | struct ieee80211_channel *notify_channel; |
@@ -2049,18 +2049,27 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2049 | notify_timestamp, notify_capability, notify_interval, notify_ie, | 2049 | notify_timestamp, notify_capability, notify_interval, notify_ie, |
2050 | notify_ielen, notify_signal, GFP_KERNEL); | 2050 | notify_ielen, notify_signal, GFP_KERNEL); |
2051 | 2051 | ||
2052 | if (!bss) { | 2052 | if (!bss) |
2053 | WL_ERR("cfg80211_inform_bss_frame error\n"); | 2053 | return -ENOMEM; |
2054 | return -EINVAL; | 2054 | |
2055 | } | 2055 | cfg80211_put_bss(bss); |
2056 | 2056 | ||
2057 | return err; | 2057 | return err; |
2058 | } | 2058 | } |
2059 | 2059 | ||
2060 | static struct brcmf_bss_info_le * | ||
2061 | next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss) | ||
2062 | { | ||
2063 | if (bss == NULL) | ||
2064 | return list->bss_info_le; | ||
2065 | return (struct brcmf_bss_info_le *)((unsigned long)bss + | ||
2066 | le32_to_cpu(bss->length)); | ||
2067 | } | ||
2068 | |||
2060 | static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) | 2069 | static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) |
2061 | { | 2070 | { |
2062 | struct brcmf_scan_results *bss_list; | 2071 | struct brcmf_scan_results *bss_list; |
2063 | struct brcmf_bss_info *bi = NULL; /* must be initialized */ | 2072 | struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ |
2064 | s32 err = 0; | 2073 | s32 err = 0; |
2065 | int i; | 2074 | int i; |
2066 | 2075 | ||
@@ -2072,7 +2081,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) | |||
2072 | } | 2081 | } |
2073 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); | 2082 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); |
2074 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { | 2083 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { |
2075 | bi = next_bss(bss_list, bi); | 2084 | bi = next_bss_le(bss_list, bi); |
2076 | err = brcmf_inform_single_bss(cfg_priv, bi); | 2085 | err = brcmf_inform_single_bss(cfg_priv, bi); |
2077 | if (err) | 2086 | if (err) |
2078 | break; | 2087 | break; |
@@ -2085,8 +2094,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2085 | { | 2094 | { |
2086 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); | 2095 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); |
2087 | struct ieee80211_channel *notify_channel; | 2096 | struct ieee80211_channel *notify_channel; |
2088 | struct brcmf_bss_info *bi = NULL; | 2097 | struct brcmf_bss_info_le *bi = NULL; |
2089 | struct ieee80211_supported_band *band; | 2098 | struct ieee80211_supported_band *band; |
2099 | struct cfg80211_bss *bss; | ||
2090 | u8 *buf = NULL; | 2100 | u8 *buf = NULL; |
2091 | s32 err = 0; | 2101 | s32 err = 0; |
2092 | u16 channel; | 2102 | u16 channel; |
@@ -2114,7 +2124,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2114 | goto CleanUp; | 2124 | goto CleanUp; |
2115 | } | 2125 | } |
2116 | 2126 | ||
2117 | bi = (struct brcmf_bss_info *)(buf + 4); | 2127 | bi = (struct brcmf_bss_info_le *)(buf + 4); |
2118 | 2128 | ||
2119 | channel = bi->ctl_ch ? bi->ctl_ch : | 2129 | channel = bi->ctl_ch ? bi->ctl_ch : |
2120 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 2130 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); |
@@ -2140,10 +2150,17 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2140 | WL_CONN("signal: %d\n", notify_signal); | 2150 | WL_CONN("signal: %d\n", notify_signal); |
2141 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); | 2151 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); |
2142 | 2152 | ||
2143 | cfg80211_inform_bss(wiphy, notify_channel, bssid, | 2153 | bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, |
2144 | notify_timestamp, notify_capability, notify_interval, | 2154 | notify_timestamp, notify_capability, notify_interval, |
2145 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); | 2155 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); |
2146 | 2156 | ||
2157 | if (!bss) { | ||
2158 | err = -ENOMEM; | ||
2159 | goto CleanUp; | ||
2160 | } | ||
2161 | |||
2162 | cfg80211_put_bss(bss); | ||
2163 | |||
2147 | CleanUp: | 2164 | CleanUp: |
2148 | 2165 | ||
2149 | kfree(buf); | 2166 | kfree(buf); |
@@ -2188,7 +2205,7 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key) | |||
2188 | 2205 | ||
2189 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) | 2206 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) |
2190 | { | 2207 | { |
2191 | struct brcmf_bss_info *bi; | 2208 | struct brcmf_bss_info_le *bi; |
2192 | struct brcmf_ssid *ssid; | 2209 | struct brcmf_ssid *ssid; |
2193 | struct brcmf_tlv *tim; | 2210 | struct brcmf_tlv *tim; |
2194 | u16 beacon_interval; | 2211 | u16 beacon_interval; |
@@ -2211,7 +2228,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) | |||
2211 | goto update_bss_info_out; | 2228 | goto update_bss_info_out; |
2212 | } | 2229 | } |
2213 | 2230 | ||
2214 | bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4); | 2231 | bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); |
2215 | err = brcmf_inform_single_bss(cfg_priv, bi); | 2232 | err = brcmf_inform_single_bss(cfg_priv, bi); |
2216 | if (err) | 2233 | if (err) |
2217 | goto update_bss_info_out; | 2234 | goto update_bss_info_out; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 62dc46144ede..a613b49cb13f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -352,15 +352,6 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) | |||
352 | return &cfg->conn_info; | 352 | return &cfg->conn_info; |
353 | } | 353 | } |
354 | 354 | ||
355 | static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list, | ||
356 | struct brcmf_bss_info *bss) | ||
357 | { | ||
358 | return bss = bss ? | ||
359 | (struct brcmf_bss_info *)((unsigned long)bss + | ||
360 | le32_to_cpu(bss->length)) : | ||
361 | list->bss_info; | ||
362 | } | ||
363 | |||
364 | extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, | 355 | extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, |
365 | struct device *busdev, | 356 | struct device *busdev, |
366 | void *data); | 357 | void *data); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index 106a7424a7cd..b51d1e421e24 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h | |||
@@ -38,88 +38,12 @@ | |||
38 | /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ | 38 | /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ |
39 | #define SI_PCIE_DMA_H32 0x80000000 | 39 | #define SI_PCIE_DMA_H32 0x80000000 |
40 | 40 | ||
41 | /* core codes */ | ||
42 | #define NODEV_CORE_ID 0x700 /* Invalid coreid */ | ||
43 | #define CC_CORE_ID 0x800 /* chipcommon core */ | ||
44 | #define ILINE20_CORE_ID 0x801 /* iline20 core */ | ||
45 | #define SRAM_CORE_ID 0x802 /* sram core */ | ||
46 | #define SDRAM_CORE_ID 0x803 /* sdram core */ | ||
47 | #define PCI_CORE_ID 0x804 /* pci core */ | ||
48 | #define MIPS_CORE_ID 0x805 /* mips core */ | ||
49 | #define ENET_CORE_ID 0x806 /* enet mac core */ | ||
50 | #define CODEC_CORE_ID 0x807 /* v90 codec core */ | ||
51 | #define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ | ||
52 | #define ADSL_CORE_ID 0x809 /* ADSL core */ | ||
53 | #define ILINE100_CORE_ID 0x80a /* iline100 core */ | ||
54 | #define IPSEC_CORE_ID 0x80b /* ipsec core */ | ||
55 | #define UTOPIA_CORE_ID 0x80c /* utopia core */ | ||
56 | #define PCMCIA_CORE_ID 0x80d /* pcmcia core */ | ||
57 | #define SOCRAM_CORE_ID 0x80e /* internal memory core */ | ||
58 | #define MEMC_CORE_ID 0x80f /* memc sdram core */ | ||
59 | #define OFDM_CORE_ID 0x810 /* OFDM phy core */ | ||
60 | #define EXTIF_CORE_ID 0x811 /* external interface core */ | ||
61 | #define D11_CORE_ID 0x812 /* 802.11 MAC core */ | ||
62 | #define APHY_CORE_ID 0x813 /* 802.11a phy core */ | ||
63 | #define BPHY_CORE_ID 0x814 /* 802.11b phy core */ | ||
64 | #define GPHY_CORE_ID 0x815 /* 802.11g phy core */ | ||
65 | #define MIPS33_CORE_ID 0x816 /* mips3302 core */ | ||
66 | #define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ | ||
67 | #define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ | ||
68 | #define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ | ||
69 | #define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ | ||
70 | #define SDIOH_CORE_ID 0x81b /* sdio host core */ | ||
71 | #define ROBO_CORE_ID 0x81c /* roboswitch core */ | ||
72 | #define ATA100_CORE_ID 0x81d /* parallel ATA core */ | ||
73 | #define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ | ||
74 | #define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ | ||
75 | #define PCIE_CORE_ID 0x820 /* pci express core */ | ||
76 | #define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ | ||
77 | #define SRAMC_CORE_ID 0x822 /* SRAM controller core */ | ||
78 | #define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ | ||
79 | #define ARM11_CORE_ID 0x824 /* ARM 1176 core */ | ||
80 | #define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ | ||
81 | #define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ | ||
82 | #define PMU_CORE_ID 0x827 /* PMU core */ | ||
83 | #define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ | ||
84 | #define SDIOD_CORE_ID 0x829 /* SDIO device core */ | ||
85 | #define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ | ||
86 | #define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ | ||
87 | #define MIPS74K_CORE_ID 0x82c /* mips 74k core */ | ||
88 | #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ | ||
89 | #define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ | ||
90 | #define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ | ||
91 | #define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ | ||
92 | #define SC_CORE_ID 0x831 /* shared common core */ | ||
93 | #define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ | ||
94 | #define SPIH_CORE_ID 0x833 /* SPI host core */ | ||
95 | #define I2S_CORE_ID 0x834 /* I2S core */ | ||
96 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ | ||
97 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ | ||
98 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ | ||
99 | #define DEF_AI_COMP 0xfff /* Default component, in ai chips it | ||
100 | * maps all unused address ranges | ||
101 | */ | ||
102 | |||
103 | /* chipcommon being the first core: */ | 41 | /* chipcommon being the first core: */ |
104 | #define SI_CC_IDX 0 | 42 | #define SI_CC_IDX 0 |
105 | 43 | ||
106 | /* SOC Interconnect types (aka chip types) */ | 44 | /* SOC Interconnect types (aka chip types) */ |
107 | #define SOCI_AI 1 | 45 | #define SOCI_AI 1 |
108 | 46 | ||
109 | /* Common core control flags */ | ||
110 | #define SICF_BIST_EN 0x8000 | ||
111 | #define SICF_PME_EN 0x4000 | ||
112 | #define SICF_CORE_BITS 0x3ffc | ||
113 | #define SICF_FGC 0x0002 | ||
114 | #define SICF_CLOCK_EN 0x0001 | ||
115 | |||
116 | /* Common core status flags */ | ||
117 | #define SISF_BIST_DONE 0x8000 | ||
118 | #define SISF_BIST_ERROR 0x4000 | ||
119 | #define SISF_GATED_CLK 0x2000 | ||
120 | #define SISF_DMA64 0x1000 | ||
121 | #define SISF_CORE_BITS 0x0fff | ||
122 | |||
123 | /* A register that is common to all cores to | 47 | /* A register that is common to all cores to |
124 | * communicate w/PMU regarding clock control. | 48 | * communicate w/PMU regarding clock control. |
125 | */ | 49 | */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 7f27dbdb6b60..43f7a724dda8 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -649,7 +649,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | |||
649 | len = roundup(len, 4); | 649 | len = roundup(len, 4); |
650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); | 650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); |
651 | 651 | ||
652 | dma_len += (u16) brcmu_pkttotlen(p); | 652 | dma_len += (u16) p->len; |
653 | 653 | ||
654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" | 654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" |
655 | " seg_cnt %d null delim %d\n", | 655 | " seg_cnt %d null delim %d\n", |
@@ -741,9 +741,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | |||
741 | if (p) { | 741 | if (p) { |
742 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | 742 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && |
743 | ((u8) (p->priority) == tid)) { | 743 | ((u8) (p->priority) == tid)) { |
744 | 744 | plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; | |
745 | plen = brcmu_pkttotlen(p) + | ||
746 | AMPDU_MAX_MPDU_OVERHEAD; | ||
747 | plen = max(scb_ampdu->min_len, plen); | 745 | plen = max(scb_ampdu->min_len, plen); |
748 | 746 | ||
749 | if ((plen + ampdu_len) > max_ampdu_bytes) { | 747 | if ((plen + ampdu_len) > max_ampdu_bytes) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 89ad1b7dab8f..55e9f45fce22 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -1153,121 +1153,6 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
1153 | &txpwr); | 1153 | &txpwr); |
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | #ifdef POWER_DBG | ||
1157 | static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr) | ||
1158 | { | ||
1159 | int i; | ||
1160 | char buf[80]; | ||
1161 | char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; | ||
1162 | |||
1163 | sprintf(buf, "CCK "); | ||
1164 | for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) | ||
1165 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1166 | txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1167 | fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1168 | printk(KERN_DEBUG "%s\n", buf); | ||
1169 | |||
1170 | sprintf(buf, "20 MHz OFDM SISO "); | ||
1171 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1172 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1173 | txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1174 | fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1175 | printk(KERN_DEBUG "%s\n", buf); | ||
1176 | |||
1177 | sprintf(buf, "20 MHz OFDM CDD "); | ||
1178 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1179 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1180 | txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1181 | fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1182 | printk(KERN_DEBUG "%s\n", buf); | ||
1183 | |||
1184 | sprintf(buf, "40 MHz OFDM SISO "); | ||
1185 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1186 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1187 | txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1188 | fraction[txpwr->ofdm_40_siso[i] % | ||
1189 | BRCMS_TXPWR_DB_FACTOR]); | ||
1190 | printk(KERN_DEBUG "%s\n", buf); | ||
1191 | |||
1192 | sprintf(buf, "40 MHz OFDM CDD "); | ||
1193 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1194 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1195 | txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1196 | fraction[txpwr->ofdm_40_cdd[i] % | ||
1197 | BRCMS_TXPWR_DB_FACTOR]); | ||
1198 | printk(KERN_DEBUG "%s\n", buf); | ||
1199 | |||
1200 | sprintf(buf, "20 MHz MCS0-7 SISO "); | ||
1201 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1202 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1203 | txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1204 | fraction[txpwr->mcs_20_siso[i] % | ||
1205 | BRCMS_TXPWR_DB_FACTOR]); | ||
1206 | printk(KERN_DEBUG "%s\n", buf); | ||
1207 | |||
1208 | sprintf(buf, "20 MHz MCS0-7 CDD "); | ||
1209 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1210 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1211 | txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1212 | fraction[txpwr->mcs_20_cdd[i] % | ||
1213 | BRCMS_TXPWR_DB_FACTOR]); | ||
1214 | printk(KERN_DEBUG "%s\n", buf); | ||
1215 | |||
1216 | sprintf(buf, "20 MHz MCS0-7 STBC "); | ||
1217 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1218 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1219 | txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1220 | fraction[txpwr->mcs_20_stbc[i] % | ||
1221 | BRCMS_TXPWR_DB_FACTOR]); | ||
1222 | printk(KERN_DEBUG "%s\n", buf); | ||
1223 | |||
1224 | sprintf(buf, "20 MHz MCS8-15 SDM "); | ||
1225 | for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) | ||
1226 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1227 | txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1228 | fraction[txpwr->mcs_20_mimo[i] % | ||
1229 | BRCMS_TXPWR_DB_FACTOR]); | ||
1230 | printk(KERN_DEBUG "%s\n", buf); | ||
1231 | |||
1232 | sprintf(buf, "40 MHz MCS0-7 SISO "); | ||
1233 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1234 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1235 | txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1236 | fraction[txpwr->mcs_40_siso[i] % | ||
1237 | BRCMS_TXPWR_DB_FACTOR]); | ||
1238 | printk(KERN_DEBUG "%s\n", buf); | ||
1239 | |||
1240 | sprintf(buf, "40 MHz MCS0-7 CDD "); | ||
1241 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1242 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1243 | txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1244 | fraction[txpwr->mcs_40_cdd[i] % | ||
1245 | BRCMS_TXPWR_DB_FACTOR]); | ||
1246 | printk(KERN_DEBUG "%s\n", buf); | ||
1247 | |||
1248 | sprintf(buf, "40 MHz MCS0-7 STBC "); | ||
1249 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1250 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1251 | txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1252 | fraction[txpwr->mcs_40_stbc[i] % | ||
1253 | BRCMS_TXPWR_DB_FACTOR]); | ||
1254 | printk(KERN_DEBUG "%s\n", buf); | ||
1255 | |||
1256 | sprintf(buf, "40 MHz MCS8-15 SDM "); | ||
1257 | for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) | ||
1258 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1259 | txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1260 | fraction[txpwr->mcs_40_mimo[i] % | ||
1261 | BRCMS_TXPWR_DB_FACTOR]); | ||
1262 | } | ||
1263 | printk(KERN_DEBUG "%s\n", buf); | ||
1264 | |||
1265 | printk(KERN_DEBUG "MCS32 %2d%s\n", | ||
1266 | txpwr->mcs32 / BRCMS_TXPWR_DB_FACTOR, | ||
1267 | fraction[txpwr->mcs32 % BRCMS_TXPWR_DB_FACTOR]); | ||
1268 | } | ||
1269 | #endif /* POWER_DBG */ | ||
1270 | |||
1271 | void | 1156 | void |
1272 | brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, | 1157 | brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, |
1273 | struct txpwr_limits *txpwr) | 1158 | struct txpwr_limits *txpwr) |
@@ -1478,9 +1363,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
1478 | txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; | 1363 | txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; |
1479 | } | 1364 | } |
1480 | 1365 | ||
1481 | #ifdef POWER_DBG | ||
1482 | wlc_phy_txpower_limits_dump(txpwr); | ||
1483 | #endif | ||
1484 | return; | 1366 | return; |
1485 | } | 1367 | } |
1486 | 1368 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index b56a30297c26..e286fb4d4813 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | 19 | ||
@@ -22,6 +21,7 @@ | |||
22 | #include <aiutils.h> | 21 | #include <aiutils.h> |
23 | #include "types.h" | 22 | #include "types.h" |
24 | #include "dma.h" | 23 | #include "dma.h" |
24 | #include "soc.h" | ||
25 | 25 | ||
26 | /* | 26 | /* |
27 | * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within | 27 | * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within |
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t) | |||
358 | 358 | ||
359 | static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) | 359 | static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) |
360 | { | 360 | { |
361 | uint dmactrlflags = di->dma.dmactrlflags; | 361 | uint dmactrlflags; |
362 | 362 | ||
363 | if (di == NULL) { | 363 | if (di == NULL) { |
364 | DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); | 364 | DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n")); |
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | dmactrlflags = di->dma.dmactrlflags; | ||
368 | dmactrlflags &= ~mask; | 369 | dmactrlflags &= ~mask; |
369 | dmactrlflags |= flags; | 370 | dmactrlflags |= flags; |
370 | 371 | ||
@@ -900,7 +901,7 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) | |||
900 | 901 | ||
901 | /* | 902 | /* |
902 | * !! rx entry routine | 903 | * !! rx entry routine |
903 | * returns a pointer to the next frame received, or NULL if there are no more | 904 | * returns the number packages in the next frame, or 0 if there are no more |
904 | * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is | 905 | * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is |
905 | * supported with pkts chain | 906 | * supported with pkts chain |
906 | * otherwise, it's treated as giant pkt and will be tossed. | 907 | * otherwise, it's treated as giant pkt and will be tossed. |
@@ -908,38 +909,40 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) | |||
908 | * buffer data. After it reaches the max size of buffer, the data continues | 909 | * buffer data. After it reaches the max size of buffer, the data continues |
909 | * in next DMA descriptor buffer WITHOUT DMA header | 910 | * in next DMA descriptor buffer WITHOUT DMA header |
910 | */ | 911 | */ |
911 | struct sk_buff *dma_rx(struct dma_pub *pub) | 912 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) |
912 | { | 913 | { |
913 | struct dma_info *di = (struct dma_info *)pub; | 914 | struct dma_info *di = (struct dma_info *)pub; |
914 | struct sk_buff *p, *head, *tail; | 915 | struct sk_buff_head dma_frames; |
916 | struct sk_buff *p, *next; | ||
915 | uint len; | 917 | uint len; |
916 | uint pkt_len; | 918 | uint pkt_len; |
917 | int resid = 0; | 919 | int resid = 0; |
920 | int pktcnt = 1; | ||
918 | 921 | ||
922 | skb_queue_head_init(&dma_frames); | ||
919 | next_frame: | 923 | next_frame: |
920 | head = _dma_getnextrxp(di, false); | 924 | p = _dma_getnextrxp(di, false); |
921 | if (head == NULL) | 925 | if (p == NULL) |
922 | return NULL; | 926 | return 0; |
923 | 927 | ||
924 | len = le16_to_cpu(*(__le16 *) (head->data)); | 928 | len = le16_to_cpu(*(__le16 *) (p->data)); |
925 | DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); | 929 | DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); |
926 | dma_spin_for_len(len, head); | 930 | dma_spin_for_len(len, p); |
927 | 931 | ||
928 | /* set actual length */ | 932 | /* set actual length */ |
929 | pkt_len = min((di->rxoffset + len), di->rxbufsize); | 933 | pkt_len = min((di->rxoffset + len), di->rxbufsize); |
930 | __skb_trim(head, pkt_len); | 934 | __skb_trim(p, pkt_len); |
935 | skb_queue_tail(&dma_frames, p); | ||
931 | resid = len - (di->rxbufsize - di->rxoffset); | 936 | resid = len - (di->rxbufsize - di->rxoffset); |
932 | 937 | ||
933 | /* check for single or multi-buffer rx */ | 938 | /* check for single or multi-buffer rx */ |
934 | if (resid > 0) { | 939 | if (resid > 0) { |
935 | tail = head; | ||
936 | while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { | 940 | while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { |
937 | tail->next = p; | ||
938 | pkt_len = min_t(uint, resid, di->rxbufsize); | 941 | pkt_len = min_t(uint, resid, di->rxbufsize); |
939 | __skb_trim(p, pkt_len); | 942 | __skb_trim(p, pkt_len); |
940 | 943 | skb_queue_tail(&dma_frames, p); | |
941 | tail = p; | ||
942 | resid -= di->rxbufsize; | 944 | resid -= di->rxbufsize; |
945 | pktcnt++; | ||
943 | } | 946 | } |
944 | 947 | ||
945 | #ifdef BCMDBG | 948 | #ifdef BCMDBG |
@@ -958,13 +961,18 @@ struct sk_buff *dma_rx(struct dma_pub *pub) | |||
958 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { | 961 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { |
959 | DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", | 962 | DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", |
960 | di->name, len)); | 963 | di->name, len)); |
961 | brcmu_pkt_buf_free_skb(head); | 964 | skb_queue_walk_safe(&dma_frames, p, next) { |
965 | skb_unlink(p, &dma_frames); | ||
966 | brcmu_pkt_buf_free_skb(p); | ||
967 | } | ||
962 | di->dma.rxgiants++; | 968 | di->dma.rxgiants++; |
969 | pktcnt = 1; | ||
963 | goto next_frame; | 970 | goto next_frame; |
964 | } | 971 | } |
965 | } | 972 | } |
966 | 973 | ||
967 | return head; | 974 | skb_queue_splice_tail(&dma_frames, skb_list); |
975 | return pktcnt; | ||
968 | } | 976 | } |
969 | 977 | ||
970 | static bool dma64_rxidle(struct dma_info *di) | 978 | static bool dma64_rxidle(struct dma_info *di) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h index ebc5bc546f3b..d317c7c12f91 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define _BRCM_DMA_H_ | 18 | #define _BRCM_DMA_H_ |
19 | 19 | ||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/skbuff.h> | ||
21 | #include "types.h" /* forward structure declarations */ | 22 | #include "types.h" /* forward structure declarations */ |
22 | 23 | ||
23 | /* map/unmap direction */ | 24 | /* map/unmap direction */ |
@@ -80,7 +81,7 @@ extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
80 | uint nrxpost, uint rxoffset, uint *msg_level); | 81 | uint nrxpost, uint rxoffset, uint *msg_level); |
81 | 82 | ||
82 | void dma_rxinit(struct dma_pub *pub); | 83 | void dma_rxinit(struct dma_pub *pub); |
83 | struct sk_buff *dma_rx(struct dma_pub *pub); | 84 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); |
84 | bool dma_rxfill(struct dma_pub *pub); | 85 | bool dma_rxfill(struct dma_pub *pub); |
85 | bool dma_rxreset(struct dma_pub *pub); | 86 | bool dma_rxreset(struct dma_pub *pub); |
86 | bool dma_txreset(struct dma_pub *pub); | 87 | bool dma_txreset(struct dma_pub *pub); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 0d8a9cdf897a..8457e969eb4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -216,8 +216,7 @@ static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = { | |||
216 | .ht_cap = { | 216 | .ht_cap = { |
217 | /* from include/linux/ieee80211.h */ | 217 | /* from include/linux/ieee80211.h */ |
218 | .cap = IEEE80211_HT_CAP_GRN_FLD | | 218 | .cap = IEEE80211_HT_CAP_GRN_FLD | |
219 | IEEE80211_HT_CAP_SGI_20 | | 219 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40, |
220 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, | ||
221 | .ht_supported = true, | 220 | .ht_supported = true, |
222 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, | 221 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, |
223 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, | 222 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, |
@@ -238,8 +237,7 @@ static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = { | |||
238 | BRCMS_LEGACY_5G_RATE_OFFSET, | 237 | BRCMS_LEGACY_5G_RATE_OFFSET, |
239 | .ht_cap = { | 238 | .ht_cap = { |
240 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | | 239 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | |
241 | IEEE80211_HT_CAP_SGI_40 | | 240 | IEEE80211_HT_CAP_SGI_40, |
242 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ | ||
243 | .ht_supported = true, | 241 | .ht_supported = true, |
244 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, | 242 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, |
245 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, | 243 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, |
@@ -287,6 +285,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
287 | { | 285 | { |
288 | struct brcms_info *wl = hw->priv; | 286 | struct brcms_info *wl = hw->priv; |
289 | bool blocked; | 287 | bool blocked; |
288 | int err; | ||
290 | 289 | ||
291 | ieee80211_wake_queues(hw); | 290 | ieee80211_wake_queues(hw); |
292 | spin_lock_bh(&wl->lock); | 291 | spin_lock_bh(&wl->lock); |
@@ -295,57 +294,69 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
295 | if (!blocked) | 294 | if (!blocked) |
296 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 295 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
297 | 296 | ||
298 | return 0; | 297 | spin_lock_bh(&wl->lock); |
298 | /* avoid acknowledging frames before a non-monitor device is added */ | ||
299 | wl->mute_tx = true; | ||
300 | |||
301 | if (!wl->pub->up) | ||
302 | err = brcms_up(wl); | ||
303 | else | ||
304 | err = -ENODEV; | ||
305 | spin_unlock_bh(&wl->lock); | ||
306 | |||
307 | if (err != 0) | ||
308 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
309 | err); | ||
310 | return err; | ||
299 | } | 311 | } |
300 | 312 | ||
301 | static void brcms_ops_stop(struct ieee80211_hw *hw) | 313 | static void brcms_ops_stop(struct ieee80211_hw *hw) |
302 | { | 314 | { |
315 | struct brcms_info *wl = hw->priv; | ||
316 | int status; | ||
317 | |||
303 | ieee80211_stop_queues(hw); | 318 | ieee80211_stop_queues(hw); |
319 | |||
320 | if (wl->wlc == NULL) | ||
321 | return; | ||
322 | |||
323 | spin_lock_bh(&wl->lock); | ||
324 | status = brcms_c_chipmatch(wl->wlc->hw->vendorid, | ||
325 | wl->wlc->hw->deviceid); | ||
326 | spin_unlock_bh(&wl->lock); | ||
327 | if (!status) { | ||
328 | wiphy_err(wl->wiphy, | ||
329 | "wl: brcms_ops_stop: chipmatch failed\n"); | ||
330 | return; | ||
331 | } | ||
332 | |||
333 | /* put driver in down state */ | ||
334 | spin_lock_bh(&wl->lock); | ||
335 | brcms_down(wl); | ||
336 | spin_unlock_bh(&wl->lock); | ||
304 | } | 337 | } |
305 | 338 | ||
306 | static int | 339 | static int |
307 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 340 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
308 | { | 341 | { |
309 | struct brcms_info *wl; | 342 | struct brcms_info *wl = hw->priv; |
310 | int err; | ||
311 | 343 | ||
312 | /* Just STA for now */ | 344 | /* Just STA for now */ |
313 | if (vif->type != NL80211_IFTYPE_AP && | 345 | if (vif->type != NL80211_IFTYPE_STATION) { |
314 | vif->type != NL80211_IFTYPE_MESH_POINT && | ||
315 | vif->type != NL80211_IFTYPE_STATION && | ||
316 | vif->type != NL80211_IFTYPE_WDS && | ||
317 | vif->type != NL80211_IFTYPE_ADHOC) { | ||
318 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" | 346 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" |
319 | " STA for now\n", __func__, vif->type); | 347 | " STA for now\n", __func__, vif->type); |
320 | return -EOPNOTSUPP; | 348 | return -EOPNOTSUPP; |
321 | } | 349 | } |
322 | 350 | ||
323 | wl = hw->priv; | 351 | wl->mute_tx = false; |
324 | spin_lock_bh(&wl->lock); | 352 | brcms_c_mute(wl->wlc, false); |
325 | if (!wl->pub->up) | ||
326 | err = brcms_up(wl); | ||
327 | else | ||
328 | err = -ENODEV; | ||
329 | spin_unlock_bh(&wl->lock); | ||
330 | |||
331 | if (err != 0) | ||
332 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
333 | err); | ||
334 | 353 | ||
335 | return err; | 354 | return 0; |
336 | } | 355 | } |
337 | 356 | ||
338 | static void | 357 | static void |
339 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 358 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
340 | { | 359 | { |
341 | struct brcms_info *wl; | ||
342 | |||
343 | wl = hw->priv; | ||
344 | |||
345 | /* put driver in down state */ | ||
346 | spin_lock_bh(&wl->lock); | ||
347 | brcms_down(wl); | ||
348 | spin_unlock_bh(&wl->lock); | ||
349 | } | 360 | } |
350 | 361 | ||
351 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | 362 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) |
@@ -609,13 +620,6 @@ brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
609 | wl->pub->global_ampdu->scb = scb; | 620 | wl->pub->global_ampdu->scb = scb; |
610 | wl->pub->global_ampdu->max_pdu = 16; | 621 | wl->pub->global_ampdu->max_pdu = 16; |
611 | 622 | ||
612 | sta->ht_cap.ht_supported = true; | ||
613 | sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
614 | sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; | ||
615 | sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | | ||
616 | IEEE80211_HT_CAP_SGI_20 | | ||
617 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; | ||
618 | |||
619 | /* | 623 | /* |
620 | * minstrel_ht initiates addBA on our behalf by calling | 624 | * minstrel_ht initiates addBA on our behalf by calling |
621 | * ieee80211_start_tx_ba_session() | 625 | * ieee80211_start_tx_ba_session() |
@@ -877,37 +881,18 @@ static void brcms_free(struct brcms_info *wl) | |||
877 | } | 881 | } |
878 | 882 | ||
879 | /* | 883 | /* |
880 | * called from both kernel as from this kernel module. | 884 | * called from both kernel as from this kernel module (error flow on attach) |
881 | * precondition: perimeter lock is not acquired. | 885 | * precondition: perimeter lock is not acquired. |
882 | */ | 886 | */ |
883 | static void brcms_remove(struct pci_dev *pdev) | 887 | static void brcms_remove(struct pci_dev *pdev) |
884 | { | 888 | { |
885 | struct brcms_info *wl; | 889 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
886 | struct ieee80211_hw *hw; | 890 | struct brcms_info *wl = hw->priv; |
887 | int status; | ||
888 | |||
889 | hw = pci_get_drvdata(pdev); | ||
890 | wl = hw->priv; | ||
891 | if (!wl) { | ||
892 | pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); | ||
893 | return; | ||
894 | } | ||
895 | 891 | ||
896 | spin_lock_bh(&wl->lock); | ||
897 | status = brcms_c_chipmatch(pdev->vendor, pdev->device); | ||
898 | spin_unlock_bh(&wl->lock); | ||
899 | if (!status) { | ||
900 | wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch " | ||
901 | "failed\n"); | ||
902 | return; | ||
903 | } | ||
904 | if (wl->wlc) { | 892 | if (wl->wlc) { |
905 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | 893 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); |
906 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 894 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
907 | ieee80211_unregister_hw(hw); | 895 | ieee80211_unregister_hw(hw); |
908 | spin_lock_bh(&wl->lock); | ||
909 | brcms_down(wl); | ||
910 | spin_unlock_bh(&wl->lock); | ||
911 | } | 896 | } |
912 | pci_disable_device(pdev); | 897 | pci_disable_device(pdev); |
913 | 898 | ||
@@ -1081,9 +1066,6 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, | |||
1081 | 1066 | ||
1082 | wl->pub->ieee_hw = hw; | 1067 | wl->pub->ieee_hw = hw; |
1083 | 1068 | ||
1084 | /* disable mpc */ | ||
1085 | brcms_c_set_radio_mpc(wl->wlc, false); | ||
1086 | |||
1087 | /* register our interrupt handler */ | 1069 | /* register our interrupt handler */ |
1088 | if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { | 1070 | if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { |
1089 | wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); | 1071 | wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); |
@@ -1319,8 +1301,7 @@ void brcms_init(struct brcms_info *wl) | |||
1319 | { | 1301 | { |
1320 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1302 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); |
1321 | brcms_reset(wl); | 1303 | brcms_reset(wl); |
1322 | 1304 | brcms_c_init(wl->wlc, wl->mute_tx); | |
1323 | brcms_c_init(wl->wlc); | ||
1324 | } | 1305 | } |
1325 | 1306 | ||
1326 | /* | 1307 | /* |
@@ -1337,6 +1318,14 @@ uint brcms_reset(struct brcms_info *wl) | |||
1337 | return 0; | 1318 | return 0; |
1338 | } | 1319 | } |
1339 | 1320 | ||
1321 | void brcms_fatal_error(struct brcms_info *wl) | ||
1322 | { | ||
1323 | wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", | ||
1324 | wl->wlc->pub->unit); | ||
1325 | brcms_reset(wl); | ||
1326 | ieee80211_restart_hw(wl->pub->ieee_hw); | ||
1327 | } | ||
1328 | |||
1340 | /* | 1329 | /* |
1341 | * These are interrupt on/off entry points. Disable interrupts | 1330 | * These are interrupt on/off entry points. Disable interrupts |
1342 | * during interrupt state transition. | 1331 | * during interrupt state transition. |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 177f0e44e4b6..6242f188b717 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h | |||
@@ -80,6 +80,7 @@ struct brcms_info { | |||
80 | struct brcms_firmware fw; | 80 | struct brcms_firmware fw; |
81 | struct wiphy *wiphy; | 81 | struct wiphy *wiphy; |
82 | struct brcms_ucode ucode; | 82 | struct brcms_ucode ucode; |
83 | bool mute_tx; | ||
83 | }; | 84 | }; |
84 | 85 | ||
85 | /* misc callbacks */ | 86 | /* misc callbacks */ |
@@ -104,5 +105,6 @@ extern bool brcms_del_timer(struct brcms_timer *timer); | |||
104 | extern void brcms_msleep(struct brcms_info *wl, uint ms); | 105 | extern void brcms_msleep(struct brcms_info *wl, uint ms); |
105 | extern void brcms_dpc(unsigned long data); | 106 | extern void brcms_dpc(unsigned long data); |
106 | extern void brcms_timer(struct brcms_timer *t); | 107 | extern void brcms_timer(struct brcms_timer *t); |
108 | extern void brcms_fatal_error(struct brcms_info *wl); | ||
107 | 109 | ||
108 | #endif /* _BRCM_MAC80211_IF_H_ */ | 110 | #endif /* _BRCM_MAC80211_IF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 510e9bb52287..36e3e0638300 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -30,44 +30,21 @@ | |||
30 | #include "mac80211_if.h" | 30 | #include "mac80211_if.h" |
31 | #include "ucode_loader.h" | 31 | #include "ucode_loader.h" |
32 | #include "main.h" | 32 | #include "main.h" |
33 | #include "soc.h" | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Indication for txflowcontrol that all priority bits in | 36 | * Indication for txflowcontrol that all priority bits in |
36 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. | 37 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. |
37 | */ | 38 | */ |
38 | #define ALLPRIO -1 | 39 | #define ALLPRIO -1 |
39 | |||
40 | /* | ||
41 | * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. | ||
42 | */ | ||
43 | #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) | ||
44 | 40 | ||
45 | /* watchdog timer, in unit of ms */ | 41 | /* watchdog timer, in unit of ms */ |
46 | #define TIMER_INTERVAL_WATCHDOG 1000 | 42 | #define TIMER_INTERVAL_WATCHDOG 1000 |
47 | /* radio monitor timer, in unit of ms */ | 43 | /* radio monitor timer, in unit of ms */ |
48 | #define TIMER_INTERVAL_RADIOCHK 800 | 44 | #define TIMER_INTERVAL_RADIOCHK 800 |
49 | |||
50 | /* Max MPC timeout, in unit of watchdog */ | ||
51 | #ifndef BRCMS_MPC_MAX_DELAYCNT | ||
52 | #define BRCMS_MPC_MAX_DELAYCNT 10 | ||
53 | #endif | ||
54 | |||
55 | /* Min MPC timeout, in unit of watchdog */ | ||
56 | #define BRCMS_MPC_MIN_DELAYCNT 1 | ||
57 | #define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */ | ||
58 | 45 | ||
59 | /* beacon interval, in unit of 1024TU */ | 46 | /* beacon interval, in unit of 1024TU */ |
60 | #define BEACON_INTERVAL_DEFAULT 100 | 47 | #define BEACON_INTERVAL_DEFAULT 100 |
61 | /* DTIM interval, in unit of beacon interval */ | ||
62 | #define DTIM_INTERVAL_DEFAULT 3 | ||
63 | |||
64 | /* Scale down delays to accommodate QT slow speed */ | ||
65 | /* beacon interval, in unit of 1024TU */ | ||
66 | #define BEACON_INTERVAL_DEF_QT 20 | ||
67 | /* DTIM interval, in unit of beacon interval */ | ||
68 | #define DTIM_INTERVAL_DEF_QT 1 | ||
69 | |||
70 | #define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ | ||
71 | 48 | ||
72 | /* n-mode support capability */ | 49 | /* n-mode support capability */ |
73 | /* 2x2 includes both 1x1 & 2x2 devices | 50 | /* 2x2 includes both 1x1 & 2x2 devices |
@@ -78,113 +55,71 @@ | |||
78 | #define WL_11N_3x3 3 | 55 | #define WL_11N_3x3 3 |
79 | #define WL_11N_4x4 4 | 56 | #define WL_11N_4x4 4 |
80 | 57 | ||
81 | /* define 11n feature disable flags */ | 58 | #define EDCF_ACI_MASK 0x60 |
82 | #define WLFEATURE_DISABLE_11N 0x00000001 | 59 | #define EDCF_ACI_SHIFT 5 |
83 | #define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 | 60 | #define EDCF_ECWMIN_MASK 0x0f |
84 | #define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 | 61 | #define EDCF_ECWMAX_SHIFT 4 |
85 | #define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 | 62 | #define EDCF_AIFSN_MASK 0x0f |
86 | #define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 | 63 | #define EDCF_AIFSN_MAX 15 |
87 | #define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 | 64 | #define EDCF_ECWMAX_MASK 0xf0 |
88 | #define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 | 65 | |
89 | #define WLFEATURE_DISABLE_11N_GF 0x00000080 | 66 | #define EDCF_AC_BE_TXOP_STA 0x0000 |
90 | 67 | #define EDCF_AC_BK_TXOP_STA 0x0000 | |
91 | #define EDCF_ACI_MASK 0x60 | 68 | #define EDCF_AC_VO_ACI_STA 0x62 |
92 | #define EDCF_ACI_SHIFT 5 | 69 | #define EDCF_AC_VO_ECW_STA 0x32 |
93 | #define EDCF_ECWMIN_MASK 0x0f | 70 | #define EDCF_AC_VI_ACI_STA 0x42 |
94 | #define EDCF_ECWMAX_SHIFT 4 | 71 | #define EDCF_AC_VI_ECW_STA 0x43 |
95 | #define EDCF_AIFSN_MASK 0x0f | 72 | #define EDCF_AC_BK_ECW_STA 0xA4 |
96 | #define EDCF_AIFSN_MAX 15 | 73 | #define EDCF_AC_VI_TXOP_STA 0x005e |
97 | #define EDCF_ECWMAX_MASK 0xf0 | 74 | #define EDCF_AC_VO_TXOP_STA 0x002f |
98 | 75 | #define EDCF_AC_BE_ACI_STA 0x03 | |
99 | #define EDCF_AC_BE_TXOP_STA 0x0000 | 76 | #define EDCF_AC_BE_ECW_STA 0xA4 |
100 | #define EDCF_AC_BK_TXOP_STA 0x0000 | 77 | #define EDCF_AC_BK_ACI_STA 0x27 |
101 | #define EDCF_AC_VO_ACI_STA 0x62 | 78 | #define EDCF_AC_VO_TXOP_AP 0x002f |
102 | #define EDCF_AC_VO_ECW_STA 0x32 | 79 | |
103 | #define EDCF_AC_VI_ACI_STA 0x42 | 80 | #define EDCF_TXOP2USEC(txop) ((txop) << 5) |
104 | #define EDCF_AC_VI_ECW_STA 0x43 | 81 | #define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) |
105 | #define EDCF_AC_BK_ECW_STA 0xA4 | 82 | |
106 | #define EDCF_AC_VI_TXOP_STA 0x005e | 83 | #define APHY_SYMBOL_TIME 4 |
107 | #define EDCF_AC_VO_TXOP_STA 0x002f | 84 | #define APHY_PREAMBLE_TIME 16 |
108 | #define EDCF_AC_BE_ACI_STA 0x03 | 85 | #define APHY_SIGNAL_TIME 4 |
109 | #define EDCF_AC_BE_ECW_STA 0xA4 | 86 | #define APHY_SIFS_TIME 16 |
110 | #define EDCF_AC_BK_ACI_STA 0x27 | 87 | #define APHY_SERVICE_NBITS 16 |
111 | #define EDCF_AC_VO_TXOP_AP 0x002f | 88 | #define APHY_TAIL_NBITS 6 |
112 | 89 | #define BPHY_SIFS_TIME 10 | |
113 | #define EDCF_TXOP2USEC(txop) ((txop) << 5) | 90 | #define BPHY_PLCP_SHORT_TIME 96 |
114 | #define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) | 91 | |
115 | 92 | #define PREN_PREAMBLE 24 | |
116 | #define APHY_SYMBOL_TIME 4 | 93 | #define PREN_MM_EXT 12 |
117 | #define APHY_PREAMBLE_TIME 16 | 94 | #define PREN_PREAMBLE_EXT 4 |
118 | #define APHY_SIGNAL_TIME 4 | ||
119 | #define APHY_SIFS_TIME 16 | ||
120 | #define APHY_SERVICE_NBITS 16 | ||
121 | #define APHY_TAIL_NBITS 6 | ||
122 | #define BPHY_SIFS_TIME 10 | ||
123 | #define BPHY_PLCP_SHORT_TIME 96 | ||
124 | |||
125 | #define PREN_PREAMBLE 24 | ||
126 | #define PREN_MM_EXT 12 | ||
127 | #define PREN_PREAMBLE_EXT 4 | ||
128 | 95 | ||
129 | #define DOT11_MAC_HDR_LEN 24 | 96 | #define DOT11_MAC_HDR_LEN 24 |
130 | #define DOT11_ACK_LEN 10 | 97 | #define DOT11_ACK_LEN 10 |
131 | #define DOT11_BA_LEN 4 | 98 | #define DOT11_BA_LEN 4 |
132 | #define DOT11_OFDM_SIGNAL_EXTENSION 6 | 99 | #define DOT11_OFDM_SIGNAL_EXTENSION 6 |
133 | #define DOT11_MIN_FRAG_LEN 256 | 100 | #define DOT11_MIN_FRAG_LEN 256 |
134 | #define DOT11_RTS_LEN 16 | 101 | #define DOT11_RTS_LEN 16 |
135 | #define DOT11_CTS_LEN 10 | 102 | #define DOT11_CTS_LEN 10 |
136 | #define DOT11_BA_BITMAP_LEN 128 | 103 | #define DOT11_BA_BITMAP_LEN 128 |
137 | #define DOT11_MIN_BEACON_PERIOD 1 | 104 | #define DOT11_MIN_BEACON_PERIOD 1 |
138 | #define DOT11_MAX_BEACON_PERIOD 0xFFFF | 105 | #define DOT11_MAX_BEACON_PERIOD 0xFFFF |
139 | #define DOT11_MAXNUMFRAGS 16 | 106 | #define DOT11_MAXNUMFRAGS 16 |
140 | #define DOT11_MAX_FRAG_LEN 2346 | 107 | #define DOT11_MAX_FRAG_LEN 2346 |
141 | 108 | ||
142 | #define BPHY_PLCP_TIME 192 | 109 | #define BPHY_PLCP_TIME 192 |
143 | #define RIFS_11N_TIME 2 | 110 | #define RIFS_11N_TIME 2 |
144 | |||
145 | #define WME_VER 1 | ||
146 | #define WME_SUBTYPE_PARAM_IE 1 | ||
147 | #define WME_TYPE 2 | ||
148 | #define WME_OUI "\x00\x50\xf2" | ||
149 | |||
150 | #define AC_BE 0 | ||
151 | #define AC_BK 1 | ||
152 | #define AC_VI 2 | ||
153 | #define AC_VO 3 | ||
154 | 111 | ||
155 | #define BCN_TMPL_LEN 512 /* length of the BCN template area */ | 112 | /* length of the BCN template area */ |
113 | #define BCN_TMPL_LEN 512 | ||
156 | 114 | ||
157 | /* brcms_bss_info flag bit values */ | 115 | /* brcms_bss_info flag bit values */ |
158 | #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ | 116 | #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ |
159 | 117 | ||
160 | /* Flags used in brcms_c_txq_info.stopped */ | 118 | /* chip rx buffer offset */ |
161 | /* per prio flow control bits */ | 119 | #define BRCMS_HWRXOFF 38 |
162 | #define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF | ||
163 | /* stop txq enqueue for packet drain */ | ||
164 | #define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 | ||
165 | /* stop txq enqueue for ampdu flow control */ | ||
166 | #define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 | ||
167 | |||
168 | #define BRCMS_HWRXOFF 38 /* chip rx buffer offset */ | ||
169 | |||
170 | /* Find basic rate for a given rate */ | ||
171 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | ||
172 | { | ||
173 | if (is_mcs_rate(rspec)) | ||
174 | return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] | ||
175 | .leg_ofdm]; | ||
176 | return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; | ||
177 | } | ||
178 | |||
179 | static u16 frametype(u32 rspec, u8 mimoframe) | ||
180 | { | ||
181 | if (is_mcs_rate(rspec)) | ||
182 | return mimoframe; | ||
183 | return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; | ||
184 | } | ||
185 | 120 | ||
186 | /* rfdisable delay timer 500 ms, runs of ALP clock */ | 121 | /* rfdisable delay timer 500 ms, runs of ALP clock */ |
187 | #define RFDISABLE_DEFAULT 10000000 | 122 | #define RFDISABLE_DEFAULT 10000000 |
188 | 123 | ||
189 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ | 124 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ |
190 | 125 | ||
@@ -194,87 +129,83 @@ static u16 frametype(u32 rspec, u8 mimoframe) | |||
194 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them | 129 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them |
195 | * elsewhere. | 130 | * elsewhere. |
196 | */ | 131 | */ |
197 | #define _BRCMS_PREC_NONE 0 /* None = - */ | 132 | #define _BRCMS_PREC_NONE 0 /* None = - */ |
198 | #define _BRCMS_PREC_BK 2 /* BK - Background */ | 133 | #define _BRCMS_PREC_BK 2 /* BK - Background */ |
199 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ | 134 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ |
200 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ | 135 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ |
201 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ | 136 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ |
202 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ | 137 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ |
203 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ | 138 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ |
204 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ | 139 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ |
205 | 140 | ||
206 | /* The BSS is generating beacons in HW */ | 141 | /* synthpu_dly times in us */ |
207 | #define BRCMS_BSSCFG_HW_BCN 0x20 | 142 | #define SYNTHPU_DLY_APHY_US 3700 |
208 | 143 | #define SYNTHPU_DLY_BPHY_US 1050 | |
209 | #define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ | 144 | #define SYNTHPU_DLY_NPHY_US 2048 |
210 | #define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us */ | 145 | #define SYNTHPU_DLY_LPPHY_US 300 |
211 | #define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us */ | 146 | |
212 | #define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ | 147 | #define ANTCNT 10 /* vanilla M_MAX_ANTCNT val */ |
213 | |||
214 | #define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ | ||
215 | |||
216 | #define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ | ||
217 | 148 | ||
218 | /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ | 149 | /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ |
219 | #define EDCF_SHORT_S 0 | 150 | #define EDCF_SHORT_S 0 |
220 | #define EDCF_SFB_S 4 | 151 | #define EDCF_SFB_S 4 |
221 | #define EDCF_LONG_S 8 | 152 | #define EDCF_LONG_S 8 |
222 | #define EDCF_LFB_S 12 | 153 | #define EDCF_LFB_S 12 |
223 | #define EDCF_SHORT_M BITFIELD_MASK(4) | 154 | #define EDCF_SHORT_M BITFIELD_MASK(4) |
224 | #define EDCF_SFB_M BITFIELD_MASK(4) | 155 | #define EDCF_SFB_M BITFIELD_MASK(4) |
225 | #define EDCF_LONG_M BITFIELD_MASK(4) | 156 | #define EDCF_LONG_M BITFIELD_MASK(4) |
226 | #define EDCF_LFB_M BITFIELD_MASK(4) | 157 | #define EDCF_LFB_M BITFIELD_MASK(4) |
227 | 158 | ||
228 | #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ | 159 | #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ |
229 | #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ | 160 | #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ |
230 | #define RETRY_LONG_DEF 4 /* Default Long retry count */ | 161 | #define RETRY_LONG_DEF 4 /* Default Long retry count */ |
231 | #define RETRY_SHORT_FB 3 /* Short count for fallback rate */ | 162 | #define RETRY_SHORT_FB 3 /* Short count for fb rate */ |
232 | #define RETRY_LONG_FB 2 /* Long count for fallback rate */ | 163 | #define RETRY_LONG_FB 2 /* Long count for fb rate */ |
233 | 164 | ||
234 | #define APHY_CWMIN 15 | 165 | #define APHY_CWMIN 15 |
235 | #define PHY_CWMAX 1023 | 166 | #define PHY_CWMAX 1023 |
236 | 167 | ||
237 | #define EDCF_AIFSN_MIN 1 | 168 | #define EDCF_AIFSN_MIN 1 |
238 | 169 | ||
239 | #define FRAGNUM_MASK 0xF | 170 | #define FRAGNUM_MASK 0xF |
240 | 171 | ||
241 | #define APHY_SLOT_TIME 9 | 172 | #define APHY_SLOT_TIME 9 |
242 | #define BPHY_SLOT_TIME 20 | 173 | #define BPHY_SLOT_TIME 20 |
243 | 174 | ||
244 | #define WL_SPURAVOID_OFF 0 | 175 | #define WL_SPURAVOID_OFF 0 |
245 | #define WL_SPURAVOID_ON1 1 | 176 | #define WL_SPURAVOID_ON1 1 |
246 | #define WL_SPURAVOID_ON2 2 | 177 | #define WL_SPURAVOID_ON2 2 |
247 | 178 | ||
248 | /* invalid core flags, use the saved coreflags */ | 179 | /* invalid core flags, use the saved coreflags */ |
249 | #define BRCMS_USE_COREFLAGS 0xffffffff | 180 | #define BRCMS_USE_COREFLAGS 0xffffffff |
250 | 181 | ||
251 | /* values for PLCPHdr_override */ | 182 | /* values for PLCPHdr_override */ |
252 | #define BRCMS_PLCP_AUTO -1 | 183 | #define BRCMS_PLCP_AUTO -1 |
253 | #define BRCMS_PLCP_SHORT 0 | 184 | #define BRCMS_PLCP_SHORT 0 |
254 | #define BRCMS_PLCP_LONG 1 | 185 | #define BRCMS_PLCP_LONG 1 |
255 | 186 | ||
256 | /* values for g_protection_override and n_protection_override */ | 187 | /* values for g_protection_override and n_protection_override */ |
257 | #define BRCMS_PROTECTION_AUTO -1 | 188 | #define BRCMS_PROTECTION_AUTO -1 |
258 | #define BRCMS_PROTECTION_OFF 0 | 189 | #define BRCMS_PROTECTION_OFF 0 |
259 | #define BRCMS_PROTECTION_ON 1 | 190 | #define BRCMS_PROTECTION_ON 1 |
260 | #define BRCMS_PROTECTION_MMHDR_ONLY 2 | 191 | #define BRCMS_PROTECTION_MMHDR_ONLY 2 |
261 | #define BRCMS_PROTECTION_CTS_ONLY 3 | 192 | #define BRCMS_PROTECTION_CTS_ONLY 3 |
262 | 193 | ||
263 | /* values for g_protection_control and n_protection_control */ | 194 | /* values for g_protection_control and n_protection_control */ |
264 | #define BRCMS_PROTECTION_CTL_OFF 0 | 195 | #define BRCMS_PROTECTION_CTL_OFF 0 |
265 | #define BRCMS_PROTECTION_CTL_LOCAL 1 | 196 | #define BRCMS_PROTECTION_CTL_LOCAL 1 |
266 | #define BRCMS_PROTECTION_CTL_OVERLAP 2 | 197 | #define BRCMS_PROTECTION_CTL_OVERLAP 2 |
267 | 198 | ||
268 | /* values for n_protection */ | 199 | /* values for n_protection */ |
269 | #define BRCMS_N_PROTECTION_OFF 0 | 200 | #define BRCMS_N_PROTECTION_OFF 0 |
270 | #define BRCMS_N_PROTECTION_OPTIONAL 1 | 201 | #define BRCMS_N_PROTECTION_OPTIONAL 1 |
271 | #define BRCMS_N_PROTECTION_20IN40 2 | 202 | #define BRCMS_N_PROTECTION_20IN40 2 |
272 | #define BRCMS_N_PROTECTION_MIXEDMODE 3 | 203 | #define BRCMS_N_PROTECTION_MIXEDMODE 3 |
273 | 204 | ||
274 | /* values for band specific 40MHz capabilities */ | 205 | /* values for band specific 40MHz capabilities */ |
275 | #define BRCMS_N_BW_20ALL 0 | 206 | #define BRCMS_N_BW_20ALL 0 |
276 | #define BRCMS_N_BW_40ALL 1 | 207 | #define BRCMS_N_BW_40ALL 1 |
277 | #define BRCMS_N_BW_20IN2G_40IN5G 2 | 208 | #define BRCMS_N_BW_20IN2G_40IN5G 2 |
278 | 209 | ||
279 | /* bitflags for SGI support (sgi_rx iovar) */ | 210 | /* bitflags for SGI support (sgi_rx iovar) */ |
280 | #define BRCMS_N_SGI_20 0x01 | 211 | #define BRCMS_N_SGI_20 0x01 |
@@ -282,48 +213,42 @@ static u16 frametype(u32 rspec, u8 mimoframe) | |||
282 | 213 | ||
283 | /* defines used by the nrate iovar */ | 214 | /* defines used by the nrate iovar */ |
284 | /* MSC in use,indicates b0-6 holds an mcs */ | 215 | /* MSC in use,indicates b0-6 holds an mcs */ |
285 | #define NRATE_MCS_INUSE 0x00000080 | 216 | #define NRATE_MCS_INUSE 0x00000080 |
286 | /* rate/mcs value */ | 217 | /* rate/mcs value */ |
287 | #define NRATE_RATE_MASK 0x0000007f | 218 | #define NRATE_RATE_MASK 0x0000007f |
288 | /* stf mode mask: siso, cdd, stbc, sdm */ | 219 | /* stf mode mask: siso, cdd, stbc, sdm */ |
289 | #define NRATE_STF_MASK 0x0000ff00 | 220 | #define NRATE_STF_MASK 0x0000ff00 |
290 | /* stf mode shift */ | 221 | /* stf mode shift */ |
291 | #define NRATE_STF_SHIFT 8 | 222 | #define NRATE_STF_SHIFT 8 |
292 | /* bit indicates override both rate & mode */ | ||
293 | #define NRATE_OVERRIDE 0x80000000 | ||
294 | /* bit indicate to override mcs only */ | 223 | /* bit indicate to override mcs only */ |
295 | #define NRATE_OVERRIDE_MCS_ONLY 0x40000000 | 224 | #define NRATE_OVERRIDE_MCS_ONLY 0x40000000 |
296 | #define NRATE_SGI_MASK 0x00800000 /* sgi mode */ | 225 | #define NRATE_SGI_MASK 0x00800000 /* sgi mode */ |
297 | #define NRATE_SGI_SHIFT 23 /* sgi mode */ | 226 | #define NRATE_SGI_SHIFT 23 /* sgi mode */ |
298 | #define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ | 227 | #define NRATE_LDPC_CODING 0x00400000 /* adv coding in use */ |
299 | #define NRATE_LDPC_SHIFT 22 /* ldpc shift */ | 228 | #define NRATE_LDPC_SHIFT 22 /* ldpc shift */ |
300 | 229 | ||
301 | #define NRATE_STF_SISO 0 /* stf mode SISO */ | 230 | #define NRATE_STF_SISO 0 /* stf mode SISO */ |
302 | #define NRATE_STF_CDD 1 /* stf mode CDD */ | 231 | #define NRATE_STF_CDD 1 /* stf mode CDD */ |
303 | #define NRATE_STF_STBC 2 /* stf mode STBC */ | 232 | #define NRATE_STF_STBC 2 /* stf mode STBC */ |
304 | #define NRATE_STF_SDM 3 /* stf mode SDM */ | 233 | #define NRATE_STF_SDM 3 /* stf mode SDM */ |
305 | 234 | ||
306 | #define MAX_DMA_SEGS 4 | 235 | #define MAX_DMA_SEGS 4 |
307 | 236 | ||
308 | /* Max # of entries in Tx FIFO based on 4kb page size */ | 237 | /* Max # of entries in Tx FIFO based on 4kb page size */ |
309 | #define NTXD 256 | 238 | #define NTXD 256 |
310 | /* Max # of entries in Rx FIFO based on 4kb page size */ | 239 | /* Max # of entries in Rx FIFO based on 4kb page size */ |
311 | #define NRXD 256 | 240 | #define NRXD 256 |
312 | 241 | ||
313 | /* try to keep this # rbufs posted to the chip */ | 242 | /* try to keep this # rbufs posted to the chip */ |
314 | #define NRXBUFPOST 32 | 243 | #define NRXBUFPOST 32 |
315 | 244 | ||
316 | /* data msg txq hiwat mark */ | 245 | /* data msg txq hiwat mark */ |
317 | #define BRCMS_DATAHIWAT 50 | 246 | #define BRCMS_DATAHIWAT 50 |
318 | 247 | ||
319 | /* bounded rx loops */ | 248 | /* max # frames to process in brcms_c_recv() */ |
320 | #define RXBND 8 /* max # frames to process in brcms_c_recv() */ | 249 | #define RXBND 8 |
321 | #define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ | 250 | /* max # tx status to process in wlc_txstatus() */ |
322 | 251 | #define TXSBND 8 | |
323 | /* | ||
324 | * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. | ||
325 | */ | ||
326 | #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) | ||
327 | 252 | ||
328 | /* brcmu_format_flags() bit description structure */ | 253 | /* brcmu_format_flags() bit description structure */ |
329 | struct brcms_c_bit_desc { | 254 | struct brcms_c_bit_desc { |
@@ -375,10 +300,22 @@ uint brcm_msg_level = | |||
375 | #endif /* BCMDBG */ | 300 | #endif /* BCMDBG */ |
376 | 301 | ||
377 | /* TX FIFO number to WME/802.1E Access Category */ | 302 | /* TX FIFO number to WME/802.1E Access Category */ |
378 | static const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; | 303 | static const u8 wme_fifo2ac[] = { |
304 | IEEE80211_AC_BK, | ||
305 | IEEE80211_AC_BE, | ||
306 | IEEE80211_AC_VI, | ||
307 | IEEE80211_AC_VO, | ||
308 | IEEE80211_AC_BE, | ||
309 | IEEE80211_AC_BE | ||
310 | }; | ||
379 | 311 | ||
380 | /* WME/802.1E Access Category to TX FIFO number */ | 312 | /* ieee80211 Access Category to TX FIFO number */ |
381 | static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; | 313 | static const u8 wme_ac2fifo[] = { |
314 | TX_AC_VO_FIFO, | ||
315 | TX_AC_VI_FIFO, | ||
316 | TX_AC_BE_FIFO, | ||
317 | TX_AC_BK_FIFO | ||
318 | }; | ||
382 | 319 | ||
383 | /* 802.1D Priority to precedence queue mapping */ | 320 | /* 802.1D Priority to precedence queue mapping */ |
384 | const u8 wlc_prio2prec_map[] = { | 321 | const u8 wlc_prio2prec_map[] = { |
@@ -405,13 +342,6 @@ static const u16 xmtfifo_sz[][NFIFO] = { | |||
405 | {9, 58, 22, 14, 14, 5}, | 342 | {9, 58, 22, 14, 14, 5}, |
406 | }; | 343 | }; |
407 | 344 | ||
408 | static const u8 acbitmap2maxprio[] = { | ||
409 | PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, | ||
410 | PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, | ||
411 | PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, | ||
412 | PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO | ||
413 | }; | ||
414 | |||
415 | #ifdef BCMDBG | 345 | #ifdef BCMDBG |
416 | static const char * const fifo_names[] = { | 346 | static const char * const fifo_names[] = { |
417 | "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; | 347 | "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; |
@@ -424,6 +354,22 @@ static const char fifo_names[6][0]; | |||
424 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); | 354 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); |
425 | #endif | 355 | #endif |
426 | 356 | ||
357 | /* Find basic rate for a given rate */ | ||
358 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | ||
359 | { | ||
360 | if (is_mcs_rate(rspec)) | ||
361 | return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] | ||
362 | .leg_ofdm]; | ||
363 | return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; | ||
364 | } | ||
365 | |||
366 | static u16 frametype(u32 rspec, u8 mimoframe) | ||
367 | { | ||
368 | if (is_mcs_rate(rspec)) | ||
369 | return mimoframe; | ||
370 | return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; | ||
371 | } | ||
372 | |||
427 | /* currently the best mechanism for determining SIFS is the band in use */ | 373 | /* currently the best mechanism for determining SIFS is the band in use */ |
428 | static u16 get_sifs(struct brcms_band *band) | 374 | static u16 get_sifs(struct brcms_band *band) |
429 | { | 375 | { |
@@ -470,20 +416,6 @@ static int brcms_chspec_bw(u16 chanspec) | |||
470 | return BRCMS_10_MHZ; | 416 | return BRCMS_10_MHZ; |
471 | } | 417 | } |
472 | 418 | ||
473 | /* | ||
474 | * return true if Minimum Power Consumption should | ||
475 | * be entered, false otherwise | ||
476 | */ | ||
477 | static bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc) | ||
478 | { | ||
479 | return false; | ||
480 | } | ||
481 | |||
482 | static bool brcms_c_ismpc(struct brcms_c_info *wlc) | ||
483 | { | ||
484 | return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc)); | ||
485 | } | ||
486 | |||
487 | static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) | 419 | static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) |
488 | { | 420 | { |
489 | if (cfg == NULL) | 421 | if (cfg == NULL) |
@@ -669,9 +601,8 @@ static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, | |||
669 | * calculate frame duration of a given rate and length, return | 601 | * calculate frame duration of a given rate and length, return |
670 | * time in usec unit | 602 | * time in usec unit |
671 | */ | 603 | */ |
672 | uint | 604 | static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, |
673 | brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, | 605 | u8 preamble_type, uint mac_len) |
674 | u8 preamble_type, uint mac_len) | ||
675 | { | 606 | { |
676 | uint nsyms, dur = 0, Ndps, kNdps; | 607 | uint nsyms, dur = 0, Ndps, kNdps; |
677 | uint rate = rspec2rate(ratespec); | 608 | uint rate = rspec2rate(ratespec); |
@@ -969,7 +900,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
969 | lfbl, /* Long Frame Rate Fallback Limit */ | 900 | lfbl, /* Long Frame Rate Fallback Limit */ |
970 | fbl; | 901 | fbl; |
971 | 902 | ||
972 | if (queue < AC_COUNT) { | 903 | if (queue < IEEE80211_NUM_ACS) { |
973 | sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], | 904 | sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], |
974 | EDCF_SFB); | 905 | EDCF_SFB); |
975 | lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], | 906 | lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], |
@@ -1018,7 +949,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
1018 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 949 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
1019 | } | 950 | } |
1020 | 951 | ||
1021 | totlen = brcmu_pkttotlen(p); | 952 | totlen = p->len; |
1022 | free_pdu = true; | 953 | free_pdu = true; |
1023 | 954 | ||
1024 | brcms_c_txfifo_complete(wlc, queue, 1); | 955 | brcms_c_txfifo_complete(wlc, queue, 1); |
@@ -2352,13 +2283,6 @@ void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) | |||
2352 | wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); | 2283 | wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); |
2353 | } | 2284 | } |
2354 | 2285 | ||
2355 | static void brcms_c_fatal_error(struct brcms_c_info *wlc) | ||
2356 | { | ||
2357 | wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", | ||
2358 | wlc->pub->unit); | ||
2359 | brcms_init(wlc->wl); | ||
2360 | } | ||
2361 | |||
2362 | static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | 2286 | static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) |
2363 | { | 2287 | { |
2364 | bool fatal = false; | 2288 | bool fatal = false; |
@@ -2414,7 +2338,7 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2414 | } | 2338 | } |
2415 | 2339 | ||
2416 | if (fatal) { | 2340 | if (fatal) { |
2417 | brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ | 2341 | brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */ |
2418 | break; | 2342 | break; |
2419 | } else | 2343 | } else |
2420 | W_REG(®s->intctrlregs[idx].intstatus, | 2344 | W_REG(®s->intctrlregs[idx].intstatus, |
@@ -2479,6 +2403,7 @@ void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) | |||
2479 | W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); | 2403 | W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); |
2480 | } | 2404 | } |
2481 | 2405 | ||
2406 | /* assumes that the d11 MAC is enabled */ | ||
2482 | static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, | 2407 | static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, |
2483 | uint tx_fifo) | 2408 | uint tx_fifo) |
2484 | { | 2409 | { |
@@ -2535,11 +2460,12 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, | |||
2535 | } | 2460 | } |
2536 | } | 2461 | } |
2537 | 2462 | ||
2538 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) | 2463 | /* precondition: requires the mac core to be enabled */ |
2464 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) | ||
2539 | { | 2465 | { |
2540 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; | 2466 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; |
2541 | 2467 | ||
2542 | if (on) { | 2468 | if (mute_tx) { |
2543 | /* suspend tx fifos */ | 2469 | /* suspend tx fifos */ |
2544 | brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); | 2470 | brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); |
2545 | brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); | 2471 | brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); |
@@ -2561,14 +2487,20 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) | |||
2561 | wlc_hw->etheraddr); | 2487 | wlc_hw->etheraddr); |
2562 | } | 2488 | } |
2563 | 2489 | ||
2564 | wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); | 2490 | wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); |
2565 | 2491 | ||
2566 | if (on) | 2492 | if (mute_tx) |
2567 | brcms_c_ucode_mute_override_set(wlc_hw); | 2493 | brcms_c_ucode_mute_override_set(wlc_hw); |
2568 | else | 2494 | else |
2569 | brcms_c_ucode_mute_override_clear(wlc_hw); | 2495 | brcms_c_ucode_mute_override_clear(wlc_hw); |
2570 | } | 2496 | } |
2571 | 2497 | ||
2498 | void | ||
2499 | brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx) | ||
2500 | { | ||
2501 | brcms_b_mute(wlc->hw, mute_tx); | ||
2502 | } | ||
2503 | |||
2572 | /* | 2504 | /* |
2573 | * Read and clear macintmask and macintstatus and intstatus registers. | 2505 | * Read and clear macintmask and macintstatus and intstatus registers. |
2574 | * This routine should be called with interrupts off | 2506 | * This routine should be called with interrupts off |
@@ -3437,8 +3369,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3437 | } | 3369 | } |
3438 | 3370 | ||
3439 | void | 3371 | void |
3440 | static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, | 3372 | static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { |
3441 | bool mute) { | ||
3442 | u32 macintmask; | 3373 | u32 macintmask; |
3443 | bool fastclk; | 3374 | bool fastclk; |
3444 | struct brcms_c_info *wlc = wlc_hw->wlc; | 3375 | struct brcms_c_info *wlc = wlc_hw->wlc; |
@@ -3463,10 +3394,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
3463 | /* core-specific initialization */ | 3394 | /* core-specific initialization */ |
3464 | brcms_b_coreinit(wlc); | 3395 | brcms_b_coreinit(wlc); |
3465 | 3396 | ||
3466 | /* suspend the tx fifos and mute the phy for preism cac time */ | ||
3467 | if (mute) | ||
3468 | brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); | ||
3469 | |||
3470 | /* band-specific inits */ | 3397 | /* band-specific inits */ |
3471 | brcms_b_bsinit(wlc, chanspec); | 3398 | brcms_b_bsinit(wlc, chanspec); |
3472 | 3399 | ||
@@ -3656,42 +3583,30 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, | |||
3656 | brcms_c_set_phy_chanspec(wlc, chanspec); | 3583 | brcms_c_set_phy_chanspec(wlc, chanspec); |
3657 | } | 3584 | } |
3658 | 3585 | ||
3659 | static void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc) | 3586 | /* |
3660 | { | 3587 | * Set or clear maccontrol bits MCTL_PROMISC, MCTL_BCNS_PROMISC and |
3661 | if (wlc->bcnmisc_monitor) | 3588 | * MCTL_KEEPCONTROL |
3662 | brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); | 3589 | */ |
3663 | else | ||
3664 | brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0); | ||
3665 | } | ||
3666 | |||
3667 | void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc) | ||
3668 | { | ||
3669 | wlc->bcnmisc_monitor = promisc; | ||
3670 | brcms_c_mac_bcn_promisc(wlc); | ||
3671 | } | ||
3672 | |||
3673 | /* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ | ||
3674 | static void brcms_c_mac_promisc(struct brcms_c_info *wlc) | 3590 | static void brcms_c_mac_promisc(struct brcms_c_info *wlc) |
3675 | { | 3591 | { |
3676 | u32 promisc_bits = 0; | 3592 | u32 promisc_bits = 0; |
3677 | 3593 | ||
3678 | /* | 3594 | if (wlc->bcnmisc_monitor) |
3679 | * promiscuous mode just sets MCTL_PROMISC | 3595 | promisc_bits |= MCTL_BCNS_PROMISC; |
3680 | * Note: APs get all BSS traffic without the need to set | ||
3681 | * the MCTL_PROMISC bit since all BSS data traffic is | ||
3682 | * directed at the AP | ||
3683 | */ | ||
3684 | if (wlc->pub->promisc) | ||
3685 | promisc_bits |= MCTL_PROMISC; | ||
3686 | 3596 | ||
3687 | /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL | ||
3688 | * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is | ||
3689 | * handled in brcms_c_mac_bcn_promisc() | ||
3690 | */ | ||
3691 | if (wlc->monitor) | 3597 | if (wlc->monitor) |
3692 | promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; | 3598 | promisc_bits |= |
3599 | MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL; | ||
3693 | 3600 | ||
3694 | brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); | 3601 | brcms_b_mctrl(wlc->hw, |
3602 | MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL, | ||
3603 | promisc_bits); | ||
3604 | } | ||
3605 | |||
3606 | void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc) | ||
3607 | { | ||
3608 | wlc->bcnmisc_monitor = promisc; | ||
3609 | brcms_c_mac_promisc(wlc); | ||
3695 | } | 3610 | } |
3696 | 3611 | ||
3697 | /* | 3612 | /* |
@@ -3723,7 +3638,6 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) | |||
3723 | } | 3638 | } |
3724 | 3639 | ||
3725 | /* update the various promisc bits */ | 3640 | /* update the various promisc bits */ |
3726 | brcms_c_mac_bcn_promisc(wlc); | ||
3727 | brcms_c_mac_promisc(wlc); | 3641 | brcms_c_mac_promisc(wlc); |
3728 | } | 3642 | } |
3729 | 3643 | ||
@@ -3979,7 +3893,7 @@ static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3979 | 3893 | ||
3980 | void | 3894 | void |
3981 | brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | 3895 | brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, |
3982 | bool mute, struct txpwr_limits *txpwr) | 3896 | bool mute_tx, struct txpwr_limits *txpwr) |
3983 | { | 3897 | { |
3984 | uint bandunit; | 3898 | uint bandunit; |
3985 | 3899 | ||
@@ -4005,7 +3919,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
4005 | } | 3919 | } |
4006 | } | 3920 | } |
4007 | 3921 | ||
4008 | wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); | 3922 | wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx); |
4009 | 3923 | ||
4010 | if (!wlc_hw->up) { | 3924 | if (!wlc_hw->up) { |
4011 | if (wlc_hw->clk) | 3925 | if (wlc_hw->clk) |
@@ -4017,7 +3931,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
4017 | wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); | 3931 | wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); |
4018 | 3932 | ||
4019 | /* Update muting of the channel */ | 3933 | /* Update muting of the channel */ |
4020 | brcms_b_mute(wlc_hw, mute, 0); | 3934 | brcms_b_mute(wlc_hw, mute_tx); |
4021 | } | 3935 | } |
4022 | } | 3936 | } |
4023 | 3937 | ||
@@ -4205,7 +4119,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4205 | EDCF_TXOP2USEC(acp_shm.txop); | 4119 | EDCF_TXOP2USEC(acp_shm.txop); |
4206 | acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); | 4120 | acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); |
4207 | 4121 | ||
4208 | if (aci == AC_VI && acp_shm.txop == 0 | 4122 | if (aci == IEEE80211_AC_VI && acp_shm.txop == 0 |
4209 | && acp_shm.aifs < EDCF_AIFSN_MAX) | 4123 | && acp_shm.aifs < EDCF_AIFSN_MAX) |
4210 | acp_shm.aifs++; | 4124 | acp_shm.aifs++; |
4211 | 4125 | ||
@@ -4242,7 +4156,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4242 | } | 4156 | } |
4243 | } | 4157 | } |
4244 | 4158 | ||
4245 | void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | 4159 | static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) |
4246 | { | 4160 | { |
4247 | u16 aci; | 4161 | u16 aci; |
4248 | int i_ac; | 4162 | int i_ac; |
@@ -4255,7 +4169,7 @@ void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | |||
4255 | }; /* ucode needs these parameters during its initialization */ | 4169 | }; /* ucode needs these parameters during its initialization */ |
4256 | const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0]; | 4170 | const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0]; |
4257 | 4171 | ||
4258 | for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) { | 4172 | for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) { |
4259 | /* find out which ac this set of params applies to */ | 4173 | /* find out which ac this set of params applies to */ |
4260 | aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; | 4174 | aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; |
4261 | 4175 | ||
@@ -4277,17 +4191,6 @@ void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | |||
4277 | } | 4191 | } |
4278 | } | 4192 | } |
4279 | 4193 | ||
4280 | /* maintain LED behavior in down state */ | ||
4281 | static void brcms_c_down_led_upd(struct brcms_c_info *wlc) | ||
4282 | { | ||
4283 | /* | ||
4284 | * maintain LEDs while in down state, turn on sbclk if | ||
4285 | * not available yet. Turn on sbclk if necessary | ||
4286 | */ | ||
4287 | brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_FLIP); | ||
4288 | brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_FLIP); | ||
4289 | } | ||
4290 | |||
4291 | static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) | 4194 | static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) |
4292 | { | 4195 | { |
4293 | /* Don't start the timer if HWRADIO feature is disabled */ | 4196 | /* Don't start the timer if HWRADIO feature is disabled */ |
@@ -4299,28 +4202,6 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) | |||
4299 | brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); | 4202 | brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); |
4300 | } | 4203 | } |
4301 | 4204 | ||
4302 | static void brcms_c_radio_disable(struct brcms_c_info *wlc) | ||
4303 | { | ||
4304 | if (!wlc->pub->up) { | ||
4305 | brcms_c_down_led_upd(wlc); | ||
4306 | return; | ||
4307 | } | ||
4308 | |||
4309 | brcms_c_radio_monitor_start(wlc); | ||
4310 | brcms_down(wlc->wl); | ||
4311 | } | ||
4312 | |||
4313 | static void brcms_c_radio_enable(struct brcms_c_info *wlc) | ||
4314 | { | ||
4315 | if (wlc->pub->up) | ||
4316 | return; | ||
4317 | |||
4318 | if (brcms_deviceremoved(wlc)) | ||
4319 | return; | ||
4320 | |||
4321 | brcms_up(wlc->wl); | ||
4322 | } | ||
4323 | |||
4324 | static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) | 4205 | static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) |
4325 | { | 4206 | { |
4326 | if (!wlc->radio_monitor) | 4207 | if (!wlc->radio_monitor) |
@@ -4343,18 +4224,6 @@ static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) | |||
4343 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); | 4224 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); |
4344 | } | 4225 | } |
4345 | 4226 | ||
4346 | /* | ||
4347 | * centralized radio disable/enable function, | ||
4348 | * invoke radio enable/disable after updating hwradio status | ||
4349 | */ | ||
4350 | static void brcms_c_radio_upd(struct brcms_c_info *wlc) | ||
4351 | { | ||
4352 | if (wlc->pub->radio_disabled) | ||
4353 | brcms_c_radio_disable(wlc); | ||
4354 | else | ||
4355 | brcms_c_radio_enable(wlc); | ||
4356 | } | ||
4357 | |||
4358 | /* update hwradio status and return it */ | 4227 | /* update hwradio status and return it */ |
4359 | bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) | 4228 | bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) |
4360 | { | 4229 | { |
@@ -4376,12 +4245,7 @@ static void brcms_c_radio_timer(void *arg) | |||
4376 | return; | 4245 | return; |
4377 | } | 4246 | } |
4378 | 4247 | ||
4379 | /* cap mpc off count */ | ||
4380 | if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT) | ||
4381 | wlc->mpc_offcnt++; | ||
4382 | |||
4383 | brcms_c_radio_hwdisable_upd(wlc); | 4248 | brcms_c_radio_hwdisable_upd(wlc); |
4384 | brcms_c_radio_upd(wlc); | ||
4385 | } | 4249 | } |
4386 | 4250 | ||
4387 | /* common low-level watchdog code */ | 4251 | /* common low-level watchdog code */ |
@@ -4407,60 +4271,6 @@ static void brcms_b_watchdog(void *arg) | |||
4407 | wlc_phy_watchdog(wlc_hw->band->pi); | 4271 | wlc_phy_watchdog(wlc_hw->band->pi); |
4408 | } | 4272 | } |
4409 | 4273 | ||
4410 | static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) | ||
4411 | { | ||
4412 | bool mpc_radio, radio_state; | ||
4413 | |||
4414 | /* | ||
4415 | * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled | ||
4416 | * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio | ||
4417 | * monitor also when WL_RADIO_MPC_DISABLE is the only reason that | ||
4418 | * the radio is going down. | ||
4419 | */ | ||
4420 | if (!wlc->mpc) { | ||
4421 | if (!wlc->pub->radio_disabled) | ||
4422 | return; | ||
4423 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); | ||
4424 | brcms_c_radio_upd(wlc); | ||
4425 | if (!wlc->pub->radio_disabled) | ||
4426 | brcms_c_radio_monitor_stop(wlc); | ||
4427 | return; | ||
4428 | } | ||
4429 | |||
4430 | /* | ||
4431 | * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in | ||
4432 | * wlc->pub->radio_disabled to go ON, always call radio_upd | ||
4433 | * synchronously to go OFF, postpone radio_upd to later when | ||
4434 | * context is safe(e.g. watchdog) | ||
4435 | */ | ||
4436 | radio_state = | ||
4437 | (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : | ||
4438 | ON); | ||
4439 | mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON; | ||
4440 | |||
4441 | if (radio_state == ON && mpc_radio == OFF) | ||
4442 | wlc->mpc_delay_off = wlc->mpc_dlycnt; | ||
4443 | else if (radio_state == OFF && mpc_radio == ON) { | ||
4444 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); | ||
4445 | brcms_c_radio_upd(wlc); | ||
4446 | if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD) | ||
4447 | wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT; | ||
4448 | else | ||
4449 | wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
4450 | } | ||
4451 | /* | ||
4452 | * Below logic is meant to capture the transition from mpc off | ||
4453 | * to mpc on for reasons other than wlc->mpc_delay_off keeping | ||
4454 | * the mpc off. In that case reset wlc->mpc_delay_off to | ||
4455 | * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off | ||
4456 | */ | ||
4457 | if ((wlc->prev_non_delay_mpc == false) && | ||
4458 | (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) | ||
4459 | wlc->mpc_delay_off = wlc->mpc_dlycnt; | ||
4460 | |||
4461 | wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc); | ||
4462 | } | ||
4463 | |||
4464 | /* common watchdog code */ | 4274 | /* common watchdog code */ |
4465 | static void brcms_c_watchdog(void *arg) | 4275 | static void brcms_c_watchdog(void *arg) |
4466 | { | 4276 | { |
@@ -4481,21 +4291,7 @@ static void brcms_c_watchdog(void *arg) | |||
4481 | /* increment second count */ | 4291 | /* increment second count */ |
4482 | wlc->pub->now++; | 4292 | wlc->pub->now++; |
4483 | 4293 | ||
4484 | /* delay radio disable */ | ||
4485 | if (wlc->mpc_delay_off) { | ||
4486 | if (--wlc->mpc_delay_off == 0) { | ||
4487 | mboolset(wlc->pub->radio_disabled, | ||
4488 | WL_RADIO_MPC_DISABLE); | ||
4489 | if (wlc->mpc && brcms_c_ismpc(wlc)) | ||
4490 | wlc->mpc_offcnt = 0; | ||
4491 | } | ||
4492 | } | ||
4493 | |||
4494 | /* mpc sync */ | ||
4495 | brcms_c_radio_mpc_upd(wlc); | ||
4496 | /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ | ||
4497 | brcms_c_radio_hwdisable_upd(wlc); | 4294 | brcms_c_radio_hwdisable_upd(wlc); |
4498 | brcms_c_radio_upd(wlc); | ||
4499 | /* if radio is disable, driver may be down, quit here */ | 4295 | /* if radio is disable, driver may be down, quit here */ |
4500 | if (wlc->pub->radio_disabled) | 4296 | if (wlc->pub->radio_disabled) |
4501 | return; | 4297 | return; |
@@ -4599,9 +4395,6 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit) | |||
4599 | /* WME QoS mode is Auto by default */ | 4395 | /* WME QoS mode is Auto by default */ |
4600 | wlc->pub->_ampdu = AMPDU_AGG_HOST; | 4396 | wlc->pub->_ampdu = AMPDU_AGG_HOST; |
4601 | wlc->pub->bcmerror = 0; | 4397 | wlc->pub->bcmerror = 0; |
4602 | |||
4603 | /* initialize mpc delay */ | ||
4604 | wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
4605 | } | 4398 | } |
4606 | 4399 | ||
4607 | static uint brcms_c_attach_module(struct brcms_c_info *wlc) | 4400 | static uint brcms_c_attach_module(struct brcms_c_info *wlc) |
@@ -5259,9 +5052,6 @@ static void brcms_c_ap_upd(struct brcms_c_info *wlc) | |||
5259 | { | 5052 | { |
5260 | /* STA-BSS; short capable */ | 5053 | /* STA-BSS; short capable */ |
5261 | wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; | 5054 | wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; |
5262 | |||
5263 | /* fixup mpc */ | ||
5264 | wlc->mpc = true; | ||
5265 | } | 5055 | } |
5266 | 5056 | ||
5267 | /* Initialize just the hardware when coming out of POR or S3/S5 system states */ | 5057 | /* Initialize just the hardware when coming out of POR or S3/S5 system states */ |
@@ -5376,7 +5166,7 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) | |||
5376 | if (!wlc->clk) | 5166 | if (!wlc->clk) |
5377 | return; | 5167 | return; |
5378 | 5168 | ||
5379 | for (ac = 0; ac < AC_COUNT; ac++) | 5169 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
5380 | brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac), | 5170 | brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac), |
5381 | wlc->wme_retries[ac]); | 5171 | wlc->wme_retries[ac]); |
5382 | } | 5172 | } |
@@ -5575,7 +5365,6 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5575 | if (!wlc->pub->up) | 5365 | if (!wlc->pub->up) |
5576 | return callbacks; | 5366 | return callbacks; |
5577 | 5367 | ||
5578 | /* in between, mpc could try to bring down again.. */ | ||
5579 | wlc->going_down = true; | 5368 | wlc->going_down = true; |
5580 | 5369 | ||
5581 | callbacks += brcms_b_bmac_down_prep(wlc->hw); | 5370 | callbacks += brcms_b_bmac_down_prep(wlc->hw); |
@@ -5852,7 +5641,7 @@ int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl) | |||
5852 | 5641 | ||
5853 | brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); | 5642 | brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); |
5854 | 5643 | ||
5855 | for (ac = 0; ac < AC_COUNT; ac++) { | 5644 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
5856 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], | 5645 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], |
5857 | EDCF_SHORT, wlc->SRL); | 5646 | EDCF_SHORT, wlc->SRL); |
5858 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], | 5647 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], |
@@ -6103,7 +5892,6 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6103 | 5892 | ||
6104 | u8 *rtsph = txh->RTSPhyHeader; | 5893 | u8 *rtsph = txh->RTSPhyHeader; |
6105 | struct ieee80211_rts rts = txh->rts_frame; | 5894 | struct ieee80211_rts rts = txh->rts_frame; |
6106 | char hexbuf[256]; | ||
6107 | 5895 | ||
6108 | /* add plcp header along with txh descriptor */ | 5896 | /* add plcp header along with txh descriptor */ |
6109 | printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); | 5897 | printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); |
@@ -6124,17 +5912,16 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6124 | printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); | 5912 | printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); |
6125 | printk(KERN_DEBUG "\n"); | 5913 | printk(KERN_DEBUG "\n"); |
6126 | 5914 | ||
6127 | brcmu_format_hex(hexbuf, iv, sizeof(txh->IV)); | 5915 | print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); |
6128 | printk(KERN_DEBUG "SecIV: %s\n", hexbuf); | 5916 | print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, |
6129 | brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); | 5917 | ra, sizeof(txh->TxFrameRA)); |
6130 | printk(KERN_DEBUG "RA: %s\n", hexbuf); | ||
6131 | 5918 | ||
6132 | printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); | 5919 | printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); |
6133 | brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); | 5920 | print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, |
6134 | printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); | 5921 | rtspfb, sizeof(txh->RTSPLCPFallback)); |
6135 | printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); | 5922 | printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); |
6136 | brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); | 5923 | print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, |
6137 | printk(KERN_DEBUG "PLCP: %s ", hexbuf); | 5924 | fragpfb, sizeof(txh->FragPLCPFallback)); |
6138 | printk(KERN_DEBUG "DUR: %04x", fragdfb); | 5925 | printk(KERN_DEBUG "DUR: %04x", fragdfb); |
6139 | printk(KERN_DEBUG "\n"); | 5926 | printk(KERN_DEBUG "\n"); |
6140 | 5927 | ||
@@ -6149,18 +5936,18 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6149 | printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); | 5936 | printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); |
6150 | printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); | 5937 | printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); |
6151 | 5938 | ||
6152 | brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); | 5939 | print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, |
6153 | printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); | 5940 | rtsph, sizeof(txh->RTSPhyHeader)); |
6154 | brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); | 5941 | print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, |
6155 | printk(KERN_DEBUG "RTS Frame: %s", hexbuf); | 5942 | (u8 *)&rts, sizeof(txh->rts_frame)); |
6156 | printk(KERN_DEBUG "\n"); | 5943 | printk(KERN_DEBUG "\n"); |
6157 | } | 5944 | } |
6158 | #endif /* defined(BCMDBG) */ | 5945 | #endif /* defined(BCMDBG) */ |
6159 | 5946 | ||
6160 | #if defined(BCMDBG) | 5947 | #if defined(BCMDBG) |
6161 | int | 5948 | static int |
6162 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, | 5949 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, |
6163 | int len) | 5950 | int len) |
6164 | { | 5951 | { |
6165 | int i; | 5952 | int i; |
6166 | char *p = buf; | 5953 | char *p = buf; |
@@ -6916,7 +6703,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6916 | qos = ieee80211_is_data_qos(h->frame_control); | 6703 | qos = ieee80211_is_data_qos(h->frame_control); |
6917 | 6704 | ||
6918 | /* compute length of frame in bytes for use in PLCP computations */ | 6705 | /* compute length of frame in bytes for use in PLCP computations */ |
6919 | len = brcmu_pkttotlen(p); | 6706 | len = p->len; |
6920 | phylen = len + FCS_LEN; | 6707 | phylen = len + FCS_LEN; |
6921 | 6708 | ||
6922 | /* Get tx_info */ | 6709 | /* Get tx_info */ |
@@ -8253,12 +8040,6 @@ int brcms_c_get_tx_power(struct brcms_c_info *wlc) | |||
8253 | return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); | 8040 | return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); |
8254 | } | 8041 | } |
8255 | 8042 | ||
8256 | void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc) | ||
8257 | { | ||
8258 | wlc->mpc = mpc; | ||
8259 | brcms_c_radio_mpc_upd(wlc); | ||
8260 | } | ||
8261 | |||
8262 | /* Process received frames */ | 8043 | /* Process received frames */ |
8263 | /* | 8044 | /* |
8264 | * Return true if more frames need to be processed. false otherwise. | 8045 | * Return true if more frames need to be processed. false otherwise. |
@@ -8328,21 +8109,17 @@ static bool | |||
8328 | brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | 8109 | brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) |
8329 | { | 8110 | { |
8330 | struct sk_buff *p; | 8111 | struct sk_buff *p; |
8331 | struct sk_buff *head = NULL; | 8112 | struct sk_buff *next = NULL; |
8332 | struct sk_buff *tail = NULL; | 8113 | struct sk_buff_head recv_frames; |
8114 | |||
8333 | uint n = 0; | 8115 | uint n = 0; |
8334 | uint bound_limit = bound ? RXBND : -1; | 8116 | uint bound_limit = bound ? RXBND : -1; |
8335 | 8117 | ||
8336 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 8118 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); |
8337 | /* gather received frames */ | 8119 | skb_queue_head_init(&recv_frames); |
8338 | while ((p = dma_rx(wlc_hw->di[fifo]))) { | ||
8339 | 8120 | ||
8340 | if (!tail) | 8121 | /* gather received frames */ |
8341 | head = tail = p; | 8122 | while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { |
8342 | else { | ||
8343 | tail->prev = p; | ||
8344 | tail = p; | ||
8345 | } | ||
8346 | 8123 | ||
8347 | /* !give others some time to run! */ | 8124 | /* !give others some time to run! */ |
8348 | if (++n >= bound_limit) | 8125 | if (++n >= bound_limit) |
@@ -8353,12 +8130,11 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | |||
8353 | dma_rxfill(wlc_hw->di[fifo]); | 8130 | dma_rxfill(wlc_hw->di[fifo]); |
8354 | 8131 | ||
8355 | /* process each frame */ | 8132 | /* process each frame */ |
8356 | while ((p = head) != NULL) { | 8133 | skb_queue_walk_safe(&recv_frames, p, next) { |
8357 | struct d11rxhdr_le *rxh_le; | 8134 | struct d11rxhdr_le *rxh_le; |
8358 | struct d11rxhdr *rxh; | 8135 | struct d11rxhdr *rxh; |
8359 | head = head->prev; | ||
8360 | p->prev = NULL; | ||
8361 | 8136 | ||
8137 | skb_unlink(p, &recv_frames); | ||
8362 | rxh_le = (struct d11rxhdr_le *)p->data; | 8138 | rxh_le = (struct d11rxhdr_le *)p->data; |
8363 | rxh = (struct d11rxhdr *)p->data; | 8139 | rxh = (struct d11rxhdr *)p->data; |
8364 | 8140 | ||
@@ -8448,8 +8224,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8448 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", | 8224 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", |
8449 | __func__, wlc_hw->sih->chip, | 8225 | __func__, wlc_hw->sih->chip, |
8450 | wlc_hw->sih->chiprev); | 8226 | wlc_hw->sih->chiprev); |
8451 | /* big hammer */ | 8227 | brcms_fatal_error(wlc_hw->wlc->wl); |
8452 | brcms_init(wlc->wl); | ||
8453 | } | 8228 | } |
8454 | 8229 | ||
8455 | /* gptimer timeout */ | 8230 | /* gptimer timeout */ |
@@ -8470,15 +8245,14 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8470 | return wlc->macintstatus != 0; | 8245 | return wlc->macintstatus != 0; |
8471 | 8246 | ||
8472 | fatal: | 8247 | fatal: |
8473 | brcms_init(wlc->wl); | 8248 | brcms_fatal_error(wlc_hw->wlc->wl); |
8474 | return wlc->macintstatus != 0; | 8249 | return wlc->macintstatus != 0; |
8475 | } | 8250 | } |
8476 | 8251 | ||
8477 | void brcms_c_init(struct brcms_c_info *wlc) | 8252 | void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) |
8478 | { | 8253 | { |
8479 | struct d11regs __iomem *regs; | 8254 | struct d11regs __iomem *regs; |
8480 | u16 chanspec; | 8255 | u16 chanspec; |
8481 | bool mute = false; | ||
8482 | 8256 | ||
8483 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 8257 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); |
8484 | 8258 | ||
@@ -8494,7 +8268,7 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8494 | else | 8268 | else |
8495 | chanspec = brcms_c_init_chanspec(wlc); | 8269 | chanspec = brcms_c_init_chanspec(wlc); |
8496 | 8270 | ||
8497 | brcms_b_init(wlc->hw, chanspec, mute); | 8271 | brcms_b_init(wlc->hw, chanspec); |
8498 | 8272 | ||
8499 | /* update beacon listen interval */ | 8273 | /* update beacon listen interval */ |
8500 | brcms_c_bcn_li_upd(wlc); | 8274 | brcms_c_bcn_li_upd(wlc); |
@@ -8560,15 +8334,16 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8560 | /* ..now really unleash hell (allow the MAC out of suspend) */ | 8334 | /* ..now really unleash hell (allow the MAC out of suspend) */ |
8561 | brcms_c_enable_mac(wlc); | 8335 | brcms_c_enable_mac(wlc); |
8562 | 8336 | ||
8337 | /* suspend the tx fifos and mute the phy for preism cac time */ | ||
8338 | if (mute_tx) | ||
8339 | brcms_b_mute(wlc->hw, true); | ||
8340 | |||
8563 | /* clear tx flow control */ | 8341 | /* clear tx flow control */ |
8564 | brcms_c_txflowcontrol_reset(wlc); | 8342 | brcms_c_txflowcontrol_reset(wlc); |
8565 | 8343 | ||
8566 | /* enable the RF Disable Delay timer */ | 8344 | /* enable the RF Disable Delay timer */ |
8567 | W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); | 8345 | W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); |
8568 | 8346 | ||
8569 | /* initialize mpc delay */ | ||
8570 | wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
8571 | |||
8572 | /* | 8347 | /* |
8573 | * Initialize WME parameters; if they haven't been set by some other | 8348 | * Initialize WME parameters; if they haven't been set by some other |
8574 | * mechanism (IOVar, etc) then read them from the hardware. | 8349 | * mechanism (IOVar, etc) then read them from the hardware. |
@@ -8577,7 +8352,7 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8577 | /* Uninitialized; read from HW */ | 8352 | /* Uninitialized; read from HW */ |
8578 | int ac; | 8353 | int ac; |
8579 | 8354 | ||
8580 | for (ac = 0; ac < AC_COUNT; ac++) | 8355 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
8581 | wlc->wme_retries[ac] = | 8356 | wlc->wme_retries[ac] = |
8582 | brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac)); | 8357 | brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac)); |
8583 | } | 8358 | } |
@@ -8754,8 +8529,6 @@ brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, | |||
8754 | brcms_c_ht_update_sgi_rx(wlc, 0); | 8529 | brcms_c_ht_update_sgi_rx(wlc, 0); |
8755 | } | 8530 | } |
8756 | 8531 | ||
8757 | /* initialize radio_mpc_disable according to wlc->mpc */ | ||
8758 | brcms_c_radio_mpc_upd(wlc); | ||
8759 | brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); | 8532 | brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); |
8760 | 8533 | ||
8761 | if (perr) | 8534 | if (perr) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index c0e0fcfdfaf8..251c350b3164 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h | |||
@@ -44,8 +44,6 @@ | |||
44 | /* transmit buffer max headroom for protocol headers */ | 44 | /* transmit buffer max headroom for protocol headers */ |
45 | #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) | 45 | #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) |
46 | 46 | ||
47 | #define AC_COUNT 4 | ||
48 | |||
49 | /* Macros for doing definition and get/set of bitfields | 47 | /* Macros for doing definition and get/set of bitfields |
50 | * Usage example, e.g. a three-bit field (bits 4-6): | 48 | * Usage example, e.g. a three-bit field (bits 4-6): |
51 | * #define <NAME>_M BITFIELD_MASK(3) | 49 | * #define <NAME>_M BITFIELD_MASK(3) |
@@ -427,11 +425,6 @@ struct brcms_txq_info { | |||
427 | * bandinit_pending: track band init in auto band. | 425 | * bandinit_pending: track band init in auto band. |
428 | * radio_monitor: radio timer is running. | 426 | * radio_monitor: radio timer is running. |
429 | * going_down: down path intermediate variable. | 427 | * going_down: down path intermediate variable. |
430 | * mpc: enable minimum power consumption. | ||
431 | * mpc_dlycnt: # of watchdog cnt before turn disable radio. | ||
432 | * mpc_offcnt: # of watchdog cnt that radio is disabled. | ||
433 | * mpc_delay_off: delay radio disable by # of watchdog cnt. | ||
434 | * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc. | ||
435 | * wdtimer: timer for watchdog routine. | 428 | * wdtimer: timer for watchdog routine. |
436 | * radio_timer: timer for hw radio button monitor routine. | 429 | * radio_timer: timer for hw radio button monitor routine. |
437 | * monitor: monitor (MPDU sniffing) mode. | 430 | * monitor: monitor (MPDU sniffing) mode. |
@@ -441,7 +434,7 @@ struct brcms_txq_info { | |||
441 | * bcn_li_dtim: beacon listen interval in # dtims. | 434 | * bcn_li_dtim: beacon listen interval in # dtims. |
442 | * WDarmed: watchdog timer is armed. | 435 | * WDarmed: watchdog timer is armed. |
443 | * WDlast: last time wlc_watchdog() was called. | 436 | * WDlast: last time wlc_watchdog() was called. |
444 | * edcf_txop[AC_COUNT]: current txop for each ac. | 437 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. |
445 | * wme_retries: per-AC retry limits. | 438 | * wme_retries: per-AC retry limits. |
446 | * tx_prec_map: Precedence map based on HW FIFO space. | 439 | * tx_prec_map: Precedence map based on HW FIFO space. |
447 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. | 440 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. |
@@ -522,12 +515,6 @@ struct brcms_c_info { | |||
522 | bool radio_monitor; | 515 | bool radio_monitor; |
523 | bool going_down; | 516 | bool going_down; |
524 | 517 | ||
525 | bool mpc; | ||
526 | u8 mpc_dlycnt; | ||
527 | u8 mpc_offcnt; | ||
528 | u8 mpc_delay_off; | ||
529 | u8 prev_non_delay_mpc; | ||
530 | |||
531 | struct brcms_timer *wdtimer; | 518 | struct brcms_timer *wdtimer; |
532 | struct brcms_timer *radio_timer; | 519 | struct brcms_timer *radio_timer; |
533 | 520 | ||
@@ -546,9 +533,9 @@ struct brcms_c_info { | |||
546 | u32 WDlast; | 533 | u32 WDlast; |
547 | 534 | ||
548 | /* WME */ | 535 | /* WME */ |
549 | u16 edcf_txop[AC_COUNT]; | 536 | u16 edcf_txop[IEEE80211_NUM_ACS]; |
550 | 537 | ||
551 | u16 wme_retries[AC_COUNT]; | 538 | u16 wme_retries[IEEE80211_NUM_ACS]; |
552 | u16 tx_prec_map; | 539 | u16 tx_prec_map; |
553 | u16 fifo2prec_map[NFIFO]; | 540 | u16 fifo2prec_map[NFIFO]; |
554 | 541 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c index a3149254cbcd..e17edf7e6833 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | |||
@@ -112,7 +112,7 @@ static const struct chan_info_basic chan_info_all[] = { | |||
112 | {216, 50800} | 112 | {216, 50800} |
113 | }; | 113 | }; |
114 | 114 | ||
115 | const u8 ofdm_rate_lookup[] = { | 115 | static const u8 ofdm_rate_lookup[] = { |
116 | 116 | ||
117 | BRCM_RATE_48M, | 117 | BRCM_RATE_48M, |
118 | BRCM_RATE_24M, | 118 | BRCM_RATE_24M, |
@@ -190,15 +190,7 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr) | |||
190 | data = R_REG(&pi->regs->radioregdata); | 190 | data = R_REG(&pi->regs->radioregdata); |
191 | } else { | 191 | } else { |
192 | W_REG_FLUSH(&pi->regs->phy4waddr, addr); | 192 | W_REG_FLUSH(&pi->regs->phy4waddr, addr); |
193 | |||
194 | #ifdef __ARM_ARCH_4T__ | ||
195 | __asm__(" .align 4 "); | ||
196 | __asm__(" nop "); | ||
197 | data = R_REG(&pi->regs->phy4wdatalo); | ||
198 | #else | ||
199 | data = R_REG(&pi->regs->phy4wdatalo); | 193 | data = R_REG(&pi->regs->phy4wdatalo); |
200 | #endif | ||
201 | |||
202 | } | 194 | } |
203 | pi->phy_wreg = 0; | 195 | pi->phy_wreg = 0; |
204 | 196 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h index bea85241a244..5f9478b1c993 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h | |||
@@ -774,11 +774,6 @@ struct brcms_phy { | |||
774 | s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; | 774 | s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; |
775 | u8 nphy_noise_index; | 775 | u8 nphy_noise_index; |
776 | 776 | ||
777 | u8 nphy_txpid2g[PHY_CORE_NUM_2]; | ||
778 | u8 nphy_txpid5g[PHY_CORE_NUM_2]; | ||
779 | u8 nphy_txpid5gl[PHY_CORE_NUM_2]; | ||
780 | u8 nphy_txpid5gh[PHY_CORE_NUM_2]; | ||
781 | |||
782 | bool nphy_gain_boost; | 777 | bool nphy_gain_boost; |
783 | bool nphy_elna_gain_config; | 778 | bool nphy_elna_gain_config; |
784 | u16 old_bphy_test; | 779 | u16 old_bphy_test; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index cd19c2f7a347..ec9b56639d54 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "phy_radio.h" | 29 | #include "phy_radio.h" |
30 | #include "phyreg_n.h" | 30 | #include "phyreg_n.h" |
31 | #include "phytbl_n.h" | 31 | #include "phytbl_n.h" |
32 | #include "soc.h" | ||
32 | 33 | ||
33 | #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ | 34 | #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ |
34 | read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ | 35 | read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ |
@@ -14417,12 +14418,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14417 | switch (band_num) { | 14418 | switch (band_num) { |
14418 | case 0: | 14419 | case 0: |
14419 | 14420 | ||
14420 | pi->nphy_txpid2g[PHY_CORE_0] = | ||
14421 | (u8) wlapi_getintvar(shim, | ||
14422 | BRCMS_SROM_TXPID2GA0); | ||
14423 | pi->nphy_txpid2g[PHY_CORE_1] = | ||
14424 | (u8) wlapi_getintvar(shim, | ||
14425 | BRCMS_SROM_TXPID2GA1); | ||
14426 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = | 14421 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = |
14427 | (s8) wlapi_getintvar(shim, | 14422 | (s8) wlapi_getintvar(shim, |
14428 | BRCMS_SROM_MAXP2GA0); | 14423 | BRCMS_SROM_MAXP2GA0); |
@@ -14486,12 +14481,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14486 | break; | 14481 | break; |
14487 | case 1: | 14482 | case 1: |
14488 | 14483 | ||
14489 | pi->nphy_txpid5g[PHY_CORE_0] = | ||
14490 | (u8) wlapi_getintvar(shim, | ||
14491 | BRCMS_SROM_TXPID5GA0); | ||
14492 | pi->nphy_txpid5g[PHY_CORE_1] = | ||
14493 | (u8) wlapi_getintvar(shim, | ||
14494 | BRCMS_SROM_TXPID5GA1); | ||
14495 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = | 14484 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = |
14496 | (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); | 14485 | (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); |
14497 | pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = | 14486 | pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = |
@@ -14551,12 +14540,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14551 | break; | 14540 | break; |
14552 | case 2: | 14541 | case 2: |
14553 | 14542 | ||
14554 | pi->nphy_txpid5gl[0] = | ||
14555 | (u8) wlapi_getintvar(shim, | ||
14556 | BRCMS_SROM_TXPID5GLA0); | ||
14557 | pi->nphy_txpid5gl[1] = | ||
14558 | (u8) wlapi_getintvar(shim, | ||
14559 | BRCMS_SROM_TXPID5GLA1); | ||
14560 | pi->nphy_pwrctrl_info[0].max_pwr_5gl = | 14543 | pi->nphy_pwrctrl_info[0].max_pwr_5gl = |
14561 | (s8) wlapi_getintvar(shim, | 14544 | (s8) wlapi_getintvar(shim, |
14562 | BRCMS_SROM_MAXP5GLA0); | 14545 | BRCMS_SROM_MAXP5GLA0); |
@@ -14615,12 +14598,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14615 | break; | 14598 | break; |
14616 | case 3: | 14599 | case 3: |
14617 | 14600 | ||
14618 | pi->nphy_txpid5gh[0] = | ||
14619 | (u8) wlapi_getintvar(shim, | ||
14620 | BRCMS_SROM_TXPID5GHA0); | ||
14621 | pi->nphy_txpid5gh[1] = | ||
14622 | (u8) wlapi_getintvar(shim, | ||
14623 | BRCMS_SROM_TXPID5GHA1); | ||
14624 | pi->nphy_pwrctrl_info[0].max_pwr_5gh = | 14601 | pi->nphy_pwrctrl_info[0].max_pwr_5gh = |
14625 | (s8) wlapi_getintvar(shim, | 14602 | (s8) wlapi_getintvar(shim, |
14626 | BRCMS_SROM_MAXP5GHA0); | 14603 | BRCMS_SROM_MAXP5GHA0); |
@@ -27994,20 +27971,11 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) | |||
27994 | chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); | 27971 | chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); |
27995 | switch (chan_freq_range) { | 27972 | switch (chan_freq_range) { |
27996 | case WL_CHAN_FREQ_RANGE_2G: | 27973 | case WL_CHAN_FREQ_RANGE_2G: |
27997 | txpi[0] = pi->nphy_txpid2g[0]; | ||
27998 | txpi[1] = pi->nphy_txpid2g[1]; | ||
27999 | break; | ||
28000 | case WL_CHAN_FREQ_RANGE_5GL: | 27974 | case WL_CHAN_FREQ_RANGE_5GL: |
28001 | txpi[0] = pi->nphy_txpid5gl[0]; | ||
28002 | txpi[1] = pi->nphy_txpid5gl[1]; | ||
28003 | break; | ||
28004 | case WL_CHAN_FREQ_RANGE_5GM: | 27975 | case WL_CHAN_FREQ_RANGE_5GM: |
28005 | txpi[0] = pi->nphy_txpid5g[0]; | ||
28006 | txpi[1] = pi->nphy_txpid5g[1]; | ||
28007 | break; | ||
28008 | case WL_CHAN_FREQ_RANGE_5GH: | 27976 | case WL_CHAN_FREQ_RANGE_5GH: |
28009 | txpi[0] = pi->nphy_txpid5gh[0]; | 27977 | txpi[0] = 0; |
28010 | txpi[1] = pi->nphy_txpid5gh[1]; | 27978 | txpi[1] = 0; |
28011 | break; | 27979 | break; |
28012 | default: | 27980 | default: |
28013 | txpi[0] = txpi[1] = 91; | 27981 | txpi[0] = txpi[1] = 91; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c index 3b36e3acfd74..12ba575f5785 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "pub.h" | 23 | #include "pub.h" |
24 | #include "aiutils.h" | 24 | #include "aiutils.h" |
25 | #include "pmu.h" | 25 | #include "pmu.h" |
26 | #include "soc.h" | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * external LPO crystal frequency | 29 | * external LPO crystal frequency |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 37bb2dcc113f..21ccf3a03987 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h | |||
@@ -170,22 +170,6 @@ enum brcms_srom_id { | |||
170 | BRCMS_SROM_TSSIPOS2G, | 170 | BRCMS_SROM_TSSIPOS2G, |
171 | BRCMS_SROM_TSSIPOS5G, | 171 | BRCMS_SROM_TSSIPOS5G, |
172 | BRCMS_SROM_TXCHAIN, | 172 | BRCMS_SROM_TXCHAIN, |
173 | BRCMS_SROM_TXPID2GA0, | ||
174 | BRCMS_SROM_TXPID2GA1, | ||
175 | BRCMS_SROM_TXPID2GA2, | ||
176 | BRCMS_SROM_TXPID2GA3, | ||
177 | BRCMS_SROM_TXPID5GA0, | ||
178 | BRCMS_SROM_TXPID5GA1, | ||
179 | BRCMS_SROM_TXPID5GA2, | ||
180 | BRCMS_SROM_TXPID5GA3, | ||
181 | BRCMS_SROM_TXPID5GHA0, | ||
182 | BRCMS_SROM_TXPID5GHA1, | ||
183 | BRCMS_SROM_TXPID5GHA2, | ||
184 | BRCMS_SROM_TXPID5GHA3, | ||
185 | BRCMS_SROM_TXPID5GLA0, | ||
186 | BRCMS_SROM_TXPID5GLA1, | ||
187 | BRCMS_SROM_TXPID5GLA2, | ||
188 | BRCMS_SROM_TXPID5GLA3, | ||
189 | /* | 173 | /* |
190 | * per-path identifiers (see srom.c) | 174 | * per-path identifiers (see srom.c) |
191 | */ | 175 | */ |
@@ -225,10 +209,6 @@ enum brcms_srom_id { | |||
225 | BRCMS_SROM_PA2GW2A1, | 209 | BRCMS_SROM_PA2GW2A1, |
226 | BRCMS_SROM_PA2GW2A2, | 210 | BRCMS_SROM_PA2GW2A2, |
227 | BRCMS_SROM_PA2GW2A3, | 211 | BRCMS_SROM_PA2GW2A3, |
228 | BRCMS_SROM_PA2GW3A0, | ||
229 | BRCMS_SROM_PA2GW3A1, | ||
230 | BRCMS_SROM_PA2GW3A2, | ||
231 | BRCMS_SROM_PA2GW3A3, | ||
232 | BRCMS_SROM_PA5GHW0A0, | 212 | BRCMS_SROM_PA5GHW0A0, |
233 | BRCMS_SROM_PA5GHW0A1, | 213 | BRCMS_SROM_PA5GHW0A1, |
234 | BRCMS_SROM_PA5GHW0A2, | 214 | BRCMS_SROM_PA5GHW0A2, |
@@ -241,10 +221,6 @@ enum brcms_srom_id { | |||
241 | BRCMS_SROM_PA5GHW2A1, | 221 | BRCMS_SROM_PA5GHW2A1, |
242 | BRCMS_SROM_PA5GHW2A2, | 222 | BRCMS_SROM_PA5GHW2A2, |
243 | BRCMS_SROM_PA5GHW2A3, | 223 | BRCMS_SROM_PA5GHW2A3, |
244 | BRCMS_SROM_PA5GHW3A0, | ||
245 | BRCMS_SROM_PA5GHW3A1, | ||
246 | BRCMS_SROM_PA5GHW3A2, | ||
247 | BRCMS_SROM_PA5GHW3A3, | ||
248 | BRCMS_SROM_PA5GLW0A0, | 224 | BRCMS_SROM_PA5GLW0A0, |
249 | BRCMS_SROM_PA5GLW0A1, | 225 | BRCMS_SROM_PA5GLW0A1, |
250 | BRCMS_SROM_PA5GLW0A2, | 226 | BRCMS_SROM_PA5GLW0A2, |
@@ -257,10 +233,6 @@ enum brcms_srom_id { | |||
257 | BRCMS_SROM_PA5GLW2A1, | 233 | BRCMS_SROM_PA5GLW2A1, |
258 | BRCMS_SROM_PA5GLW2A2, | 234 | BRCMS_SROM_PA5GLW2A2, |
259 | BRCMS_SROM_PA5GLW2A3, | 235 | BRCMS_SROM_PA5GLW2A3, |
260 | BRCMS_SROM_PA5GLW3A0, | ||
261 | BRCMS_SROM_PA5GLW3A1, | ||
262 | BRCMS_SROM_PA5GLW3A2, | ||
263 | BRCMS_SROM_PA5GLW3A3, | ||
264 | BRCMS_SROM_PA5GW0A0, | 236 | BRCMS_SROM_PA5GW0A0, |
265 | BRCMS_SROM_PA5GW0A1, | 237 | BRCMS_SROM_PA5GW0A1, |
266 | BRCMS_SROM_PA5GW0A2, | 238 | BRCMS_SROM_PA5GW0A2, |
@@ -273,14 +245,9 @@ enum brcms_srom_id { | |||
273 | BRCMS_SROM_PA5GW2A1, | 245 | BRCMS_SROM_PA5GW2A1, |
274 | BRCMS_SROM_PA5GW2A2, | 246 | BRCMS_SROM_PA5GW2A2, |
275 | BRCMS_SROM_PA5GW2A3, | 247 | BRCMS_SROM_PA5GW2A3, |
276 | BRCMS_SROM_PA5GW3A0, | ||
277 | BRCMS_SROM_PA5GW3A1, | ||
278 | BRCMS_SROM_PA5GW3A2, | ||
279 | BRCMS_SROM_PA5GW3A3, | ||
280 | }; | 248 | }; |
281 | 249 | ||
282 | #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ | 250 | #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ |
283 | #define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ | ||
284 | 251 | ||
285 | /* phy types */ | 252 | /* phy types */ |
286 | #define PHY_TYPE_A 0 /* Phy type A */ | 253 | #define PHY_TYPE_A 0 /* Phy type A */ |
@@ -414,7 +381,6 @@ struct brcms_pub { | |||
414 | uint _nbands; /* # bands supported */ | 381 | uint _nbands; /* # bands supported */ |
415 | uint now; /* # elapsed seconds */ | 382 | uint now; /* # elapsed seconds */ |
416 | 383 | ||
417 | bool promisc; /* promiscuous destination address */ | ||
418 | bool delayed_down; /* down delayed */ | 384 | bool delayed_down; /* down delayed */ |
419 | bool associated; /* true:part of [I]BSS, false: not */ | 385 | bool associated; /* true:part of [I]BSS, false: not */ |
420 | /* (union of stas_associated, aps_associated) */ | 386 | /* (union of stas_associated, aps_associated) */ |
@@ -572,7 +538,7 @@ extern int brcms_c_up(struct brcms_c_info *wlc); | |||
572 | extern uint brcms_c_down(struct brcms_c_info *wlc); | 538 | extern uint brcms_c_down(struct brcms_c_info *wlc); |
573 | 539 | ||
574 | extern bool brcms_c_chipmatch(u16 vendor, u16 device); | 540 | extern bool brcms_c_chipmatch(u16 vendor, u16 device); |
575 | extern void brcms_c_init(struct brcms_c_info *wlc); | 541 | extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); |
576 | extern void brcms_c_reset(struct brcms_c_info *wlc); | 542 | extern void brcms_c_reset(struct brcms_c_info *wlc); |
577 | 543 | ||
578 | extern void brcms_c_intrson(struct brcms_c_info *wlc); | 544 | extern void brcms_c_intrson(struct brcms_c_info *wlc); |
@@ -628,7 +594,7 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, | |||
628 | u8 interval); | 594 | u8 interval); |
629 | extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); | 595 | extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); |
630 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); | 596 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); |
631 | extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc); | ||
632 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); | 597 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); |
598 | extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); | ||
633 | 599 | ||
634 | #endif /* _BRCM_PUB_H_ */ | 600 | #endif /* _BRCM_PUB_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h index e7b9dc2f2731..980d578825cc 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/rate.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "types.h" | 20 | #include "types.h" |
21 | #include "d11.h" | 21 | #include "d11.h" |
22 | #include "phy_hal.h" | ||
22 | 23 | ||
23 | extern const u8 rate_info[]; | 24 | extern const u8 rate_info[]; |
24 | extern const struct brcms_c_rateset cck_ofdm_mimo_rates; | 25 | extern const struct brcms_c_rateset cck_ofdm_mimo_rates; |
@@ -198,11 +199,9 @@ static inline u8 cck_rspec(u8 cck) | |||
198 | 199 | ||
199 | /* Convert encoded rate value in plcp header to numerical rates in 500 KHz | 200 | /* Convert encoded rate value in plcp header to numerical rates in 500 KHz |
200 | * increments */ | 201 | * increments */ |
201 | extern const u8 ofdm_rate_lookup[]; | ||
202 | |||
203 | static inline u8 ofdm_phy2mac_rate(u8 rlpt) | 202 | static inline u8 ofdm_phy2mac_rate(u8 rlpt) |
204 | { | 203 | { |
205 | return ofdm_rate_lookup[rlpt & 0x7]; | 204 | return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7]; |
206 | } | 205 | } |
207 | 206 | ||
208 | static inline u8 cck_phy2mac_rate(u8 signal) | 207 | static inline u8 cck_phy2mac_rate(u8 signal) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c index 99f791048e84..b6987ea9fc68 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "aiutils.h" | 28 | #include "aiutils.h" |
29 | #include "otp.h" | 29 | #include "otp.h" |
30 | #include "srom.h" | 30 | #include "srom.h" |
31 | #include "soc.h" | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * SROM CRC8 polynomial value: | 34 | * SROM CRC8 polynomial value: |
@@ -62,9 +63,6 @@ | |||
62 | #define SROM_MACHI_ET1 42 | 63 | #define SROM_MACHI_ET1 42 |
63 | #define SROM_MACMID_ET1 43 | 64 | #define SROM_MACMID_ET1 43 |
64 | #define SROM_MACLO_ET1 44 | 65 | #define SROM_MACLO_ET1 44 |
65 | #define SROM3_MACHI 37 | ||
66 | #define SROM3_MACMID 38 | ||
67 | #define SROM3_MACLO 39 | ||
68 | 66 | ||
69 | #define SROM_BXARSSI2G 40 | 67 | #define SROM_BXARSSI2G 40 |
70 | #define SROM_BXARSSI5G 41 | 68 | #define SROM_BXARSSI5G 41 |
@@ -101,7 +99,6 @@ | |||
101 | 99 | ||
102 | #define SROM_BFL 57 | 100 | #define SROM_BFL 57 |
103 | #define SROM_BFL2 28 | 101 | #define SROM_BFL2 28 |
104 | #define SROM3_BFL2 61 | ||
105 | 102 | ||
106 | #define SROM_AG10 58 | 103 | #define SROM_AG10 58 |
107 | 104 | ||
@@ -109,99 +106,16 @@ | |||
109 | 106 | ||
110 | #define SROM_OPO 60 | 107 | #define SROM_OPO 60 |
111 | 108 | ||
112 | #define SROM3_LEDDC 62 | ||
113 | |||
114 | #define SROM_CRCREV 63 | 109 | #define SROM_CRCREV 63 |
115 | 110 | ||
116 | /* SROM Rev 4: Reallocate the software part of the srom to accommodate | ||
117 | * MIMO features. It assumes up to two PCIE functions and 440 bytes | ||
118 | * of usable srom i.e. the usable storage in chips with OTP that | ||
119 | * implements hardware redundancy. | ||
120 | */ | ||
121 | |||
122 | #define SROM4_WORDS 220 | 111 | #define SROM4_WORDS 220 |
123 | 112 | ||
124 | #define SROM4_SIGN 32 | ||
125 | #define SROM4_SIGNATURE 0x5372 | ||
126 | |||
127 | #define SROM4_BREV 33 | ||
128 | |||
129 | #define SROM4_BFL0 34 | ||
130 | #define SROM4_BFL1 35 | ||
131 | #define SROM4_BFL2 36 | ||
132 | #define SROM4_BFL3 37 | ||
133 | #define SROM5_BFL0 37 | ||
134 | #define SROM5_BFL1 38 | ||
135 | #define SROM5_BFL2 39 | ||
136 | #define SROM5_BFL3 40 | ||
137 | |||
138 | #define SROM4_MACHI 38 | ||
139 | #define SROM4_MACMID 39 | ||
140 | #define SROM4_MACLO 40 | ||
141 | #define SROM5_MACHI 41 | ||
142 | #define SROM5_MACMID 42 | ||
143 | #define SROM5_MACLO 43 | ||
144 | |||
145 | #define SROM4_CCODE 41 | ||
146 | #define SROM4_REGREV 42 | ||
147 | #define SROM5_CCODE 34 | ||
148 | #define SROM5_REGREV 35 | ||
149 | |||
150 | #define SROM4_LEDBH10 43 | ||
151 | #define SROM4_LEDBH32 44 | ||
152 | #define SROM5_LEDBH10 59 | ||
153 | #define SROM5_LEDBH32 60 | ||
154 | |||
155 | #define SROM4_LEDDC 45 | ||
156 | #define SROM5_LEDDC 45 | ||
157 | |||
158 | #define SROM4_AA 46 | ||
159 | |||
160 | #define SROM4_AG10 47 | ||
161 | #define SROM4_AG32 48 | ||
162 | |||
163 | #define SROM4_TXPID2G 49 | ||
164 | #define SROM4_TXPID5G 51 | ||
165 | #define SROM4_TXPID5GL 53 | ||
166 | #define SROM4_TXPID5GH 55 | ||
167 | |||
168 | #define SROM4_TXRXC 61 | ||
169 | #define SROM4_TXCHAIN_MASK 0x000f | 113 | #define SROM4_TXCHAIN_MASK 0x000f |
170 | #define SROM4_TXCHAIN_SHIFT 0 | ||
171 | #define SROM4_RXCHAIN_MASK 0x00f0 | 114 | #define SROM4_RXCHAIN_MASK 0x00f0 |
172 | #define SROM4_RXCHAIN_SHIFT 4 | ||
173 | #define SROM4_SWITCH_MASK 0xff00 | 115 | #define SROM4_SWITCH_MASK 0xff00 |
174 | #define SROM4_SWITCH_SHIFT 8 | ||
175 | 116 | ||
176 | /* Per-path fields */ | 117 | /* Per-path fields */ |
177 | #define MAX_PATH_SROM 4 | 118 | #define MAX_PATH_SROM 4 |
178 | #define SROM4_PATH0 64 | ||
179 | #define SROM4_PATH1 87 | ||
180 | #define SROM4_PATH2 110 | ||
181 | #define SROM4_PATH3 133 | ||
182 | |||
183 | #define SROM4_2G_ITT_MAXP 0 | ||
184 | #define SROM4_2G_PA 1 | ||
185 | #define SROM4_5G_ITT_MAXP 5 | ||
186 | #define SROM4_5GLH_MAXP 6 | ||
187 | #define SROM4_5G_PA 7 | ||
188 | #define SROM4_5GL_PA 11 | ||
189 | #define SROM4_5GH_PA 15 | ||
190 | |||
191 | /* All the miriad power offsets */ | ||
192 | #define SROM4_2G_CCKPO 156 | ||
193 | #define SROM4_2G_OFDMPO 157 | ||
194 | #define SROM4_5G_OFDMPO 159 | ||
195 | #define SROM4_5GL_OFDMPO 161 | ||
196 | #define SROM4_5GH_OFDMPO 163 | ||
197 | #define SROM4_2G_MCSPO 165 | ||
198 | #define SROM4_5G_MCSPO 173 | ||
199 | #define SROM4_5GL_MCSPO 181 | ||
200 | #define SROM4_5GH_MCSPO 189 | ||
201 | #define SROM4_CDDPO 197 | ||
202 | #define SROM4_STBCPO 198 | ||
203 | #define SROM4_BW40PO 199 | ||
204 | #define SROM4_BWDUPPO 200 | ||
205 | 119 | ||
206 | #define SROM4_CRCREV 219 | 120 | #define SROM4_CRCREV 219 |
207 | 121 | ||
@@ -424,103 +338,32 @@ struct brcms_varbuf { | |||
424 | static const struct brcms_sromvar pci_sromvars[] = { | 338 | static const struct brcms_sromvar pci_sromvars[] = { |
425 | {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, | 339 | {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, |
426 | 0xffff}, | 340 | 0xffff}, |
427 | {BRCMS_SROM_BOARDREV, 0x0000000e, SRFL_PRHEX, SROM_AABREV, | ||
428 | SROM_BR_MASK}, | ||
429 | {BRCMS_SROM_BOARDREV, 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, | ||
430 | {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, | 341 | {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, |
431 | {BRCMS_SROM_BOARDFLAGS, 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, | ||
432 | {BRCMS_SROM_BOARDFLAGS, 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, | ||
433 | 0xffff}, | ||
434 | {BRCMS_SROM_CONT, 0, 0, SROM_BFL2, 0xffff}, | ||
435 | {BRCMS_SROM_BOARDFLAGS, 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, | ||
436 | 0xffff}, | ||
437 | {BRCMS_SROM_CONT, 0, 0, SROM3_BFL2, 0xffff}, | ||
438 | {BRCMS_SROM_BOARDFLAGS, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, | ||
439 | 0xffff}, | ||
440 | {BRCMS_SROM_CONT, 0, 0, SROM4_BFL1, 0xffff}, | ||
441 | {BRCMS_SROM_BOARDFLAGS, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, | ||
442 | 0xffff}, | ||
443 | {BRCMS_SROM_CONT, 0, 0, SROM5_BFL1, 0xffff}, | ||
444 | {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, | 342 | {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, |
445 | 0xffff}, | 343 | 0xffff}, |
446 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, | 344 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, |
447 | {BRCMS_SROM_BOARDFLAGS2, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, | ||
448 | 0xffff}, | ||
449 | {BRCMS_SROM_CONT, 0, 0, SROM4_BFL3, 0xffff}, | ||
450 | {BRCMS_SROM_BOARDFLAGS2, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, | ||
451 | 0xffff}, | ||
452 | {BRCMS_SROM_CONT, 0, 0, SROM5_BFL3, 0xffff}, | ||
453 | {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, | 345 | {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, |
454 | 0xffff}, | 346 | 0xffff}, |
455 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, | 347 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, |
456 | {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, | 348 | {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, |
457 | {BRCMS_SROM_BOARDNUM, 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, | ||
458 | {BRCMS_SROM_BOARDNUM, 0x00000008, 0, SROM3_MACLO, 0xffff}, | ||
459 | {BRCMS_SROM_BOARDNUM, 0x00000010, 0, SROM4_MACLO, 0xffff}, | ||
460 | {BRCMS_SROM_BOARDNUM, 0x000000e0, 0, SROM5_MACLO, 0xffff}, | ||
461 | {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, | 349 | {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, |
462 | {BRCMS_SROM_CC, 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, | ||
463 | {BRCMS_SROM_REGREV, 0x00000008, 0, SROM_OPO, 0xff00}, | ||
464 | {BRCMS_SROM_REGREV, 0x00000010, 0, SROM4_REGREV, 0x00ff}, | ||
465 | {BRCMS_SROM_REGREV, 0x000000e0, 0, SROM5_REGREV, 0x00ff}, | ||
466 | {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, | 350 | {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, |
467 | {BRCMS_SROM_LEDBH0, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, | ||
468 | {BRCMS_SROM_LEDBH1, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, | ||
469 | {BRCMS_SROM_LEDBH2, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, | ||
470 | {BRCMS_SROM_LEDBH3, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, | ||
471 | {BRCMS_SROM_LEDBH0, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, | ||
472 | {BRCMS_SROM_LEDBH1, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, | ||
473 | {BRCMS_SROM_LEDBH2, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, | ||
474 | {BRCMS_SROM_LEDBH3, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, | ||
475 | {BRCMS_SROM_LEDBH0, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, | ||
476 | {BRCMS_SROM_LEDBH1, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, | ||
477 | {BRCMS_SROM_LEDBH2, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, | ||
478 | {BRCMS_SROM_LEDBH3, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, | ||
479 | {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, | 351 | {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, |
480 | {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, | 352 | {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, |
481 | {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, | 353 | {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, |
482 | {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, | 354 | {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, |
483 | {BRCMS_SROM_PA0B0, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, | ||
484 | {BRCMS_SROM_PA0B1, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, | ||
485 | {BRCMS_SROM_PA0B2, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, | ||
486 | {BRCMS_SROM_PA0ITSSIT, 0x0000000e, 0, SROM_ITT, 0x00ff}, | ||
487 | {BRCMS_SROM_PA0MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, | ||
488 | {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, | 355 | {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, |
489 | {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, | 356 | {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, |
490 | {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, | 357 | {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, |
491 | {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, | 358 | {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, |
492 | {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, | 359 | {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, |
493 | {BRCMS_SROM_OPO, 0x0000000c, 0, SROM_OPO, 0x00ff}, | ||
494 | {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, | 360 | {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, |
495 | {BRCMS_SROM_AA2G, 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, | ||
496 | {BRCMS_SROM_AA2G, 0x000000f0, 0, SROM4_AA, 0x00ff}, | ||
497 | {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, | 361 | {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, |
498 | {BRCMS_SROM_AA5G, 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, | ||
499 | {BRCMS_SROM_AA5G, 0x000000f0, 0, SROM4_AA, 0xff00}, | ||
500 | {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, | 362 | {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, |
501 | {BRCMS_SROM_AG0, 0x0000000e, 0, SROM_AG10, 0x00ff}, | ||
502 | {BRCMS_SROM_AG1, 0x0000000e, 0, SROM_AG10, 0xff00}, | ||
503 | {BRCMS_SROM_AG0, 0x000000f0, 0, SROM4_AG10, 0x00ff}, | ||
504 | {BRCMS_SROM_AG1, 0x000000f0, 0, SROM4_AG10, 0xff00}, | ||
505 | {BRCMS_SROM_AG2, 0x000000f0, 0, SROM4_AG32, 0x00ff}, | ||
506 | {BRCMS_SROM_AG3, 0x000000f0, 0, SROM4_AG32, 0xff00}, | ||
507 | {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, | 363 | {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, |
508 | {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, | 364 | {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, |
509 | {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, | 365 | {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, |
510 | {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, | 366 | {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, |
511 | {BRCMS_SROM_PA1B0, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, | ||
512 | {BRCMS_SROM_PA1B1, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, | ||
513 | {BRCMS_SROM_PA1B2, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, | ||
514 | {BRCMS_SROM_PA1LOB0, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, | ||
515 | {BRCMS_SROM_PA1LOB1, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, | ||
516 | {BRCMS_SROM_PA1LOB2, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, | ||
517 | {BRCMS_SROM_PA1HIB0, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, | ||
518 | {BRCMS_SROM_PA1HIB1, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, | ||
519 | {BRCMS_SROM_PA1HIB2, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, | ||
520 | {BRCMS_SROM_PA1ITSSIT, 0x0000000e, 0, SROM_ITT, 0xff00}, | ||
521 | {BRCMS_SROM_PA1MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, | ||
522 | {BRCMS_SROM_PA1LOMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, | ||
523 | {BRCMS_SROM_PA1HIMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, | ||
524 | {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, | 367 | {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, |
525 | {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, | 368 | {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, |
526 | {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, | 369 | {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, |
@@ -534,40 +377,20 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
534 | {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, | 377 | {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, |
535 | {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, | 378 | {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, |
536 | {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, | 379 | {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, |
537 | {BRCMS_SROM_BXA2G, 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, | ||
538 | {BRCMS_SROM_RSSISAV2G, 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, | ||
539 | {BRCMS_SROM_RSSISMC2G, 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, | ||
540 | {BRCMS_SROM_RSSISMF2G, 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, | ||
541 | {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, | 380 | {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, |
542 | {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, | 381 | {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, |
543 | {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, | 382 | {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, |
544 | {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, | 383 | {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, |
545 | {BRCMS_SROM_BXA5G, 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, | ||
546 | {BRCMS_SROM_RSSISAV5G, 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, | ||
547 | {BRCMS_SROM_RSSISMC5G, 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, | ||
548 | {BRCMS_SROM_RSSISMF5G, 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, | ||
549 | {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, | 384 | {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, |
550 | {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, | 385 | {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, |
551 | {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, | 386 | {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, |
552 | {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, | 387 | {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, |
553 | {BRCMS_SROM_TRI2G, 0x00000008, 0, SROM_TRI52G, 0x00ff}, | ||
554 | {BRCMS_SROM_TRI5G, 0x00000008, 0, SROM_TRI52G, 0xff00}, | ||
555 | {BRCMS_SROM_TRI5GL, 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, | ||
556 | {BRCMS_SROM_TRI5GH, 0x00000008, 0, SROM_TRI5GHL, 0xff00}, | ||
557 | {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, | 388 | {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, |
558 | {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, | 389 | {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, |
559 | {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, | 390 | {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, |
560 | {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, | 391 | {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, |
561 | {BRCMS_SROM_RXPO2G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, | ||
562 | {BRCMS_SROM_RXPO5G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, | ||
563 | {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, | 392 | {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, |
564 | {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, | 393 | {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, |
565 | {BRCMS_SROM_TXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
566 | SROM4_TXCHAIN_MASK}, | ||
567 | {BRCMS_SROM_RXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
568 | SROM4_RXCHAIN_MASK}, | ||
569 | {BRCMS_SROM_ANTSWITCH, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
570 | SROM4_SWITCH_MASK}, | ||
571 | {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, | 394 | {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, |
572 | SROM4_TXCHAIN_MASK}, | 395 | SROM4_TXCHAIN_MASK}, |
573 | {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, | 396 | {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, |
@@ -594,43 +417,11 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
594 | SROM8_FEM_ANTSWLUT_MASK}, | 417 | SROM8_FEM_ANTSWLUT_MASK}, |
595 | {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, | 418 | {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, |
596 | {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, | 419 | {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, |
597 | {BRCMS_SROM_TXPID2GA0, 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, | 420 | |
598 | {BRCMS_SROM_TXPID2GA1, 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, | ||
599 | {BRCMS_SROM_TXPID2GA2, 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, | ||
600 | {BRCMS_SROM_TXPID2GA3, 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, | ||
601 | {BRCMS_SROM_TXPID5GA0, 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, | ||
602 | {BRCMS_SROM_TXPID5GA1, 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, | ||
603 | {BRCMS_SROM_TXPID5GA2, 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, | ||
604 | {BRCMS_SROM_TXPID5GA3, 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, | ||
605 | {BRCMS_SROM_TXPID5GLA0, 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, | ||
606 | {BRCMS_SROM_TXPID5GLA1, 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, | ||
607 | {BRCMS_SROM_TXPID5GLA2, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, | ||
608 | {BRCMS_SROM_TXPID5GLA3, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, | ||
609 | {BRCMS_SROM_TXPID5GHA0, 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, | ||
610 | {BRCMS_SROM_TXPID5GHA1, 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, | ||
611 | {BRCMS_SROM_TXPID5GHA2, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, | ||
612 | {BRCMS_SROM_TXPID5GHA3, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, | ||
613 | |||
614 | {BRCMS_SROM_CCODE, 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, | ||
615 | {BRCMS_SROM_CCODE, 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, | ||
616 | {BRCMS_SROM_CCODE, 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, | ||
617 | {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, | 421 | {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, |
618 | {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, | 422 | {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, |
619 | {BRCMS_SROM_MACADDR, 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, | ||
620 | {BRCMS_SROM_MACADDR, 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, | ||
621 | {BRCMS_SROM_MACADDR, 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, | ||
622 | {BRCMS_SROM_IL0MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, | ||
623 | 0xffff}, | ||
624 | {BRCMS_SROM_ET1MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, | ||
625 | 0xffff}, | ||
626 | {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, | 423 | {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, |
627 | 0xffff}, | 424 | 0xffff}, |
628 | {BRCMS_SROM_LEDDC, 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, | ||
629 | 0xffff}, | ||
630 | {BRCMS_SROM_LEDDC, 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, | ||
631 | 0xffff}, | ||
632 | {BRCMS_SROM_LEDDC, 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, | ||
633 | 0xffff}, | ||
634 | {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, | 425 | {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, |
635 | 0x01ff}, | 426 | 0x01ff}, |
636 | {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, | 427 | {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, |
@@ -650,16 +441,7 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
650 | {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, | 441 | {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, |
651 | 0x00ff}, | 442 | 0x00ff}, |
652 | 443 | ||
653 | {BRCMS_SROM_CCK2GPO, 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, | ||
654 | {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, | 444 | {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, |
655 | {BRCMS_SROM_OFDM2GPO, 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, | ||
656 | {BRCMS_SROM_CONT, 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, | ||
657 | {BRCMS_SROM_OFDM5GPO, 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, | ||
658 | {BRCMS_SROM_CONT, 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, | ||
659 | {BRCMS_SROM_OFDM5GLPO, 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, | ||
660 | {BRCMS_SROM_CONT, 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, | ||
661 | {BRCMS_SROM_OFDM5GHPO, 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, | ||
662 | {BRCMS_SROM_CONT, 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, | ||
663 | {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, | 445 | {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, |
664 | {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, | 446 | {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, |
665 | {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, | 447 | {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, |
@@ -668,38 +450,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
668 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, | 450 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, |
669 | {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, | 451 | {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, |
670 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, | 452 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, |
671 | {BRCMS_SROM_MCS2GPO0, 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, | ||
672 | {BRCMS_SROM_MCS2GPO1, 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, | ||
673 | {BRCMS_SROM_MCS2GPO2, 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, | ||
674 | {BRCMS_SROM_MCS2GPO3, 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, | ||
675 | {BRCMS_SROM_MCS2GPO4, 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, | ||
676 | {BRCMS_SROM_MCS2GPO5, 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, | ||
677 | {BRCMS_SROM_MCS2GPO6, 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, | ||
678 | {BRCMS_SROM_MCS2GPO7, 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, | ||
679 | {BRCMS_SROM_MCS5GPO0, 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, | ||
680 | {BRCMS_SROM_MCS5GPO1, 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, | ||
681 | {BRCMS_SROM_MCS5GPO2, 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, | ||
682 | {BRCMS_SROM_MCS5GPO3, 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, | ||
683 | {BRCMS_SROM_MCS5GPO4, 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, | ||
684 | {BRCMS_SROM_MCS5GPO5, 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, | ||
685 | {BRCMS_SROM_MCS5GPO6, 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, | ||
686 | {BRCMS_SROM_MCS5GPO7, 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, | ||
687 | {BRCMS_SROM_MCS5GLPO0, 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, | ||
688 | {BRCMS_SROM_MCS5GLPO1, 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, | ||
689 | {BRCMS_SROM_MCS5GLPO2, 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, | ||
690 | {BRCMS_SROM_MCS5GLPO3, 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, | ||
691 | {BRCMS_SROM_MCS5GLPO4, 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, | ||
692 | {BRCMS_SROM_MCS5GLPO5, 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, | ||
693 | {BRCMS_SROM_MCS5GLPO6, 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, | ||
694 | {BRCMS_SROM_MCS5GLPO7, 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, | ||
695 | {BRCMS_SROM_MCS5GHPO0, 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, | ||
696 | {BRCMS_SROM_MCS5GHPO1, 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, | ||
697 | {BRCMS_SROM_MCS5GHPO2, 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, | ||
698 | {BRCMS_SROM_MCS5GHPO3, 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, | ||
699 | {BRCMS_SROM_MCS5GHPO4, 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, | ||
700 | {BRCMS_SROM_MCS5GHPO5, 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, | ||
701 | {BRCMS_SROM_MCS5GHPO6, 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, | ||
702 | {BRCMS_SROM_MCS5GHPO7, 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, | ||
703 | {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, | 453 | {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, |
704 | {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, | 454 | {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, |
705 | {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, | 455 | {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, |
@@ -732,10 +482,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
732 | {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, | 482 | {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, |
733 | {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, | 483 | {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, |
734 | {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, | 484 | {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, |
735 | {BRCMS_SROM_CDDPO, 0x000000f0, 0, SROM4_CDDPO, 0xffff}, | ||
736 | {BRCMS_SROM_STBCPO, 0x000000f0, 0, SROM4_STBCPO, 0xffff}, | ||
737 | {BRCMS_SROM_BW40PO, 0x000000f0, 0, SROM4_BW40PO, 0xffff}, | ||
738 | {BRCMS_SROM_BWDUPPO, 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, | ||
739 | {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, | 485 | {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, |
740 | {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, | 486 | {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, |
741 | {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, | 487 | {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, |
@@ -811,34 +557,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
811 | }; | 557 | }; |
812 | 558 | ||
813 | static const struct brcms_sromvar perpath_pci_sromvars[] = { | 559 | static const struct brcms_sromvar perpath_pci_sromvars[] = { |
814 | {BRCMS_SROM_MAXP2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, | ||
815 | {BRCMS_SROM_ITT2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, | ||
816 | {BRCMS_SROM_ITT5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, | ||
817 | {BRCMS_SROM_PA2GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, | ||
818 | {BRCMS_SROM_PA2GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, | ||
819 | {BRCMS_SROM_PA2GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, | ||
820 | {BRCMS_SROM_PA2GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, | ||
821 | {BRCMS_SROM_MAXP5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, | ||
822 | {BRCMS_SROM_MAXP5GHA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, | ||
823 | {BRCMS_SROM_MAXP5GLA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, | ||
824 | {BRCMS_SROM_PA5GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, | ||
825 | {BRCMS_SROM_PA5GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, | ||
826 | {BRCMS_SROM_PA5GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, | ||
827 | {BRCMS_SROM_PA5GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, | ||
828 | {BRCMS_SROM_PA5GLW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, | ||
829 | {BRCMS_SROM_PA5GLW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, | ||
830 | 0xffff}, | ||
831 | {BRCMS_SROM_PA5GLW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, | ||
832 | 0xffff}, | ||
833 | {BRCMS_SROM_PA5GLW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, | ||
834 | 0xffff}, | ||
835 | {BRCMS_SROM_PA5GHW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, | ||
836 | {BRCMS_SROM_PA5GHW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, | ||
837 | 0xffff}, | ||
838 | {BRCMS_SROM_PA5GHW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, | ||
839 | 0xffff}, | ||
840 | {BRCMS_SROM_PA5GHW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, | ||
841 | 0xffff}, | ||
842 | {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, | 560 | {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, |
843 | {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, | 561 | {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, |
844 | {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, | 562 | {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, |
@@ -868,24 +586,17 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = { | |||
868 | * shared between devices. */ | 586 | * shared between devices. */ |
869 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; | 587 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; |
870 | 588 | ||
871 | static u16 __iomem * | 589 | static u8 __iomem * |
872 | srom_window_address(struct si_pub *sih, u8 __iomem *curmap) | 590 | srom_window_address(struct si_pub *sih, u8 __iomem *curmap) |
873 | { | 591 | { |
874 | if (sih->ccrev < 32) | 592 | if (sih->ccrev < 32) |
875 | return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET); | 593 | return curmap + PCI_BAR0_SPROM_OFFSET; |
876 | if (sih->cccaps & CC_CAP_SROM) | 594 | if (sih->cccaps & CC_CAP_SROM) |
877 | return (u16 __iomem *) | 595 | return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP; |
878 | (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP); | ||
879 | 596 | ||
880 | return NULL; | 597 | return NULL; |
881 | } | 598 | } |
882 | 599 | ||
883 | /* Parse SROM and create name=value pairs. 'srom' points to | ||
884 | * the SROM word array. 'off' specifies the offset of the | ||
885 | * first word 'srom' points to, which should be either 0 or | ||
886 | * SROM3_SWRG_OFF (full SROM or software region). | ||
887 | */ | ||
888 | |||
889 | static uint mask_shift(u16 mask) | 600 | static uint mask_shift(u16 mask) |
890 | { | 601 | { |
891 | uint i; | 602 | uint i; |
@@ -906,18 +617,16 @@ static uint mask_width(u16 mask) | |||
906 | return 0; | 617 | return 0; |
907 | } | 618 | } |
908 | 619 | ||
909 | static inline void ltoh16_buf(u16 *buf, unsigned int size) | 620 | static inline void le16_to_cpu_buf(u16 *buf, uint nwords) |
910 | { | 621 | { |
911 | size /= 2; | 622 | while (nwords--) |
912 | while (size--) | 623 | *(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords)); |
913 | *(buf + size) = le16_to_cpu(*(__le16 *)(buf + size)); | ||
914 | } | 624 | } |
915 | 625 | ||
916 | static inline void htol16_buf(u16 *buf, unsigned int size) | 626 | static inline void cpu_to_le16_buf(u16 *buf, uint nwords) |
917 | { | 627 | { |
918 | size /= 2; | 628 | while (nwords--) |
919 | while (size--) | 629 | *(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords)); |
920 | *(__le16 *)(buf + size) = cpu_to_le16(*(buf + size)); | ||
921 | } | 630 | } |
922 | 631 | ||
923 | /* | 632 | /* |
@@ -929,11 +638,14 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
929 | struct brcms_srom_list_head *entry; | 638 | struct brcms_srom_list_head *entry; |
930 | enum brcms_srom_id id; | 639 | enum brcms_srom_id id; |
931 | u16 w; | 640 | u16 w; |
932 | u32 val; | 641 | u32 val = 0; |
933 | const struct brcms_sromvar *srv; | 642 | const struct brcms_sromvar *srv; |
934 | uint width; | 643 | uint width; |
935 | uint flags; | 644 | uint flags; |
936 | u32 sr = (1 << sromrev); | 645 | u32 sr = (1 << sromrev); |
646 | uint p; | ||
647 | uint pb = SROM8_PATH0; | ||
648 | const uint psz = SROM8_PATH1 - SROM8_PATH0; | ||
937 | 649 | ||
938 | /* first store the srom revision */ | 650 | /* first store the srom revision */ |
939 | entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); | 651 | entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); |
@@ -1031,47 +743,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
1031 | list_add(&entry->var_list, var_list); | 743 | list_add(&entry->var_list, var_list); |
1032 | } | 744 | } |
1033 | 745 | ||
1034 | if (sromrev >= 4) { | 746 | for (p = 0; p < MAX_PATH_SROM; p++) { |
1035 | /* Do per-path variables */ | 747 | for (srv = perpath_pci_sromvars; |
1036 | uint p, pb, psz; | 748 | srv->varid != BRCMS_SROM_NULL; srv++) { |
1037 | 749 | if ((srv->revmask & sr) == 0) | |
1038 | if (sromrev >= 8) { | 750 | continue; |
1039 | pb = SROM8_PATH0; | ||
1040 | psz = SROM8_PATH1 - SROM8_PATH0; | ||
1041 | } else { | ||
1042 | pb = SROM4_PATH0; | ||
1043 | psz = SROM4_PATH1 - SROM4_PATH0; | ||
1044 | } | ||
1045 | |||
1046 | for (p = 0; p < MAX_PATH_SROM; p++) { | ||
1047 | for (srv = perpath_pci_sromvars; | ||
1048 | srv->varid != BRCMS_SROM_NULL; srv++) { | ||
1049 | if ((srv->revmask & sr) == 0) | ||
1050 | continue; | ||
1051 | 751 | ||
1052 | if (srv->flags & SRFL_NOVAR) | 752 | if (srv->flags & SRFL_NOVAR) |
1053 | continue; | 753 | continue; |
1054 | 754 | ||
1055 | w = srom[pb + srv->off]; | 755 | w = srom[pb + srv->off]; |
1056 | val = (w & srv->mask) >> mask_shift(srv->mask); | 756 | val = (w & srv->mask) >> mask_shift(srv->mask); |
1057 | width = mask_width(srv->mask); | 757 | width = mask_width(srv->mask); |
1058 | 758 | ||
1059 | /* Cheating: no per-path var is more than | 759 | /* Cheating: no per-path var is more than |
1060 | * 1 word */ | 760 | * 1 word */ |
1061 | if ((srv->flags & SRFL_NOFFS) | 761 | if ((srv->flags & SRFL_NOFFS) |
1062 | && ((int)val == (1 << width) - 1)) | 762 | && ((int)val == (1 << width) - 1)) |
1063 | continue; | 763 | continue; |
1064 | 764 | ||
1065 | entry = | 765 | entry = |
1066 | kzalloc(sizeof(struct brcms_srom_list_head), | 766 | kzalloc(sizeof(struct brcms_srom_list_head), |
1067 | GFP_KERNEL); | 767 | GFP_KERNEL); |
1068 | entry->varid = srv->varid+p; | 768 | entry->varid = srv->varid+p; |
1069 | entry->var_type = BRCMS_SROM_UNUMBER; | 769 | entry->var_type = BRCMS_SROM_UNUMBER; |
1070 | entry->uval = val; | 770 | entry->uval = val; |
1071 | list_add(&entry->var_list, var_list); | 771 | list_add(&entry->var_list, var_list); |
1072 | } | ||
1073 | pb += psz; | ||
1074 | } | 772 | } |
773 | pb += psz; | ||
1075 | } | 774 | } |
1076 | } | 775 | } |
1077 | 776 | ||
@@ -1080,41 +779,38 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
1080 | * Return 0 on success, nonzero on error. | 779 | * Return 0 on success, nonzero on error. |
1081 | */ | 780 | */ |
1082 | static int | 781 | static int |
1083 | sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, | 782 | sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff, |
1084 | u16 *buf, uint nwords, bool check_crc) | 783 | u16 *buf, uint nwords, bool check_crc) |
1085 | { | 784 | { |
1086 | int err = 0; | 785 | int err = 0; |
1087 | uint i; | 786 | uint i; |
787 | u8 *bbuf = (u8 *)buf; /* byte buffer */ | ||
788 | uint nbytes = nwords << 1; | ||
1088 | 789 | ||
1089 | /* read the sprom */ | 790 | /* read the sprom in bytes */ |
1090 | for (i = 0; i < nwords; i++) | 791 | for (i = 0; i < nbytes; i++) |
1091 | buf[i] = R_REG(&sprom[wordoff + i]); | 792 | bbuf[i] = readb(sprom+i); |
1092 | |||
1093 | if (check_crc) { | ||
1094 | 793 | ||
1095 | if (buf[0] == 0xffff) | 794 | if (buf[0] == 0xffff) |
1096 | /* | 795 | /* |
1097 | * The hardware thinks that an srom that starts with | 796 | * The hardware thinks that an srom that starts with |
1098 | * 0xffff is blank, regardless of the rest of the | 797 | * 0xffff is blank, regardless of the rest of the |
1099 | * content, so declare it bad. | 798 | * content, so declare it bad. |
1100 | */ | 799 | */ |
1101 | return -ENODATA; | 800 | return -ENODATA; |
1102 | |||
1103 | /* fixup the endianness so crc8 will pass */ | ||
1104 | htol16_buf(buf, nwords * 2); | ||
1105 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2, | ||
1106 | CRC8_INIT_VALUE) != | ||
1107 | CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | ||
1108 | /* DBG only pci always read srom4 first, then srom8/9 */ | ||
1109 | err = -EIO; | ||
1110 | 801 | ||
802 | if (check_crc && | ||
803 | crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) != | ||
804 | CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | ||
805 | err = -EIO; | ||
806 | else | ||
1111 | /* now correct the endianness of the byte array */ | 807 | /* now correct the endianness of the byte array */ |
1112 | ltoh16_buf(buf, nwords * 2); | 808 | le16_to_cpu_buf(buf, nwords); |
1113 | } | 809 | |
1114 | return err; | 810 | return err; |
1115 | } | 811 | } |
1116 | 812 | ||
1117 | static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | 813 | static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords) |
1118 | { | 814 | { |
1119 | u8 *otp; | 815 | u8 *otp; |
1120 | uint sz = OTP_SZ_MAX / 2; /* size in words */ | 816 | uint sz = OTP_SZ_MAX / 2; /* size in words */ |
@@ -1126,7 +822,8 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1126 | 822 | ||
1127 | err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); | 823 | err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); |
1128 | 824 | ||
1129 | memcpy(buf, otp, bufsz); | 825 | sz = min_t(uint, sz, nwords); |
826 | memcpy(buf, otp, sz * 2); | ||
1130 | 827 | ||
1131 | kfree(otp); | 828 | kfree(otp); |
1132 | 829 | ||
@@ -1139,13 +836,13 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1139 | return -ENODATA; | 836 | return -ENODATA; |
1140 | 837 | ||
1141 | /* fixup the endianness so crc8 will pass */ | 838 | /* fixup the endianness so crc8 will pass */ |
1142 | htol16_buf(buf, bufsz); | 839 | cpu_to_le16_buf(buf, sz); |
1143 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2, | 840 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2, |
1144 | CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | 841 | CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) |
1145 | err = -EIO; | 842 | err = -EIO; |
1146 | 843 | else | |
1147 | /* now correct the endianness of the byte array */ | 844 | /* now correct the endianness of the byte array */ |
1148 | ltoh16_buf(buf, bufsz); | 845 | le16_to_cpu_buf(buf, sz); |
1149 | 846 | ||
1150 | return err; | 847 | return err; |
1151 | } | 848 | } |
@@ -1157,7 +854,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1157 | static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | 854 | static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) |
1158 | { | 855 | { |
1159 | u16 *srom; | 856 | u16 *srom; |
1160 | u16 __iomem *sromwindow; | 857 | u8 __iomem *sromwindow; |
1161 | u8 sromrev = 0; | 858 | u8 sromrev = 0; |
1162 | u32 sr; | 859 | u32 sr; |
1163 | int err = 0; | 860 | int err = 0; |
@@ -1173,29 +870,16 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | |||
1173 | 870 | ||
1174 | crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); | 871 | crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); |
1175 | if (ai_is_sprom_available(sih)) { | 872 | if (ai_is_sprom_available(sih)) { |
1176 | err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, | 873 | err = sprom_read_pci(sih, sromwindow, 0, srom, |
1177 | true); | 874 | SROM4_WORDS, true); |
1178 | 875 | ||
1179 | if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || | 876 | if (err == 0) |
1180 | (((sih->buscoretype == PCIE_CORE_ID) | 877 | /* srom read and passed crc */ |
1181 | && (sih->buscorerev >= 6)) | ||
1182 | || ((sih->buscoretype == PCI_CORE_ID) | ||
1183 | && (sih->buscorerev >= 0xe)))) { | ||
1184 | /* sromrev >= 4, read more */ | ||
1185 | err = sprom_read_pci(sih, sromwindow, 0, srom, | ||
1186 | SROM4_WORDS, true); | ||
1187 | sromrev = srom[SROM4_CRCREV] & 0xff; | ||
1188 | } else if (err == 0) { | ||
1189 | /* srom is good and is rev < 4 */ | ||
1190 | /* top word of sprom contains version and crc8 */ | 878 | /* top word of sprom contains version and crc8 */ |
1191 | sromrev = srom[SROM_CRCREV] & 0xff; | 879 | sromrev = srom[SROM4_CRCREV] & 0xff; |
1192 | /* bcm4401 sroms misprogrammed */ | ||
1193 | if (sromrev == 0x10) | ||
1194 | sromrev = 1; | ||
1195 | } | ||
1196 | } else { | 880 | } else { |
1197 | /* Use OTP if SPROM not available */ | 881 | /* Use OTP if SPROM not available */ |
1198 | err = otp_read_pci(sih, srom, SROM_MAX); | 882 | err = otp_read_pci(sih, srom, SROM4_WORDS); |
1199 | if (err == 0) | 883 | if (err == 0) |
1200 | /* OTP only contain SROM rev8/rev9 for now */ | 884 | /* OTP only contain SROM rev8/rev9 for now */ |
1201 | sromrev = srom[SROM4_CRCREV] & 0xff; | 885 | sromrev = srom[SROM4_CRCREV] & 0xff; |
@@ -1208,10 +892,9 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | |||
1208 | sr = 1 << sromrev; | 892 | sr = 1 << sromrev; |
1209 | 893 | ||
1210 | /* | 894 | /* |
1211 | * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, | 895 | * srom version check: Current valid versions: 8, 9 |
1212 | * 9 | ||
1213 | */ | 896 | */ |
1214 | if ((sr & 0x33e) == 0) { | 897 | if ((sr & 0x300) == 0) { |
1215 | err = -EINVAL; | 898 | err = -EINVAL; |
1216 | goto errout; | 899 | goto errout; |
1217 | } | 900 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/drivers/net/wireless/brcm80211/brcmsmac/srom.h index 708c43ff51cc..c81df9798e50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.h | |||
@@ -26,9 +26,4 @@ extern void srom_free_vars(struct si_pub *sih); | |||
26 | extern int srom_read(struct si_pub *sih, uint bus, void *curmap, | 26 | extern int srom_read(struct si_pub *sih, uint bus, void *curmap, |
27 | uint byteoff, uint nbytes, u16 *buf, bool check_crc); | 27 | uint byteoff, uint nbytes, u16 *buf, bool check_crc); |
28 | 28 | ||
29 | /* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP | ||
30 | * and extract from it into name=value pairs | ||
31 | */ | ||
32 | extern int srom_parsecis(u8 **pcis, uint ciscnt, | ||
33 | char **vars, uint *count); | ||
34 | #endif /* _BRCM_SROM_H_ */ | 29 | #endif /* _BRCM_SROM_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index f27c48910827..b7537f70a795 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | |||
19 | #include <brcmu_utils.h> | 20 | #include <brcmu_utils.h> |
20 | 21 | ||
21 | MODULE_AUTHOR("Broadcom Corporation"); | 22 | MODULE_AUTHOR("Broadcom Corporation"); |
@@ -40,74 +41,20 @@ EXPORT_SYMBOL(brcmu_pkt_buf_get_skb); | |||
40 | /* Free the driver packet. Free the tag if present */ | 41 | /* Free the driver packet. Free the tag if present */ |
41 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) | 42 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) |
42 | { | 43 | { |
43 | struct sk_buff *nskb; | 44 | WARN_ON(skb->next); |
44 | int nest = 0; | 45 | if (skb->destructor) |
45 | 46 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | |
46 | /* perversion: we use skb->next to chain multi-skb packets */ | 47 | * destructor exists |
47 | while (skb) { | 48 | */ |
48 | nskb = skb->next; | 49 | dev_kfree_skb_any(skb); |
49 | skb->next = NULL; | 50 | else |
50 | 51 | /* can free immediately (even in_irq()) if destructor | |
51 | if (skb->destructor) | 52 | * does not exist |
52 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | 53 | */ |
53 | * destructor exists | 54 | dev_kfree_skb(skb); |
54 | */ | ||
55 | dev_kfree_skb_any(skb); | ||
56 | else | ||
57 | /* can free immediately (even in_irq()) if destructor | ||
58 | * does not exist | ||
59 | */ | ||
60 | dev_kfree_skb(skb); | ||
61 | |||
62 | nest++; | ||
63 | skb = nskb; | ||
64 | } | ||
65 | } | 55 | } |
66 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); | 56 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); |
67 | 57 | ||
68 | |||
69 | /* copy a buffer into a pkt buffer chain */ | ||
70 | uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len, | ||
71 | unsigned char *buf) | ||
72 | { | ||
73 | uint n, ret = 0; | ||
74 | |||
75 | /* skip 'offset' bytes */ | ||
76 | for (; p && offset; p = p->next) { | ||
77 | if (offset < (uint) (p->len)) | ||
78 | break; | ||
79 | offset -= p->len; | ||
80 | } | ||
81 | |||
82 | if (!p) | ||
83 | return 0; | ||
84 | |||
85 | /* copy the data */ | ||
86 | for (; p && len; p = p->next) { | ||
87 | n = min((uint) (p->len) - offset, (uint) len); | ||
88 | memcpy(p->data + offset, buf, n); | ||
89 | buf += n; | ||
90 | len -= n; | ||
91 | ret += n; | ||
92 | offset = 0; | ||
93 | } | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | EXPORT_SYMBOL(brcmu_pktfrombuf); | ||
98 | |||
99 | /* return total length of buffer chain */ | ||
100 | uint brcmu_pkttotlen(struct sk_buff *p) | ||
101 | { | ||
102 | uint total; | ||
103 | |||
104 | total = 0; | ||
105 | for (; p; p = p->next) | ||
106 | total += p->len; | ||
107 | return total; | ||
108 | } | ||
109 | EXPORT_SYMBOL(brcmu_pkttotlen); | ||
110 | |||
111 | /* | 58 | /* |
112 | * osl multiple-precedence packet queue | 59 | * osl multiple-precedence packet queue |
113 | * hi_prec is always >= the number of the highest non-empty precedence | 60 | * hi_prec is always >= the number of the highest non-empty precedence |
@@ -115,21 +62,13 @@ EXPORT_SYMBOL(brcmu_pkttotlen); | |||
115 | struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, | 62 | struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, |
116 | struct sk_buff *p) | 63 | struct sk_buff *p) |
117 | { | 64 | { |
118 | struct pktq_prec *q; | 65 | struct sk_buff_head *q; |
119 | 66 | ||
120 | if (pktq_full(pq) || pktq_pfull(pq, prec)) | 67 | if (pktq_full(pq) || pktq_pfull(pq, prec)) |
121 | return NULL; | 68 | return NULL; |
122 | 69 | ||
123 | q = &pq->q[prec]; | 70 | q = &pq->q[prec].skblist; |
124 | 71 | skb_queue_tail(q, p); | |
125 | if (q->head) | ||
126 | q->tail->prev = p; | ||
127 | else | ||
128 | q->head = p; | ||
129 | |||
130 | q->tail = p; | ||
131 | q->len++; | ||
132 | |||
133 | pq->len++; | 72 | pq->len++; |
134 | 73 | ||
135 | if (pq->hi_prec < prec) | 74 | if (pq->hi_prec < prec) |
@@ -142,20 +81,13 @@ EXPORT_SYMBOL(brcmu_pktq_penq); | |||
142 | struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, | 81 | struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, |
143 | struct sk_buff *p) | 82 | struct sk_buff *p) |
144 | { | 83 | { |
145 | struct pktq_prec *q; | 84 | struct sk_buff_head *q; |
146 | 85 | ||
147 | if (pktq_full(pq) || pktq_pfull(pq, prec)) | 86 | if (pktq_full(pq) || pktq_pfull(pq, prec)) |
148 | return NULL; | 87 | return NULL; |
149 | 88 | ||
150 | q = &pq->q[prec]; | 89 | q = &pq->q[prec].skblist; |
151 | 90 | skb_queue_head(q, p); | |
152 | if (q->head == NULL) | ||
153 | q->tail = p; | ||
154 | |||
155 | p->prev = q->head; | ||
156 | q->head = p; | ||
157 | q->len++; | ||
158 | |||
159 | pq->len++; | 91 | pq->len++; |
160 | 92 | ||
161 | if (pq->hi_prec < prec) | 93 | if (pq->hi_prec < prec) |
@@ -167,53 +99,30 @@ EXPORT_SYMBOL(brcmu_pktq_penq_head); | |||
167 | 99 | ||
168 | struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) | 100 | struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) |
169 | { | 101 | { |
170 | struct pktq_prec *q; | 102 | struct sk_buff_head *q; |
171 | struct sk_buff *p; | 103 | struct sk_buff *p; |
172 | 104 | ||
173 | q = &pq->q[prec]; | 105 | q = &pq->q[prec].skblist; |
174 | 106 | p = skb_dequeue(q); | |
175 | p = q->head; | ||
176 | if (p == NULL) | 107 | if (p == NULL) |
177 | return NULL; | 108 | return NULL; |
178 | 109 | ||
179 | q->head = p->prev; | ||
180 | if (q->head == NULL) | ||
181 | q->tail = NULL; | ||
182 | |||
183 | q->len--; | ||
184 | |||
185 | pq->len--; | 110 | pq->len--; |
186 | |||
187 | p->prev = NULL; | ||
188 | |||
189 | return p; | 111 | return p; |
190 | } | 112 | } |
191 | EXPORT_SYMBOL(brcmu_pktq_pdeq); | 113 | EXPORT_SYMBOL(brcmu_pktq_pdeq); |
192 | 114 | ||
193 | struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) | 115 | struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) |
194 | { | 116 | { |
195 | struct pktq_prec *q; | 117 | struct sk_buff_head *q; |
196 | struct sk_buff *p, *prev; | 118 | struct sk_buff *p; |
197 | |||
198 | q = &pq->q[prec]; | ||
199 | 119 | ||
200 | p = q->head; | 120 | q = &pq->q[prec].skblist; |
121 | p = skb_dequeue_tail(q); | ||
201 | if (p == NULL) | 122 | if (p == NULL) |
202 | return NULL; | 123 | return NULL; |
203 | 124 | ||
204 | for (prev = NULL; p != q->tail; p = p->prev) | ||
205 | prev = p; | ||
206 | |||
207 | if (prev) | ||
208 | prev->prev = NULL; | ||
209 | else | ||
210 | q->head = NULL; | ||
211 | |||
212 | q->tail = prev; | ||
213 | q->len--; | ||
214 | |||
215 | pq->len--; | 125 | pq->len--; |
216 | |||
217 | return p; | 126 | return p; |
218 | } | 127 | } |
219 | EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); | 128 | EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); |
@@ -222,31 +131,17 @@ void | |||
222 | brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, | 131 | brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, |
223 | bool (*fn)(struct sk_buff *, void *), void *arg) | 132 | bool (*fn)(struct sk_buff *, void *), void *arg) |
224 | { | 133 | { |
225 | struct pktq_prec *q; | 134 | struct sk_buff_head *q; |
226 | struct sk_buff *p, *prev = NULL; | 135 | struct sk_buff *p, *next; |
227 | 136 | ||
228 | q = &pq->q[prec]; | 137 | q = &pq->q[prec].skblist; |
229 | p = q->head; | 138 | skb_queue_walk_safe(q, p, next) { |
230 | while (p) { | ||
231 | if (fn == NULL || (*fn) (p, arg)) { | 139 | if (fn == NULL || (*fn) (p, arg)) { |
232 | bool head = (p == q->head); | 140 | skb_unlink(p, q); |
233 | if (head) | ||
234 | q->head = p->prev; | ||
235 | else | ||
236 | prev->prev = p->prev; | ||
237 | p->prev = NULL; | ||
238 | brcmu_pkt_buf_free_skb(p); | 141 | brcmu_pkt_buf_free_skb(p); |
239 | q->len--; | ||
240 | pq->len--; | 142 | pq->len--; |
241 | p = (head ? q->head : prev->prev); | ||
242 | } else { | ||
243 | prev = p; | ||
244 | p = p->prev; | ||
245 | } | 143 | } |
246 | } | 144 | } |
247 | |||
248 | if (q->head == NULL) | ||
249 | q->tail = NULL; | ||
250 | } | 145 | } |
251 | EXPORT_SYMBOL(brcmu_pktq_pflush); | 146 | EXPORT_SYMBOL(brcmu_pktq_pflush); |
252 | 147 | ||
@@ -271,8 +166,10 @@ void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len) | |||
271 | 166 | ||
272 | pq->max = (u16) max_len; | 167 | pq->max = (u16) max_len; |
273 | 168 | ||
274 | for (prec = 0; prec < num_prec; prec++) | 169 | for (prec = 0; prec < num_prec; prec++) { |
275 | pq->q[prec].max = pq->max; | 170 | pq->q[prec].max = pq->max; |
171 | skb_queue_head_init(&pq->q[prec].skblist); | ||
172 | } | ||
276 | } | 173 | } |
277 | EXPORT_SYMBOL(brcmu_pktq_init); | 174 | EXPORT_SYMBOL(brcmu_pktq_init); |
278 | 175 | ||
@@ -284,13 +181,13 @@ struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out) | |||
284 | return NULL; | 181 | return NULL; |
285 | 182 | ||
286 | for (prec = 0; prec < pq->hi_prec; prec++) | 183 | for (prec = 0; prec < pq->hi_prec; prec++) |
287 | if (pq->q[prec].head) | 184 | if (!skb_queue_empty(&pq->q[prec].skblist)) |
288 | break; | 185 | break; |
289 | 186 | ||
290 | if (prec_out) | 187 | if (prec_out) |
291 | *prec_out = prec; | 188 | *prec_out = prec; |
292 | 189 | ||
293 | return pq->q[prec].tail; | 190 | return skb_peek_tail(&pq->q[prec].skblist); |
294 | } | 191 | } |
295 | EXPORT_SYMBOL(brcmu_pktq_peek_tail); | 192 | EXPORT_SYMBOL(brcmu_pktq_peek_tail); |
296 | 193 | ||
@@ -303,7 +200,7 @@ int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp) | |||
303 | 200 | ||
304 | for (prec = 0; prec <= pq->hi_prec; prec++) | 201 | for (prec = 0; prec <= pq->hi_prec; prec++) |
305 | if (prec_bmp & (1 << prec)) | 202 | if (prec_bmp & (1 << prec)) |
306 | len += pq->q[prec].len; | 203 | len += pq->q[prec].skblist.qlen; |
307 | 204 | ||
308 | return len; | 205 | return len; |
309 | } | 206 | } |
@@ -313,39 +210,32 @@ EXPORT_SYMBOL(brcmu_pktq_mlen); | |||
313 | struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, | 210 | struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, |
314 | int *prec_out) | 211 | int *prec_out) |
315 | { | 212 | { |
316 | struct pktq_prec *q; | 213 | struct sk_buff_head *q; |
317 | struct sk_buff *p; | 214 | struct sk_buff *p; |
318 | int prec; | 215 | int prec; |
319 | 216 | ||
320 | if (pq->len == 0) | 217 | if (pq->len == 0) |
321 | return NULL; | 218 | return NULL; |
322 | 219 | ||
323 | while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) | 220 | while ((prec = pq->hi_prec) > 0 && |
221 | skb_queue_empty(&pq->q[prec].skblist)) | ||
324 | pq->hi_prec--; | 222 | pq->hi_prec--; |
325 | 223 | ||
326 | while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) | 224 | while ((prec_bmp & (1 << prec)) == 0 || |
225 | skb_queue_empty(&pq->q[prec].skblist)) | ||
327 | if (prec-- == 0) | 226 | if (prec-- == 0) |
328 | return NULL; | 227 | return NULL; |
329 | 228 | ||
330 | q = &pq->q[prec]; | 229 | q = &pq->q[prec].skblist; |
331 | 230 | p = skb_dequeue(q); | |
332 | p = q->head; | ||
333 | if (p == NULL) | 231 | if (p == NULL) |
334 | return NULL; | 232 | return NULL; |
335 | 233 | ||
336 | q->head = p->prev; | 234 | pq->len--; |
337 | if (q->head == NULL) | ||
338 | q->tail = NULL; | ||
339 | |||
340 | q->len--; | ||
341 | 235 | ||
342 | if (prec_out) | 236 | if (prec_out) |
343 | *prec_out = prec; | 237 | *prec_out = prec; |
344 | 238 | ||
345 | pq->len--; | ||
346 | |||
347 | p->prev = NULL; | ||
348 | |||
349 | return p; | 239 | return p; |
350 | } | 240 | } |
351 | EXPORT_SYMBOL(brcmu_pktq_mdeq); | 241 | EXPORT_SYMBOL(brcmu_pktq_mdeq); |
@@ -364,23 +254,3 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) | |||
364 | } | 254 | } |
365 | EXPORT_SYMBOL(brcmu_prpkt); | 255 | EXPORT_SYMBOL(brcmu_prpkt); |
366 | #endif /* defined(BCMDBG) */ | 256 | #endif /* defined(BCMDBG) */ |
367 | |||
368 | #if defined(BCMDBG) | ||
369 | /* | ||
370 | * print bytes formatted as hex to a string. return the resulting | ||
371 | * string length | ||
372 | */ | ||
373 | int brcmu_format_hex(char *str, const void *bytes, int len) | ||
374 | { | ||
375 | int i; | ||
376 | char *p = str; | ||
377 | const u8 *src = (const u8 *)bytes; | ||
378 | |||
379 | for (i = 0; i < len; i++) { | ||
380 | p += snprintf(p, 3, "%02X", *src); | ||
381 | src++; | ||
382 | } | ||
383 | return (int)(p - str); | ||
384 | } | ||
385 | EXPORT_SYMBOL(brcmu_format_hex); | ||
386 | #endif /* defined(BCMDBG) */ | ||
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 7d0f46e0eb95..ad249a0b4730 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h | |||
@@ -65,9 +65,7 @@ | |||
65 | #define ETHER_ADDR_STR_LEN 18 | 65 | #define ETHER_ADDR_STR_LEN 18 |
66 | 66 | ||
67 | struct pktq_prec { | 67 | struct pktq_prec { |
68 | struct sk_buff *head; /* first packet to dequeue */ | 68 | struct sk_buff_head skblist; |
69 | struct sk_buff *tail; /* last packet to dequeue */ | ||
70 | u16 len; /* number of queued packets */ | ||
71 | u16 max; /* maximum number of queued packets */ | 69 | u16 max; /* maximum number of queued packets */ |
72 | }; | 70 | }; |
73 | 71 | ||
@@ -88,32 +86,32 @@ struct pktq { | |||
88 | 86 | ||
89 | static inline int pktq_plen(struct pktq *pq, int prec) | 87 | static inline int pktq_plen(struct pktq *pq, int prec) |
90 | { | 88 | { |
91 | return pq->q[prec].len; | 89 | return pq->q[prec].skblist.qlen; |
92 | } | 90 | } |
93 | 91 | ||
94 | static inline int pktq_pavail(struct pktq *pq, int prec) | 92 | static inline int pktq_pavail(struct pktq *pq, int prec) |
95 | { | 93 | { |
96 | return pq->q[prec].max - pq->q[prec].len; | 94 | return pq->q[prec].max - pq->q[prec].skblist.qlen; |
97 | } | 95 | } |
98 | 96 | ||
99 | static inline bool pktq_pfull(struct pktq *pq, int prec) | 97 | static inline bool pktq_pfull(struct pktq *pq, int prec) |
100 | { | 98 | { |
101 | return pq->q[prec].len >= pq->q[prec].max; | 99 | return pq->q[prec].skblist.qlen >= pq->q[prec].max; |
102 | } | 100 | } |
103 | 101 | ||
104 | static inline bool pktq_pempty(struct pktq *pq, int prec) | 102 | static inline bool pktq_pempty(struct pktq *pq, int prec) |
105 | { | 103 | { |
106 | return pq->q[prec].len == 0; | 104 | return skb_queue_empty(&pq->q[prec].skblist); |
107 | } | 105 | } |
108 | 106 | ||
109 | static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) | 107 | static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) |
110 | { | 108 | { |
111 | return pq->q[prec].head; | 109 | return skb_peek(&pq->q[prec].skblist); |
112 | } | 110 | } |
113 | 111 | ||
114 | static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) | 112 | static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) |
115 | { | 113 | { |
116 | return pq->q[prec].tail; | 114 | return skb_peek_tail(&pq->q[prec].skblist); |
117 | } | 115 | } |
118 | 116 | ||
119 | extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, | 117 | extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, |
@@ -172,24 +170,16 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir, | |||
172 | bool (*fn)(struct sk_buff *, void *), void *arg); | 170 | bool (*fn)(struct sk_buff *, void *), void *arg); |
173 | 171 | ||
174 | /* externs */ | 172 | /* externs */ |
175 | /* packet */ | ||
176 | extern uint brcmu_pktfrombuf(struct sk_buff *p, | ||
177 | uint offset, int len, unsigned char *buf); | ||
178 | extern uint brcmu_pkttotlen(struct sk_buff *p); | ||
179 | |||
180 | /* ip address */ | 173 | /* ip address */ |
181 | struct ipv4_addr; | 174 | struct ipv4_addr; |
182 | 175 | ||
176 | |||
177 | /* externs */ | ||
178 | /* format/print */ | ||
183 | #ifdef BCMDBG | 179 | #ifdef BCMDBG |
184 | extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); | 180 | extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); |
185 | #else | 181 | #else |
186 | #define brcmu_prpkt(a, b) | 182 | #define brcmu_prpkt(a, b) |
187 | #endif /* BCMDBG */ | 183 | #endif /* BCMDBG */ |
188 | 184 | ||
189 | /* externs */ | ||
190 | /* format/print */ | ||
191 | #if defined(BCMDBG) | ||
192 | extern int brcmu_format_hex(char *str, const void *bytes, int len); | ||
193 | #endif | ||
194 | |||
195 | #endif /* _BRCMU_UTILS_H_ */ | 185 | #endif /* _BRCMU_UTILS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h index 1e5f310af1e7..f0d8c04a9c8c 100644 --- a/drivers/net/wireless/brcm80211/include/defs.h +++ b/drivers/net/wireless/brcm80211/include/defs.h | |||
@@ -62,7 +62,6 @@ | |||
62 | 62 | ||
63 | #define WL_RADIO_SW_DISABLE (1<<0) | 63 | #define WL_RADIO_SW_DISABLE (1<<0) |
64 | #define WL_RADIO_HW_DISABLE (1<<1) | 64 | #define WL_RADIO_HW_DISABLE (1<<1) |
65 | #define WL_RADIO_MPC_DISABLE (1<<2) | ||
66 | /* some countries don't support any channel */ | 65 | /* some countries don't support any channel */ |
67 | #define WL_RADIO_COUNTRY_DISABLE (1<<3) | 66 | #define WL_RADIO_COUNTRY_DISABLE (1<<3) |
68 | 67 | ||
diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h index 4fcb956ad9e0..4e9b7e4827ea 100644 --- a/drivers/net/wireless/brcm80211/include/soc.h +++ b/drivers/net/wireless/brcm80211/include/soc.h | |||
@@ -77,8 +77,9 @@ | |||
77 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ | 77 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ |
78 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ | 78 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ |
79 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ | 79 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ |
80 | /* Default component, in ai chips it maps all unused address ranges */ | 80 | #define DEF_AI_COMP 0xfff /* Default component, in ai chips it |
81 | #define DEF_AI_COMP 0xfff | 81 | * maps all unused address ranges |
82 | */ | ||
82 | 83 | ||
83 | /* Common core control flags */ | 84 | /* Common core control flags */ |
84 | #define SICF_BIST_EN 0x8000 | 85 | #define SICF_BIST_EN 0x8000 |
@@ -87,4 +88,11 @@ | |||
87 | #define SICF_FGC 0x0002 | 88 | #define SICF_FGC 0x0002 |
88 | #define SICF_CLOCK_EN 0x0001 | 89 | #define SICF_CLOCK_EN 0x0001 |
89 | 90 | ||
91 | /* Common core status flags */ | ||
92 | #define SISF_BIST_DONE 0x8000 | ||
93 | #define SISF_BIST_ERROR 0x4000 | ||
94 | #define SISF_GATED_CLK 0x2000 | ||
95 | #define SISF_DMA64 0x1000 | ||
96 | #define SISF_CORE_BITS 0x0fff | ||
97 | |||
90 | #endif /* _BRCM_SOC_H */ | 98 | #endif /* _BRCM_SOC_H */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 99a710dfe771..99575884ff52 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -131,6 +131,14 @@ static struct ieee80211_rate ipw2200_rates[] = { | |||
131 | #define ipw2200_bg_rates (ipw2200_rates + 0) | 131 | #define ipw2200_bg_rates (ipw2200_rates + 0) |
132 | #define ipw2200_num_bg_rates 12 | 132 | #define ipw2200_num_bg_rates 12 |
133 | 133 | ||
134 | /* Ugly macro to convert literal channel numbers into their mhz equivalents | ||
135 | * There are certianly some conditions that will break this (like feeding it '30') | ||
136 | * but they shouldn't arise since nothing talks on channel 30. */ | ||
137 | #define ieee80211chan2mhz(x) \ | ||
138 | (((x) <= 14) ? \ | ||
139 | (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \ | ||
140 | ((x) + 1000) * 5) | ||
141 | |||
134 | #ifdef CONFIG_IPW2200_QOS | 142 | #ifdef CONFIG_IPW2200_QOS |
135 | static int qos_enable = 0; | 143 | static int qos_enable = 0; |
136 | static int qos_burst_enable = 0; | 144 | static int qos_burst_enable = 0; |
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 70f5586d96bd..3d5821eeb054 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -66,16 +66,8 @@ extern u32 libipw_debug_level; | |||
66 | do { if (libipw_debug_level & (level)) \ | 66 | do { if (libipw_debug_level & (level)) \ |
67 | printk(KERN_DEBUG "libipw: %c %s " fmt, \ | 67 | printk(KERN_DEBUG "libipw: %c %s " fmt, \ |
68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | 68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) |
69 | static inline bool libipw_ratelimit_debug(u32 level) | ||
70 | { | ||
71 | return (libipw_debug_level & level) && net_ratelimit(); | ||
72 | } | ||
73 | #else | 69 | #else |
74 | #define LIBIPW_DEBUG(level, fmt, args...) do {} while (0) | 70 | #define LIBIPW_DEBUG(level, fmt, args...) do {} while (0) |
75 | static inline bool libipw_ratelimit_debug(u32 level) | ||
76 | { | ||
77 | return false; | ||
78 | } | ||
79 | #endif /* CONFIG_LIBIPW_DEBUG */ | 71 | #endif /* CONFIG_LIBIPW_DEBUG */ |
80 | 72 | ||
81 | /* | 73 | /* |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index c73e5ed8db5e..a7ab280994c8 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # WIFI | 1 | # WIFI |
2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o | 2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o |
3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o | 3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o |
4 | iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o | 4 | iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o |
5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o | 5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o |
6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o | 6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 79431977a968..b3193571ed07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -270,11 +270,6 @@ struct iwl_cfg iwl2000_2bgn_cfg = { | |||
270 | .ht_params = &iwl2000_ht_params, | 270 | .ht_params = &iwl2000_ht_params, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | struct iwl_cfg iwl2000_2bg_cfg = { | ||
274 | .name = "2000 Series 2x2 BG", | ||
275 | IWL_DEVICE_2000, | ||
276 | }; | ||
277 | |||
278 | struct iwl_cfg iwl2000_2bgn_d_cfg = { | 273 | struct iwl_cfg iwl2000_2bgn_d_cfg = { |
279 | .name = "2000D Series 2x2 BGN", | 274 | .name = "2000D Series 2x2 BGN", |
280 | IWL_DEVICE_2000, | 275 | IWL_DEVICE_2000, |
@@ -304,11 +299,6 @@ struct iwl_cfg iwl2030_2bgn_cfg = { | |||
304 | .ht_params = &iwl2000_ht_params, | 299 | .ht_params = &iwl2000_ht_params, |
305 | }; | 300 | }; |
306 | 301 | ||
307 | struct iwl_cfg iwl2030_2bg_cfg = { | ||
308 | .name = "2000 Series 2x2 BG/BT", | ||
309 | IWL_DEVICE_2030, | ||
310 | }; | ||
311 | |||
312 | #define IWL_DEVICE_105 \ | 302 | #define IWL_DEVICE_105 \ |
313 | .fw_name_pre = IWL105_FW_PRE, \ | 303 | .fw_name_pre = IWL105_FW_PRE, \ |
314 | .ucode_api_max = IWL105_UCODE_API_MAX, \ | 304 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
@@ -326,11 +316,6 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
326 | .rx_with_siso_diversity = true, \ | 316 | .rx_with_siso_diversity = true, \ |
327 | .iq_invert = true \ | 317 | .iq_invert = true \ |
328 | 318 | ||
329 | struct iwl_cfg iwl105_bg_cfg = { | ||
330 | .name = "105 Series 1x1 BG", | ||
331 | IWL_DEVICE_105, | ||
332 | }; | ||
333 | |||
334 | struct iwl_cfg iwl105_bgn_cfg = { | 319 | struct iwl_cfg iwl105_bgn_cfg = { |
335 | .name = "105 Series 1x1 BGN", | 320 | .name = "105 Series 1x1 BGN", |
336 | IWL_DEVICE_105, | 321 | IWL_DEVICE_105, |
@@ -361,11 +346,6 @@ struct iwl_cfg iwl105_bgn_d_cfg = { | |||
361 | .rx_with_siso_diversity = true, \ | 346 | .rx_with_siso_diversity = true, \ |
362 | .iq_invert = true \ | 347 | .iq_invert = true \ |
363 | 348 | ||
364 | struct iwl_cfg iwl135_bg_cfg = { | ||
365 | .name = "135 Series 1x1 BG/BT", | ||
366 | IWL_DEVICE_135, | ||
367 | }; | ||
368 | |||
369 | struct iwl_cfg iwl135_bgn_cfg = { | 349 | struct iwl_cfg iwl135_bgn_cfg = { |
370 | .name = "135 Series 1x1 BGN/BT", | 350 | .name = "135 Series 1x1 BGN/BT", |
371 | IWL_DEVICE_135, | 351 | IWL_DEVICE_135, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c840c78278db..ee3363fdf309 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -439,16 +439,6 @@ struct iwl_cfg iwl6035_2agn_cfg = { | |||
439 | .ht_params = &iwl6000_ht_params, | 439 | .ht_params = &iwl6000_ht_params, |
440 | }; | 440 | }; |
441 | 441 | ||
442 | struct iwl_cfg iwl6035_2abg_cfg = { | ||
443 | .name = "6035 Series 2x2 ABG/BT", | ||
444 | IWL_DEVICE_6030, | ||
445 | }; | ||
446 | |||
447 | struct iwl_cfg iwl6035_2bg_cfg = { | ||
448 | .name = "6035 Series 2x2 BG/BT", | ||
449 | IWL_DEVICE_6030, | ||
450 | }; | ||
451 | |||
452 | struct iwl_cfg iwl1030_bgn_cfg = { | 442 | struct iwl_cfg iwl1030_bgn_cfg = { |
453 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", | 443 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", |
454 | IWL_DEVICE_6030, | 444 | IWL_DEVICE_6030, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 1a52ed29f2d6..0bc962217351 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -827,6 +827,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) | |||
827 | case IEEE80211_SMPS_STATIC: | 827 | case IEEE80211_SMPS_STATIC: |
828 | case IEEE80211_SMPS_DYNAMIC: | 828 | case IEEE80211_SMPS_DYNAMIC: |
829 | return IWL_NUM_IDLE_CHAINS_SINGLE; | 829 | return IWL_NUM_IDLE_CHAINS_SINGLE; |
830 | case IEEE80211_SMPS_AUTOMATIC: | ||
830 | case IEEE80211_SMPS_OFF: | 831 | case IEEE80211_SMPS_OFF: |
831 | return active_cnt; | 832 | return active_cnt; |
832 | default: | 833 | default: |
@@ -983,3 +984,360 @@ void iwlagn_remove_notification(struct iwl_priv *priv, | |||
983 | list_del(&wait_entry->list); | 984 | list_del(&wait_entry->list); |
984 | spin_unlock_bh(&priv->notif_wait_lock); | 985 | spin_unlock_bh(&priv->notif_wait_lock); |
985 | } | 986 | } |
987 | |||
988 | #ifdef CONFIG_PM_SLEEP | ||
989 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) | ||
990 | { | ||
991 | int i; | ||
992 | |||
993 | for (i = 0; i < IWLAGN_P1K_SIZE; i++) | ||
994 | out[i] = cpu_to_le16(p1k[i]); | ||
995 | } | ||
996 | |||
997 | struct wowlan_key_data { | ||
998 | struct iwl_rxon_context *ctx; | ||
999 | struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc; | ||
1000 | struct iwlagn_wowlan_tkip_params_cmd *tkip; | ||
1001 | const u8 *bssid; | ||
1002 | bool error, use_rsc_tsc, use_tkip; | ||
1003 | }; | ||
1004 | |||
1005 | |||
1006 | static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | ||
1007 | struct ieee80211_vif *vif, | ||
1008 | struct ieee80211_sta *sta, | ||
1009 | struct ieee80211_key_conf *key, | ||
1010 | void *_data) | ||
1011 | { | ||
1012 | struct iwl_priv *priv = hw->priv; | ||
1013 | struct wowlan_key_data *data = _data; | ||
1014 | struct iwl_rxon_context *ctx = data->ctx; | ||
1015 | struct aes_sc *aes_sc, *aes_tx_sc = NULL; | ||
1016 | struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL; | ||
1017 | struct iwlagn_p1k_cache *rx_p1ks; | ||
1018 | u8 *rx_mic_key; | ||
1019 | struct ieee80211_key_seq seq; | ||
1020 | u32 cur_rx_iv32 = 0; | ||
1021 | u16 p1k[IWLAGN_P1K_SIZE]; | ||
1022 | int ret, i; | ||
1023 | |||
1024 | mutex_lock(&priv->shrd->mutex); | ||
1025 | |||
1026 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
1027 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | ||
1028 | !sta && !ctx->key_mapping_keys) | ||
1029 | ret = iwl_set_default_wep_key(priv, ctx, key); | ||
1030 | else | ||
1031 | ret = iwl_set_dynamic_key(priv, ctx, key, sta); | ||
1032 | |||
1033 | if (ret) { | ||
1034 | IWL_ERR(priv, "Error setting key during suspend!\n"); | ||
1035 | data->error = true; | ||
1036 | } | ||
1037 | |||
1038 | switch (key->cipher) { | ||
1039 | case WLAN_CIPHER_SUITE_TKIP: | ||
1040 | if (sta) { | ||
1041 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc; | ||
1042 | tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc; | ||
1043 | |||
1044 | rx_p1ks = data->tkip->rx_uni; | ||
1045 | |||
1046 | ieee80211_get_key_tx_seq(key, &seq); | ||
1047 | tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1048 | tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1049 | |||
1050 | ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k); | ||
1051 | iwlagn_convert_p1k(p1k, data->tkip->tx.p1k); | ||
1052 | |||
1053 | memcpy(data->tkip->mic_keys.tx, | ||
1054 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
1055 | IWLAGN_MIC_KEY_SIZE); | ||
1056 | |||
1057 | rx_mic_key = data->tkip->mic_keys.rx_unicast; | ||
1058 | } else { | ||
1059 | tkip_sc = | ||
1060 | data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc; | ||
1061 | rx_p1ks = data->tkip->rx_multi; | ||
1062 | rx_mic_key = data->tkip->mic_keys.rx_mcast; | ||
1063 | } | ||
1064 | |||
1065 | /* | ||
1066 | * For non-QoS this relies on the fact that both the uCode and | ||
1067 | * mac80211 use TID 0 (as they need to to avoid replay attacks) | ||
1068 | * for checking the IV in the frames. | ||
1069 | */ | ||
1070 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1071 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1072 | tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1073 | tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1074 | /* wrapping isn't allowed, AP must rekey */ | ||
1075 | if (seq.tkip.iv32 > cur_rx_iv32) | ||
1076 | cur_rx_iv32 = seq.tkip.iv32; | ||
1077 | } | ||
1078 | |||
1079 | ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k); | ||
1080 | iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k); | ||
1081 | ieee80211_get_tkip_rx_p1k(key, data->bssid, | ||
1082 | cur_rx_iv32 + 1, p1k); | ||
1083 | iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k); | ||
1084 | |||
1085 | memcpy(rx_mic_key, | ||
1086 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
1087 | IWLAGN_MIC_KEY_SIZE); | ||
1088 | |||
1089 | data->use_tkip = true; | ||
1090 | data->use_rsc_tsc = true; | ||
1091 | break; | ||
1092 | case WLAN_CIPHER_SUITE_CCMP: | ||
1093 | if (sta) { | ||
1094 | u8 *pn = seq.ccmp.pn; | ||
1095 | |||
1096 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc; | ||
1097 | aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc; | ||
1098 | |||
1099 | ieee80211_get_key_tx_seq(key, &seq); | ||
1100 | aes_tx_sc->pn = cpu_to_le64( | ||
1101 | (u64)pn[5] | | ||
1102 | ((u64)pn[4] << 8) | | ||
1103 | ((u64)pn[3] << 16) | | ||
1104 | ((u64)pn[2] << 24) | | ||
1105 | ((u64)pn[1] << 32) | | ||
1106 | ((u64)pn[0] << 40)); | ||
1107 | } else | ||
1108 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc; | ||
1109 | |||
1110 | /* | ||
1111 | * For non-QoS this relies on the fact that both the uCode and | ||
1112 | * mac80211 use TID 0 for checking the IV in the frames. | ||
1113 | */ | ||
1114 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1115 | u8 *pn = seq.ccmp.pn; | ||
1116 | |||
1117 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1118 | aes_sc->pn = cpu_to_le64( | ||
1119 | (u64)pn[5] | | ||
1120 | ((u64)pn[4] << 8) | | ||
1121 | ((u64)pn[3] << 16) | | ||
1122 | ((u64)pn[2] << 24) | | ||
1123 | ((u64)pn[1] << 32) | | ||
1124 | ((u64)pn[0] << 40)); | ||
1125 | } | ||
1126 | data->use_rsc_tsc = true; | ||
1127 | break; | ||
1128 | } | ||
1129 | |||
1130 | mutex_unlock(&priv->shrd->mutex); | ||
1131 | } | ||
1132 | |||
1133 | int iwlagn_send_patterns(struct iwl_priv *priv, | ||
1134 | struct cfg80211_wowlan *wowlan) | ||
1135 | { | ||
1136 | struct iwlagn_wowlan_patterns_cmd *pattern_cmd; | ||
1137 | struct iwl_host_cmd cmd = { | ||
1138 | .id = REPLY_WOWLAN_PATTERNS, | ||
1139 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1140 | .flags = CMD_SYNC, | ||
1141 | }; | ||
1142 | int i, err; | ||
1143 | |||
1144 | if (!wowlan->n_patterns) | ||
1145 | return 0; | ||
1146 | |||
1147 | cmd.len[0] = sizeof(*pattern_cmd) + | ||
1148 | wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern); | ||
1149 | |||
1150 | pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL); | ||
1151 | if (!pattern_cmd) | ||
1152 | return -ENOMEM; | ||
1153 | |||
1154 | pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); | ||
1155 | |||
1156 | for (i = 0; i < wowlan->n_patterns; i++) { | ||
1157 | int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); | ||
1158 | |||
1159 | memcpy(&pattern_cmd->patterns[i].mask, | ||
1160 | wowlan->patterns[i].mask, mask_len); | ||
1161 | memcpy(&pattern_cmd->patterns[i].pattern, | ||
1162 | wowlan->patterns[i].pattern, | ||
1163 | wowlan->patterns[i].pattern_len); | ||
1164 | pattern_cmd->patterns[i].mask_size = mask_len; | ||
1165 | pattern_cmd->patterns[i].pattern_size = | ||
1166 | wowlan->patterns[i].pattern_len; | ||
1167 | } | ||
1168 | |||
1169 | cmd.data[0] = pattern_cmd; | ||
1170 | err = iwl_trans_send_cmd(trans(priv), &cmd); | ||
1171 | kfree(pattern_cmd); | ||
1172 | return err; | ||
1173 | } | ||
1174 | |||
1175 | int iwlagn_suspend(struct iwl_priv *priv, | ||
1176 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | ||
1177 | { | ||
1178 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | ||
1179 | struct iwl_rxon_cmd rxon; | ||
1180 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1181 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | ||
1182 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | ||
1183 | struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; | ||
1184 | struct wowlan_key_data key_data = { | ||
1185 | .ctx = ctx, | ||
1186 | .bssid = ctx->active.bssid_addr, | ||
1187 | .use_rsc_tsc = false, | ||
1188 | .tkip = &tkip_cmd, | ||
1189 | .use_tkip = false, | ||
1190 | }; | ||
1191 | int ret, i; | ||
1192 | u16 seq; | ||
1193 | |||
1194 | key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); | ||
1195 | if (!key_data.rsc_tsc) | ||
1196 | return -ENOMEM; | ||
1197 | |||
1198 | memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd)); | ||
1199 | |||
1200 | /* | ||
1201 | * We know the last used seqno, and the uCode expects to know that | ||
1202 | * one, it will increment before TX. | ||
1203 | */ | ||
1204 | seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ; | ||
1205 | wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq); | ||
1206 | |||
1207 | /* | ||
1208 | * For QoS counters, we store the one to use next, so subtract 0x10 | ||
1209 | * since the uCode will add 0x10 before using the value. | ||
1210 | */ | ||
1211 | for (i = 0; i < 8; i++) { | ||
1212 | seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number; | ||
1213 | seq -= 0x10; | ||
1214 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); | ||
1215 | } | ||
1216 | |||
1217 | if (wowlan->disconnect) | ||
1218 | wakeup_filter_cmd.enabled |= | ||
1219 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS | | ||
1220 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE); | ||
1221 | if (wowlan->magic_pkt) | ||
1222 | wakeup_filter_cmd.enabled |= | ||
1223 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET); | ||
1224 | if (wowlan->gtk_rekey_failure) | ||
1225 | wakeup_filter_cmd.enabled |= | ||
1226 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL); | ||
1227 | if (wowlan->eap_identity_req) | ||
1228 | wakeup_filter_cmd.enabled |= | ||
1229 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ); | ||
1230 | if (wowlan->four_way_handshake) | ||
1231 | wakeup_filter_cmd.enabled |= | ||
1232 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE); | ||
1233 | if (wowlan->n_patterns) | ||
1234 | wakeup_filter_cmd.enabled |= | ||
1235 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH); | ||
1236 | |||
1237 | if (wowlan->rfkill_release) | ||
1238 | d3_cfg_cmd.wakeup_flags |= | ||
1239 | cpu_to_le32(IWLAGN_D3_WAKEUP_RFKILL); | ||
1240 | |||
1241 | iwl_scan_cancel_timeout(priv, 200); | ||
1242 | |||
1243 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | ||
1244 | |||
1245 | iwl_trans_stop_device(trans(priv)); | ||
1246 | |||
1247 | priv->shrd->wowlan = true; | ||
1248 | |||
1249 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | ||
1250 | if (ret) | ||
1251 | goto out; | ||
1252 | |||
1253 | /* now configure WoWLAN ucode */ | ||
1254 | ret = iwl_alive_start(priv); | ||
1255 | if (ret) | ||
1256 | goto out; | ||
1257 | |||
1258 | memcpy(&ctx->staging, &rxon, sizeof(rxon)); | ||
1259 | ret = iwlagn_commit_rxon(priv, ctx); | ||
1260 | if (ret) | ||
1261 | goto out; | ||
1262 | |||
1263 | ret = iwl_power_update_mode(priv, true); | ||
1264 | if (ret) | ||
1265 | goto out; | ||
1266 | |||
1267 | if (!iwlagn_mod_params.sw_crypto) { | ||
1268 | /* mark all keys clear */ | ||
1269 | priv->ucode_key_table = 0; | ||
1270 | ctx->key_mapping_keys = 0; | ||
1271 | |||
1272 | /* | ||
1273 | * This needs to be unlocked due to lock ordering | ||
1274 | * constraints. Since we're in the suspend path | ||
1275 | * that isn't really a problem though. | ||
1276 | */ | ||
1277 | mutex_unlock(&priv->shrd->mutex); | ||
1278 | ieee80211_iter_keys(priv->hw, ctx->vif, | ||
1279 | iwlagn_wowlan_program_keys, | ||
1280 | &key_data); | ||
1281 | mutex_lock(&priv->shrd->mutex); | ||
1282 | if (key_data.error) { | ||
1283 | ret = -EIO; | ||
1284 | goto out; | ||
1285 | } | ||
1286 | |||
1287 | if (key_data.use_rsc_tsc) { | ||
1288 | struct iwl_host_cmd rsc_tsc_cmd = { | ||
1289 | .id = REPLY_WOWLAN_TSC_RSC_PARAMS, | ||
1290 | .flags = CMD_SYNC, | ||
1291 | .data[0] = key_data.rsc_tsc, | ||
1292 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1293 | .len[0] = sizeof(key_data.rsc_tsc), | ||
1294 | }; | ||
1295 | |||
1296 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | ||
1297 | if (ret) | ||
1298 | goto out; | ||
1299 | } | ||
1300 | |||
1301 | if (key_data.use_tkip) { | ||
1302 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
1303 | REPLY_WOWLAN_TKIP_PARAMS, | ||
1304 | CMD_SYNC, sizeof(tkip_cmd), | ||
1305 | &tkip_cmd); | ||
1306 | if (ret) | ||
1307 | goto out; | ||
1308 | } | ||
1309 | |||
1310 | if (priv->have_rekey_data) { | ||
1311 | memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd)); | ||
1312 | memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN); | ||
1313 | kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN); | ||
1314 | memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN); | ||
1315 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | ||
1316 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | ||
1317 | |||
1318 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
1319 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | ||
1320 | CMD_SYNC, sizeof(kek_kck_cmd), | ||
1321 | &kek_kck_cmd); | ||
1322 | if (ret) | ||
1323 | goto out; | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, | ||
1328 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | ||
1329 | if (ret) | ||
1330 | goto out; | ||
1331 | |||
1332 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | ||
1333 | CMD_SYNC, sizeof(wakeup_filter_cmd), | ||
1334 | &wakeup_filter_cmd); | ||
1335 | if (ret) | ||
1336 | goto out; | ||
1337 | |||
1338 | ret = iwlagn_send_patterns(priv, wowlan); | ||
1339 | out: | ||
1340 | kfree(key_data.rsc_tsc); | ||
1341 | return ret; | ||
1342 | } | ||
1343 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 66118cea2af3..359c47a4fcea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -1458,10 +1458,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1458 | break; | 1458 | break; |
1459 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: | 1459 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: |
1460 | /* avoid antenna B unless MIMO */ | 1460 | /* avoid antenna B unless MIMO */ |
1461 | valid_tx_ant = | ||
1462 | first_antenna(hw_params(priv).valid_tx_ant); | ||
1463 | if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) | 1461 | if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) |
1464 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; | 1462 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
1465 | break; | 1463 | break; |
1466 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: | 1464 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: |
1467 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1465 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
@@ -1636,10 +1634,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1636 | break; | 1634 | break; |
1637 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: | 1635 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: |
1638 | /* avoid antenna B unless MIMO */ | 1636 | /* avoid antenna B unless MIMO */ |
1639 | valid_tx_ant = | ||
1640 | first_antenna(hw_params(priv).valid_tx_ant); | ||
1641 | if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) | 1637 | if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) |
1642 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1638 | tbl->action = IWL_SISO_SWITCH_MIMO2_AB; |
1643 | break; | 1639 | break; |
1644 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: | 1640 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: |
1645 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1641 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 5af9e6258a16..fdb4c3786114 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -800,7 +800,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
800 | ctx->active.bssid_addr)) | 800 | ctx->active.bssid_addr)) |
801 | continue; | 801 | continue; |
802 | ctx->last_tx_rejected = false; | 802 | ctx->last_tx_rejected = false; |
803 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid); | 803 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, |
804 | "channel got active"); | ||
804 | } | 805 | } |
805 | } | 806 | } |
806 | 807 | ||
@@ -1032,6 +1033,50 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1032 | return 0; | 1033 | return 0; |
1033 | } | 1034 | } |
1034 | 1035 | ||
1036 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | ||
1037 | struct iwl_rx_mem_buffer *rxb, | ||
1038 | struct iwl_device_cmd *cmd) | ||
1039 | { | ||
1040 | struct iwl_wipan_noa_data *new_data, *old_data; | ||
1041 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1042 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; | ||
1043 | |||
1044 | /* no condition -- we're in softirq */ | ||
1045 | old_data = rcu_dereference_protected(priv->noa_data, true); | ||
1046 | |||
1047 | if (noa_notif->noa_active) { | ||
1048 | u32 len = le16_to_cpu(noa_notif->noa_attribute.length); | ||
1049 | u32 copylen = len; | ||
1050 | |||
1051 | /* EID, len, OUI, subtype */ | ||
1052 | len += 1 + 1 + 3 + 1; | ||
1053 | /* P2P id, P2P length */ | ||
1054 | len += 1 + 2; | ||
1055 | copylen += 1 + 2; | ||
1056 | |||
1057 | new_data = kmalloc(sizeof(*new_data) + len, GFP_ATOMIC); | ||
1058 | if (new_data) { | ||
1059 | new_data->length = len; | ||
1060 | new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC; | ||
1061 | new_data->data[1] = len - 2; /* not counting EID, len */ | ||
1062 | new_data->data[2] = (WLAN_OUI_WFA >> 16) & 0xff; | ||
1063 | new_data->data[3] = (WLAN_OUI_WFA >> 8) & 0xff; | ||
1064 | new_data->data[4] = (WLAN_OUI_WFA >> 0) & 0xff; | ||
1065 | new_data->data[5] = WLAN_OUI_TYPE_WFA_P2P; | ||
1066 | memcpy(&new_data->data[6], &noa_notif->noa_attribute, | ||
1067 | copylen); | ||
1068 | } | ||
1069 | } else | ||
1070 | new_data = NULL; | ||
1071 | |||
1072 | rcu_assign_pointer(priv->noa_data, new_data); | ||
1073 | |||
1074 | if (old_data) | ||
1075 | kfree_rcu(old_data, rcu_head); | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1035 | /** | 1080 | /** |
1036 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | 1081 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks |
1037 | * | 1082 | * |
@@ -1055,6 +1100,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1055 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; | 1100 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; |
1056 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; | 1101 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; |
1057 | 1102 | ||
1103 | handlers[REPLY_WIPAN_NOA_NOTIFICATION] = iwlagn_rx_noa_notification; | ||
1104 | |||
1058 | /* | 1105 | /* |
1059 | * The same handler is used for both the REPLY to a discrete | 1106 | * The same handler is used for both the REPLY to a discrete |
1060 | * statistics request from the host as well as for the periodic | 1107 | * statistics request from the host as well as for the periodic |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58a381c01c89..8de97f5a1825 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -45,7 +45,8 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, | |||
45 | send->filter_flags = old_filter; | 45 | send->filter_flags = old_filter; |
46 | 46 | ||
47 | if (ret) | 47 | if (ret) |
48 | IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret); | 48 | IWL_DEBUG_QUIET_RFKILL(priv, |
49 | "Error clearing ASSOC_MSK on BSS (%d)\n", ret); | ||
49 | 50 | ||
50 | return ret; | 51 | return ret; |
51 | } | 52 | } |
@@ -116,7 +117,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
116 | if (ctx->ht.enabled) | 117 | if (ctx->ht.enabled) |
117 | ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 118 | ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
118 | 119 | ||
119 | IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", | 120 | IWL_DEBUG_INFO(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", |
120 | ctx->qos_data.qos_active, | 121 | ctx->qos_data.qos_active, |
121 | ctx->qos_data.def_qos_parm.qos_flags); | 122 | ctx->qos_data.def_qos_parm.qos_flags); |
122 | 123 | ||
@@ -124,7 +125,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
124 | sizeof(struct iwl_qosparam_cmd), | 125 | sizeof(struct iwl_qosparam_cmd), |
125 | &ctx->qos_data.def_qos_parm); | 126 | &ctx->qos_data.def_qos_parm); |
126 | if (ret) | 127 | if (ret) |
127 | IWL_ERR(priv, "Failed to update QoS\n"); | 128 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); |
128 | } | 129 | } |
129 | 130 | ||
130 | static int iwlagn_update_beacon(struct iwl_priv *priv, | 131 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
@@ -541,6 +542,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
541 | 542 | ||
542 | mutex_lock(&priv->shrd->mutex); | 543 | mutex_lock(&priv->shrd->mutex); |
543 | 544 | ||
545 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
546 | goto out; | ||
547 | |||
544 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { | 548 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { |
545 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 549 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); |
546 | goto out; | 550 | goto out; |
@@ -840,7 +844,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
840 | if (ctx->last_tx_rejected) { | 844 | if (ctx->last_tx_rejected) { |
841 | ctx->last_tx_rejected = false; | 845 | ctx->last_tx_rejected = false; |
842 | iwl_trans_wake_any_queue(trans(priv), | 846 | iwl_trans_wake_any_queue(trans(priv), |
843 | ctx->ctxid); | 847 | ctx->ctxid, |
848 | "Disassoc: flush queue"); | ||
844 | } | 849 | } |
845 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 850 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
846 | 851 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index ed6283623932..901fd9485d75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -647,7 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
647 | int ret; | 647 | int ret; |
648 | struct iwl_addsta_cmd sta_cmd; | 648 | struct iwl_addsta_cmd sta_cmd; |
649 | struct iwl_link_quality_cmd lq; | 649 | struct iwl_link_quality_cmd lq; |
650 | bool active; | 650 | bool active, have_lq = false; |
651 | 651 | ||
652 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 652 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); |
653 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 653 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
@@ -657,7 +657,10 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
657 | 657 | ||
658 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 658 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
659 | sta_cmd.mode = 0; | 659 | sta_cmd.mode = 0; |
660 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | 660 | if (priv->stations[sta_id].lq) { |
661 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | ||
662 | have_lq = true; | ||
663 | } | ||
661 | 664 | ||
662 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; | 665 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; |
663 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 666 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
@@ -679,7 +682,8 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
679 | if (ret) | 682 | if (ret) |
680 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", | 683 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", |
681 | priv->stations[sta_id].sta.sta.addr, ret); | 684 | priv->stations[sta_id].sta.sta.addr, ret); |
682 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | 685 | if (have_lq) |
686 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | ||
683 | } | 687 | } |
684 | 688 | ||
685 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | 689 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) |
@@ -825,28 +829,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
825 | return ret; | 829 | return ret; |
826 | } | 830 | } |
827 | 831 | ||
828 | int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
829 | struct ieee80211_vif *vif, | ||
830 | struct ieee80211_sta *sta) | ||
831 | { | ||
832 | struct iwl_priv *priv = hw->priv; | ||
833 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
834 | int ret; | ||
835 | |||
836 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
837 | "station %pM\n", sta->addr); | ||
838 | mutex_lock(&priv->shrd->mutex); | ||
839 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
840 | sta->addr); | ||
841 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
842 | if (ret) | ||
843 | IWL_ERR(priv, "Error removing station %pM\n", | ||
844 | sta->addr); | ||
845 | mutex_unlock(&priv->shrd->mutex); | ||
846 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
847 | |||
848 | return ret; | ||
849 | } | ||
850 | 832 | ||
851 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 833 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
852 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) | 834 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) |
@@ -1464,20 +1446,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1464 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1446 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1465 | } | 1447 | } |
1466 | 1448 | ||
1467 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
1468 | { | ||
1469 | unsigned long flags; | ||
1470 | 1449 | ||
1471 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
1472 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
1473 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
1474 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1475 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1476 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1477 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1478 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1479 | |||
1480 | } | ||
1481 | 1450 | ||
1482 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | 1451 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) |
1483 | { | 1452 | { |
@@ -1494,36 +1463,3 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | |||
1494 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1463 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); |
1495 | 1464 | ||
1496 | } | 1465 | } |
1497 | |||
1498 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
1499 | struct ieee80211_vif *vif, | ||
1500 | enum sta_notify_cmd cmd, | ||
1501 | struct ieee80211_sta *sta) | ||
1502 | { | ||
1503 | struct iwl_priv *priv = hw->priv; | ||
1504 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1505 | int sta_id; | ||
1506 | |||
1507 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1508 | |||
1509 | switch (cmd) { | ||
1510 | case STA_NOTIFY_SLEEP: | ||
1511 | WARN_ON(!sta_priv->client); | ||
1512 | sta_priv->asleep = true; | ||
1513 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
1514 | ieee80211_sta_block_awake(hw, sta, true); | ||
1515 | break; | ||
1516 | case STA_NOTIFY_AWAKE: | ||
1517 | WARN_ON(!sta_priv->client); | ||
1518 | if (!sta_priv->asleep) | ||
1519 | break; | ||
1520 | sta_priv->asleep = false; | ||
1521 | sta_id = iwl_sta_id(sta); | ||
1522 | if (sta_id != IWL_INVALID_STATION) | ||
1523 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1524 | break; | ||
1525 | default: | ||
1526 | break; | ||
1527 | } | ||
1528 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1529 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 35a6b71f358c..e6a02e09ee18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -283,6 +283,19 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
283 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); | 283 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); |
284 | #endif | 284 | #endif |
285 | 285 | ||
286 | if (unlikely(ieee80211_is_probe_resp(fc))) { | ||
287 | struct iwl_wipan_noa_data *noa_data = | ||
288 | rcu_dereference(priv->noa_data); | ||
289 | |||
290 | if (noa_data && | ||
291 | pskb_expand_head(skb, 0, noa_data->length, | ||
292 | GFP_ATOMIC) == 0) { | ||
293 | memcpy(skb_put(skb, noa_data->length), | ||
294 | noa_data->data, noa_data->length); | ||
295 | hdr = (struct ieee80211_hdr *)skb->data; | ||
296 | } | ||
297 | } | ||
298 | |||
286 | hdr_len = ieee80211_hdrlen(fc); | 299 | hdr_len = ieee80211_hdrlen(fc); |
287 | 300 | ||
288 | /* For management frames use broadcast id to do not break aggregation */ | 301 | /* For management frames use broadcast id to do not break aggregation */ |
@@ -800,7 +813,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
800 | iwl_is_associated_ctx(ctx) && ctx->vif && | 813 | iwl_is_associated_ctx(ctx) && ctx->vif && |
801 | ctx->vif->type == NL80211_IFTYPE_STATION) { | 814 | ctx->vif->type == NL80211_IFTYPE_STATION) { |
802 | ctx->last_tx_rejected = true; | 815 | ctx->last_tx_rejected = true; |
803 | iwl_trans_stop_queue(trans(priv), txq_id); | 816 | iwl_trans_stop_queue(trans(priv), txq_id, |
817 | "Tx on passive channel"); | ||
804 | 818 | ||
805 | IWL_DEBUG_TX_REPLY(priv, | 819 | IWL_DEBUG_TX_REPLY(priv, |
806 | "TXQ %d status %s (0x%08x) " | 820 | "TXQ %d status %s (0x%08x) " |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8ba0dd54e37d..9ec315b31d45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/dma-mapping.h> | ||
34 | 35 | ||
35 | #include "iwl-dev.h" | 36 | #include "iwl-dev.h" |
36 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
@@ -72,51 +73,98 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
72 | {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS} | 73 | {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS} |
73 | }; | 74 | }; |
74 | 75 | ||
76 | /****************************************************************************** | ||
77 | * | ||
78 | * uCode download functions | ||
79 | * | ||
80 | ******************************************************************************/ | ||
81 | |||
82 | static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) | ||
83 | { | ||
84 | if (desc->v_addr) | ||
85 | dma_free_coherent(bus->dev, desc->len, | ||
86 | desc->v_addr, desc->p_addr); | ||
87 | desc->v_addr = NULL; | ||
88 | desc->len = 0; | ||
89 | } | ||
90 | |||
91 | static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) | ||
92 | { | ||
93 | iwl_free_fw_desc(bus, &img->code); | ||
94 | iwl_free_fw_desc(bus, &img->data); | ||
95 | } | ||
96 | |||
97 | void iwl_dealloc_ucode(struct iwl_trans *trans) | ||
98 | { | ||
99 | iwl_free_fw_img(bus(trans), &trans->ucode_rt); | ||
100 | iwl_free_fw_img(bus(trans), &trans->ucode_init); | ||
101 | iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); | ||
102 | } | ||
103 | |||
104 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | ||
105 | const void *data, size_t len) | ||
106 | { | ||
107 | if (!len) { | ||
108 | desc->v_addr = NULL; | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | |||
112 | desc->v_addr = dma_alloc_coherent(bus->dev, len, | ||
113 | &desc->p_addr, GFP_KERNEL); | ||
114 | if (!desc->v_addr) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | desc->len = len; | ||
118 | memcpy(desc->v_addr, data, len); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
75 | /* | 122 | /* |
76 | * ucode | 123 | * ucode |
77 | */ | 124 | */ |
78 | static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | 125 | static int iwlagn_load_section(struct iwl_trans *trans, const char *name, |
79 | struct fw_desc *image, u32 dst_addr) | 126 | struct fw_desc *image, u32 dst_addr) |
80 | { | 127 | { |
128 | struct iwl_bus *bus = bus(trans); | ||
81 | dma_addr_t phy_addr = image->p_addr; | 129 | dma_addr_t phy_addr = image->p_addr; |
82 | u32 byte_cnt = image->len; | 130 | u32 byte_cnt = image->len; |
83 | int ret; | 131 | int ret; |
84 | 132 | ||
85 | priv->ucode_write_complete = 0; | 133 | trans->ucode_write_complete = 0; |
86 | 134 | ||
87 | iwl_write_direct32(bus(priv), | 135 | iwl_write_direct32(bus, |
88 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 136 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
89 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | 137 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); |
90 | 138 | ||
91 | iwl_write_direct32(bus(priv), | 139 | iwl_write_direct32(bus, |
92 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | 140 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); |
93 | 141 | ||
94 | iwl_write_direct32(bus(priv), | 142 | iwl_write_direct32(bus, |
95 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | 143 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), |
96 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | 144 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); |
97 | 145 | ||
98 | iwl_write_direct32(bus(priv), | 146 | iwl_write_direct32(bus, |
99 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | 147 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), |
100 | (iwl_get_dma_hi_addr(phy_addr) | 148 | (iwl_get_dma_hi_addr(phy_addr) |
101 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | 149 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); |
102 | 150 | ||
103 | iwl_write_direct32(bus(priv), | 151 | iwl_write_direct32(bus, |
104 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | 152 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), |
105 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | 153 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | |
106 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | 154 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | |
107 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | 155 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); |
108 | 156 | ||
109 | iwl_write_direct32(bus(priv), | 157 | iwl_write_direct32(bus, |
110 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 158 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
111 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 159 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
112 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 160 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
113 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 161 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
114 | 162 | ||
115 | IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); | 163 | IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); |
116 | ret = wait_event_timeout(priv->shrd->wait_command_queue, | 164 | ret = wait_event_timeout(trans->shrd->wait_command_queue, |
117 | priv->ucode_write_complete, 5 * HZ); | 165 | trans->ucode_write_complete, 5 * HZ); |
118 | if (!ret) { | 166 | if (!ret) { |
119 | IWL_ERR(priv, "Could not load the %s uCode section\n", | 167 | IWL_ERR(trans, "Could not load the %s uCode section\n", |
120 | name); | 168 | name); |
121 | return -ETIMEDOUT; | 169 | return -ETIMEDOUT; |
122 | } | 170 | } |
@@ -124,17 +172,41 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | |||
124 | return 0; | 172 | return 0; |
125 | } | 173 | } |
126 | 174 | ||
127 | static int iwlagn_load_given_ucode(struct iwl_priv *priv, | 175 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, |
128 | struct fw_img *image) | 176 | enum iwl_ucode_type ucode_type) |
177 | { | ||
178 | switch (ucode_type) { | ||
179 | case IWL_UCODE_INIT: | ||
180 | return &trans->ucode_init; | ||
181 | case IWL_UCODE_WOWLAN: | ||
182 | return &trans->ucode_wowlan; | ||
183 | case IWL_UCODE_REGULAR: | ||
184 | return &trans->ucode_rt; | ||
185 | case IWL_UCODE_NONE: | ||
186 | break; | ||
187 | } | ||
188 | return NULL; | ||
189 | } | ||
190 | |||
191 | static int iwlagn_load_given_ucode(struct iwl_trans *trans, | ||
192 | enum iwl_ucode_type ucode_type) | ||
129 | { | 193 | { |
130 | int ret = 0; | 194 | int ret = 0; |
195 | struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); | ||
196 | |||
197 | |||
198 | if (!image) { | ||
199 | IWL_ERR(trans, "Invalid ucode requested (%d)\n", | ||
200 | ucode_type); | ||
201 | return -EINVAL; | ||
202 | } | ||
131 | 203 | ||
132 | ret = iwlagn_load_section(priv, "INST", &image->code, | 204 | ret = iwlagn_load_section(trans, "INST", &image->code, |
133 | IWLAGN_RTC_INST_LOWER_BOUND); | 205 | IWLAGN_RTC_INST_LOWER_BOUND); |
134 | if (ret) | 206 | if (ret) |
135 | return ret; | 207 | return ret; |
136 | 208 | ||
137 | return iwlagn_load_section(priv, "DATA", &image->data, | 209 | return iwlagn_load_section(trans, "DATA", &image->data, |
138 | IWLAGN_RTC_DATA_LOWER_BOUND); | 210 | IWLAGN_RTC_DATA_LOWER_BOUND); |
139 | } | 211 | } |
140 | 212 | ||
@@ -418,7 +490,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) | |||
418 | * using sample data 100 bytes apart. If these sample points are good, | 490 | * using sample data 100 bytes apart. If these sample points are good, |
419 | * it's a pretty good bet that everything between them is good, too. | 491 | * it's a pretty good bet that everything between them is good, too. |
420 | */ | 492 | */ |
421 | static int iwl_verify_inst_sparse(struct iwl_priv *priv, | 493 | static int iwl_verify_inst_sparse(struct iwl_bus *bus, |
422 | struct fw_desc *fw_desc) | 494 | struct fw_desc *fw_desc) |
423 | { | 495 | { |
424 | __le32 *image = (__le32 *)fw_desc->v_addr; | 496 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -426,15 +498,15 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
426 | u32 val; | 498 | u32 val; |
427 | u32 i; | 499 | u32 i; |
428 | 500 | ||
429 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | 501 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); |
430 | 502 | ||
431 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 503 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
432 | /* read data comes through single port, auto-incr addr */ | 504 | /* read data comes through single port, auto-incr addr */ |
433 | /* NOTE: Use the debugless read so we don't flood kernel log | 505 | /* NOTE: Use the debugless read so we don't flood kernel log |
434 | * if IWL_DL_IO is set */ | 506 | * if IWL_DL_IO is set */ |
435 | iwl_write_direct32(bus(priv), HBUS_TARG_MEM_RADDR, | 507 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, |
436 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 508 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
437 | val = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 509 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); |
438 | if (val != le32_to_cpu(*image)) | 510 | if (val != le32_to_cpu(*image)) |
439 | return -EIO; | 511 | return -EIO; |
440 | } | 512 | } |
@@ -442,7 +514,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
442 | return 0; | 514 | return 0; |
443 | } | 515 | } |
444 | 516 | ||
445 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, | 517 | static void iwl_print_mismatch_inst(struct iwl_bus *bus, |
446 | struct fw_desc *fw_desc) | 518 | struct fw_desc *fw_desc) |
447 | { | 519 | { |
448 | __le32 *image = (__le32 *)fw_desc->v_addr; | 520 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -451,18 +523,18 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
451 | u32 offs; | 523 | u32 offs; |
452 | int errors = 0; | 524 | int errors = 0; |
453 | 525 | ||
454 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | 526 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); |
455 | 527 | ||
456 | iwl_write_direct32(bus(priv), HBUS_TARG_MEM_RADDR, | 528 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, |
457 | IWLAGN_RTC_INST_LOWER_BOUND); | 529 | IWLAGN_RTC_INST_LOWER_BOUND); |
458 | 530 | ||
459 | for (offs = 0; | 531 | for (offs = 0; |
460 | offs < len && errors < 20; | 532 | offs < len && errors < 20; |
461 | offs += sizeof(u32), image++) { | 533 | offs += sizeof(u32), image++) { |
462 | /* read data comes through single port, auto-incr addr */ | 534 | /* read data comes through single port, auto-incr addr */ |
463 | val = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 535 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); |
464 | if (val != le32_to_cpu(*image)) { | 536 | if (val != le32_to_cpu(*image)) { |
465 | IWL_ERR(priv, "uCode INST section at " | 537 | IWL_ERR(bus, "uCode INST section at " |
466 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 538 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
467 | offs, val, le32_to_cpu(*image)); | 539 | offs, val, le32_to_cpu(*image)); |
468 | errors++; | 540 | errors++; |
@@ -474,16 +546,24 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
474 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 546 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
475 | * and verify its contents | 547 | * and verify its contents |
476 | */ | 548 | */ |
477 | static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) | 549 | static int iwl_verify_ucode(struct iwl_trans *trans, |
550 | enum iwl_ucode_type ucode_type) | ||
478 | { | 551 | { |
479 | if (!iwl_verify_inst_sparse(priv, &img->code)) { | 552 | struct fw_img *img = iwl_get_ucode_image(trans, ucode_type); |
480 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); | 553 | |
554 | if (!img) { | ||
555 | IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { | ||
560 | IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); | ||
481 | return 0; | 561 | return 0; |
482 | } | 562 | } |
483 | 563 | ||
484 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 564 | IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
485 | 565 | ||
486 | iwl_print_mismatch_inst(priv, &img->code); | 566 | iwl_print_mismatch_inst(bus(trans), &img->code); |
487 | return -EIO; | 567 | return -EIO; |
488 | } | 568 | } |
489 | 569 | ||
@@ -519,13 +599,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, | |||
519 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 599 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
520 | 600 | ||
521 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 601 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
522 | struct fw_img *image, | 602 | enum iwl_ucode_type ucode_type) |
523 | enum iwlagn_ucode_type ucode_type) | ||
524 | { | 603 | { |
525 | struct iwl_notification_wait alive_wait; | 604 | struct iwl_notification_wait alive_wait; |
526 | struct iwlagn_alive_data alive_data; | 605 | struct iwlagn_alive_data alive_data; |
527 | int ret; | 606 | int ret; |
528 | enum iwlagn_ucode_type old_type; | 607 | enum iwl_ucode_type old_type; |
529 | 608 | ||
530 | ret = iwl_trans_start_device(trans(priv)); | 609 | ret = iwl_trans_start_device(trans(priv)); |
531 | if (ret) | 610 | if (ret) |
@@ -537,7 +616,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
537 | old_type = priv->ucode_type; | 616 | old_type = priv->ucode_type; |
538 | priv->ucode_type = ucode_type; | 617 | priv->ucode_type = ucode_type; |
539 | 618 | ||
540 | ret = iwlagn_load_given_ucode(priv, image); | 619 | ret = iwlagn_load_given_ucode(trans(priv), ucode_type); |
541 | if (ret) { | 620 | if (ret) { |
542 | priv->ucode_type = old_type; | 621 | priv->ucode_type = old_type; |
543 | iwlagn_remove_notification(priv, &alive_wait); | 622 | iwlagn_remove_notification(priv, &alive_wait); |
@@ -568,7 +647,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
568 | * skip it for WoWLAN. | 647 | * skip it for WoWLAN. |
569 | */ | 648 | */ |
570 | if (ucode_type != IWL_UCODE_WOWLAN) { | 649 | if (ucode_type != IWL_UCODE_WOWLAN) { |
571 | ret = iwl_verify_ucode(priv, image); | 650 | ret = iwl_verify_ucode(trans(priv), ucode_type); |
572 | if (ret) { | 651 | if (ret) { |
573 | priv->ucode_type = old_type; | 652 | priv->ucode_type = old_type; |
574 | return ret; | 653 | return ret; |
@@ -597,7 +676,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
597 | lockdep_assert_held(&priv->shrd->mutex); | 676 | lockdep_assert_held(&priv->shrd->mutex); |
598 | 677 | ||
599 | /* No init ucode required? Curious, but maybe ok */ | 678 | /* No init ucode required? Curious, but maybe ok */ |
600 | if (!priv->ucode_init.code.len) | 679 | if (!trans(priv)->ucode_init.code.len) |
601 | return 0; | 680 | return 0; |
602 | 681 | ||
603 | if (priv->ucode_type != IWL_UCODE_NONE) | 682 | if (priv->ucode_type != IWL_UCODE_NONE) |
@@ -608,8 +687,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
608 | NULL, NULL); | 687 | NULL, NULL); |
609 | 688 | ||
610 | /* Will also start the device */ | 689 | /* Will also start the device */ |
611 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 690 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
612 | IWL_UCODE_INIT); | ||
613 | if (ret) | 691 | if (ret) |
614 | goto error; | 692 | goto error; |
615 | 693 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ccba69b7f8a7..e235e84de8b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
35 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
36 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
@@ -452,52 +451,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
452 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 451 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
453 | } | 452 | } |
454 | 453 | ||
455 | /****************************************************************************** | ||
456 | * | ||
457 | * uCode download functions | ||
458 | * | ||
459 | ******************************************************************************/ | ||
460 | |||
461 | static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) | ||
462 | { | ||
463 | if (desc->v_addr) | ||
464 | dma_free_coherent(bus(priv)->dev, desc->len, | ||
465 | desc->v_addr, desc->p_addr); | ||
466 | desc->v_addr = NULL; | ||
467 | desc->len = 0; | ||
468 | } | ||
469 | |||
470 | static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img) | ||
471 | { | ||
472 | iwl_free_fw_desc(priv, &img->code); | ||
473 | iwl_free_fw_desc(priv, &img->data); | ||
474 | } | ||
475 | |||
476 | static void iwl_dealloc_ucode(struct iwl_priv *priv) | ||
477 | { | ||
478 | iwl_free_fw_img(priv, &priv->ucode_rt); | ||
479 | iwl_free_fw_img(priv, &priv->ucode_init); | ||
480 | iwl_free_fw_img(priv, &priv->ucode_wowlan); | ||
481 | } | ||
482 | |||
483 | static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, | ||
484 | const void *data, size_t len) | ||
485 | { | ||
486 | if (!len) { | ||
487 | desc->v_addr = NULL; | ||
488 | return -EINVAL; | ||
489 | } | ||
490 | |||
491 | desc->v_addr = dma_alloc_coherent(bus(priv)->dev, len, | ||
492 | &desc->p_addr, GFP_KERNEL); | ||
493 | if (!desc->v_addr) | ||
494 | return -ENOMEM; | ||
495 | |||
496 | desc->len = len; | ||
497 | memcpy(desc->v_addr, data, len); | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 454 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
502 | { | 455 | { |
503 | int i; | 456 | int i; |
@@ -555,16 +508,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
555 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 508 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
556 | } | 509 | } |
557 | 510 | ||
558 | |||
559 | struct iwlagn_ucode_capabilities { | ||
560 | u32 max_probe_length; | ||
561 | u32 standard_phy_calibration_size; | ||
562 | u32 flags; | ||
563 | }; | ||
564 | |||
565 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | 511 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); |
566 | static int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
567 | struct iwlagn_ucode_capabilities *capa); | ||
568 | 512 | ||
569 | #define UCODE_EXPERIMENTAL_INDEX 100 | 513 | #define UCODE_EXPERIMENTAL_INDEX 100 |
570 | #define UCODE_EXPERIMENTAL_TAG "exp" | 514 | #define UCODE_EXPERIMENTAL_TAG "exp" |
@@ -1040,30 +984,32 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1040 | /* Runtime instructions and 2 copies of data: | 984 | /* Runtime instructions and 2 copies of data: |
1041 | * 1) unmodified from disk | 985 | * 1) unmodified from disk |
1042 | * 2) backup cache for save/restore during power-downs */ | 986 | * 2) backup cache for save/restore during power-downs */ |
1043 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code, | 987 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, |
1044 | pieces.inst, pieces.inst_size)) | 988 | pieces.inst, pieces.inst_size)) |
1045 | goto err_pci_alloc; | 989 | goto err_pci_alloc; |
1046 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.data, | 990 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, |
1047 | pieces.data, pieces.data_size)) | 991 | pieces.data, pieces.data_size)) |
1048 | goto err_pci_alloc; | 992 | goto err_pci_alloc; |
1049 | 993 | ||
1050 | /* Initialization instructions and data */ | 994 | /* Initialization instructions and data */ |
1051 | if (pieces.init_size && pieces.init_data_size) { | 995 | if (pieces.init_size && pieces.init_data_size) { |
1052 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code, | 996 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, |
1053 | pieces.init, pieces.init_size)) | 997 | pieces.init, pieces.init_size)) |
1054 | goto err_pci_alloc; | 998 | goto err_pci_alloc; |
1055 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data, | 999 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, |
1056 | pieces.init_data, pieces.init_data_size)) | 1000 | pieces.init_data, pieces.init_data_size)) |
1057 | goto err_pci_alloc; | 1001 | goto err_pci_alloc; |
1058 | } | 1002 | } |
1059 | 1003 | ||
1060 | /* WoWLAN instructions and data */ | 1004 | /* WoWLAN instructions and data */ |
1061 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | 1005 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { |
1062 | if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.code, | 1006 | if (iwl_alloc_fw_desc(bus(priv), |
1007 | &trans(priv)->ucode_wowlan.code, | ||
1063 | pieces.wowlan_inst, | 1008 | pieces.wowlan_inst, |
1064 | pieces.wowlan_inst_size)) | 1009 | pieces.wowlan_inst_size)) |
1065 | goto err_pci_alloc; | 1010 | goto err_pci_alloc; |
1066 | if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.data, | 1011 | if (iwl_alloc_fw_desc(bus(priv), |
1012 | &trans(priv)->ucode_wowlan.data, | ||
1067 | pieces.wowlan_data, | 1013 | pieces.wowlan_data, |
1068 | pieces.wowlan_data_size)) | 1014 | pieces.wowlan_data_size)) |
1069 | goto err_pci_alloc; | 1015 | goto err_pci_alloc; |
@@ -1156,7 +1102,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1156 | 1102 | ||
1157 | err_pci_alloc: | 1103 | err_pci_alloc: |
1158 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1104 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1159 | iwl_dealloc_ucode(priv); | 1105 | iwl_dealloc_ucode(trans(priv)); |
1160 | out_unbind: | 1106 | out_unbind: |
1161 | complete(&priv->firmware_loading_complete); | 1107 | complete(&priv->firmware_loading_complete); |
1162 | device_release_driver(bus(priv)->dev); | 1108 | device_release_driver(bus(priv)->dev); |
@@ -1352,7 +1298,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1352 | 1298 | ||
1353 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); | 1299 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
1354 | 1300 | ||
1355 | static void __iwl_down(struct iwl_priv *priv) | 1301 | void __iwl_down(struct iwl_priv *priv) |
1356 | { | 1302 | { |
1357 | int exit_pending; | 1303 | int exit_pending; |
1358 | 1304 | ||
@@ -1415,7 +1361,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1415 | priv->beacon_skb = NULL; | 1361 | priv->beacon_skb = NULL; |
1416 | } | 1362 | } |
1417 | 1363 | ||
1418 | static void iwl_down(struct iwl_priv *priv) | 1364 | void iwl_down(struct iwl_priv *priv) |
1419 | { | 1365 | { |
1420 | mutex_lock(&priv->shrd->mutex); | 1366 | mutex_lock(&priv->shrd->mutex); |
1421 | __iwl_down(priv); | 1367 | __iwl_down(priv); |
@@ -1424,57 +1370,6 @@ static void iwl_down(struct iwl_priv *priv) | |||
1424 | iwl_cancel_deferred_work(priv); | 1370 | iwl_cancel_deferred_work(priv); |
1425 | } | 1371 | } |
1426 | 1372 | ||
1427 | #define MAX_HW_RESTARTS 5 | ||
1428 | |||
1429 | static int __iwl_up(struct iwl_priv *priv) | ||
1430 | { | ||
1431 | struct iwl_rxon_context *ctx; | ||
1432 | int ret; | ||
1433 | |||
1434 | lockdep_assert_held(&priv->shrd->mutex); | ||
1435 | |||
1436 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
1437 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | ||
1438 | return -EIO; | ||
1439 | } | ||
1440 | |||
1441 | for_each_context(priv, ctx) { | ||
1442 | ret = iwlagn_alloc_bcast_station(priv, ctx); | ||
1443 | if (ret) { | ||
1444 | iwl_dealloc_bcast_stations(priv); | ||
1445 | return ret; | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | ret = iwlagn_run_init_ucode(priv); | ||
1450 | if (ret) { | ||
1451 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | ||
1452 | goto error; | ||
1453 | } | ||
1454 | |||
1455 | ret = iwlagn_load_ucode_wait_alive(priv, | ||
1456 | &priv->ucode_rt, | ||
1457 | IWL_UCODE_REGULAR); | ||
1458 | if (ret) { | ||
1459 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||
1460 | goto error; | ||
1461 | } | ||
1462 | |||
1463 | ret = iwl_alive_start(priv); | ||
1464 | if (ret) | ||
1465 | goto error; | ||
1466 | return 0; | ||
1467 | |||
1468 | error: | ||
1469 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
1470 | __iwl_down(priv); | ||
1471 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
1472 | |||
1473 | IWL_ERR(priv, "Unable to initialize device.\n"); | ||
1474 | return ret; | ||
1475 | } | ||
1476 | |||
1477 | |||
1478 | /***************************************************************************** | 1373 | /***************************************************************************** |
1479 | * | 1374 | * |
1480 | * Workqueue callbacks | 1375 | * Workqueue callbacks |
@@ -1502,7 +1397,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
1502 | mutex_unlock(&priv->shrd->mutex); | 1397 | mutex_unlock(&priv->shrd->mutex); |
1503 | } | 1398 | } |
1504 | 1399 | ||
1505 | static void iwlagn_prepare_restart(struct iwl_priv *priv) | 1400 | void iwlagn_prepare_restart(struct iwl_priv *priv) |
1506 | { | 1401 | { |
1507 | struct iwl_rxon_context *ctx; | 1402 | struct iwl_rxon_context *ctx; |
1508 | bool bt_full_concurrent; | 1403 | bool bt_full_concurrent; |
@@ -1559,1173 +1454,8 @@ static void iwl_bg_restart(struct work_struct *data) | |||
1559 | } | 1454 | } |
1560 | } | 1455 | } |
1561 | 1456 | ||
1562 | /***************************************************************************** | ||
1563 | * | ||
1564 | * mac80211 entry point functions | ||
1565 | * | ||
1566 | *****************************************************************************/ | ||
1567 | |||
1568 | static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { | ||
1569 | { | ||
1570 | .max = 1, | ||
1571 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1572 | }, | ||
1573 | { | ||
1574 | .max = 1, | ||
1575 | .types = BIT(NL80211_IFTYPE_AP), | ||
1576 | }, | ||
1577 | }; | ||
1578 | |||
1579 | static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { | ||
1580 | { | ||
1581 | .max = 2, | ||
1582 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1583 | }, | ||
1584 | }; | ||
1585 | |||
1586 | static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { | ||
1587 | { | ||
1588 | .max = 1, | ||
1589 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1590 | }, | ||
1591 | { | ||
1592 | .max = 1, | ||
1593 | .types = BIT(NL80211_IFTYPE_P2P_GO) | | ||
1594 | BIT(NL80211_IFTYPE_AP), | ||
1595 | }, | ||
1596 | }; | ||
1597 | |||
1598 | static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { | ||
1599 | { | ||
1600 | .max = 2, | ||
1601 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1602 | }, | ||
1603 | { | ||
1604 | .max = 1, | ||
1605 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
1606 | }, | ||
1607 | }; | ||
1608 | |||
1609 | static const struct ieee80211_iface_combination | ||
1610 | iwlagn_iface_combinations_dualmode[] = { | ||
1611 | { .num_different_channels = 1, | ||
1612 | .max_interfaces = 2, | ||
1613 | .beacon_int_infra_match = true, | ||
1614 | .limits = iwlagn_sta_ap_limits, | ||
1615 | .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), | ||
1616 | }, | ||
1617 | { .num_different_channels = 1, | ||
1618 | .max_interfaces = 2, | ||
1619 | .limits = iwlagn_2sta_limits, | ||
1620 | .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), | ||
1621 | }, | ||
1622 | }; | ||
1623 | |||
1624 | static const struct ieee80211_iface_combination | ||
1625 | iwlagn_iface_combinations_p2p[] = { | ||
1626 | { .num_different_channels = 1, | ||
1627 | .max_interfaces = 2, | ||
1628 | .beacon_int_infra_match = true, | ||
1629 | .limits = iwlagn_p2p_sta_go_limits, | ||
1630 | .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), | ||
1631 | }, | ||
1632 | { .num_different_channels = 1, | ||
1633 | .max_interfaces = 2, | ||
1634 | .limits = iwlagn_p2p_2sta_limits, | ||
1635 | .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), | ||
1636 | }, | ||
1637 | }; | ||
1638 | |||
1639 | /* | ||
1640 | * Not a mac80211 entry point function, but it fits in with all the | ||
1641 | * other mac80211 functions grouped here. | ||
1642 | */ | ||
1643 | static int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
1644 | struct iwlagn_ucode_capabilities *capa) | ||
1645 | { | ||
1646 | int ret; | ||
1647 | struct ieee80211_hw *hw = priv->hw; | ||
1648 | struct iwl_rxon_context *ctx; | ||
1649 | |||
1650 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
1651 | |||
1652 | /* Tell mac80211 our characteristics */ | ||
1653 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
1654 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1655 | IEEE80211_HW_NEED_DTIM_PERIOD | | ||
1656 | IEEE80211_HW_SPECTRUM_MGMT | | ||
1657 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
1658 | |||
1659 | /* | ||
1660 | * Including the following line will crash some AP's. This | ||
1661 | * workaround removes the stimulus which causes the crash until | ||
1662 | * the AP software can be fixed. | ||
1663 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
1664 | */ | ||
1665 | |||
1666 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
1667 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
1668 | |||
1669 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1670 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
1671 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
1672 | |||
1673 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | ||
1674 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1675 | |||
1676 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
1677 | hw->vif_data_size = sizeof(struct iwl_vif_priv); | ||
1678 | |||
1679 | for_each_context(priv, ctx) { | ||
1680 | hw->wiphy->interface_modes |= ctx->interface_modes; | ||
1681 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | ||
1682 | } | ||
1683 | |||
1684 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1685 | |||
1686 | if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { | ||
1687 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; | ||
1688 | hw->wiphy->n_iface_combinations = | ||
1689 | ARRAY_SIZE(iwlagn_iface_combinations_p2p); | ||
1690 | } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | ||
1691 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode; | ||
1692 | hw->wiphy->n_iface_combinations = | ||
1693 | ARRAY_SIZE(iwlagn_iface_combinations_dualmode); | ||
1694 | } | ||
1695 | |||
1696 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
1697 | |||
1698 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | ||
1699 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | ||
1700 | WIPHY_FLAG_IBSS_RSN; | ||
1701 | |||
1702 | if (priv->ucode_wowlan.code.len && device_can_wakeup(bus(priv)->dev)) { | ||
1703 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | ||
1704 | WIPHY_WOWLAN_DISCONNECT | | ||
1705 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | | ||
1706 | WIPHY_WOWLAN_RFKILL_RELEASE; | ||
1707 | if (!iwlagn_mod_params.sw_crypto) | ||
1708 | hw->wiphy->wowlan.flags |= | ||
1709 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | | ||
1710 | WIPHY_WOWLAN_GTK_REKEY_FAILURE; | ||
1711 | |||
1712 | hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; | ||
1713 | hw->wiphy->wowlan.pattern_min_len = | ||
1714 | IWLAGN_WOWLAN_MIN_PATTERN_LEN; | ||
1715 | hw->wiphy->wowlan.pattern_max_len = | ||
1716 | IWLAGN_WOWLAN_MAX_PATTERN_LEN; | ||
1717 | } | ||
1718 | |||
1719 | if (iwlagn_mod_params.power_save) | ||
1720 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1721 | else | ||
1722 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1723 | |||
1724 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
1725 | /* we create the 802.11 header and a zero-length SSID element */ | ||
1726 | hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; | ||
1727 | |||
1728 | /* Default value; 4 EDCA QOS priorities */ | ||
1729 | hw->queues = 4; | ||
1730 | |||
1731 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
1732 | |||
1733 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
1734 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1735 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
1736 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
1737 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1738 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
1739 | |||
1740 | iwl_leds_init(priv); | ||
1741 | |||
1742 | ret = ieee80211_register_hw(priv->hw); | ||
1743 | if (ret) { | ||
1744 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
1745 | return ret; | ||
1746 | } | ||
1747 | priv->mac80211_registered = 1; | ||
1748 | |||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1752 | |||
1753 | static int iwlagn_mac_start(struct ieee80211_hw *hw) | ||
1754 | { | ||
1755 | struct iwl_priv *priv = hw->priv; | ||
1756 | int ret; | ||
1757 | |||
1758 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1759 | |||
1760 | /* we should be verifying the device is ready to be opened */ | ||
1761 | mutex_lock(&priv->shrd->mutex); | ||
1762 | ret = __iwl_up(priv); | ||
1763 | mutex_unlock(&priv->shrd->mutex); | ||
1764 | if (ret) | ||
1765 | return ret; | ||
1766 | |||
1767 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | ||
1768 | |||
1769 | /* Now we should be done, and the READY bit should be set. */ | ||
1770 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | ||
1771 | ret = -EIO; | ||
1772 | |||
1773 | iwlagn_led_enable(priv); | ||
1774 | |||
1775 | priv->is_open = 1; | ||
1776 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1777 | return 0; | ||
1778 | } | ||
1779 | |||
1780 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) | ||
1781 | { | ||
1782 | struct iwl_priv *priv = hw->priv; | ||
1783 | |||
1784 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1785 | |||
1786 | if (!priv->is_open) | ||
1787 | return; | ||
1788 | |||
1789 | priv->is_open = 0; | ||
1790 | |||
1791 | iwl_down(priv); | ||
1792 | |||
1793 | flush_workqueue(priv->shrd->workqueue); | ||
1794 | |||
1795 | /* User space software may expect getting rfkill changes | ||
1796 | * even if interface is down */ | ||
1797 | iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); | ||
1798 | iwl_enable_rfkill_int(priv); | ||
1799 | |||
1800 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1801 | } | ||
1802 | |||
1803 | #ifdef CONFIG_PM_SLEEP | ||
1804 | static int iwlagn_send_patterns(struct iwl_priv *priv, | ||
1805 | struct cfg80211_wowlan *wowlan) | ||
1806 | { | ||
1807 | struct iwlagn_wowlan_patterns_cmd *pattern_cmd; | ||
1808 | struct iwl_host_cmd cmd = { | ||
1809 | .id = REPLY_WOWLAN_PATTERNS, | ||
1810 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1811 | .flags = CMD_SYNC, | ||
1812 | }; | ||
1813 | int i, err; | ||
1814 | |||
1815 | if (!wowlan->n_patterns) | ||
1816 | return 0; | ||
1817 | |||
1818 | cmd.len[0] = sizeof(*pattern_cmd) + | ||
1819 | wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern); | ||
1820 | |||
1821 | pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL); | ||
1822 | if (!pattern_cmd) | ||
1823 | return -ENOMEM; | ||
1824 | |||
1825 | pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); | ||
1826 | |||
1827 | for (i = 0; i < wowlan->n_patterns; i++) { | ||
1828 | int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); | ||
1829 | |||
1830 | memcpy(&pattern_cmd->patterns[i].mask, | ||
1831 | wowlan->patterns[i].mask, mask_len); | ||
1832 | memcpy(&pattern_cmd->patterns[i].pattern, | ||
1833 | wowlan->patterns[i].pattern, | ||
1834 | wowlan->patterns[i].pattern_len); | ||
1835 | pattern_cmd->patterns[i].mask_size = mask_len; | ||
1836 | pattern_cmd->patterns[i].pattern_size = | ||
1837 | wowlan->patterns[i].pattern_len; | ||
1838 | } | ||
1839 | |||
1840 | cmd.data[0] = pattern_cmd; | ||
1841 | err = iwl_trans_send_cmd(trans(priv), &cmd); | ||
1842 | kfree(pattern_cmd); | ||
1843 | return err; | ||
1844 | } | ||
1845 | #endif | ||
1846 | |||
1847 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
1848 | struct ieee80211_vif *vif, | ||
1849 | struct cfg80211_gtk_rekey_data *data) | ||
1850 | { | ||
1851 | struct iwl_priv *priv = hw->priv; | ||
1852 | |||
1853 | if (iwlagn_mod_params.sw_crypto) | ||
1854 | return; | ||
1855 | |||
1856 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1857 | mutex_lock(&priv->shrd->mutex); | ||
1858 | |||
1859 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | ||
1860 | goto out; | ||
1861 | |||
1862 | memcpy(priv->kek, data->kek, NL80211_KEK_LEN); | ||
1863 | memcpy(priv->kck, data->kck, NL80211_KCK_LEN); | ||
1864 | priv->replay_ctr = cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr)); | ||
1865 | priv->have_rekey_data = true; | ||
1866 | |||
1867 | out: | ||
1868 | mutex_unlock(&priv->shrd->mutex); | ||
1869 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1870 | } | ||
1871 | |||
1872 | struct wowlan_key_data { | ||
1873 | struct iwl_rxon_context *ctx; | ||
1874 | struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc; | ||
1875 | struct iwlagn_wowlan_tkip_params_cmd *tkip; | ||
1876 | const u8 *bssid; | ||
1877 | bool error, use_rsc_tsc, use_tkip; | ||
1878 | }; | ||
1879 | |||
1880 | #ifdef CONFIG_PM_SLEEP | ||
1881 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) | ||
1882 | { | ||
1883 | int i; | ||
1884 | |||
1885 | for (i = 0; i < IWLAGN_P1K_SIZE; i++) | ||
1886 | out[i] = cpu_to_le16(p1k[i]); | ||
1887 | } | ||
1888 | |||
1889 | static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | ||
1890 | struct ieee80211_vif *vif, | ||
1891 | struct ieee80211_sta *sta, | ||
1892 | struct ieee80211_key_conf *key, | ||
1893 | void *_data) | ||
1894 | { | ||
1895 | struct iwl_priv *priv = hw->priv; | ||
1896 | struct wowlan_key_data *data = _data; | ||
1897 | struct iwl_rxon_context *ctx = data->ctx; | ||
1898 | struct aes_sc *aes_sc, *aes_tx_sc = NULL; | ||
1899 | struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL; | ||
1900 | struct iwlagn_p1k_cache *rx_p1ks; | ||
1901 | u8 *rx_mic_key; | ||
1902 | struct ieee80211_key_seq seq; | ||
1903 | u32 cur_rx_iv32 = 0; | ||
1904 | u16 p1k[IWLAGN_P1K_SIZE]; | ||
1905 | int ret, i; | ||
1906 | |||
1907 | mutex_lock(&priv->shrd->mutex); | ||
1908 | |||
1909 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
1910 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | ||
1911 | !sta && !ctx->key_mapping_keys) | ||
1912 | ret = iwl_set_default_wep_key(priv, ctx, key); | ||
1913 | else | ||
1914 | ret = iwl_set_dynamic_key(priv, ctx, key, sta); | ||
1915 | |||
1916 | if (ret) { | ||
1917 | IWL_ERR(priv, "Error setting key during suspend!\n"); | ||
1918 | data->error = true; | ||
1919 | } | ||
1920 | |||
1921 | switch (key->cipher) { | ||
1922 | case WLAN_CIPHER_SUITE_TKIP: | ||
1923 | if (sta) { | ||
1924 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc; | ||
1925 | tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc; | ||
1926 | |||
1927 | rx_p1ks = data->tkip->rx_uni; | ||
1928 | |||
1929 | ieee80211_get_key_tx_seq(key, &seq); | ||
1930 | tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1931 | tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1932 | |||
1933 | ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k); | ||
1934 | iwlagn_convert_p1k(p1k, data->tkip->tx.p1k); | ||
1935 | |||
1936 | memcpy(data->tkip->mic_keys.tx, | ||
1937 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
1938 | IWLAGN_MIC_KEY_SIZE); | ||
1939 | |||
1940 | rx_mic_key = data->tkip->mic_keys.rx_unicast; | ||
1941 | } else { | ||
1942 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc; | ||
1943 | rx_p1ks = data->tkip->rx_multi; | ||
1944 | rx_mic_key = data->tkip->mic_keys.rx_mcast; | ||
1945 | } | ||
1946 | |||
1947 | /* | ||
1948 | * For non-QoS this relies on the fact that both the uCode and | ||
1949 | * mac80211 use TID 0 (as they need to to avoid replay attacks) | ||
1950 | * for checking the IV in the frames. | ||
1951 | */ | ||
1952 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1953 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1954 | tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1955 | tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1956 | /* wrapping isn't allowed, AP must rekey */ | ||
1957 | if (seq.tkip.iv32 > cur_rx_iv32) | ||
1958 | cur_rx_iv32 = seq.tkip.iv32; | ||
1959 | } | ||
1960 | |||
1961 | ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k); | ||
1962 | iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k); | ||
1963 | ieee80211_get_tkip_rx_p1k(key, data->bssid, | ||
1964 | cur_rx_iv32 + 1, p1k); | ||
1965 | iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k); | ||
1966 | |||
1967 | memcpy(rx_mic_key, | ||
1968 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
1969 | IWLAGN_MIC_KEY_SIZE); | ||
1970 | |||
1971 | data->use_tkip = true; | ||
1972 | data->use_rsc_tsc = true; | ||
1973 | break; | ||
1974 | case WLAN_CIPHER_SUITE_CCMP: | ||
1975 | if (sta) { | ||
1976 | u8 *pn = seq.ccmp.pn; | ||
1977 | |||
1978 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc; | ||
1979 | aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc; | ||
1980 | |||
1981 | ieee80211_get_key_tx_seq(key, &seq); | ||
1982 | aes_tx_sc->pn = cpu_to_le64( | ||
1983 | (u64)pn[5] | | ||
1984 | ((u64)pn[4] << 8) | | ||
1985 | ((u64)pn[3] << 16) | | ||
1986 | ((u64)pn[2] << 24) | | ||
1987 | ((u64)pn[1] << 32) | | ||
1988 | ((u64)pn[0] << 40)); | ||
1989 | } else | ||
1990 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc; | ||
1991 | |||
1992 | /* | ||
1993 | * For non-QoS this relies on the fact that both the uCode and | ||
1994 | * mac80211 use TID 0 for checking the IV in the frames. | ||
1995 | */ | ||
1996 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1997 | u8 *pn = seq.ccmp.pn; | ||
1998 | |||
1999 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
2000 | aes_sc->pn = cpu_to_le64( | ||
2001 | (u64)pn[5] | | ||
2002 | ((u64)pn[4] << 8) | | ||
2003 | ((u64)pn[3] << 16) | | ||
2004 | ((u64)pn[2] << 24) | | ||
2005 | ((u64)pn[1] << 32) | | ||
2006 | ((u64)pn[0] << 40)); | ||
2007 | } | ||
2008 | data->use_rsc_tsc = true; | ||
2009 | break; | ||
2010 | } | ||
2011 | |||
2012 | mutex_unlock(&priv->shrd->mutex); | ||
2013 | } | ||
2014 | |||
2015 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | ||
2016 | struct cfg80211_wowlan *wowlan) | ||
2017 | { | ||
2018 | struct iwl_priv *priv = hw->priv; | ||
2019 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | ||
2020 | struct iwl_rxon_cmd rxon; | ||
2021 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2022 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | ||
2023 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | ||
2024 | struct wowlan_key_data key_data = { | ||
2025 | .ctx = ctx, | ||
2026 | .bssid = ctx->active.bssid_addr, | ||
2027 | .use_rsc_tsc = false, | ||
2028 | .tkip = &tkip_cmd, | ||
2029 | .use_tkip = false, | ||
2030 | }; | ||
2031 | int ret, i; | ||
2032 | u16 seq; | ||
2033 | |||
2034 | if (WARN_ON(!wowlan)) | ||
2035 | return -EINVAL; | ||
2036 | |||
2037 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2038 | mutex_lock(&priv->shrd->mutex); | ||
2039 | |||
2040 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | ||
2041 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | ||
2042 | !iwl_is_associated_ctx(ctx)) { | ||
2043 | ret = 1; | ||
2044 | goto out; | ||
2045 | } | ||
2046 | |||
2047 | key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); | ||
2048 | if (!key_data.rsc_tsc) { | ||
2049 | ret = -ENOMEM; | ||
2050 | goto out; | ||
2051 | } | ||
2052 | |||
2053 | memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd)); | ||
2054 | |||
2055 | /* | ||
2056 | * We know the last used seqno, and the uCode expects to know that | ||
2057 | * one, it will increment before TX. | ||
2058 | */ | ||
2059 | seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ; | ||
2060 | wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq); | ||
2061 | |||
2062 | /* | ||
2063 | * For QoS counters, we store the one to use next, so subtract 0x10 | ||
2064 | * since the uCode will add 0x10 before using the value. | ||
2065 | */ | ||
2066 | for (i = 0; i < 8; i++) { | ||
2067 | seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number; | ||
2068 | seq -= 0x10; | ||
2069 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); | ||
2070 | } | ||
2071 | |||
2072 | if (wowlan->disconnect) | ||
2073 | wakeup_filter_cmd.enabled |= | ||
2074 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS | | ||
2075 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE); | ||
2076 | if (wowlan->magic_pkt) | ||
2077 | wakeup_filter_cmd.enabled |= | ||
2078 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET); | ||
2079 | if (wowlan->gtk_rekey_failure) | ||
2080 | wakeup_filter_cmd.enabled |= | ||
2081 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL); | ||
2082 | if (wowlan->eap_identity_req) | ||
2083 | wakeup_filter_cmd.enabled |= | ||
2084 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ); | ||
2085 | if (wowlan->four_way_handshake) | ||
2086 | wakeup_filter_cmd.enabled |= | ||
2087 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE); | ||
2088 | if (wowlan->rfkill_release) | ||
2089 | wakeup_filter_cmd.enabled |= | ||
2090 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL); | ||
2091 | if (wowlan->n_patterns) | ||
2092 | wakeup_filter_cmd.enabled |= | ||
2093 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH); | ||
2094 | |||
2095 | iwl_scan_cancel_timeout(priv, 200); | ||
2096 | |||
2097 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | ||
2098 | |||
2099 | iwl_trans_stop_device(trans(priv)); | ||
2100 | |||
2101 | priv->shrd->wowlan = true; | ||
2102 | |||
2103 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_wowlan, | ||
2104 | IWL_UCODE_WOWLAN); | ||
2105 | if (ret) | ||
2106 | goto error; | ||
2107 | |||
2108 | /* now configure WoWLAN ucode */ | ||
2109 | ret = iwl_alive_start(priv); | ||
2110 | if (ret) | ||
2111 | goto error; | ||
2112 | |||
2113 | memcpy(&ctx->staging, &rxon, sizeof(rxon)); | ||
2114 | ret = iwlagn_commit_rxon(priv, ctx); | ||
2115 | if (ret) | ||
2116 | goto error; | ||
2117 | |||
2118 | ret = iwl_power_update_mode(priv, true); | ||
2119 | if (ret) | ||
2120 | goto error; | ||
2121 | |||
2122 | if (!iwlagn_mod_params.sw_crypto) { | ||
2123 | /* mark all keys clear */ | ||
2124 | priv->ucode_key_table = 0; | ||
2125 | ctx->key_mapping_keys = 0; | ||
2126 | |||
2127 | /* | ||
2128 | * This needs to be unlocked due to lock ordering | ||
2129 | * constraints. Since we're in the suspend path | ||
2130 | * that isn't really a problem though. | ||
2131 | */ | ||
2132 | mutex_unlock(&priv->shrd->mutex); | ||
2133 | ieee80211_iter_keys(priv->hw, ctx->vif, | ||
2134 | iwlagn_wowlan_program_keys, | ||
2135 | &key_data); | ||
2136 | mutex_lock(&priv->shrd->mutex); | ||
2137 | if (key_data.error) { | ||
2138 | ret = -EIO; | ||
2139 | goto error; | ||
2140 | } | ||
2141 | |||
2142 | if (key_data.use_rsc_tsc) { | ||
2143 | struct iwl_host_cmd rsc_tsc_cmd = { | ||
2144 | .id = REPLY_WOWLAN_TSC_RSC_PARAMS, | ||
2145 | .flags = CMD_SYNC, | ||
2146 | .data[0] = key_data.rsc_tsc, | ||
2147 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
2148 | .len[0] = sizeof(*key_data.rsc_tsc), | ||
2149 | }; | ||
2150 | |||
2151 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | ||
2152 | if (ret) | ||
2153 | goto error; | ||
2154 | } | ||
2155 | |||
2156 | if (key_data.use_tkip) { | ||
2157 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
2158 | REPLY_WOWLAN_TKIP_PARAMS, | ||
2159 | CMD_SYNC, sizeof(tkip_cmd), | ||
2160 | &tkip_cmd); | ||
2161 | if (ret) | ||
2162 | goto error; | ||
2163 | } | ||
2164 | |||
2165 | if (priv->have_rekey_data) { | ||
2166 | memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd)); | ||
2167 | memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN); | ||
2168 | kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN); | ||
2169 | memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN); | ||
2170 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | ||
2171 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | ||
2172 | |||
2173 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
2174 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | ||
2175 | CMD_SYNC, sizeof(kek_kck_cmd), | ||
2176 | &kek_kck_cmd); | ||
2177 | if (ret) | ||
2178 | goto error; | ||
2179 | } | ||
2180 | } | ||
2181 | |||
2182 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | ||
2183 | CMD_SYNC, sizeof(wakeup_filter_cmd), | ||
2184 | &wakeup_filter_cmd); | ||
2185 | if (ret) | ||
2186 | goto error; | ||
2187 | |||
2188 | ret = iwlagn_send_patterns(priv, wowlan); | ||
2189 | if (ret) | ||
2190 | goto error; | ||
2191 | |||
2192 | device_set_wakeup_enable(bus(priv)->dev, true); | ||
2193 | |||
2194 | /* Now let the ucode operate on its own */ | ||
2195 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | ||
2196 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
2197 | |||
2198 | goto out; | ||
2199 | |||
2200 | error: | ||
2201 | priv->shrd->wowlan = false; | ||
2202 | iwlagn_prepare_restart(priv); | ||
2203 | ieee80211_restart_hw(priv->hw); | ||
2204 | out: | ||
2205 | mutex_unlock(&priv->shrd->mutex); | ||
2206 | kfree(key_data.rsc_tsc); | ||
2207 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2208 | |||
2209 | return ret; | ||
2210 | } | ||
2211 | |||
2212 | static int iwlagn_mac_resume(struct ieee80211_hw *hw) | ||
2213 | { | ||
2214 | struct iwl_priv *priv = hw->priv; | ||
2215 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2216 | struct ieee80211_vif *vif; | ||
2217 | unsigned long flags; | ||
2218 | u32 base, status = 0xffffffff; | ||
2219 | int ret = -EIO; | ||
2220 | |||
2221 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2222 | mutex_lock(&priv->shrd->mutex); | ||
2223 | |||
2224 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | ||
2225 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
2226 | |||
2227 | base = priv->device_pointers.error_event_table; | ||
2228 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | ||
2229 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | ||
2230 | ret = iwl_grab_nic_access_silent(bus(priv)); | ||
2231 | if (ret == 0) { | ||
2232 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); | ||
2233 | status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | ||
2234 | iwl_release_nic_access(bus(priv)); | ||
2235 | } | ||
2236 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | ||
2237 | |||
2238 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
2239 | if (ret == 0) { | ||
2240 | if (!priv->wowlan_sram) | ||
2241 | priv->wowlan_sram = | ||
2242 | kzalloc(priv->ucode_wowlan.data.len, | ||
2243 | GFP_KERNEL); | ||
2244 | |||
2245 | if (priv->wowlan_sram) | ||
2246 | _iwl_read_targ_mem_words( | ||
2247 | bus(priv), 0x800000, priv->wowlan_sram, | ||
2248 | priv->ucode_wowlan.data.len / 4); | ||
2249 | } | ||
2250 | #endif | ||
2251 | } | ||
2252 | |||
2253 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | ||
2254 | vif = ctx->vif; | ||
2255 | |||
2256 | priv->shrd->wowlan = false; | ||
2257 | |||
2258 | device_set_wakeup_enable(bus(priv)->dev, false); | ||
2259 | |||
2260 | iwlagn_prepare_restart(priv); | ||
2261 | |||
2262 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); | ||
2263 | iwl_connection_init_rx_config(priv, ctx); | ||
2264 | iwlagn_set_rxon_chain(priv, ctx); | ||
2265 | |||
2266 | mutex_unlock(&priv->shrd->mutex); | ||
2267 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2268 | |||
2269 | ieee80211_resume_disconnect(vif); | ||
2270 | |||
2271 | return 1; | ||
2272 | } | ||
2273 | #endif | ||
2274 | |||
2275 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2276 | { | ||
2277 | struct iwl_priv *priv = hw->priv; | ||
2278 | |||
2279 | IWL_DEBUG_MACDUMP(priv, "enter\n"); | ||
2280 | |||
2281 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
2282 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
2283 | |||
2284 | if (iwlagn_tx_skb(priv, skb)) | ||
2285 | dev_kfree_skb_any(skb); | ||
2286 | |||
2287 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | ||
2288 | } | ||
2289 | |||
2290 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
2291 | struct ieee80211_vif *vif, | ||
2292 | struct ieee80211_key_conf *keyconf, | ||
2293 | struct ieee80211_sta *sta, | ||
2294 | u32 iv32, u16 *phase1key) | ||
2295 | { | ||
2296 | struct iwl_priv *priv = hw->priv; | ||
2297 | |||
2298 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | ||
2299 | } | ||
2300 | |||
2301 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
2302 | struct ieee80211_vif *vif, | ||
2303 | struct ieee80211_sta *sta, | ||
2304 | struct ieee80211_key_conf *key) | ||
2305 | { | ||
2306 | struct iwl_priv *priv = hw->priv; | ||
2307 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2308 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2309 | int ret; | ||
2310 | bool is_default_wep_key = false; | ||
2311 | |||
2312 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2313 | |||
2314 | if (iwlagn_mod_params.sw_crypto) { | ||
2315 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | ||
2316 | return -EOPNOTSUPP; | ||
2317 | } | ||
2318 | |||
2319 | /* | ||
2320 | * We could program these keys into the hardware as well, but we | ||
2321 | * don't expect much multicast traffic in IBSS and having keys | ||
2322 | * for more stations is probably more useful. | ||
2323 | * | ||
2324 | * Mark key TX-only and return 0. | ||
2325 | */ | ||
2326 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
2327 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
2328 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | /* If they key was TX-only, accept deletion */ | ||
2333 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | ||
2334 | return 0; | ||
2335 | |||
2336 | mutex_lock(&priv->shrd->mutex); | ||
2337 | iwl_scan_cancel_timeout(priv, 100); | ||
2338 | |||
2339 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | ||
2340 | |||
2341 | /* | ||
2342 | * If we are getting WEP group key and we didn't receive any key mapping | ||
2343 | * so far, we are in legacy wep mode (group key only), otherwise we are | ||
2344 | * in 1X mode. | ||
2345 | * In legacy wep mode, we use another host command to the uCode. | ||
2346 | */ | ||
2347 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
2348 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { | ||
2349 | if (cmd == SET_KEY) | ||
2350 | is_default_wep_key = !ctx->key_mapping_keys; | ||
2351 | else | ||
2352 | is_default_wep_key = | ||
2353 | key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT; | ||
2354 | } | ||
2355 | |||
2356 | |||
2357 | switch (cmd) { | ||
2358 | case SET_KEY: | ||
2359 | if (is_default_wep_key) { | ||
2360 | ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); | ||
2361 | break; | ||
2362 | } | ||
2363 | ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta); | ||
2364 | if (ret) { | ||
2365 | /* | ||
2366 | * can't add key for RX, but we don't need it | ||
2367 | * in the device for TX so still return 0 | ||
2368 | */ | ||
2369 | ret = 0; | ||
2370 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
2371 | } | ||
2372 | |||
2373 | IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); | ||
2374 | break; | ||
2375 | case DISABLE_KEY: | ||
2376 | if (is_default_wep_key) | ||
2377 | ret = iwl_remove_default_wep_key(priv, ctx, key); | ||
2378 | else | ||
2379 | ret = iwl_remove_dynamic_key(priv, ctx, key, sta); | ||
2380 | |||
2381 | IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); | ||
2382 | break; | ||
2383 | default: | ||
2384 | ret = -EINVAL; | ||
2385 | } | ||
2386 | |||
2387 | mutex_unlock(&priv->shrd->mutex); | ||
2388 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2389 | |||
2390 | return ret; | ||
2391 | } | ||
2392 | |||
2393 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
2394 | struct ieee80211_vif *vif, | ||
2395 | enum ieee80211_ampdu_mlme_action action, | ||
2396 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
2397 | u8 buf_size) | ||
2398 | { | ||
2399 | struct iwl_priv *priv = hw->priv; | ||
2400 | int ret = -EINVAL; | ||
2401 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
2402 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
2403 | |||
2404 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | ||
2405 | sta->addr, tid); | ||
2406 | |||
2407 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) | ||
2408 | return -EACCES; | ||
2409 | |||
2410 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2411 | mutex_lock(&priv->shrd->mutex); | ||
2412 | |||
2413 | switch (action) { | ||
2414 | case IEEE80211_AMPDU_RX_START: | ||
2415 | IWL_DEBUG_HT(priv, "start Rx\n"); | ||
2416 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | ||
2417 | break; | ||
2418 | case IEEE80211_AMPDU_RX_STOP: | ||
2419 | IWL_DEBUG_HT(priv, "stop Rx\n"); | ||
2420 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | ||
2421 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
2422 | ret = 0; | ||
2423 | break; | ||
2424 | case IEEE80211_AMPDU_TX_START: | ||
2425 | IWL_DEBUG_HT(priv, "start Tx\n"); | ||
2426 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | ||
2427 | break; | ||
2428 | case IEEE80211_AMPDU_TX_STOP: | ||
2429 | IWL_DEBUG_HT(priv, "stop Tx\n"); | ||
2430 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | ||
2431 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | ||
2432 | priv->agg_tids_count--; | ||
2433 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2434 | priv->agg_tids_count); | ||
2435 | } | ||
2436 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
2437 | ret = 0; | ||
2438 | if (!priv->agg_tids_count && priv->cfg->ht_params && | ||
2439 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
2440 | /* | ||
2441 | * switch off RTS/CTS if it was previously enabled | ||
2442 | */ | ||
2443 | sta_priv->lq_sta.lq.general_params.flags &= | ||
2444 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
2445 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
2446 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
2447 | } | ||
2448 | break; | ||
2449 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2450 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | ||
2451 | |||
2452 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, iwl_sta_id(sta), | ||
2453 | tid, buf_size); | ||
2454 | |||
2455 | /* | ||
2456 | * If the limit is 0, then it wasn't initialised yet, | ||
2457 | * use the default. We can do that since we take the | ||
2458 | * minimum below, and we don't want to go above our | ||
2459 | * default due to hardware restrictions. | ||
2460 | */ | ||
2461 | if (sta_priv->max_agg_bufsize == 0) | ||
2462 | sta_priv->max_agg_bufsize = | ||
2463 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
2464 | |||
2465 | /* | ||
2466 | * Even though in theory the peer could have different | ||
2467 | * aggregation reorder buffer sizes for different sessions, | ||
2468 | * our ucode doesn't allow for that and has a global limit | ||
2469 | * for each station. Therefore, use the minimum of all the | ||
2470 | * aggregation sessions and our default value. | ||
2471 | */ | ||
2472 | sta_priv->max_agg_bufsize = | ||
2473 | min(sta_priv->max_agg_bufsize, buf_size); | ||
2474 | |||
2475 | if (priv->cfg->ht_params && | ||
2476 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
2477 | /* | ||
2478 | * switch to RTS/CTS if it is the prefer protection | ||
2479 | * method for HT traffic | ||
2480 | */ | ||
2481 | |||
2482 | sta_priv->lq_sta.lq.general_params.flags |= | ||
2483 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
2484 | } | ||
2485 | priv->agg_tids_count++; | ||
2486 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2487 | priv->agg_tids_count); | ||
2488 | |||
2489 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
2490 | sta_priv->max_agg_bufsize; | ||
2491 | |||
2492 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
2493 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
2494 | |||
2495 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
2496 | sta->addr, tid); | ||
2497 | ret = 0; | ||
2498 | break; | ||
2499 | } | ||
2500 | mutex_unlock(&priv->shrd->mutex); | ||
2501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2502 | return ret; | ||
2503 | } | ||
2504 | |||
2505 | static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | ||
2506 | struct ieee80211_vif *vif, | ||
2507 | struct ieee80211_sta *sta) | ||
2508 | { | ||
2509 | struct iwl_priv *priv = hw->priv; | ||
2510 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
2511 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2512 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | ||
2513 | int ret = 0; | ||
2514 | u8 sta_id; | ||
2515 | |||
2516 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
2517 | sta->addr); | ||
2518 | mutex_lock(&priv->shrd->mutex); | ||
2519 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
2520 | sta->addr); | ||
2521 | sta_priv->sta_id = IWL_INVALID_STATION; | ||
2522 | |||
2523 | atomic_set(&sta_priv->pending_frames, 0); | ||
2524 | if (vif->type == NL80211_IFTYPE_AP) | ||
2525 | sta_priv->client = true; | ||
2526 | |||
2527 | ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, | ||
2528 | is_ap, sta, &sta_id); | ||
2529 | if (ret) { | ||
2530 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | ||
2531 | sta->addr, ret); | ||
2532 | /* Should we return success if return code is EEXIST ? */ | ||
2533 | goto out; | ||
2534 | } | ||
2535 | |||
2536 | sta_priv->sta_id = sta_id; | ||
2537 | |||
2538 | /* Initialize rate scaling */ | ||
2539 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | ||
2540 | sta->addr); | ||
2541 | iwl_rs_rate_init(priv, sta, sta_id); | ||
2542 | out: | ||
2543 | mutex_unlock(&priv->shrd->mutex); | ||
2544 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2545 | |||
2546 | return ret; | ||
2547 | } | ||
2548 | |||
2549 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
2550 | struct ieee80211_channel_switch *ch_switch) | ||
2551 | { | ||
2552 | struct iwl_priv *priv = hw->priv; | ||
2553 | const struct iwl_channel_info *ch_info; | ||
2554 | struct ieee80211_conf *conf = &hw->conf; | ||
2555 | struct ieee80211_channel *channel = ch_switch->channel; | ||
2556 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | ||
2557 | /* | ||
2558 | * MULTI-FIXME | ||
2559 | * When we add support for multiple interfaces, we need to | ||
2560 | * revisit this. The channel switch command in the device | ||
2561 | * only affects the BSS context, but what does that really | ||
2562 | * mean? And what if we get a CSA on the second interface? | ||
2563 | * This needs a lot of work. | ||
2564 | */ | ||
2565 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2566 | u16 ch; | ||
2567 | |||
2568 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2569 | |||
2570 | mutex_lock(&priv->shrd->mutex); | ||
2571 | |||
2572 | if (iwl_is_rfkill(priv->shrd)) | ||
2573 | goto out; | ||
2574 | |||
2575 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | ||
2576 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | ||
2577 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | ||
2578 | goto out; | ||
2579 | |||
2580 | if (!iwl_is_associated_ctx(ctx)) | ||
2581 | goto out; | ||
2582 | |||
2583 | if (!priv->cfg->lib->set_channel_switch) | ||
2584 | goto out; | ||
2585 | |||
2586 | ch = channel->hw_value; | ||
2587 | if (le16_to_cpu(ctx->active.channel) == ch) | ||
2588 | goto out; | ||
2589 | |||
2590 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
2591 | if (!is_channel_valid(ch_info)) { | ||
2592 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
2593 | goto out; | ||
2594 | } | ||
2595 | |||
2596 | spin_lock_irq(&priv->shrd->lock); | ||
2597 | |||
2598 | priv->current_ht_config.smps = conf->smps_mode; | ||
2599 | |||
2600 | /* Configure HT40 channels */ | ||
2601 | ctx->ht.enabled = conf_is_ht(conf); | ||
2602 | if (ctx->ht.enabled) { | ||
2603 | if (conf_is_ht40_minus(conf)) { | ||
2604 | ctx->ht.extension_chan_offset = | ||
2605 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
2606 | ctx->ht.is_40mhz = true; | ||
2607 | } else if (conf_is_ht40_plus(conf)) { | ||
2608 | ctx->ht.extension_chan_offset = | ||
2609 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
2610 | ctx->ht.is_40mhz = true; | ||
2611 | } else { | ||
2612 | ctx->ht.extension_chan_offset = | ||
2613 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
2614 | ctx->ht.is_40mhz = false; | ||
2615 | } | ||
2616 | } else | ||
2617 | ctx->ht.is_40mhz = false; | ||
2618 | |||
2619 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
2620 | ctx->staging.flags = 0; | ||
2621 | |||
2622 | iwl_set_rxon_channel(priv, channel, ctx); | ||
2623 | iwl_set_rxon_ht(priv, ht_conf); | ||
2624 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
2625 | |||
2626 | spin_unlock_irq(&priv->shrd->lock); | ||
2627 | |||
2628 | iwl_set_rate(priv); | ||
2629 | /* | ||
2630 | * at this point, staging_rxon has the | ||
2631 | * configuration for channel switch | ||
2632 | */ | ||
2633 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
2634 | priv->switch_channel = cpu_to_le16(ch); | ||
2635 | if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) { | ||
2636 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
2637 | priv->switch_channel = 0; | ||
2638 | ieee80211_chswitch_done(ctx->vif, false); | ||
2639 | } | ||
2640 | |||
2641 | out: | ||
2642 | mutex_unlock(&priv->shrd->mutex); | ||
2643 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2644 | } | ||
2645 | |||
2646 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
2647 | unsigned int changed_flags, | ||
2648 | unsigned int *total_flags, | ||
2649 | u64 multicast) | ||
2650 | { | ||
2651 | struct iwl_priv *priv = hw->priv; | ||
2652 | __le32 filter_or = 0, filter_nand = 0; | ||
2653 | struct iwl_rxon_context *ctx; | ||
2654 | |||
2655 | #define CHK(test, flag) do { \ | ||
2656 | if (*total_flags & (test)) \ | ||
2657 | filter_or |= (flag); \ | ||
2658 | else \ | ||
2659 | filter_nand |= (flag); \ | ||
2660 | } while (0) | ||
2661 | |||
2662 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
2663 | changed_flags, *total_flags); | ||
2664 | 1457 | ||
2665 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
2666 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | ||
2667 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | ||
2668 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
2669 | 1458 | ||
2670 | #undef CHK | ||
2671 | |||
2672 | mutex_lock(&priv->shrd->mutex); | ||
2673 | |||
2674 | for_each_context(priv, ctx) { | ||
2675 | ctx->staging.filter_flags &= ~filter_nand; | ||
2676 | ctx->staging.filter_flags |= filter_or; | ||
2677 | |||
2678 | /* | ||
2679 | * Not committing directly because hardware can perform a scan, | ||
2680 | * but we'll eventually commit the filter flags change anyway. | ||
2681 | */ | ||
2682 | } | ||
2683 | |||
2684 | mutex_unlock(&priv->shrd->mutex); | ||
2685 | |||
2686 | /* | ||
2687 | * Receiving all multicast frames is always enabled by the | ||
2688 | * default flags setup in iwl_connection_init_rx_config() | ||
2689 | * since we currently do not support programming multicast | ||
2690 | * filters into the device. | ||
2691 | */ | ||
2692 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
2693 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
2694 | } | ||
2695 | |||
2696 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
2697 | { | ||
2698 | struct iwl_priv *priv = hw->priv; | ||
2699 | |||
2700 | mutex_lock(&priv->shrd->mutex); | ||
2701 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2702 | |||
2703 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
2704 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | ||
2705 | goto done; | ||
2706 | } | ||
2707 | if (iwl_is_rfkill(priv->shrd)) { | ||
2708 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | ||
2709 | goto done; | ||
2710 | } | ||
2711 | |||
2712 | /* | ||
2713 | * mac80211 will not push any more frames for transmit | ||
2714 | * until the flush is completed | ||
2715 | */ | ||
2716 | if (drop) { | ||
2717 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | ||
2718 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | ||
2719 | IWL_ERR(priv, "flush request fail\n"); | ||
2720 | goto done; | ||
2721 | } | ||
2722 | } | ||
2723 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | ||
2724 | iwl_trans_wait_tx_queue_empty(trans(priv)); | ||
2725 | done: | ||
2726 | mutex_unlock(&priv->shrd->mutex); | ||
2727 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2728 | } | ||
2729 | 1459 | ||
2730 | void iwlagn_disable_roc(struct iwl_priv *priv) | 1460 | void iwlagn_disable_roc(struct iwl_priv *priv) |
2731 | { | 1461 | { |
@@ -2759,160 +1489,6 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
2759 | mutex_unlock(&priv->shrd->mutex); | 1489 | mutex_unlock(&priv->shrd->mutex); |
2760 | } | 1490 | } |
2761 | 1491 | ||
2762 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
2763 | struct ieee80211_channel *channel, | ||
2764 | enum nl80211_channel_type channel_type, | ||
2765 | int duration) | ||
2766 | { | ||
2767 | struct iwl_priv *priv = hw->priv; | ||
2768 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
2769 | int err = 0; | ||
2770 | |||
2771 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
2772 | return -EOPNOTSUPP; | ||
2773 | |||
2774 | if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
2775 | return -EOPNOTSUPP; | ||
2776 | |||
2777 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2778 | mutex_lock(&priv->shrd->mutex); | ||
2779 | |||
2780 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
2781 | err = -EBUSY; | ||
2782 | goto out; | ||
2783 | } | ||
2784 | |||
2785 | priv->hw_roc_channel = channel; | ||
2786 | priv->hw_roc_chantype = channel_type; | ||
2787 | priv->hw_roc_duration = duration; | ||
2788 | priv->hw_roc_start_notified = false; | ||
2789 | cancel_delayed_work(&priv->hw_roc_disable_work); | ||
2790 | |||
2791 | if (!ctx->is_active) { | ||
2792 | ctx->is_active = true; | ||
2793 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
2794 | memcpy(ctx->staging.node_addr, | ||
2795 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
2796 | ETH_ALEN); | ||
2797 | memcpy(ctx->staging.bssid_addr, | ||
2798 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
2799 | ETH_ALEN); | ||
2800 | err = iwlagn_commit_rxon(priv, ctx); | ||
2801 | if (err) | ||
2802 | goto out; | ||
2803 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK | | ||
2804 | RXON_FILTER_PROMISC_MSK | | ||
2805 | RXON_FILTER_CTL2HOST_MSK; | ||
2806 | |||
2807 | err = iwlagn_commit_rxon(priv, ctx); | ||
2808 | if (err) { | ||
2809 | iwlagn_disable_roc(priv); | ||
2810 | goto out; | ||
2811 | } | ||
2812 | priv->hw_roc_setup = true; | ||
2813 | } | ||
2814 | |||
2815 | err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band); | ||
2816 | if (err) | ||
2817 | iwlagn_disable_roc(priv); | ||
2818 | |||
2819 | out: | ||
2820 | mutex_unlock(&priv->shrd->mutex); | ||
2821 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2822 | |||
2823 | return err; | ||
2824 | } | ||
2825 | |||
2826 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
2827 | { | ||
2828 | struct iwl_priv *priv = hw->priv; | ||
2829 | |||
2830 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
2831 | return -EOPNOTSUPP; | ||
2832 | |||
2833 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2834 | mutex_lock(&priv->shrd->mutex); | ||
2835 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | ||
2836 | iwlagn_disable_roc(priv); | ||
2837 | mutex_unlock(&priv->shrd->mutex); | ||
2838 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2839 | |||
2840 | return 0; | ||
2841 | } | ||
2842 | |||
2843 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
2844 | struct ieee80211_vif *vif, | ||
2845 | const u8 *bssid, | ||
2846 | enum ieee80211_tx_sync_type type) | ||
2847 | { | ||
2848 | struct iwl_priv *priv = hw->priv; | ||
2849 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2850 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2851 | int ret; | ||
2852 | u8 sta_id; | ||
2853 | |||
2854 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2855 | mutex_lock(&priv->shrd->mutex); | ||
2856 | |||
2857 | if (iwl_is_associated_ctx(ctx)) { | ||
2858 | ret = 0; | ||
2859 | goto out; | ||
2860 | } | ||
2861 | |||
2862 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
2863 | ret = -EBUSY; | ||
2864 | goto out; | ||
2865 | } | ||
2866 | |||
2867 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
2868 | if (ret) | ||
2869 | goto out; | ||
2870 | |||
2871 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
2872 | ret = -EIO; | ||
2873 | goto out_remove_sta; | ||
2874 | } | ||
2875 | |||
2876 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
2877 | ctx->preauth_bssid = true; | ||
2878 | |||
2879 | ret = iwlagn_commit_rxon(priv, ctx); | ||
2880 | |||
2881 | if (ret == 0) | ||
2882 | goto out; | ||
2883 | |||
2884 | out_remove_sta: | ||
2885 | iwl_remove_station(priv, sta_id, bssid); | ||
2886 | out: | ||
2887 | mutex_unlock(&priv->shrd->mutex); | ||
2888 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2889 | |||
2890 | return ret; | ||
2891 | } | ||
2892 | |||
2893 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
2894 | struct ieee80211_vif *vif, | ||
2895 | const u8 *bssid, | ||
2896 | enum ieee80211_tx_sync_type type) | ||
2897 | { | ||
2898 | struct iwl_priv *priv = hw->priv; | ||
2899 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2900 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2901 | |||
2902 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2903 | mutex_lock(&priv->shrd->mutex); | ||
2904 | |||
2905 | if (iwl_is_associated_ctx(ctx)) | ||
2906 | goto out; | ||
2907 | |||
2908 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
2909 | ctx->preauth_bssid = false; | ||
2910 | /* no need to commit */ | ||
2911 | out: | ||
2912 | mutex_unlock(&priv->shrd->mutex); | ||
2913 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2914 | } | ||
2915 | |||
2916 | /***************************************************************************** | 1492 | /***************************************************************************** |
2917 | * | 1493 | * |
2918 | * driver setup and teardown | 1494 | * driver setup and teardown |
@@ -3062,81 +1638,13 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
3062 | kmem_cache_destroy(priv->tx_cmd_pool); | 1638 | kmem_cache_destroy(priv->tx_cmd_pool); |
3063 | kfree(priv->scan_cmd); | 1639 | kfree(priv->scan_cmd); |
3064 | kfree(priv->beacon_cmd); | 1640 | kfree(priv->beacon_cmd); |
1641 | kfree(rcu_dereference_raw(priv->noa_data)); | ||
3065 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1642 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
3066 | kfree(priv->wowlan_sram); | 1643 | kfree(priv->wowlan_sram); |
3067 | #endif | 1644 | #endif |
3068 | } | 1645 | } |
3069 | 1646 | ||
3070 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
3071 | enum ieee80211_rssi_event rssi_event) | ||
3072 | { | ||
3073 | struct iwl_priv *priv = hw->priv; | ||
3074 | |||
3075 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
3076 | mutex_lock(&priv->shrd->mutex); | ||
3077 | |||
3078 | if (priv->cfg->bt_params && | ||
3079 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
3080 | if (rssi_event == RSSI_EVENT_LOW) | ||
3081 | priv->bt_enable_pspoll = true; | ||
3082 | else if (rssi_event == RSSI_EVENT_HIGH) | ||
3083 | priv->bt_enable_pspoll = false; | ||
3084 | |||
3085 | iwlagn_send_advance_bt_config(priv); | ||
3086 | } else { | ||
3087 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," | ||
3088 | "ignoring RSSI callback\n"); | ||
3089 | } | ||
3090 | |||
3091 | mutex_unlock(&priv->shrd->mutex); | ||
3092 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
3093 | } | ||
3094 | |||
3095 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
3096 | struct ieee80211_sta *sta, bool set) | ||
3097 | { | ||
3098 | struct iwl_priv *priv = hw->priv; | ||
3099 | |||
3100 | queue_work(priv->shrd->workqueue, &priv->beacon_update); | ||
3101 | 1647 | ||
3102 | return 0; | ||
3103 | } | ||
3104 | |||
3105 | struct ieee80211_ops iwlagn_hw_ops = { | ||
3106 | .tx = iwlagn_mac_tx, | ||
3107 | .start = iwlagn_mac_start, | ||
3108 | .stop = iwlagn_mac_stop, | ||
3109 | #ifdef CONFIG_PM_SLEEP | ||
3110 | .suspend = iwlagn_mac_suspend, | ||
3111 | .resume = iwlagn_mac_resume, | ||
3112 | #endif | ||
3113 | .add_interface = iwlagn_mac_add_interface, | ||
3114 | .remove_interface = iwlagn_mac_remove_interface, | ||
3115 | .change_interface = iwlagn_mac_change_interface, | ||
3116 | .config = iwlagn_mac_config, | ||
3117 | .configure_filter = iwlagn_configure_filter, | ||
3118 | .set_key = iwlagn_mac_set_key, | ||
3119 | .update_tkip_key = iwlagn_mac_update_tkip_key, | ||
3120 | .set_rekey_data = iwlagn_mac_set_rekey_data, | ||
3121 | .conf_tx = iwlagn_mac_conf_tx, | ||
3122 | .bss_info_changed = iwlagn_bss_info_changed, | ||
3123 | .ampdu_action = iwlagn_mac_ampdu_action, | ||
3124 | .hw_scan = iwlagn_mac_hw_scan, | ||
3125 | .sta_notify = iwlagn_mac_sta_notify, | ||
3126 | .sta_add = iwlagn_mac_sta_add, | ||
3127 | .sta_remove = iwlagn_mac_sta_remove, | ||
3128 | .channel_switch = iwlagn_mac_channel_switch, | ||
3129 | .flush = iwlagn_mac_flush, | ||
3130 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | ||
3131 | .remain_on_channel = iwlagn_mac_remain_on_channel, | ||
3132 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, | ||
3133 | .rssi_callback = iwlagn_mac_rssi_callback, | ||
3134 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | ||
3135 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | ||
3136 | .tx_sync = iwlagn_mac_tx_sync, | ||
3137 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
3138 | .set_tim = iwlagn_mac_set_tim, | ||
3139 | }; | ||
3140 | 1648 | ||
3141 | static u32 iwl_hw_detect(struct iwl_priv *priv) | 1649 | static u32 iwl_hw_detect(struct iwl_priv *priv) |
3142 | { | 1650 | { |
@@ -3170,27 +1678,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3170 | return priv->cfg->lib->set_hw_params(priv); | 1678 | return priv->cfg->lib->set_hw_params(priv); |
3171 | } | 1679 | } |
3172 | 1680 | ||
3173 | /* This function both allocates and initializes hw and priv. */ | ||
3174 | static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) | ||
3175 | { | ||
3176 | struct iwl_priv *priv; | ||
3177 | /* mac80211 allocates memory for this device instance, including | ||
3178 | * space for this driver's private structure */ | ||
3179 | struct ieee80211_hw *hw; | ||
3180 | |||
3181 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); | ||
3182 | if (hw == NULL) { | ||
3183 | pr_err("%s: Can not allocate network device\n", | ||
3184 | cfg->name); | ||
3185 | goto out; | ||
3186 | } | ||
3187 | 1681 | ||
3188 | priv = hw->priv; | ||
3189 | priv->hw = hw; | ||
3190 | |||
3191 | out: | ||
3192 | return hw; | ||
3193 | } | ||
3194 | 1682 | ||
3195 | int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | 1683 | int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, |
3196 | struct iwl_cfg *cfg) | 1684 | struct iwl_cfg *cfg) |
@@ -3204,8 +1692,9 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
3204 | /************************ | 1692 | /************************ |
3205 | * 1. Allocating HW data | 1693 | * 1. Allocating HW data |
3206 | ************************/ | 1694 | ************************/ |
3207 | hw = iwl_alloc_all(cfg); | 1695 | hw = iwl_alloc_all(); |
3208 | if (!hw) { | 1696 | if (!hw) { |
1697 | pr_err("%s: Cannot allocate network device\n", cfg->name); | ||
3209 | err = -ENOMEM; | 1698 | err = -ENOMEM; |
3210 | goto out; | 1699 | goto out; |
3211 | } | 1700 | } |
@@ -3397,7 +1886,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) | |||
3397 | /*This will stop the queues, move the device to low power state */ | 1886 | /*This will stop the queues, move the device to low power state */ |
3398 | iwl_trans_stop_device(trans(priv)); | 1887 | iwl_trans_stop_device(trans(priv)); |
3399 | 1888 | ||
3400 | iwl_dealloc_ucode(priv); | 1889 | iwl_dealloc_ucode(trans(priv)); |
3401 | 1890 | ||
3402 | iwl_eeprom_free(priv); | 1891 | iwl_eeprom_free(priv); |
3403 | 1892 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5b936ec1a541..5d8d2f445923 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -65,6 +65,12 @@ | |||
65 | 65 | ||
66 | #include "iwl-dev.h" | 66 | #include "iwl-dev.h" |
67 | 67 | ||
68 | struct iwlagn_ucode_capabilities { | ||
69 | u32 max_probe_length; | ||
70 | u32 standard_phy_calibration_size; | ||
71 | u32 flags; | ||
72 | }; | ||
73 | |||
68 | extern struct ieee80211_ops iwlagn_hw_ops; | 74 | extern struct ieee80211_ops iwlagn_hw_ops; |
69 | 75 | ||
70 | int iwl_reset_ict(struct iwl_trans *trans); | 76 | int iwl_reset_ict(struct iwl_trans *trans); |
@@ -77,6 +83,15 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) | |||
77 | hdr->data_valid = 1; | 83 | hdr->data_valid = 1; |
78 | } | 84 | } |
79 | 85 | ||
86 | void __iwl_down(struct iwl_priv *priv); | ||
87 | void iwl_down(struct iwl_priv *priv); | ||
88 | void iwlagn_prepare_restart(struct iwl_priv *priv); | ||
89 | |||
90 | /* MAC80211 */ | ||
91 | struct ieee80211_hw *iwl_alloc_all(void); | ||
92 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
93 | struct iwlagn_ucode_capabilities *capa); | ||
94 | |||
80 | /* RXON */ | 95 | /* RXON */ |
81 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 96 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
82 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 97 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -95,8 +110,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | |||
95 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); | 110 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); |
96 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | 111 | int iwlagn_run_init_ucode(struct iwl_priv *priv); |
97 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 112 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
98 | struct fw_img *image, | 113 | enum iwl_ucode_type ucode_type); |
99 | enum iwlagn_ucode_type ucode_type); | ||
100 | 114 | ||
101 | /* lib */ | 115 | /* lib */ |
102 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 116 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
@@ -105,6 +119,12 @@ u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); | |||
105 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 119 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
106 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 120 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
107 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 121 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
122 | #ifdef CONFIG_PM_SLEEP | ||
123 | int iwlagn_send_patterns(struct iwl_priv *priv, | ||
124 | struct cfg80211_wowlan *wowlan); | ||
125 | int iwlagn_suspend(struct iwl_priv *priv, | ||
126 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
127 | #endif | ||
108 | 128 | ||
109 | /* rx */ | 129 | /* rx */ |
110 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 130 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
@@ -196,9 +216,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
196 | struct ieee80211_sta *sta, u8 *sta_id_r); | 216 | struct ieee80211_sta *sta, u8 *sta_id_r); |
197 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 217 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
198 | const u8 *addr); | 218 | const u8 *addr); |
199 | int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
200 | struct ieee80211_sta *sta); | ||
201 | |||
202 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 219 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
203 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); | 220 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); |
204 | 221 | ||
@@ -316,10 +333,6 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); | |||
316 | int iwl_update_bcast_station(struct iwl_priv *priv, | 333 | int iwl_update_bcast_station(struct iwl_priv *priv, |
317 | struct iwl_rxon_context *ctx); | 334 | struct iwl_rxon_context *ctx); |
318 | int iwl_update_bcast_stations(struct iwl_priv *priv); | 335 | int iwl_update_bcast_stations(struct iwl_priv *priv); |
319 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
320 | struct ieee80211_vif *vif, | ||
321 | enum sta_notify_cmd cmd, | ||
322 | struct ieee80211_sta *sta); | ||
323 | 336 | ||
324 | /* rate */ | 337 | /* rate */ |
325 | static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) | 338 | static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index 2a2dc4597ba1..e1d78257e4a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h | |||
@@ -101,17 +101,11 @@ extern struct iwl_cfg iwl100_bg_cfg; | |||
101 | extern struct iwl_cfg iwl130_bgn_cfg; | 101 | extern struct iwl_cfg iwl130_bgn_cfg; |
102 | extern struct iwl_cfg iwl130_bg_cfg; | 102 | extern struct iwl_cfg iwl130_bg_cfg; |
103 | extern struct iwl_cfg iwl2000_2bgn_cfg; | 103 | extern struct iwl_cfg iwl2000_2bgn_cfg; |
104 | extern struct iwl_cfg iwl2000_2bg_cfg; | ||
105 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; | 104 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; |
106 | extern struct iwl_cfg iwl2030_2bgn_cfg; | 105 | extern struct iwl_cfg iwl2030_2bgn_cfg; |
107 | extern struct iwl_cfg iwl2030_2bg_cfg; | ||
108 | extern struct iwl_cfg iwl6035_2agn_cfg; | 106 | extern struct iwl_cfg iwl6035_2agn_cfg; |
109 | extern struct iwl_cfg iwl6035_2abg_cfg; | ||
110 | extern struct iwl_cfg iwl6035_2bg_cfg; | ||
111 | extern struct iwl_cfg iwl105_bg_cfg; | ||
112 | extern struct iwl_cfg iwl105_bgn_cfg; | 107 | extern struct iwl_cfg iwl105_bgn_cfg; |
113 | extern struct iwl_cfg iwl105_bgn_d_cfg; | 108 | extern struct iwl_cfg iwl105_bgn_d_cfg; |
114 | extern struct iwl_cfg iwl135_bg_cfg; | ||
115 | extern struct iwl_cfg iwl135_bgn_cfg; | 109 | extern struct iwl_cfg iwl135_bgn_cfg; |
116 | 110 | ||
117 | #endif /* __iwl_pci_h__ */ | 111 | #endif /* __iwl_pci_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 69d5f85d11e2..f4eccf583775 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -198,6 +198,7 @@ enum { | |||
198 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, | 198 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, |
199 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, | 199 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, |
200 | REPLY_WOWLAN_GET_STATUS = 0xe5, | 200 | REPLY_WOWLAN_GET_STATUS = 0xe5, |
201 | REPLY_D3_CONFIG = 0xd3, | ||
201 | 202 | ||
202 | REPLY_MAX = 0xff | 203 | REPLY_MAX = 0xff |
203 | }; | 204 | }; |
@@ -3801,6 +3802,19 @@ struct iwl_bt_coex_prot_env_cmd { | |||
3801 | } __attribute__((packed)); | 3802 | } __attribute__((packed)); |
3802 | 3803 | ||
3803 | /* | 3804 | /* |
3805 | * REPLY_D3_CONFIG | ||
3806 | */ | ||
3807 | enum iwlagn_d3_wakeup_filters { | ||
3808 | IWLAGN_D3_WAKEUP_RFKILL = BIT(0), | ||
3809 | IWLAGN_D3_WAKEUP_SYSASSERT = BIT(1), | ||
3810 | }; | ||
3811 | |||
3812 | struct iwlagn_d3_config_cmd { | ||
3813 | __le32 min_sleep_time; | ||
3814 | __le32 wakeup_flags; | ||
3815 | } __packed; | ||
3816 | |||
3817 | /* | ||
3804 | * REPLY_WOWLAN_PATTERNS | 3818 | * REPLY_WOWLAN_PATTERNS |
3805 | */ | 3819 | */ |
3806 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 | 3820 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 |
@@ -3830,19 +3844,16 @@ enum iwlagn_wowlan_wakeup_filters { | |||
3830 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), | 3844 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), |
3831 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), | 3845 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), |
3832 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), | 3846 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), |
3833 | IWLAGN_WOWLAN_WAKEUP_RFKILL = BIT(5), | 3847 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5), |
3834 | IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR = BIT(6), | 3848 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6), |
3835 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(7), | 3849 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(7), |
3836 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(8), | 3850 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(8), |
3837 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(9), | ||
3838 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(10), | ||
3839 | }; | 3851 | }; |
3840 | 3852 | ||
3841 | struct iwlagn_wowlan_wakeup_filter_cmd { | 3853 | struct iwlagn_wowlan_wakeup_filter_cmd { |
3842 | __le32 enabled; | 3854 | __le32 enabled; |
3843 | __le16 non_qos_seq; | 3855 | __le16 non_qos_seq; |
3844 | u8 min_sleep_seconds; | 3856 | __le16 reserved; |
3845 | u8 reserved; | ||
3846 | __le16 qos_seq[8]; | 3857 | __le16 qos_seq[8]; |
3847 | }; | 3858 | }; |
3848 | 3859 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 001fdf140abb..f9e9170e977a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1120,229 +1120,8 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
1120 | &statistics_cmd); | 1120 | &statistics_cmd); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
1124 | struct ieee80211_vif *vif, u16 queue, | ||
1125 | const struct ieee80211_tx_queue_params *params) | ||
1126 | { | ||
1127 | struct iwl_priv *priv = hw->priv; | ||
1128 | struct iwl_rxon_context *ctx; | ||
1129 | unsigned long flags; | ||
1130 | int q; | ||
1131 | |||
1132 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1133 | |||
1134 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1135 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
1136 | return -EIO; | ||
1137 | } | ||
1138 | |||
1139 | if (queue >= AC_NUM) { | ||
1140 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | q = AC_NUM - 1 - queue; | ||
1145 | |||
1146 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
1147 | |||
1148 | /* | ||
1149 | * MULTI-FIXME | ||
1150 | * This may need to be done per interface in nl80211/cfg80211/mac80211. | ||
1151 | */ | ||
1152 | for_each_context(priv, ctx) { | ||
1153 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | ||
1154 | cpu_to_le16(params->cw_min); | ||
1155 | ctx->qos_data.def_qos_parm.ac[q].cw_max = | ||
1156 | cpu_to_le16(params->cw_max); | ||
1157 | ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
1158 | ctx->qos_data.def_qos_parm.ac[q].edca_txop = | ||
1159 | cpu_to_le16((params->txop * 32)); | ||
1160 | |||
1161 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
1162 | } | ||
1163 | |||
1164 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
1165 | |||
1166 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | ||
1171 | { | ||
1172 | struct iwl_priv *priv = hw->priv; | ||
1173 | |||
1174 | return priv->ibss_manager == IWL_IBSS_MANAGER; | ||
1175 | } | ||
1176 | |||
1177 | static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
1178 | { | ||
1179 | iwl_connection_init_rx_config(priv, ctx); | ||
1180 | |||
1181 | iwlagn_set_rxon_chain(priv, ctx); | ||
1182 | |||
1183 | return iwlagn_commit_rxon(priv, ctx); | ||
1184 | } | ||
1185 | |||
1186 | static int iwl_setup_interface(struct iwl_priv *priv, | ||
1187 | struct iwl_rxon_context *ctx) | ||
1188 | { | ||
1189 | struct ieee80211_vif *vif = ctx->vif; | ||
1190 | int err; | ||
1191 | |||
1192 | lockdep_assert_held(&priv->shrd->mutex); | ||
1193 | |||
1194 | /* | ||
1195 | * This variable will be correct only when there's just | ||
1196 | * a single context, but all code using it is for hardware | ||
1197 | * that supports only one context. | ||
1198 | */ | ||
1199 | priv->iw_mode = vif->type; | ||
1200 | |||
1201 | ctx->is_active = true; | ||
1202 | |||
1203 | err = iwl_set_mode(priv, ctx); | ||
1204 | if (err) { | ||
1205 | if (!ctx->always_active) | ||
1206 | ctx->is_active = false; | ||
1207 | return err; | ||
1208 | } | ||
1209 | |||
1210 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && | ||
1211 | vif->type == NL80211_IFTYPE_ADHOC) { | ||
1212 | /* | ||
1213 | * pretend to have high BT traffic as long as we | ||
1214 | * are operating in IBSS mode, as this will cause | ||
1215 | * the rate scaling etc. to behave as intended. | ||
1216 | */ | ||
1217 | priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; | ||
1218 | } | ||
1219 | |||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
1224 | struct ieee80211_vif *vif) | ||
1225 | { | ||
1226 | struct iwl_priv *priv = hw->priv; | ||
1227 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1228 | struct iwl_rxon_context *tmp, *ctx = NULL; | ||
1229 | int err; | ||
1230 | enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); | ||
1231 | |||
1232 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | ||
1233 | viftype, vif->addr); | ||
1234 | |||
1235 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
1236 | |||
1237 | mutex_lock(&priv->shrd->mutex); | ||
1238 | |||
1239 | iwlagn_disable_roc(priv); | ||
1240 | |||
1241 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1242 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | ||
1243 | err = -EINVAL; | ||
1244 | goto out; | ||
1245 | } | ||
1246 | |||
1247 | for_each_context(priv, tmp) { | ||
1248 | u32 possible_modes = | ||
1249 | tmp->interface_modes | tmp->exclusive_interface_modes; | ||
1250 | |||
1251 | if (tmp->vif) { | ||
1252 | /* check if this busy context is exclusive */ | ||
1253 | if (tmp->exclusive_interface_modes & | ||
1254 | BIT(tmp->vif->type)) { | ||
1255 | err = -EINVAL; | ||
1256 | goto out; | ||
1257 | } | ||
1258 | continue; | ||
1259 | } | ||
1260 | |||
1261 | if (!(possible_modes & BIT(viftype))) | ||
1262 | continue; | ||
1263 | 1123 | ||
1264 | /* have maybe usable context w/o interface */ | ||
1265 | ctx = tmp; | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | if (!ctx) { | ||
1270 | err = -EOPNOTSUPP; | ||
1271 | goto out; | ||
1272 | } | ||
1273 | |||
1274 | vif_priv->ctx = ctx; | ||
1275 | ctx->vif = vif; | ||
1276 | |||
1277 | err = iwl_setup_interface(priv, ctx); | ||
1278 | if (!err) | ||
1279 | goto out; | ||
1280 | 1124 | ||
1281 | ctx->vif = NULL; | ||
1282 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
1283 | out: | ||
1284 | mutex_unlock(&priv->shrd->mutex); | ||
1285 | |||
1286 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1287 | return err; | ||
1288 | } | ||
1289 | |||
1290 | static void iwl_teardown_interface(struct iwl_priv *priv, | ||
1291 | struct ieee80211_vif *vif, | ||
1292 | bool mode_change) | ||
1293 | { | ||
1294 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1295 | |||
1296 | lockdep_assert_held(&priv->shrd->mutex); | ||
1297 | |||
1298 | if (priv->scan_vif == vif) { | ||
1299 | iwl_scan_cancel_timeout(priv, 200); | ||
1300 | iwl_force_scan_end(priv); | ||
1301 | } | ||
1302 | |||
1303 | if (!mode_change) { | ||
1304 | iwl_set_mode(priv, ctx); | ||
1305 | if (!ctx->always_active) | ||
1306 | ctx->is_active = false; | ||
1307 | } | ||
1308 | |||
1309 | /* | ||
1310 | * When removing the IBSS interface, overwrite the | ||
1311 | * BT traffic load with the stored one from the last | ||
1312 | * notification, if any. If this is a device that | ||
1313 | * doesn't implement this, this has no effect since | ||
1314 | * both values are the same and zero. | ||
1315 | */ | ||
1316 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
1317 | priv->bt_traffic_load = priv->last_bt_traffic_load; | ||
1318 | } | ||
1319 | |||
1320 | void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
1321 | struct ieee80211_vif *vif) | ||
1322 | { | ||
1323 | struct iwl_priv *priv = hw->priv; | ||
1324 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1325 | |||
1326 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1327 | |||
1328 | mutex_lock(&priv->shrd->mutex); | ||
1329 | |||
1330 | if (WARN_ON(ctx->vif != vif)) { | ||
1331 | struct iwl_rxon_context *tmp; | ||
1332 | IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif); | ||
1333 | for_each_context(priv, tmp) | ||
1334 | IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n", | ||
1335 | tmp->ctxid, tmp, tmp->vif); | ||
1336 | } | ||
1337 | ctx->vif = NULL; | ||
1338 | |||
1339 | iwl_teardown_interface(priv, vif, false); | ||
1340 | |||
1341 | mutex_unlock(&priv->shrd->mutex); | ||
1342 | |||
1343 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1344 | |||
1345 | } | ||
1346 | 1125 | ||
1347 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1126 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1348 | 1127 | ||
@@ -1649,97 +1428,13 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1649 | return 0; | 1428 | return 0; |
1650 | } | 1429 | } |
1651 | 1430 | ||
1652 | int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
1653 | struct ieee80211_vif *vif, | ||
1654 | enum nl80211_iftype newtype, bool newp2p) | ||
1655 | { | ||
1656 | struct iwl_priv *priv = hw->priv; | ||
1657 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1658 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1659 | struct iwl_rxon_context *tmp; | ||
1660 | enum nl80211_iftype newviftype = newtype; | ||
1661 | u32 interface_modes; | ||
1662 | int err; | ||
1663 | |||
1664 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1665 | |||
1666 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | ||
1667 | |||
1668 | mutex_lock(&priv->shrd->mutex); | ||
1669 | |||
1670 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | ||
1671 | /* | ||
1672 | * Huh? But wait ... this can maybe happen when | ||
1673 | * we're in the middle of a firmware restart! | ||
1674 | */ | ||
1675 | err = -EBUSY; | ||
1676 | goto out; | ||
1677 | } | ||
1678 | |||
1679 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; | ||
1680 | |||
1681 | if (!(interface_modes & BIT(newtype))) { | ||
1682 | err = -EBUSY; | ||
1683 | goto out; | ||
1684 | } | ||
1685 | |||
1686 | /* | ||
1687 | * Refuse a change that should be done by moving from the PAN | ||
1688 | * context to the BSS context instead, if the BSS context is | ||
1689 | * available and can support the new interface type. | ||
1690 | */ | ||
1691 | if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||
1692 | (bss_ctx->interface_modes & BIT(newtype) || | ||
1693 | bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||
1694 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1695 | err = -EBUSY; | ||
1696 | goto out; | ||
1697 | } | ||
1698 | |||
1699 | if (ctx->exclusive_interface_modes & BIT(newtype)) { | ||
1700 | for_each_context(priv, tmp) { | ||
1701 | if (ctx == tmp) | ||
1702 | continue; | ||
1703 | |||
1704 | if (!tmp->vif) | ||
1705 | continue; | ||
1706 | |||
1707 | /* | ||
1708 | * The current mode switch would be exclusive, but | ||
1709 | * another context is active ... refuse the switch. | ||
1710 | */ | ||
1711 | err = -EBUSY; | ||
1712 | goto out; | ||
1713 | } | ||
1714 | } | ||
1715 | |||
1716 | /* success */ | ||
1717 | iwl_teardown_interface(priv, vif, true); | ||
1718 | vif->type = newviftype; | ||
1719 | vif->p2p = newp2p; | ||
1720 | err = iwl_setup_interface(priv, ctx); | ||
1721 | WARN_ON(err); | ||
1722 | /* | ||
1723 | * We've switched internally, but submitting to the | ||
1724 | * device may have failed for some reason. Mask this | ||
1725 | * error, because otherwise mac80211 will not switch | ||
1726 | * (and set the interface type back) and we'll be | ||
1727 | * out of sync with it. | ||
1728 | */ | ||
1729 | err = 0; | ||
1730 | |||
1731 | out: | ||
1732 | mutex_unlock(&priv->shrd->mutex); | ||
1733 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1734 | |||
1735 | return err; | ||
1736 | } | ||
1737 | 1431 | ||
1738 | int iwl_cmd_echo_test(struct iwl_priv *priv) | 1432 | int iwl_cmd_echo_test(struct iwl_priv *priv) |
1739 | { | 1433 | { |
1740 | int ret; | 1434 | int ret; |
1741 | struct iwl_host_cmd cmd = { | 1435 | struct iwl_host_cmd cmd = { |
1742 | .id = REPLY_ECHO, | 1436 | .id = REPLY_ECHO, |
1437 | .len = { 0 }, | ||
1743 | .flags = CMD_SYNC, | 1438 | .flags = CMD_SYNC, |
1744 | }; | 1439 | }; |
1745 | 1440 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 137da3380704..fa47f75185df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -237,10 +237,6 @@ struct iwl_cfg { | |||
237 | * L i b * | 237 | * L i b * |
238 | ***************************/ | 238 | ***************************/ |
239 | 239 | ||
240 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
241 | struct ieee80211_vif *vif, u16 queue, | ||
242 | const struct ieee80211_tx_queue_params *params); | ||
243 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); | ||
244 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 240 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
245 | int hw_decrypt); | 241 | int hw_decrypt); |
246 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 242 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -260,13 +256,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
260 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | 256 | void iwl_connection_init_rx_config(struct iwl_priv *priv, |
261 | struct iwl_rxon_context *ctx); | 257 | struct iwl_rxon_context *ctx); |
262 | void iwl_set_rate(struct iwl_priv *priv); | 258 | void iwl_set_rate(struct iwl_priv *priv); |
263 | int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
264 | struct ieee80211_vif *vif); | ||
265 | void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
266 | struct ieee80211_vif *vif); | ||
267 | int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
268 | struct ieee80211_vif *vif, | ||
269 | enum nl80211_iftype newtype, bool newp2p); | ||
270 | int iwl_cmd_echo_test(struct iwl_priv *priv); | 259 | int iwl_cmd_echo_test(struct iwl_priv *priv); |
271 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 260 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
272 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); | 261 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); |
@@ -323,9 +312,6 @@ void iwl_init_scan_params(struct iwl_priv *priv); | |||
323 | int iwl_scan_cancel(struct iwl_priv *priv); | 312 | int iwl_scan_cancel(struct iwl_priv *priv); |
324 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 313 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
325 | void iwl_force_scan_end(struct iwl_priv *priv); | 314 | void iwl_force_scan_end(struct iwl_priv *priv); |
326 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
327 | struct ieee80211_vif *vif, | ||
328 | struct cfg80211_scan_request *req); | ||
329 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | 315 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
330 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); | 316 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); |
331 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 317 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b9f3267e720c..fbc3095c7b44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -284,8 +284,8 @@ | |||
284 | #define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 | 284 | #define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 |
285 | #define CSR_HW_REV_TYPE_2x30 (0x00000C0) | 285 | #define CSR_HW_REV_TYPE_2x30 (0x00000C0) |
286 | #define CSR_HW_REV_TYPE_2x00 (0x0000100) | 286 | #define CSR_HW_REV_TYPE_2x00 (0x0000100) |
287 | #define CSR_HW_REV_TYPE_200 (0x0000110) | 287 | #define CSR_HW_REV_TYPE_105 (0x0000110) |
288 | #define CSR_HW_REV_TYPE_230 (0x0000120) | 288 | #define CSR_HW_REV_TYPE_135 (0x0000120) |
289 | #define CSR_HW_REV_TYPE_NONE (0x00001F0) | 289 | #define CSR_HW_REV_TYPE_NONE (0x00001F0) |
290 | 290 | ||
291 | /* EEPROM REG */ | 291 | /* EEPROM REG */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 69a77e24d229..40ef97bac1aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -70,10 +70,25 @@ do { \ | |||
70 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ | 70 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ |
71 | } while (0) | 71 | } while (0) |
72 | 72 | ||
73 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ | ||
74 | do { \ | ||
75 | if (!iwl_is_rfkill(p->shrd)) \ | ||
76 | dev_printk(KERN_ERR, bus(p)->dev, "%c %s " fmt, \ | ||
77 | (in_interrupt() ? 'I' : 'U'), __func__ , ##args); \ | ||
78 | else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ | ||
79 | dev_printk(KERN_ERR, bus(p)->dev, "(RFKILL) %c %s " fmt, \ | ||
80 | (in_interrupt() ? 'I' : 'U'), __func__ , ##args); \ | ||
81 | } while (0) | ||
82 | |||
73 | #else | 83 | #else |
74 | #define IWL_DEBUG(m, level, fmt, args...) | 84 | #define IWL_DEBUG(m, level, fmt, args...) |
75 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) | 85 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) |
76 | #define iwl_print_hex_dump(m, level, p, len) | 86 | #define iwl_print_hex_dump(m, level, p, len) |
87 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ | ||
88 | do { \ | ||
89 | if (!iwl_is_rfkill(p->shrd)) \ | ||
90 | IWL_ERR(p, fmt, ##args); \ | ||
91 | } while (0) | ||
77 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 92 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
78 | 93 | ||
79 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 94 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -151,7 +166,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
151 | #define IWL_DL_11H (1 << 28) | 166 | #define IWL_DL_11H (1 << 28) |
152 | #define IWL_DL_STATS (1 << 29) | 167 | #define IWL_DL_STATS (1 << 29) |
153 | #define IWL_DL_TX_REPLY (1 << 30) | 168 | #define IWL_DL_TX_REPLY (1 << 30) |
154 | #define IWL_DL_QOS (1 << 31) | 169 | #define IWL_DL_TX_QUEUES (1 << 31) |
155 | 170 | ||
156 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) | 171 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) |
157 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) | 172 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) |
@@ -188,7 +203,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
188 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) | 203 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) |
189 | #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ | 204 | #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ |
190 | IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) | 205 | IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) |
191 | #define IWL_DEBUG_QOS(p, f, a...) IWL_DEBUG(p, IWL_DL_QOS, f, ## a) | 206 | #define IWL_DEBUG_TX_QUEUES(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a) |
192 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) | 207 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) |
193 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) | 208 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) |
194 | #define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) | 209 | #define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index a1670e3f8bfa..68b04f5b10ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -236,9 +236,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
237 | priv->dbgfs_sram_offset = 0x800000; | 237 | priv->dbgfs_sram_offset = 0x800000; |
238 | if (priv->ucode_type == IWL_UCODE_INIT) | 238 | if (priv->ucode_type == IWL_UCODE_INIT) |
239 | priv->dbgfs_sram_len = priv->ucode_init.data.len; | 239 | priv->dbgfs_sram_len = trans(priv)->ucode_init.data.len; |
240 | else | 240 | else |
241 | priv->dbgfs_sram_len = priv->ucode_rt.data.len; | 241 | priv->dbgfs_sram_len = trans(priv)->ucode_rt.data.len; |
242 | } | 242 | } |
243 | len = priv->dbgfs_sram_len; | 243 | len = priv->dbgfs_sram_len; |
244 | 244 | ||
@@ -341,7 +341,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
341 | 341 | ||
342 | return simple_read_from_buffer(user_buf, count, ppos, | 342 | return simple_read_from_buffer(user_buf, count, ppos, |
343 | priv->wowlan_sram, | 343 | priv->wowlan_sram, |
344 | priv->ucode_wowlan.data.len); | 344 | trans(priv)->ucode_wowlan.data.len); |
345 | } | 345 | } |
346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
347 | size_t count, loff_t *ppos) | 347 | size_t count, loff_t *ppos) |
@@ -430,7 +430,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
430 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 430 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
431 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " | 431 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " |
432 | "version: 0x%x\n", | 432 | "version: 0x%x\n", |
433 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 433 | (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
434 | ? "OTP" : "EEPROM", eeprom_ver); | 434 | ? "OTP" : "EEPROM", eeprom_ver); |
435 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | 435 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { |
436 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | 436 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6c00a447963d..556e4a2c19bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -230,17 +230,6 @@ struct iwl_vif_priv { | |||
230 | u8 ibss_bssid_sta_id; | 230 | u8 ibss_bssid_sta_id; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
234 | struct fw_desc { | ||
235 | void *v_addr; /* access by driver */ | ||
236 | dma_addr_t p_addr; /* access by card's busmaster DMA */ | ||
237 | u32 len; /* bytes */ | ||
238 | }; | ||
239 | |||
240 | struct fw_img { | ||
241 | struct fw_desc code, data; | ||
242 | }; | ||
243 | |||
244 | /* v1/v2 uCode file layout */ | 233 | /* v1/v2 uCode file layout */ |
245 | struct iwl_ucode_header { | 234 | struct iwl_ucode_header { |
246 | __le32 ver; /* major/minor/API/serial */ | 235 | __le32 ver; /* major/minor/API/serial */ |
@@ -805,13 +794,6 @@ enum iwl_scan_type { | |||
805 | IWL_SCAN_ROC, | 794 | IWL_SCAN_ROC, |
806 | }; | 795 | }; |
807 | 796 | ||
808 | enum iwlagn_ucode_type { | ||
809 | IWL_UCODE_NONE, | ||
810 | IWL_UCODE_REGULAR, | ||
811 | IWL_UCODE_INIT, | ||
812 | IWL_UCODE_WOWLAN, | ||
813 | }; | ||
814 | |||
815 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 797 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
816 | struct iwl_testmode_trace { | 798 | struct iwl_testmode_trace { |
817 | u32 buff_size; | 799 | u32 buff_size; |
@@ -824,6 +806,12 @@ struct iwl_testmode_trace { | |||
824 | }; | 806 | }; |
825 | #endif | 807 | #endif |
826 | 808 | ||
809 | struct iwl_wipan_noa_data { | ||
810 | struct rcu_head rcu_head; | ||
811 | u32 length; | ||
812 | u8 data[]; | ||
813 | }; | ||
814 | |||
827 | struct iwl_priv { | 815 | struct iwl_priv { |
828 | 816 | ||
829 | /*data shared among all the driver's layers */ | 817 | /*data shared among all the driver's layers */ |
@@ -883,6 +871,8 @@ struct iwl_priv { | |||
883 | /* init calibration results */ | 871 | /* init calibration results */ |
884 | struct iwl_calib_result calib_results[IWL_CALIB_MAX]; | 872 | struct iwl_calib_result calib_results[IWL_CALIB_MAX]; |
885 | 873 | ||
874 | struct iwl_wipan_noa_data __rcu *noa_data; | ||
875 | |||
886 | /* Scan related variables */ | 876 | /* Scan related variables */ |
887 | unsigned long scan_start; | 877 | unsigned long scan_start; |
888 | unsigned long scan_start_tsf; | 878 | unsigned long scan_start_tsf; |
@@ -907,12 +897,7 @@ struct iwl_priv { | |||
907 | u32 ucode_ver; /* version of ucode, copy of | 897 | u32 ucode_ver; /* version of ucode, copy of |
908 | iwl_ucode.ver */ | 898 | iwl_ucode.ver */ |
909 | 899 | ||
910 | struct fw_img ucode_rt; | 900 | enum iwl_ucode_type ucode_type; |
911 | struct fw_img ucode_init; | ||
912 | struct fw_img ucode_wowlan; | ||
913 | |||
914 | enum iwlagn_ucode_type ucode_type; | ||
915 | u8 ucode_write_complete; /* the image write is complete */ | ||
916 | char firmware_name[25]; | 901 | char firmware_name[25]; |
917 | 902 | ||
918 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; | 903 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; |
@@ -959,7 +944,6 @@ struct iwl_priv { | |||
959 | 944 | ||
960 | /* eeprom -- this is in the card's little endian byte order */ | 945 | /* eeprom -- this is in the card's little endian byte order */ |
961 | u8 *eeprom; | 946 | u8 *eeprom; |
962 | int nvm_device_type; | ||
963 | struct iwl_eeprom_calib_info *calib_info; | 947 | struct iwl_eeprom_calib_info *calib_info; |
964 | 948 | ||
965 | enum nl80211_iftype iw_mode; | 949 | enum nl80211_iftype iw_mode; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index a635a7e75447..2a2c8de64a04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | /* sparse doesn't like tracepoint macros */ | 29 | /* sparse doesn't like tracepoint macros */ |
30 | #ifndef __CHECKER__ | 30 | #ifndef __CHECKER__ |
31 | #include "iwl-dev.h" | 31 | #include "iwl-trans.h" |
32 | 32 | ||
33 | #define CREATE_TRACE_POINTS | 33 | #define CREATE_TRACE_POINTS |
34 | #include "iwl-devtrace.h" | 34 | #include "iwl-devtrace.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 8a51c5ccda1e..f9d3319ecad5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/tracepoint.h> | 30 | #include <linux/tracepoint.h> |
31 | 31 | ||
32 | struct iwl_priv; | ||
33 | 32 | ||
34 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) | 33 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) |
35 | #undef TRACE_EVENT | 34 | #undef TRACE_EVENT |
@@ -37,14 +36,14 @@ struct iwl_priv; | |||
37 | static inline void trace_ ## name(proto) {} | 36 | static inline void trace_ ## name(proto) {} |
38 | #endif | 37 | #endif |
39 | 38 | ||
40 | #define PRIV_ENTRY __field(struct iwl_priv *, priv) | 39 | #define PRIV_ENTRY __field(void *, priv) |
41 | #define PRIV_ASSIGN __entry->priv = priv | 40 | #define PRIV_ASSIGN __entry->priv = priv |
42 | 41 | ||
43 | #undef TRACE_SYSTEM | 42 | #undef TRACE_SYSTEM |
44 | #define TRACE_SYSTEM iwlwifi_io | 43 | #define TRACE_SYSTEM iwlwifi_io |
45 | 44 | ||
46 | TRACE_EVENT(iwlwifi_dev_ioread32, | 45 | TRACE_EVENT(iwlwifi_dev_ioread32, |
47 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 46 | TP_PROTO(void *priv, u32 offs, u32 val), |
48 | TP_ARGS(priv, offs, val), | 47 | TP_ARGS(priv, offs, val), |
49 | TP_STRUCT__entry( | 48 | TP_STRUCT__entry( |
50 | PRIV_ENTRY | 49 | PRIV_ENTRY |
@@ -60,7 +59,7 @@ TRACE_EVENT(iwlwifi_dev_ioread32, | |||
60 | ); | 59 | ); |
61 | 60 | ||
62 | TRACE_EVENT(iwlwifi_dev_iowrite8, | 61 | TRACE_EVENT(iwlwifi_dev_iowrite8, |
63 | TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), | 62 | TP_PROTO(void *priv, u32 offs, u8 val), |
64 | TP_ARGS(priv, offs, val), | 63 | TP_ARGS(priv, offs, val), |
65 | TP_STRUCT__entry( | 64 | TP_STRUCT__entry( |
66 | PRIV_ENTRY | 65 | PRIV_ENTRY |
@@ -76,7 +75,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite8, | |||
76 | ); | 75 | ); |
77 | 76 | ||
78 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 77 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
79 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 78 | TP_PROTO(void *priv, u32 offs, u32 val), |
80 | TP_ARGS(priv, offs, val), | 79 | TP_ARGS(priv, offs, val), |
81 | TP_STRUCT__entry( | 80 | TP_STRUCT__entry( |
82 | PRIV_ENTRY | 81 | PRIV_ENTRY |
@@ -95,7 +94,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, | |||
95 | #define TRACE_SYSTEM iwlwifi_ucode | 94 | #define TRACE_SYSTEM iwlwifi_ucode |
96 | 95 | ||
97 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | 96 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, |
98 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | 97 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), |
99 | TP_ARGS(priv, time, data, ev), | 98 | TP_ARGS(priv, time, data, ev), |
100 | TP_STRUCT__entry( | 99 | TP_STRUCT__entry( |
101 | PRIV_ENTRY | 100 | PRIV_ENTRY |
@@ -115,7 +114,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | |||
115 | ); | 114 | ); |
116 | 115 | ||
117 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | 116 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, |
118 | TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), | 117 | TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), |
119 | TP_ARGS(priv, wraps, n_entry, p_entry), | 118 | TP_ARGS(priv, wraps, n_entry, p_entry), |
120 | TP_STRUCT__entry( | 119 | TP_STRUCT__entry( |
121 | PRIV_ENTRY | 120 | PRIV_ENTRY |
@@ -139,7 +138,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | |||
139 | #define TRACE_SYSTEM iwlwifi | 138 | #define TRACE_SYSTEM iwlwifi |
140 | 139 | ||
141 | TRACE_EVENT(iwlwifi_dev_hcmd, | 140 | TRACE_EVENT(iwlwifi_dev_hcmd, |
142 | TP_PROTO(struct iwl_priv *priv, u32 flags, | 141 | TP_PROTO(void *priv, u32 flags, |
143 | const void *hcmd0, size_t len0, | 142 | const void *hcmd0, size_t len0, |
144 | const void *hcmd1, size_t len1, | 143 | const void *hcmd1, size_t len1, |
145 | const void *hcmd2, size_t len2), | 144 | const void *hcmd2, size_t len2), |
@@ -164,7 +163,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd, | |||
164 | ); | 163 | ); |
165 | 164 | ||
166 | TRACE_EVENT(iwlwifi_dev_rx, | 165 | TRACE_EVENT(iwlwifi_dev_rx, |
167 | TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len), | 166 | TP_PROTO(void *priv, void *rxbuf, size_t len), |
168 | TP_ARGS(priv, rxbuf, len), | 167 | TP_ARGS(priv, rxbuf, len), |
169 | TP_STRUCT__entry( | 168 | TP_STRUCT__entry( |
170 | PRIV_ENTRY | 169 | PRIV_ENTRY |
@@ -179,7 +178,7 @@ TRACE_EVENT(iwlwifi_dev_rx, | |||
179 | ); | 178 | ); |
180 | 179 | ||
181 | TRACE_EVENT(iwlwifi_dev_tx, | 180 | TRACE_EVENT(iwlwifi_dev_tx, |
182 | TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen, | 181 | TP_PROTO(void *priv, void *tfd, size_t tfdlen, |
183 | void *buf0, size_t buf0_len, | 182 | void *buf0, size_t buf0_len, |
184 | void *buf1, size_t buf1_len), | 183 | void *buf1, size_t buf1_len), |
185 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 184 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
@@ -211,7 +210,7 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
211 | ); | 210 | ); |
212 | 211 | ||
213 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 212 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
214 | TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low, | 213 | TP_PROTO(void *priv, u32 desc, u32 tsf_low, |
215 | u32 data1, u32 data2, u32 line, u32 blink1, | 214 | u32 data1, u32 data2, u32 line, u32 blink1, |
216 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, | 215 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
217 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, | 216 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
@@ -271,7 +270,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
271 | ); | 270 | ); |
272 | 271 | ||
273 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 272 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
274 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | 273 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), |
275 | TP_ARGS(priv, time, data, ev), | 274 | TP_ARGS(priv, time, data, ev), |
276 | TP_STRUCT__entry( | 275 | TP_STRUCT__entry( |
277 | PRIV_ENTRY | 276 | PRIV_ENTRY |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index a4e43bd4a547..dcada0827ea4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -149,23 +149,23 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | |||
149 | * EEPROM chip, not a single event, so even reads could conflict if they | 149 | * EEPROM chip, not a single event, so even reads could conflict if they |
150 | * weren't arbitrated by the semaphore. | 150 | * weren't arbitrated by the semaphore. |
151 | */ | 151 | */ |
152 | static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | 152 | static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) |
153 | { | 153 | { |
154 | u16 count; | 154 | u16 count; |
155 | int ret; | 155 | int ret; |
156 | 156 | ||
157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | 157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { |
158 | /* Request semaphore */ | 158 | /* Request semaphore */ |
159 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 159 | iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, |
160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
161 | 161 | ||
162 | /* See if we got it */ | 162 | /* See if we got it */ |
163 | ret = iwl_poll_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 163 | ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, |
164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
166 | EEPROM_SEM_TIMEOUT); | 166 | EEPROM_SEM_TIMEOUT); |
167 | if (ret >= 0) { | 167 | if (ret >= 0) { |
168 | IWL_DEBUG_EEPROM(priv, | 168 | IWL_DEBUG_EEPROM(bus, |
169 | "Acquired semaphore after %d tries.\n", | 169 | "Acquired semaphore after %d tries.\n", |
170 | count+1); | 170 | count+1); |
171 | return ret; | 171 | return ret; |
@@ -175,39 +175,39 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | |||
175 | return ret; | 175 | return ret; |
176 | } | 176 | } |
177 | 177 | ||
178 | static void iwl_eeprom_release_semaphore(struct iwl_priv *priv) | 178 | static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) |
179 | { | 179 | { |
180 | iwl_clear_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 180 | iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, |
181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
182 | 182 | ||
183 | } | 183 | } |
184 | 184 | ||
185 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | 185 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans) |
186 | { | 186 | { |
187 | u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | 187 | u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; |
188 | int ret = 0; | 188 | int ret = 0; |
189 | 189 | ||
190 | IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); | 190 | IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); |
191 | switch (gp) { | 191 | switch (gp) { |
192 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | 192 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: |
193 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { | 193 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_OTP) { |
194 | IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", | 194 | IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", |
195 | gp); | 195 | gp); |
196 | ret = -ENOENT; | 196 | ret = -ENOENT; |
197 | } | 197 | } |
198 | break; | 198 | break; |
199 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | 199 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: |
200 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | 200 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: |
201 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { | 201 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { |
202 | IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); | 202 | IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); |
203 | ret = -ENOENT; | 203 | ret = -ENOENT; |
204 | } | 204 | } |
205 | break; | 205 | break; |
206 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | 206 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: |
207 | default: | 207 | default: |
208 | IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " | 208 | IWL_ERR(trans, "bad EEPROM/OTP signature, type=%s, " |
209 | "EEPROM_GP=0x%08x\n", | 209 | "EEPROM_GP=0x%08x\n", |
210 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 210 | (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
211 | ? "OTP" : "EEPROM", gp); | 211 | ? "OTP" : "EEPROM", gp); |
212 | ret = -ENOENT; | 212 | ret = -ENOENT; |
213 | break; | 213 | break; |
@@ -302,19 +302,19 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) | |||
302 | * | 302 | * |
303 | ******************************************************************************/ | 303 | ******************************************************************************/ |
304 | 304 | ||
305 | static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) | 305 | static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) |
306 | { | 306 | { |
307 | iwl_read32(bus(priv), CSR_OTP_GP_REG); | 307 | iwl_read32(bus, CSR_OTP_GP_REG); |
308 | 308 | ||
309 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | 309 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) |
310 | iwl_clear_bit(bus(priv), CSR_OTP_GP_REG, | 310 | iwl_clear_bit(bus, CSR_OTP_GP_REG, |
311 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 311 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
312 | else | 312 | else |
313 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 313 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
314 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 314 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
315 | } | 315 | } |
316 | 316 | ||
317 | static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | 317 | static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) |
318 | { | 318 | { |
319 | u32 otpgp; | 319 | u32 otpgp; |
320 | int nvm_type; | 320 | int nvm_type; |
@@ -322,7 +322,7 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
322 | /* OTP only valid for CP/PP and after */ | 322 | /* OTP only valid for CP/PP and after */ |
323 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { | 323 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { |
324 | case CSR_HW_REV_TYPE_NONE: | 324 | case CSR_HW_REV_TYPE_NONE: |
325 | IWL_ERR(priv, "Unknown hardware type\n"); | 325 | IWL_ERR(bus, "Unknown hardware type\n"); |
326 | return -ENOENT; | 326 | return -ENOENT; |
327 | case CSR_HW_REV_TYPE_5300: | 327 | case CSR_HW_REV_TYPE_5300: |
328 | case CSR_HW_REV_TYPE_5350: | 328 | case CSR_HW_REV_TYPE_5350: |
@@ -331,7 +331,7 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
331 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | 331 | nvm_type = NVM_DEVICE_TYPE_EEPROM; |
332 | break; | 332 | break; |
333 | default: | 333 | default: |
334 | otpgp = iwl_read32(bus(priv), CSR_OTP_GP_REG); | 334 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); |
335 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | 335 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) |
336 | nvm_type = NVM_DEVICE_TYPE_OTP; | 336 | nvm_type = NVM_DEVICE_TYPE_OTP; |
337 | else | 337 | else |
@@ -341,73 +341,73 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
341 | return nvm_type; | 341 | return nvm_type; |
342 | } | 342 | } |
343 | 343 | ||
344 | static int iwl_init_otp_access(struct iwl_priv *priv) | 344 | static int iwl_init_otp_access(struct iwl_bus *bus) |
345 | { | 345 | { |
346 | int ret; | 346 | int ret; |
347 | 347 | ||
348 | /* Enable 40MHz radio clock */ | 348 | /* Enable 40MHz radio clock */ |
349 | iwl_write32(bus(priv), CSR_GP_CNTRL, | 349 | iwl_write32(bus, CSR_GP_CNTRL, |
350 | iwl_read32(bus(priv), CSR_GP_CNTRL) | | 350 | iwl_read32(bus, CSR_GP_CNTRL) | |
351 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 351 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
352 | 352 | ||
353 | /* wait for clock to be ready */ | 353 | /* wait for clock to be ready */ |
354 | ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, | 354 | ret = iwl_poll_bit(bus, CSR_GP_CNTRL, |
355 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 355 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
356 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 356 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
357 | 25000); | 357 | 25000); |
358 | if (ret < 0) | 358 | if (ret < 0) |
359 | IWL_ERR(priv, "Time out access OTP\n"); | 359 | IWL_ERR(bus, "Time out access OTP\n"); |
360 | else { | 360 | else { |
361 | iwl_set_bits_prph(bus(priv), APMG_PS_CTRL_REG, | 361 | iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, |
362 | APMG_PS_CTRL_VAL_RESET_REQ); | 362 | APMG_PS_CTRL_VAL_RESET_REQ); |
363 | udelay(5); | 363 | udelay(5); |
364 | iwl_clear_bits_prph(bus(priv), APMG_PS_CTRL_REG, | 364 | iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, |
365 | APMG_PS_CTRL_VAL_RESET_REQ); | 365 | APMG_PS_CTRL_VAL_RESET_REQ); |
366 | 366 | ||
367 | /* | 367 | /* |
368 | * CSR auto clock gate disable bit - | 368 | * CSR auto clock gate disable bit - |
369 | * this is only applicable for HW with OTP shadow RAM | 369 | * this is only applicable for HW with OTP shadow RAM |
370 | */ | 370 | */ |
371 | if (priv->cfg->base_params->shadow_ram_support) | 371 | if (priv(bus)->cfg->base_params->shadow_ram_support) |
372 | iwl_set_bit(bus(priv), CSR_DBG_LINK_PWR_MGMT_REG, | 372 | iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, |
373 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | 373 | CSR_RESET_LINK_PWR_MGMT_DISABLED); |
374 | } | 374 | } |
375 | return ret; | 375 | return ret; |
376 | } | 376 | } |
377 | 377 | ||
378 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) | 378 | static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) |
379 | { | 379 | { |
380 | int ret = 0; | 380 | int ret = 0; |
381 | u32 r; | 381 | u32 r; |
382 | u32 otpgp; | 382 | u32 otpgp; |
383 | 383 | ||
384 | iwl_write32(bus(priv), CSR_EEPROM_REG, | 384 | iwl_write32(bus, CSR_EEPROM_REG, |
385 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | 385 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); |
386 | ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, | 386 | ret = iwl_poll_bit(bus, CSR_EEPROM_REG, |
387 | CSR_EEPROM_REG_READ_VALID_MSK, | 387 | CSR_EEPROM_REG_READ_VALID_MSK, |
388 | CSR_EEPROM_REG_READ_VALID_MSK, | 388 | CSR_EEPROM_REG_READ_VALID_MSK, |
389 | IWL_EEPROM_ACCESS_TIMEOUT); | 389 | IWL_EEPROM_ACCESS_TIMEOUT); |
390 | if (ret < 0) { | 390 | if (ret < 0) { |
391 | IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); | 391 | IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); |
392 | return ret; | 392 | return ret; |
393 | } | 393 | } |
394 | r = iwl_read32(bus(priv), CSR_EEPROM_REG); | 394 | r = iwl_read32(bus, CSR_EEPROM_REG); |
395 | /* check for ECC errors: */ | 395 | /* check for ECC errors: */ |
396 | otpgp = iwl_read32(bus(priv), CSR_OTP_GP_REG); | 396 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); |
397 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | 397 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { |
398 | /* stop in this case */ | 398 | /* stop in this case */ |
399 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | 399 | /* set the uncorrectable OTP ECC bit for acknowledgement */ |
400 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 400 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
401 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 401 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
402 | IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n"); | 402 | IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); |
403 | return -EINVAL; | 403 | return -EINVAL; |
404 | } | 404 | } |
405 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | 405 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { |
406 | /* continue in this case */ | 406 | /* continue in this case */ |
407 | /* set the correctable OTP ECC bit for acknowledgement */ | 407 | /* set the correctable OTP ECC bit for acknowledgement */ |
408 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 408 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
409 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 409 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
410 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); | 410 | IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); |
411 | } | 411 | } |
412 | *eeprom_data = cpu_to_le16(r >> 16); | 412 | *eeprom_data = cpu_to_le16(r >> 16); |
413 | return 0; | 413 | return 0; |
@@ -416,20 +416,20 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat | |||
416 | /* | 416 | /* |
417 | * iwl_is_otp_empty: check for empty OTP | 417 | * iwl_is_otp_empty: check for empty OTP |
418 | */ | 418 | */ |
419 | static bool iwl_is_otp_empty(struct iwl_priv *priv) | 419 | static bool iwl_is_otp_empty(struct iwl_bus *bus) |
420 | { | 420 | { |
421 | u16 next_link_addr = 0; | 421 | u16 next_link_addr = 0; |
422 | __le16 link_value; | 422 | __le16 link_value; |
423 | bool is_empty = false; | 423 | bool is_empty = false; |
424 | 424 | ||
425 | /* locate the beginning of OTP link list */ | 425 | /* locate the beginning of OTP link list */ |
426 | if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) { | 426 | if (!iwl_read_otp_word(bus, next_link_addr, &link_value)) { |
427 | if (!link_value) { | 427 | if (!link_value) { |
428 | IWL_ERR(priv, "OTP is empty\n"); | 428 | IWL_ERR(bus, "OTP is empty\n"); |
429 | is_empty = true; | 429 | is_empty = true; |
430 | } | 430 | } |
431 | } else { | 431 | } else { |
432 | IWL_ERR(priv, "Unable to read first block of OTP list.\n"); | 432 | IWL_ERR(bus, "Unable to read first block of OTP list.\n"); |
433 | is_empty = true; | 433 | is_empty = true; |
434 | } | 434 | } |
435 | 435 | ||
@@ -446,7 +446,7 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv) | |||
446 | * we should read and used to configure the device. | 446 | * we should read and used to configure the device. |
447 | * only perform this operation if shadow RAM is disabled | 447 | * only perform this operation if shadow RAM is disabled |
448 | */ | 448 | */ |
449 | static int iwl_find_otp_image(struct iwl_priv *priv, | 449 | static int iwl_find_otp_image(struct iwl_bus *bus, |
450 | u16 *validblockaddr) | 450 | u16 *validblockaddr) |
451 | { | 451 | { |
452 | u16 next_link_addr = 0, valid_addr; | 452 | u16 next_link_addr = 0, valid_addr; |
@@ -454,10 +454,10 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
454 | int usedblocks = 0; | 454 | int usedblocks = 0; |
455 | 455 | ||
456 | /* set addressing mode to absolute to traverse the link list */ | 456 | /* set addressing mode to absolute to traverse the link list */ |
457 | iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE); | 457 | iwl_set_otp_access(bus, IWL_OTP_ACCESS_ABSOLUTE); |
458 | 458 | ||
459 | /* checking for empty OTP or error */ | 459 | /* checking for empty OTP or error */ |
460 | if (iwl_is_otp_empty(priv)) | 460 | if (iwl_is_otp_empty(bus)) |
461 | return -EINVAL; | 461 | return -EINVAL; |
462 | 462 | ||
463 | /* | 463 | /* |
@@ -471,9 +471,9 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
471 | */ | 471 | */ |
472 | valid_addr = next_link_addr; | 472 | valid_addr = next_link_addr; |
473 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | 473 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); |
474 | IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n", | 474 | IWL_DEBUG_EEPROM(bus, "OTP blocks %d addr 0x%x\n", |
475 | usedblocks, next_link_addr); | 475 | usedblocks, next_link_addr); |
476 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) | 476 | if (iwl_read_otp_word(bus, next_link_addr, &link_value)) |
477 | return -EINVAL; | 477 | return -EINVAL; |
478 | if (!link_value) { | 478 | if (!link_value) { |
479 | /* | 479 | /* |
@@ -488,10 +488,10 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
488 | } | 488 | } |
489 | /* more in the link list, continue */ | 489 | /* more in the link list, continue */ |
490 | usedblocks++; | 490 | usedblocks++; |
491 | } while (usedblocks <= priv->cfg->base_params->max_ll_items); | 491 | } while (usedblocks <= priv(bus)->cfg->base_params->max_ll_items); |
492 | 492 | ||
493 | /* OTP has no valid blocks */ | 493 | /* OTP has no valid blocks */ |
494 | IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n"); | 494 | IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); |
495 | return -EINVAL; | 495 | return -EINVAL; |
496 | } | 496 | } |
497 | 497 | ||
@@ -504,28 +504,28 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
504 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | 504 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. |
505 | * find the highest tx power from all chains for the channel | 505 | * find the highest tx power from all chains for the channel |
506 | */ | 506 | */ |
507 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | 507 | static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, |
508 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 508 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
509 | int element, s8 *max_txpower_in_half_dbm) | 509 | int element, s8 *max_txpower_in_half_dbm) |
510 | { | 510 | { |
511 | s8 max_txpower_avg = 0; /* (dBm) */ | 511 | s8 max_txpower_avg = 0; /* (dBm) */ |
512 | 512 | ||
513 | /* Take the highest tx power from any valid chains */ | 513 | /* Take the highest tx power from any valid chains */ |
514 | if ((priv->cfg->valid_tx_ant & ANT_A) && | 514 | if ((cfg->valid_tx_ant & ANT_A) && |
515 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) | 515 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) |
516 | max_txpower_avg = enhanced_txpower[element].chain_a_max; | 516 | max_txpower_avg = enhanced_txpower[element].chain_a_max; |
517 | if ((priv->cfg->valid_tx_ant & ANT_B) && | 517 | if ((cfg->valid_tx_ant & ANT_B) && |
518 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) | 518 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) |
519 | max_txpower_avg = enhanced_txpower[element].chain_b_max; | 519 | max_txpower_avg = enhanced_txpower[element].chain_b_max; |
520 | if ((priv->cfg->valid_tx_ant & ANT_C) && | 520 | if ((cfg->valid_tx_ant & ANT_C) && |
521 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) | 521 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) |
522 | max_txpower_avg = enhanced_txpower[element].chain_c_max; | 522 | max_txpower_avg = enhanced_txpower[element].chain_c_max; |
523 | if (((priv->cfg->valid_tx_ant == ANT_AB) | | 523 | if (((cfg->valid_tx_ant == ANT_AB) | |
524 | (priv->cfg->valid_tx_ant == ANT_BC) | | 524 | (cfg->valid_tx_ant == ANT_BC) | |
525 | (priv->cfg->valid_tx_ant == ANT_AC)) && | 525 | (cfg->valid_tx_ant == ANT_AC)) && |
526 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) | 526 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) |
527 | max_txpower_avg = enhanced_txpower[element].mimo2_max; | 527 | max_txpower_avg = enhanced_txpower[element].mimo2_max; |
528 | if ((priv->cfg->valid_tx_ant == ANT_ABC) && | 528 | if ((cfg->valid_tx_ant == ANT_ABC) && |
529 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) | 529 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) |
530 | max_txpower_avg = enhanced_txpower[element].mimo3_max; | 530 | max_txpower_avg = enhanced_txpower[element].mimo3_max; |
531 | 531 | ||
@@ -627,7 +627,7 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
627 | ((txp->delta_20_in_40 & 0xf0) >> 4), | 627 | ((txp->delta_20_in_40 & 0xf0) >> 4), |
628 | (txp->delta_20_in_40 & 0x0f)); | 628 | (txp->delta_20_in_40 & 0x0f)); |
629 | 629 | ||
630 | max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, | 630 | max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, |
631 | &max_txp_avg_halfdbm); | 631 | &max_txp_avg_halfdbm); |
632 | 632 | ||
633 | /* | 633 | /* |
@@ -660,8 +660,8 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
660 | u16 validblockaddr = 0; | 660 | u16 validblockaddr = 0; |
661 | u16 cache_addr = 0; | 661 | u16 cache_addr = 0; |
662 | 662 | ||
663 | priv->nvm_device_type = iwl_get_nvm_type(priv, hw_rev); | 663 | trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev); |
664 | if (priv->nvm_device_type == -ENOENT) | 664 | if (trans(priv)->nvm_device_type == -ENOENT) |
665 | return -ENOENT; | 665 | return -ENOENT; |
666 | /* allocate eeprom */ | 666 | /* allocate eeprom */ |
667 | sz = priv->cfg->base_params->eeprom_size; | 667 | sz = priv->cfg->base_params->eeprom_size; |
@@ -675,7 +675,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
675 | 675 | ||
676 | iwl_apm_init(priv); | 676 | iwl_apm_init(priv); |
677 | 677 | ||
678 | ret = iwl_eeprom_verify_signature(priv); | 678 | ret = iwl_eeprom_verify_signature(trans(priv)); |
679 | if (ret < 0) { | 679 | if (ret < 0) { |
680 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 680 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
681 | ret = -ENOENT; | 681 | ret = -ENOENT; |
@@ -683,16 +683,16 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
683 | } | 683 | } |
684 | 684 | ||
685 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 685 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
686 | ret = iwl_eeprom_acquire_semaphore(priv); | 686 | ret = iwl_eeprom_acquire_semaphore(bus(priv)); |
687 | if (ret < 0) { | 687 | if (ret < 0) { |
688 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | 688 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
689 | ret = -ENOENT; | 689 | ret = -ENOENT; |
690 | goto err; | 690 | goto err; |
691 | } | 691 | } |
692 | 692 | ||
693 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | 693 | if (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) { |
694 | 694 | ||
695 | ret = iwl_init_otp_access(priv); | 695 | ret = iwl_init_otp_access(bus(priv)); |
696 | if (ret) { | 696 | if (ret) { |
697 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); | 697 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); |
698 | ret = -ENOENT; | 698 | ret = -ENOENT; |
@@ -707,7 +707,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
707 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 707 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
708 | /* traversing the linked list if no shadow ram supported */ | 708 | /* traversing the linked list if no shadow ram supported */ |
709 | if (!priv->cfg->base_params->shadow_ram_support) { | 709 | if (!priv->cfg->base_params->shadow_ram_support) { |
710 | if (iwl_find_otp_image(priv, &validblockaddr)) { | 710 | if (iwl_find_otp_image(bus(priv), &validblockaddr)) { |
711 | ret = -ENOENT; | 711 | ret = -ENOENT; |
712 | goto done; | 712 | goto done; |
713 | } | 713 | } |
@@ -716,7 +716,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
716 | addr += sizeof(u16)) { | 716 | addr += sizeof(u16)) { |
717 | __le16 eeprom_data; | 717 | __le16 eeprom_data; |
718 | 718 | ||
719 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); | 719 | ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data); |
720 | if (ret) | 720 | if (ret) |
721 | goto done; | 721 | goto done; |
722 | e[cache_addr / 2] = eeprom_data; | 722 | e[cache_addr / 2] = eeprom_data; |
@@ -744,13 +744,13 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
744 | } | 744 | } |
745 | 745 | ||
746 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", | 746 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", |
747 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 747 | (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
748 | ? "OTP" : "EEPROM", | 748 | ? "OTP" : "EEPROM", |
749 | iwl_eeprom_query16(priv, EEPROM_VERSION)); | 749 | iwl_eeprom_query16(priv, EEPROM_VERSION)); |
750 | 750 | ||
751 | ret = 0; | 751 | ret = 0; |
752 | done: | 752 | done: |
753 | iwl_eeprom_release_semaphore(priv); | 753 | iwl_eeprom_release_semaphore(bus(priv)); |
754 | 754 | ||
755 | err: | 755 | err: |
756 | if (ret) | 756 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c new file mode 100644 index 000000000000..05b1f0d2f387 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -0,0 +1,1632 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/skbuff.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/firmware.h> | ||
39 | #include <linux/etherdevice.h> | ||
40 | #include <linux/if_arp.h> | ||
41 | |||
42 | #include <net/mac80211.h> | ||
43 | |||
44 | #include <asm/div64.h> | ||
45 | |||
46 | #include "iwl-eeprom.h" | ||
47 | #include "iwl-dev.h" | ||
48 | #include "iwl-core.h" | ||
49 | #include "iwl-io.h" | ||
50 | #include "iwl-agn-calib.h" | ||
51 | #include "iwl-agn.h" | ||
52 | #include "iwl-shared.h" | ||
53 | #include "iwl-bus.h" | ||
54 | #include "iwl-trans.h" | ||
55 | |||
56 | /***************************************************************************** | ||
57 | * | ||
58 | * mac80211 entry point functions | ||
59 | * | ||
60 | *****************************************************************************/ | ||
61 | |||
62 | static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { | ||
63 | { | ||
64 | .max = 1, | ||
65 | .types = BIT(NL80211_IFTYPE_STATION), | ||
66 | }, | ||
67 | { | ||
68 | .max = 1, | ||
69 | .types = BIT(NL80211_IFTYPE_AP), | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { | ||
74 | { | ||
75 | .max = 2, | ||
76 | .types = BIT(NL80211_IFTYPE_STATION), | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { | ||
81 | { | ||
82 | .max = 1, | ||
83 | .types = BIT(NL80211_IFTYPE_STATION), | ||
84 | }, | ||
85 | { | ||
86 | .max = 1, | ||
87 | .types = BIT(NL80211_IFTYPE_P2P_GO) | | ||
88 | BIT(NL80211_IFTYPE_AP), | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { | ||
93 | { | ||
94 | .max = 2, | ||
95 | .types = BIT(NL80211_IFTYPE_STATION), | ||
96 | }, | ||
97 | { | ||
98 | .max = 1, | ||
99 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static const struct ieee80211_iface_combination | ||
104 | iwlagn_iface_combinations_dualmode[] = { | ||
105 | { .num_different_channels = 1, | ||
106 | .max_interfaces = 2, | ||
107 | .beacon_int_infra_match = true, | ||
108 | .limits = iwlagn_sta_ap_limits, | ||
109 | .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), | ||
110 | }, | ||
111 | { .num_different_channels = 1, | ||
112 | .max_interfaces = 2, | ||
113 | .limits = iwlagn_2sta_limits, | ||
114 | .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static const struct ieee80211_iface_combination | ||
119 | iwlagn_iface_combinations_p2p[] = { | ||
120 | { .num_different_channels = 1, | ||
121 | .max_interfaces = 2, | ||
122 | .beacon_int_infra_match = true, | ||
123 | .limits = iwlagn_p2p_sta_go_limits, | ||
124 | .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), | ||
125 | }, | ||
126 | { .num_different_channels = 1, | ||
127 | .max_interfaces = 2, | ||
128 | .limits = iwlagn_p2p_2sta_limits, | ||
129 | .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | /* | ||
134 | * Not a mac80211 entry point function, but it fits in with all the | ||
135 | * other mac80211 functions grouped here. | ||
136 | */ | ||
137 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
138 | struct iwlagn_ucode_capabilities *capa) | ||
139 | { | ||
140 | int ret; | ||
141 | struct ieee80211_hw *hw = priv->hw; | ||
142 | struct iwl_rxon_context *ctx; | ||
143 | |||
144 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
145 | |||
146 | /* Tell mac80211 our characteristics */ | ||
147 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
148 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
149 | IEEE80211_HW_NEED_DTIM_PERIOD | | ||
150 | IEEE80211_HW_SPECTRUM_MGMT | | ||
151 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
152 | |||
153 | /* | ||
154 | * Including the following line will crash some AP's. This | ||
155 | * workaround removes the stimulus which causes the crash until | ||
156 | * the AP software can be fixed. | ||
157 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
158 | */ | ||
159 | |||
160 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
161 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
162 | |||
163 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
164 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
165 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
166 | |||
167 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | ||
168 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
169 | |||
170 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
171 | hw->vif_data_size = sizeof(struct iwl_vif_priv); | ||
172 | |||
173 | for_each_context(priv, ctx) { | ||
174 | hw->wiphy->interface_modes |= ctx->interface_modes; | ||
175 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | ||
176 | } | ||
177 | |||
178 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
179 | |||
180 | if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { | ||
181 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; | ||
182 | hw->wiphy->n_iface_combinations = | ||
183 | ARRAY_SIZE(iwlagn_iface_combinations_p2p); | ||
184 | } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | ||
185 | hw->wiphy->iface_combinations = | ||
186 | iwlagn_iface_combinations_dualmode; | ||
187 | hw->wiphy->n_iface_combinations = | ||
188 | ARRAY_SIZE(iwlagn_iface_combinations_dualmode); | ||
189 | } | ||
190 | |||
191 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
192 | |||
193 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | ||
194 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | ||
195 | WIPHY_FLAG_IBSS_RSN; | ||
196 | |||
197 | if (trans(priv)->ucode_wowlan.code.len && | ||
198 | device_can_wakeup(bus(priv)->dev)) { | ||
199 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | ||
200 | WIPHY_WOWLAN_DISCONNECT | | ||
201 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | | ||
202 | WIPHY_WOWLAN_RFKILL_RELEASE; | ||
203 | if (!iwlagn_mod_params.sw_crypto) | ||
204 | hw->wiphy->wowlan.flags |= | ||
205 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | | ||
206 | WIPHY_WOWLAN_GTK_REKEY_FAILURE; | ||
207 | |||
208 | hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; | ||
209 | hw->wiphy->wowlan.pattern_min_len = | ||
210 | IWLAGN_WOWLAN_MIN_PATTERN_LEN; | ||
211 | hw->wiphy->wowlan.pattern_max_len = | ||
212 | IWLAGN_WOWLAN_MAX_PATTERN_LEN; | ||
213 | } | ||
214 | |||
215 | if (iwlagn_mod_params.power_save) | ||
216 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
217 | else | ||
218 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
219 | |||
220 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
221 | /* we create the 802.11 header and a zero-length SSID element */ | ||
222 | hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; | ||
223 | |||
224 | /* Default value; 4 EDCA QOS priorities */ | ||
225 | hw->queues = 4; | ||
226 | |||
227 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
228 | |||
229 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
230 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
231 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
232 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
233 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
234 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
235 | |||
236 | iwl_leds_init(priv); | ||
237 | |||
238 | ret = ieee80211_register_hw(priv->hw); | ||
239 | if (ret) { | ||
240 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
241 | return ret; | ||
242 | } | ||
243 | priv->mac80211_registered = 1; | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int __iwl_up(struct iwl_priv *priv) | ||
249 | { | ||
250 | struct iwl_rxon_context *ctx; | ||
251 | int ret; | ||
252 | |||
253 | lockdep_assert_held(&priv->shrd->mutex); | ||
254 | |||
255 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
256 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | ||
257 | return -EIO; | ||
258 | } | ||
259 | |||
260 | for_each_context(priv, ctx) { | ||
261 | ret = iwlagn_alloc_bcast_station(priv, ctx); | ||
262 | if (ret) { | ||
263 | iwl_dealloc_bcast_stations(priv); | ||
264 | return ret; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | ret = iwlagn_run_init_ucode(priv); | ||
269 | if (ret) { | ||
270 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | ||
271 | goto error; | ||
272 | } | ||
273 | |||
274 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); | ||
275 | if (ret) { | ||
276 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||
277 | goto error; | ||
278 | } | ||
279 | |||
280 | ret = iwl_alive_start(priv); | ||
281 | if (ret) | ||
282 | goto error; | ||
283 | return 0; | ||
284 | |||
285 | error: | ||
286 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
287 | __iwl_down(priv); | ||
288 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
289 | |||
290 | IWL_ERR(priv, "Unable to initialize device.\n"); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | static int iwlagn_mac_start(struct ieee80211_hw *hw) | ||
295 | { | ||
296 | struct iwl_priv *priv = hw->priv; | ||
297 | int ret; | ||
298 | |||
299 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
300 | |||
301 | /* we should be verifying the device is ready to be opened */ | ||
302 | mutex_lock(&priv->shrd->mutex); | ||
303 | ret = __iwl_up(priv); | ||
304 | mutex_unlock(&priv->shrd->mutex); | ||
305 | if (ret) | ||
306 | return ret; | ||
307 | |||
308 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | ||
309 | |||
310 | /* Now we should be done, and the READY bit should be set. */ | ||
311 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | ||
312 | ret = -EIO; | ||
313 | |||
314 | iwlagn_led_enable(priv); | ||
315 | |||
316 | priv->is_open = 1; | ||
317 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) | ||
322 | { | ||
323 | struct iwl_priv *priv = hw->priv; | ||
324 | |||
325 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
326 | |||
327 | if (!priv->is_open) | ||
328 | return; | ||
329 | |||
330 | priv->is_open = 0; | ||
331 | |||
332 | iwl_down(priv); | ||
333 | |||
334 | flush_workqueue(priv->shrd->workqueue); | ||
335 | |||
336 | /* User space software may expect getting rfkill changes | ||
337 | * even if interface is down */ | ||
338 | iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); | ||
339 | iwl_enable_rfkill_int(priv); | ||
340 | |||
341 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
342 | } | ||
343 | |||
344 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
345 | struct ieee80211_vif *vif, | ||
346 | struct cfg80211_gtk_rekey_data *data) | ||
347 | { | ||
348 | struct iwl_priv *priv = hw->priv; | ||
349 | |||
350 | if (iwlagn_mod_params.sw_crypto) | ||
351 | return; | ||
352 | |||
353 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
354 | mutex_lock(&priv->shrd->mutex); | ||
355 | |||
356 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | ||
357 | goto out; | ||
358 | |||
359 | memcpy(priv->kek, data->kek, NL80211_KEK_LEN); | ||
360 | memcpy(priv->kck, data->kck, NL80211_KCK_LEN); | ||
361 | priv->replay_ctr = | ||
362 | cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr)); | ||
363 | priv->have_rekey_data = true; | ||
364 | |||
365 | out: | ||
366 | mutex_unlock(&priv->shrd->mutex); | ||
367 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
368 | } | ||
369 | |||
370 | #ifdef CONFIG_PM_SLEEP | ||
371 | |||
372 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | ||
373 | struct cfg80211_wowlan *wowlan) | ||
374 | { | ||
375 | struct iwl_priv *priv = hw->priv; | ||
376 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
377 | int ret; | ||
378 | |||
379 | if (WARN_ON(!wowlan)) | ||
380 | return -EINVAL; | ||
381 | |||
382 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
383 | mutex_lock(&priv->shrd->mutex); | ||
384 | |||
385 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | ||
386 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | ||
387 | !iwl_is_associated_ctx(ctx)) { | ||
388 | ret = 1; | ||
389 | goto out; | ||
390 | } | ||
391 | |||
392 | ret = iwlagn_suspend(priv, hw, wowlan); | ||
393 | if (ret) | ||
394 | goto error; | ||
395 | |||
396 | device_set_wakeup_enable(bus(priv)->dev, true); | ||
397 | |||
398 | /* Now let the ucode operate on its own */ | ||
399 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | ||
400 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
401 | |||
402 | goto out; | ||
403 | |||
404 | error: | ||
405 | priv->shrd->wowlan = false; | ||
406 | iwlagn_prepare_restart(priv); | ||
407 | ieee80211_restart_hw(priv->hw); | ||
408 | out: | ||
409 | mutex_unlock(&priv->shrd->mutex); | ||
410 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
411 | |||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | static int iwlagn_mac_resume(struct ieee80211_hw *hw) | ||
416 | { | ||
417 | struct iwl_priv *priv = hw->priv; | ||
418 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
419 | struct ieee80211_vif *vif; | ||
420 | unsigned long flags; | ||
421 | u32 base, status = 0xffffffff; | ||
422 | int ret = -EIO; | ||
423 | |||
424 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
425 | mutex_lock(&priv->shrd->mutex); | ||
426 | |||
427 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | ||
428 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
429 | |||
430 | base = priv->device_pointers.error_event_table; | ||
431 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | ||
432 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | ||
433 | ret = iwl_grab_nic_access_silent(bus(priv)); | ||
434 | if (ret == 0) { | ||
435 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); | ||
436 | status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | ||
437 | iwl_release_nic_access(bus(priv)); | ||
438 | } | ||
439 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | ||
440 | |||
441 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
442 | if (ret == 0) { | ||
443 | struct iwl_trans *trans = trans(priv); | ||
444 | if (!priv->wowlan_sram) | ||
445 | priv->wowlan_sram = | ||
446 | kzalloc(trans->ucode_wowlan.data.len, | ||
447 | GFP_KERNEL); | ||
448 | |||
449 | if (priv->wowlan_sram) | ||
450 | _iwl_read_targ_mem_words( | ||
451 | bus(priv), 0x800000, priv->wowlan_sram, | ||
452 | trans->ucode_wowlan.data.len / 4); | ||
453 | } | ||
454 | #endif | ||
455 | } | ||
456 | |||
457 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | ||
458 | vif = ctx->vif; | ||
459 | |||
460 | priv->shrd->wowlan = false; | ||
461 | |||
462 | device_set_wakeup_enable(bus(priv)->dev, false); | ||
463 | |||
464 | iwlagn_prepare_restart(priv); | ||
465 | |||
466 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); | ||
467 | iwl_connection_init_rx_config(priv, ctx); | ||
468 | iwlagn_set_rxon_chain(priv, ctx); | ||
469 | |||
470 | mutex_unlock(&priv->shrd->mutex); | ||
471 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
472 | |||
473 | ieee80211_resume_disconnect(vif); | ||
474 | |||
475 | return 1; | ||
476 | } | ||
477 | |||
478 | #endif | ||
479 | |||
480 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
481 | { | ||
482 | struct iwl_priv *priv = hw->priv; | ||
483 | |||
484 | IWL_DEBUG_MACDUMP(priv, "enter\n"); | ||
485 | |||
486 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
487 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
488 | |||
489 | if (iwlagn_tx_skb(priv, skb)) | ||
490 | dev_kfree_skb_any(skb); | ||
491 | |||
492 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | ||
493 | } | ||
494 | |||
495 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
496 | struct ieee80211_vif *vif, | ||
497 | struct ieee80211_key_conf *keyconf, | ||
498 | struct ieee80211_sta *sta, | ||
499 | u32 iv32, u16 *phase1key) | ||
500 | { | ||
501 | struct iwl_priv *priv = hw->priv; | ||
502 | |||
503 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | ||
504 | } | ||
505 | |||
506 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
507 | struct ieee80211_vif *vif, | ||
508 | struct ieee80211_sta *sta, | ||
509 | struct ieee80211_key_conf *key) | ||
510 | { | ||
511 | struct iwl_priv *priv = hw->priv; | ||
512 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
513 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
514 | int ret; | ||
515 | bool is_default_wep_key = false; | ||
516 | |||
517 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
518 | |||
519 | if (iwlagn_mod_params.sw_crypto) { | ||
520 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | ||
521 | return -EOPNOTSUPP; | ||
522 | } | ||
523 | |||
524 | /* | ||
525 | * We could program these keys into the hardware as well, but we | ||
526 | * don't expect much multicast traffic in IBSS and having keys | ||
527 | * for more stations is probably more useful. | ||
528 | * | ||
529 | * Mark key TX-only and return 0. | ||
530 | */ | ||
531 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
532 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
533 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | /* If they key was TX-only, accept deletion */ | ||
538 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | ||
539 | return 0; | ||
540 | |||
541 | mutex_lock(&priv->shrd->mutex); | ||
542 | iwl_scan_cancel_timeout(priv, 100); | ||
543 | |||
544 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | ||
545 | |||
546 | /* | ||
547 | * If we are getting WEP group key and we didn't receive any key mapping | ||
548 | * so far, we are in legacy wep mode (group key only), otherwise we are | ||
549 | * in 1X mode. | ||
550 | * In legacy wep mode, we use another host command to the uCode. | ||
551 | */ | ||
552 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
553 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { | ||
554 | if (cmd == SET_KEY) | ||
555 | is_default_wep_key = !ctx->key_mapping_keys; | ||
556 | else | ||
557 | is_default_wep_key = | ||
558 | key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT; | ||
559 | } | ||
560 | |||
561 | |||
562 | switch (cmd) { | ||
563 | case SET_KEY: | ||
564 | if (is_default_wep_key) { | ||
565 | ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); | ||
566 | break; | ||
567 | } | ||
568 | ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta); | ||
569 | if (ret) { | ||
570 | /* | ||
571 | * can't add key for RX, but we don't need it | ||
572 | * in the device for TX so still return 0 | ||
573 | */ | ||
574 | ret = 0; | ||
575 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
576 | } | ||
577 | |||
578 | IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); | ||
579 | break; | ||
580 | case DISABLE_KEY: | ||
581 | if (is_default_wep_key) | ||
582 | ret = iwl_remove_default_wep_key(priv, ctx, key); | ||
583 | else | ||
584 | ret = iwl_remove_dynamic_key(priv, ctx, key, sta); | ||
585 | |||
586 | IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); | ||
587 | break; | ||
588 | default: | ||
589 | ret = -EINVAL; | ||
590 | } | ||
591 | |||
592 | mutex_unlock(&priv->shrd->mutex); | ||
593 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
594 | |||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
599 | struct ieee80211_vif *vif, | ||
600 | enum ieee80211_ampdu_mlme_action action, | ||
601 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
602 | u8 buf_size) | ||
603 | { | ||
604 | struct iwl_priv *priv = hw->priv; | ||
605 | int ret = -EINVAL; | ||
606 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
607 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
608 | |||
609 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | ||
610 | sta->addr, tid); | ||
611 | |||
612 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) | ||
613 | return -EACCES; | ||
614 | |||
615 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
616 | mutex_lock(&priv->shrd->mutex); | ||
617 | |||
618 | switch (action) { | ||
619 | case IEEE80211_AMPDU_RX_START: | ||
620 | IWL_DEBUG_HT(priv, "start Rx\n"); | ||
621 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | ||
622 | break; | ||
623 | case IEEE80211_AMPDU_RX_STOP: | ||
624 | IWL_DEBUG_HT(priv, "stop Rx\n"); | ||
625 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | ||
626 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
627 | ret = 0; | ||
628 | break; | ||
629 | case IEEE80211_AMPDU_TX_START: | ||
630 | IWL_DEBUG_HT(priv, "start Tx\n"); | ||
631 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | ||
632 | break; | ||
633 | case IEEE80211_AMPDU_TX_STOP: | ||
634 | IWL_DEBUG_HT(priv, "stop Tx\n"); | ||
635 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | ||
636 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | ||
637 | priv->agg_tids_count--; | ||
638 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
639 | priv->agg_tids_count); | ||
640 | } | ||
641 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
642 | ret = 0; | ||
643 | if (!priv->agg_tids_count && priv->cfg->ht_params && | ||
644 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
645 | /* | ||
646 | * switch off RTS/CTS if it was previously enabled | ||
647 | */ | ||
648 | sta_priv->lq_sta.lq.general_params.flags &= | ||
649 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
650 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
651 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
652 | } | ||
653 | break; | ||
654 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
655 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | ||
656 | |||
657 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, iwl_sta_id(sta), | ||
658 | tid, buf_size); | ||
659 | |||
660 | /* | ||
661 | * If the limit is 0, then it wasn't initialised yet, | ||
662 | * use the default. We can do that since we take the | ||
663 | * minimum below, and we don't want to go above our | ||
664 | * default due to hardware restrictions. | ||
665 | */ | ||
666 | if (sta_priv->max_agg_bufsize == 0) | ||
667 | sta_priv->max_agg_bufsize = | ||
668 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
669 | |||
670 | /* | ||
671 | * Even though in theory the peer could have different | ||
672 | * aggregation reorder buffer sizes for different sessions, | ||
673 | * our ucode doesn't allow for that and has a global limit | ||
674 | * for each station. Therefore, use the minimum of all the | ||
675 | * aggregation sessions and our default value. | ||
676 | */ | ||
677 | sta_priv->max_agg_bufsize = | ||
678 | min(sta_priv->max_agg_bufsize, buf_size); | ||
679 | |||
680 | if (priv->cfg->ht_params && | ||
681 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
682 | /* | ||
683 | * switch to RTS/CTS if it is the prefer protection | ||
684 | * method for HT traffic | ||
685 | */ | ||
686 | |||
687 | sta_priv->lq_sta.lq.general_params.flags |= | ||
688 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
689 | } | ||
690 | priv->agg_tids_count++; | ||
691 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
692 | priv->agg_tids_count); | ||
693 | |||
694 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
695 | sta_priv->max_agg_bufsize; | ||
696 | |||
697 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
698 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
699 | |||
700 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
701 | sta->addr, tid); | ||
702 | ret = 0; | ||
703 | break; | ||
704 | } | ||
705 | mutex_unlock(&priv->shrd->mutex); | ||
706 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
707 | return ret; | ||
708 | } | ||
709 | |||
710 | static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | ||
711 | struct ieee80211_vif *vif, | ||
712 | struct ieee80211_sta *sta) | ||
713 | { | ||
714 | struct iwl_priv *priv = hw->priv; | ||
715 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
716 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
717 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | ||
718 | int ret = 0; | ||
719 | u8 sta_id; | ||
720 | |||
721 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
722 | sta->addr); | ||
723 | mutex_lock(&priv->shrd->mutex); | ||
724 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
725 | sta->addr); | ||
726 | sta_priv->sta_id = IWL_INVALID_STATION; | ||
727 | |||
728 | atomic_set(&sta_priv->pending_frames, 0); | ||
729 | if (vif->type == NL80211_IFTYPE_AP) | ||
730 | sta_priv->client = true; | ||
731 | |||
732 | ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, | ||
733 | is_ap, sta, &sta_id); | ||
734 | if (ret) { | ||
735 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | ||
736 | sta->addr, ret); | ||
737 | /* Should we return success if return code is EEXIST ? */ | ||
738 | goto out; | ||
739 | } | ||
740 | |||
741 | sta_priv->sta_id = sta_id; | ||
742 | |||
743 | /* Initialize rate scaling */ | ||
744 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | ||
745 | sta->addr); | ||
746 | iwl_rs_rate_init(priv, sta, sta_id); | ||
747 | out: | ||
748 | mutex_unlock(&priv->shrd->mutex); | ||
749 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
750 | |||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
755 | struct ieee80211_channel_switch *ch_switch) | ||
756 | { | ||
757 | struct iwl_priv *priv = hw->priv; | ||
758 | const struct iwl_channel_info *ch_info; | ||
759 | struct ieee80211_conf *conf = &hw->conf; | ||
760 | struct ieee80211_channel *channel = ch_switch->channel; | ||
761 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | ||
762 | /* | ||
763 | * MULTI-FIXME | ||
764 | * When we add support for multiple interfaces, we need to | ||
765 | * revisit this. The channel switch command in the device | ||
766 | * only affects the BSS context, but what does that really | ||
767 | * mean? And what if we get a CSA on the second interface? | ||
768 | * This needs a lot of work. | ||
769 | */ | ||
770 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
771 | u16 ch; | ||
772 | |||
773 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
774 | |||
775 | mutex_lock(&priv->shrd->mutex); | ||
776 | |||
777 | if (iwl_is_rfkill(priv->shrd)) | ||
778 | goto out; | ||
779 | |||
780 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | ||
781 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | ||
782 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | ||
783 | goto out; | ||
784 | |||
785 | if (!iwl_is_associated_ctx(ctx)) | ||
786 | goto out; | ||
787 | |||
788 | if (!priv->cfg->lib->set_channel_switch) | ||
789 | goto out; | ||
790 | |||
791 | ch = channel->hw_value; | ||
792 | if (le16_to_cpu(ctx->active.channel) == ch) | ||
793 | goto out; | ||
794 | |||
795 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
796 | if (!is_channel_valid(ch_info)) { | ||
797 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
798 | goto out; | ||
799 | } | ||
800 | |||
801 | spin_lock_irq(&priv->shrd->lock); | ||
802 | |||
803 | priv->current_ht_config.smps = conf->smps_mode; | ||
804 | |||
805 | /* Configure HT40 channels */ | ||
806 | ctx->ht.enabled = conf_is_ht(conf); | ||
807 | if (ctx->ht.enabled) { | ||
808 | if (conf_is_ht40_minus(conf)) { | ||
809 | ctx->ht.extension_chan_offset = | ||
810 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
811 | ctx->ht.is_40mhz = true; | ||
812 | } else if (conf_is_ht40_plus(conf)) { | ||
813 | ctx->ht.extension_chan_offset = | ||
814 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
815 | ctx->ht.is_40mhz = true; | ||
816 | } else { | ||
817 | ctx->ht.extension_chan_offset = | ||
818 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
819 | ctx->ht.is_40mhz = false; | ||
820 | } | ||
821 | } else | ||
822 | ctx->ht.is_40mhz = false; | ||
823 | |||
824 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
825 | ctx->staging.flags = 0; | ||
826 | |||
827 | iwl_set_rxon_channel(priv, channel, ctx); | ||
828 | iwl_set_rxon_ht(priv, ht_conf); | ||
829 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
830 | |||
831 | spin_unlock_irq(&priv->shrd->lock); | ||
832 | |||
833 | iwl_set_rate(priv); | ||
834 | /* | ||
835 | * at this point, staging_rxon has the | ||
836 | * configuration for channel switch | ||
837 | */ | ||
838 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
839 | priv->switch_channel = cpu_to_le16(ch); | ||
840 | if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) { | ||
841 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
842 | priv->switch_channel = 0; | ||
843 | ieee80211_chswitch_done(ctx->vif, false); | ||
844 | } | ||
845 | |||
846 | out: | ||
847 | mutex_unlock(&priv->shrd->mutex); | ||
848 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
849 | } | ||
850 | |||
851 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
852 | unsigned int changed_flags, | ||
853 | unsigned int *total_flags, | ||
854 | u64 multicast) | ||
855 | { | ||
856 | struct iwl_priv *priv = hw->priv; | ||
857 | __le32 filter_or = 0, filter_nand = 0; | ||
858 | struct iwl_rxon_context *ctx; | ||
859 | |||
860 | #define CHK(test, flag) do { \ | ||
861 | if (*total_flags & (test)) \ | ||
862 | filter_or |= (flag); \ | ||
863 | else \ | ||
864 | filter_nand |= (flag); \ | ||
865 | } while (0) | ||
866 | |||
867 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
868 | changed_flags, *total_flags); | ||
869 | |||
870 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
871 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | ||
872 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | ||
873 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
874 | |||
875 | #undef CHK | ||
876 | |||
877 | mutex_lock(&priv->shrd->mutex); | ||
878 | |||
879 | for_each_context(priv, ctx) { | ||
880 | ctx->staging.filter_flags &= ~filter_nand; | ||
881 | ctx->staging.filter_flags |= filter_or; | ||
882 | |||
883 | /* | ||
884 | * Not committing directly because hardware can perform a scan, | ||
885 | * but we'll eventually commit the filter flags change anyway. | ||
886 | */ | ||
887 | } | ||
888 | |||
889 | mutex_unlock(&priv->shrd->mutex); | ||
890 | |||
891 | /* | ||
892 | * Receiving all multicast frames is always enabled by the | ||
893 | * default flags setup in iwl_connection_init_rx_config() | ||
894 | * since we currently do not support programming multicast | ||
895 | * filters into the device. | ||
896 | */ | ||
897 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
898 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
899 | } | ||
900 | |||
901 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
902 | { | ||
903 | struct iwl_priv *priv = hw->priv; | ||
904 | |||
905 | mutex_lock(&priv->shrd->mutex); | ||
906 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
907 | |||
908 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
909 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | ||
910 | goto done; | ||
911 | } | ||
912 | if (iwl_is_rfkill(priv->shrd)) { | ||
913 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | ||
914 | goto done; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * mac80211 will not push any more frames for transmit | ||
919 | * until the flush is completed | ||
920 | */ | ||
921 | if (drop) { | ||
922 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | ||
923 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | ||
924 | IWL_ERR(priv, "flush request fail\n"); | ||
925 | goto done; | ||
926 | } | ||
927 | } | ||
928 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | ||
929 | iwl_trans_wait_tx_queue_empty(trans(priv)); | ||
930 | done: | ||
931 | mutex_unlock(&priv->shrd->mutex); | ||
932 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
933 | } | ||
934 | |||
935 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
936 | struct ieee80211_channel *channel, | ||
937 | enum nl80211_channel_type channel_type, | ||
938 | int duration) | ||
939 | { | ||
940 | struct iwl_priv *priv = hw->priv; | ||
941 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
942 | int err = 0; | ||
943 | |||
944 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
945 | return -EOPNOTSUPP; | ||
946 | |||
947 | if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
948 | return -EOPNOTSUPP; | ||
949 | |||
950 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
951 | mutex_lock(&priv->shrd->mutex); | ||
952 | |||
953 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
954 | err = -EBUSY; | ||
955 | goto out; | ||
956 | } | ||
957 | |||
958 | priv->hw_roc_channel = channel; | ||
959 | priv->hw_roc_chantype = channel_type; | ||
960 | /* convert from ms to TU */ | ||
961 | priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); | ||
962 | priv->hw_roc_start_notified = false; | ||
963 | cancel_delayed_work(&priv->hw_roc_disable_work); | ||
964 | |||
965 | if (!ctx->is_active) { | ||
966 | static const struct iwl_qos_info default_qos_data = { | ||
967 | .def_qos_parm = { | ||
968 | .ac[0] = { | ||
969 | .cw_min = cpu_to_le16(3), | ||
970 | .cw_max = cpu_to_le16(7), | ||
971 | .aifsn = 2, | ||
972 | .edca_txop = cpu_to_le16(1504), | ||
973 | }, | ||
974 | .ac[1] = { | ||
975 | .cw_min = cpu_to_le16(7), | ||
976 | .cw_max = cpu_to_le16(15), | ||
977 | .aifsn = 2, | ||
978 | .edca_txop = cpu_to_le16(3008), | ||
979 | }, | ||
980 | .ac[2] = { | ||
981 | .cw_min = cpu_to_le16(15), | ||
982 | .cw_max = cpu_to_le16(1023), | ||
983 | .aifsn = 3, | ||
984 | }, | ||
985 | .ac[3] = { | ||
986 | .cw_min = cpu_to_le16(15), | ||
987 | .cw_max = cpu_to_le16(1023), | ||
988 | .aifsn = 7, | ||
989 | }, | ||
990 | }, | ||
991 | }; | ||
992 | |||
993 | ctx->is_active = true; | ||
994 | ctx->qos_data = default_qos_data; | ||
995 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
996 | memcpy(ctx->staging.node_addr, | ||
997 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
998 | ETH_ALEN); | ||
999 | memcpy(ctx->staging.bssid_addr, | ||
1000 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
1001 | ETH_ALEN); | ||
1002 | err = iwlagn_commit_rxon(priv, ctx); | ||
1003 | if (err) | ||
1004 | goto out; | ||
1005 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK | | ||
1006 | RXON_FILTER_PROMISC_MSK | | ||
1007 | RXON_FILTER_CTL2HOST_MSK; | ||
1008 | |||
1009 | err = iwlagn_commit_rxon(priv, ctx); | ||
1010 | if (err) { | ||
1011 | iwlagn_disable_roc(priv); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | priv->hw_roc_setup = true; | ||
1015 | } | ||
1016 | |||
1017 | err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band); | ||
1018 | if (err) | ||
1019 | iwlagn_disable_roc(priv); | ||
1020 | |||
1021 | out: | ||
1022 | mutex_unlock(&priv->shrd->mutex); | ||
1023 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1024 | |||
1025 | return err; | ||
1026 | } | ||
1027 | |||
1028 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
1029 | { | ||
1030 | struct iwl_priv *priv = hw->priv; | ||
1031 | |||
1032 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
1033 | return -EOPNOTSUPP; | ||
1034 | |||
1035 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1036 | mutex_lock(&priv->shrd->mutex); | ||
1037 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | ||
1038 | iwlagn_disable_roc(priv); | ||
1039 | mutex_unlock(&priv->shrd->mutex); | ||
1040 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
1046 | struct ieee80211_vif *vif, | ||
1047 | const u8 *bssid, | ||
1048 | enum ieee80211_tx_sync_type type) | ||
1049 | { | ||
1050 | struct iwl_priv *priv = hw->priv; | ||
1051 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1052 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1053 | int ret; | ||
1054 | u8 sta_id; | ||
1055 | |||
1056 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1057 | mutex_lock(&priv->shrd->mutex); | ||
1058 | |||
1059 | if (iwl_is_associated_ctx(ctx)) { | ||
1060 | ret = 0; | ||
1061 | goto out; | ||
1062 | } | ||
1063 | |||
1064 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, | ||
1065 | &priv->shrd->status)) { | ||
1066 | ret = -EBUSY; | ||
1067 | goto out; | ||
1068 | } | ||
1069 | |||
1070 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
1071 | if (ret) | ||
1072 | goto out; | ||
1073 | |||
1074 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
1075 | ret = -EIO; | ||
1076 | goto out_remove_sta; | ||
1077 | } | ||
1078 | |||
1079 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
1080 | ctx->preauth_bssid = true; | ||
1081 | |||
1082 | ret = iwlagn_commit_rxon(priv, ctx); | ||
1083 | |||
1084 | if (ret == 0) | ||
1085 | goto out; | ||
1086 | |||
1087 | out_remove_sta: | ||
1088 | iwl_remove_station(priv, sta_id, bssid); | ||
1089 | out: | ||
1090 | mutex_unlock(&priv->shrd->mutex); | ||
1091 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1092 | |||
1093 | return ret; | ||
1094 | } | ||
1095 | |||
1096 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
1097 | struct ieee80211_vif *vif, | ||
1098 | const u8 *bssid, | ||
1099 | enum ieee80211_tx_sync_type type) | ||
1100 | { | ||
1101 | struct iwl_priv *priv = hw->priv; | ||
1102 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1103 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1104 | |||
1105 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1106 | mutex_lock(&priv->shrd->mutex); | ||
1107 | |||
1108 | if (iwl_is_associated_ctx(ctx)) | ||
1109 | goto out; | ||
1110 | |||
1111 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
1112 | ctx->preauth_bssid = false; | ||
1113 | /* no need to commit */ | ||
1114 | out: | ||
1115 | mutex_unlock(&priv->shrd->mutex); | ||
1116 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1117 | } | ||
1118 | |||
1119 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
1120 | enum ieee80211_rssi_event rssi_event) | ||
1121 | { | ||
1122 | struct iwl_priv *priv = hw->priv; | ||
1123 | |||
1124 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1125 | mutex_lock(&priv->shrd->mutex); | ||
1126 | |||
1127 | if (priv->cfg->bt_params && | ||
1128 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
1129 | if (rssi_event == RSSI_EVENT_LOW) | ||
1130 | priv->bt_enable_pspoll = true; | ||
1131 | else if (rssi_event == RSSI_EVENT_HIGH) | ||
1132 | priv->bt_enable_pspoll = false; | ||
1133 | |||
1134 | iwlagn_send_advance_bt_config(priv); | ||
1135 | } else { | ||
1136 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," | ||
1137 | "ignoring RSSI callback\n"); | ||
1138 | } | ||
1139 | |||
1140 | mutex_unlock(&priv->shrd->mutex); | ||
1141 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1142 | } | ||
1143 | |||
1144 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
1145 | struct ieee80211_sta *sta, bool set) | ||
1146 | { | ||
1147 | struct iwl_priv *priv = hw->priv; | ||
1148 | |||
1149 | queue_work(priv->shrd->workqueue, &priv->beacon_update); | ||
1150 | |||
1151 | return 0; | ||
1152 | } | ||
1153 | |||
1154 | static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
1155 | struct ieee80211_vif *vif, u16 queue, | ||
1156 | const struct ieee80211_tx_queue_params *params) | ||
1157 | { | ||
1158 | struct iwl_priv *priv = hw->priv; | ||
1159 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1160 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1161 | unsigned long flags; | ||
1162 | int q; | ||
1163 | |||
1164 | if (WARN_ON(!ctx)) | ||
1165 | return -EINVAL; | ||
1166 | |||
1167 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1168 | |||
1169 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1170 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
1171 | return -EIO; | ||
1172 | } | ||
1173 | |||
1174 | if (queue >= AC_NUM) { | ||
1175 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | q = AC_NUM - 1 - queue; | ||
1180 | |||
1181 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
1182 | |||
1183 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | ||
1184 | cpu_to_le16(params->cw_min); | ||
1185 | ctx->qos_data.def_qos_parm.ac[q].cw_max = | ||
1186 | cpu_to_le16(params->cw_max); | ||
1187 | ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
1188 | ctx->qos_data.def_qos_parm.ac[q].edca_txop = | ||
1189 | cpu_to_le16((params->txop * 32)); | ||
1190 | |||
1191 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
1192 | |||
1193 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
1194 | |||
1195 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | ||
1200 | { | ||
1201 | struct iwl_priv *priv = hw->priv; | ||
1202 | |||
1203 | return priv->ibss_manager == IWL_IBSS_MANAGER; | ||
1204 | } | ||
1205 | |||
1206 | static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
1207 | { | ||
1208 | iwl_connection_init_rx_config(priv, ctx); | ||
1209 | |||
1210 | iwlagn_set_rxon_chain(priv, ctx); | ||
1211 | |||
1212 | return iwlagn_commit_rxon(priv, ctx); | ||
1213 | } | ||
1214 | |||
1215 | static int iwl_setup_interface(struct iwl_priv *priv, | ||
1216 | struct iwl_rxon_context *ctx) | ||
1217 | { | ||
1218 | struct ieee80211_vif *vif = ctx->vif; | ||
1219 | int err; | ||
1220 | |||
1221 | lockdep_assert_held(&priv->shrd->mutex); | ||
1222 | |||
1223 | /* | ||
1224 | * This variable will be correct only when there's just | ||
1225 | * a single context, but all code using it is for hardware | ||
1226 | * that supports only one context. | ||
1227 | */ | ||
1228 | priv->iw_mode = vif->type; | ||
1229 | |||
1230 | ctx->is_active = true; | ||
1231 | |||
1232 | err = iwl_set_mode(priv, ctx); | ||
1233 | if (err) { | ||
1234 | if (!ctx->always_active) | ||
1235 | ctx->is_active = false; | ||
1236 | return err; | ||
1237 | } | ||
1238 | |||
1239 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && | ||
1240 | vif->type == NL80211_IFTYPE_ADHOC) { | ||
1241 | /* | ||
1242 | * pretend to have high BT traffic as long as we | ||
1243 | * are operating in IBSS mode, as this will cause | ||
1244 | * the rate scaling etc. to behave as intended. | ||
1245 | */ | ||
1246 | priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; | ||
1247 | } | ||
1248 | |||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
1253 | struct ieee80211_vif *vif) | ||
1254 | { | ||
1255 | struct iwl_priv *priv = hw->priv; | ||
1256 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1257 | struct iwl_rxon_context *tmp, *ctx = NULL; | ||
1258 | int err; | ||
1259 | enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); | ||
1260 | |||
1261 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | ||
1262 | viftype, vif->addr); | ||
1263 | |||
1264 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
1265 | |||
1266 | mutex_lock(&priv->shrd->mutex); | ||
1267 | |||
1268 | iwlagn_disable_roc(priv); | ||
1269 | |||
1270 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1271 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | ||
1272 | err = -EINVAL; | ||
1273 | goto out; | ||
1274 | } | ||
1275 | |||
1276 | for_each_context(priv, tmp) { | ||
1277 | u32 possible_modes = | ||
1278 | tmp->interface_modes | tmp->exclusive_interface_modes; | ||
1279 | |||
1280 | if (tmp->vif) { | ||
1281 | /* check if this busy context is exclusive */ | ||
1282 | if (tmp->exclusive_interface_modes & | ||
1283 | BIT(tmp->vif->type)) { | ||
1284 | err = -EINVAL; | ||
1285 | goto out; | ||
1286 | } | ||
1287 | continue; | ||
1288 | } | ||
1289 | |||
1290 | if (!(possible_modes & BIT(viftype))) | ||
1291 | continue; | ||
1292 | |||
1293 | /* have maybe usable context w/o interface */ | ||
1294 | ctx = tmp; | ||
1295 | break; | ||
1296 | } | ||
1297 | |||
1298 | if (!ctx) { | ||
1299 | err = -EOPNOTSUPP; | ||
1300 | goto out; | ||
1301 | } | ||
1302 | |||
1303 | vif_priv->ctx = ctx; | ||
1304 | ctx->vif = vif; | ||
1305 | |||
1306 | err = iwl_setup_interface(priv, ctx); | ||
1307 | if (!err) | ||
1308 | goto out; | ||
1309 | |||
1310 | ctx->vif = NULL; | ||
1311 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
1312 | out: | ||
1313 | mutex_unlock(&priv->shrd->mutex); | ||
1314 | |||
1315 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1316 | return err; | ||
1317 | } | ||
1318 | |||
1319 | static void iwl_teardown_interface(struct iwl_priv *priv, | ||
1320 | struct ieee80211_vif *vif, | ||
1321 | bool mode_change) | ||
1322 | { | ||
1323 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1324 | |||
1325 | lockdep_assert_held(&priv->shrd->mutex); | ||
1326 | |||
1327 | if (priv->scan_vif == vif) { | ||
1328 | iwl_scan_cancel_timeout(priv, 200); | ||
1329 | iwl_force_scan_end(priv); | ||
1330 | } | ||
1331 | |||
1332 | if (!mode_change) { | ||
1333 | iwl_set_mode(priv, ctx); | ||
1334 | if (!ctx->always_active) | ||
1335 | ctx->is_active = false; | ||
1336 | } | ||
1337 | |||
1338 | /* | ||
1339 | * When removing the IBSS interface, overwrite the | ||
1340 | * BT traffic load with the stored one from the last | ||
1341 | * notification, if any. If this is a device that | ||
1342 | * doesn't implement this, this has no effect since | ||
1343 | * both values are the same and zero. | ||
1344 | */ | ||
1345 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
1346 | priv->bt_traffic_load = priv->last_bt_traffic_load; | ||
1347 | } | ||
1348 | |||
1349 | static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
1350 | struct ieee80211_vif *vif) | ||
1351 | { | ||
1352 | struct iwl_priv *priv = hw->priv; | ||
1353 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1354 | |||
1355 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1356 | |||
1357 | mutex_lock(&priv->shrd->mutex); | ||
1358 | |||
1359 | if (WARN_ON(ctx->vif != vif)) { | ||
1360 | struct iwl_rxon_context *tmp; | ||
1361 | IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif); | ||
1362 | for_each_context(priv, tmp) | ||
1363 | IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n", | ||
1364 | tmp->ctxid, tmp, tmp->vif); | ||
1365 | } | ||
1366 | ctx->vif = NULL; | ||
1367 | |||
1368 | iwl_teardown_interface(priv, vif, false); | ||
1369 | |||
1370 | mutex_unlock(&priv->shrd->mutex); | ||
1371 | |||
1372 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1373 | |||
1374 | } | ||
1375 | |||
1376 | static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
1377 | struct ieee80211_vif *vif, | ||
1378 | enum nl80211_iftype newtype, bool newp2p) | ||
1379 | { | ||
1380 | struct iwl_priv *priv = hw->priv; | ||
1381 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1382 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1383 | struct iwl_rxon_context *tmp; | ||
1384 | enum nl80211_iftype newviftype = newtype; | ||
1385 | u32 interface_modes; | ||
1386 | int err; | ||
1387 | |||
1388 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1389 | |||
1390 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | ||
1391 | |||
1392 | mutex_lock(&priv->shrd->mutex); | ||
1393 | |||
1394 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | ||
1395 | /* | ||
1396 | * Huh? But wait ... this can maybe happen when | ||
1397 | * we're in the middle of a firmware restart! | ||
1398 | */ | ||
1399 | err = -EBUSY; | ||
1400 | goto out; | ||
1401 | } | ||
1402 | |||
1403 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; | ||
1404 | |||
1405 | if (!(interface_modes & BIT(newtype))) { | ||
1406 | err = -EBUSY; | ||
1407 | goto out; | ||
1408 | } | ||
1409 | |||
1410 | /* | ||
1411 | * Refuse a change that should be done by moving from the PAN | ||
1412 | * context to the BSS context instead, if the BSS context is | ||
1413 | * available and can support the new interface type. | ||
1414 | */ | ||
1415 | if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||
1416 | (bss_ctx->interface_modes & BIT(newtype) || | ||
1417 | bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||
1418 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1419 | err = -EBUSY; | ||
1420 | goto out; | ||
1421 | } | ||
1422 | |||
1423 | if (ctx->exclusive_interface_modes & BIT(newtype)) { | ||
1424 | for_each_context(priv, tmp) { | ||
1425 | if (ctx == tmp) | ||
1426 | continue; | ||
1427 | |||
1428 | if (!tmp->vif) | ||
1429 | continue; | ||
1430 | |||
1431 | /* | ||
1432 | * The current mode switch would be exclusive, but | ||
1433 | * another context is active ... refuse the switch. | ||
1434 | */ | ||
1435 | err = -EBUSY; | ||
1436 | goto out; | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | /* success */ | ||
1441 | iwl_teardown_interface(priv, vif, true); | ||
1442 | vif->type = newviftype; | ||
1443 | vif->p2p = newp2p; | ||
1444 | err = iwl_setup_interface(priv, ctx); | ||
1445 | WARN_ON(err); | ||
1446 | /* | ||
1447 | * We've switched internally, but submitting to the | ||
1448 | * device may have failed for some reason. Mask this | ||
1449 | * error, because otherwise mac80211 will not switch | ||
1450 | * (and set the interface type back) and we'll be | ||
1451 | * out of sync with it. | ||
1452 | */ | ||
1453 | err = 0; | ||
1454 | |||
1455 | out: | ||
1456 | mutex_unlock(&priv->shrd->mutex); | ||
1457 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1458 | |||
1459 | return err; | ||
1460 | } | ||
1461 | |||
1462 | static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
1463 | struct ieee80211_vif *vif, | ||
1464 | struct cfg80211_scan_request *req) | ||
1465 | { | ||
1466 | struct iwl_priv *priv = hw->priv; | ||
1467 | int ret; | ||
1468 | |||
1469 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1470 | |||
1471 | if (req->n_channels == 0) | ||
1472 | return -EINVAL; | ||
1473 | |||
1474 | mutex_lock(&priv->shrd->mutex); | ||
1475 | |||
1476 | /* | ||
1477 | * If an internal scan is in progress, just set | ||
1478 | * up the scan_request as per above. | ||
1479 | */ | ||
1480 | if (priv->scan_type != IWL_SCAN_NORMAL) { | ||
1481 | IWL_DEBUG_SCAN(priv, | ||
1482 | "SCAN request during internal scan - defer\n"); | ||
1483 | priv->scan_request = req; | ||
1484 | priv->scan_vif = vif; | ||
1485 | ret = 0; | ||
1486 | } else { | ||
1487 | priv->scan_request = req; | ||
1488 | priv->scan_vif = vif; | ||
1489 | /* | ||
1490 | * mac80211 will only ask for one band at a time | ||
1491 | * so using channels[0] here is ok | ||
1492 | */ | ||
1493 | ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, | ||
1494 | req->channels[0]->band); | ||
1495 | if (ret) { | ||
1496 | priv->scan_request = NULL; | ||
1497 | priv->scan_vif = NULL; | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1502 | |||
1503 | mutex_unlock(&priv->shrd->mutex); | ||
1504 | |||
1505 | return ret; | ||
1506 | } | ||
1507 | |||
1508 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
1509 | struct ieee80211_vif *vif, | ||
1510 | struct ieee80211_sta *sta) | ||
1511 | { | ||
1512 | struct iwl_priv *priv = hw->priv; | ||
1513 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1514 | int ret; | ||
1515 | |||
1516 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
1517 | "station %pM\n", sta->addr); | ||
1518 | mutex_lock(&priv->shrd->mutex); | ||
1519 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
1520 | sta->addr); | ||
1521 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
1522 | if (ret) | ||
1523 | IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", | ||
1524 | sta->addr); | ||
1525 | mutex_unlock(&priv->shrd->mutex); | ||
1526 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1527 | |||
1528 | return ret; | ||
1529 | } | ||
1530 | |||
1531 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
1532 | { | ||
1533 | unsigned long flags; | ||
1534 | |||
1535 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
1536 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
1537 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
1538 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1539 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1540 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1541 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1542 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1543 | |||
1544 | } | ||
1545 | |||
1546 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
1547 | struct ieee80211_vif *vif, | ||
1548 | enum sta_notify_cmd cmd, | ||
1549 | struct ieee80211_sta *sta) | ||
1550 | { | ||
1551 | struct iwl_priv *priv = hw->priv; | ||
1552 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1553 | int sta_id; | ||
1554 | |||
1555 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1556 | |||
1557 | switch (cmd) { | ||
1558 | case STA_NOTIFY_SLEEP: | ||
1559 | WARN_ON(!sta_priv->client); | ||
1560 | sta_priv->asleep = true; | ||
1561 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
1562 | ieee80211_sta_block_awake(hw, sta, true); | ||
1563 | break; | ||
1564 | case STA_NOTIFY_AWAKE: | ||
1565 | WARN_ON(!sta_priv->client); | ||
1566 | if (!sta_priv->asleep) | ||
1567 | break; | ||
1568 | sta_priv->asleep = false; | ||
1569 | sta_id = iwl_sta_id(sta); | ||
1570 | if (sta_id != IWL_INVALID_STATION) | ||
1571 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1572 | break; | ||
1573 | default: | ||
1574 | break; | ||
1575 | } | ||
1576 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1577 | } | ||
1578 | |||
1579 | struct ieee80211_ops iwlagn_hw_ops = { | ||
1580 | .tx = iwlagn_mac_tx, | ||
1581 | .start = iwlagn_mac_start, | ||
1582 | .stop = iwlagn_mac_stop, | ||
1583 | #ifdef CONFIG_PM_SLEEP | ||
1584 | .suspend = iwlagn_mac_suspend, | ||
1585 | .resume = iwlagn_mac_resume, | ||
1586 | #endif | ||
1587 | .add_interface = iwlagn_mac_add_interface, | ||
1588 | .remove_interface = iwlagn_mac_remove_interface, | ||
1589 | .change_interface = iwlagn_mac_change_interface, | ||
1590 | .config = iwlagn_mac_config, | ||
1591 | .configure_filter = iwlagn_configure_filter, | ||
1592 | .set_key = iwlagn_mac_set_key, | ||
1593 | .update_tkip_key = iwlagn_mac_update_tkip_key, | ||
1594 | .set_rekey_data = iwlagn_mac_set_rekey_data, | ||
1595 | .conf_tx = iwlagn_mac_conf_tx, | ||
1596 | .bss_info_changed = iwlagn_bss_info_changed, | ||
1597 | .ampdu_action = iwlagn_mac_ampdu_action, | ||
1598 | .hw_scan = iwlagn_mac_hw_scan, | ||
1599 | .sta_notify = iwlagn_mac_sta_notify, | ||
1600 | .sta_add = iwlagn_mac_sta_add, | ||
1601 | .sta_remove = iwlagn_mac_sta_remove, | ||
1602 | .channel_switch = iwlagn_mac_channel_switch, | ||
1603 | .flush = iwlagn_mac_flush, | ||
1604 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | ||
1605 | .remain_on_channel = iwlagn_mac_remain_on_channel, | ||
1606 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, | ||
1607 | .rssi_callback = iwlagn_mac_rssi_callback, | ||
1608 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | ||
1609 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | ||
1610 | .tx_sync = iwlagn_mac_tx_sync, | ||
1611 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
1612 | .set_tim = iwlagn_mac_set_tim, | ||
1613 | }; | ||
1614 | |||
1615 | /* This function both allocates and initializes hw and priv. */ | ||
1616 | struct ieee80211_hw *iwl_alloc_all(void) | ||
1617 | { | ||
1618 | struct iwl_priv *priv; | ||
1619 | /* mac80211 allocates memory for this device instance, including | ||
1620 | * space for this driver's private structure */ | ||
1621 | struct ieee80211_hw *hw; | ||
1622 | |||
1623 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); | ||
1624 | if (!hw) | ||
1625 | goto out; | ||
1626 | |||
1627 | priv = hw->priv; | ||
1628 | priv->hw = hw; | ||
1629 | |||
1630 | out: | ||
1631 | return hw; | ||
1632 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 1800029911ad..850ec8e51b17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -256,6 +256,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
256 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, | 256 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, |
257 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, | 257 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, |
258 | {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, | 258 | {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, |
259 | {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */ | ||
260 | {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */ | ||
259 | 261 | ||
260 | /* 6x30 Series */ | 262 | /* 6x30 Series */ |
261 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, | 263 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, |
@@ -325,46 +327,28 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
325 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | 327 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, |
326 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | 328 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, |
327 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | 329 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, |
328 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
329 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
330 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
331 | {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)}, | 330 | {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)}, |
332 | 331 | ||
333 | /* 2x30 Series */ | 332 | /* 2x30 Series */ |
334 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | 333 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, |
335 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | 334 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, |
336 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | 335 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, |
337 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
338 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
339 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
340 | 336 | ||
341 | /* 6x35 Series */ | 337 | /* 6x35 Series */ |
342 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | 338 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, |
343 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | 339 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, |
344 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | 340 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, |
345 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
346 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
347 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
348 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
349 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
350 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
351 | 341 | ||
352 | /* 105 Series */ | 342 | /* 105 Series */ |
353 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | 343 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, |
354 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, | 344 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, |
355 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, | 345 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, |
356 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, | ||
357 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, | ||
358 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, | ||
359 | {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)}, | 346 | {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)}, |
360 | 347 | ||
361 | /* 135 Series */ | 348 | /* 135 Series */ |
362 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, | 349 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, |
363 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, | 350 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, |
364 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, | 351 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, |
365 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, | ||
366 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, | ||
367 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, | ||
368 | 352 | ||
369 | {0} | 353 | {0} |
370 | }; | 354 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index e5d727f537d0..359d2182757b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -416,6 +416,8 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) | |||
416 | 416 | ||
417 | if (!iwl_is_associated_ctx(ctx)) | 417 | if (!iwl_is_associated_ctx(ctx)) |
418 | continue; | 418 | continue; |
419 | if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P) | ||
420 | continue; | ||
419 | value = ctx->beacon_int; | 421 | value = ctx->beacon_int; |
420 | if (!value) | 422 | if (!value) |
421 | value = IWL_PASSIVE_DWELL_BASE; | 423 | value = IWL_PASSIVE_DWELL_BASE; |
@@ -678,7 +680,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
678 | priv->contexts[IWL_RXON_CTX_BSS].active.flags & | 680 | priv->contexts[IWL_RXON_CTX_BSS].active.flags & |
679 | RXON_FLG_CHANNEL_MODE_MSK) | 681 | RXON_FLG_CHANNEL_MODE_MSK) |
680 | >> RXON_FLG_CHANNEL_MODE_POS; | 682 | >> RXON_FLG_CHANNEL_MODE_POS; |
681 | if (chan_mod == CHANNEL_MODE_PURE_40) { | 683 | if ((priv->scan_request && priv->scan_request->no_cck) || |
684 | chan_mod == CHANNEL_MODE_PURE_40) { | ||
682 | rate = IWL_RATE_6M_PLCP; | 685 | rate = IWL_RATE_6M_PLCP; |
683 | } else { | 686 | } else { |
684 | rate = IWL_RATE_1M_PLCP; | 687 | rate = IWL_RATE_1M_PLCP; |
@@ -938,51 +941,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
938 | return 0; | 941 | return 0; |
939 | } | 942 | } |
940 | 943 | ||
941 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
942 | struct ieee80211_vif *vif, | ||
943 | struct cfg80211_scan_request *req) | ||
944 | { | ||
945 | struct iwl_priv *priv = hw->priv; | ||
946 | int ret; | ||
947 | |||
948 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
949 | |||
950 | if (req->n_channels == 0) | ||
951 | return -EINVAL; | ||
952 | |||
953 | mutex_lock(&priv->shrd->mutex); | ||
954 | |||
955 | /* | ||
956 | * If an internal scan is in progress, just set | ||
957 | * up the scan_request as per above. | ||
958 | */ | ||
959 | if (priv->scan_type != IWL_SCAN_NORMAL) { | ||
960 | IWL_DEBUG_SCAN(priv, | ||
961 | "SCAN request during internal scan - defer\n"); | ||
962 | priv->scan_request = req; | ||
963 | priv->scan_vif = vif; | ||
964 | ret = 0; | ||
965 | } else { | ||
966 | priv->scan_request = req; | ||
967 | priv->scan_vif = vif; | ||
968 | /* | ||
969 | * mac80211 will only ask for one band at a time | ||
970 | * so using channels[0] here is ok | ||
971 | */ | ||
972 | ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, | ||
973 | req->channels[0]->band); | ||
974 | if (ret) { | ||
975 | priv->scan_request = NULL; | ||
976 | priv->scan_vif = NULL; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
981 | |||
982 | mutex_unlock(&priv->shrd->mutex); | ||
983 | |||
984 | return ret; | ||
985 | } | ||
986 | 944 | ||
987 | /* | 945 | /* |
988 | * internal short scan, this function should only been called while associated. | 946 | * internal short scan, this function should only been called while associated. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 5e50d88f302b..e3882d0cfc85 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c | |||
@@ -396,8 +396,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
396 | break; | 396 | break; |
397 | 397 | ||
398 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 398 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
399 | status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 399 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
400 | IWL_UCODE_INIT); | ||
401 | if (status) | 400 | if (status) |
402 | IWL_DEBUG_INFO(priv, | 401 | IWL_DEBUG_INFO(priv, |
403 | "Error loading init ucode: %d\n", status); | 402 | "Error loading init ucode: %d\n", status); |
@@ -409,9 +408,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
409 | break; | 408 | break; |
410 | 409 | ||
411 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 410 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
412 | status = iwlagn_load_ucode_wait_alive(priv, | 411 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
413 | &priv->ucode_rt, | ||
414 | IWL_UCODE_REGULAR); | ||
415 | if (status) { | 412 | if (status) { |
416 | IWL_DEBUG_INFO(priv, | 413 | IWL_DEBUG_INFO(priv, |
417 | "Error loading runtime ucode: %d\n", status); | 414 | "Error loading runtime ucode: %d\n", status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 2b6756e8b8f9..afaaa2a51b96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -355,7 +355,7 @@ static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 357 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
358 | struct iwl_tx_queue *txq) | 358 | struct iwl_tx_queue *txq, const char *msg) |
359 | { | 359 | { |
360 | u8 queue = txq->swq_id; | 360 | u8 queue = txq->swq_id; |
361 | u8 ac = queue & 3; | 361 | u8 ac = queue & 3; |
@@ -363,13 +363,22 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
363 | struct iwl_trans_pcie *trans_pcie = | 363 | struct iwl_trans_pcie *trans_pcie = |
364 | IWL_TRANS_GET_PCIE_TRANS(trans); | 364 | IWL_TRANS_GET_PCIE_TRANS(trans); |
365 | 365 | ||
366 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) | 366 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { |
367 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) | 367 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { |
368 | iwl_wake_sw_queue(priv(trans), ac); | 368 | iwl_wake_sw_queue(priv(trans), ac); |
369 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", | ||
370 | hwq, ac, msg); | ||
371 | } else { | ||
372 | IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" | ||
373 | " stop count %d. %s", | ||
374 | hwq, ac, atomic_read(&trans_pcie-> | ||
375 | queue_stop_count[ac]), msg); | ||
376 | } | ||
377 | } | ||
369 | } | 378 | } |
370 | 379 | ||
371 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 380 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
372 | struct iwl_tx_queue *txq) | 381 | struct iwl_tx_queue *txq, const char *msg) |
373 | { | 382 | { |
374 | u8 queue = txq->swq_id; | 383 | u8 queue = txq->swq_id; |
375 | u8 ac = queue & 3; | 384 | u8 ac = queue & 3; |
@@ -377,9 +386,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
377 | struct iwl_trans_pcie *trans_pcie = | 386 | struct iwl_trans_pcie *trans_pcie = |
378 | IWL_TRANS_GET_PCIE_TRANS(trans); | 387 | IWL_TRANS_GET_PCIE_TRANS(trans); |
379 | 388 | ||
380 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) | 389 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { |
381 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) | 390 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { |
382 | iwl_stop_sw_queue(priv(trans), ac); | 391 | iwl_stop_sw_queue(priv(trans), ac); |
392 | IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" | ||
393 | " stop count %d. %s", | ||
394 | hwq, ac, atomic_read(&trans_pcie-> | ||
395 | queue_stop_count[ac]), msg); | ||
396 | } else { | ||
397 | IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" | ||
398 | " stop count %d. %s", | ||
399 | hwq, ac, atomic_read(&trans_pcie-> | ||
400 | queue_stop_count[ac]), msg); | ||
401 | } | ||
402 | } else { | ||
403 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", | ||
404 | hwq, msg); | ||
405 | } | ||
383 | } | 406 | } |
384 | 407 | ||
385 | #ifdef ieee80211_stop_queue | 408 | #ifdef ieee80211_stop_queue |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 374c68cc1d70..ee126f844a5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -1108,7 +1108,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1108 | isr_stats->tx++; | 1108 | isr_stats->tx++; |
1109 | handled |= CSR_INT_BIT_FH_TX; | 1109 | handled |= CSR_INT_BIT_FH_TX; |
1110 | /* Wake up uCode load routine, now that load is complete */ | 1110 | /* Wake up uCode load routine, now that load is complete */ |
1111 | priv(trans)->ucode_write_complete = 1; | 1111 | trans->ucode_write_complete = 1; |
1112 | wake_up(&trans->shrd->wait_command_queue); | 1112 | wake_up(&trans->shrd->wait_command_queue); |
1113 | } | 1113 | } |
1114 | 1114 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 4a0c95302a7e..6dba1515023c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -430,7 +430,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
430 | 430 | ||
431 | txq->sched_retry = scd_retry; | 431 | txq->sched_retry = scd_retry; |
432 | 432 | ||
433 | IWL_DEBUG_INFO(trans, "%s %s Queue %d on FIFO %d\n", | 433 | IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", |
434 | active ? "Activate" : "Deactivate", | 434 | active ? "Activate" : "Deactivate", |
435 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); | 435 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); |
436 | } | 436 | } |
@@ -561,12 +561,13 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, | |||
561 | 561 | ||
562 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | 562 | tid_data = &trans->shrd->tid_data[sta_id][tid]; |
563 | if (tid_data->tfds_in_queue == 0) { | 563 | if (tid_data->tfds_in_queue == 0) { |
564 | IWL_DEBUG_HT(trans, "HW queue is empty\n"); | 564 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); |
565 | tid_data->agg.state = IWL_AGG_ON; | 565 | tid_data->agg.state = IWL_AGG_ON; |
566 | iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); | 566 | iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); |
567 | } else { | 567 | } else { |
568 | IWL_DEBUG_HT(trans, "HW queue is NOT empty: %d packets in HW" | 568 | IWL_DEBUG_TX_QUEUES(trans, |
569 | "queue\n", tid_data->tfds_in_queue); | 569 | "HW queue is NOT empty: %d packets in HW" |
570 | " queue\n", tid_data->tfds_in_queue); | ||
570 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | 571 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; |
571 | } | 572 | } |
572 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | 573 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); |
@@ -643,14 +644,15 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, | |||
643 | 644 | ||
644 | /* The queue is not empty */ | 645 | /* The queue is not empty */ |
645 | if (write_ptr != read_ptr) { | 646 | if (write_ptr != read_ptr) { |
646 | IWL_DEBUG_HT(trans, "Stopping a non empty AGG HW QUEUE\n"); | 647 | IWL_DEBUG_TX_QUEUES(trans, |
648 | "Stopping a non empty AGG HW QUEUE\n"); | ||
647 | trans->shrd->tid_data[sta_id][tid].agg.state = | 649 | trans->shrd->tid_data[sta_id][tid].agg.state = |
648 | IWL_EMPTYING_HW_QUEUE_DELBA; | 650 | IWL_EMPTYING_HW_QUEUE_DELBA; |
649 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | 651 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); |
650 | return 0; | 652 | return 0; |
651 | } | 653 | } |
652 | 654 | ||
653 | IWL_DEBUG_HT(trans, "HW queue is empty\n"); | 655 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); |
654 | turn_off: | 656 | turn_off: |
655 | trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 657 | trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; |
656 | 658 | ||
@@ -982,7 +984,8 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
982 | 984 | ||
983 | ret = iwl_enqueue_hcmd(trans, cmd); | 985 | ret = iwl_enqueue_hcmd(trans, cmd); |
984 | if (ret < 0) { | 986 | if (ret < 0) { |
985 | IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", | 987 | IWL_DEBUG_QUIET_RFKILL(trans, |
988 | "Error sending %s: enqueue_hcmd failed: %d\n", | ||
986 | get_cmd_string(cmd->id), ret); | 989 | get_cmd_string(cmd->id), ret); |
987 | return ret; | 990 | return ret; |
988 | } | 991 | } |
@@ -1000,6 +1003,20 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1000 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1003 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
1001 | get_cmd_string(cmd->id)); | 1004 | get_cmd_string(cmd->id)); |
1002 | 1005 | ||
1006 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
1007 | return -EBUSY; | ||
1008 | |||
1009 | |||
1010 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
1011 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
1012 | get_cmd_string(cmd->id)); | ||
1013 | return -ECANCELED; | ||
1014 | } | ||
1015 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | ||
1016 | IWL_ERR(trans, "Command %s failed: FW Error\n", | ||
1017 | get_cmd_string(cmd->id)); | ||
1018 | return -EIO; | ||
1019 | } | ||
1003 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 1020 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
1004 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 1021 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
1005 | get_cmd_string(cmd->id)); | 1022 | get_cmd_string(cmd->id)); |
@@ -1008,7 +1025,8 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1008 | if (cmd_idx < 0) { | 1025 | if (cmd_idx < 0) { |
1009 | ret = cmd_idx; | 1026 | ret = cmd_idx; |
1010 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 1027 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
1011 | IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", | 1028 | IWL_DEBUG_QUIET_RFKILL(trans, |
1029 | "Error sending %s: enqueue_hcmd failed: %d\n", | ||
1012 | get_cmd_string(cmd->id), ret); | 1030 | get_cmd_string(cmd->id), ret); |
1013 | return ret; | 1031 | return ret; |
1014 | } | 1032 | } |
@@ -1022,12 +1040,12 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1022 | &trans_pcie->txq[trans->shrd->cmd_queue]; | 1040 | &trans_pcie->txq[trans->shrd->cmd_queue]; |
1023 | struct iwl_queue *q = &txq->q; | 1041 | struct iwl_queue *q = &txq->q; |
1024 | 1042 | ||
1025 | IWL_ERR(trans, | 1043 | IWL_DEBUG_QUIET_RFKILL(trans, |
1026 | "Error sending %s: time out after %dms.\n", | 1044 | "Error sending %s: time out after %dms.\n", |
1027 | get_cmd_string(cmd->id), | 1045 | get_cmd_string(cmd->id), |
1028 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1046 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
1029 | 1047 | ||
1030 | IWL_ERR(trans, | 1048 | IWL_DEBUG_QUIET_RFKILL(trans, |
1031 | "Current CMD queue read_ptr %d write_ptr %d\n", | 1049 | "Current CMD queue read_ptr %d write_ptr %d\n", |
1032 | q->read_ptr, q->write_ptr); | 1050 | q->read_ptr, q->write_ptr); |
1033 | 1051 | ||
@@ -1039,18 +1057,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1039 | } | 1057 | } |
1040 | } | 1058 | } |
1041 | 1059 | ||
1042 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
1043 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
1044 | get_cmd_string(cmd->id)); | ||
1045 | ret = -ECANCELED; | ||
1046 | goto fail; | ||
1047 | } | ||
1048 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | ||
1049 | IWL_ERR(trans, "Command %s failed: FW Error\n", | ||
1050 | get_cmd_string(cmd->id)); | ||
1051 | ret = -EIO; | ||
1052 | goto fail; | ||
1053 | } | ||
1054 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { | 1060 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { |
1055 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 1061 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
1056 | get_cmd_string(cmd->id)); | 1062 | get_cmd_string(cmd->id)); |
@@ -1071,7 +1077,7 @@ cancel: | |||
1071 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= | 1077 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= |
1072 | ~CMD_WANT_SKB; | 1078 | ~CMD_WANT_SKB; |
1073 | } | 1079 | } |
1074 | fail: | 1080 | |
1075 | if (cmd->reply_page) { | 1081 | if (cmd->reply_page) { |
1076 | iwl_free_pages(trans->shrd, cmd->reply_page); | 1082 | iwl_free_pages(trans->shrd, cmd->reply_page); |
1077 | cmd->reply_page = 0; | 1083 | cmd->reply_page = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index da3411057afc..a1a58330273f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -1231,7 +1231,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1231 | txq->need_update = 1; | 1231 | txq->need_update = 1; |
1232 | iwl_txq_update_write_ptr(trans, txq); | 1232 | iwl_txq_update_write_ptr(trans, txq); |
1233 | } else { | 1233 | } else { |
1234 | iwl_stop_queue(trans, txq); | 1234 | iwl_stop_queue(trans, txq, "Queue is full"); |
1235 | } | 1235 | } |
1236 | } | 1236 | } |
1237 | return 0; | 1237 | return 0; |
@@ -1283,20 +1283,21 @@ static int iwlagn_txq_check_empty(struct iwl_trans *trans, | |||
1283 | /* aggregated HW queue */ | 1283 | /* aggregated HW queue */ |
1284 | if ((txq_id == tid_data->agg.txq_id) && | 1284 | if ((txq_id == tid_data->agg.txq_id) && |
1285 | (q->read_ptr == q->write_ptr)) { | 1285 | (q->read_ptr == q->write_ptr)) { |
1286 | IWL_DEBUG_HT(trans, | 1286 | IWL_DEBUG_TX_QUEUES(trans, |
1287 | "HW queue empty: continue DELBA flow\n"); | 1287 | "HW queue empty: continue DELBA flow\n"); |
1288 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); | 1288 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); |
1289 | tid_data->agg.state = IWL_AGG_OFF; | 1289 | tid_data->agg.state = IWL_AGG_OFF; |
1290 | iwl_stop_tx_ba_trans_ready(priv(trans), | 1290 | iwl_stop_tx_ba_trans_ready(priv(trans), |
1291 | NUM_IWL_RXON_CTX, | 1291 | NUM_IWL_RXON_CTX, |
1292 | sta_id, tid); | 1292 | sta_id, tid); |
1293 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id]); | 1293 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], |
1294 | "DELBA flow complete"); | ||
1294 | } | 1295 | } |
1295 | break; | 1296 | break; |
1296 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 1297 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
1297 | /* We are reclaiming the last packet of the queue */ | 1298 | /* We are reclaiming the last packet of the queue */ |
1298 | if (tid_data->tfds_in_queue == 0) { | 1299 | if (tid_data->tfds_in_queue == 0) { |
1299 | IWL_DEBUG_HT(trans, | 1300 | IWL_DEBUG_TX_QUEUES(trans, |
1300 | "HW queue empty: continue ADDBA flow\n"); | 1301 | "HW queue empty: continue ADDBA flow\n"); |
1301 | tid_data->agg.state = IWL_AGG_ON; | 1302 | tid_data->agg.state = IWL_AGG_ON; |
1302 | iwl_start_tx_ba_trans_ready(priv(trans), | 1303 | iwl_start_tx_ba_trans_ready(priv(trans), |
@@ -1354,7 +1355,7 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1354 | ssn , tfd_num, txq_id, txq->swq_id); | 1355 | ssn , tfd_num, txq_id, txq->swq_id); |
1355 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1356 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
1356 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond) | 1357 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond) |
1357 | iwl_wake_queue(trans, txq); | 1358 | iwl_wake_queue(trans, txq, "Packets reclaimed"); |
1358 | } | 1359 | } |
1359 | 1360 | ||
1360 | iwl_free_tfds_in_queue(trans, sta_id, tid, freed); | 1361 | iwl_free_tfds_in_queue(trans, sta_id, tid, freed); |
@@ -1418,7 +1419,8 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1418 | #endif /* CONFIG_PM_SLEEP */ | 1419 | #endif /* CONFIG_PM_SLEEP */ |
1419 | 1420 | ||
1420 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | 1421 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, |
1421 | enum iwl_rxon_context_id ctx) | 1422 | enum iwl_rxon_context_id ctx, |
1423 | const char *msg) | ||
1422 | { | 1424 | { |
1423 | u8 ac, txq_id; | 1425 | u8 ac, txq_id; |
1424 | struct iwl_trans_pcie *trans_pcie = | 1426 | struct iwl_trans_pcie *trans_pcie = |
@@ -1426,11 +1428,11 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | |||
1426 | 1428 | ||
1427 | for (ac = 0; ac < AC_NUM; ac++) { | 1429 | for (ac = 0; ac < AC_NUM; ac++) { |
1428 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; | 1430 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; |
1429 | IWL_DEBUG_INFO(trans, "Queue Status: Q[%d] %s\n", | 1431 | IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", |
1430 | ac, | 1432 | ac, |
1431 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) | 1433 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) |
1432 | ? "stopped" : "awake"); | 1434 | ? "stopped" : "awake"); |
1433 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id]); | 1435 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); |
1434 | } | 1436 | } |
1435 | } | 1437 | } |
1436 | 1438 | ||
@@ -1453,11 +1455,12 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) | |||
1453 | return iwl_trans; | 1455 | return iwl_trans; |
1454 | } | 1456 | } |
1455 | 1457 | ||
1456 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id) | 1458 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, |
1459 | const char *msg) | ||
1457 | { | 1460 | { |
1458 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1461 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1459 | 1462 | ||
1460 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id]); | 1463 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); |
1461 | } | 1464 | } |
1462 | 1465 | ||
1463 | #define IWL_FLUSH_WAIT_MS 2000 | 1466 | #define IWL_FLUSH_WAIT_MS 2000 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index c5923125c3f9..50227ebc0ee2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -171,7 +171,8 @@ struct iwl_trans_ops { | |||
171 | void (*tx_start)(struct iwl_trans *trans); | 171 | void (*tx_start)(struct iwl_trans *trans); |
172 | 172 | ||
173 | void (*wake_any_queue)(struct iwl_trans *trans, | 173 | void (*wake_any_queue)(struct iwl_trans *trans, |
174 | enum iwl_rxon_context_id ctx); | 174 | enum iwl_rxon_context_id ctx, |
175 | const char *msg); | ||
175 | 176 | ||
176 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 177 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
177 | 178 | ||
@@ -196,7 +197,7 @@ struct iwl_trans_ops { | |||
196 | 197 | ||
197 | void (*free)(struct iwl_trans *trans); | 198 | void (*free)(struct iwl_trans *trans); |
198 | 199 | ||
199 | void (*stop_queue)(struct iwl_trans *trans, int q); | 200 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); |
200 | 201 | ||
201 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 202 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
202 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | 203 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); |
@@ -207,17 +208,48 @@ struct iwl_trans_ops { | |||
207 | #endif | 208 | #endif |
208 | }; | 209 | }; |
209 | 210 | ||
211 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
212 | struct fw_desc { | ||
213 | dma_addr_t p_addr; /* hardware address */ | ||
214 | void *v_addr; /* software address */ | ||
215 | u32 len; /* size in bytes */ | ||
216 | }; | ||
217 | |||
218 | struct fw_img { | ||
219 | struct fw_desc code; /* firmware code image */ | ||
220 | struct fw_desc data; /* firmware data image */ | ||
221 | }; | ||
222 | |||
223 | enum iwl_ucode_type { | ||
224 | IWL_UCODE_NONE, | ||
225 | IWL_UCODE_REGULAR, | ||
226 | IWL_UCODE_INIT, | ||
227 | IWL_UCODE_WOWLAN, | ||
228 | }; | ||
229 | |||
210 | /** | 230 | /** |
211 | * struct iwl_trans - transport common data | 231 | * struct iwl_trans - transport common data |
212 | * @ops - pointer to iwl_trans_ops | 232 | * @ops - pointer to iwl_trans_ops |
213 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 233 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
214 | * @hcmd_lock: protects HCMD | 234 | * @hcmd_lock: protects HCMD |
235 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
236 | * @ucode_rt: run time ucode image | ||
237 | * @ucode_init: init ucode image | ||
238 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
215 | */ | 239 | */ |
216 | struct iwl_trans { | 240 | struct iwl_trans { |
217 | const struct iwl_trans_ops *ops; | 241 | const struct iwl_trans_ops *ops; |
218 | struct iwl_shared *shrd; | 242 | struct iwl_shared *shrd; |
219 | spinlock_t hcmd_lock; | 243 | spinlock_t hcmd_lock; |
220 | 244 | ||
245 | u8 ucode_write_complete; /* the image write is complete */ | ||
246 | struct fw_img ucode_rt; | ||
247 | struct fw_img ucode_init; | ||
248 | struct fw_img ucode_wowlan; | ||
249 | |||
250 | /* eeprom related variables */ | ||
251 | int nvm_device_type; | ||
252 | |||
221 | /* pointer to trans specific struct */ | 253 | /* pointer to trans specific struct */ |
222 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 254 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
223 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); | 255 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); |
@@ -249,9 +281,10 @@ static inline void iwl_trans_tx_start(struct iwl_trans *trans) | |||
249 | } | 281 | } |
250 | 282 | ||
251 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 283 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, |
252 | enum iwl_rxon_context_id ctx) | 284 | enum iwl_rxon_context_id ctx, |
285 | const char *msg) | ||
253 | { | 286 | { |
254 | trans->ops->wake_any_queue(trans, ctx); | 287 | trans->ops->wake_any_queue(trans, ctx, msg); |
255 | } | 288 | } |
256 | 289 | ||
257 | 290 | ||
@@ -311,9 +344,10 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
311 | trans->ops->free(trans); | 344 | trans->ops->free(trans); |
312 | } | 345 | } |
313 | 346 | ||
314 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q) | 347 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, |
348 | const char *msg) | ||
315 | { | 349 | { |
316 | trans->ops->stop_queue(trans, q); | 350 | trans->ops->stop_queue(trans, q, msg); |
317 | } | 351 | } |
318 | 352 | ||
319 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | 353 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
@@ -348,4 +382,8 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) | |||
348 | ******************************************************/ | 382 | ******************************************************/ |
349 | extern const struct iwl_trans_ops trans_ops_pcie; | 383 | extern const struct iwl_trans_ops trans_ops_pcie; |
350 | 384 | ||
385 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | ||
386 | const void *data, size_t len); | ||
387 | void iwl_dealloc_ucode(struct iwl_trans *trans); | ||
388 | |||
351 | #endif /* __iwl_trans_h__ */ | 389 | #endif /* __iwl_trans_h__ */ |
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index c42be81e979e..48e8218fd23b 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -165,11 +165,15 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
165 | struct key_params *params) | 165 | struct key_params *params) |
166 | { | 166 | { |
167 | struct iwm_priv *iwm = ndev_to_iwm(ndev); | 167 | struct iwm_priv *iwm = ndev_to_iwm(ndev); |
168 | struct iwm_key *key = &iwm->keys[key_index]; | 168 | struct iwm_key *key; |
169 | int ret; | 169 | int ret; |
170 | 170 | ||
171 | IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); | 171 | IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); |
172 | 172 | ||
173 | if (key_index >= IWM_NUM_KEYS) | ||
174 | return -ENOENT; | ||
175 | |||
176 | key = &iwm->keys[key_index]; | ||
173 | memset(key, 0, sizeof(struct iwm_key)); | 177 | memset(key, 0, sizeof(struct iwm_key)); |
174 | ret = iwm_key_init(key, key_index, mac_addr, params); | 178 | ret = iwm_key_init(key, key_index, mac_addr, params); |
175 | if (ret < 0) { | 179 | if (ret < 0) { |
@@ -214,8 +218,12 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
214 | u8 key_index, bool pairwise, const u8 *mac_addr) | 218 | u8 key_index, bool pairwise, const u8 *mac_addr) |
215 | { | 219 | { |
216 | struct iwm_priv *iwm = ndev_to_iwm(ndev); | 220 | struct iwm_priv *iwm = ndev_to_iwm(ndev); |
217 | struct iwm_key *key = &iwm->keys[key_index]; | 221 | struct iwm_key *key; |
218 | 222 | ||
223 | if (key_index >= IWM_NUM_KEYS) | ||
224 | return -ENOENT; | ||
225 | |||
226 | key = &iwm->keys[key_index]; | ||
219 | if (!iwm->keys[key_index].key_len) { | 227 | if (!iwm->keys[key_index].key_len) { |
220 | IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); | 228 | IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); |
221 | return 0; | 229 | return 0; |
@@ -236,6 +244,9 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, | |||
236 | 244 | ||
237 | IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); | 245 | IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); |
238 | 246 | ||
247 | if (key_index >= IWM_NUM_KEYS) | ||
248 | return -ENOENT; | ||
249 | |||
239 | if (!iwm->keys[key_index].key_len) { | 250 | if (!iwm->keys[key_index].key_len) { |
240 | IWM_ERR(iwm, "Key %d not used\n", key_index); | 251 | IWM_ERR(iwm, "Key %d not used\n", key_index); |
241 | return -EINVAL; | 252 | return -EINVAL; |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4fcd653bddc4..89f34ad8d34a 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -485,6 +485,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy, | |||
485 | static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | 485 | static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, |
486 | struct cmd_header *resp) | 486 | struct cmd_header *resp) |
487 | { | 487 | { |
488 | struct cfg80211_bss *bss; | ||
488 | struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; | 489 | struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; |
489 | int bsssize; | 490 | int bsssize; |
490 | const u8 *pos; | 491 | const u8 *pos; |
@@ -632,12 +633,14 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
632 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); | 633 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); |
633 | 634 | ||
634 | if (channel && | 635 | if (channel && |
635 | !(channel->flags & IEEE80211_CHAN_DISABLED)) | 636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { |
636 | cfg80211_inform_bss(wiphy, channel, | 637 | bss = cfg80211_inform_bss(wiphy, channel, |
637 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), | 638 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), |
638 | capa, intvl, ie, ielen, | 639 | capa, intvl, ie, ielen, |
639 | LBS_SCAN_RSSI_TO_MBM(rssi), | 640 | LBS_SCAN_RSSI_TO_MBM(rssi), |
640 | GFP_KERNEL); | 641 | GFP_KERNEL); |
642 | cfg80211_put_bss(bss); | ||
643 | } | ||
641 | } else | 644 | } else |
642 | lbs_deb_scan("scan response: missing BSS channel IE\n"); | 645 | lbs_deb_scan("scan response: missing BSS channel IE\n"); |
643 | 646 | ||
@@ -1720,6 +1723,7 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1720 | 2 + 2 + /* atim */ | 1723 | 2 + 2 + /* atim */ |
1721 | 2 + 8]; /* extended rates */ | 1724 | 2 + 8]; /* extended rates */ |
1722 | u8 *fake = fake_ie; | 1725 | u8 *fake = fake_ie; |
1726 | struct cfg80211_bss *bss; | ||
1723 | 1727 | ||
1724 | lbs_deb_enter(LBS_DEB_CFG80211); | 1728 | lbs_deb_enter(LBS_DEB_CFG80211); |
1725 | 1729 | ||
@@ -1763,14 +1767,15 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1763 | *fake++ = 0x6c; | 1767 | *fake++ = 0x6c; |
1764 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); | 1768 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); |
1765 | 1769 | ||
1766 | cfg80211_inform_bss(priv->wdev->wiphy, | 1770 | bss = cfg80211_inform_bss(priv->wdev->wiphy, |
1767 | params->channel, | 1771 | params->channel, |
1768 | bssid, | 1772 | bssid, |
1769 | 0, | 1773 | 0, |
1770 | capability, | 1774 | capability, |
1771 | params->beacon_interval, | 1775 | params->beacon_interval, |
1772 | fake_ie, fake - fake_ie, | 1776 | fake_ie, fake - fake_ie, |
1773 | 0, GFP_KERNEL); | 1777 | 0, GFP_KERNEL); |
1778 | cfg80211_put_bss(bss); | ||
1774 | 1779 | ||
1775 | memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); | 1780 | memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); |
1776 | priv->wdev->ssid_len = params->ssid_len; | 1781 | priv->wdev->ssid_len = params->ssid_len; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 523ad55a2885..6cf6d6d25e21 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1748,6 +1748,8 @@ static int __init init_mac80211_hwsim(void) | |||
1748 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 1748 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
1749 | IEEE80211_HW_AMPDU_AGGREGATION; | 1749 | IEEE80211_HW_AMPDU_AGGREGATION; |
1750 | 1750 | ||
1751 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | ||
1752 | |||
1751 | /* ask mac80211 to reserve space for magic */ | 1753 | /* ask mac80211 to reserve space for magic */ |
1752 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); | 1754 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); |
1753 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); | 1755 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 7aa9aa0ac958..681d3f2a4c28 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * Since the buffer is linear, the function uses rotation to simulate | 33 | * Since the buffer is linear, the function uses rotation to simulate |
34 | * circular buffer. | 34 | * circular buffer. |
35 | */ | 35 | */ |
36 | static int | 36 | static void |
37 | mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | 37 | mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, |
38 | struct mwifiex_rx_reorder_tbl | 38 | struct mwifiex_rx_reorder_tbl |
39 | *rx_reor_tbl_ptr, int start_win) | 39 | *rx_reor_tbl_ptr, int start_win) |
@@ -71,8 +71,6 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
71 | 71 | ||
72 | rx_reor_tbl_ptr->start_win = start_win; | 72 | rx_reor_tbl_ptr->start_win = start_win; |
73 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 73 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
74 | |||
75 | return 0; | ||
76 | } | 74 | } |
77 | 75 | ||
78 | /* | 76 | /* |
@@ -83,7 +81,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
83 | * Since the buffer is linear, the function uses rotation to simulate | 81 | * Since the buffer is linear, the function uses rotation to simulate |
84 | * circular buffer. | 82 | * circular buffer. |
85 | */ | 83 | */ |
86 | static int | 84 | static void |
87 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | 85 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, |
88 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) | 86 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) |
89 | { | 87 | { |
@@ -119,7 +117,6 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | |||
119 | rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) | 117 | rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) |
120 | &(MAX_TID_VALUE - 1); | 118 | &(MAX_TID_VALUE - 1); |
121 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 119 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
122 | return 0; | ||
123 | } | 120 | } |
124 | 121 | ||
125 | /* | 122 | /* |
@@ -405,7 +402,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
405 | u8 *ta, u8 pkt_type, void *payload) | 402 | u8 *ta, u8 pkt_type, void *payload) |
406 | { | 403 | { |
407 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 404 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; |
408 | int start_win, end_win, win_size, ret; | 405 | int start_win, end_win, win_size; |
409 | u16 pkt_index; | 406 | u16 pkt_index; |
410 | 407 | ||
411 | rx_reor_tbl_ptr = | 408 | rx_reor_tbl_ptr = |
@@ -452,11 +449,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
452 | start_win = (end_win - win_size) + 1; | 449 | start_win = (end_win - win_size) + 1; |
453 | else | 450 | else |
454 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; | 451 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; |
455 | ret = mwifiex_11n_dispatch_pkt_until_start_win(priv, | 452 | mwifiex_11n_dispatch_pkt_until_start_win(priv, |
456 | rx_reor_tbl_ptr, start_win); | 453 | rx_reor_tbl_ptr, start_win); |
457 | |||
458 | if (ret) | ||
459 | return ret; | ||
460 | } | 454 | } |
461 | 455 | ||
462 | if (pkt_type != PKT_TYPE_BAR) { | 456 | if (pkt_type != PKT_TYPE_BAR) { |
@@ -475,9 +469,9 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
475 | * Dispatch all packets sequentially from start_win until a | 469 | * Dispatch all packets sequentially from start_win until a |
476 | * hole is found and adjust the start_win appropriately | 470 | * hole is found and adjust the start_win appropriately |
477 | */ | 471 | */ |
478 | ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); | 472 | mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); |
479 | 473 | ||
480 | return ret; | 474 | return 0; |
481 | } | 475 | } |
482 | 476 | ||
483 | /* | 477 | /* |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 462c71067bfb..e9ab9a3fbe9c 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -780,6 +780,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
780 | { | 780 | { |
781 | struct ieee80211_channel *chan; | 781 | struct ieee80211_channel *chan; |
782 | struct mwifiex_bss_info bss_info; | 782 | struct mwifiex_bss_info bss_info; |
783 | struct cfg80211_bss *bss; | ||
783 | int ie_len; | 784 | int ie_len; |
784 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; | 785 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; |
785 | enum ieee80211_band band; | 786 | enum ieee80211_band band; |
@@ -800,9 +801,10 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
800 | ieee80211_channel_to_frequency(bss_info.bss_chan, | 801 | ieee80211_channel_to_frequency(bss_info.bss_chan, |
801 | band)); | 802 | band)); |
802 | 803 | ||
803 | cfg80211_inform_bss(priv->wdev->wiphy, chan, | 804 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, |
804 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, | 805 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, |
805 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 806 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
807 | cfg80211_put_bss(bss); | ||
806 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); | 808 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); |
807 | 809 | ||
808 | return 0; | 810 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 0cc5d73cb0c1..35cb29cbd96e 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -673,7 +673,7 @@ struct host_cmd_ds_802_11_ad_hoc_start { | |||
673 | union ieee_types_phy_param_set phy_param_set; | 673 | union ieee_types_phy_param_set phy_param_set; |
674 | u16 reserved1; | 674 | u16 reserved1; |
675 | __le16 cap_info_bitmap; | 675 | __le16 cap_info_bitmap; |
676 | u8 DataRate[HOSTCMD_SUPPORTED_RATES]; | 676 | u8 data_rate[HOSTCMD_SUPPORTED_RATES]; |
677 | } __packed; | 677 | } __packed; |
678 | 678 | ||
679 | struct host_cmd_ds_802_11_ad_hoc_result { | 679 | struct host_cmd_ds_802_11_ad_hoc_result { |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index d792b3fb7c16..26940455255b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -187,8 +187,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
187 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL; | 187 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL; |
188 | 188 | ||
189 | skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm)); | 189 | skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm)); |
190 | sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) | ||
191 | (adapter->sleep_cfm->data); | ||
192 | 190 | ||
193 | adapter->cmd_sent = false; | 191 | adapter->cmd_sent = false; |
194 | 192 | ||
@@ -254,6 +252,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
254 | mwifiex_wmm_init(adapter); | 252 | mwifiex_wmm_init(adapter); |
255 | 253 | ||
256 | if (adapter->sleep_cfm) { | 254 | if (adapter->sleep_cfm) { |
255 | sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) | ||
256 | adapter->sleep_cfm->data; | ||
257 | memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); | 257 | memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); |
258 | sleep_cfm_buf->command = | 258 | sleep_cfm_buf->command = |
259 | cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); | 259 | cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 62b4c2938608..1c4981367e50 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -724,8 +724,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
724 | u32 cmd_append_size = 0; | 724 | u32 cmd_append_size = 0; |
725 | u32 i; | 725 | u32 i; |
726 | u16 tmp_cap; | 726 | u16 tmp_cap; |
727 | uint16_t ht_cap_info; | ||
728 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; | 727 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; |
728 | u8 radio_type; | ||
729 | 729 | ||
730 | struct mwifiex_ie_types_htcap *ht_cap; | 730 | struct mwifiex_ie_types_htcap *ht_cap; |
731 | struct mwifiex_ie_types_htinfo *ht_info; | 731 | struct mwifiex_ie_types_htinfo *ht_info; |
@@ -837,8 +837,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
837 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; | 837 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; |
838 | } | 838 | } |
839 | 839 | ||
840 | memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate)); | 840 | memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate)); |
841 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); | 841 | mwifiex_get_active_data_rates(priv, adhoc_start->data_rate); |
842 | if ((adapter->adhoc_start_band & BAND_G) && | 842 | if ((adapter->adhoc_start_band & BAND_G) && |
843 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { | 843 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { |
844 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, | 844 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
@@ -850,20 +850,19 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
850 | } | 850 | } |
851 | } | 851 | } |
852 | /* Find the last non zero */ | 852 | /* Find the last non zero */ |
853 | for (i = 0; i < sizeof(adhoc_start->DataRate) && | 853 | for (i = 0; i < sizeof(adhoc_start->data_rate); i++) |
854 | adhoc_start->DataRate[i]; | 854 | if (!adhoc_start->data_rate[i]) |
855 | i++) | 855 | break; |
856 | ; | ||
857 | 856 | ||
858 | priv->curr_bss_params.num_of_rates = i; | 857 | priv->curr_bss_params.num_of_rates = i; |
859 | 858 | ||
860 | /* Copy the ad-hoc creating rates into Current BSS rate structure */ | 859 | /* Copy the ad-hoc creating rates into Current BSS rate structure */ |
861 | memcpy(&priv->curr_bss_params.data_rates, | 860 | memcpy(&priv->curr_bss_params.data_rates, |
862 | &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates); | 861 | &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); |
863 | 862 | ||
864 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", | 863 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", |
865 | adhoc_start->DataRate[0], adhoc_start->DataRate[1], | 864 | adhoc_start->data_rate[0], adhoc_start->data_rate[1], |
866 | adhoc_start->DataRate[2], adhoc_start->DataRate[3]); | 865 | adhoc_start->data_rate[2], adhoc_start->data_rate[3]); |
867 | 866 | ||
868 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); | 867 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); |
869 | 868 | ||
@@ -914,55 +913,40 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
914 | } | 913 | } |
915 | 914 | ||
916 | if (adapter->adhoc_11n_enabled) { | 915 | if (adapter->adhoc_11n_enabled) { |
917 | { | 916 | /* Fill HT CAPABILITY */ |
918 | ht_cap = (struct mwifiex_ie_types_htcap *) pos; | 917 | ht_cap = (struct mwifiex_ie_types_htcap *) pos; |
919 | memset(ht_cap, 0, | 918 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); |
920 | sizeof(struct mwifiex_ie_types_htcap)); | 919 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); |
921 | ht_cap->header.type = | 920 | ht_cap->header.len = |
922 | cpu_to_le16(WLAN_EID_HT_CAPABILITY); | 921 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); |
923 | ht_cap->header.len = | 922 | radio_type = mwifiex_band_to_radio_type( |
924 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | 923 | priv->adapter->config_bands); |
925 | ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); | 924 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
926 | 925 | ||
927 | ht_cap_info |= IEEE80211_HT_CAP_SGI_20; | 926 | pos += sizeof(struct mwifiex_ie_types_htcap); |
928 | if (adapter->chan_offset) { | 927 | cmd_append_size += |
929 | ht_cap_info |= IEEE80211_HT_CAP_SGI_40; | 928 | sizeof(struct mwifiex_ie_types_htcap); |
930 | ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40; | ||
931 | ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
932 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | ||
933 | } | ||
934 | 929 | ||
935 | ht_cap->ht_cap.ampdu_params_info | 930 | /* Fill HT INFORMATION */ |
936 | = IEEE80211_HT_MAX_AMPDU_64K; | 931 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; |
937 | ht_cap->ht_cap.mcs.rx_mask[0] = 0xff; | 932 | memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); |
938 | pos += sizeof(struct mwifiex_ie_types_htcap); | 933 | ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); |
939 | cmd_append_size += | 934 | ht_info->header.len = |
940 | sizeof(struct mwifiex_ie_types_htcap); | 935 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); |
941 | } | 936 | |
942 | { | 937 | ht_info->ht_info.control_chan = |
943 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; | 938 | (u8) priv->curr_bss_params.bss_descriptor.channel; |
944 | memset(ht_info, 0, | 939 | if (adapter->chan_offset) { |
945 | sizeof(struct mwifiex_ie_types_htinfo)); | 940 | ht_info->ht_info.ht_param = adapter->chan_offset; |
946 | ht_info->header.type = | 941 | ht_info->ht_info.ht_param |= |
947 | cpu_to_le16(WLAN_EID_HT_INFORMATION); | ||
948 | ht_info->header.len = | ||
949 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); | ||
950 | ht_info->ht_info.control_chan = | ||
951 | (u8) priv->curr_bss_params.bss_descriptor. | ||
952 | channel; | ||
953 | if (adapter->chan_offset) { | ||
954 | ht_info->ht_info.ht_param = | ||
955 | adapter->chan_offset; | ||
956 | ht_info->ht_info.ht_param |= | ||
957 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | 942 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; |
958 | } | ||
959 | ht_info->ht_info.operation_mode = | ||
960 | cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
961 | ht_info->ht_info.basic_set[0] = 0xff; | ||
962 | pos += sizeof(struct mwifiex_ie_types_htinfo); | ||
963 | cmd_append_size += | ||
964 | sizeof(struct mwifiex_ie_types_htinfo); | ||
965 | } | 943 | } |
944 | ht_info->ht_info.operation_mode = | ||
945 | cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
946 | ht_info->ht_info.basic_set[0] = 0xff; | ||
947 | pos += sizeof(struct mwifiex_ie_types_htinfo); | ||
948 | cmd_append_size += | ||
949 | sizeof(struct mwifiex_ie_types_htinfo); | ||
966 | } | 950 | } |
967 | 951 | ||
968 | cmd->size = cpu_to_le16((u16) | 952 | cmd->size = cpu_to_le16((u16) |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index d34acf082d3a..a2f32008f9a8 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -386,7 +386,6 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); | 386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); |
387 | if (!card->txbd_ring_vbase) { | 387 | if (!card->txbd_ring_vbase) { |
388 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); | 388 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); |
389 | kfree(card->txbd_ring_vbase); | ||
390 | return -1; | 389 | return -1; |
391 | } | 390 | } |
392 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); | 391 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); |
@@ -1229,9 +1228,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1229 | if (!skb) | 1228 | if (!skb) |
1230 | return 0; | 1229 | return 0; |
1231 | 1230 | ||
1232 | if (rdptr >= MWIFIEX_MAX_EVT_BD) | 1231 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { |
1233 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", | 1232 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", |
1234 | rdptr); | 1233 | rdptr); |
1234 | ret = -EINVAL; | ||
1235 | goto done; | ||
1236 | } | ||
1235 | 1237 | ||
1236 | /* Read the event ring write pointer set by firmware */ | 1238 | /* Read the event ring write pointer set by firmware */ |
1237 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1239 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
@@ -1672,9 +1674,8 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type, | |||
1672 | struct sk_buff *skb, | 1674 | struct sk_buff *skb, |
1673 | struct mwifiex_tx_param *tx_param) | 1675 | struct mwifiex_tx_param *tx_param) |
1674 | { | 1676 | { |
1675 | if (!adapter || !skb) { | 1677 | if (!skb) { |
1676 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %p>\n", | 1678 | dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__); |
1677 | __func__, adapter, skb); | ||
1678 | return -1; | 1679 | return -1; |
1679 | } | 1680 | } |
1680 | 1681 | ||
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index dae8dbb24a03..8a18bcc23b26 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1469,7 +1469,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, | |||
1469 | s32 rssi, const u8 *ie_buf, size_t ie_len, | 1469 | s32 rssi, const u8 *ie_buf, size_t ie_len, |
1470 | u16 beacon_period, u16 cap_info_bitmap, u8 band) | 1470 | u16 beacon_period, u16 cap_info_bitmap, u8 band) |
1471 | { | 1471 | { |
1472 | struct mwifiex_bssdescriptor *bss_desc = NULL; | 1472 | struct mwifiex_bssdescriptor *bss_desc; |
1473 | int ret; | 1473 | int ret; |
1474 | unsigned long flags; | 1474 | unsigned long flags; |
1475 | u8 *beacon_ie; | 1475 | u8 *beacon_ie; |
@@ -1484,6 +1484,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, | |||
1484 | 1484 | ||
1485 | beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); | 1485 | beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); |
1486 | if (!beacon_ie) { | 1486 | if (!beacon_ie) { |
1487 | kfree(bss_desc); | ||
1487 | dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); | 1488 | dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); |
1488 | return -ENOMEM; | 1489 | return -ENOMEM; |
1489 | } | 1490 | } |
@@ -1534,11 +1535,6 @@ done: | |||
1534 | return 0; | 1535 | return 0; |
1535 | } | 1536 | } |
1536 | 1537 | ||
1537 | static void mwifiex_free_bss_priv(struct cfg80211_bss *bss) | ||
1538 | { | ||
1539 | kfree(bss->priv); | ||
1540 | } | ||
1541 | |||
1542 | /* | 1538 | /* |
1543 | * This function handles the command response of scan. | 1539 | * This function handles the command response of scan. |
1544 | * | 1540 | * |
@@ -1764,7 +1760,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1764 | cap_info_bitmap, beacon_period, | 1760 | cap_info_bitmap, beacon_period, |
1765 | ie_buf, ie_len, rssi, GFP_KERNEL); | 1761 | ie_buf, ie_len, rssi, GFP_KERNEL); |
1766 | *(u8 *)bss->priv = band; | 1762 | *(u8 *)bss->priv = band; |
1767 | bss->free_priv = mwifiex_free_bss_priv; | 1763 | cfg80211_put_bss(bss); |
1768 | 1764 | ||
1769 | if (priv->media_connected && !memcmp(bssid, | 1765 | if (priv->media_connected && !memcmp(bssid, |
1770 | priv->curr_bss_params.bss_descriptor | 1766 | priv->curr_bss_params.bss_descriptor |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 283171bbcedf..ffaf3f3a57df 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -1630,14 +1630,14 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) | |||
1630 | card->mpa_tx.pkt_cnt = 0; | 1630 | card->mpa_tx.pkt_cnt = 0; |
1631 | card->mpa_tx.start_port = 0; | 1631 | card->mpa_tx.start_port = 0; |
1632 | 1632 | ||
1633 | card->mpa_tx.enabled = 0; | 1633 | card->mpa_tx.enabled = 1; |
1634 | card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; | 1634 | card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; |
1635 | 1635 | ||
1636 | card->mpa_rx.buf_len = 0; | 1636 | card->mpa_rx.buf_len = 0; |
1637 | card->mpa_rx.pkt_cnt = 0; | 1637 | card->mpa_rx.pkt_cnt = 0; |
1638 | card->mpa_rx.start_port = 0; | 1638 | card->mpa_rx.start_port = 0; |
1639 | 1639 | ||
1640 | card->mpa_rx.enabled = 0; | 1640 | card->mpa_rx.enabled = 1; |
1641 | card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; | 1641 | card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; |
1642 | 1642 | ||
1643 | /* Allocate buffers for SDIO MP-A */ | 1643 | /* Allocate buffers for SDIO MP-A */ |
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 27430512f7cd..5e1ef7e5da4f 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c | |||
@@ -126,6 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
126 | u16 rx_pkt_type; | 126 | u16 rx_pkt_type; |
127 | struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; | 127 | struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; |
128 | 128 | ||
129 | if (!priv) | ||
130 | return -1; | ||
131 | |||
129 | local_rx_pd = (struct rxpd *) (skb->data); | 132 | local_rx_pd = (struct rxpd *) (skb->data); |
130 | rx_pkt_type = local_rx_pd->rx_pkt_type; | 133 | rx_pkt_type = local_rx_pd->rx_pkt_type; |
131 | 134 | ||
@@ -189,12 +192,11 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
189 | (u8) local_rx_pd->rx_pkt_type, | 192 | (u8) local_rx_pd->rx_pkt_type, |
190 | skb); | 193 | skb); |
191 | 194 | ||
192 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { | 195 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) |
193 | if (priv && (ret == -1)) | ||
194 | priv->stats.rx_dropped++; | ||
195 | |||
196 | dev_kfree_skb_any(skb); | 196 | dev_kfree_skb_any(skb); |
197 | } | 197 | |
198 | if (ret) | ||
199 | priv->stats.rx_dropped++; | ||
198 | 200 | ||
199 | return ret; | 201 | return ret; |
200 | } | 202 | } |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index e99ca1c1e0d8..96e39edfec77 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
@@ -76,6 +76,7 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, | |||
76 | { | 76 | { |
77 | struct wiphy *wiphy = priv_to_wiphy(priv); | 77 | struct wiphy *wiphy = priv_to_wiphy(priv); |
78 | struct ieee80211_channel *channel; | 78 | struct ieee80211_channel *channel; |
79 | struct cfg80211_bss *cbss; | ||
79 | u8 *ie; | 80 | u8 *ie; |
80 | u8 ie_buf[46]; | 81 | u8 ie_buf[46]; |
81 | u64 timestamp; | 82 | u64 timestamp; |
@@ -121,9 +122,10 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, | |||
121 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); | 122 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); |
122 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); | 123 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); |
123 | 124 | ||
124 | cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, | 125 | cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, |
125 | capability, beacon_interval, ie_buf, ie_len, | 126 | capability, beacon_interval, ie_buf, ie_len, |
126 | signal, GFP_KERNEL); | 127 | signal, GFP_KERNEL); |
128 | cfg80211_put_bss(cbss); | ||
127 | } | 129 | } |
128 | 130 | ||
129 | void orinoco_add_extscan_result(struct orinoco_private *priv, | 131 | void orinoco_add_extscan_result(struct orinoco_private *priv, |
@@ -132,6 +134,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
132 | { | 134 | { |
133 | struct wiphy *wiphy = priv_to_wiphy(priv); | 135 | struct wiphy *wiphy = priv_to_wiphy(priv); |
134 | struct ieee80211_channel *channel; | 136 | struct ieee80211_channel *channel; |
137 | struct cfg80211_bss *cbss; | ||
135 | const u8 *ie; | 138 | const u8 *ie; |
136 | u64 timestamp; | 139 | u64 timestamp; |
137 | s32 signal; | 140 | s32 signal; |
@@ -152,9 +155,10 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
152 | ie = bss->data; | 155 | ie = bss->data; |
153 | signal = SIGNAL_TO_MBM(bss->level); | 156 | signal = SIGNAL_TO_MBM(bss->level); |
154 | 157 | ||
155 | cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, | 158 | cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, |
156 | capability, beacon_interval, ie, ie_len, | 159 | capability, beacon_interval, ie, ie_len, |
157 | signal, GFP_KERNEL); | 160 | signal, GFP_KERNEL); |
161 | cfg80211_put_bss(cbss); | ||
158 | } | 162 | } |
159 | 163 | ||
160 | void orinoco_add_hostscan_results(struct orinoco_private *priv, | 164 | void orinoco_add_hostscan_results(struct orinoco_private *priv, |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0c13840a7de5..620e3c0e88e0 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -414,6 +414,7 @@ struct ndis_80211_pmkid { | |||
414 | #define RNDIS_WLAN_ALG_TKIP (1<<1) | 414 | #define RNDIS_WLAN_ALG_TKIP (1<<1) |
415 | #define RNDIS_WLAN_ALG_CCMP (1<<2) | 415 | #define RNDIS_WLAN_ALG_CCMP (1<<2) |
416 | 416 | ||
417 | #define RNDIS_WLAN_NUM_KEYS 4 | ||
417 | #define RNDIS_WLAN_KEY_MGMT_NONE 0 | 418 | #define RNDIS_WLAN_KEY_MGMT_NONE 0 |
418 | #define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0) | 419 | #define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0) |
419 | #define RNDIS_WLAN_KEY_MGMT_PSK (1<<1) | 420 | #define RNDIS_WLAN_KEY_MGMT_PSK (1<<1) |
@@ -516,7 +517,7 @@ struct rndis_wlan_private { | |||
516 | 517 | ||
517 | /* encryption stuff */ | 518 | /* encryption stuff */ |
518 | int encr_tx_key_index; | 519 | int encr_tx_key_index; |
519 | struct rndis_wlan_encr_key encr_keys[4]; | 520 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; |
520 | int wpa_version; | 521 | int wpa_version; |
521 | 522 | ||
522 | u8 command_buffer[COMMAND_BUFFER_SIZE]; | 523 | u8 command_buffer[COMMAND_BUFFER_SIZE]; |
@@ -1535,6 +1536,9 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) | |||
1535 | bool is_wpa; | 1536 | bool is_wpa; |
1536 | int ret; | 1537 | int ret; |
1537 | 1538 | ||
1539 | if (index >= RNDIS_WLAN_NUM_KEYS) | ||
1540 | return -ENOENT; | ||
1541 | |||
1538 | if (priv->encr_keys[index].len == 0) | 1542 | if (priv->encr_keys[index].len == 0) |
1539 | return 0; | 1543 | return 0; |
1540 | 1544 | ||
@@ -1972,11 +1976,12 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1972 | return ret; | 1976 | return ret; |
1973 | } | 1977 | } |
1974 | 1978 | ||
1975 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | 1979 | static bool rndis_bss_info_update(struct usbnet *usbdev, |
1976 | struct ndis_80211_bssid_ex *bssid) | 1980 | struct ndis_80211_bssid_ex *bssid) |
1977 | { | 1981 | { |
1978 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1982 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1979 | struct ieee80211_channel *channel; | 1983 | struct ieee80211_channel *channel; |
1984 | struct cfg80211_bss *bss; | ||
1980 | s32 signal; | 1985 | s32 signal; |
1981 | u64 timestamp; | 1986 | u64 timestamp; |
1982 | u16 capability; | 1987 | u16 capability; |
@@ -2015,9 +2020,12 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | |||
2015 | capability = le16_to_cpu(fixed->capabilities); | 2020 | capability = le16_to_cpu(fixed->capabilities); |
2016 | beacon_interval = le16_to_cpu(fixed->beacon_interval); | 2021 | beacon_interval = le16_to_cpu(fixed->beacon_interval); |
2017 | 2022 | ||
2018 | return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, | 2023 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, |
2019 | timestamp, capability, beacon_interval, ie, ie_len, signal, | 2024 | timestamp, capability, beacon_interval, ie, ie_len, signal, |
2020 | GFP_KERNEL); | 2025 | GFP_KERNEL); |
2026 | cfg80211_put_bss(bss); | ||
2027 | |||
2028 | return (bss != NULL); | ||
2021 | } | 2029 | } |
2022 | 2030 | ||
2023 | static struct ndis_80211_bssid_ex *next_bssid_list_item( | 2031 | static struct ndis_80211_bssid_ex *next_bssid_list_item( |
@@ -2451,6 +2459,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | |||
2451 | 2459 | ||
2452 | netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index); | 2460 | netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index); |
2453 | 2461 | ||
2462 | if (key_index >= RNDIS_WLAN_NUM_KEYS) | ||
2463 | return -ENOENT; | ||
2464 | |||
2454 | priv->encr_tx_key_index = key_index; | 2465 | priv->encr_tx_key_index = key_index; |
2455 | 2466 | ||
2456 | if (is_wpa_key(priv, key_index)) | 2467 | if (is_wpa_key(priv, key_index)) |
@@ -2641,6 +2652,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2641 | struct ieee80211_channel *channel; | 2652 | struct ieee80211_channel *channel; |
2642 | struct ndis_80211_conf config; | 2653 | struct ndis_80211_conf config; |
2643 | struct ndis_80211_ssid ssid; | 2654 | struct ndis_80211_ssid ssid; |
2655 | struct cfg80211_bss *bss; | ||
2644 | s32 signal; | 2656 | s32 signal; |
2645 | u64 timestamp; | 2657 | u64 timestamp; |
2646 | u16 capability; | 2658 | u16 capability; |
@@ -2714,9 +2726,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2714 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, | 2726 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, |
2715 | ssid.essid, signal); | 2727 | ssid.essid, signal); |
2716 | 2728 | ||
2717 | cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, | 2729 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, |
2718 | timestamp, capability, beacon_interval, ie_buf, ie_len, | 2730 | timestamp, capability, beacon_interval, ie_buf, ie_len, |
2719 | signal, GFP_KERNEL); | 2731 | signal, GFP_KERNEL); |
2732 | cfg80211_put_bss(bss); | ||
2720 | } | 2733 | } |
2721 | 2734 | ||
2722 | /* | 2735 | /* |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index c244f2f1b83f..94a3e1706158 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -275,6 +275,8 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
275 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, | 275 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, |
276 | 276 | ||
277 | /****** 8188CU ********/ | 277 | /****** 8188CU ********/ |
278 | /* RTL8188CTV */ | ||
279 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x018a, rtl92cu_hal_cfg)}, | ||
278 | /* 8188CE-VAU USB minCard */ | 280 | /* 8188CE-VAU USB minCard */ |
279 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, | 281 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, |
280 | /* 8188cu 1*1 dongle */ | 282 | /* 8188cu 1*1 dongle */ |
@@ -291,14 +293,14 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
291 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, | 293 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, |
292 | /* 8188RU in Alfa AWUS036NHR */ | 294 | /* 8188RU in Alfa AWUS036NHR */ |
293 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, | 295 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, |
296 | /* RTL8188CUS-VL */ | ||
297 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, | ||
294 | /* 8188 Combo for BC4 */ | 298 | /* 8188 Combo for BC4 */ |
295 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, | 299 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, |
296 | 300 | ||
297 | /****** 8192CU ********/ | 301 | /****** 8192CU ********/ |
298 | /* 8191cu 1*2 */ | ||
299 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, | ||
300 | /* 8192cu 2*2 */ | 302 | /* 8192cu 2*2 */ |
301 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, | 303 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8178, rtl92cu_hal_cfg)}, |
302 | /* 8192CE-VAU USB minCard */ | 304 | /* 8192CE-VAU USB minCard */ |
303 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, | 305 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, |
304 | 306 | ||
@@ -309,13 +311,17 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
309 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 311 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
310 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 312 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
311 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ | 313 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ |
312 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 314 | {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
315 | {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | ||
313 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | 316 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ |
314 | /* HP - Lite-On ,8188CUS Slim Combo */ | 317 | /* HP - Lite-On ,8188CUS Slim Combo */ |
315 | {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, | 318 | {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, |
316 | {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ | 319 | {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ |
317 | {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ | 320 | {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ |
321 | {RTL_USB_DEVICE(0x2019, 0x4902, rtl92cu_hal_cfg)}, /*Planex - Etop*/ | ||
318 | {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ | 322 | {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ |
323 | /*SW-WF02-AD15 -Abocom*/ | ||
324 | {RTL_USB_DEVICE(0x2019, 0xab2e, rtl92cu_hal_cfg)}, | ||
319 | {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ | 325 | {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ |
320 | {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ | 326 | {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ |
321 | {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ | 327 | {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ |
@@ -326,14 +332,36 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
326 | {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ | 332 | {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ |
327 | {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ | 333 | {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ |
328 | 334 | ||
335 | /****** 8188 RU ********/ | ||
336 | /* Netcore */ | ||
337 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x317f, rtl92cu_hal_cfg)}, | ||
338 | |||
339 | /****** 8188CUS Slim Solo********/ | ||
340 | {RTL_USB_DEVICE(0x04f2, 0xaff7, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
341 | {RTL_USB_DEVICE(0x04f2, 0xaff9, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
342 | {RTL_USB_DEVICE(0x04f2, 0xaffa, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
343 | |||
344 | /****** 8188CUS Slim Combo ********/ | ||
345 | {RTL_USB_DEVICE(0x04f2, 0xaff8, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
346 | {RTL_USB_DEVICE(0x04f2, 0xaffb, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
347 | {RTL_USB_DEVICE(0x04f2, 0xaffc, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
348 | {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/ | ||
349 | |||
329 | /****** 8192CU ********/ | 350 | /****** 8192CU ********/ |
351 | {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/ | ||
352 | {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/ | ||
330 | {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ | 353 | {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ |
331 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ | 354 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ |
332 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ | 355 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ |
356 | {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ | ||
357 | {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ | ||
358 | {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ | ||
359 | {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ | ||
333 | {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ | 360 | {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ |
334 | {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | 361 | {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ |
335 | {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | 362 | {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ |
336 | {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ | 363 | {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ |
364 | {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ | ||
337 | {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ | 365 | {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ |
338 | {} | 366 | {} |
339 | }; | 367 | }; |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 128ccb79318c..fc29c671cf3b 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, | |||
559 | break; | 559 | break; |
560 | } | 560 | } |
561 | /* Fail if SSID isn't present in the filters */ | 561 | /* Fail if SSID isn't present in the filters */ |
562 | if (j == req->n_ssids) { | 562 | if (j == cmd->n_ssids) { |
563 | ret = -EINVAL; | 563 | ret = -EINVAL; |
564 | goto out_free; | 564 | goto out_free; |
565 | } | 565 | } |