aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c4
-rw-r--r--drivers/bcma/host_pci.c11
-rw-r--r--drivers/bcma/host_soc.c2
-rw-r--r--drivers/bluetooth/bcm203x.c8
-rw-r--r--drivers/bluetooth/bfusb.c12
-rw-r--r--drivers/bluetooth/bluecard_cs.c5
-rw-r--r--drivers/bluetooth/bpa10x.c8
-rw-r--r--drivers/bluetooth/bt3c_cs.c5
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c15
-rw-r--r--drivers/bluetooth/btsdio.c8
-rw-r--r--drivers/bluetooth/btuart_cs.c5
-rw-r--r--drivers/bluetooth/btusb.c13
-rw-r--r--drivers/bluetooth/btwilink.c8
-rw-r--r--drivers/bluetooth/dtl1_cs.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c149
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c812
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h4
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c1
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c4
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c1
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h10
-rw-r--r--drivers/net/wireless/b43/main.c51
-rw-r--r--drivers/net/wireless/b43/phy_common.c17
-rw-r--r--drivers/net/wireless/b43/phy_common.h6
-rw-r--r--drivers/net/wireless/b43/phy_n.c668
-rw-r--r--drivers/net/wireless/b43/phy_n.h1
-rw-r--r--drivers/net/wireless/b43/radio_2057.c141
-rw-r--r--drivers/net/wireless/b43/radio_2057.h430
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c75
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h10
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c13
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h5
-rw-r--r--drivers/net/wireless/iwlegacy/common.c15
-rw-r--r--drivers/net/wireless/iwlegacy/common.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c26
-rw-r--r--drivers/net/wireless/mwifiex/11n.h15
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c14
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c66
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h5
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c17
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c5
-rw-r--r--drivers/net/wireless/mwifiex/decl.h3
-rw-r--r--drivers/net/wireless/mwifiex/fw.h42
-rw-r--r--drivers/net/wireless/mwifiex/init.c107
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h5
-rw-r--r--drivers/net/wireless/mwifiex/main.c3
-rw-r--r--drivers/net/wireless/mwifiex/main.h38
-rw-r--r--drivers/net/wireless/mwifiex/scan.c6
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c55
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c64
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c12
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c38
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c5
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c1
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c290
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c255
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c59
-rw-r--r--drivers/net/wireless/p54/eeprom.c108
-rw-r--r--drivers/net/wireless/p54/eeprom.h12
-rw-r--r--drivers/net/wireless/p54/p54pci.c88
-rw-r--r--drivers/net/wireless/p54/p54pci.h1
-rw-r--r--drivers/ssb/driver_mipscore.c28
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h85
-rw-r--r--include/linux/bcma/bcma_regs.h2
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h4
-rw-r--r--include/net/bluetooth/bluetooth.h10
-rw-r--r--include/net/bluetooth/hci.h11
-rw-r--r--include/net/bluetooth/hci_core.h22
-rw-r--r--include/net/bluetooth/l2cap.h17
-rw-r--r--include/net/bluetooth/smp.h8
-rw-r--r--net/bluetooth/a2mp.c16
-rw-r--r--net/bluetooth/af_bluetooth.c141
-rw-r--r--net/bluetooth/bnep/sock.c22
-rw-r--r--net/bluetooth/cmtp/sock.c23
-rw-r--r--net/bluetooth/hci_core.c6
-rw-r--r--net/bluetooth/hci_event.c93
-rw-r--r--net/bluetooth/hci_sock.c13
-rw-r--r--net/bluetooth/hidp/sock.c22
-rw-r--r--net/bluetooth/l2cap_core.c32
-rw-r--r--net/bluetooth/l2cap_sock.c22
-rw-r--r--net/bluetooth/mgmt.c34
-rw-r--r--net/bluetooth/rfcomm/sock.c14
-rw-r--r--net/bluetooth/sco.c16
-rw-r--r--net/mac80211/mesh.c21
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_plink.c44
95 files changed, 3509 insertions, 1126 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index c9a4f46c5143..8b8f2f3862a2 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -101,7 +101,7 @@ void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
101 bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val); 101 bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
102} 102}
103 103
104void bcma_pmu_workarounds(struct bcma_drv_cc *cc) 104static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
105{ 105{
106 struct bcma_bus *bus = cc->core->bus; 106 struct bcma_bus *bus = cc->core->bus;
107 107
@@ -257,7 +257,7 @@ static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
257} 257}
258 258
259/* query bus clock frequency for PMU-enabled chipcommon */ 259/* query bus clock frequency for PMU-enabled chipcommon */
260u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc) 260static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
261{ 261{
262 struct bcma_bus *bus = cc->core->bus; 262 struct bcma_bus *bus = cc->core->bus;
263 263
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index a6e5672c67e7..f7b0af7100cd 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -77,8 +77,8 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
77} 77}
78 78
79#ifdef CONFIG_BCMA_BLOCKIO 79#ifdef CONFIG_BCMA_BLOCKIO
80void bcma_host_pci_block_read(struct bcma_device *core, void *buffer, 80static void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
81 size_t count, u16 offset, u8 reg_width) 81 size_t count, u16 offset, u8 reg_width)
82{ 82{
83 void __iomem *addr = core->bus->mmio + offset; 83 void __iomem *addr = core->bus->mmio + offset;
84 if (core->bus->mapped_core != core) 84 if (core->bus->mapped_core != core)
@@ -100,8 +100,9 @@ void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
100 } 100 }
101} 101}
102 102
103void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer, 103static void bcma_host_pci_block_write(struct bcma_device *core,
104 size_t count, u16 offset, u8 reg_width) 104 const void *buffer, size_t count,
105 u16 offset, u8 reg_width)
105{ 106{
106 void __iomem *addr = core->bus->mmio + offset; 107 void __iomem *addr = core->bus->mmio + offset;
107 if (core->bus->mapped_core != core) 108 if (core->bus->mapped_core != core)
@@ -139,7 +140,7 @@ static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
139 iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); 140 iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
140} 141}
141 142
142const struct bcma_host_ops bcma_host_pci_ops = { 143static const struct bcma_host_ops bcma_host_pci_ops = {
143 .read8 = bcma_host_pci_read8, 144 .read8 = bcma_host_pci_read8,
144 .read16 = bcma_host_pci_read16, 145 .read16 = bcma_host_pci_read16,
145 .read32 = bcma_host_pci_read32, 146 .read32 = bcma_host_pci_read32,
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
index 3c381fb8f9c4..3475e600011a 100644
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -143,7 +143,7 @@ static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
143 writel(value, core->io_wrap + offset); 143 writel(value, core->io_wrap + offset);
144} 144}
145 145
146const struct bcma_host_ops bcma_host_soc_ops = { 146static const struct bcma_host_ops bcma_host_soc_ops = {
147 .read8 = bcma_host_soc_read8, 147 .read8 = bcma_host_soc_read8,
148 .read16 = bcma_host_soc_read16, 148 .read16 = bcma_host_soc_read16,
149 .read32 = bcma_host_soc_read32, 149 .read32 = bcma_host_soc_read32,
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 37ae175162f3..364f82b34d03 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -177,7 +177,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
177 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 177 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
178 return -ENODEV; 178 return -ENODEV;
179 179
180 data = kzalloc(sizeof(*data), GFP_KERNEL); 180 data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
181 if (!data) { 181 if (!data) {
182 BT_ERR("Can't allocate memory for data structure"); 182 BT_ERR("Can't allocate memory for data structure");
183 return -ENOMEM; 183 return -ENOMEM;
@@ -189,14 +189,12 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
189 data->urb = usb_alloc_urb(0, GFP_KERNEL); 189 data->urb = usb_alloc_urb(0, GFP_KERNEL);
190 if (!data->urb) { 190 if (!data->urb) {
191 BT_ERR("Can't allocate URB"); 191 BT_ERR("Can't allocate URB");
192 kfree(data);
193 return -ENOMEM; 192 return -ENOMEM;
194 } 193 }
195 194
196 if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { 195 if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
197 BT_ERR("Mini driver request failed"); 196 BT_ERR("Mini driver request failed");
198 usb_free_urb(data->urb); 197 usb_free_urb(data->urb);
199 kfree(data);
200 return -EIO; 198 return -EIO;
201 } 199 }
202 200
@@ -209,7 +207,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
209 BT_ERR("Can't allocate memory for mini driver"); 207 BT_ERR("Can't allocate memory for mini driver");
210 release_firmware(firmware); 208 release_firmware(firmware);
211 usb_free_urb(data->urb); 209 usb_free_urb(data->urb);
212 kfree(data);
213 return -ENOMEM; 210 return -ENOMEM;
214 } 211 }
215 212
@@ -224,7 +221,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
224 BT_ERR("Firmware request failed"); 221 BT_ERR("Firmware request failed");
225 usb_free_urb(data->urb); 222 usb_free_urb(data->urb);
226 kfree(data->buffer); 223 kfree(data->buffer);
227 kfree(data);
228 return -EIO; 224 return -EIO;
229 } 225 }
230 226
@@ -236,7 +232,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
236 release_firmware(firmware); 232 release_firmware(firmware);
237 usb_free_urb(data->urb); 233 usb_free_urb(data->urb);
238 kfree(data->buffer); 234 kfree(data->buffer);
239 kfree(data);
240 return -ENOMEM; 235 return -ENOMEM;
241 } 236 }
242 237
@@ -271,7 +266,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
271 usb_free_urb(data->urb); 266 usb_free_urb(data->urb);
272 kfree(data->fw_data); 267 kfree(data->fw_data);
273 kfree(data->buffer); 268 kfree(data->buffer);
274 kfree(data);
275} 269}
276 270
277static struct usb_driver bcm203x_driver = { 271static struct usb_driver bcm203x_driver = {
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 32e825144fe9..995aee9cba22 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -653,7 +653,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
653 } 653 }
654 654
655 /* Initialize control structure and load firmware */ 655 /* Initialize control structure and load firmware */
656 data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL); 656 data = devm_kzalloc(&intf->dev, sizeof(struct bfusb_data), GFP_KERNEL);
657 if (!data) { 657 if (!data) {
658 BT_ERR("Can't allocate memory for control structure"); 658 BT_ERR("Can't allocate memory for control structure");
659 goto done; 659 goto done;
@@ -674,7 +674,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
674 674
675 if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { 675 if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
676 BT_ERR("Firmware request failed"); 676 BT_ERR("Firmware request failed");
677 goto error; 677 goto done;
678 } 678 }
679 679
680 BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); 680 BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
@@ -690,7 +690,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
690 hdev = hci_alloc_dev(); 690 hdev = hci_alloc_dev();
691 if (!hdev) { 691 if (!hdev) {
692 BT_ERR("Can't allocate HCI device"); 692 BT_ERR("Can't allocate HCI device");
693 goto error; 693 goto done;
694 } 694 }
695 695
696 data->hdev = hdev; 696 data->hdev = hdev;
@@ -708,7 +708,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
708 if (hci_register_dev(hdev) < 0) { 708 if (hci_register_dev(hdev) < 0) {
709 BT_ERR("Can't register HCI device"); 709 BT_ERR("Can't register HCI device");
710 hci_free_dev(hdev); 710 hci_free_dev(hdev);
711 goto error; 711 goto done;
712 } 712 }
713 713
714 usb_set_intfdata(intf, data); 714 usb_set_intfdata(intf, data);
@@ -718,9 +718,6 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
718release: 718release:
719 release_firmware(firmware); 719 release_firmware(firmware);
720 720
721error:
722 kfree(data);
723
724done: 721done:
725 return -EIO; 722 return -EIO;
726} 723}
@@ -741,7 +738,6 @@ static void bfusb_disconnect(struct usb_interface *intf)
741 738
742 hci_unregister_dev(hdev); 739 hci_unregister_dev(hdev);
743 hci_free_dev(hdev); 740 hci_free_dev(hdev);
744 kfree(data);
745} 741}
746 742
747static struct usb_driver bfusb_driver = { 743static struct usb_driver bfusb_driver = {
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 66c3a6770c41..0c0838d9b56c 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -849,7 +849,7 @@ static int bluecard_probe(struct pcmcia_device *link)
849 bluecard_info_t *info; 849 bluecard_info_t *info;
850 850
851 /* Create new info device */ 851 /* Create new info device */
852 info = kzalloc(sizeof(*info), GFP_KERNEL); 852 info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
853 if (!info) 853 if (!info)
854 return -ENOMEM; 854 return -ENOMEM;
855 855
@@ -864,10 +864,7 @@ static int bluecard_probe(struct pcmcia_device *link)
864 864
865static void bluecard_detach(struct pcmcia_device *link) 865static void bluecard_detach(struct pcmcia_device *link)
866{ 866{
867 bluecard_info_t *info = link->priv;
868
869 bluecard_release(link); 867 bluecard_release(link);
870 kfree(info);
871} 868}
872 869
873 870
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 29caaed2d715..2fe4a8031348 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -443,7 +443,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
443 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 443 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
444 return -ENODEV; 444 return -ENODEV;
445 445
446 data = kzalloc(sizeof(*data), GFP_KERNEL); 446 data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
447 if (!data) 447 if (!data)
448 return -ENOMEM; 448 return -ENOMEM;
449 449
@@ -453,10 +453,8 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
453 init_usb_anchor(&data->rx_anchor); 453 init_usb_anchor(&data->rx_anchor);
454 454
455 hdev = hci_alloc_dev(); 455 hdev = hci_alloc_dev();
456 if (!hdev) { 456 if (!hdev)
457 kfree(data);
458 return -ENOMEM; 457 return -ENOMEM;
459 }
460 458
461 hdev->bus = HCI_USB; 459 hdev->bus = HCI_USB;
462 hci_set_drvdata(hdev, data); 460 hci_set_drvdata(hdev, data);
@@ -475,7 +473,6 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
475 err = hci_register_dev(hdev); 473 err = hci_register_dev(hdev);
476 if (err < 0) { 474 if (err < 0) {
477 hci_free_dev(hdev); 475 hci_free_dev(hdev);
478 kfree(data);
479 return err; 476 return err;
480 } 477 }
481 478
@@ -500,7 +497,6 @@ static void bpa10x_disconnect(struct usb_interface *intf)
500 hci_free_dev(data->hdev); 497 hci_free_dev(data->hdev);
501 kfree_skb(data->rx_skb[0]); 498 kfree_skb(data->rx_skb[0]);
502 kfree_skb(data->rx_skb[1]); 499 kfree_skb(data->rx_skb[1]);
503 kfree(data);
504} 500}
505 501
506static struct usb_driver bpa10x_driver = { 502static struct usb_driver bpa10x_driver = {
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 8925b6d672a6..7ffd3f407144 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -638,7 +638,7 @@ static int bt3c_probe(struct pcmcia_device *link)
638 bt3c_info_t *info; 638 bt3c_info_t *info;
639 639
640 /* Create new info device */ 640 /* Create new info device */
641 info = kzalloc(sizeof(*info), GFP_KERNEL); 641 info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
642 if (!info) 642 if (!info)
643 return -ENOMEM; 643 return -ENOMEM;
644 644
@@ -654,10 +654,7 @@ static int bt3c_probe(struct pcmcia_device *link)
654 654
655static void bt3c_detach(struct pcmcia_device *link) 655static void bt3c_detach(struct pcmcia_device *link)
656{ 656{
657 bt3c_info_t *info = link->priv;
658
659 bt3c_release(link); 657 bt3c_release(link);
660 kfree(info);
661} 658}
662 659
663static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data) 660static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 6a9e9717d3ab..03b3acba6143 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -956,11 +956,9 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
956 BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d", 956 BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d",
957 id->vendor, id->device, id->class, func->num); 957 id->vendor, id->device, id->class, func->num);
958 958
959 card = kzalloc(sizeof(*card), GFP_KERNEL); 959 card = devm_kzalloc(&func->dev, sizeof(*card), GFP_KERNEL);
960 if (!card) { 960 if (!card)
961 ret = -ENOMEM; 961 return -ENOMEM;
962 goto done;
963 }
964 962
965 card->func = func; 963 card->func = func;
966 964
@@ -974,8 +972,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
974 972
975 if (btmrvl_sdio_register_dev(card) < 0) { 973 if (btmrvl_sdio_register_dev(card) < 0) {
976 BT_ERR("Failed to register BT device!"); 974 BT_ERR("Failed to register BT device!");
977 ret = -ENODEV; 975 return -ENODEV;
978 goto free_card;
979 } 976 }
980 977
981 /* Disable the interrupts on the card */ 978 /* Disable the interrupts on the card */
@@ -1023,9 +1020,6 @@ disable_host_int:
1023 btmrvl_sdio_disable_host_int(card); 1020 btmrvl_sdio_disable_host_int(card);
1024unreg_dev: 1021unreg_dev:
1025 btmrvl_sdio_unregister_dev(card); 1022 btmrvl_sdio_unregister_dev(card);
1026free_card:
1027 kfree(card);
1028done:
1029 return ret; 1023 return ret;
1030} 1024}
1031 1025
@@ -1047,7 +1041,6 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
1047 BT_DBG("unregester dev"); 1041 BT_DBG("unregester dev");
1048 btmrvl_sdio_unregister_dev(card); 1042 btmrvl_sdio_unregister_dev(card);
1049 btmrvl_remove_card(card->priv); 1043 btmrvl_remove_card(card->priv);
1050 kfree(card);
1051 } 1044 }
1052 } 1045 }
1053} 1046}
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index e10ea0347051..4a9909713874 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -304,7 +304,7 @@ static int btsdio_probe(struct sdio_func *func,
304 tuple = tuple->next; 304 tuple = tuple->next;
305 } 305 }
306 306
307 data = kzalloc(sizeof(*data), GFP_KERNEL); 307 data = devm_kzalloc(&func->dev, sizeof(*data), GFP_KERNEL);
308 if (!data) 308 if (!data)
309 return -ENOMEM; 309 return -ENOMEM;
310 310
@@ -315,10 +315,8 @@ static int btsdio_probe(struct sdio_func *func,
315 skb_queue_head_init(&data->txq); 315 skb_queue_head_init(&data->txq);
316 316
317 hdev = hci_alloc_dev(); 317 hdev = hci_alloc_dev();
318 if (!hdev) { 318 if (!hdev)
319 kfree(data);
320 return -ENOMEM; 319 return -ENOMEM;
321 }
322 320
323 hdev->bus = HCI_SDIO; 321 hdev->bus = HCI_SDIO;
324 hci_set_drvdata(hdev, data); 322 hci_set_drvdata(hdev, data);
@@ -340,7 +338,6 @@ static int btsdio_probe(struct sdio_func *func,
340 err = hci_register_dev(hdev); 338 err = hci_register_dev(hdev);
341 if (err < 0) { 339 if (err < 0) {
342 hci_free_dev(hdev); 340 hci_free_dev(hdev);
343 kfree(data);
344 return err; 341 return err;
345 } 342 }
346 343
@@ -366,7 +363,6 @@ static void btsdio_remove(struct sdio_func *func)
366 hci_unregister_dev(hdev); 363 hci_unregister_dev(hdev);
367 364
368 hci_free_dev(hdev); 365 hci_free_dev(hdev);
369 kfree(data);
370} 366}
371 367
372static struct sdio_driver btsdio_driver = { 368static struct sdio_driver btsdio_driver = {
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 21e803a6a281..2f510a87b28f 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -567,7 +567,7 @@ static int btuart_probe(struct pcmcia_device *link)
567 btuart_info_t *info; 567 btuart_info_t *info;
568 568
569 /* Create new info device */ 569 /* Create new info device */
570 info = kzalloc(sizeof(*info), GFP_KERNEL); 570 info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
571 if (!info) 571 if (!info)
572 return -ENOMEM; 572 return -ENOMEM;
573 573
@@ -583,10 +583,7 @@ static int btuart_probe(struct pcmcia_device *link)
583 583
584static void btuart_detach(struct pcmcia_device *link) 584static void btuart_detach(struct pcmcia_device *link)
585{ 585{
586 btuart_info_t *info = link->priv;
587
588 btuart_release(link); 586 btuart_release(link);
589 kfree(info);
590} 587}
591 588
592static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data) 589static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e27221411036..f637c2550016 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -952,7 +952,7 @@ static int btusb_probe(struct usb_interface *intf,
952 return -ENODEV; 952 return -ENODEV;
953 } 953 }
954 954
955 data = kzalloc(sizeof(*data), GFP_KERNEL); 955 data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
956 if (!data) 956 if (!data)
957 return -ENOMEM; 957 return -ENOMEM;
958 958
@@ -975,10 +975,8 @@ static int btusb_probe(struct usb_interface *intf,
975 } 975 }
976 } 976 }
977 977
978 if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { 978 if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
979 kfree(data);
980 return -ENODEV; 979 return -ENODEV;
981 }
982 980
983 data->cmdreq_type = USB_TYPE_CLASS; 981 data->cmdreq_type = USB_TYPE_CLASS;
984 982
@@ -998,10 +996,8 @@ static int btusb_probe(struct usb_interface *intf,
998 init_usb_anchor(&data->deferred); 996 init_usb_anchor(&data->deferred);
999 997
1000 hdev = hci_alloc_dev(); 998 hdev = hci_alloc_dev();
1001 if (!hdev) { 999 if (!hdev)
1002 kfree(data);
1003 return -ENOMEM; 1000 return -ENOMEM;
1004 }
1005 1001
1006 hdev->bus = HCI_USB; 1002 hdev->bus = HCI_USB;
1007 hci_set_drvdata(hdev, data); 1003 hci_set_drvdata(hdev, data);
@@ -1069,7 +1065,6 @@ static int btusb_probe(struct usb_interface *intf,
1069 data->isoc, data); 1065 data->isoc, data);
1070 if (err < 0) { 1066 if (err < 0) {
1071 hci_free_dev(hdev); 1067 hci_free_dev(hdev);
1072 kfree(data);
1073 return err; 1068 return err;
1074 } 1069 }
1075 } 1070 }
@@ -1077,7 +1072,6 @@ static int btusb_probe(struct usb_interface *intf,
1077 err = hci_register_dev(hdev); 1072 err = hci_register_dev(hdev);
1078 if (err < 0) { 1073 if (err < 0) {
1079 hci_free_dev(hdev); 1074 hci_free_dev(hdev);
1080 kfree(data);
1081 return err; 1075 return err;
1082 } 1076 }
1083 1077
@@ -1110,7 +1104,6 @@ static void btusb_disconnect(struct usb_interface *intf)
1110 usb_driver_release_interface(&btusb_driver, data->isoc); 1104 usb_driver_release_interface(&btusb_driver, data->isoc);
1111 1105
1112 hci_free_dev(hdev); 1106 hci_free_dev(hdev);
1113 kfree(data);
1114} 1107}
1115 1108
1116#ifdef CONFIG_PM 1109#ifdef CONFIG_PM
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
index 88694697f34f..4ad7b35cfc0e 100644
--- a/drivers/bluetooth/btwilink.c
+++ b/drivers/bluetooth/btwilink.c
@@ -297,16 +297,14 @@ static int bt_ti_probe(struct platform_device *pdev)
297 struct hci_dev *hdev; 297 struct hci_dev *hdev;
298 int err; 298 int err;
299 299
300 hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL); 300 hst = devm_kzalloc(&pdev->dev, sizeof(struct ti_st), GFP_KERNEL);
301 if (!hst) 301 if (!hst)
302 return -ENOMEM; 302 return -ENOMEM;
303 303
304 /* Expose "hciX" device to user space */ 304 /* Expose "hciX" device to user space */
305 hdev = hci_alloc_dev(); 305 hdev = hci_alloc_dev();
306 if (!hdev) { 306 if (!hdev)
307 kfree(hst);
308 return -ENOMEM; 307 return -ENOMEM;
309 }
310 308
311 BT_DBG("hdev %p", hdev); 309 BT_DBG("hdev %p", hdev);
312 310
@@ -321,7 +319,6 @@ static int bt_ti_probe(struct platform_device *pdev)
321 err = hci_register_dev(hdev); 319 err = hci_register_dev(hdev);
322 if (err < 0) { 320 if (err < 0) {
323 BT_ERR("Can't register HCI device error %d", err); 321 BT_ERR("Can't register HCI device error %d", err);
324 kfree(hst);
325 hci_free_dev(hdev); 322 hci_free_dev(hdev);
326 return err; 323 return err;
327 } 324 }
@@ -347,7 +344,6 @@ static int bt_ti_remove(struct platform_device *pdev)
347 hci_unregister_dev(hdev); 344 hci_unregister_dev(hdev);
348 345
349 hci_free_dev(hdev); 346 hci_free_dev(hdev);
350 kfree(hst);
351 347
352 dev_set_drvdata(&pdev->dev, NULL); 348 dev_set_drvdata(&pdev->dev, NULL);
353 return 0; 349 return 0;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 97a7784db4a2..036cb366fe6e 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -550,7 +550,7 @@ static int dtl1_probe(struct pcmcia_device *link)
550 dtl1_info_t *info; 550 dtl1_info_t *info;
551 551
552 /* Create new info device */ 552 /* Create new info device */
553 info = kzalloc(sizeof(*info), GFP_KERNEL); 553 info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
554 if (!info) 554 if (!info)
555 return -ENOMEM; 555 return -ENOMEM;
556 556
@@ -569,7 +569,6 @@ static void dtl1_detach(struct pcmcia_device *link)
569 569
570 dtl1_close(info); 570 dtl1_close(info);
571 pcmcia_disable_device(link); 571 pcmcia_disable_device(link);
572 kfree(info);
573} 572}
574 573
575static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) 574static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 64a453a6dfe4..3150def17193 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1331,7 +1331,6 @@ struct ath5k_hw {
1331 unsigned int nexttbtt; /* next beacon time in TU */ 1331 unsigned int nexttbtt; /* next beacon time in TU */
1332 struct ath5k_txq *cabq; /* content after beacon */ 1332 struct ath5k_txq *cabq; /* content after beacon */
1333 1333
1334 int power_level; /* Requested tx power in dBm */
1335 bool assoc; /* associate state */ 1334 bool assoc; /* associate state */
1336 bool enable_beacon; /* true if beacons are on */ 1335 bool enable_beacon; /* true if beacons are on */
1337 1336
@@ -1425,6 +1424,7 @@ struct ath5k_hw {
1425 /* Value in dB units */ 1424 /* Value in dB units */
1426 s16 txp_cck_ofdm_pwr_delta; 1425 s16 txp_cck_ofdm_pwr_delta;
1427 bool txp_setup; 1426 bool txp_setup;
1427 int txp_requested; /* Requested tx power in dBm */
1428 } ah_txpower; 1428 } ah_txpower;
1429 1429
1430 struct ath5k_nfcal_hist ah_nfcal_hist; 1430 struct ath5k_nfcal_hist ah_nfcal_hist;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8c4c040a47b8..9d48f9a461e1 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -723,7 +723,7 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
723 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 723 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
724 ieee80211_get_hdrlen_from_skb(skb), padsize, 724 ieee80211_get_hdrlen_from_skb(skb), padsize,
725 get_hw_packet_type(skb), 725 get_hw_packet_type(skb),
726 (ah->power_level * 2), 726 (ah->ah_txpower.txp_requested * 2),
727 hw_rate, 727 hw_rate,
728 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, 728 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
729 cts_rate, duration); 729 cts_rate, duration);
@@ -1778,7 +1778,8 @@ ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)
1778 ds->ds_data = bf->skbaddr; 1778 ds->ds_data = bf->skbaddr;
1779 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 1779 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
1780 ieee80211_get_hdrlen_from_skb(skb), padsize, 1780 ieee80211_get_hdrlen_from_skb(skb), padsize,
1781 AR5K_PKT_TYPE_BEACON, (ah->power_level * 2), 1781 AR5K_PKT_TYPE_BEACON,
1782 (ah->ah_txpower.txp_requested * 2),
1782 ieee80211_get_tx_rate(ah->hw, info)->hw_value, 1783 ieee80211_get_tx_rate(ah->hw, info)->hw_value,
1783 1, AR5K_TXKEYIX_INVALID, 1784 1, AR5K_TXKEYIX_INVALID,
1784 antenna, flags, 0, 0); 1785 antenna, flags, 0, 0);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 260e7dc7f751..92ee3a0a5192 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -207,8 +207,8 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
207 } 207 }
208 208
209 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 209 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
210 (ah->power_level != conf->power_level)) { 210 (ah->ah_txpower.txp_requested != conf->power_level)) {
211 ah->power_level = conf->power_level; 211 ah->ah_txpower.txp_requested = conf->power_level;
212 212
213 /* Half dB steps */ 213 /* Half dB steps */
214 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); 214 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 8b71a2d947e0..01c90ed58453 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -3516,6 +3516,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3516{ 3516{
3517 unsigned int i; 3517 unsigned int i;
3518 u16 *rates; 3518 u16 *rates;
3519 s16 rate_idx_scaled = 0;
3519 3520
3520 /* max_pwr is power level we got from driver/user in 0.5dB 3521 /* max_pwr is power level we got from driver/user in 0.5dB
3521 * units, switch to 0.25dB units so we can compare */ 3522 * units, switch to 0.25dB units so we can compare */
@@ -3562,20 +3563,32 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3562 for (i = 8; i <= 15; i++) 3563 for (i = 8; i <= 15; i++)
3563 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta; 3564 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
3564 3565
3566 /* Save min/max and current tx power for this channel
3567 * in 0.25dB units.
3568 *
3569 * Note: We use rates[0] for current tx power because
3570 * it covers most of the rates, in most cases. It's our
3571 * tx power limit and what the user expects to see. */
3572 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3573 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3574
3575 /* Set max txpower for correct OFDM operation on all rates
3576 * -that is the txpower for 54Mbit-, it's used for the PAPD
3577 * gain probe and it's in 0.5dB units */
3578 ah->ah_txpower.txp_ofdm = rates[7];
3579
3565 /* Now that we have all rates setup use table offset to 3580 /* Now that we have all rates setup use table offset to
3566 * match the power range set by user with the power indices 3581 * match the power range set by user with the power indices
3567 * on PCDAC/PDADC table */ 3582 * on PCDAC/PDADC table */
3568 for (i = 0; i < 16; i++) { 3583 for (i = 0; i < 16; i++) {
3569 rates[i] += ah->ah_txpower.txp_offset; 3584 rate_idx_scaled = rates[i] + ah->ah_txpower.txp_offset;
3570 /* Don't get out of bounds */ 3585 /* Don't get out of bounds */
3571 if (rates[i] > 63) 3586 if (rate_idx_scaled > 63)
3572 rates[i] = 63; 3587 rate_idx_scaled = 63;
3588 if (rate_idx_scaled < 0)
3589 rate_idx_scaled = 0;
3590 rates[i] = rate_idx_scaled;
3573 } 3591 }
3574
3575 /* Min/max in 0.25dB units */
3576 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3577 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3578 ah->ah_txpower.txp_ofdm = rates[7];
3579} 3592}
3580 3593
3581 3594
@@ -3639,10 +3652,17 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3639 if (!ah->ah_txpower.txp_setup || 3652 if (!ah->ah_txpower.txp_setup ||
3640 (channel->hw_value != curr_channel->hw_value) || 3653 (channel->hw_value != curr_channel->hw_value) ||
3641 (channel->center_freq != curr_channel->center_freq)) { 3654 (channel->center_freq != curr_channel->center_freq)) {
3642 /* Reset TX power values */ 3655 /* Reset TX power values but preserve requested
3656 * tx power from above */
3657 int requested_txpower = ah->ah_txpower.txp_requested;
3658
3643 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 3659 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
3660
3661 /* Restore TPC setting and requested tx power */
3644 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 3662 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
3645 3663
3664 ah->ah_txpower.txp_requested = requested_txpower;
3665
3646 /* Calculate the powertable */ 3666 /* Calculate the powertable */
3647 ret = ath5k_setup_channel_powertable(ah, channel, 3667 ret = ath5k_setup_channel_powertable(ah, channel,
3648 ee_mode, type); 3668 ee_mode, type);
@@ -3789,8 +3809,9 @@ ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3789 * RF buffer settings on 5211/5212+ so that we 3809 * RF buffer settings on 5211/5212+ so that we
3790 * properly set curve indices. 3810 * properly set curve indices.
3791 */ 3811 */
3792 ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ? 3812 ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_requested ?
3793 ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER); 3813 ah->ah_txpower.txp_requested * 2 :
3814 AR5K_TUNE_MAX_TXPOWER);
3794 if (ret) 3815 if (ret)
3795 return ret; 3816 return ret;
3796 3817
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 2588848f4a82..c37fe9620e41 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4901,90 +4901,79 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4901 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], 4901 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4902 chan->channel); 4902 chan->channel);
4903 4903
4904 /* 4904 /*
4905 * compare test group from regulatory 4905 * compare test group from regulatory
4906 * channel list with test mode from pCtlMode 4906 * channel list with test mode from pCtlMode
4907 * list 4907 * list
4908 */ 4908 */
4909 if ((((cfgCtl & ~CTL_MODE_M) | 4909 if ((((cfgCtl & ~CTL_MODE_M) |
4910 (pCtlMode[ctlMode] & CTL_MODE_M)) == 4910 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4911 ctlIndex[i]) || 4911 ctlIndex[i]) ||
4912 (((cfgCtl & ~CTL_MODE_M) | 4912 (((cfgCtl & ~CTL_MODE_M) |
4913 (pCtlMode[ctlMode] & CTL_MODE_M)) == 4913 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4914 ((ctlIndex[i] & CTL_MODE_M) | 4914 ((ctlIndex[i] & CTL_MODE_M) |
4915 SD_NO_CTL))) { 4915 SD_NO_CTL))) {
4916 twiceMinEdgePower = 4916 twiceMinEdgePower =
4917 ar9003_hw_get_max_edge_power(pEepData, 4917 ar9003_hw_get_max_edge_power(pEepData,
4918 freq, i, 4918 freq, i,
4919 is2ghz); 4919 is2ghz);
4920 4920
4921 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) 4921 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4922 /* 4922 /*
4923 * Find the minimum of all CTL 4923 * Find the minimum of all CTL
4924 * edge powers that apply to 4924 * edge powers that apply to
4925 * this channel 4925 * this channel
4926 */ 4926 */
4927 twiceMaxEdgePower = 4927 twiceMaxEdgePower =
4928 min(twiceMaxEdgePower, 4928 min(twiceMaxEdgePower,
4929 twiceMinEdgePower); 4929 twiceMinEdgePower);
4930 else { 4930 else {
4931 /* specific */ 4931 /* specific */
4932 twiceMaxEdgePower = 4932 twiceMaxEdgePower = twiceMinEdgePower;
4933 twiceMinEdgePower; 4933 break;
4934 break;
4935 }
4936 } 4934 }
4937 } 4935 }
4936 }
4938 4937
4939 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 4938 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4940 4939
4941 ath_dbg(common, REGULATORY, 4940 ath_dbg(common, REGULATORY,
4942 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n", 4941 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4943 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 4942 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4944 scaledPower, minCtlPower); 4943 scaledPower, minCtlPower);
4945 4944
4946 /* Apply ctl mode to correct target power set */ 4945 /* Apply ctl mode to correct target power set */
4947 switch (pCtlMode[ctlMode]) { 4946 switch (pCtlMode[ctlMode]) {
4948 case CTL_11B: 4947 case CTL_11B:
4949 for (i = ALL_TARGET_LEGACY_1L_5L; 4948 for (i = ALL_TARGET_LEGACY_1L_5L;
4950 i <= ALL_TARGET_LEGACY_11S; i++) 4949 i <= ALL_TARGET_LEGACY_11S; i++)
4951 pPwrArray[i] = 4950 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
4952 (u8)min((u16)pPwrArray[i], 4951 minCtlPower);
4953 minCtlPower); 4952 break;
4954 break; 4953 case CTL_11A:
4955 case CTL_11A: 4954 case CTL_11G:
4956 case CTL_11G: 4955 for (i = ALL_TARGET_LEGACY_6_24;
4957 for (i = ALL_TARGET_LEGACY_6_24; 4956 i <= ALL_TARGET_LEGACY_54; i++)
4958 i <= ALL_TARGET_LEGACY_54; i++) 4957 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
4959 pPwrArray[i] = 4958 minCtlPower);
4960 (u8)min((u16)pPwrArray[i], 4959 break;
4961 minCtlPower); 4960 case CTL_5GHT20:
4962 break; 4961 case CTL_2GHT20:
4963 case CTL_5GHT20: 4962 for (i = ALL_TARGET_HT20_0_8_16;
4964 case CTL_2GHT20: 4963 i <= ALL_TARGET_HT20_23; i++)
4965 for (i = ALL_TARGET_HT20_0_8_16; 4964 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
4966 i <= ALL_TARGET_HT20_21; i++) 4965 minCtlPower);
4967 pPwrArray[i] = 4966 break;
4968 (u8)min((u16)pPwrArray[i], 4967 case CTL_5GHT40:
4969 minCtlPower); 4968 case CTL_2GHT40:
4970 pPwrArray[ALL_TARGET_HT20_22] = 4969 for (i = ALL_TARGET_HT40_0_8_16;
4971 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22], 4970 i <= ALL_TARGET_HT40_23; i++)
4972 minCtlPower); 4971 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
4973 pPwrArray[ALL_TARGET_HT20_23] = 4972 minCtlPower);
4974 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23], 4973 break;
4975 minCtlPower); 4974 default:
4976 break; 4975 break;
4977 case CTL_5GHT40: 4976 }
4978 case CTL_2GHT40:
4979 for (i = ALL_TARGET_HT40_0_8_16;
4980 i <= ALL_TARGET_HT40_23; i++)
4981 pPwrArray[i] =
4982 (u8)min((u16)pPwrArray[i],
4983 minCtlPower);
4984 break;
4985 default:
4986 break;
4987 }
4988 } /* end ctl mode checking */ 4977 } /* end ctl mode checking */
4989} 4978}
4990 4979
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index e034add9cd5a..4b12c347d188 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -25,141 +25,141 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
25 8, /* MCS start */ 25 8, /* MCS start */
26 { 26 {
27 [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, 27 [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000,
28 5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */ 28 5400, 0, 12 }, /* 6 Mb */
29 [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, 29 [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000,
30 7800, 1, 18, 0, 1, 1, 1 }, /* 9 Mb */ 30 7800, 1, 18 }, /* 9 Mb */
31 [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, 31 [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
32 10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */ 32 10000, 2, 24 }, /* 12 Mb */
33 [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, 33 [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
34 13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */ 34 13900, 3, 36 }, /* 18 Mb */
35 [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, 35 [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
36 17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */ 36 17300, 4, 48 }, /* 24 Mb */
37 [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, 37 [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
38 23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */ 38 23000, 5, 72 }, /* 36 Mb */
39 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, 39 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
40 27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */ 40 27400, 6, 96 }, /* 48 Mb */
41 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, 41 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
42 29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */ 42 29300, 7, 108 }, /* 54 Mb */
43 [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500, 43 [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500,
44 6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */ 44 6400, 0, 0 }, /* 6.5 Mb */
45 [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, 45 [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
46 12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */ 46 12700, 1, 1 }, /* 13 Mb */
47 [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, 47 [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
48 18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */ 48 18800, 2, 2 }, /* 19.5 Mb */
49 [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, 49 [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
50 25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */ 50 25000, 3, 3 }, /* 26 Mb */
51 [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, 51 [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
52 36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */ 52 36700, 4, 4 }, /* 39 Mb */
53 [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, 53 [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
54 48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */ 54 48100, 5, 5 }, /* 52 Mb */
55 [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, 55 [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
56 53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */ 56 53500, 6, 6 }, /* 58.5 Mb */
57 [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, 57 [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
58 59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */ 58 59000, 7, 7 }, /* 65 Mb */
59 [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, 59 [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
60 65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */ 60 65400, 7, 7 }, /* 75 Mb */
61 [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, 61 [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
62 12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */ 62 12700, 8, 8 }, /* 13 Mb */
63 [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, 63 [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
64 24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */ 64 24800, 9, 9 }, /* 26 Mb */
65 [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, 65 [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
66 36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */ 66 36600, 10, 10 }, /* 39 Mb */
67 [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, 67 [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
68 48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */ 68 48100, 11, 11 }, /* 52 Mb */
69 [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, 69 [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
70 69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */ 70 69500, 12, 12 }, /* 78 Mb */
71 [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, 71 [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
72 89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */ 72 89500, 13, 13 }, /* 104 Mb */
73 [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, 73 [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
74 98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */ 74 98900, 14, 14 }, /* 117 Mb */
75 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, 75 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
76 108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */ 76 108300, 15, 15 }, /* 130 Mb */
77 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, 77 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
78 120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */ 78 120000, 15, 15 }, /* 144.4 Mb */
79 [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, 79 [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
80 17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */ 80 17400, 16, 16 }, /* 19.5 Mb */
81 [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, 81 [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
82 35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */ 82 35100, 17, 17 }, /* 39 Mb */
83 [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, 83 [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
84 52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */ 84 52600, 18, 18 }, /* 58.5 Mb */
85 [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, 85 [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
86 70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */ 86 70400, 19, 19 }, /* 78 Mb */
87 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, 87 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
88 104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */ 88 104900, 20, 20 }, /* 117 Mb */
89 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, 89 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
90 115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/ 90 115800, 20, 20 }, /* 130 Mb*/
91 [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, 91 [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
92 137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */ 92 137200, 21, 21 }, /* 156 Mb */
93 [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, 93 [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
94 151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */ 94 151100, 21, 21 }, /* 173.3 Mb */
95 [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, 95 [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
96 152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */ 96 152800, 22, 22 }, /* 175.5 Mb */
97 [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, 97 [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
98 168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/ 98 168400, 22, 22 }, /* 195 Mb*/
99 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, 99 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
100 168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */ 100 168400, 23, 23 }, /* 195 Mb */
101 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, 101 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
102 185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */ 102 185000, 23, 23 }, /* 216.7 Mb */
103 [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, 103 [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
104 13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/ 104 13200, 0, 0 }, /* 13.5 Mb*/
105 [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, 105 [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
106 25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/ 106 25900, 1, 1 }, /* 27.0 Mb*/
107 [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, 107 [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
108 38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/ 108 38600, 2, 2 }, /* 40.5 Mb*/
109 [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, 109 [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
110 49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */ 110 49800, 3, 3 }, /* 54 Mb */
111 [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, 111 [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
112 72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */ 112 72200, 4, 4 }, /* 81 Mb */
113 [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, 113 [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000,
114 92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */ 114 92900, 5, 5 }, /* 108 Mb */
115 [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, 115 [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
116 102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/ 116 102700, 6, 6 }, /* 121.5 Mb*/
117 [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, 117 [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
118 112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */ 118 112000, 7, 7 }, /* 135 Mb */
119 [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, 119 [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
120 122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */ 120 122000, 7, 7 }, /* 150 Mb */
121 [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, 121 [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
122 25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */ 122 25800, 8, 8 }, /* 27 Mb */
123 [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, 123 [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
124 49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */ 124 49800, 9, 9 }, /* 54 Mb */
125 [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, 125 [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
126 71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */ 126 71900, 10, 10 }, /* 81 Mb */
127 [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, 127 [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
128 92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */ 128 92500, 11, 11 }, /* 108 Mb */
129 [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, 129 [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
130 130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */ 130 130300, 12, 12 }, /* 162 Mb */
131 [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, 131 [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
132 162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */ 132 162800, 13, 13 }, /* 216 Mb */
133 [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, 133 [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
134 178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */ 134 178200, 14, 14 }, /* 243 Mb */
135 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, 135 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
136 192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */ 136 192100, 15, 15 }, /* 270 Mb */
137 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, 137 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
138 207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */ 138 207000, 15, 15 }, /* 300 Mb */
139 [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, 139 [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
140 36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */ 140 36100, 16, 16 }, /* 40.5 Mb */
141 [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, 141 [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
142 72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */ 142 72900, 17, 17 }, /* 81 Mb */
143 [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, 143 [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
144 108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */ 144 108300, 18, 18 }, /* 121.5 Mb */
145 [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, 145 [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
146 142000, 19, 19, 4, 59, 59, 59 }, /* 162 Mb */ 146 142000, 19, 19 }, /* 162 Mb */
147 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 147 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
148 205100, 20, 20, 4, 60, 61, 61 }, /* 243 Mb */ 148 205100, 20, 20 }, /* 243 Mb */
149 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, 149 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
150 224700, 20, 20, 4, 60, 61, 61 }, /* 270 Mb */ 150 224700, 20, 20 }, /* 270 Mb */
151 [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 151 [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
152 263100, 21, 21, 4, 62, 63, 63 }, /* 324 Mb */ 152 263100, 21, 21 }, /* 324 Mb */
153 [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, 153 [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
154 288000, 21, 21, 4, 62, 63, 63 }, /* 360 Mb */ 154 288000, 21, 21 }, /* 360 Mb */
155 [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, 155 [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
156 290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */ 156 290700, 22, 22 }, /* 364.5 Mb */
157 [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, 157 [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
158 317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */ 158 317200, 22, 22 }, /* 405 Mb */
159 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, 159 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
160 317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */ 160 317200, 23, 23 }, /* 405 Mb */
161 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, 161 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
162 346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */ 162 346400, 23, 23 }, /* 450 Mb */
163 }, 163 },
164 50, /* probe interval */ 164 50, /* probe interval */
165 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 165 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -173,149 +173,149 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
173 12, /* MCS start */ 173 12, /* MCS start */
174 { 174 {
175 [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000, 175 [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000,
176 900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */ 176 900, 0, 2 }, /* 1 Mb */
177 [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000, 177 [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000,
178 1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */ 178 1900, 1, 4 }, /* 2 Mb */
179 [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500, 179 [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500,
180 4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */ 180 4900, 2, 11 }, /* 5.5 Mb */
181 [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000, 181 [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000,
182 8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */ 182 8100, 3, 22 }, /* 11 Mb */
183 [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, 183 [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000,
184 5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */ 184 5400, 4, 12 }, /* 6 Mb */
185 [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, 185 [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000,
186 7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */ 186 7800, 5, 18 }, /* 9 Mb */
187 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, 187 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
188 10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */ 188 10100, 6, 24 }, /* 12 Mb */
189 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, 189 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
190 14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */ 190 14100, 7, 36 }, /* 18 Mb */
191 [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, 191 [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
192 17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */ 192 17700, 8, 48 }, /* 24 Mb */
193 [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, 193 [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
194 23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */ 194 23700, 9, 72 }, /* 36 Mb */
195 [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, 195 [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
196 27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */ 196 27400, 10, 96 }, /* 48 Mb */
197 [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, 197 [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
198 30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */ 198 30900, 11, 108 }, /* 54 Mb */
199 [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, 199 [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500,
200 6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */ 200 6400, 0, 0 }, /* 6.5 Mb */
201 [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, 201 [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
202 12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */ 202 12700, 1, 1 }, /* 13 Mb */
203 [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, 203 [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
204 18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/ 204 18800, 2, 2 }, /* 19.5 Mb*/
205 [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, 205 [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
206 25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */ 206 25000, 3, 3 }, /* 26 Mb */
207 [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, 207 [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
208 36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */ 208 36700, 4, 4 }, /* 39 Mb */
209 [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, 209 [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
210 48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */ 210 48100, 5, 5 }, /* 52 Mb */
211 [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, 211 [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
212 53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */ 212 53500, 6, 6 }, /* 58.5 Mb */
213 [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, 213 [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
214 59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */ 214 59000, 7, 7 }, /* 65 Mb */
215 [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, 215 [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
216 65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/ 216 65400, 7, 7 }, /* 65 Mb*/
217 [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, 217 [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
218 12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */ 218 12700, 8, 8 }, /* 13 Mb */
219 [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, 219 [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
220 24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */ 220 24800, 9, 9 }, /* 26 Mb */
221 [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, 221 [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
222 36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */ 222 36600, 10, 10 }, /* 39 Mb */
223 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, 223 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
224 48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */ 224 48100, 11, 11 }, /* 52 Mb */
225 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, 225 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
226 69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */ 226 69500, 12, 12 }, /* 78 Mb */
227 [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, 227 [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
228 89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */ 228 89500, 13, 13 }, /* 104 Mb */
229 [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, 229 [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
230 98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */ 230 98900, 14, 14 }, /* 117 Mb */
231 [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, 231 [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
232 108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */ 232 108300, 15, 15 }, /* 130 Mb */
233 [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, 233 [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
234 120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */ 234 120000, 15, 15 }, /* 144.4 Mb */
235 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, 235 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
236 17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */ 236 17400, 16, 16 }, /* 19.5 Mb */
237 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, 237 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
238 35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */ 238 35100, 17, 17 }, /* 39 Mb */
239 [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, 239 [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
240 52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */ 240 52600, 18, 18 }, /* 58.5 Mb */
241 [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, 241 [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
242 70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */ 242 70400, 19, 19 }, /* 78 Mb */
243 [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, 243 [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
244 104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */ 244 104900, 20, 20 }, /* 117 Mb */
245 [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, 245 [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
246 115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */ 246 115800, 20, 20 }, /* 130 Mb */
247 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, 247 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
248 137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */ 248 137200, 21, 21 }, /* 156 Mb */
249 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, 249 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
250 151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */ 250 151100, 21, 21 }, /* 173.3 Mb */
251 [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, 251 [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
252 152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */ 252 152800, 22, 22 }, /* 175.5 Mb */
253 [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, 253 [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
254 168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */ 254 168400, 22, 22 }, /* 195 Mb */
255 [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, 255 [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
256 168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */ 256 168400, 23, 23 }, /* 195 Mb */
257 [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, 257 [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
258 185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */ 258 185000, 23, 23 }, /* 216.7 Mb */
259 [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, 259 [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
260 13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */ 260 13200, 0, 0 }, /* 13.5 Mb */
261 [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, 261 [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
262 25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */ 262 25900, 1, 1 }, /* 27.0 Mb */
263 [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, 263 [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
264 38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */ 264 38600, 2, 2 }, /* 40.5 Mb */
265 [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, 265 [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
266 49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */ 266 49800, 3, 3 }, /* 54 Mb */
267 [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, 267 [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
268 72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */ 268 72200, 4, 4 }, /* 81 Mb */
269 [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, 269 [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000,
270 92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */ 270 92900, 5, 5 }, /* 108 Mb */
271 [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, 271 [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
272 102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */ 272 102700, 6, 6 }, /* 121.5 Mb */
273 [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, 273 [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
274 112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */ 274 112000, 7, 7 }, /* 135 Mb */
275 [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, 275 [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
276 122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */ 276 122000, 7, 7 }, /* 150 Mb */
277 [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, 277 [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
278 25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */ 278 25800, 8, 8 }, /* 27 Mb */
279 [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, 279 [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
280 49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */ 280 49800, 9, 9 }, /* 54 Mb */
281 [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, 281 [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
282 71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */ 282 71900, 10, 10 }, /* 81 Mb */
283 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, 283 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
284 92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */ 284 92500, 11, 11 }, /* 108 Mb */
285 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, 285 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
286 130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */ 286 130300, 12, 12 }, /* 162 Mb */
287 [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, 287 [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
288 162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */ 288 162800, 13, 13 }, /* 216 Mb */
289 [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, 289 [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
290 178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */ 290 178200, 14, 14 }, /* 243 Mb */
291 [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, 291 [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
292 192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */ 292 192100, 15, 15 }, /* 270 Mb */
293 [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, 293 [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
294 207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */ 294 207000, 15, 15 }, /* 300 Mb */
295 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, 295 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
296 36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */ 296 36100, 16, 16 }, /* 40.5 Mb */
297 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, 297 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
298 72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */ 298 72900, 17, 17 }, /* 81 Mb */
299 [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, 299 [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
300 108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */ 300 108300, 18, 18 }, /* 121.5 Mb */
301 [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, 301 [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
302 142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */ 302 142000, 19, 19 }, /* 162 Mb */
303 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 303 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
304 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ 304 205100, 20, 20 }, /* 243 Mb */
305 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, 305 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
306 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */ 306 224700, 20, 20 }, /* 270 Mb */
307 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 307 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
308 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ 308 263100, 21, 21 }, /* 324 Mb */
309 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, 309 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
310 288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */ 310 288000, 21, 21 }, /* 360 Mb */
311 [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, 311 [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
312 290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */ 312 290700, 22, 22 }, /* 364.5 Mb */
313 [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, 313 [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
314 317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */ 314 317200, 22, 22 }, /* 405 Mb */
315 [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, 315 [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
316 317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */ 316 317200, 23, 23 }, /* 405 Mb */
317 [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, 317 [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
318 346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */ 318 346400, 23, 23 }, /* 450 Mb */
319 }, 319 },
320 50, /* probe interval */ 320 50, /* probe interval */
321 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 321 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -326,21 +326,21 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
326 0, 326 0,
327 { 327 {
328 { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 328 { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
329 5400, 0, 12, 0}, 329 5400, 0, 12},
330 { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 330 { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
331 7800, 1, 18, 0}, 331 7800, 1, 18},
332 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 332 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
333 10000, 2, 24, 2}, 333 10000, 2, 24},
334 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 334 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
335 13900, 3, 36, 2}, 335 13900, 3, 36},
336 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 336 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
337 17300, 4, 48, 4}, 337 17300, 4, 48},
338 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 338 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
339 23000, 5, 72, 4}, 339 23000, 5, 72},
340 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 340 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
341 27400, 6, 96, 4}, 341 27400, 6, 96},
342 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 342 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
343 29300, 7, 108, 4}, 343 29300, 7, 108},
344 }, 344 },
345 50, /* probe interval */ 345 50, /* probe interval */
346 0, /* Phy rates allowed initially */ 346 0, /* Phy rates allowed initially */
@@ -351,63 +351,62 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
351 0, 351 0,
352 { 352 {
353 { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 353 { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
354 900, 0, 2, 0}, 354 900, 0, 2},
355 { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 355 { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
356 1900, 1, 4, 1}, 356 1900, 1, 4},
357 { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 357 { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
358 4900, 2, 11, 2}, 358 4900, 2, 11},
359 { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 359 { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
360 8100, 3, 22, 3}, 360 8100, 3, 22},
361 { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 361 { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
362 5400, 4, 12, 4}, 362 5400, 4, 12},
363 { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 363 { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
364 7800, 5, 18, 4}, 364 7800, 5, 18},
365 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 365 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
366 10000, 6, 24, 6}, 366 10000, 6, 24},
367 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 367 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
368 13900, 7, 36, 6}, 368 13900, 7, 36},
369 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 369 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
370 17300, 8, 48, 8}, 370 17300, 8, 48},
371 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 371 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
372 23000, 9, 72, 8}, 372 23000, 9, 72},
373 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 373 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
374 27400, 10, 96, 8}, 374 27400, 10, 96},
375 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 375 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
376 29300, 11, 108, 8}, 376 29300, 11, 108},
377 }, 377 },
378 50, /* probe interval */ 378 50, /* probe interval */
379 0, /* Phy rates allowed initially */ 379 0, /* Phy rates allowed initially */
380}; 380};
381 381
382static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, 382static int ath_rc_get_rateindex(struct ath_rate_priv *ath_rc_priv,
383 struct ieee80211_tx_rate *rate) 383 struct ieee80211_tx_rate *rate)
384{ 384{
385 int rix = 0, i = 0; 385 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
386 static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; 386 int rix, i, idx = 0;
387 387
388 if (!(rate->flags & IEEE80211_TX_RC_MCS)) 388 if (!(rate->flags & IEEE80211_TX_RC_MCS))
389 return rate->idx; 389 return rate->idx;
390 390
391 while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { 391 for (i = 0; i < ath_rc_priv->max_valid_rate; i++) {
392 rix++; i++; 392 idx = ath_rc_priv->valid_rate_index[i];
393
394 if (WLAN_RC_PHY_HT(rate_table->info[idx].phy) &&
395 rate_table->info[idx].ratecode == rate->idx)
396 break;
393 } 397 }
394 398
395 rix += rate->idx + rate_table->mcs_start; 399 rix = idx;
396 400
397 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 401 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
398 (rate->flags & IEEE80211_TX_RC_SHORT_GI)) 402 rix++;
399 rix = rate_table->info[rix].ht_index;
400 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
401 rix = rate_table->info[rix].sgi_index;
402 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
403 rix = rate_table->info[rix].cw40index;
404 403
405 return rix; 404 return rix;
406} 405}
407 406
408static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, 407static void ath_rc_sort_validrates(struct ath_rate_priv *ath_rc_priv)
409 struct ath_rate_priv *ath_rc_priv)
410{ 408{
409 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
411 u8 i, j, idx, idx_next; 410 u8 i, j, idx, idx_next;
412 411
413 for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) { 412 for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
@@ -424,21 +423,6 @@ static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
424 } 423 }
425} 424}
426 425
427static void ath_rc_init_valid_rate_idx(struct ath_rate_priv *ath_rc_priv)
428{
429 u8 i;
430
431 for (i = 0; i < ath_rc_priv->rate_table_size; i++)
432 ath_rc_priv->valid_rate_index[i] = 0;
433}
434
435static inline void ath_rc_set_valid_rate_idx(struct ath_rate_priv *ath_rc_priv,
436 u8 index, int valid_tx_rate)
437{
438 BUG_ON(index > ath_rc_priv->rate_table_size);
439 ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate;
440}
441
442static inline 426static inline
443int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table, 427int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
444 struct ath_rate_priv *ath_rc_priv, 428 struct ath_rate_priv *ath_rc_priv,
@@ -479,8 +463,7 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
479} 463}
480 464
481static inline int 465static inline int
482ath_rc_get_lower_rix(const struct ath_rate_table *rate_table, 466ath_rc_get_lower_rix(struct ath_rate_priv *ath_rc_priv,
483 struct ath_rate_priv *ath_rc_priv,
484 u8 cur_valid_txrate, u8 *next_idx) 467 u8 cur_valid_txrate, u8 *next_idx)
485{ 468{
486 int8_t i; 469 int8_t i;
@@ -495,10 +478,9 @@ ath_rc_get_lower_rix(const struct ath_rate_table *rate_table,
495 return 0; 478 return 0;
496} 479}
497 480
498static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, 481static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv)
499 const struct ath_rate_table *rate_table,
500 u32 capflag)
501{ 482{
483 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
502 u8 i, hi = 0; 484 u8 i, hi = 0;
503 485
504 for (i = 0; i < rate_table->rate_cnt; i++) { 486 for (i = 0; i < rate_table->rate_cnt; i++) {
@@ -506,14 +488,14 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
506 u32 phy = rate_table->info[i].phy; 488 u32 phy = rate_table->info[i].phy;
507 u8 valid_rate_count = 0; 489 u8 valid_rate_count = 0;
508 490
509 if (!ath_rc_valid_phyrate(phy, capflag, 0)) 491 if (!ath_rc_valid_phyrate(phy, ath_rc_priv->ht_cap, 0))
510 continue; 492 continue;
511 493
512 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; 494 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
513 495
514 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; 496 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
515 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 497 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
516 ath_rc_set_valid_rate_idx(ath_rc_priv, i, 1); 498 ath_rc_priv->valid_rate_index[i] = true;
517 hi = i; 499 hi = i;
518 } 500 }
519 } 501 }
@@ -521,76 +503,73 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
521 return hi; 503 return hi;
522} 504}
523 505
524static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, 506static inline bool ath_rc_check_legacy(u8 rate, u8 dot11rate, u16 rate_flags,
525 const struct ath_rate_table *rate_table, 507 u32 phy, u32 capflag)
526 struct ath_rateset *rateset,
527 u32 capflag)
528{ 508{
529 u8 i, j, hi = 0; 509 if (rate != dot11rate || WLAN_RC_PHY_HT(phy))
510 return false;
530 511
531 /* Use intersection of working rates and valid rates */ 512 if ((rate_flags & WLAN_RC_CAP_MODE(capflag)) != WLAN_RC_CAP_MODE(capflag))
532 for (i = 0; i < rateset->rs_nrates; i++) { 513 return false;
533 for (j = 0; j < rate_table->rate_cnt; j++) {
534 u32 phy = rate_table->info[j].phy;
535 u16 rate_flags = rate_table->info[j].rate_flags;
536 u8 rate = rateset->rs_rates[i];
537 u8 dot11rate = rate_table->info[j].dot11rate;
538
539 /* We allow a rate only if its valid and the
540 * capflag matches one of the validity
541 * (VALID/VALID_20/VALID_40) flags */
542
543 if ((rate == dot11rate) &&
544 (rate_flags & WLAN_RC_CAP_MODE(capflag)) ==
545 WLAN_RC_CAP_MODE(capflag) &&
546 (rate_flags & WLAN_RC_CAP_STREAM(capflag)) &&
547 !WLAN_RC_PHY_HT(phy)) {
548 u8 valid_rate_count = 0;
549
550 if (!ath_rc_valid_phyrate(phy, capflag, 0))
551 continue;
552
553 valid_rate_count =
554 ath_rc_priv->valid_phy_ratecnt[phy];
555
556 ath_rc_priv->valid_phy_rateidx[phy]
557 [valid_rate_count] = j;
558 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
559 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
560 hi = max(hi, j);
561 }
562 }
563 }
564 514
565 return hi; 515 if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag)))
516 return false;
517
518 return true;
566} 519}
567 520
568static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, 521static inline bool ath_rc_check_ht(u8 rate, u8 dot11rate, u16 rate_flags,
569 const struct ath_rate_table *rate_table, 522 u32 phy, u32 capflag)
570 struct ath_rateset *rateset, u32 capflag)
571{ 523{
572 u8 i, j, hi = 0; 524 if (rate != dot11rate || !WLAN_RC_PHY_HT(phy))
525 return false;
526
527 if (!WLAN_RC_PHY_HT_VALID(rate_flags, capflag))
528 return false;
529
530 if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag)))
531 return false;
532
533 return true;
534}
535
536static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, bool legacy)
537{
538 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
539 struct ath_rateset *rateset;
540 u32 phy, capflag = ath_rc_priv->ht_cap;
541 u16 rate_flags;
542 u8 i, j, hi = 0, rate, dot11rate, valid_rate_count;
543
544 if (legacy)
545 rateset = &ath_rc_priv->neg_rates;
546 else
547 rateset = &ath_rc_priv->neg_ht_rates;
573 548
574 /* Use intersection of working rates and valid rates */
575 for (i = 0; i < rateset->rs_nrates; i++) { 549 for (i = 0; i < rateset->rs_nrates; i++) {
576 for (j = 0; j < rate_table->rate_cnt; j++) { 550 for (j = 0; j < rate_table->rate_cnt; j++) {
577 u32 phy = rate_table->info[j].phy; 551 phy = rate_table->info[j].phy;
578 u16 rate_flags = rate_table->info[j].rate_flags; 552 rate_flags = rate_table->info[j].rate_flags;
579 u8 rate = rateset->rs_rates[i]; 553 rate = rateset->rs_rates[i];
580 u8 dot11rate = rate_table->info[j].dot11rate; 554 dot11rate = rate_table->info[j].dot11rate;
581 555
582 if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) || 556 if (legacy &&
583 !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) || 557 !ath_rc_check_legacy(rate, dot11rate,
584 !WLAN_RC_PHY_HT_VALID(rate_flags, capflag)) 558 rate_flags, phy, capflag))
559 continue;
560
561 if (!legacy &&
562 !ath_rc_check_ht(rate, dot11rate,
563 rate_flags, phy, capflag))
585 continue; 564 continue;
586 565
587 if (!ath_rc_valid_phyrate(phy, capflag, 0)) 566 if (!ath_rc_valid_phyrate(phy, capflag, 0))
588 continue; 567 continue;
589 568
590 ath_rc_priv->valid_phy_rateidx[phy] 569 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
591 [ath_rc_priv->valid_phy_ratecnt[phy]] = j; 570 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = j;
592 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 571 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
593 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); 572 ath_rc_priv->valid_rate_index[j] = true;
594 hi = max(hi, j); 573 hi = max(hi, j);
595 } 574 }
596 } 575 }
@@ -598,13 +577,10 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
598 return hi; 577 return hi;
599} 578}
600 579
601/* Finds the highest rate index we can use */ 580static u8 ath_rc_get_highest_rix(struct ath_rate_priv *ath_rc_priv,
602static u8 ath_rc_get_highest_rix(struct ath_softc *sc, 581 int *is_probing)
603 struct ath_rate_priv *ath_rc_priv,
604 const struct ath_rate_table *rate_table,
605 int *is_probing,
606 bool legacy)
607{ 582{
583 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
608 u32 best_thruput, this_thruput, now_msec; 584 u32 best_thruput, this_thruput, now_msec;
609 u8 rate, next_rate, best_rate, maxindex, minindex; 585 u8 rate, next_rate, best_rate, maxindex, minindex;
610 int8_t index = 0; 586 int8_t index = 0;
@@ -624,8 +600,6 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
624 u8 per_thres; 600 u8 per_thres;
625 601
626 rate = ath_rc_priv->valid_rate_index[index]; 602 rate = ath_rc_priv->valid_rate_index[index];
627 if (legacy && !(rate_table->info[rate].rate_flags & RC_LEGACY))
628 continue;
629 if (rate > ath_rc_priv->rate_max_phy) 603 if (rate > ath_rc_priv->rate_max_phy)
630 continue; 604 continue;
631 605
@@ -707,8 +681,6 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
707 rate->count = tries; 681 rate->count = tries;
708 rate->idx = rate_table->info[rix].ratecode; 682 rate->idx = rate_table->info[rix].ratecode;
709 683
710 if (txrc->short_preamble)
711 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
712 if (txrc->rts || rtsctsenable) 684 if (txrc->rts || rtsctsenable)
713 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 685 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
714 686
@@ -726,37 +698,25 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
726 const struct ath_rate_table *rate_table, 698 const struct ath_rate_table *rate_table,
727 struct ieee80211_tx_info *tx_info) 699 struct ieee80211_tx_info *tx_info)
728{ 700{
729 struct ieee80211_tx_rate *rates = tx_info->control.rates; 701 struct ieee80211_bss_conf *bss_conf;
730 int i = 0, rix = 0, cix, enable_g_protection = 0;
731 702
732 /* get the cix for the lowest valid rix */ 703 if (!tx_info->control.vif)
733 for (i = 3; i >= 0; i--) { 704 return;
734 if (rates[i].count && (rates[i].idx >= 0)) { 705 /*
735 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 706 * For legacy frames, mac80211 takes care of CTS protection.
736 break; 707 */
737 } 708 if (!(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS))
738 } 709 return;
739 cix = rate_table->info[rix].ctrl_rate;
740 710
741 /* All protection frames are transmited at 2Mb/s for 802.11g, 711 bss_conf = &tx_info->control.vif->bss_conf;
742 * otherwise we transmit them at 1Mb/s */ 712
743 if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ && 713 if (!bss_conf->basic_rates)
744 !conf_is_ht(&sc->hw->conf)) 714 return;
745 enable_g_protection = 1;
746 715
747 /* 716 /*
748 * If 802.11g protection is enabled, determine whether to use RTS/CTS or 717 * For now, use the lowest allowed basic rate for HT frames.
749 * just CTS. Note that this is only done for OFDM/HT unicast frames.
750 */ 718 */
751 if ((tx_info->control.vif && 719 tx_info->control.rts_cts_rate_idx = __ffs(bss_conf->basic_rates);
752 tx_info->control.vif->bss_conf.use_cts_prot) &&
753 (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
754 WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
755 rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
756 cix = rate_table->info[enable_g_protection].ctrl_rate;
757 }
758
759 tx_info->control.rts_cts_rate_idx = cix;
760} 720}
761 721
762static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, 722static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
@@ -789,14 +749,8 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
789 try_per_rate = 4; 749 try_per_rate = 4;
790 750
791 rate_table = ath_rc_priv->rate_table; 751 rate_table = ath_rc_priv->rate_table;
792 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, 752 rix = ath_rc_get_highest_rix(ath_rc_priv, &is_probe);
793 &is_probe, false);
794 753
795 /*
796 * If we're in HT mode and both us and our peer supports LDPC.
797 * We don't need to check our own device's capabilities as our own
798 * ht capabilities would have already been intersected with our peer's.
799 */
800 if (conf_is_ht(&sc->hw->conf) && 754 if (conf_is_ht(&sc->hw->conf) &&
801 (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) 755 (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
802 tx_info->flags |= IEEE80211_TX_CTL_LDPC; 756 tx_info->flags |= IEEE80211_TX_CTL_LDPC;
@@ -806,52 +760,45 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
806 tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT); 760 tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
807 761
808 if (is_probe) { 762 if (is_probe) {
809 /* set one try for probe rates. For the 763 /*
810 * probes don't enable rts */ 764 * Set one try for probe rates. For the
765 * probes don't enable RTS.
766 */
811 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 767 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
812 1, rix, 0); 768 1, rix, 0);
813 769 /*
814 /* Get the next tried/allowed rate. No RTS for the next series 770 * Get the next tried/allowed rate.
815 * after the probe rate 771 * No RTS for the next series after the probe rate.
816 */ 772 */
817 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); 773 ath_rc_get_lower_rix(ath_rc_priv, rix, &rix);
818 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 774 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
819 try_per_rate, rix, 0); 775 try_per_rate, rix, 0);
820 776
821 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 777 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
822 } else { 778 } else {
823 /* Set the chosen rate. No RTS for first series entry. */ 779 /*
780 * Set the chosen rate. No RTS for first series entry.
781 */
824 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 782 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
825 try_per_rate, rix, 0); 783 try_per_rate, rix, 0);
826 } 784 }
827 785
828 /* Fill in the other rates for multirate retry */ 786 for ( ; i < 4; i++) {
829 for ( ; i < 3; i++) { 787 /*
788 * Use twice the number of tries for the last MRR segment.
789 */
790 if (i + 1 == 4)
791 try_per_rate = 8;
792
793 ath_rc_get_lower_rix(ath_rc_priv, rix, &rix);
830 794
831 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); 795 /*
832 /* All other rates in the series have RTS enabled */ 796 * All other rates in the series have RTS enabled.
797 */
833 ath_rc_rate_set_series(rate_table, &rates[i], txrc, 798 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
834 try_per_rate, rix, 1); 799 try_per_rate, rix, 1);
835 } 800 }
836 801
837 /* Use twice the number of tries for the last MRR segment. */
838 try_per_rate = 8;
839
840 /*
841 * If the last rate in the rate series is MCS and has
842 * more than 80% of per thresh, then use a legacy rate
843 * as last retry to ensure that the frame is tried in both
844 * MCS and legacy rate.
845 */
846 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
847 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy) &&
848 (ath_rc_priv->per[rix] > 45))
849 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
850 &is_probe, true);
851
852 /* All other rates in the series have RTS enabled */
853 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
854 try_per_rate, rix, 1);
855 /* 802 /*
856 * NB:Change rate series to enable aggregation when operating 803 * NB:Change rate series to enable aggregation when operating
857 * at lower MCS rates. When first rate in series is MCS2 804 * at lower MCS rates. When first rate in series is MCS2
@@ -893,7 +840,6 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
893 rates[0].count = ATH_TXMAXTRY; 840 rates[0].count = ATH_TXMAXTRY;
894 } 841 }
895 842
896 /* Setup RTS/CTS */
897 ath_rc_rate_set_rtscts(sc, rate_table, tx_info); 843 ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
898} 844}
899 845
@@ -1046,9 +992,6 @@ static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
1046 stats->per = per; 992 stats->per = per;
1047} 993}
1048 994
1049/* Update PER, RSSI and whatever else that the code thinks it is doing.
1050 If you can make sense of all this, you really need to go out more. */
1051
1052static void ath_rc_update_ht(struct ath_softc *sc, 995static void ath_rc_update_ht(struct ath_softc *sc,
1053 struct ath_rate_priv *ath_rc_priv, 996 struct ath_rate_priv *ath_rc_priv,
1054 struct ieee80211_tx_info *tx_info, 997 struct ieee80211_tx_info *tx_info,
@@ -1077,8 +1020,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1077 if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 && 1020 if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 &&
1078 rate_table->info[tx_rate].ratekbps <= 1021 rate_table->info[tx_rate].ratekbps <=
1079 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { 1022 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1080 ath_rc_get_lower_rix(rate_table, ath_rc_priv, 1023 ath_rc_get_lower_rix(ath_rc_priv, (u8)tx_rate,
1081 (u8)tx_rate, &ath_rc_priv->rate_max_phy); 1024 &ath_rc_priv->rate_max_phy);
1082 1025
1083 /* Don't probe for a little while. */ 1026 /* Don't probe for a little while. */
1084 ath_rc_priv->probe_time = now_msec; 1027 ath_rc_priv->probe_time = now_msec;
@@ -1122,25 +1065,42 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1122 1065
1123} 1066}
1124 1067
1068static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1069{
1070 struct ath_rc_stats *stats;
1071
1072 stats = &rc->rcstats[final_rate];
1073 stats->success++;
1074}
1125 1075
1126static void ath_rc_tx_status(struct ath_softc *sc, 1076static void ath_rc_tx_status(struct ath_softc *sc,
1127 struct ath_rate_priv *ath_rc_priv, 1077 struct ath_rate_priv *ath_rc_priv,
1128 struct ieee80211_tx_info *tx_info, 1078 struct sk_buff *skb)
1129 int final_ts_idx, int xretries, int long_retry)
1130{ 1079{
1131 const struct ath_rate_table *rate_table; 1080 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1132 struct ieee80211_tx_rate *rates = tx_info->status.rates; 1081 struct ieee80211_tx_rate *rates = tx_info->status.rates;
1082 struct ieee80211_tx_rate *rate;
1083 int final_ts_idx = 0, xretries = 0, long_retry = 0;
1133 u8 flags; 1084 u8 flags;
1134 u32 i = 0, rix; 1085 u32 i = 0, rix;
1135 1086
1136 rate_table = ath_rc_priv->rate_table; 1087 for (i = 0; i < sc->hw->max_rates; i++) {
1088 rate = &tx_info->status.rates[i];
1089 if (rate->idx < 0 || !rate->count)
1090 break;
1091
1092 final_ts_idx = i;
1093 long_retry = rate->count - 1;
1094 }
1095
1096 if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
1097 xretries = 1;
1137 1098
1138 /* 1099 /*
1139 * If the first rate is not the final index, there 1100 * If the first rate is not the final index, there
1140 * are intermediate rate failures to be processed. 1101 * are intermediate rate failures to be processed.
1141 */ 1102 */
1142 if (final_ts_idx != 0) { 1103 if (final_ts_idx != 0) {
1143 /* Process intermediate rates that failed.*/
1144 for (i = 0; i < final_ts_idx ; i++) { 1104 for (i = 0; i < final_ts_idx ; i++) {
1145 if (rates[i].count != 0 && (rates[i].idx >= 0)) { 1105 if (rates[i].count != 0 && (rates[i].idx >= 0)) {
1146 flags = rates[i].flags; 1106 flags = rates[i].flags;
@@ -1152,32 +1112,24 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1152 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) 1112 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1153 return; 1113 return;
1154 1114
1155 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1115 rix = ath_rc_get_rateindex(ath_rc_priv, &rates[i]);
1156 ath_rc_update_ht(sc, ath_rc_priv, tx_info, 1116 ath_rc_update_ht(sc, ath_rc_priv, tx_info,
1157 rix, xretries ? 1 : 2, 1117 rix, xretries ? 1 : 2,
1158 rates[i].count); 1118 rates[i].count);
1159 } 1119 }
1160 } 1120 }
1161 } else {
1162 /*
1163 * Handle the special case of MIMO PS burst, where the second
1164 * aggregate is sent out with only one rate and one try.
1165 * Treating it as an excessive retry penalizes the rate
1166 * inordinately.
1167 */
1168 if (rates[0].count == 1 && xretries == 1)
1169 xretries = 2;
1170 } 1121 }
1171 1122
1172 flags = rates[i].flags; 1123 flags = rates[final_ts_idx].flags;
1173 1124
1174 /* If HT40 and we have switched mode from 40 to 20 => don't update */ 1125 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1175 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 1126 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1176 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) 1127 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1177 return; 1128 return;
1178 1129
1179 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1130 rix = ath_rc_get_rateindex(ath_rc_priv, &rates[final_ts_idx]);
1180 ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry); 1131 ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry);
1132 ath_debug_stat_rc(ath_rc_priv, rix);
1181} 1133}
1182 1134
1183static const 1135static const
@@ -1185,8 +1137,6 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1185 enum ieee80211_band band, 1137 enum ieee80211_band band,
1186 bool is_ht) 1138 bool is_ht)
1187{ 1139{
1188 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1189
1190 switch(band) { 1140 switch(band) {
1191 case IEEE80211_BAND_2GHZ: 1141 case IEEE80211_BAND_2GHZ:
1192 if (is_ht) 1142 if (is_ht)
@@ -1197,34 +1147,25 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1197 return &ar5416_11na_ratetable; 1147 return &ar5416_11na_ratetable;
1198 return &ar5416_11a_ratetable; 1148 return &ar5416_11a_ratetable;
1199 default: 1149 default:
1200 ath_dbg(common, CONFIG, "Invalid band\n");
1201 return NULL; 1150 return NULL;
1202 } 1151 }
1203} 1152}
1204 1153
1205static void ath_rc_init(struct ath_softc *sc, 1154static void ath_rc_init(struct ath_softc *sc,
1206 struct ath_rate_priv *ath_rc_priv, 1155 struct ath_rate_priv *ath_rc_priv)
1207 struct ieee80211_supported_band *sband,
1208 struct ieee80211_sta *sta,
1209 const struct ath_rate_table *rate_table)
1210{ 1156{
1157 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
1211 struct ath_rateset *rateset = &ath_rc_priv->neg_rates; 1158 struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
1212 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1159 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1213 struct ath_rateset *ht_mcs = &ath_rc_priv->neg_ht_rates;
1214 u8 i, j, k, hi = 0, hthi = 0; 1160 u8 i, j, k, hi = 0, hthi = 0;
1215 1161
1216 /* Initial rate table size. Will change depending
1217 * on the working rate set */
1218 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1162 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1219 1163
1220 /* Initialize thresholds according to the global rate table */
1221 for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) { 1164 for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1222 ath_rc_priv->per[i] = 0; 1165 ath_rc_priv->per[i] = 0;
1166 ath_rc_priv->valid_rate_index[i] = 0;
1223 } 1167 }
1224 1168
1225 /* Determine the valid rates */
1226 ath_rc_init_valid_rate_idx(ath_rc_priv);
1227
1228 for (i = 0; i < WLAN_RC_PHY_MAX; i++) { 1169 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1229 for (j = 0; j < RATE_TABLE_SIZE; j++) 1170 for (j = 0; j < RATE_TABLE_SIZE; j++)
1230 ath_rc_priv->valid_phy_rateidx[i][j] = 0; 1171 ath_rc_priv->valid_phy_rateidx[i][j] = 0;
@@ -1232,25 +1173,19 @@ static void ath_rc_init(struct ath_softc *sc,
1232 } 1173 }
1233 1174
1234 if (!rateset->rs_nrates) { 1175 if (!rateset->rs_nrates) {
1235 /* No working rate, just initialize valid rates */ 1176 hi = ath_rc_init_validrates(ath_rc_priv);
1236 hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1237 ath_rc_priv->ht_cap);
1238 } else { 1177 } else {
1239 /* Use intersection of working rates and valid rates */ 1178 hi = ath_rc_setvalid_rates(ath_rc_priv, true);
1240 hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table, 1179
1241 rateset, ath_rc_priv->ht_cap); 1180 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG)
1242 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { 1181 hthi = ath_rc_setvalid_rates(ath_rc_priv, false);
1243 hthi = ath_rc_setvalid_htrates(ath_rc_priv, 1182
1244 rate_table,
1245 ht_mcs,
1246 ath_rc_priv->ht_cap);
1247 }
1248 hi = max(hi, hthi); 1183 hi = max(hi, hthi);
1249 } 1184 }
1250 1185
1251 ath_rc_priv->rate_table_size = hi + 1; 1186 ath_rc_priv->rate_table_size = hi + 1;
1252 ath_rc_priv->rate_max_phy = 0; 1187 ath_rc_priv->rate_max_phy = 0;
1253 BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE); 1188 WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1254 1189
1255 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { 1190 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1256 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { 1191 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
@@ -1258,28 +1193,26 @@ static void ath_rc_init(struct ath_softc *sc,
1258 ath_rc_priv->valid_phy_rateidx[i][j]; 1193 ath_rc_priv->valid_phy_rateidx[i][j];
1259 } 1194 }
1260 1195
1261 if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) 1196 if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) ||
1262 || !ath_rc_priv->valid_phy_ratecnt[i]) 1197 !ath_rc_priv->valid_phy_ratecnt[i])
1263 continue; 1198 continue;
1264 1199
1265 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1]; 1200 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1266 } 1201 }
1267 BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE); 1202 WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1268 BUG_ON(k > RATE_TABLE_SIZE); 1203 WARN_ON(k > RATE_TABLE_SIZE);
1269 1204
1270 ath_rc_priv->max_valid_rate = k; 1205 ath_rc_priv->max_valid_rate = k;
1271 ath_rc_sort_validrates(rate_table, ath_rc_priv); 1206 ath_rc_sort_validrates(ath_rc_priv);
1272 ath_rc_priv->rate_max_phy = (k > 4) ? 1207 ath_rc_priv->rate_max_phy = (k > 4) ?
1273 ath_rc_priv->valid_rate_index[k-4] : 1208 ath_rc_priv->valid_rate_index[k-4] :
1274 ath_rc_priv->valid_rate_index[k-1]; 1209 ath_rc_priv->valid_rate_index[k-1];
1275 ath_rc_priv->rate_table = rate_table;
1276 1210
1277 ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n", 1211 ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n",
1278 ath_rc_priv->ht_cap); 1212 ath_rc_priv->ht_cap);
1279} 1213}
1280 1214
1281static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, 1215static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta)
1282 bool is_cw40, bool is_sgi)
1283{ 1216{
1284 u8 caps = 0; 1217 u8 caps = 0;
1285 1218
@@ -1289,9 +1222,10 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
1289 caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; 1222 caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
1290 else if (sta->ht_cap.mcs.rx_mask[1]) 1223 else if (sta->ht_cap.mcs.rx_mask[1])
1291 caps |= WLAN_RC_DS_FLAG; 1224 caps |= WLAN_RC_DS_FLAG;
1292 if (is_cw40) 1225 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
1293 caps |= WLAN_RC_40_FLAG; 1226 caps |= WLAN_RC_40_FLAG;
1294 if (is_sgi) 1227 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40 ||
1228 sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
1295 caps |= WLAN_RC_SGI_FLAG; 1229 caps |= WLAN_RC_SGI_FLAG;
1296 } 1230 }
1297 1231
@@ -1319,15 +1253,6 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
1319/* mac80211 Rate Control callbacks */ 1253/* mac80211 Rate Control callbacks */
1320/***********************************/ 1254/***********************************/
1321 1255
1322static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1323{
1324 struct ath_rc_stats *stats;
1325
1326 stats = &rc->rcstats[final_rate];
1327 stats->success++;
1328}
1329
1330
1331static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, 1256static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1332 struct ieee80211_sta *sta, void *priv_sta, 1257 struct ieee80211_sta *sta, void *priv_sta,
1333 struct sk_buff *skb) 1258 struct sk_buff *skb)
@@ -1335,22 +1260,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1335 struct ath_softc *sc = priv; 1260 struct ath_softc *sc = priv;
1336 struct ath_rate_priv *ath_rc_priv = priv_sta; 1261 struct ath_rate_priv *ath_rc_priv = priv_sta;
1337 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1262 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1338 struct ieee80211_hdr *hdr; 1263 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1339 int final_ts_idx = 0, tx_status = 0; 1264 __le16 fc = hdr->frame_control;
1340 int long_retry = 0;
1341 __le16 fc;
1342 int i;
1343
1344 hdr = (struct ieee80211_hdr *)skb->data;
1345 fc = hdr->frame_control;
1346 for (i = 0; i < sc->hw->max_rates; i++) {
1347 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
1348 if (rate->idx < 0 || !rate->count)
1349 break;
1350
1351 final_ts_idx = i;
1352 long_retry = rate->count - 1;
1353 }
1354 1265
1355 if (!priv_sta || !ieee80211_is_data(fc)) 1266 if (!priv_sta || !ieee80211_is_data(fc))
1356 return; 1267 return;
@@ -1363,11 +1274,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1363 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1274 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
1364 return; 1275 return;
1365 1276
1366 if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) 1277 ath_rc_tx_status(sc, ath_rc_priv, skb);
1367 tx_status = 1;
1368
1369 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1370 long_retry);
1371 1278
1372 /* Check if aggregation has to be enabled for this tid */ 1279 /* Check if aggregation has to be enabled for this tid */
1373 if (conf_is_ht(&sc->hw->conf) && 1280 if (conf_is_ht(&sc->hw->conf) &&
@@ -1383,19 +1290,14 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1383 ieee80211_start_tx_ba_session(sta, tid, 0); 1290 ieee80211_start_tx_ba_session(sta, tid, 0);
1384 } 1291 }
1385 } 1292 }
1386
1387 ath_debug_stat_rc(ath_rc_priv,
1388 ath_rc_get_rateindex(ath_rc_priv->rate_table,
1389 &tx_info->status.rates[final_ts_idx]));
1390} 1293}
1391 1294
1392static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1295static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1393 struct ieee80211_sta *sta, void *priv_sta) 1296 struct ieee80211_sta *sta, void *priv_sta)
1394{ 1297{
1395 struct ath_softc *sc = priv; 1298 struct ath_softc *sc = priv;
1299 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1396 struct ath_rate_priv *ath_rc_priv = priv_sta; 1300 struct ath_rate_priv *ath_rc_priv = priv_sta;
1397 const struct ath_rate_table *rate_table;
1398 bool is_cw40, is_sgi = false;
1399 int i, j = 0; 1301 int i, j = 0;
1400 1302
1401 for (i = 0; i < sband->n_bitrates; i++) { 1303 for (i = 0; i < sband->n_bitrates; i++) {
@@ -1417,20 +1319,15 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1417 ath_rc_priv->neg_ht_rates.rs_nrates = j; 1319 ath_rc_priv->neg_ht_rates.rs_nrates = j;
1418 } 1320 }
1419 1321
1420 is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); 1322 ath_rc_priv->rate_table = ath_choose_rate_table(sc, sband->band,
1421 1323 sta->ht_cap.ht_supported);
1422 if (is_cw40) 1324 if (!ath_rc_priv->rate_table) {
1423 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); 1325 ath_err(common, "No rate table chosen\n");
1424 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) 1326 return;
1425 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); 1327 }
1426
1427 /* Choose rate table first */
1428
1429 rate_table = ath_choose_rate_table(sc, sband->band,
1430 sta->ht_cap.ht_supported);
1431 1328
1432 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); 1329 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta);
1433 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1330 ath_rc_init(sc, priv_sta);
1434} 1331}
1435 1332
1436static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, 1333static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
@@ -1439,40 +1336,14 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1439{ 1336{
1440 struct ath_softc *sc = priv; 1337 struct ath_softc *sc = priv;
1441 struct ath_rate_priv *ath_rc_priv = priv_sta; 1338 struct ath_rate_priv *ath_rc_priv = priv_sta;
1442 const struct ath_rate_table *rate_table = NULL;
1443 bool oper_cw40 = false, oper_sgi;
1444 bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
1445 bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG);
1446
1447 /* FIXME: Handle AP mode later when we support CWM */
1448 1339
1449 if (changed & IEEE80211_RC_BW_CHANGED) { 1340 if (changed & IEEE80211_RC_BW_CHANGED) {
1450 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) 1341 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta);
1451 return; 1342 ath_rc_init(sc, priv_sta);
1452 1343
1453 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 1344 ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
1454 oper_cw40 = true; 1345 "Operating HT Bandwidth changed to: %d\n",
1455 1346 sc->hw->conf.channel_type);
1456 if (oper_cw40)
1457 oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1458 true : false;
1459 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
1460 oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1461 true : false;
1462 else
1463 oper_sgi = false;
1464
1465 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
1466 rate_table = ath_choose_rate_table(sc, sband->band,
1467 sta->ht_cap.ht_supported);
1468 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1469 oper_cw40, oper_sgi);
1470 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1471
1472 ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
1473 "Operating HT Bandwidth changed to: %d\n",
1474 sc->hw->conf.channel_type);
1475 }
1476 } 1347 }
1477} 1348}
1478 1349
@@ -1484,7 +1355,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1484 struct ath_rate_priv *rc = file->private_data; 1355 struct ath_rate_priv *rc = file->private_data;
1485 char *buf; 1356 char *buf;
1486 unsigned int len = 0, max; 1357 unsigned int len = 0, max;
1487 int i = 0; 1358 int rix;
1488 ssize_t retval; 1359 ssize_t retval;
1489 1360
1490 if (rc->rate_table == NULL) 1361 if (rc->rate_table == NULL)
@@ -1500,7 +1371,8 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1500 "HT", "MCS", "Rate", 1371 "HT", "MCS", "Rate",
1501 "Success", "Retries", "XRetries", "PER"); 1372 "Success", "Retries", "XRetries", "PER");
1502 1373
1503 for (i = 0; i < rc->rate_table_size; i++) { 1374 for (rix = 0; rix < rc->max_valid_rate; rix++) {
1375 u8 i = rc->valid_rate_index[rix];
1504 u32 ratekbps = rc->rate_table->info[i].ratekbps; 1376 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1505 struct ath_rc_stats *stats = &rc->rcstats[i]; 1377 struct ath_rc_stats *stats = &rc->rcstats[i];
1506 char mcs[5]; 1378 char mcs[5];
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 75f8e9b06b28..268e67dc5fb2 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -160,10 +160,6 @@ struct ath_rate_table {
160 u32 user_ratekbps; 160 u32 user_ratekbps;
161 u8 ratecode; 161 u8 ratecode;
162 u8 dot11rate; 162 u8 dot11rate;
163 u8 ctrl_rate;
164 u8 cw40index;
165 u8 sgi_index;
166 u8 ht_index;
167 } info[RATE_TABLE_SIZE]; 163 } info[RATE_TABLE_SIZE];
168 u32 probe_interval; 164 u32 probe_interval;
169 u8 initial_ratemax; 165 u8 initial_ratemax;
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index c5ca6f1f5836..24ac2876a733 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -341,6 +341,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
341 if (SUPP(CARL9170FW_WLANTX_CAB)) { 341 if (SUPP(CARL9170FW_WLANTX_CAB)) {
342 if_comb_types |= 342 if_comb_types |=
343 BIT(NL80211_IFTYPE_AP) | 343 BIT(NL80211_IFTYPE_AP) |
344 BIT(NL80211_IFTYPE_MESH_POINT) |
344 BIT(NL80211_IFTYPE_P2P_GO); 345 BIT(NL80211_IFTYPE_P2P_GO);
345 } 346 }
346 } 347 }
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 53415bfd8bef..f8676280dc36 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -318,10 +318,10 @@ int carl9170_set_operating_mode(struct ar9170 *ar)
318 bssid = common->curbssid; 318 bssid = common->curbssid;
319 319
320 switch (vif->type) { 320 switch (vif->type) {
321 case NL80211_IFTYPE_MESH_POINT:
322 case NL80211_IFTYPE_ADHOC: 321 case NL80211_IFTYPE_ADHOC:
323 cam_mode |= AR9170_MAC_CAM_IBSS; 322 cam_mode |= AR9170_MAC_CAM_IBSS;
324 break; 323 break;
324 case NL80211_IFTYPE_MESH_POINT:
325 case NL80211_IFTYPE_AP: 325 case NL80211_IFTYPE_AP:
326 cam_mode |= AR9170_MAC_CAM_AP; 326 cam_mode |= AR9170_MAC_CAM_AP;
327 327
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 858e58dfc4dc..18554ab76733 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -616,10 +616,12 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw,
616 616
617 goto unlock; 617 goto unlock;
618 618
619 case NL80211_IFTYPE_MESH_POINT:
619 case NL80211_IFTYPE_AP: 620 case NL80211_IFTYPE_AP:
620 if ((vif->type == NL80211_IFTYPE_STATION) || 621 if ((vif->type == NL80211_IFTYPE_STATION) ||
621 (vif->type == NL80211_IFTYPE_WDS) || 622 (vif->type == NL80211_IFTYPE_WDS) ||
622 (vif->type == NL80211_IFTYPE_AP)) 623 (vif->type == NL80211_IFTYPE_AP) ||
624 (vif->type == NL80211_IFTYPE_MESH_POINT))
623 break; 625 break;
624 626
625 err = -EBUSY; 627 err = -EBUSY;
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 6f6a34155667..b813f43061f5 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -206,6 +206,7 @@ void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
206 206
207 case NL80211_IFTYPE_AP: 207 case NL80211_IFTYPE_AP:
208 case NL80211_IFTYPE_ADHOC: 208 case NL80211_IFTYPE_ADHOC:
209 case NL80211_IFTYPE_MESH_POINT:
209 carl9170_update_beacon(ar, true); 210 carl9170_update_beacon(ar, true);
210 break; 211 break;
211 212
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 4648bbf76abc..098fe9ee7096 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -4,6 +4,7 @@ b43-y += tables.o
4b43-$(CONFIG_B43_PHY_N) += tables_nphy.o 4b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
5b43-$(CONFIG_B43_PHY_N) += radio_2055.o 5b43-$(CONFIG_B43_PHY_N) += radio_2055.o
6b43-$(CONFIG_B43_PHY_N) += radio_2056.o 6b43-$(CONFIG_B43_PHY_N) += radio_2056.o
7b43-$(CONFIG_B43_PHY_N) += radio_2057.o
7b43-y += phy_common.o 8b43-y += phy_common.o
8b43-y += phy_g.o 9b43-y += phy_g.o
9b43-y += phy_a.o 10b43-y += phy_a.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 7c899fc7ddd0..b298e5d68be2 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -241,16 +241,18 @@ enum {
241#define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ 241#define B43_SHM_SH_PHYVER 0x0050 /* PHY version */
242#define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ 242#define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */
243#define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ 243#define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */
244#define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */ 244#define B43_SHM_SH_HOSTF1 0x005E /* Hostflags 1 for ucode options */
245#define B43_SHM_SH_HOSTFMI 0x0060 /* Hostflags for ucode options (middle) */ 245#define B43_SHM_SH_HOSTF2 0x0060 /* Hostflags 2 for ucode options */
246#define B43_SHM_SH_HOSTFHI 0x0062 /* Hostflags for ucode options (high) */ 246#define B43_SHM_SH_HOSTF3 0x0062 /* Hostflags 3 for ucode options */
247#define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */ 247#define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */
248#define B43_SHM_SH_RADAR 0x0066 /* Radar register */ 248#define B43_SHM_SH_RADAR 0x0066 /* Radar register */
249#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ 249#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */
250#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */ 250#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */
251#define B43_SHM_SH_HOSTF4 0x0078 /* Hostflags 4 for ucode options */
251#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ 252#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
252#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ 253#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */
253#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ 254#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */
255#define B43_SHM_SH_HOSTF5 0x00D4 /* Hostflags 5 for ucode options */
254#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ 256#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
255/* TSSI information */ 257/* TSSI information */
256#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */ 258#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
@@ -415,6 +417,8 @@ enum {
415#define B43_PHYTYPE_HT 0x07 417#define B43_PHYTYPE_HT 0x07
416#define B43_PHYTYPE_LCN 0x08 418#define B43_PHYTYPE_LCN 0x08
417#define B43_PHYTYPE_LCNXN 0x09 419#define B43_PHYTYPE_LCNXN 0x09
420#define B43_PHYTYPE_LCN40 0x0a
421#define B43_PHYTYPE_AC 0x0b
418 422
419/* PHYRegisters */ 423/* PHYRegisters */
420#define B43_PHY_ILT_A_CTRL 0x0072 424#define B43_PHY_ILT_A_CTRL 0x0072
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a140165dfee0..d97a95b1addb 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -533,11 +533,11 @@ u64 b43_hf_read(struct b43_wldev *dev)
533{ 533{
534 u64 ret; 534 u64 ret;
535 535
536 ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI); 536 ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF3);
537 ret <<= 16; 537 ret <<= 16;
538 ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI); 538 ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF2);
539 ret <<= 16; 539 ret <<= 16;
540 ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO); 540 ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1);
541 541
542 return ret; 542 return ret;
543} 543}
@@ -550,9 +550,9 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
550 lo = (value & 0x00000000FFFFULL); 550 lo = (value & 0x00000000FFFFULL);
551 mi = (value & 0x0000FFFF0000ULL) >> 16; 551 mi = (value & 0x0000FFFF0000ULL) >> 16;
552 hi = (value & 0xFFFF00000000ULL) >> 32; 552 hi = (value & 0xFFFF00000000ULL) >> 32;
553 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO, lo); 553 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1, lo);
554 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI, mi); 554 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF2, mi);
555 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); 555 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF3, hi);
556} 556}
557 557
558/* Read the firmware capabilities bitmask (Opensource firmware only) */ 558/* Read the firmware capabilities bitmask (Opensource firmware only) */
@@ -4282,6 +4282,35 @@ out:
4282 return err; 4282 return err;
4283} 4283}
4284 4284
4285static char *b43_phy_name(struct b43_wldev *dev, u8 phy_type)
4286{
4287 switch (phy_type) {
4288 case B43_PHYTYPE_A:
4289 return "A";
4290 case B43_PHYTYPE_B:
4291 return "B";
4292 case B43_PHYTYPE_G:
4293 return "G";
4294 case B43_PHYTYPE_N:
4295 return "N";
4296 case B43_PHYTYPE_LP:
4297 return "LP";
4298 case B43_PHYTYPE_SSLPN:
4299 return "SSLPN";
4300 case B43_PHYTYPE_HT:
4301 return "HT";
4302 case B43_PHYTYPE_LCN:
4303 return "LCN";
4304 case B43_PHYTYPE_LCNXN:
4305 return "LCNXN";
4306 case B43_PHYTYPE_LCN40:
4307 return "LCN40";
4308 case B43_PHYTYPE_AC:
4309 return "AC";
4310 }
4311 return "UNKNOWN";
4312}
4313
4285/* Get PHY and RADIO versioning numbers */ 4314/* Get PHY and RADIO versioning numbers */
4286static int b43_phy_versioning(struct b43_wldev *dev) 4315static int b43_phy_versioning(struct b43_wldev *dev)
4287{ 4316{
@@ -4342,13 +4371,13 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4342 unsupported = 1; 4371 unsupported = 1;
4343 } 4372 }
4344 if (unsupported) { 4373 if (unsupported) {
4345 b43err(dev->wl, "FOUND UNSUPPORTED PHY " 4374 b43err(dev->wl, "FOUND UNSUPPORTED PHY (Analog %u, Type %d (%s), Revision %u)\n",
4346 "(Analog %u, Type %u, Revision %u)\n", 4375 analog_type, phy_type, b43_phy_name(dev, phy_type),
4347 analog_type, phy_type, phy_rev); 4376 phy_rev);
4348 return -EOPNOTSUPP; 4377 return -EOPNOTSUPP;
4349 } 4378 }
4350 b43dbg(dev->wl, "Found PHY: Analog %u, Type %u, Revision %u\n", 4379 b43info(dev->wl, "Found PHY: Analog %u, Type %d (%s), Revision %u\n",
4351 analog_type, phy_type, phy_rev); 4380 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
4352 4381
4353 /* Get RADIO versioning */ 4382 /* Get RADIO versioning */
4354 if (dev->dev->core_rev >= 24) { 4383 if (dev->dev->core_rev >= 24) {
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 3f8883b14d9c..f01676ac481b 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -240,6 +240,21 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
240 (b43_radio_read16(dev, offset) & mask) | set); 240 (b43_radio_read16(dev, offset) & mask) | set);
241} 241}
242 242
243bool b43_radio_wait_value(struct b43_wldev *dev, u16 offset, u16 mask,
244 u16 value, int delay, int timeout)
245{
246 u16 val;
247 int i;
248
249 for (i = 0; i < timeout; i += delay) {
250 val = b43_radio_read(dev, offset);
251 if ((val & mask) == value)
252 return true;
253 udelay(delay);
254 }
255 return false;
256}
257
243u16 b43_phy_read(struct b43_wldev *dev, u16 reg) 258u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
244{ 259{
245 assert_mac_suspended(dev); 260 assert_mac_suspended(dev);
@@ -428,7 +443,7 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
428 average = (a + b + c + d + 2) / 4; 443 average = (a + b + c + d + 2) / 4;
429 if (is_ofdm) { 444 if (is_ofdm) {
430 /* Adjust for CCK-boost */ 445 /* Adjust for CCK-boost */
431 if (b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO) 446 if (b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1)
432 & B43_HF_CCKBOOST) 447 & B43_HF_CCKBOOST)
433 average = (average >= 13) ? (average - 13) : 0; 448 average = (average >= 13) ? (average - 13) : 0;
434 } 449 }
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 9233b13fc16d..f1b999349876 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -365,6 +365,12 @@ void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
365void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set); 365void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
366 366
367/** 367/**
368 * b43_radio_wait_value - Waits for a given value in masked register read
369 */
370bool b43_radio_wait_value(struct b43_wldev *dev, u16 offset, u16 mask,
371 u16 value, int delay, int timeout);
372
373/**
368 * b43_radio_lock - Lock firmware radio register access 374 * b43_radio_lock - Lock firmware radio register access
369 */ 375 */
370void b43_radio_lock(struct b43_wldev *dev); 376void b43_radio_lock(struct b43_wldev *dev);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b92bb9c92ad1..3c35382ee6c2 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -32,6 +32,7 @@
32#include "tables_nphy.h" 32#include "tables_nphy.h"
33#include "radio_2055.h" 33#include "radio_2055.h"
34#include "radio_2056.h" 34#include "radio_2056.h"
35#include "radio_2057.h"
35#include "main.h" 36#include "main.h"
36 37
37struct nphy_txgains { 38struct nphy_txgains {
@@ -126,6 +127,46 @@ ok:
126 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); 127 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
127} 128}
128 129
130/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
131static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field,
132 u16 value, u8 core, bool off,
133 u8 override)
134{
135 const struct nphy_rf_control_override_rev7 *e;
136 u16 en_addrs[3][2] = {
137 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
138 };
139 u16 en_addr;
140 u16 en_mask = field;
141 u16 val_addr;
142 u8 i;
143
144 /* Remember: we can get NULL! */
145 e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
146
147 for (i = 0; i < 2; i++) {
148 if (override >= ARRAY_SIZE(en_addrs)) {
149 b43err(dev->wl, "Invalid override value %d\n", override);
150 return;
151 }
152 en_addr = en_addrs[override][i];
153
154 val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1;
155
156 if (off) {
157 b43_phy_mask(dev, en_addr, ~en_mask);
158 if (e) /* Do it safer, better than wl */
159 b43_phy_mask(dev, val_addr, ~e->val_mask);
160 } else {
161 if (!core || (core & (1 << i))) {
162 b43_phy_set(dev, en_addr, en_mask);
163 if (e)
164 b43_phy_maskset(dev, val_addr, ~e->val_mask, (value << e->val_shift));
165 }
166 }
167 }
168}
169
129/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ 170/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
130static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, 171static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
131 u16 value, u8 core, bool off) 172 u16 value, u8 core, bool off)
@@ -459,6 +500,137 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
459} 500}
460 501
461/************************************************** 502/**************************************************
503 * Radio 0x2057
504 **************************************************/
505
506/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
507static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
508{
509 struct b43_phy *phy = &dev->phy;
510 u16 tmp;
511
512 if (phy->radio_rev == 5) {
513 b43_phy_mask(dev, 0x342, ~0x2);
514 udelay(10);
515 b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
516 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
517 }
518
519 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
520 udelay(10);
521 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
522 if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
523 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
524 return 0;
525 }
526 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
527 tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
528 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
529
530 if (phy->radio_rev == 5) {
531 b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
532 b43_radio_mask(dev, 0x1ca, ~0x2);
533 }
534 if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
535 b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
536 b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
537 tmp << 2);
538 }
539
540 return tmp & 0x3e;
541}
542
543/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
544static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
545{
546 struct b43_phy *phy = &dev->phy;
547 bool special = (phy->radio_rev == 3 || phy->radio_rev == 4 ||
548 phy->radio_rev == 6);
549 u16 tmp;
550
551 if (special) {
552 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
553 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
554 } else {
555 b43_radio_write(dev, 0x1AE, 0x61);
556 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
557 }
558 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
559 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
560 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
561 5000000))
562 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
563 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
564 if (special) {
565 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
566 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
567 } else {
568 b43_radio_write(dev, 0x1AE, 0x69);
569 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
570 }
571 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
572 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
573 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
574 5000000))
575 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
576 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
577 if (special) {
578 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
579 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
580 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
581 } else {
582 b43_radio_write(dev, 0x1AE, 0x73);
583 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
584 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
585 }
586 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
587 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
588 5000000)) {
589 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
590 return 0;
591 }
592 tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
593 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
594 return tmp;
595}
596
597static void b43_radio_2057_init_pre(struct b43_wldev *dev)
598{
599 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_CHIP0PU);
600 /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
601 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_OEPORFORCE);
602 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
603 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_CHIP0PU);
604}
605
606static void b43_radio_2057_init_post(struct b43_wldev *dev)
607{
608 b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
609
610 b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
611 b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
612 mdelay(2);
613 b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
614 b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
615
616 if (dev->phy.n->init_por) {
617 b43_radio_2057_rcal(dev);
618 b43_radio_2057_rccal(dev);
619 }
620 b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
621
622 dev->phy.n->init_por = false;
623}
624
625/* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
626static void b43_radio_2057_init(struct b43_wldev *dev)
627{
628 b43_radio_2057_init_pre(dev);
629 r2057_upload_inittabs(dev);
630 b43_radio_2057_init_post(dev);
631}
632
633/**************************************************
462 * Radio 0x2056 634 * Radio 0x2056
463 **************************************************/ 635 **************************************************/
464 636
@@ -545,7 +717,9 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
545 enum ieee80211_band band = b43_current_band(dev->wl); 717 enum ieee80211_band band = b43_current_band(dev->wl);
546 u16 offset; 718 u16 offset;
547 u8 i; 719 u8 i;
548 u16 bias, cbias, pag_boost, pgag_boost, mixg_boost, padg_boost; 720 u16 bias, cbias;
721 u16 pag_boost, padg_boost, pgag_boost, mixg_boost;
722 u16 paa_boost, pada_boost, pgaa_boost, mixa_boost;
549 723
550 B43_WARN_ON(dev->phy.rev < 3); 724 B43_WARN_ON(dev->phy.rev < 3);
551 725
@@ -630,7 +804,56 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
630 b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee); 804 b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
631 } 805 }
632 } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) { 806 } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
633 /* TODO */ 807 u16 freq = dev->phy.channel_freq;
808 if (freq < 5100) {
809 paa_boost = 0xA;
810 pada_boost = 0x77;
811 pgaa_boost = 0xF;
812 mixa_boost = 0xF;
813 } else if (freq < 5340) {
814 paa_boost = 0x8;
815 pada_boost = 0x77;
816 pgaa_boost = 0xFB;
817 mixa_boost = 0xF;
818 } else if (freq < 5650) {
819 paa_boost = 0x0;
820 pada_boost = 0x77;
821 pgaa_boost = 0xB;
822 mixa_boost = 0xF;
823 } else {
824 paa_boost = 0x0;
825 pada_boost = 0x77;
826 if (freq != 5825)
827 pgaa_boost = -(freq - 18) / 36 + 168;
828 else
829 pgaa_boost = 6;
830 mixa_boost = 0xF;
831 }
832
833 for (i = 0; i < 2; i++) {
834 offset = i ? B2056_TX1 : B2056_TX0;
835
836 b43_radio_write(dev,
837 offset | B2056_TX_INTPAA_BOOST_TUNE, paa_boost);
838 b43_radio_write(dev,
839 offset | B2056_TX_PADA_BOOST_TUNE, pada_boost);
840 b43_radio_write(dev,
841 offset | B2056_TX_PGAA_BOOST_TUNE, pgaa_boost);
842 b43_radio_write(dev,
843 offset | B2056_TX_MIXA_BOOST_TUNE, mixa_boost);
844 b43_radio_write(dev,
845 offset | B2056_TX_TXSPARE1, 0x30);
846 b43_radio_write(dev,
847 offset | B2056_TX_PA_SPARE2, 0xee);
848 b43_radio_write(dev,
849 offset | B2056_TX_PADA_CASCBIAS, 0x03);
850 b43_radio_write(dev,
851 offset | B2056_TX_INTPAA_IAUX_STAT, 0x50);
852 b43_radio_write(dev,
853 offset | B2056_TX_INTPAA_IMAIN_STAT, 0x50);
854 b43_radio_write(dev,
855 offset | B2056_TX_INTPAA_CASCBIAS, 0x30);
856 }
634 } 857 }
635 858
636 udelay(50); 859 udelay(50);
@@ -643,6 +866,37 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
643 udelay(300); 866 udelay(300);
644} 867}
645 868
869static u8 b43_radio_2056_rcal(struct b43_wldev *dev)
870{
871 struct b43_phy *phy = &dev->phy;
872 u16 mast2, tmp;
873
874 if (phy->rev != 3)
875 return 0;
876
877 mast2 = b43_radio_read(dev, B2056_SYN_PLL_MAST2);
878 b43_radio_write(dev, B2056_SYN_PLL_MAST2, mast2 | 0x7);
879
880 udelay(10);
881 b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x01);
882 udelay(10);
883 b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x09);
884
885 if (!b43_radio_wait_value(dev, B2056_SYN_RCAL_CODE_OUT, 0x80, 0x80, 100,
886 1000000)) {
887 b43err(dev->wl, "Radio recalibration timeout\n");
888 return 0;
889 }
890
891 b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x01);
892 tmp = b43_radio_read(dev, B2056_SYN_RCAL_CODE_OUT);
893 b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x00);
894
895 b43_radio_write(dev, B2056_SYN_PLL_MAST2, mast2);
896
897 return tmp & 0x1f;
898}
899
646static void b43_radio_init2056_pre(struct b43_wldev *dev) 900static void b43_radio_init2056_pre(struct b43_wldev *dev)
647{ 901{
648 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, 902 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
@@ -665,10 +919,8 @@ static void b43_radio_init2056_post(struct b43_wldev *dev)
665 b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2); 919 b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
666 b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC); 920 b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
667 b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1); 921 b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
668 /* 922 if (dev->phy.n->init_por)
669 if (nphy->init_por) 923 b43_radio_2056_rcal(dev);
670 Call Radio 2056 Recalibrate
671 */
672} 924}
673 925
674/* 926/*
@@ -680,6 +932,8 @@ static void b43_radio_init2056(struct b43_wldev *dev)
680 b43_radio_init2056_pre(dev); 932 b43_radio_init2056_pre(dev);
681 b2056_upload_inittabs(dev, 0, 0); 933 b2056_upload_inittabs(dev, 0, 0);
682 b43_radio_init2056_post(dev); 934 b43_radio_init2056_post(dev);
935
936 dev->phy.n->init_por = false;
683} 937}
684 938
685/************************************************** 939/**************************************************
@@ -753,8 +1007,6 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
753{ 1007{
754 struct b43_phy_n *nphy = dev->phy.n; 1008 struct b43_phy_n *nphy = dev->phy.n;
755 struct ssb_sprom *sprom = dev->dev->bus_sprom; 1009 struct ssb_sprom *sprom = dev->dev->bus_sprom;
756 int i;
757 u16 val;
758 bool workaround = false; 1010 bool workaround = false;
759 1011
760 if (sprom->revision < 4) 1012 if (sprom->revision < 4)
@@ -777,15 +1029,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
777 b43_radio_set(dev, B2055_CAL_MISC, 0x1); 1029 b43_radio_set(dev, B2055_CAL_MISC, 0x1);
778 msleep(1); 1030 msleep(1);
779 b43_radio_set(dev, B2055_CAL_MISC, 0x40); 1031 b43_radio_set(dev, B2055_CAL_MISC, 0x40);
780 for (i = 0; i < 200; i++) { 1032 if (!b43_radio_wait_value(dev, B2055_CAL_COUT2, 0x80, 0x80, 10, 2000))
781 val = b43_radio_read(dev, B2055_CAL_COUT2);
782 if (val & 0x80) {
783 i = 0;
784 break;
785 }
786 udelay(10);
787 }
788 if (i)
789 b43err(dev->wl, "radio post init timeout\n"); 1033 b43err(dev->wl, "radio post init timeout\n");
790 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 1034 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
791 b43_switch_channel(dev, dev->phy.channel); 1035 b43_switch_channel(dev, dev->phy.channel);
@@ -1860,12 +2104,334 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
1860/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 2104/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
1861static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev) 2105static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
1862{ 2106{
1863 if (dev->phy.rev >= 3) 2107 if (dev->phy.rev >= 7)
2108 ; /* TODO */
2109 else if (dev->phy.rev >= 3)
1864 b43_nphy_gain_ctl_workarounds_rev3plus(dev); 2110 b43_nphy_gain_ctl_workarounds_rev3plus(dev);
1865 else 2111 else
1866 b43_nphy_gain_ctl_workarounds_rev1_2(dev); 2112 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
1867} 2113}
1868 2114
2115/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
2116static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
2117{
2118 if (!offset)
2119 offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
2120 return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
2121}
2122
2123static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2124{
2125 struct ssb_sprom *sprom = dev->dev->bus_sprom;
2126 struct b43_phy *phy = &dev->phy;
2127
2128 u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
2129 0x1F };
2130 u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
2131
2132 u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
2133 u8 ntab7_138_146[] = { 0x11, 0x11 };
2134 u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
2135
2136 u16 lpf_20, lpf_40, lpf_11b;
2137 u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
2138 u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
2139 bool rccal_ovrd = false;
2140
2141 u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
2142 u16 bias, conv, filt;
2143
2144 u32 tmp32;
2145 u8 core;
2146
2147 if (phy->rev == 7) {
2148 b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
2149 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
2150 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0x80FF, 0x2700);
2151 b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0xFF80, 0x002E);
2152 b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0x80FF, 0x3300);
2153 b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0xFF80, 0x0037);
2154 b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0x80FF, 0x3A00);
2155 b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0xFF80, 0x003C);
2156 b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0x80FF, 0x3E00);
2157 b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0xFF80, 0x003E);
2158 b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0x80FF, 0x3F00);
2159 b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0xFF80, 0x0040);
2160 b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0x80FF, 0x4000);
2161 b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0xFF80, 0x0040);
2162 b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0x80FF, 0x4000);
2163 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
2164 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
2165 }
2166 if (phy->rev <= 8) {
2167 b43_phy_write(dev, 0x23F, 0x1B0);
2168 b43_phy_write(dev, 0x240, 0x1B0);
2169 }
2170 if (phy->rev >= 8)
2171 b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
2172
2173 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
2174 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 2);
2175 tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
2176 tmp32 &= 0xffffff;
2177 b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
2178 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
2179 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
2180
2181 if (b43_nphy_ipa(dev))
2182 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
2183 rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
2184
2185 b43_phy_maskset(dev, 0x299, 0x3FFF, 0x4000);
2186 b43_phy_maskset(dev, 0x29D, 0x3FFF, 0x4000);
2187
2188 lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
2189 lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
2190 lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
2191 if (b43_nphy_ipa(dev)) {
2192 if ((phy->radio_rev == 5 && phy->is_40mhz) ||
2193 phy->radio_rev == 7 || phy->radio_rev == 8) {
2194 bcap_val = b43_radio_read(dev, 0x16b);
2195 scap_val = b43_radio_read(dev, 0x16a);
2196 scap_val_11b = scap_val;
2197 bcap_val_11b = bcap_val;
2198 if (phy->radio_rev == 5 && phy->is_40mhz) {
2199 scap_val_11n_20 = scap_val;
2200 bcap_val_11n_20 = bcap_val;
2201 scap_val_11n_40 = bcap_val_11n_40 = 0xc;
2202 rccal_ovrd = true;
2203 } else { /* Rev 7/8 */
2204 lpf_20 = 4;
2205 lpf_11b = 1;
2206 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2207 scap_val_11n_20 = 0xc;
2208 bcap_val_11n_20 = 0xc;
2209 scap_val_11n_40 = 0xa;
2210 bcap_val_11n_40 = 0xa;
2211 } else {
2212 scap_val_11n_20 = 0x14;
2213 bcap_val_11n_20 = 0x14;
2214 scap_val_11n_40 = 0xf;
2215 bcap_val_11n_40 = 0xf;
2216 }
2217 rccal_ovrd = true;
2218 }
2219 }
2220 } else {
2221 if (phy->radio_rev == 5) {
2222 lpf_20 = 1;
2223 lpf_40 = 3;
2224 bcap_val = b43_radio_read(dev, 0x16b);
2225 scap_val = b43_radio_read(dev, 0x16a);
2226 scap_val_11b = scap_val;
2227 bcap_val_11b = bcap_val;
2228 scap_val_11n_20 = 0x11;
2229 scap_val_11n_40 = 0x11;
2230 bcap_val_11n_20 = 0x13;
2231 bcap_val_11n_40 = 0x13;
2232 rccal_ovrd = true;
2233 }
2234 }
2235 if (rccal_ovrd) {
2236 rx2tx_lut_20_11b = (bcap_val_11b << 8) |
2237 (scap_val_11b << 3) |
2238 lpf_11b;
2239 rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
2240 (scap_val_11n_20 << 3) |
2241 lpf_20;
2242 rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
2243 (scap_val_11n_40 << 3) |
2244 lpf_40;
2245 for (core = 0; core < 2; core++) {
2246 b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
2247 rx2tx_lut_20_11b);
2248 b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
2249 rx2tx_lut_20_11n);
2250 b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
2251 rx2tx_lut_20_11n);
2252 b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
2253 rx2tx_lut_40_11n);
2254 b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
2255 rx2tx_lut_40_11n);
2256 b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
2257 rx2tx_lut_40_11n);
2258 b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
2259 rx2tx_lut_40_11n);
2260 b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
2261 rx2tx_lut_40_11n);
2262 }
2263 b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, false, 2);
2264 }
2265 b43_phy_write(dev, 0x32F, 0x3);
2266 if (phy->radio_rev == 4 || phy->radio_rev == 6)
2267 b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, false, 0);
2268
2269 if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) {
2270 if (sprom->revision &&
2271 sprom->boardflags2_hi & B43_BFH2_IPALVLSHIFT_3P3) {
2272 b43_radio_write(dev, 0x5, 0x05);
2273 b43_radio_write(dev, 0x6, 0x30);
2274 b43_radio_write(dev, 0x7, 0x00);
2275 b43_radio_set(dev, 0x4f, 0x1);
2276 b43_radio_set(dev, 0xd4, 0x1);
2277 bias = 0x1f;
2278 conv = 0x6f;
2279 filt = 0xaa;
2280 } else {
2281 bias = 0x2b;
2282 conv = 0x7f;
2283 filt = 0xee;
2284 }
2285 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2286 for (core = 0; core < 2; core++) {
2287 if (core == 0) {
2288 b43_radio_write(dev, 0x5F, bias);
2289 b43_radio_write(dev, 0x64, conv);
2290 b43_radio_write(dev, 0x66, filt);
2291 } else {
2292 b43_radio_write(dev, 0xE8, bias);
2293 b43_radio_write(dev, 0xE9, conv);
2294 b43_radio_write(dev, 0xEB, filt);
2295 }
2296 }
2297 }
2298 }
2299
2300 if (b43_nphy_ipa(dev)) {
2301 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2302 if (phy->radio_rev == 3 || phy->radio_rev == 4 ||
2303 phy->radio_rev == 6) {
2304 for (core = 0; core < 2; core++) {
2305 if (core == 0)
2306 b43_radio_write(dev, 0x51,
2307 0x7f);
2308 else
2309 b43_radio_write(dev, 0xd6,
2310 0x7f);
2311 }
2312 }
2313 if (phy->radio_rev == 3) {
2314 for (core = 0; core < 2; core++) {
2315 if (core == 0) {
2316 b43_radio_write(dev, 0x64,
2317 0x13);
2318 b43_radio_write(dev, 0x5F,
2319 0x1F);
2320 b43_radio_write(dev, 0x66,
2321 0xEE);
2322 b43_radio_write(dev, 0x59,
2323 0x8A);
2324 b43_radio_write(dev, 0x80,
2325 0x3E);
2326 } else {
2327 b43_radio_write(dev, 0x69,
2328 0x13);
2329 b43_radio_write(dev, 0xE8,
2330 0x1F);
2331 b43_radio_write(dev, 0xEB,
2332 0xEE);
2333 b43_radio_write(dev, 0xDE,
2334 0x8A);
2335 b43_radio_write(dev, 0x105,
2336 0x3E);
2337 }
2338 }
2339 } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2340 if (!phy->is_40mhz) {
2341 b43_radio_write(dev, 0x5F, 0x14);
2342 b43_radio_write(dev, 0xE8, 0x12);
2343 } else {
2344 b43_radio_write(dev, 0x5F, 0x16);
2345 b43_radio_write(dev, 0xE8, 0x16);
2346 }
2347 }
2348 } else {
2349 u16 freq = phy->channel_freq;
2350 if ((freq >= 5180 && freq <= 5230) ||
2351 (freq >= 5745 && freq <= 5805)) {
2352 b43_radio_write(dev, 0x7D, 0xFF);
2353 b43_radio_write(dev, 0xFE, 0xFF);
2354 }
2355 }
2356 } else {
2357 if (phy->radio_rev != 5) {
2358 for (core = 0; core < 2; core++) {
2359 if (core == 0) {
2360 b43_radio_write(dev, 0x5c, 0x61);
2361 b43_radio_write(dev, 0x51, 0x70);
2362 } else {
2363 b43_radio_write(dev, 0xe1, 0x61);
2364 b43_radio_write(dev, 0xd6, 0x70);
2365 }
2366 }
2367 }
2368 }
2369
2370 if (phy->radio_rev == 4) {
2371 b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2372 b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2373 for (core = 0; core < 2; core++) {
2374 if (core == 0) {
2375 b43_radio_write(dev, 0x1a1, 0x00);
2376 b43_radio_write(dev, 0x1a2, 0x3f);
2377 b43_radio_write(dev, 0x1a6, 0x3f);
2378 } else {
2379 b43_radio_write(dev, 0x1a7, 0x00);
2380 b43_radio_write(dev, 0x1ab, 0x3f);
2381 b43_radio_write(dev, 0x1ac, 0x3f);
2382 }
2383 }
2384 } else {
2385 b43_phy_set(dev, B43_NPHY_AFECTL_C1, 0x4);
2386 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x4);
2387 b43_phy_set(dev, B43_NPHY_AFECTL_C2, 0x4);
2388 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4);
2389
2390 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x1);
2391 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
2392 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
2393 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
2394 b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2395 b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2396
2397 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
2398 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
2399 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x4);
2400 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4);
2401 }
2402
2403 b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
2404
2405 b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
2406 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
2407 b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
2408 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
2409 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
2410 b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
2411 b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
2412
2413 if (!phy->is_40mhz) {
2414 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
2415 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
2416 } else {
2417 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
2418 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
2419 }
2420
2421 b43_nphy_gain_ctl_workarounds(dev);
2422
2423 /* TODO
2424 b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4,
2425 aux_adc_vmid_rev7_core0);
2426 b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4,
2427 aux_adc_vmid_rev7_core1);
2428 b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0C), 4,
2429 aux_adc_gain_rev7);
2430 b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1C), 4,
2431 aux_adc_gain_rev7);
2432 */
2433}
2434
1869static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) 2435static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
1870{ 2436{
1871 struct b43_phy_n *nphy = dev->phy.n; 2437 struct b43_phy_n *nphy = dev->phy.n;
@@ -1916,7 +2482,7 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
1916 rx2tx_delays[6] = 1; 2482 rx2tx_delays[6] = 1;
1917 rx2tx_events[7] = 0x1F; 2483 rx2tx_events[7] = 0x1F;
1918 } 2484 }
1919 b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, 2485 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events, rx2tx_delays,
1920 ARRAY_SIZE(rx2tx_events)); 2486 ARRAY_SIZE(rx2tx_events));
1921 } 2487 }
1922 2488
@@ -1926,8 +2492,13 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
1926 2492
1927 b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); 2493 b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700);
1928 2494
1929 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); 2495 if (!dev->phy.is_40mhz) {
1930 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); 2496 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
2497 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
2498 } else {
2499 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x14D);
2500 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x14D);
2501 }
1931 2502
1932 b43_nphy_gain_ctl_workarounds(dev); 2503 b43_nphy_gain_ctl_workarounds(dev);
1933 2504
@@ -1963,13 +2534,14 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
1963 b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); 2534 b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32);
1964 2535
1965 if (dev->phy.rev == 4 && 2536 if (dev->phy.rev == 4 &&
1966 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { 2537 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1967 b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, 2538 b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC,
1968 0x70); 2539 0x70);
1969 b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, 2540 b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC,
1970 0x70); 2541 0x70);
1971 } 2542 }
1972 2543
2544 /* Dropped probably-always-true condition */
1973 b43_phy_write(dev, 0x224, 0x03eb); 2545 b43_phy_write(dev, 0x224, 0x03eb);
1974 b43_phy_write(dev, 0x225, 0x03eb); 2546 b43_phy_write(dev, 0x225, 0x03eb);
1975 b43_phy_write(dev, 0x226, 0x0341); 2547 b43_phy_write(dev, 0x226, 0x0341);
@@ -1982,6 +2554,9 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
1982 b43_phy_write(dev, 0x22d, 0x042b); 2554 b43_phy_write(dev, 0x22d, 0x042b);
1983 b43_phy_write(dev, 0x22e, 0x0381); 2555 b43_phy_write(dev, 0x22e, 0x0381);
1984 b43_phy_write(dev, 0x22f, 0x0381); 2556 b43_phy_write(dev, 0x22f, 0x0381);
2557
2558 if (dev->phy.rev >= 6 && sprom->boardflags2_lo & B43_BFL2_SINGLEANT_CCK)
2559 ; /* TODO: 0x0080000000000000 HF */
1985} 2560}
1986 2561
1987static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) 2562static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
@@ -1996,6 +2571,12 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
1996 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; 2571 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
1997 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; 2572 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
1998 2573
2574 if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD ||
2575 dev->dev->board_type == 0x8B) {
2576 delays1[0] = 0x1;
2577 delays1[5] = 0x14;
2578 }
2579
1999 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && 2580 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
2000 nphy->band5g_pwrgain) { 2581 nphy->band5g_pwrgain) {
2001 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); 2582 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
@@ -2007,8 +2588,10 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
2007 2588
2008 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); 2589 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
2009 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); 2590 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
2010 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); 2591 if (dev->phy.rev < 3) {
2011 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); 2592 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
2593 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
2594 }
2012 2595
2013 if (dev->phy.rev < 2) { 2596 if (dev->phy.rev < 2) {
2014 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); 2597 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
@@ -2024,11 +2607,6 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
2024 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); 2607 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
2025 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); 2608 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
2026 2609
2027 if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD &&
2028 dev->dev->board_type == 0x8B) {
2029 delays1[0] = 0x1;
2030 delays1[5] = 0x14;
2031 }
2032 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); 2610 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
2033 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); 2611 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
2034 2612
@@ -2055,11 +2633,13 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
2055 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); 2633 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
2056 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); 2634 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
2057 2635
2058 b43_phy_mask(dev, B43_NPHY_PIL_DW1, 2636 if (dev->phy.rev < 3) {
2059 ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); 2637 b43_phy_mask(dev, B43_NPHY_PIL_DW1,
2060 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); 2638 ~B43_NPHY_PIL_DW_64QAM & 0xFFFF);
2061 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); 2639 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
2062 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); 2640 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
2641 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
2642 }
2063 2643
2064 if (dev->phy.rev == 2) 2644 if (dev->phy.rev == 2)
2065 b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 2645 b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
@@ -2083,7 +2663,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
2083 b43_phy_set(dev, B43_NPHY_IQFLIP, 2663 b43_phy_set(dev, B43_NPHY_IQFLIP,
2084 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); 2664 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
2085 2665
2086 if (dev->phy.rev >= 3) 2666 if (dev->phy.rev >= 7)
2667 b43_nphy_workarounds_rev7plus(dev);
2668 else if (dev->phy.rev >= 3)
2087 b43_nphy_workarounds_rev3plus(dev); 2669 b43_nphy_workarounds_rev3plus(dev);
2088 else 2670 else
2089 b43_nphy_workarounds_rev1_2(dev); 2671 b43_nphy_workarounds_rev1_2(dev);
@@ -2542,7 +3124,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
2542 b43_nphy_ipa_internal_tssi_setup(dev); 3124 b43_nphy_ipa_internal_tssi_setup(dev);
2543 3125
2544 if (phy->rev >= 7) 3126 if (phy->rev >= 7)
2545 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 0, 0 as arguments */ 3127 b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, false, 0);
2546 else if (phy->rev >= 3) 3128 else if (phy->rev >= 3)
2547 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false); 3129 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false);
2548 3130
@@ -2554,7 +3136,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
2554 b43_nphy_rssi_select(dev, 0, 0); 3136 b43_nphy_rssi_select(dev, 0, 0);
2555 3137
2556 if (phy->rev >= 7) 3138 if (phy->rev >= 7)
2557 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 1, 0 as arguments */ 3139 b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, true, 0);
2558 else if (phy->rev >= 3) 3140 else if (phy->rev >= 3)
2559 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true); 3141 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true);
2560 3142
@@ -4761,6 +5343,7 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
4761 nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4); 5343 nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
4762 nphy->spur_avoid = (phy->rev >= 3) ? 5344 nphy->spur_avoid = (phy->rev >= 3) ?
4763 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE; 5345 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
5346 nphy->init_por = true;
4764 nphy->gain_boost = true; /* this way we follow wl, assume it is true */ 5347 nphy->gain_boost = true; /* this way we follow wl, assume it is true */
4765 nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ 5348 nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
4766 nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */ 5349 nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
@@ -4801,6 +5384,8 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
4801 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2; 5384 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
4802 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2; 5385 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
4803 } 5386 }
5387
5388 nphy->init_por = true;
4804} 5389}
4805 5390
4806static void b43_nphy_op_free(struct b43_wldev *dev) 5391static void b43_nphy_op_free(struct b43_wldev *dev)
@@ -4887,7 +5472,9 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
4887 if (blocked) { 5472 if (blocked) {
4888 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, 5473 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
4889 ~B43_NPHY_RFCTL_CMD_CHIP0PU); 5474 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
4890 if (dev->phy.rev >= 3) { 5475 if (dev->phy.rev >= 7) {
5476 /* TODO */
5477 } else if (dev->phy.rev >= 3) {
4891 b43_radio_mask(dev, 0x09, ~0x2); 5478 b43_radio_mask(dev, 0x09, ~0x2);
4892 5479
4893 b43_radio_write(dev, 0x204D, 0); 5480 b43_radio_write(dev, 0x204D, 0);
@@ -4905,7 +5492,10 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
4905 b43_radio_write(dev, 0x3064, 0); 5492 b43_radio_write(dev, 0x3064, 0);
4906 } 5493 }
4907 } else { 5494 } else {
4908 if (dev->phy.rev >= 3) { 5495 if (dev->phy.rev >= 7) {
5496 b43_radio_2057_init(dev);
5497 b43_switch_channel(dev, dev->phy.channel);
5498 } else if (dev->phy.rev >= 3) {
4909 b43_radio_init2056(dev); 5499 b43_radio_init2056(dev);
4910 b43_switch_channel(dev, dev->phy.channel); 5500 b43_switch_channel(dev, dev->phy.channel);
4911 } else { 5501 } else {
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index fd12b386fea1..092c0140c249 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -785,6 +785,7 @@ struct b43_phy_n {
785 u16 papd_epsilon_offset[2]; 785 u16 papd_epsilon_offset[2];
786 s32 preamble_override; 786 s32 preamble_override;
787 u32 bb_mult_save; 787 u32 bb_mult_save;
788 bool init_por;
788 789
789 bool gain_boost; 790 bool gain_boost;
790 bool elna_gain_config; 791 bool elna_gain_config;
diff --git a/drivers/net/wireless/b43/radio_2057.c b/drivers/net/wireless/b43/radio_2057.c
new file mode 100644
index 000000000000..d61d6830c5c7
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2057.c
@@ -0,0 +1,141 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n 2057 radio device data tables
5
6 Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22
23*/
24
25#include "b43.h"
26#include "radio_2057.h"
27#include "phy_common.h"
28
29static u16 r2057_rev4_init[42][2] = {
30 { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
31 { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
32 { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
33 { 0x8C, 0xf0 }, { 0x91, 0x3f }, { 0x92, 0x36 }, { 0xA4, 0x8c },
34 { 0xA8, 0x55 }, { 0xAF, 0x01 }, { 0x10F, 0xf0 }, { 0x110, 0x10 },
35 { 0x111, 0xf0 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x129, 0x8c },
36 { 0x12D, 0x55 }, { 0x134, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
37 { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
38 { 0x169, 0x02 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
39 { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
40 { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
41};
42
43static u16 r2057_rev5_init[44][2] = {
44 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
45 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
46 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
47 { 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
48 { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
49 { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
50 { 0x117, 0x36 }, { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
51 { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
52 { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 },
53 { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 },
54 { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
55};
56
57static u16 r2057_rev5a_init[45][2] = {
58 { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
59 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
60 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
61 { 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
62 { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
63 { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
64 { 0x117, 0x36 }, { 0x126, 0x20 }, { 0x14E, 0x01 }, { 0x15E, 0x00 },
65 { 0x15F, 0x00 }, { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 },
66 { 0x163, 0x00 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
67 { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
68 { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 },
69 { 0x1C2, 0x80 },
70};
71
72static u16 r2057_rev7_init[54][2] = {
73 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
74 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
75 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
76 { 0x66, 0xee }, { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 },
77 { 0x7C, 0x14 }, { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f },
78 { 0x92, 0x36 }, { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
79 { 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x13 }, { 0xEB, 0xee },
80 { 0xF3, 0x58 }, { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x14 },
81 { 0x102, 0xee }, { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 },
82 { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
83 { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
84 { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
85 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
86 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
87};
88
89static u16 r2057_rev8_init[54][2] = {
90 { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
91 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
92 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
93 { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, { 0x7C, 0x0f },
94 { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
95 { 0xA1, 0x20 }, { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
96 { 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0xF3, 0x58 },
97 { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x0f }, { 0x102, 0xee },
98 { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x126, 0x20 },
99 { 0x14E, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
100 { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
101 { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
102 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
103 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
104};
105
106void r2057_upload_inittabs(struct b43_wldev *dev)
107{
108 struct b43_phy *phy = &dev->phy;
109 u16 *table = NULL;
110 u16 size, i;
111
112 if (phy->rev == 7) {
113 table = r2057_rev4_init[0];
114 size = ARRAY_SIZE(r2057_rev4_init);
115 } else if (phy->rev == 8 || phy->rev == 9) {
116 if (phy->radio_rev == 5) {
117 if (phy->radio_rev == 8) {
118 table = r2057_rev5_init[0];
119 size = ARRAY_SIZE(r2057_rev5_init);
120 } else {
121 table = r2057_rev5a_init[0];
122 size = ARRAY_SIZE(r2057_rev5a_init);
123 }
124 } else if (phy->radio_rev == 7) {
125 table = r2057_rev7_init[0];
126 size = ARRAY_SIZE(r2057_rev7_init);
127 } else if (phy->radio_rev == 9) {
128 table = r2057_rev8_init[0];
129 size = ARRAY_SIZE(r2057_rev8_init);
130 }
131 }
132
133 if (table) {
134 for (i = 0; i < 10; i++) {
135 pr_info("radio_write 0x%X ", *table);
136 table++;
137 pr_info("0x%X\n", *table);
138 table++;
139 }
140 }
141}
diff --git a/drivers/net/wireless/b43/radio_2057.h b/drivers/net/wireless/b43/radio_2057.h
new file mode 100644
index 000000000000..eeebd8fbeb0d
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2057.h
@@ -0,0 +1,430 @@
1#ifndef B43_RADIO_2057_H_
2#define B43_RADIO_2057_H_
3
4#include <linux/types.h>
5
6#include "tables_nphy.h"
7
8#define R2057_DACBUF_VINCM_CORE0 0x000
9#define R2057_IDCODE 0x001
10#define R2057_RCCAL_MASTER 0x002
11#define R2057_RCCAL_CAP_SIZE 0x003
12#define R2057_RCAL_CONFIG 0x004
13#define R2057_GPAIO_CONFIG 0x005
14#define R2057_GPAIO_SEL1 0x006
15#define R2057_GPAIO_SEL0 0x007
16#define R2057_CLPO_CONFIG 0x008
17#define R2057_BANDGAP_CONFIG 0x009
18#define R2057_BANDGAP_RCAL_TRIM 0x00a
19#define R2057_AFEREG_CONFIG 0x00b
20#define R2057_TEMPSENSE_CONFIG 0x00c
21#define R2057_XTAL_CONFIG1 0x00d
22#define R2057_XTAL_ICORE_SIZE 0x00e
23#define R2057_XTAL_BUF_SIZE 0x00f
24#define R2057_XTAL_PULLCAP_SIZE 0x010
25#define R2057_RFPLL_MASTER 0x011
26#define R2057_VCOMONITOR_VTH_L 0x012
27#define R2057_VCOMONITOR_VTH_H 0x013
28#define R2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x014
29#define R2057_VCO_VARCSIZE_IDAC 0x015
30#define R2057_VCOCAL_COUNTVAL0 0x016
31#define R2057_VCOCAL_COUNTVAL1 0x017
32#define R2057_VCOCAL_INTCLK_COUNT 0x018
33#define R2057_VCOCAL_MASTER 0x019
34#define R2057_VCOCAL_NUMCAPCHANGE 0x01a
35#define R2057_VCOCAL_WINSIZE 0x01b
36#define R2057_VCOCAL_DELAY_AFTER_REFRESH 0x01c
37#define R2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x01d
38#define R2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x01e
39#define R2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x01f
40#define R2057_VCO_FORCECAPEN_FORCECAP1 0x020
41#define R2057_VCO_FORCECAP0 0x021
42#define R2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x022
43#define R2057_RFPLL_PFD_RESET_PW 0x023
44#define R2057_RFPLL_LOOPFILTER_R2 0x024
45#define R2057_RFPLL_LOOPFILTER_R1 0x025
46#define R2057_RFPLL_LOOPFILTER_C3 0x026
47#define R2057_RFPLL_LOOPFILTER_C2 0x027
48#define R2057_RFPLL_LOOPFILTER_C1 0x028
49#define R2057_CP_KPD_IDAC 0x029
50#define R2057_RFPLL_IDACS 0x02a
51#define R2057_RFPLL_MISC_EN 0x02b
52#define R2057_RFPLL_MMD0 0x02c
53#define R2057_RFPLL_MMD1 0x02d
54#define R2057_RFPLL_MISC_CAL_RESETN 0x02e
55#define R2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x02f
56#define R2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x030
57#define R2057_VCOCAL_READCAP0 0x031
58#define R2057_VCOCAL_READCAP1 0x032
59#define R2057_VCOCAL_STATUS 0x033
60#define R2057_LOGEN_PUS 0x034
61#define R2057_LOGEN_PTAT_RESETS 0x035
62#define R2057_VCOBUF_IDACS 0x036
63#define R2057_VCOBUF_TUNE 0x037
64#define R2057_CMOSBUF_TX2GQ_IDACS 0x038
65#define R2057_CMOSBUF_TX2GI_IDACS 0x039
66#define R2057_CMOSBUF_TX5GQ_IDACS 0x03a
67#define R2057_CMOSBUF_TX5GI_IDACS 0x03b
68#define R2057_CMOSBUF_RX2GQ_IDACS 0x03c
69#define R2057_CMOSBUF_RX2GI_IDACS 0x03d
70#define R2057_CMOSBUF_RX5GQ_IDACS 0x03e
71#define R2057_CMOSBUF_RX5GI_IDACS 0x03f
72#define R2057_LOGEN_MX2G_IDACS 0x040
73#define R2057_LOGEN_MX2G_TUNE 0x041
74#define R2057_LOGEN_MX5G_IDACS 0x042
75#define R2057_LOGEN_MX5G_TUNE 0x043
76#define R2057_LOGEN_MX5G_RCCR 0x044
77#define R2057_LOGEN_INDBUF2G_IDAC 0x045
78#define R2057_LOGEN_INDBUF2G_IBOOST 0x046
79#define R2057_LOGEN_INDBUF2G_TUNE 0x047
80#define R2057_LOGEN_INDBUF5G_IDAC 0x048
81#define R2057_LOGEN_INDBUF5G_IBOOST 0x049
82#define R2057_LOGEN_INDBUF5G_TUNE 0x04a
83#define R2057_CMOSBUF_TX_RCCR 0x04b
84#define R2057_CMOSBUF_RX_RCCR 0x04c
85#define R2057_LOGEN_SEL_PKDET 0x04d
86#define R2057_CMOSBUF_SHAREIQ_PTAT 0x04e
87#define R2057_RXTXBIAS_CONFIG_CORE0 0x04f
88#define R2057_TXGM_TXRF_PUS_CORE0 0x050
89#define R2057_TXGM_IDAC_BLEED_CORE0 0x051
90#define R2057_TXGM_GAIN_CORE0 0x056
91#define R2057_TXGM2G_PKDET_PUS_CORE0 0x057
92#define R2057_PAD2G_PTATS_CORE0 0x058
93#define R2057_PAD2G_IDACS_CORE0 0x059
94#define R2057_PAD2G_BOOST_PU_CORE0 0x05a
95#define R2057_PAD2G_CASCV_GAIN_CORE0 0x05b
96#define R2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x05c
97#define R2057_TXMIX2G_LODC_CORE0 0x05d
98#define R2057_PAD2G_TUNE_PUS_CORE0 0x05e
99#define R2057_IPA2G_GAIN_CORE0 0x05f
100#define R2057_TSSI2G_SPARE1_CORE0 0x060
101#define R2057_TSSI2G_SPARE2_CORE0 0x061
102#define R2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x062
103#define R2057_IPA2G_IMAIN_CORE0 0x063
104#define R2057_IPA2G_CASCONV_CORE0 0x064
105#define R2057_IPA2G_CASCOFFV_CORE0 0x065
106#define R2057_IPA2G_BIAS_FILTER_CORE0 0x066
107#define R2057_TX5G_PKDET_CORE0 0x069
108#define R2057_PGA_PTAT_TXGM5G_PU_CORE0 0x06a
109#define R2057_PAD5G_PTATS1_CORE0 0x06b
110#define R2057_PAD5G_CLASS_PTATS2_CORE0 0x06c
111#define R2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x06d
112#define R2057_PAD5G_CASCV_IMAIN_CORE0 0x06e
113#define R2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x06f
114#define R2057_PGA_BOOST_TUNE_CORE0 0x070
115#define R2057_PGA_GAIN_CORE0 0x071
116#define R2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x072
117#define R2057_TXMIX5G_BOOST_TUNE_CORE0 0x073
118#define R2057_PAD5G_TUNE_MISC_PUS_CORE0 0x074
119#define R2057_IPA5G_IAUX_CORE0 0x075
120#define R2057_IPA5G_GAIN_CORE0 0x076
121#define R2057_TSSI5G_SPARE1_CORE0 0x077
122#define R2057_TSSI5G_SPARE2_CORE0 0x078
123#define R2057_IPA5G_CASCOFFV_PU_CORE0 0x079
124#define R2057_IPA5G_PTAT_CORE0 0x07a
125#define R2057_IPA5G_IMAIN_CORE0 0x07b
126#define R2057_IPA5G_CASCONV_CORE0 0x07c
127#define R2057_IPA5G_BIAS_FILTER_CORE0 0x07d
128#define R2057_PAD_BIAS_FILTER_BWS_CORE0 0x080
129#define R2057_TR2G_CONFIG1_CORE0_NU 0x081
130#define R2057_TR2G_CONFIG2_CORE0_NU 0x082
131#define R2057_LNA5G_RFEN_CORE0 0x083
132#define R2057_TR5G_CONFIG2_CORE0_NU 0x084
133#define R2057_RXRFBIAS_IBOOST_PU_CORE0 0x085
134#define R2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x086
135#define R2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x087
136#define R2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x088
137#define R2057_RXMIX_CMFBITAIL_PU_CORE0 0x089
138#define R2057_LNA2_IMAIN_PTAT_PU_CORE0 0x08a
139#define R2057_LNA2_IAUX_PTAT_CORE0 0x08b
140#define R2057_LNA1_IMAIN_PTAT_PU_CORE0 0x08c
141#define R2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x08d
142#define R2057_RXRFBIAS_BANDSEL_CORE0 0x08e
143#define R2057_TIA_CONFIG_CORE0 0x08f
144#define R2057_TIA_IQGAIN_CORE0 0x090
145#define R2057_TIA_IBIAS2_CORE0 0x091
146#define R2057_TIA_IBIAS1_CORE0 0x092
147#define R2057_TIA_SPARE_Q_CORE0 0x093
148#define R2057_TIA_SPARE_I_CORE0 0x094
149#define R2057_RXMIX2G_PUS_CORE0 0x095
150#define R2057_RXMIX2G_VCMREFS_CORE0 0x096
151#define R2057_RXMIX2G_LODC_QI_CORE0 0x097
152#define R2057_W12G_BW_LNA2G_PUS_CORE0 0x098
153#define R2057_LNA2G_GAIN_CORE0 0x099
154#define R2057_LNA2G_TUNE_CORE0 0x09a
155#define R2057_RXMIX5G_PUS_CORE0 0x09b
156#define R2057_RXMIX5G_VCMREFS_CORE0 0x09c
157#define R2057_RXMIX5G_LODC_QI_CORE0 0x09d
158#define R2057_W15G_BW_LNA5G_PUS_CORE0 0x09e
159#define R2057_LNA5G_GAIN_CORE0 0x09f
160#define R2057_LNA5G_TUNE_CORE0 0x0a0
161#define R2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0x0a1
162#define R2057_RXBB_BIAS_MASTER_CORE0 0x0a2
163#define R2057_RXBB_VGABUF_IDACS_CORE0 0x0a3
164#define R2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0x0a4
165#define R2057_TXBUF_VINCM_CORE0 0x0a5
166#define R2057_TXBUF_IDACS_CORE0 0x0a6
167#define R2057_LPF_RESP_RXBUF_BW_CORE0 0x0a7
168#define R2057_RXBB_CC_CORE0 0x0a8
169#define R2057_RXBB_SPARE3_CORE0 0x0a9
170#define R2057_RXBB_RCCAL_HPC_CORE0 0x0aa
171#define R2057_LPF_IDACS_CORE0 0x0ab
172#define R2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0x0ac
173#define R2057_TXBUF_GAIN_CORE0 0x0ad
174#define R2057_AFELOOPBACK_AACI_RESP_CORE0 0x0ae
175#define R2057_RXBUF_DEGEN_CORE0 0x0af
176#define R2057_RXBB_SPARE2_CORE0 0x0b0
177#define R2057_RXBB_SPARE1_CORE0 0x0b1
178#define R2057_RSSI_MASTER_CORE0 0x0b2
179#define R2057_W2_MASTER_CORE0 0x0b3
180#define R2057_NB_MASTER_CORE0 0x0b4
181#define R2057_W2_IDACS0_Q_CORE0 0x0b5
182#define R2057_W2_IDACS1_Q_CORE0 0x0b6
183#define R2057_W2_IDACS0_I_CORE0 0x0b7
184#define R2057_W2_IDACS1_I_CORE0 0x0b8
185#define R2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0x0b9
186#define R2057_NB_IDACS_Q_CORE0 0x0ba
187#define R2057_NB_IDACS_I_CORE0 0x0bb
188#define R2057_BACKUP4_CORE0 0x0c1
189#define R2057_BACKUP3_CORE0 0x0c2
190#define R2057_BACKUP2_CORE0 0x0c3
191#define R2057_BACKUP1_CORE0 0x0c4
192#define R2057_SPARE16_CORE0 0x0c5
193#define R2057_SPARE15_CORE0 0x0c6
194#define R2057_SPARE14_CORE0 0x0c7
195#define R2057_SPARE13_CORE0 0x0c8
196#define R2057_SPARE12_CORE0 0x0c9
197#define R2057_SPARE11_CORE0 0x0ca
198#define R2057_TX2G_BIAS_RESETS_CORE0 0x0cb
199#define R2057_TX5G_BIAS_RESETS_CORE0 0x0cc
200#define R2057_IQTEST_SEL_PU 0x0cd
201#define R2057_XTAL_CONFIG2 0x0ce
202#define R2057_BUFS_MISC_LPFBW_CORE0 0x0cf
203#define R2057_TXLPF_RCCAL_CORE0 0x0d0
204#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0x0d1
205#define R2057_LPF_GAIN_CORE0 0x0d2
206#define R2057_DACBUF_IDACS_BW_CORE0 0x0d3
207#define R2057_RXTXBIAS_CONFIG_CORE1 0x0d4
208#define R2057_TXGM_TXRF_PUS_CORE1 0x0d5
209#define R2057_TXGM_IDAC_BLEED_CORE1 0x0d6
210#define R2057_TXGM_GAIN_CORE1 0x0db
211#define R2057_TXGM2G_PKDET_PUS_CORE1 0x0dc
212#define R2057_PAD2G_PTATS_CORE1 0x0dd
213#define R2057_PAD2G_IDACS_CORE1 0x0de
214#define R2057_PAD2G_BOOST_PU_CORE1 0x0df
215#define R2057_PAD2G_CASCV_GAIN_CORE1 0x0e0
216#define R2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0x0e1
217#define R2057_TXMIX2G_LODC_CORE1 0x0e2
218#define R2057_PAD2G_TUNE_PUS_CORE1 0x0e3
219#define R2057_IPA2G_GAIN_CORE1 0x0e4
220#define R2057_TSSI2G_SPARE1_CORE1 0x0e5
221#define R2057_TSSI2G_SPARE2_CORE1 0x0e6
222#define R2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0x0e7
223#define R2057_IPA2G_IMAIN_CORE1 0x0e8
224#define R2057_IPA2G_CASCONV_CORE1 0x0e9
225#define R2057_IPA2G_CASCOFFV_CORE1 0x0ea
226#define R2057_IPA2G_BIAS_FILTER_CORE1 0x0eb
227#define R2057_TX5G_PKDET_CORE1 0x0ee
228#define R2057_PGA_PTAT_TXGM5G_PU_CORE1 0x0ef
229#define R2057_PAD5G_PTATS1_CORE1 0x0f0
230#define R2057_PAD5G_CLASS_PTATS2_CORE1 0x0f1
231#define R2057_PGA_BOOSTPTAT_IMAIN_CORE1 0x0f2
232#define R2057_PAD5G_CASCV_IMAIN_CORE1 0x0f3
233#define R2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0x0f4
234#define R2057_PGA_BOOST_TUNE_CORE1 0x0f5
235#define R2057_PGA_GAIN_CORE1 0x0f6
236#define R2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0x0f7
237#define R2057_TXMIX5G_BOOST_TUNE_CORE1 0x0f8
238#define R2057_PAD5G_TUNE_MISC_PUS_CORE1 0x0f9
239#define R2057_IPA5G_IAUX_CORE1 0x0fa
240#define R2057_IPA5G_GAIN_CORE1 0x0fb
241#define R2057_TSSI5G_SPARE1_CORE1 0x0fc
242#define R2057_TSSI5G_SPARE2_CORE1 0x0fd
243#define R2057_IPA5G_CASCOFFV_PU_CORE1 0x0fe
244#define R2057_IPA5G_PTAT_CORE1 0x0ff
245#define R2057_IPA5G_IMAIN_CORE1 0x100
246#define R2057_IPA5G_CASCONV_CORE1 0x101
247#define R2057_IPA5G_BIAS_FILTER_CORE1 0x102
248#define R2057_PAD_BIAS_FILTER_BWS_CORE1 0x105
249#define R2057_TR2G_CONFIG1_CORE1_NU 0x106
250#define R2057_TR2G_CONFIG2_CORE1_NU 0x107
251#define R2057_LNA5G_RFEN_CORE1 0x108
252#define R2057_TR5G_CONFIG2_CORE1_NU 0x109
253#define R2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a
254#define R2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
255#define R2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c
256#define R2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d
257#define R2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e
258#define R2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f
259#define R2057_LNA2_IAUX_PTAT_CORE1 0x110
260#define R2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111
261#define R2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
262#define R2057_RXRFBIAS_BANDSEL_CORE1 0x113
263#define R2057_TIA_CONFIG_CORE1 0x114
264#define R2057_TIA_IQGAIN_CORE1 0x115
265#define R2057_TIA_IBIAS2_CORE1 0x116
266#define R2057_TIA_IBIAS1_CORE1 0x117
267#define R2057_TIA_SPARE_Q_CORE1 0x118
268#define R2057_TIA_SPARE_I_CORE1 0x119
269#define R2057_RXMIX2G_PUS_CORE1 0x11a
270#define R2057_RXMIX2G_VCMREFS_CORE1 0x11b
271#define R2057_RXMIX2G_LODC_QI_CORE1 0x11c
272#define R2057_W12G_BW_LNA2G_PUS_CORE1 0x11d
273#define R2057_LNA2G_GAIN_CORE1 0x11e
274#define R2057_LNA2G_TUNE_CORE1 0x11f
275#define R2057_RXMIX5G_PUS_CORE1 0x120
276#define R2057_RXMIX5G_VCMREFS_CORE1 0x121
277#define R2057_RXMIX5G_LODC_QI_CORE1 0x122
278#define R2057_W15G_BW_LNA5G_PUS_CORE1 0x123
279#define R2057_LNA5G_GAIN_CORE1 0x124
280#define R2057_LNA5G_TUNE_CORE1 0x125
281#define R2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126
282#define R2057_RXBB_BIAS_MASTER_CORE1 0x127
283#define R2057_RXBB_VGABUF_IDACS_CORE1 0x128
284#define R2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
285#define R2057_TXBUF_VINCM_CORE1 0x12a
286#define R2057_TXBUF_IDACS_CORE1 0x12b
287#define R2057_LPF_RESP_RXBUF_BW_CORE1 0x12c
288#define R2057_RXBB_CC_CORE1 0x12d
289#define R2057_RXBB_SPARE3_CORE1 0x12e
290#define R2057_RXBB_RCCAL_HPC_CORE1 0x12f
291#define R2057_LPF_IDACS_CORE1 0x130
292#define R2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131
293#define R2057_TXBUF_GAIN_CORE1 0x132
294#define R2057_AFELOOPBACK_AACI_RESP_CORE1 0x133
295#define R2057_RXBUF_DEGEN_CORE1 0x134
296#define R2057_RXBB_SPARE2_CORE1 0x135
297#define R2057_RXBB_SPARE1_CORE1 0x136
298#define R2057_RSSI_MASTER_CORE1 0x137
299#define R2057_W2_MASTER_CORE1 0x138
300#define R2057_NB_MASTER_CORE1 0x139
301#define R2057_W2_IDACS0_Q_CORE1 0x13a
302#define R2057_W2_IDACS1_Q_CORE1 0x13b
303#define R2057_W2_IDACS0_I_CORE1 0x13c
304#define R2057_W2_IDACS1_I_CORE1 0x13d
305#define R2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e
306#define R2057_NB_IDACS_Q_CORE1 0x13f
307#define R2057_NB_IDACS_I_CORE1 0x140
308#define R2057_BACKUP4_CORE1 0x146
309#define R2057_BACKUP3_CORE1 0x147
310#define R2057_BACKUP2_CORE1 0x148
311#define R2057_BACKUP1_CORE1 0x149
312#define R2057_SPARE16_CORE1 0x14a
313#define R2057_SPARE15_CORE1 0x14b
314#define R2057_SPARE14_CORE1 0x14c
315#define R2057_SPARE13_CORE1 0x14d
316#define R2057_SPARE12_CORE1 0x14e
317#define R2057_SPARE11_CORE1 0x14f
318#define R2057_TX2G_BIAS_RESETS_CORE1 0x150
319#define R2057_TX5G_BIAS_RESETS_CORE1 0x151
320#define R2057_SPARE8_CORE1 0x152
321#define R2057_SPARE7_CORE1 0x153
322#define R2057_BUFS_MISC_LPFBW_CORE1 0x154
323#define R2057_TXLPF_RCCAL_CORE1 0x155
324#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
325#define R2057_LPF_GAIN_CORE1 0x157
326#define R2057_DACBUF_IDACS_BW_CORE1 0x158
327#define R2057_DACBUF_VINCM_CORE1 0x159
328#define R2057_RCCAL_START_R1_Q1_P1 0x15a
329#define R2057_RCCAL_X1 0x15b
330#define R2057_RCCAL_TRC0 0x15c
331#define R2057_RCCAL_TRC1 0x15d
332#define R2057_RCCAL_DONE_OSCCAP 0x15e
333#define R2057_RCCAL_N0_0 0x15f
334#define R2057_RCCAL_N0_1 0x160
335#define R2057_RCCAL_N1_0 0x161
336#define R2057_RCCAL_N1_1 0x162
337#define R2057_RCAL_STATUS 0x163
338#define R2057_XTALPUOVR_PINCTRL 0x164
339#define R2057_OVR_REG0 0x165
340#define R2057_OVR_REG1 0x166
341#define R2057_OVR_REG2 0x167
342#define R2057_OVR_REG3 0x168
343#define R2057_OVR_REG4 0x169
344#define R2057_RCCAL_SCAP_VAL 0x16a
345#define R2057_RCCAL_BCAP_VAL 0x16b
346#define R2057_RCCAL_HPC_VAL 0x16c
347#define R2057_RCCAL_OVERRIDES 0x16d
348#define R2057_TX0_IQCAL_GAIN_BW 0x170
349#define R2057_TX0_LOFT_FINE_I 0x171
350#define R2057_TX0_LOFT_FINE_Q 0x172
351#define R2057_TX0_LOFT_COARSE_I 0x173
352#define R2057_TX0_LOFT_COARSE_Q 0x174
353#define R2057_TX0_TX_SSI_MASTER 0x175
354#define R2057_TX0_IQCAL_VCM_HG 0x176
355#define R2057_TX0_IQCAL_IDAC 0x177
356#define R2057_TX0_TSSI_VCM 0x178
357#define R2057_TX0_TX_SSI_MUX 0x179
358#define R2057_TX0_TSSIA 0x17a
359#define R2057_TX0_TSSIG 0x17b
360#define R2057_TX0_TSSI_MISC1 0x17c
361#define R2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d
362#define R2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
363#define R2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
364#define R2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
365#define R2057_TX1_IQCAL_GAIN_BW 0x190
366#define R2057_TX1_LOFT_FINE_I 0x191
367#define R2057_TX1_LOFT_FINE_Q 0x192
368#define R2057_TX1_LOFT_COARSE_I 0x193
369#define R2057_TX1_LOFT_COARSE_Q 0x194
370#define R2057_TX1_TX_SSI_MASTER 0x195
371#define R2057_TX1_IQCAL_VCM_HG 0x196
372#define R2057_TX1_IQCAL_IDAC 0x197
373#define R2057_TX1_TSSI_VCM 0x198
374#define R2057_TX1_TX_SSI_MUX 0x199
375#define R2057_TX1_TSSIA 0x19a
376#define R2057_TX1_TSSIG 0x19b
377#define R2057_TX1_TSSI_MISC1 0x19c
378#define R2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d
379#define R2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
380#define R2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
381#define R2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
382#define R2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
383#define R2057_AFE_SET_VCM_I_CORE0 0x1a2
384#define R2057_AFE_SET_VCM_Q_CORE0 0x1a3
385#define R2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4
386#define R2057_AFE_STATUS_VCM_I_CORE0 0x1a5
387#define R2057_AFE_STATUS_VCM_Q_CORE0 0x1a6
388#define R2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7
389#define R2057_AFE_SET_VCM_I_CORE1 0x1a8
390#define R2057_AFE_SET_VCM_Q_CORE1 0x1a9
391#define R2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa
392#define R2057_AFE_STATUS_VCM_I_CORE1 0x1ab
393#define R2057_AFE_STATUS_VCM_Q_CORE1 0x1ac
394
395#define R2057v7_DACBUF_VINCM_CORE0 0x1ad
396#define R2057v7_RCCAL_MASTER 0x1ae
397#define R2057v7_TR2G_CONFIG3_CORE0_NU 0x1af
398#define R2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0
399#define R2057v7_LOGEN_PUS1 0x1b1
400#define R2057v7_OVR_REG5 0x1b2
401#define R2057v7_OVR_REG6 0x1b3
402#define R2057v7_OVR_REG7 0x1b4
403#define R2057v7_OVR_REG8 0x1b5
404#define R2057v7_OVR_REG9 0x1b6
405#define R2057v7_OVR_REG10 0x1b7
406#define R2057v7_OVR_REG11 0x1b8
407#define R2057v7_OVR_REG12 0x1b9
408#define R2057v7_OVR_REG13 0x1ba
409#define R2057v7_OVR_REG14 0x1bb
410#define R2057v7_OVR_REG15 0x1bc
411#define R2057v7_OVR_REG16 0x1bd
412#define R2057v7_OVR_REG1 0x1be
413#define R2057v7_OVR_REG18 0x1bf
414#define R2057v7_OVR_REG19 0x1c0
415#define R2057v7_OVR_REG20 0x1c1
416#define R2057v7_OVR_REG21 0x1c2
417#define R2057v7_OVR_REG2 0x1c3
418#define R2057v7_OVR_REG23 0x1c4
419#define R2057v7_OVR_REG24 0x1c5
420#define R2057v7_OVR_REG25 0x1c6
421#define R2057v7_OVR_REG26 0x1c7
422#define R2057v7_OVR_REG27 0x1c8
423#define R2057v7_OVR_REG28 0x1c9
424#define R2057v7_IQTEST_SEL_PU2 0x1ca
425
426#define R2057_VCM_MASK 0x7
427
428void r2057_upload_inittabs(struct b43_wldev *dev);
429
430#endif /* B43_RADIO_2057_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index f0d8377429c6..97d4e27bf36f 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2757,6 +2757,49 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
2757 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ 2757 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
2758}; 2758};
2759 2759
2760/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2761static const struct nphy_rf_control_override_rev7
2762 tbl_rf_control_override_rev7_over0[] = {
2763 { 0x0004, 0x07A, 0x07D, 0x0002, 1 },
2764 { 0x0008, 0x07A, 0x07D, 0x0004, 2 },
2765 { 0x0010, 0x07A, 0x07D, 0x0010, 4 },
2766 { 0x0020, 0x07A, 0x07D, 0x0020, 5 },
2767 { 0x0040, 0x07A, 0x07D, 0x0040, 6 },
2768 { 0x0080, 0x0F8, 0x0FA, 0x0080, 7 },
2769 { 0x0400, 0x0F8, 0x0FA, 0x0070, 4 },
2770 { 0x0800, 0x07B, 0x07E, 0xFFFF, 0 },
2771 { 0x1000, 0x07C, 0x07F, 0xFFFF, 0 },
2772 { 0x6000, 0x348, 0x349, 0xFFFF, 0 },
2773 { 0x2000, 0x348, 0x349, 0x000F, 0 },
2774};
2775
2776/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2777static const struct nphy_rf_control_override_rev7
2778 tbl_rf_control_override_rev7_over1[] = {
2779 { 0x0002, 0x340, 0x341, 0x0002, 1 },
2780 { 0x0008, 0x340, 0x341, 0x0008, 3 },
2781 { 0x0020, 0x340, 0x341, 0x0020, 5 },
2782 { 0x0010, 0x340, 0x341, 0x0010, 4 },
2783 { 0x0004, 0x340, 0x341, 0x0004, 2 },
2784 { 0x0080, 0x340, 0x341, 0x0700, 8 },
2785 { 0x0800, 0x340, 0x341, 0x4000, 14 },
2786 { 0x0400, 0x340, 0x341, 0x2000, 13 },
2787 { 0x0200, 0x340, 0x341, 0x0800, 12 },
2788 { 0x0100, 0x340, 0x341, 0x0100, 11 },
2789 { 0x0040, 0x340, 0x341, 0x0040, 6 },
2790 { 0x0001, 0x340, 0x341, 0x0001, 0 },
2791};
2792
2793/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2794static const struct nphy_rf_control_override_rev7
2795 tbl_rf_control_override_rev7_over2[] = {
2796 { 0x0008, 0x344, 0x345, 0x0008, 3 },
2797 { 0x0002, 0x344, 0x345, 0x0002, 1 },
2798 { 0x0001, 0x344, 0x345, 0x0001, 0 },
2799 { 0x0004, 0x344, 0x345, 0x0004, 2 },
2800 { 0x0010, 0x344, 0x345, 0x0010, 4 },
2801};
2802
2760struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = { 2803struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = {
2761 { 10, 14, 19, 27 }, 2804 { 10, 14, 19, 27 },
2762 { -5, 6, 10, 15 }, 2805 { -5, 6, 10, 15 },
@@ -3248,3 +3291,35 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
3248 3291
3249 return e; 3292 return e;
3250} 3293}
3294
3295const struct nphy_rf_control_override_rev7 *b43_nphy_get_rf_ctl_over_rev7(
3296 struct b43_wldev *dev, u16 field, u8 override)
3297{
3298 const struct nphy_rf_control_override_rev7 *e;
3299 u8 size, i;
3300
3301 switch (override) {
3302 case 0:
3303 e = tbl_rf_control_override_rev7_over0;
3304 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over0);
3305 break;
3306 case 1:
3307 e = tbl_rf_control_override_rev7_over1;
3308 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over1);
3309 break;
3310 case 2:
3311 e = tbl_rf_control_override_rev7_over2;
3312 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over2);
3313 break;
3314 default:
3315 b43err(dev->wl, "Invalid override value %d\n", override);
3316 return NULL;
3317 }
3318
3319 for (i = 0; i < size; i++) {
3320 if (e[i].field == field)
3321 return &e[i];
3322 }
3323
3324 return NULL;
3325}
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index f348953c0230..c600700ceedc 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -35,6 +35,14 @@ struct nphy_rf_control_override_rev3 {
35 u8 val_addr1; 35 u8 val_addr1;
36}; 36};
37 37
38struct nphy_rf_control_override_rev7 {
39 u16 field;
40 u16 val_addr_core0;
41 u16 val_addr_core1;
42 u16 val_mask;
43 u8 val_shift;
44};
45
38struct nphy_gain_ctl_workaround_entry { 46struct nphy_gain_ctl_workaround_entry {
39 s8 lna1_gain[4]; 47 s8 lna1_gain[4];
40 s8 lna2_gain[4]; 48 s8 lna2_gain[4];
@@ -202,5 +210,7 @@ extern const struct nphy_rf_control_override_rev2
202 tbl_rf_control_override_rev2[]; 210 tbl_rf_control_override_rev2[];
203extern const struct nphy_rf_control_override_rev3 211extern const struct nphy_rf_control_override_rev3
204 tbl_rf_control_override_rev3[]; 212 tbl_rf_control_override_rev3[];
213const struct nphy_rf_control_override_rev7 *b43_nphy_get_rf_ctl_over_rev7(
214 struct b43_wldev *dev, u16 field, u8 override);
205 215
206#endif /* B43_TABLES_NPHY_H_ */ 216#endif /* B43_TABLES_NPHY_H_ */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 8156135a0590..3ea1a85d38d1 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1920,7 +1920,7 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
1920 return 0; 1920 return 0;
1921 ssb_write32(gpiodev, B43legacy_GPIO_CONTROL, 1921 ssb_write32(gpiodev, B43legacy_GPIO_CONTROL,
1922 (ssb_read32(gpiodev, B43legacy_GPIO_CONTROL) 1922 (ssb_read32(gpiodev, B43legacy_GPIO_CONTROL)
1923 & mask) | set); 1923 & ~mask) | set);
1924 1924
1925 return 0; 1925 return 0;
1926} 1926}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 192ad5c1fcc8..1c70defba6c3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -86,7 +86,9 @@ MODULE_AUTHOR("Broadcom Corporation");
86MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); 86MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
87MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); 87MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
88MODULE_LICENSE("Dual BSD/GPL"); 88MODULE_LICENSE("Dual BSD/GPL");
89 89/* This needs to be adjusted when brcms_firmwares changes */
90MODULE_FIRMWARE("brcm/bcm43xx-0.fw");
91MODULE_FIRMWARE("brcm/bcm43xx_hdr-0.fw");
90 92
91/* recognized BCMA Core IDs */ 93/* recognized BCMA Core IDs */
92static struct bcma_device_id brcms_coreid_table[] = { 94static struct bcma_device_id brcms_coreid_table[] = {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 03ca65324845..75086b37c817 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7512,15 +7512,10 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7512 7512
7513 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); 7513 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
7514 7514
7515 if (channel > 14) { 7515 rx_status->band =
7516 rx_status->band = IEEE80211_BAND_5GHZ; 7516 channel > 14 ? IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
7517 rx_status->freq = ieee80211_ofdm_chan_to_freq( 7517 rx_status->freq =
7518 WF_CHAN_FACTOR_5_G/2, channel); 7518 ieee80211_channel_to_frequency(channel, rx_status->band);
7519
7520 } else {
7521 rx_status->band = IEEE80211_BAND_2GHZ;
7522 rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
7523 }
7524 7519
7525 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh); 7520 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
7526 7521
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index f10d30274c23..c11a290a1edf 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -67,11 +67,6 @@
67#define WL_CHANSPEC_BAND_2G 0x2000 67#define WL_CHANSPEC_BAND_2G 0x2000
68#define INVCHANSPEC 255 68#define INVCHANSPEC 255
69 69
70/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
71#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
72#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
73#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
74
75#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) 70#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
76#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) 71#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
77 72
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 0370403fd0bd..eb9987520d61 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4860,7 +4860,7 @@ EXPORT_SYMBOL(il_add_beacon_time);
4860 4860
4861#ifdef CONFIG_PM 4861#ifdef CONFIG_PM
4862 4862
4863int 4863static int
4864il_pci_suspend(struct device *device) 4864il_pci_suspend(struct device *device)
4865{ 4865{
4866 struct pci_dev *pdev = to_pci_dev(device); 4866 struct pci_dev *pdev = to_pci_dev(device);
@@ -4877,9 +4877,8 @@ il_pci_suspend(struct device *device)
4877 4877
4878 return 0; 4878 return 0;
4879} 4879}
4880EXPORT_SYMBOL(il_pci_suspend);
4881 4880
4882int 4881static int
4883il_pci_resume(struct device *device) 4882il_pci_resume(struct device *device)
4884{ 4883{
4885 struct pci_dev *pdev = to_pci_dev(device); 4884 struct pci_dev *pdev = to_pci_dev(device);
@@ -4906,16 +4905,8 @@ il_pci_resume(struct device *device)
4906 4905
4907 return 0; 4906 return 0;
4908} 4907}
4909EXPORT_SYMBOL(il_pci_resume);
4910 4908
4911const struct dev_pm_ops il_pm_ops = { 4909SIMPLE_DEV_PM_OPS(il_pm_ops, il_pci_suspend, il_pci_resume);
4912 .suspend = il_pci_suspend,
4913 .resume = il_pci_resume,
4914 .freeze = il_pci_suspend,
4915 .thaw = il_pci_resume,
4916 .poweroff = il_pci_suspend,
4917 .restore = il_pci_resume,
4918};
4919EXPORT_SYMBOL(il_pm_ops); 4910EXPORT_SYMBOL(il_pm_ops);
4920 4911
4921#endif /* CONFIG_PM */ 4912#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 5f5017767b99..3d3135ed62d7 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1845,8 +1845,6 @@ __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
1845 u32 beacon_interval); 1845 u32 beacon_interval);
1846 1846
1847#ifdef CONFIG_PM 1847#ifdef CONFIG_PM
1848int il_pci_suspend(struct device *device);
1849int il_pci_resume(struct device *device);
1850extern const struct dev_pm_ops il_pm_ops; 1848extern const struct dev_pm_ops il_pm_ops;
1851 1849
1852#define IL_LEGACY_PM_OPS (&il_pm_ops) 1850#define IL_LEGACY_PM_OPS (&il_pm_ops)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index e535c937628b..d2732736f864 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -726,3 +726,29 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
726 726
727 return count; 727 return count;
728} 728}
729
730/*
731 * This function retrieves the entry for specific tx BA stream table by RA and
732 * deletes it.
733 */
734void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra)
735{
736 struct mwifiex_tx_ba_stream_tbl *tbl, *tmp;
737 unsigned long flags;
738
739 if (!ra)
740 return;
741
742 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
743 list_for_each_entry_safe(tbl, tmp, &priv->tx_ba_stream_tbl_ptr, list) {
744 if (!memcmp(tbl->ra, ra, ETH_ALEN)) {
745 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
746 flags);
747 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, tbl);
748 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
749 }
750 }
751 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
752
753 return;
754}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 28366e9211fb..67c087cf9dc7 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -69,6 +69,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
69int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, 69int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
70 int cmd_action, 70 int cmd_action,
71 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); 71 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
72void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
72 73
73/* 74/*
74 * This function checks whether AMPDU is allowed or not for a particular TID. 75 * This function checks whether AMPDU is allowed or not for a particular TID.
@@ -157,4 +158,18 @@ mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
157 158
158 return false; 159 return false;
159} 160}
161
162/*
163 * This function checks whether associated station is 11n enabled
164 */
165static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
166 struct mwifiex_sta_node *node)
167{
168
169 if (!node || (priv->bss_role != MWIFIEX_BSS_ROLE_UAP) ||
170 !priv->ap_11n_enabled)
171 return 0;
172
173 return node->is_11n_enabled;
174}
160#endif /* !_MWIFIEX_11N_H_ */ 175#endif /* !_MWIFIEX_11N_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index ab84eb943749..395f1bfd4102 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -62,9 +62,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
62 }; 62 };
63 struct tx_packet_hdr *tx_header; 63 struct tx_packet_hdr *tx_header;
64 64
65 skb_put(skb_aggr, sizeof(*tx_header)); 65 tx_header = (void *)skb_put(skb_aggr, sizeof(*tx_header));
66
67 tx_header = (struct tx_packet_hdr *) skb_aggr->data;
68 66
69 /* Copy DA and SA */ 67 /* Copy DA and SA */
70 dt_offset = 2 * ETH_ALEN; 68 dt_offset = 2 * ETH_ALEN;
@@ -82,12 +80,10 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
82 tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN); 80 tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN);
83 81
84 /* Add payload */ 82 /* Add payload */
85 skb_put(skb_aggr, skb_src->len); 83 memcpy(skb_put(skb_aggr, skb_src->len), skb_src->data, skb_src->len);
86 memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, 84
87 skb_src->len); 85 /* Add padding for new MSDU to start from 4 byte boundary */
88 *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + 86 *pad = (4 - ((unsigned long)skb_aggr->tail & 0x3)) % 4;
89 LLC_SNAP_LEN)) & 3)) : 0;
90 skb_put(skb_aggr, *pad);
91 87
92 return skb_aggr->len + *pad; 88 return skb_aggr->len + *pad;
93} 89}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 591ccd33f83c..24e2582b467c 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -54,8 +54,13 @@ mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv,
54 tbl->rx_reorder_ptr[i] = NULL; 54 tbl->rx_reorder_ptr[i] = NULL;
55 } 55 }
56 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); 56 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
57 if (rx_tmp_ptr) 57 if (rx_tmp_ptr) {
58 mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); 58 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
59 mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr);
60 else
61 mwifiex_process_rx_packet(priv->adapter,
62 rx_tmp_ptr);
63 }
59 } 64 }
60 65
61 spin_lock_irqsave(&priv->rx_pkt_lock, flags); 66 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
@@ -97,7 +102,11 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
97 rx_tmp_ptr = tbl->rx_reorder_ptr[i]; 102 rx_tmp_ptr = tbl->rx_reorder_ptr[i];
98 tbl->rx_reorder_ptr[i] = NULL; 103 tbl->rx_reorder_ptr[i] = NULL;
99 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); 104 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
100 mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); 105
106 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
107 mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr);
108 else
109 mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
101 } 110 }
102 111
103 spin_lock_irqsave(&priv->rx_pkt_lock, flags); 112 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
@@ -148,7 +157,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
148 * This function returns the pointer to an entry in Rx reordering 157 * This function returns the pointer to an entry in Rx reordering
149 * table which matches the given TA/TID pair. 158 * table which matches the given TA/TID pair.
150 */ 159 */
151static struct mwifiex_rx_reorder_tbl * 160struct mwifiex_rx_reorder_tbl *
152mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) 161mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
153{ 162{
154 struct mwifiex_rx_reorder_tbl *tbl; 163 struct mwifiex_rx_reorder_tbl *tbl;
@@ -167,6 +176,31 @@ mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
167 return NULL; 176 return NULL;
168} 177}
169 178
179/* This function retrieves the pointer to an entry in Rx reordering
180 * table which matches the given TA and deletes it.
181 */
182void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
183{
184 struct mwifiex_rx_reorder_tbl *tbl, *tmp;
185 unsigned long flags;
186
187 if (!ta)
188 return;
189
190 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
191 list_for_each_entry_safe(tbl, tmp, &priv->rx_reorder_tbl_ptr, list) {
192 if (!memcmp(tbl->ta, ta, ETH_ALEN)) {
193 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
194 flags);
195 mwifiex_del_rx_reorder_entry(priv, tbl);
196 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
197 }
198 }
199 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
200
201 return;
202}
203
170/* 204/*
171 * This function finds the last sequence number used in the packets 205 * This function finds the last sequence number used in the packets
172 * buffered in Rx reordering table. 206 * buffered in Rx reordering table.
@@ -226,6 +260,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
226 struct mwifiex_rx_reorder_tbl *tbl, *new_node; 260 struct mwifiex_rx_reorder_tbl *tbl, *new_node;
227 u16 last_seq = 0; 261 u16 last_seq = 0;
228 unsigned long flags; 262 unsigned long flags;
263 struct mwifiex_sta_node *node;
229 264
230 /* 265 /*
231 * If we get a TID, ta pair which is already present dispatch all the 266 * If we get a TID, ta pair which is already present dispatch all the
@@ -248,13 +283,19 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
248 new_node->tid = tid; 283 new_node->tid = tid;
249 memcpy(new_node->ta, ta, ETH_ALEN); 284 memcpy(new_node->ta, ta, ETH_ALEN);
250 new_node->start_win = seq_num; 285 new_node->start_win = seq_num;
251 if (mwifiex_queuing_ra_based(priv)) 286
252 /* TODO for adhoc */ 287 if (mwifiex_queuing_ra_based(priv)) {
253 dev_dbg(priv->adapter->dev, 288 dev_dbg(priv->adapter->dev,
254 "info: ADHOC:last_seq=%d start_win=%d\n", 289 "info: AP/ADHOC:last_seq=%d start_win=%d\n",
255 last_seq, new_node->start_win); 290 last_seq, new_node->start_win);
256 else 291 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
292 node = mwifiex_get_sta_entry(priv, ta);
293 if (node)
294 last_seq = node->rx_seq[tid];
295 }
296 } else {
257 last_seq = priv->rx_seq[tid]; 297 last_seq = priv->rx_seq[tid];
298 }
258 299
259 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && 300 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
260 last_seq >= new_node->start_win) 301 last_seq >= new_node->start_win)
@@ -396,8 +437,13 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
396 437
397 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); 438 tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
398 if (!tbl) { 439 if (!tbl) {
399 if (pkt_type != PKT_TYPE_BAR) 440 if (pkt_type != PKT_TYPE_BAR) {
400 mwifiex_process_rx_packet(priv->adapter, payload); 441 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
442 mwifiex_handle_uap_rx_forward(priv, payload);
443 else
444 mwifiex_process_rx_packet(priv->adapter,
445 payload);
446 }
401 return 0; 447 return 0;
402 } 448 }
403 start_win = tbl->start_win; 449 start_win = tbl->start_win;
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 6c9815a0f5d8..72848591691a 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -38,6 +38,8 @@
38#define ADDBA_RSP_STATUS_ACCEPT 0 38#define ADDBA_RSP_STATUS_ACCEPT 0
39 39
40#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff 40#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff
41#define BA_SETUP_MAX_PACKET_THRESHOLD 16
42#define BA_SETUP_PACKET_OFFSET 16
41 43
42static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) 44static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
43{ 45{
@@ -68,5 +70,8 @@ struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
68 mwifiex_private 70 mwifiex_private
69 *priv, int tid, 71 *priv, int tid,
70 u8 *ta); 72 u8 *ta);
73struct mwifiex_rx_reorder_tbl *
74mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta);
75void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta);
71 76
72#endif /* _MWIFIEX_11N_RXREORDER_H_ */ 77#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 3f66ebb0a630..dd0410d2d465 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -33,8 +33,10 @@ mwifiex-y += uap_cmd.o
33mwifiex-y += ie.o 33mwifiex-y += ie.o
34mwifiex-y += sta_cmdresp.o 34mwifiex-y += sta_cmdresp.o
35mwifiex-y += sta_event.o 35mwifiex-y += sta_event.o
36mwifiex-y += uap_event.o
36mwifiex-y += sta_tx.o 37mwifiex-y += sta_tx.o
37mwifiex-y += sta_rx.o 38mwifiex-y += sta_rx.o
39mwifiex-y += uap_txrx.o
38mwifiex-y += cfg80211.o 40mwifiex-y += cfg80211.o
39mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o 41mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
40obj-$(CONFIG_MWIFIEX) += mwifiex.o 42obj-$(CONFIG_MWIFIEX) += mwifiex.o
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index fe42137384da..e57f543413de 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -99,7 +99,7 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
99 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 99 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
100 const u8 *peer_mac = pairwise ? mac_addr : bc_mac; 100 const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
101 101
102 if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) { 102 if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
103 wiphy_err(wiphy, "deleting the crypto keys\n"); 103 wiphy_err(wiphy, "deleting the crypto keys\n");
104 return -EFAULT; 104 return -EFAULT;
105 } 105 }
@@ -171,7 +171,8 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
171 171
172 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) { 172 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
173 priv->wep_key_curr_index = key_index; 173 priv->wep_key_curr_index = key_index;
174 } else if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { 174 } else if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index,
175 NULL, 0)) {
175 wiphy_err(wiphy, "set default Tx key index\n"); 176 wiphy_err(wiphy, "set default Tx key index\n");
176 return -EFAULT; 177 return -EFAULT;
177 } 178 }
@@ -207,7 +208,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
207 return 0; 208 return 0;
208 } 209 }
209 210
210 if (mwifiex_set_encode(priv, params->key, params->key_len, 211 if (mwifiex_set_encode(priv, params, params->key, params->key_len,
211 key_index, peer_mac, 0)) { 212 key_index, peer_mac, 0)) {
212 wiphy_err(wiphy, "crypto keys added\n"); 213 wiphy_err(wiphy, "crypto keys added\n");
213 return -EFAULT; 214 return -EFAULT;
@@ -748,6 +749,7 @@ static const u32 mwifiex_cipher_suites[] = {
748 WLAN_CIPHER_SUITE_WEP104, 749 WLAN_CIPHER_SUITE_WEP104,
749 WLAN_CIPHER_SUITE_TKIP, 750 WLAN_CIPHER_SUITE_TKIP,
750 WLAN_CIPHER_SUITE_CCMP, 751 WLAN_CIPHER_SUITE_CCMP,
752 WLAN_CIPHER_SUITE_AES_CMAC,
751}; 753};
752 754
753/* 755/*
@@ -906,6 +908,8 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
906 if (mwifiex_del_mgmt_ies(priv)) 908 if (mwifiex_del_mgmt_ies(priv))
907 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n"); 909 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
908 910
911 priv->ap_11n_enabled = 0;
912
909 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, 913 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
910 HostCmd_ACT_GEN_SET, 0, NULL)) { 914 HostCmd_ACT_GEN_SET, 0, NULL)) {
911 wiphy_err(wiphy, "Failed to stop the BSS\n"); 915 wiphy_err(wiphy, "Failed to stop the BSS\n");
@@ -1159,7 +1163,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
1159 priv->wep_key_curr_index = 0; 1163 priv->wep_key_curr_index = 0;
1160 priv->sec_info.encryption_mode = 0; 1164 priv->sec_info.encryption_mode = 0;
1161 priv->sec_info.is_authtype_auto = 0; 1165 priv->sec_info.is_authtype_auto = 0;
1162 ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1); 1166 ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
1163 1167
1164 if (mode == NL80211_IFTYPE_ADHOC) { 1168 if (mode == NL80211_IFTYPE_ADHOC) {
1165 /* "privacy" is set only for ad-hoc mode */ 1169 /* "privacy" is set only for ad-hoc mode */
@@ -1206,8 +1210,9 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
1206 "info: setting wep encryption" 1210 "info: setting wep encryption"
1207 " with key len %d\n", sme->key_len); 1211 " with key len %d\n", sme->key_len);
1208 priv->wep_key_curr_index = sme->key_idx; 1212 priv->wep_key_curr_index = sme->key_idx;
1209 ret = mwifiex_set_encode(priv, sme->key, sme->key_len, 1213 ret = mwifiex_set_encode(priv, NULL, sme->key,
1210 sme->key_idx, NULL, 0); 1214 sme->key_len, sme->key_idx,
1215 NULL, 0);
1211 } 1216 }
1212 } 1217 }
1213done: 1218done:
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index c68adec3cc8b..c229dddcf1c2 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -447,7 +447,10 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
447 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 447 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
448 } 448 }
449 449
450 ret = mwifiex_process_sta_event(priv); 450 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
451 ret = mwifiex_process_uap_event(priv);
452 else
453 ret = mwifiex_process_sta_event(priv);
451 454
452 adapter->event_cause = 0; 455 adapter->event_cause = 0;
453 adapter->event_skb = NULL; 456 adapter->event_skb = NULL;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 070ef25f5186..400d360ac91f 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -60,6 +60,9 @@
60#define MWIFIEX_SDIO_BLOCK_SIZE 256 60#define MWIFIEX_SDIO_BLOCK_SIZE 256
61 61
62#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) 62#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
63#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
64
65#define MWIFIEX_BRIDGED_PKTS_THRESHOLD 1024
63 66
64enum mwifiex_bss_type { 67enum mwifiex_bss_type {
65 MWIFIEX_BSS_TYPE_STA = 0, 68 MWIFIEX_BSS_TYPE_STA = 0,
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index e831b440a24a..ae06f31c6838 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -65,10 +65,12 @@ enum KEY_TYPE_ID {
65 KEY_TYPE_ID_TKIP, 65 KEY_TYPE_ID_TKIP,
66 KEY_TYPE_ID_AES, 66 KEY_TYPE_ID_AES,
67 KEY_TYPE_ID_WAPI, 67 KEY_TYPE_ID_WAPI,
68 KEY_TYPE_ID_AES_CMAC,
68}; 69};
69#define KEY_MCAST BIT(0) 70#define KEY_MCAST BIT(0)
70#define KEY_UNICAST BIT(1) 71#define KEY_UNICAST BIT(1)
71#define KEY_ENABLED BIT(2) 72#define KEY_ENABLED BIT(2)
73#define KEY_IGTK BIT(10)
72 74
73#define WAPI_KEY_LEN 50 75#define WAPI_KEY_LEN 50
74 76
@@ -424,10 +426,10 @@ struct txpd {
424struct rxpd { 426struct rxpd {
425 u8 bss_type; 427 u8 bss_type;
426 u8 bss_num; 428 u8 bss_num;
427 u16 rx_pkt_length; 429 __le16 rx_pkt_length;
428 u16 rx_pkt_offset; 430 __le16 rx_pkt_offset;
429 u16 rx_pkt_type; 431 __le16 rx_pkt_type;
430 u16 seq_num; 432 __le16 seq_num;
431 u8 priority; 433 u8 priority;
432 u8 rx_rate; 434 u8 rx_rate;
433 s8 snr; 435 s8 snr;
@@ -439,6 +441,31 @@ struct rxpd {
439 u8 reserved; 441 u8 reserved;
440} __packed; 442} __packed;
441 443
444struct uap_txpd {
445 u8 bss_type;
446 u8 bss_num;
447 __le16 tx_pkt_length;
448 __le16 tx_pkt_offset;
449 __le16 tx_pkt_type;
450 __le32 tx_control;
451 u8 priority;
452 u8 flags;
453 u8 pkt_delay_2ms;
454 u8 reserved1;
455 __le32 reserved2;
456};
457
458struct uap_rxpd {
459 u8 bss_type;
460 u8 bss_num;
461 __le16 rx_pkt_length;
462 __le16 rx_pkt_offset;
463 __le16 rx_pkt_type;
464 __le16 seq_num;
465 u8 priority;
466 u8 reserved1;
467};
468
442enum mwifiex_chan_scan_mode_bitmasks { 469enum mwifiex_chan_scan_mode_bitmasks {
443 MWIFIEX_PASSIVE_SCAN = BIT(0), 470 MWIFIEX_PASSIVE_SCAN = BIT(0),
444 MWIFIEX_DISABLE_CHAN_FILT = BIT(1), 471 MWIFIEX_DISABLE_CHAN_FILT = BIT(1),
@@ -558,6 +585,13 @@ struct mwifiex_ie_type_key_param_set {
558 u8 key[50]; 585 u8 key[50];
559} __packed; 586} __packed;
560 587
588#define IGTK_PN_LEN 8
589
590struct mwifiex_cmac_param {
591 u8 ipn[IGTK_PN_LEN];
592 u8 key[WLAN_KEY_LEN_AES_CMAC];
593} __packed;
594
561struct host_cmd_ds_802_11_key_material { 595struct host_cmd_ds_802_11_key_material {
562 __le16 action; 596 __le16 action;
563 struct mwifiex_ie_type_key_param_set key_param_set; 597 struct mwifiex_ie_type_key_param_set key_param_set;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 21fdc6c02775..fad2c8d2bdde 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -64,60 +64,72 @@ static void scan_delay_timer_fn(unsigned long data)
64 struct cmd_ctrl_node *cmd_node, *tmp_node; 64 struct cmd_ctrl_node *cmd_node, *tmp_node;
65 unsigned long flags; 65 unsigned long flags;
66 66
67 if (!mwifiex_wmm_lists_empty(adapter)) { 67 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
68 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { 68 /*
69 * Abort scan operation by cancelling all pending scan
70 * commands
71 */
72 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
73 list_for_each_entry_safe(cmd_node, tmp_node,
74 &adapter->scan_pending_q, list) {
75 list_del(&cmd_node->list);
76 cmd_node->wait_q_enabled = false;
77 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
78 }
79 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
80
81 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
82 adapter->scan_processing = false;
83 adapter->scan_delay_cnt = 0;
84 adapter->empty_tx_q_cnt = 0;
85 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
86
87 if (priv->user_scan_cfg) {
88 dev_dbg(priv->adapter->dev,
89 "info: %s: scan aborted\n", __func__);
90 cfg80211_scan_done(priv->scan_request, 1);
91 priv->scan_request = NULL;
92 kfree(priv->user_scan_cfg);
93 priv->user_scan_cfg = NULL;
94 }
95 goto done;
96 }
97
98 if (!atomic_read(&priv->adapter->is_tx_received)) {
99 adapter->empty_tx_q_cnt++;
100 if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
69 /* 101 /*
70 * Abort scan operation by cancelling all pending scan 102 * No Tx traffic for 200msec. Get scan command from
71 * command 103 * scan pending queue and put to cmd pending queue to
104 * resume scan operation
72 */ 105 */
106 adapter->scan_delay_cnt = 0;
107 adapter->empty_tx_q_cnt = 0;
73 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 108 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
74 list_for_each_entry_safe(cmd_node, tmp_node, 109 cmd_node = list_first_entry(&adapter->scan_pending_q,
75 &adapter->scan_pending_q, 110 struct cmd_ctrl_node, list);
76 list) { 111 list_del(&cmd_node->list);
77 list_del(&cmd_node->list);
78 cmd_node->wait_q_enabled = false;
79 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
80 }
81 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 112 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
82 flags); 113 flags);
83 114
84 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 115 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
85 adapter->scan_processing = false; 116 true);
86 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, 117 goto done;
87 flags);
88
89 if (priv->user_scan_cfg) {
90 dev_dbg(priv->adapter->dev,
91 "info: %s: scan aborted\n", __func__);
92 cfg80211_scan_done(priv->scan_request, 1);
93 priv->scan_request = NULL;
94 kfree(priv->user_scan_cfg);
95 priv->user_scan_cfg = NULL;
96 }
97 } else {
98 /*
99 * Tx data queue is still not empty, delay scan
100 * operation further by 20msec.
101 */
102 mod_timer(&priv->scan_delay_timer, jiffies +
103 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
104 adapter->scan_delay_cnt++;
105 } 118 }
106 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
107 } else { 119 } else {
108 /* 120 adapter->empty_tx_q_cnt = 0;
109 * Tx data queue is empty. Get scan command from scan_pending_q
110 * and put to cmd_pending_q to resume scan operation
111 */
112 adapter->scan_delay_cnt = 0;
113 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
114 cmd_node = list_first_entry(&adapter->scan_pending_q,
115 struct cmd_ctrl_node, list);
116 list_del(&cmd_node->list);
117 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
118
119 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
120 } 121 }
122
123 /* Delay scan operation further by 20msec */
124 mod_timer(&priv->scan_delay_timer, jiffies +
125 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
126 adapter->scan_delay_cnt++;
127
128done:
129 if (atomic_read(&priv->adapter->is_tx_received))
130 atomic_set(&priv->adapter->is_tx_received, false);
131
132 return;
121} 133}
122 134
123/* 135/*
@@ -196,6 +208,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
196 priv->curr_bcn_size = 0; 208 priv->curr_bcn_size = 0;
197 priv->wps_ie = NULL; 209 priv->wps_ie = NULL;
198 priv->wps_ie_len = 0; 210 priv->wps_ie_len = 0;
211 priv->ap_11n_enabled = 0;
199 212
200 priv->scan_block = false; 213 priv->scan_block = false;
201 214
@@ -345,6 +358,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
345 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 358 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
346 adapter->arp_filter_size = 0; 359 adapter->arp_filter_size = 0;
347 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 360 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
361 adapter->empty_tx_q_cnt = 0;
348} 362}
349 363
350/* 364/*
@@ -410,6 +424,7 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
410 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list); 424 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
411 list_del(&priv->tx_ba_stream_tbl_ptr); 425 list_del(&priv->tx_ba_stream_tbl_ptr);
412 list_del(&priv->rx_reorder_tbl_ptr); 426 list_del(&priv->rx_reorder_tbl_ptr);
427 list_del(&priv->sta_list);
413 } 428 }
414 } 429 }
415} 430}
@@ -472,6 +487,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
472 spin_lock_init(&priv->rx_pkt_lock); 487 spin_lock_init(&priv->rx_pkt_lock);
473 spin_lock_init(&priv->wmm.ra_list_spinlock); 488 spin_lock_init(&priv->wmm.ra_list_spinlock);
474 spin_lock_init(&priv->curr_bcn_buf_lock); 489 spin_lock_init(&priv->curr_bcn_buf_lock);
490 spin_lock_init(&priv->sta_list_spinlock);
475 } 491 }
476 } 492 }
477 493
@@ -504,6 +520,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
504 } 520 }
505 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); 521 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
506 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); 522 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
523 INIT_LIST_HEAD(&priv->sta_list);
507 524
508 spin_lock_init(&priv->tx_ba_stream_tbl_lock); 525 spin_lock_init(&priv->tx_ba_stream_tbl_lock);
509 spin_lock_init(&priv->rx_reorder_tbl_lock); 526 spin_lock_init(&priv->rx_reorder_tbl_lock);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 50191539bb32..6a5eded3be10 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -213,7 +213,7 @@ struct mwifiex_debug_info {
213}; 213};
214 214
215#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 215#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000
216#define WAPI_RXPN_LEN 16 216#define PN_LEN 16
217 217
218struct mwifiex_ds_encrypt_key { 218struct mwifiex_ds_encrypt_key {
219 u32 key_disable; 219 u32 key_disable;
@@ -222,7 +222,8 @@ struct mwifiex_ds_encrypt_key {
222 u8 key_material[WLAN_MAX_KEY_LEN]; 222 u8 key_material[WLAN_MAX_KEY_LEN];
223 u8 mac_addr[ETH_ALEN]; 223 u8 mac_addr[ETH_ALEN];
224 u32 is_wapi_key; 224 u32 is_wapi_key;
225 u8 wapi_rxpn[WAPI_RXPN_LEN]; 225 u8 pn[PN_LEN]; /* packet number */
226 u8 is_igtk_key;
226}; 227};
227 228
228struct mwifiex_power_cfg { 229struct mwifiex_power_cfg {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 46803621d015..cb1155286e0f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -520,6 +520,9 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
520 mwifiex_wmm_add_buf_txqueue(priv, skb); 520 mwifiex_wmm_add_buf_txqueue(priv, skb);
521 atomic_inc(&priv->adapter->tx_pending); 521 atomic_inc(&priv->adapter->tx_pending);
522 522
523 if (priv->adapter->scan_delay_cnt)
524 atomic_set(&priv->adapter->is_tx_received, true);
525
523 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { 526 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
524 mwifiex_set_trans_start(dev); 527 mwifiex_set_trans_start(dev);
525 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); 528 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e7c2a82fd610..994bc4fc263e 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -88,6 +88,7 @@ enum {
88#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) 88#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
89 89
90#define MWIFIEX_MAX_SCAN_DELAY_CNT 50 90#define MWIFIEX_MAX_SCAN_DELAY_CNT 50
91#define MWIFIEX_MAX_EMPTY_TX_Q_CNT 10
91#define MWIFIEX_SCAN_DELAY_MSEC 20 92#define MWIFIEX_SCAN_DELAY_MSEC 20
92 93
93#define RSN_GTK_OUI_OFFSET 2 94#define RSN_GTK_OUI_OFFSET 2
@@ -199,6 +200,9 @@ struct mwifiex_ra_list_tbl {
199 u8 ra[ETH_ALEN]; 200 u8 ra[ETH_ALEN];
200 u32 total_pkts_size; 201 u32 total_pkts_size;
201 u32 is_11n_enabled; 202 u32 is_11n_enabled;
203 u16 max_amsdu;
204 u16 pkt_count;
205 u8 ba_packet_thr;
202}; 206};
203 207
204struct mwifiex_tid_tbl { 208struct mwifiex_tid_tbl {
@@ -431,6 +435,9 @@ struct mwifiex_private {
431 u8 wmm_enabled; 435 u8 wmm_enabled;
432 u8 wmm_qosinfo; 436 u8 wmm_qosinfo;
433 struct mwifiex_wmm_desc wmm; 437 struct mwifiex_wmm_desc wmm;
438 struct list_head sta_list;
439 /* spin lock for associated station list */
440 spinlock_t sta_list_spinlock;
434 struct list_head tx_ba_stream_tbl_ptr; 441 struct list_head tx_ba_stream_tbl_ptr;
435 /* spin lock for tx_ba_stream_tbl_ptr queue */ 442 /* spin lock for tx_ba_stream_tbl_ptr queue */
436 spinlock_t tx_ba_stream_tbl_lock; 443 spinlock_t tx_ba_stream_tbl_lock;
@@ -486,6 +493,7 @@ struct mwifiex_private {
486 u16 assocresp_idx; 493 u16 assocresp_idx;
487 u16 rsn_idx; 494 u16 rsn_idx;
488 struct timer_list scan_delay_timer; 495 struct timer_list scan_delay_timer;
496 u8 ap_11n_enabled;
489}; 497};
490 498
491enum mwifiex_ba_status { 499enum mwifiex_ba_status {
@@ -550,6 +558,19 @@ struct mwifiex_bss_priv {
550 u64 fw_tsf; 558 u64 fw_tsf;
551}; 559};
552 560
561/* This is AP specific structure which stores information
562 * about associated STA
563 */
564struct mwifiex_sta_node {
565 struct list_head list;
566 u8 mac_addr[ETH_ALEN];
567 u8 is_wmm_enabled;
568 u8 is_11n_enabled;
569 u8 ampdu_sta[MAX_NUM_TID];
570 u16 rx_seq[MAX_NUM_TID];
571 u16 max_amsdu;
572};
573
553struct mwifiex_if_ops { 574struct mwifiex_if_ops {
554 int (*init_if) (struct mwifiex_adapter *); 575 int (*init_if) (struct mwifiex_adapter *);
555 void (*cleanup_if) (struct mwifiex_adapter *); 576 void (*cleanup_if) (struct mwifiex_adapter *);
@@ -690,6 +711,9 @@ struct mwifiex_adapter {
690 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 711 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
691 u16 max_mgmt_ie_index; 712 u16 max_mgmt_ie_index;
692 u8 scan_delay_cnt; 713 u8 scan_delay_cnt;
714 u8 empty_tx_q_cnt;
715 atomic_t is_tx_received;
716 atomic_t pending_bridged_pkts;
693}; 717};
694 718
695int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 719int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -780,7 +804,15 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
780 struct host_cmd_ds_command *resp); 804 struct host_cmd_ds_command *resp);
781int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, 805int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
782 struct sk_buff *skb); 806 struct sk_buff *skb);
807int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
808 struct sk_buff *skb);
809int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv,
810 struct sk_buff *skb);
783int mwifiex_process_sta_event(struct mwifiex_private *); 811int mwifiex_process_sta_event(struct mwifiex_private *);
812int mwifiex_process_uap_event(struct mwifiex_private *);
813struct mwifiex_sta_node *
814mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
815void mwifiex_delete_all_station_list(struct mwifiex_private *priv);
784void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); 816void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
785int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); 817int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
786int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, 818int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
@@ -949,9 +981,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
949 const struct mwifiex_user_scan_cfg *user_scan_in); 981 const struct mwifiex_user_scan_cfg *user_scan_in);
950int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); 982int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
951 983
952int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 984int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
953 int key_len, u8 key_index, const u8 *mac_addr, 985 const u8 *key, int key_len, u8 key_index,
954 int disable); 986 const u8 *mac_addr, int disable);
955 987
956int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); 988int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
957 989
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 04dc7ca4ac22..215d07e6c462 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -989,6 +989,8 @@ mwifiex_config_scan(struct mwifiex_private *priv,
989 *max_chan_per_scan = 2; 989 *max_chan_per_scan = 2;
990 else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD) 990 else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD)
991 *max_chan_per_scan = 3; 991 *max_chan_per_scan = 3;
992 else
993 *max_chan_per_scan = 4;
992 } 994 }
993} 995}
994 996
@@ -1433,9 +1435,9 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1433 if (ret) 1435 if (ret)
1434 dev_err(priv->adapter->dev, "cannot find ssid " 1436 dev_err(priv->adapter->dev, "cannot find ssid "
1435 "%s\n", bss_desc->ssid.ssid); 1437 "%s\n", bss_desc->ssid.ssid);
1436 break; 1438 break;
1437 default: 1439 default:
1438 ret = 0; 1440 ret = 0;
1439 } 1441 }
1440 } 1442 }
1441 1443
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index df3a33c530cf..0cc3406050dc 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -610,7 +610,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
610 memcpy(&key_material->key_param_set.key[2], 610 memcpy(&key_material->key_param_set.key[2],
611 enc_key->key_material, enc_key->key_len); 611 enc_key->key_material, enc_key->key_len);
612 memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], 612 memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
613 enc_key->wapi_rxpn, WAPI_RXPN_LEN); 613 enc_key->pn, PN_LEN);
614 key_material->key_param_set.length = 614 key_material->key_param_set.length =
615 cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN); 615 cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
616 616
@@ -621,23 +621,38 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
621 return ret; 621 return ret;
622 } 622 }
623 if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { 623 if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
624 dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); 624 if (enc_key->is_igtk_key) {
625 key_material->key_param_set.key_type_id = 625 dev_dbg(priv->adapter->dev, "cmd: CMAC_AES\n");
626 key_material->key_param_set.key_type_id =
627 cpu_to_le16(KEY_TYPE_ID_AES_CMAC);
628 if (cmd_oid == KEY_INFO_ENABLED)
629 key_material->key_param_set.key_info =
630 cpu_to_le16(KEY_ENABLED);
631 else
632 key_material->key_param_set.key_info =
633 cpu_to_le16(!KEY_ENABLED);
634
635 key_material->key_param_set.key_info |=
636 cpu_to_le16(KEY_IGTK);
637 } else {
638 dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
639 key_material->key_param_set.key_type_id =
626 cpu_to_le16(KEY_TYPE_ID_AES); 640 cpu_to_le16(KEY_TYPE_ID_AES);
627 if (cmd_oid == KEY_INFO_ENABLED) 641 if (cmd_oid == KEY_INFO_ENABLED)
628 key_material->key_param_set.key_info = 642 key_material->key_param_set.key_info =
629 cpu_to_le16(KEY_ENABLED); 643 cpu_to_le16(KEY_ENABLED);
630 else 644 else
631 key_material->key_param_set.key_info = 645 key_material->key_param_set.key_info =
632 cpu_to_le16(!KEY_ENABLED); 646 cpu_to_le16(!KEY_ENABLED);
633 647
634 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) 648 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
635 /* AES pairwise key: unicast */ 649 /* AES pairwise key: unicast */
636 key_material->key_param_set.key_info |= 650 key_material->key_param_set.key_info |=
637 cpu_to_le16(KEY_UNICAST); 651 cpu_to_le16(KEY_UNICAST);
638 else /* AES group key: multicast */ 652 else /* AES group key: multicast */
639 key_material->key_param_set.key_info |= 653 key_material->key_param_set.key_info |=
640 cpu_to_le16(KEY_MCAST); 654 cpu_to_le16(KEY_MCAST);
655 }
641 } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { 656 } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
642 dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); 657 dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
643 key_material->key_param_set.key_type_id = 658 key_material->key_param_set.key_type_id =
@@ -668,6 +683,24 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
668 key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN) 683 key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
669 + sizeof(struct mwifiex_ie_types_header); 684 + sizeof(struct mwifiex_ie_types_header);
670 685
686 if (le16_to_cpu(key_material->key_param_set.key_type_id) ==
687 KEY_TYPE_ID_AES_CMAC) {
688 struct mwifiex_cmac_param *param =
689 (void *)key_material->key_param_set.key;
690
691 memcpy(param->ipn, enc_key->pn, IGTK_PN_LEN);
692 memcpy(param->key, enc_key->key_material,
693 WLAN_KEY_LEN_AES_CMAC);
694
695 key_param_len = sizeof(struct mwifiex_cmac_param);
696 key_material->key_param_set.key_len =
697 cpu_to_le16(key_param_len);
698 key_param_len += KEYPARAMSET_FIXED_LEN;
699 key_material->key_param_set.length =
700 cpu_to_le16(key_param_len);
701 key_param_len += sizeof(struct mwifiex_ie_types_header);
702 }
703
671 cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN 704 cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
672 + key_param_len); 705 + key_param_len);
673 706
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index b8614a825460..dff51d55271c 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -184,10 +184,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
184int mwifiex_process_sta_event(struct mwifiex_private *priv) 184int mwifiex_process_sta_event(struct mwifiex_private *priv)
185{ 185{
186 struct mwifiex_adapter *adapter = priv->adapter; 186 struct mwifiex_adapter *adapter = priv->adapter;
187 int len, ret = 0; 187 int ret = 0;
188 u32 eventcause = adapter->event_cause; 188 u32 eventcause = adapter->event_cause;
189 struct station_info sinfo; 189 u16 ctrl;
190 struct mwifiex_assoc_event *event;
191 190
192 switch (eventcause) { 191 switch (eventcause) {
193 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: 192 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
@@ -279,10 +278,16 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
279 278
280 case EVENT_MIC_ERR_UNICAST: 279 case EVENT_MIC_ERR_UNICAST:
281 dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n"); 280 dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n");
281 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
282 NL80211_KEYTYPE_PAIRWISE,
283 -1, NULL, GFP_KERNEL);
282 break; 284 break;
283 285
284 case EVENT_MIC_ERR_MULTICAST: 286 case EVENT_MIC_ERR_MULTICAST:
285 dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n"); 287 dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n");
288 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
289 NL80211_KEYTYPE_GROUP,
290 -1, NULL, GFP_KERNEL);
286 break; 291 break;
287 case EVENT_MIB_CHANGED: 292 case EVENT_MIB_CHANGED:
288 case EVENT_INIT_DONE: 293 case EVENT_INIT_DONE:
@@ -384,11 +389,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
384 adapter->event_body); 389 adapter->event_body);
385 break; 390 break;
386 case EVENT_AMSDU_AGGR_CTRL: 391 case EVENT_AMSDU_AGGR_CTRL:
387 dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", 392 ctrl = le16_to_cpu(*(__le16 *)adapter->event_body);
388 *(u16 *) adapter->event_body); 393 dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", ctrl);
394
389 adapter->tx_buf_size = 395 adapter->tx_buf_size =
390 min(adapter->curr_tx_buf_size, 396 min_t(u16, adapter->curr_tx_buf_size, ctrl);
391 le16_to_cpu(*(__le16 *) adapter->event_body));
392 dev_dbg(adapter->dev, "event: tx_buf_size %d\n", 397 dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
393 adapter->tx_buf_size); 398 adapter->tx_buf_size);
394 break; 399 break;
@@ -405,51 +410,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
405 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause); 410 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
406 break; 411 break;
407 412
408 case EVENT_UAP_STA_ASSOC:
409 memset(&sinfo, 0, sizeof(sinfo));
410 event = (struct mwifiex_assoc_event *)
411 (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER);
412 if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
413 len = -1;
414
415 if (ieee80211_is_assoc_req(event->frame_control))
416 len = 0;
417 else if (ieee80211_is_reassoc_req(event->frame_control))
418 /* There will be ETH_ALEN bytes of
419 * current_ap_addr before the re-assoc ies.
420 */
421 len = ETH_ALEN;
422
423 if (len != -1) {
424 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
425 sinfo.assoc_req_ies = &event->data[len];
426 len = (u8 *)sinfo.assoc_req_ies -
427 (u8 *)&event->frame_control;
428 sinfo.assoc_req_ies_len =
429 le16_to_cpu(event->len) - (u16)len;
430 }
431 }
432 cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo,
433 GFP_KERNEL);
434 break;
435 case EVENT_UAP_STA_DEAUTH:
436 cfg80211_del_sta(priv->netdev, adapter->event_body +
437 MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL);
438 break;
439 case EVENT_UAP_BSS_IDLE:
440 priv->media_connected = false;
441 break;
442 case EVENT_UAP_BSS_ACTIVE:
443 priv->media_connected = true;
444 break;
445 case EVENT_UAP_BSS_START:
446 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
447 memcpy(priv->netdev->dev_addr, adapter->event_body+2, ETH_ALEN);
448 break;
449 case EVENT_UAP_MIC_COUNTERMEASURES:
450 /* For future development */
451 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
452 break;
453 default: 413 default:
454 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 414 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
455 eventcause); 415 eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index fb2136089a22..3f025976f79a 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -942,20 +942,26 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
942 * This function allocates the IOCTL request buffer, fills it 942 * This function allocates the IOCTL request buffer, fills it
943 * with requisite parameters and calls the IOCTL handler. 943 * with requisite parameters and calls the IOCTL handler.
944 */ 944 */
945int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 945int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
946 int key_len, u8 key_index, 946 const u8 *key, int key_len, u8 key_index,
947 const u8 *mac_addr, int disable) 947 const u8 *mac_addr, int disable)
948{ 948{
949 struct mwifiex_ds_encrypt_key encrypt_key; 949 struct mwifiex_ds_encrypt_key encrypt_key;
950 950
951 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); 951 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
952 encrypt_key.key_len = key_len; 952 encrypt_key.key_len = key_len;
953
954 if (kp && kp->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
955 encrypt_key.is_igtk_key = true;
956
953 if (!disable) { 957 if (!disable) {
954 encrypt_key.key_index = key_index; 958 encrypt_key.key_index = key_index;
955 if (key_len) 959 if (key_len)
956 memcpy(encrypt_key.key_material, key, key_len); 960 memcpy(encrypt_key.key_material, key, key_len);
957 if (mac_addr) 961 if (mac_addr)
958 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); 962 memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
963 if (kp && kp->seq && kp->seq_len)
964 memcpy(encrypt_key.pn, kp->seq, kp->seq_len);
959 } else { 965 } else {
960 encrypt_key.key_disable = true; 966 encrypt_key.key_disable = true;
961 if (mac_addr) 967 if (mac_addr)
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 02ce3b77d3e7..d91d5c08c73a 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -54,8 +54,8 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
54 54
55 local_rx_pd = (struct rxpd *) (skb->data); 55 local_rx_pd = (struct rxpd *) (skb->data);
56 56
57 rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd + 57 rx_pkt_hdr = (void *)local_rx_pd +
58 local_rx_pd->rx_pkt_offset); 58 le16_to_cpu(local_rx_pd->rx_pkt_offset);
59 59
60 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr, 60 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
61 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) { 61 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
@@ -125,7 +125,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
125 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 125 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
126 struct rx_packet_hdr *rx_pkt_hdr; 126 struct rx_packet_hdr *rx_pkt_hdr;
127 u8 ta[ETH_ALEN]; 127 u8 ta[ETH_ALEN];
128 u16 rx_pkt_type; 128 u16 rx_pkt_type, rx_pkt_offset, rx_pkt_length, seq_num;
129 struct mwifiex_private *priv = 129 struct mwifiex_private *priv =
130 mwifiex_get_priv_by_id(adapter, rx_info->bss_num, 130 mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
131 rx_info->bss_type); 131 rx_info->bss_type);
@@ -134,16 +134,17 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
134 return -1; 134 return -1;
135 135
136 local_rx_pd = (struct rxpd *) (skb->data); 136 local_rx_pd = (struct rxpd *) (skb->data);
137 rx_pkt_type = local_rx_pd->rx_pkt_type; 137 rx_pkt_type = le16_to_cpu(local_rx_pd->rx_pkt_type);
138 rx_pkt_offset = le16_to_cpu(local_rx_pd->rx_pkt_offset);
139 rx_pkt_length = le16_to_cpu(local_rx_pd->rx_pkt_length);
140 seq_num = le16_to_cpu(local_rx_pd->seq_num);
138 141
139 rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd + 142 rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset;
140 local_rx_pd->rx_pkt_offset);
141 143
142 if ((local_rx_pd->rx_pkt_offset + local_rx_pd->rx_pkt_length) > 144 if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) {
143 (u16) skb->len) { 145 dev_err(adapter->dev,
144 dev_err(adapter->dev, "wrong rx packet: len=%d," 146 "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
145 " rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len, 147 skb->len, rx_pkt_offset, rx_pkt_length);
146 local_rx_pd->rx_pkt_offset, local_rx_pd->rx_pkt_length);
147 priv->stats.rx_dropped++; 148 priv->stats.rx_dropped++;
148 149
149 if (adapter->if_ops.data_complete) 150 if (adapter->if_ops.data_complete)
@@ -154,14 +155,14 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
154 return ret; 155 return ret;
155 } 156 }
156 157
157 if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) { 158 if (rx_pkt_type == PKT_TYPE_AMSDU) {
158 struct sk_buff_head list; 159 struct sk_buff_head list;
159 struct sk_buff *rx_skb; 160 struct sk_buff *rx_skb;
160 161
161 __skb_queue_head_init(&list); 162 __skb_queue_head_init(&list);
162 163
163 skb_pull(skb, local_rx_pd->rx_pkt_offset); 164 skb_pull(skb, rx_pkt_offset);
164 skb_trim(skb, local_rx_pd->rx_pkt_length); 165 skb_trim(skb, rx_pkt_length);
165 166
166 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, 167 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
167 priv->wdev->iftype, 0, false); 168 priv->wdev->iftype, 0, false);
@@ -189,17 +190,14 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
189 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN); 190 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
190 } else { 191 } else {
191 if (rx_pkt_type != PKT_TYPE_BAR) 192 if (rx_pkt_type != PKT_TYPE_BAR)
192 priv->rx_seq[local_rx_pd->priority] = 193 priv->rx_seq[local_rx_pd->priority] = seq_num;
193 local_rx_pd->seq_num;
194 memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address, 194 memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address,
195 ETH_ALEN); 195 ETH_ALEN);
196 } 196 }
197 197
198 /* Reorder and send to OS */ 198 /* Reorder and send to OS */
199 ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, 199 ret = mwifiex_11n_rx_reorder_pkt(priv, seq_num, local_rx_pd->priority,
200 local_rx_pd->priority, ta, 200 ta, (u8) rx_pkt_type, skb);
201 (u8) local_rx_pd->rx_pkt_type,
202 skb);
203 201
204 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { 202 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
205 if (adapter->if_ops.data_complete) 203 if (adapter->if_ops.data_complete)
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index cecb27283196..985073d0df1a 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -51,6 +51,9 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
51 rx_info->bss_num = priv->bss_num; 51 rx_info->bss_num = priv->bss_num;
52 rx_info->bss_type = priv->bss_type; 52 rx_info->bss_type = priv->bss_type;
53 53
54 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
55 return mwifiex_process_uap_rx_packet(adapter, skb);
56
54 return mwifiex_process_sta_rx_packet(adapter, skb); 57 return mwifiex_process_sta_rx_packet(adapter, skb);
55} 58}
56EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); 59EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
@@ -157,6 +160,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
157 priv->stats.tx_errors++; 160 priv->stats.tx_errors++;
158 } 161 }
159 162
163 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
164 atomic_dec_return(&adapter->pending_bridged_pkts);
160 if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) 165 if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING)
161 goto done; 166 goto done;
162 167
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index f40e93fe894a..c10aac04be6a 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -167,6 +167,7 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
167 if (ht_ie) { 167 if (ht_ie) {
168 memcpy(&bss_cfg->ht_cap, ht_ie + 2, 168 memcpy(&bss_cfg->ht_cap, ht_ie + 2,
169 sizeof(struct ieee80211_ht_cap)); 169 sizeof(struct ieee80211_ht_cap));
170 priv->ap_11n_enabled = 1;
170 } else { 171 } else {
171 memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); 172 memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
172 bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP); 173 bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
new file mode 100644
index 000000000000..a33fa394e349
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -0,0 +1,290 @@
1/*
2 * Marvell Wireless LAN device driver: AP event handling
3 *
4 * Copyright (C) 2012, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "main.h"
22#include "11n.h"
23
24/*
25 * This function will return the pointer to station entry in station list
26 * table which matches specified mac address.
27 * This function should be called after acquiring RA list spinlock.
28 * NULL is returned if station entry is not found in associated STA list.
29 */
30struct mwifiex_sta_node *
31mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac)
32{
33 struct mwifiex_sta_node *node;
34
35 if (!mac)
36 return NULL;
37
38 list_for_each_entry(node, &priv->sta_list, list) {
39 if (!memcmp(node->mac_addr, mac, ETH_ALEN))
40 return node;
41 }
42
43 return NULL;
44}
45
46/*
47 * This function will add a sta_node entry to associated station list
48 * table with the given mac address.
49 * If entry exist already, existing entry is returned.
50 * If received mac address is NULL, NULL is returned.
51 */
52static struct mwifiex_sta_node *
53mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac)
54{
55 struct mwifiex_sta_node *node;
56 unsigned long flags;
57
58 if (!mac)
59 return NULL;
60
61 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
62 node = mwifiex_get_sta_entry(priv, mac);
63 if (node)
64 goto done;
65
66 node = kzalloc(sizeof(struct mwifiex_sta_node), GFP_ATOMIC);
67 if (!node)
68 goto done;
69
70 memcpy(node->mac_addr, mac, ETH_ALEN);
71 list_add_tail(&node->list, &priv->sta_list);
72
73done:
74 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
75 return node;
76}
77
78/*
79 * This function will search for HT IE in association request IEs
80 * and set station HT parameters accordingly.
81 */
82static void
83mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
84 int ies_len, struct mwifiex_sta_node *node)
85{
86 const struct ieee80211_ht_cap *ht_cap;
87
88 if (!ies)
89 return;
90
91 ht_cap = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
92 if (ht_cap) {
93 node->is_11n_enabled = 1;
94 node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
95 IEEE80211_HT_CAP_MAX_AMSDU ?
96 MWIFIEX_TX_DATA_BUF_SIZE_8K :
97 MWIFIEX_TX_DATA_BUF_SIZE_4K;
98 } else {
99 node->is_11n_enabled = 0;
100 }
101
102 return;
103}
104
105/*
106 * This function will delete a station entry from station list
107 */
108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
109{
110 struct mwifiex_sta_node *node, *tmp;
111 unsigned long flags;
112
113 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
114
115 node = mwifiex_get_sta_entry(priv, mac);
116 if (node) {
117 list_for_each_entry_safe(node, tmp, &priv->sta_list,
118 list) {
119 list_del(&node->list);
120 kfree(node);
121 }
122 }
123
124 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
125 return;
126}
127
128/*
129 * This function will delete all stations from associated station list.
130 */
131static void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
132{
133 struct mwifiex_sta_node *node, *tmp;
134 unsigned long flags;
135
136 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
137
138 list_for_each_entry_safe(node, tmp, &priv->sta_list, list) {
139 list_del(&node->list);
140 kfree(node);
141 }
142
143 INIT_LIST_HEAD(&priv->sta_list);
144 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
145 return;
146}
147
148/*
149 * This function handles AP interface specific events generated by firmware.
150 *
151 * Event specific routines are called by this function based
152 * upon the generated event cause.
153 *
154 *
155 * Events supported for AP -
156 * - EVENT_UAP_STA_ASSOC
157 * - EVENT_UAP_STA_DEAUTH
158 * - EVENT_UAP_BSS_ACTIVE
159 * - EVENT_UAP_BSS_START
160 * - EVENT_UAP_BSS_IDLE
161 * - EVENT_UAP_MIC_COUNTERMEASURES:
162 */
163int mwifiex_process_uap_event(struct mwifiex_private *priv)
164{
165 struct mwifiex_adapter *adapter = priv->adapter;
166 int len, i;
167 u32 eventcause = adapter->event_cause;
168 struct station_info sinfo;
169 struct mwifiex_assoc_event *event;
170 struct mwifiex_sta_node *node;
171 u8 *deauth_mac;
172 struct host_cmd_ds_11n_batimeout *ba_timeout;
173 u16 ctrl;
174
175 switch (eventcause) {
176 case EVENT_UAP_STA_ASSOC:
177 memset(&sinfo, 0, sizeof(sinfo));
178 event = (struct mwifiex_assoc_event *)
179 (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER);
180 if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
181 len = -1;
182
183 if (ieee80211_is_assoc_req(event->frame_control))
184 len = 0;
185 else if (ieee80211_is_reassoc_req(event->frame_control))
186 /* There will be ETH_ALEN bytes of
187 * current_ap_addr before the re-assoc ies.
188 */
189 len = ETH_ALEN;
190
191 if (len != -1) {
192 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
193 sinfo.assoc_req_ies = &event->data[len];
194 len = (u8 *)sinfo.assoc_req_ies -
195 (u8 *)&event->frame_control;
196 sinfo.assoc_req_ies_len =
197 le16_to_cpu(event->len) - (u16)len;
198 }
199 }
200 cfg80211_new_sta(priv->netdev, event->sta_addr, &sinfo,
201 GFP_KERNEL);
202
203 node = mwifiex_add_sta_entry(priv, event->sta_addr);
204 if (!node) {
205 dev_warn(adapter->dev,
206 "could not create station entry!\n");
207 return -1;
208 }
209
210 if (!priv->ap_11n_enabled)
211 break;
212
213 mwifiex_set_sta_ht_cap(priv, sinfo.assoc_req_ies,
214 sinfo.assoc_req_ies_len, node);
215
216 for (i = 0; i < MAX_NUM_TID; i++) {
217 if (node->is_11n_enabled)
218 node->ampdu_sta[i] =
219 priv->aggr_prio_tbl[i].ampdu_user;
220 else
221 node->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
222 }
223 memset(node->rx_seq, 0xff, sizeof(node->rx_seq));
224 break;
225 case EVENT_UAP_STA_DEAUTH:
226 deauth_mac = adapter->event_body +
227 MWIFIEX_UAP_EVENT_EXTRA_HEADER;
228 cfg80211_del_sta(priv->netdev, deauth_mac, GFP_KERNEL);
229
230 if (priv->ap_11n_enabled) {
231 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, deauth_mac);
232 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, deauth_mac);
233 }
234 mwifiex_del_sta_entry(priv, deauth_mac);
235 break;
236 case EVENT_UAP_BSS_IDLE:
237 priv->media_connected = false;
238 mwifiex_clean_txrx(priv);
239 mwifiex_del_all_sta_list(priv);
240 break;
241 case EVENT_UAP_BSS_ACTIVE:
242 priv->media_connected = true;
243 break;
244 case EVENT_UAP_BSS_START:
245 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
246 memcpy(priv->netdev->dev_addr, adapter->event_body + 2,
247 ETH_ALEN);
248 break;
249 case EVENT_UAP_MIC_COUNTERMEASURES:
250 /* For future development */
251 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
252 break;
253 case EVENT_AMSDU_AGGR_CTRL:
254 ctrl = le16_to_cpu(*(__le16 *)adapter->event_body);
255 dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", ctrl);
256
257 if (priv->media_connected) {
258 adapter->tx_buf_size =
259 min_t(u16, adapter->curr_tx_buf_size, ctrl);
260 dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
261 adapter->tx_buf_size);
262 }
263 break;
264 case EVENT_ADDBA:
265 dev_dbg(adapter->dev, "event: ADDBA Request\n");
266 if (priv->media_connected)
267 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP,
268 HostCmd_ACT_GEN_SET, 0,
269 adapter->event_body);
270 break;
271 case EVENT_DELBA:
272 dev_dbg(adapter->dev, "event: DELBA Request\n");
273 if (priv->media_connected)
274 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
275 break;
276 case EVENT_BA_STREAM_TIEMOUT:
277 dev_dbg(adapter->dev, "event: BA Stream timeout\n");
278 if (priv->media_connected) {
279 ba_timeout = (void *)adapter->event_body;
280 mwifiex_11n_ba_stream_timeout(priv, ba_timeout);
281 }
282 break;
283 default:
284 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
285 eventcause);
286 break;
287 }
288
289 return 0;
290}
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
new file mode 100644
index 000000000000..6d814f0f07f2
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -0,0 +1,255 @@
1/*
2 * Marvell Wireless LAN device driver: AP TX and RX data handling
3 *
4 * Copyright (C) 2012, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "main.h"
23#include "wmm.h"
24#include "11n_aggr.h"
25#include "11n_rxreorder.h"
26
27static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
28 struct sk_buff *skb)
29{
30 struct mwifiex_adapter *adapter = priv->adapter;
31 struct uap_rxpd *uap_rx_pd;
32 struct rx_packet_hdr *rx_pkt_hdr;
33 struct sk_buff *new_skb;
34 struct mwifiex_txinfo *tx_info;
35 int hdr_chop;
36 struct timeval tv;
37 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
38
39 uap_rx_pd = (struct uap_rxpd *)(skb->data);
40 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
41
42 if ((atomic_read(&adapter->pending_bridged_pkts) >=
43 MWIFIEX_BRIDGED_PKTS_THRESHOLD)) {
44 dev_err(priv->adapter->dev,
45 "Tx: Bridge packet limit reached. Drop packet!\n");
46 kfree_skb(skb);
47 return;
48 }
49
50 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
51 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)))
52 /* Chop off the rxpd + the excess memory from
53 * 802.2/llc/snap header that was removed.
54 */
55 hdr_chop = (u8 *)eth_hdr - (u8 *)uap_rx_pd;
56 else
57 /* Chop off the rxpd */
58 hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd;
59
60 /* Chop off the leading header bytes so the it points
61 * to the start of either the reconstructed EthII frame
62 * or the 802.2/llc/snap frame.
63 */
64 skb_pull(skb, hdr_chop);
65
66 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
67 dev_dbg(priv->adapter->dev,
68 "data: Tx: insufficient skb headroom %d\n",
69 skb_headroom(skb));
70 /* Insufficient skb headroom - allocate a new skb */
71 new_skb =
72 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
73 if (unlikely(!new_skb)) {
74 dev_err(priv->adapter->dev,
75 "Tx: cannot allocate new_skb\n");
76 kfree_skb(skb);
77 priv->stats.tx_dropped++;
78 return;
79 }
80
81 kfree_skb(skb);
82 skb = new_skb;
83 dev_dbg(priv->adapter->dev, "info: new skb headroom %d\n",
84 skb_headroom(skb));
85 }
86
87 tx_info = MWIFIEX_SKB_TXCB(skb);
88 tx_info->bss_num = priv->bss_num;
89 tx_info->bss_type = priv->bss_type;
90 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
91
92 do_gettimeofday(&tv);
93 skb->tstamp = timeval_to_ktime(tv);
94 mwifiex_wmm_add_buf_txqueue(priv, skb);
95 atomic_inc(&adapter->tx_pending);
96 atomic_inc(&adapter->pending_bridged_pkts);
97
98 if ((atomic_read(&adapter->tx_pending) >= MAX_TX_PENDING)) {
99 mwifiex_set_trans_start(priv->netdev);
100 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
101 }
102 return;
103}
104
105/*
106 * This function contains logic for AP packet forwarding.
107 *
108 * If a packet is multicast/broadcast, it is sent to kernel/upper layer
109 * as well as queued back to AP TX queue so that it can be sent to other
110 * associated stations.
111 * If a packet is unicast and RA is present in associated station list,
112 * it is again requeued into AP TX queue.
113 * If a packet is unicast and RA is not in associated station list,
114 * packet is forwarded to kernel to handle routing logic.
115 */
116int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv,
117 struct sk_buff *skb)
118{
119 struct mwifiex_adapter *adapter = priv->adapter;
120 struct uap_rxpd *uap_rx_pd;
121 struct rx_packet_hdr *rx_pkt_hdr;
122 u8 ra[ETH_ALEN];
123 struct sk_buff *skb_uap;
124
125 uap_rx_pd = (struct uap_rxpd *)(skb->data);
126 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
127
128 /* don't do packet forwarding in disconnected state */
129 if (!priv->media_connected) {
130 dev_err(adapter->dev, "drop packet in disconnected state.\n");
131 dev_kfree_skb_any(skb);
132 return 0;
133 }
134
135 memcpy(ra, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN);
136
137 if (is_multicast_ether_addr(ra)) {
138 skb_uap = skb_copy(skb, GFP_ATOMIC);
139 mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
140 } else {
141 if (mwifiex_get_sta_entry(priv, ra)) {
142 /* Requeue Intra-BSS packet */
143 mwifiex_uap_queue_bridged_pkt(priv, skb);
144 return 0;
145 }
146 }
147
148 /* Forward unicat/Inter-BSS packets to kernel. */
149 return mwifiex_process_rx_packet(adapter, skb);
150}
151
152/*
153 * This function processes the packet received on AP interface.
154 *
155 * The function looks into the RxPD and performs sanity tests on the
156 * received buffer to ensure its a valid packet before processing it
157 * further. If the packet is determined to be aggregated, it is
158 * de-aggregated accordingly. Then skb is passed to AP packet forwarding logic.
159 *
160 * The completion callback is called after processing is complete.
161 */
162int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
163 struct sk_buff *skb)
164{
165 int ret;
166 struct uap_rxpd *uap_rx_pd;
167 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
168 struct rx_packet_hdr *rx_pkt_hdr;
169 u16 rx_pkt_type;
170 u8 ta[ETH_ALEN], pkt_type;
171 struct mwifiex_sta_node *node;
172
173 struct mwifiex_private *priv =
174 mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
175 rx_info->bss_type);
176
177 if (!priv)
178 return -1;
179
180 uap_rx_pd = (struct uap_rxpd *)(skb->data);
181 rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
182 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
183
184 if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
185 le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) {
186 dev_err(adapter->dev,
187 "wrong rx packet: len=%d, offset=%d, length=%d\n",
188 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
189 le16_to_cpu(uap_rx_pd->rx_pkt_length));
190 priv->stats.rx_dropped++;
191
192 if (adapter->if_ops.data_complete)
193 adapter->if_ops.data_complete(adapter, skb);
194 else
195 dev_kfree_skb_any(skb);
196
197 return 0;
198 }
199
200 if (le16_to_cpu(uap_rx_pd->rx_pkt_type) == PKT_TYPE_AMSDU) {
201 struct sk_buff_head list;
202 struct sk_buff *rx_skb;
203
204 __skb_queue_head_init(&list);
205 skb_pull(skb, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
206 skb_trim(skb, le16_to_cpu(uap_rx_pd->rx_pkt_length));
207
208 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
209 priv->wdev->iftype, 0, false);
210
211 while (!skb_queue_empty(&list)) {
212 rx_skb = __skb_dequeue(&list);
213 ret = mwifiex_recv_packet(adapter, rx_skb);
214 if (ret)
215 dev_err(adapter->dev,
216 "AP:Rx A-MSDU failed");
217 }
218
219 return 0;
220 }
221
222 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
223
224 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
225 node = mwifiex_get_sta_entry(priv, ta);
226 if (node)
227 node->rx_seq[uap_rx_pd->priority] =
228 le16_to_cpu(uap_rx_pd->seq_num);
229 }
230
231 if (!priv->ap_11n_enabled ||
232 (!mwifiex_11n_get_rx_reorder_tbl(priv, uap_rx_pd->priority, ta) &&
233 (le16_to_cpu(uap_rx_pd->rx_pkt_type) != PKT_TYPE_AMSDU))) {
234 ret = mwifiex_handle_uap_rx_forward(priv, skb);
235 return ret;
236 }
237
238 /* Reorder and send to kernel */
239 pkt_type = (u8)le16_to_cpu(uap_rx_pd->rx_pkt_type);
240 ret = mwifiex_11n_rx_reorder_pkt(priv, le16_to_cpu(uap_rx_pd->seq_num),
241 uap_rx_pd->priority, ta, pkt_type,
242 skb);
243
244 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
245 if (adapter->if_ops.data_complete)
246 adapter->if_ops.data_complete(adapter, skb);
247 else
248 dev_kfree_skb_any(skb);
249 }
250
251 if (ret)
252 priv->stats.rx_dropped++;
253
254 return ret;
255}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 3fa4d4176993..8ccd6999fa9f 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -127,6 +127,29 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
127 return ra_list; 127 return ra_list;
128} 128}
129 129
130/* This function returns random no between 16 and 32 to be used as threshold
131 * for no of packets after which BA setup is initiated.
132 */
133static u8 mwifiex_get_random_ba_threshold(void)
134{
135 u32 sec, usec;
136 struct timeval ba_tstamp;
137 u8 ba_threshold;
138
139 /* setup ba_packet_threshold here random number between
140 * [BA_SETUP_PACKET_OFFSET,
141 * BA_SETUP_PACKET_OFFSET+BA_SETUP_MAX_PACKET_THRESHOLD-1]
142 */
143
144 do_gettimeofday(&ba_tstamp);
145 sec = (ba_tstamp.tv_sec & 0xFFFF) + (ba_tstamp.tv_sec >> 16);
146 usec = (ba_tstamp.tv_usec & 0xFFFF) + (ba_tstamp.tv_usec >> 16);
147 ba_threshold = (((sec << 16) + usec) % BA_SETUP_MAX_PACKET_THRESHOLD)
148 + BA_SETUP_PACKET_OFFSET;
149
150 return ba_threshold;
151}
152
130/* 153/*
131 * This function allocates and adds a RA list for all TIDs 154 * This function allocates and adds a RA list for all TIDs
132 * with the given RA. 155 * with the given RA.
@@ -137,6 +160,12 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
137 int i; 160 int i;
138 struct mwifiex_ra_list_tbl *ra_list; 161 struct mwifiex_ra_list_tbl *ra_list;
139 struct mwifiex_adapter *adapter = priv->adapter; 162 struct mwifiex_adapter *adapter = priv->adapter;
163 struct mwifiex_sta_node *node;
164 unsigned long flags;
165
166 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
167 node = mwifiex_get_sta_entry(priv, ra);
168 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
140 169
141 for (i = 0; i < MAX_NUM_TID; ++i) { 170 for (i = 0; i < MAX_NUM_TID; ++i) {
142 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra); 171 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
@@ -145,14 +174,24 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
145 if (!ra_list) 174 if (!ra_list)
146 break; 175 break;
147 176
148 if (!mwifiex_queuing_ra_based(priv)) 177 ra_list->is_11n_enabled = 0;
178 if (!mwifiex_queuing_ra_based(priv)) {
149 ra_list->is_11n_enabled = IS_11N_ENABLED(priv); 179 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
150 else 180 } else {
151 ra_list->is_11n_enabled = false; 181 ra_list->is_11n_enabled =
182 mwifiex_is_sta_11n_enabled(priv, node);
183 if (ra_list->is_11n_enabled)
184 ra_list->max_amsdu = node->max_amsdu;
185 }
152 186
153 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n", 187 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",
154 ra_list, ra_list->is_11n_enabled); 188 ra_list, ra_list->is_11n_enabled);
155 189
190 if (ra_list->is_11n_enabled) {
191 ra_list->pkt_count = 0;
192 ra_list->ba_packet_thr =
193 mwifiex_get_random_ba_threshold();
194 }
156 list_add_tail(&ra_list->list, 195 list_add_tail(&ra_list->list,
157 &priv->wmm.tid_tbl_ptr[i].ra_list); 196 &priv->wmm.tid_tbl_ptr[i].ra_list);
158 197
@@ -647,6 +686,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
647 skb_queue_tail(&ra_list->skb_head, skb); 686 skb_queue_tail(&ra_list->skb_head, skb);
648 687
649 ra_list->total_pkts_size += skb->len; 688 ra_list->total_pkts_size += skb->len;
689 ra_list->pkt_count++;
650 690
651 atomic_inc(&priv->wmm.tx_pkts_queued); 691 atomic_inc(&priv->wmm.tx_pkts_queued);
652 692
@@ -986,10 +1026,17 @@ mwifiex_is_11n_aggragation_possible(struct mwifiex_private *priv,
986{ 1026{
987 int count = 0, total_size = 0; 1027 int count = 0, total_size = 0;
988 struct sk_buff *skb, *tmp; 1028 struct sk_buff *skb, *tmp;
1029 int max_amsdu_size;
1030
1031 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP && priv->ap_11n_enabled &&
1032 ptr->is_11n_enabled)
1033 max_amsdu_size = min_t(int, ptr->max_amsdu, max_buf_size);
1034 else
1035 max_amsdu_size = max_buf_size;
989 1036
990 skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { 1037 skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
991 total_size += skb->len; 1038 total_size += skb->len;
992 if (total_size >= max_buf_size) 1039 if (total_size >= max_amsdu_size)
993 break; 1040 break;
994 if (++count >= MIN_NUM_AMSDU) 1041 if (++count >= MIN_NUM_AMSDU)
995 return true; 1042 return true;
@@ -1050,6 +1097,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1050 skb_queue_tail(&ptr->skb_head, skb); 1097 skb_queue_tail(&ptr->skb_head, skb);
1051 1098
1052 ptr->total_pkts_size += skb->len; 1099 ptr->total_pkts_size += skb->len;
1100 ptr->pkt_count++;
1053 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; 1101 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
1054 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1102 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1055 ra_list_flags); 1103 ra_list_flags);
@@ -1231,7 +1279,8 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1231 /* ra_list_spinlock has been freed in 1279 /* ra_list_spinlock has been freed in
1232 mwifiex_send_single_packet() */ 1280 mwifiex_send_single_packet() */
1233 } else { 1281 } else {
1234 if (mwifiex_is_ampdu_allowed(priv, tid)) { 1282 if (mwifiex_is_ampdu_allowed(priv, tid) &&
1283 ptr->pkt_count > ptr->ba_packet_thr) {
1235 if (mwifiex_space_avail_for_new_ba_stream(adapter)) { 1284 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1236 mwifiex_create_ba_tbl(priv, ptr->ra, tid, 1285 mwifiex_create_ba_tbl(priv, ptr->ra, tid,
1237 BA_SETUP_INPROGRESS); 1286 BA_SETUP_INPROGRESS);
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 14037092ba89..1ef1bfe6a9d7 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -76,6 +76,7 @@ struct p54_channel_entry {
76 u16 freq; 76 u16 freq;
77 u16 data; 77 u16 data;
78 int index; 78 int index;
79 int max_power;
79 enum ieee80211_band band; 80 enum ieee80211_band band;
80}; 81};
81 82
@@ -173,6 +174,7 @@ static int p54_generate_band(struct ieee80211_hw *dev,
173 for (i = 0, j = 0; (j < list->band_channel_num[band]) && 174 for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
174 (i < list->entries); i++) { 175 (i < list->entries); i++) {
175 struct p54_channel_entry *chan = &list->channels[i]; 176 struct p54_channel_entry *chan = &list->channels[i];
177 struct ieee80211_channel *dest = &tmp->channels[j];
176 178
177 if (chan->band != band) 179 if (chan->band != band)
178 continue; 180 continue;
@@ -190,14 +192,15 @@ static int p54_generate_band(struct ieee80211_hw *dev,
190 continue; 192 continue;
191 } 193 }
192 194
193 tmp->channels[j].band = chan->band; 195 dest->band = chan->band;
194 tmp->channels[j].center_freq = chan->freq; 196 dest->center_freq = chan->freq;
197 dest->max_power = chan->max_power;
195 priv->survey[*chan_num].channel = &tmp->channels[j]; 198 priv->survey[*chan_num].channel = &tmp->channels[j];
196 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM | 199 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
197 SURVEY_INFO_CHANNEL_TIME | 200 SURVEY_INFO_CHANNEL_TIME |
198 SURVEY_INFO_CHANNEL_TIME_BUSY | 201 SURVEY_INFO_CHANNEL_TIME_BUSY |
199 SURVEY_INFO_CHANNEL_TIME_TX; 202 SURVEY_INFO_CHANNEL_TIME_TX;
200 tmp->channels[j].hw_value = (*chan_num); 203 dest->hw_value = (*chan_num);
201 j++; 204 j++;
202 (*chan_num)++; 205 (*chan_num)++;
203 } 206 }
@@ -229,10 +232,11 @@ err_out:
229 return ret; 232 return ret;
230} 233}
231 234
232static void p54_update_channel_param(struct p54_channel_list *list, 235static struct p54_channel_entry *p54_update_channel_param(struct p54_channel_list *list,
233 u16 freq, u16 data) 236 u16 freq, u16 data)
234{ 237{
235 int band, i; 238 int i;
239 struct p54_channel_entry *entry = NULL;
236 240
237 /* 241 /*
238 * usually all lists in the eeprom are mostly sorted. 242 * usually all lists in the eeprom are mostly sorted.
@@ -241,30 +245,78 @@ static void p54_update_channel_param(struct p54_channel_list *list,
241 */ 245 */
242 for (i = list->entries; i >= 0; i--) { 246 for (i = list->entries; i >= 0; i--) {
243 if (freq == list->channels[i].freq) { 247 if (freq == list->channels[i].freq) {
244 list->channels[i].data |= data; 248 entry = &list->channels[i];
245 break; 249 break;
246 } 250 }
247 } 251 }
248 252
249 if ((i < 0) && (list->entries < list->max_entries)) { 253 if ((i < 0) && (list->entries < list->max_entries)) {
250 /* entry does not exist yet. Initialize a new one. */ 254 /* entry does not exist yet. Initialize a new one. */
251 band = p54_get_band_from_freq(freq); 255 int band = p54_get_band_from_freq(freq);
252 256
253 /* 257 /*
254 * filter out frequencies which don't belong into 258 * filter out frequencies which don't belong into
255 * any supported band. 259 * any supported band.
256 */ 260 */
257 if (band < 0) 261 if (band >= 0) {
258 return ; 262 i = list->entries++;
263 list->band_channel_num[band]++;
264
265 entry = &list->channels[i];
266 entry->freq = freq;
267 entry->band = band;
268 entry->index = ieee80211_frequency_to_channel(freq);
269 entry->max_power = 0;
270 entry->data = 0;
271 }
272 }
259 273
260 i = list->entries++; 274 if (entry)
261 list->band_channel_num[band]++; 275 entry->data |= data;
262 276
263 list->channels[i].freq = freq; 277 return entry;
264 list->channels[i].data = data; 278}
265 list->channels[i].band = band; 279
266 list->channels[i].index = ieee80211_frequency_to_channel(freq); 280static int p54_get_maxpower(struct p54_common *priv, void *data)
267 /* TODO: parse output_limit and fill max_power */ 281{
282 switch (priv->rxhw & PDR_SYNTH_FRONTEND_MASK) {
283 case PDR_SYNTH_FRONTEND_LONGBOW: {
284 struct pda_channel_output_limit_longbow *pda = data;
285 int j;
286 u16 rawpower = 0;
287 pda = data;
288 for (j = 0; j < ARRAY_SIZE(pda->point); j++) {
289 struct pda_channel_output_limit_point_longbow *point =
290 &pda->point[j];
291 rawpower = max_t(u16,
292 rawpower, le16_to_cpu(point->val_qpsk));
293 rawpower = max_t(u16,
294 rawpower, le16_to_cpu(point->val_bpsk));
295 rawpower = max_t(u16,
296 rawpower, le16_to_cpu(point->val_16qam));
297 rawpower = max_t(u16,
298 rawpower, le16_to_cpu(point->val_64qam));
299 }
300 /* longbow seems to use 1/16 dBm units */
301 return rawpower / 16;
302 }
303
304 case PDR_SYNTH_FRONTEND_DUETTE3:
305 case PDR_SYNTH_FRONTEND_DUETTE2:
306 case PDR_SYNTH_FRONTEND_FRISBEE:
307 case PDR_SYNTH_FRONTEND_XBOW: {
308 struct pda_channel_output_limit *pda = data;
309 u8 rawpower = 0;
310 rawpower = max(rawpower, pda->val_qpsk);
311 rawpower = max(rawpower, pda->val_bpsk);
312 rawpower = max(rawpower, pda->val_16qam);
313 rawpower = max(rawpower, pda->val_64qam);
314 /* raw values are in 1/4 dBm units */
315 return rawpower / 4;
316 }
317
318 default:
319 return 20;
268 } 320 }
269} 321}
270 322
@@ -315,12 +367,19 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
315 } 367 }
316 368
317 if (i < priv->output_limit->entries) { 369 if (i < priv->output_limit->entries) {
318 freq = le16_to_cpup((__le16 *) (i * 370 struct p54_channel_entry *tmp;
319 priv->output_limit->entry_size + 371
320 priv->output_limit->offset + 372 void *data = (void *) ((unsigned long) i *
321 priv->output_limit->data)); 373 priv->output_limit->entry_size +
322 374 priv->output_limit->offset +
323 p54_update_channel_param(list, freq, CHAN_HAS_LIMIT); 375 priv->output_limit->data);
376
377 freq = le16_to_cpup((__le16 *) data);
378 tmp = p54_update_channel_param(list, freq,
379 CHAN_HAS_LIMIT);
380 if (tmp) {
381 tmp->max_power = p54_get_maxpower(priv, data);
382 }
324 } 383 }
325 384
326 if (i < priv->curve_data->entries) { 385 if (i < priv->curve_data->entries) {
@@ -834,11 +893,12 @@ good_eeprom:
834 goto err; 893 goto err;
835 } 894 }
836 895
896 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
897
837 err = p54_generate_channel_lists(dev); 898 err = p54_generate_channel_lists(dev);
838 if (err) 899 if (err)
839 goto err; 900 goto err;
840 901
841 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
842 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) 902 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
843 p54_init_xbow_synth(priv); 903 p54_init_xbow_synth(priv);
844 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) 904 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
diff --git a/drivers/net/wireless/p54/eeprom.h b/drivers/net/wireless/p54/eeprom.h
index afde72b84606..20ebe39a3f4e 100644
--- a/drivers/net/wireless/p54/eeprom.h
+++ b/drivers/net/wireless/p54/eeprom.h
@@ -57,6 +57,18 @@ struct pda_channel_output_limit {
57 u8 rate_set_size; 57 u8 rate_set_size;
58} __packed; 58} __packed;
59 59
60struct pda_channel_output_limit_point_longbow {
61 __le16 val_bpsk;
62 __le16 val_qpsk;
63 __le16 val_16qam;
64 __le16 val_64qam;
65} __packed;
66
67struct pda_channel_output_limit_longbow {
68 __le16 freq;
69 struct pda_channel_output_limit_point_longbow point[3];
70} __packed;
71
60struct pda_pa_curve_data_sample_rev0 { 72struct pda_pa_curve_data_sample_rev0 {
61 u8 rf_power; 73 u8 rf_power;
62 u8 pa_detector; 74 u8 pa_detector;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 89318adc8c7f..b4390797d78c 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -488,6 +488,58 @@ static int p54p_open(struct ieee80211_hw *dev)
488 return 0; 488 return 0;
489} 489}
490 490
491static void p54p_firmware_step2(const struct firmware *fw,
492 void *context)
493{
494 struct p54p_priv *priv = context;
495 struct ieee80211_hw *dev = priv->common.hw;
496 struct pci_dev *pdev = priv->pdev;
497 int err;
498
499 if (!fw) {
500 dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
501 err = -ENOENT;
502 goto out;
503 }
504
505 priv->firmware = fw;
506
507 err = p54p_open(dev);
508 if (err)
509 goto out;
510 err = p54_read_eeprom(dev);
511 p54p_stop(dev);
512 if (err)
513 goto out;
514
515 err = p54_register_common(dev, &pdev->dev);
516 if (err)
517 goto out;
518
519out:
520
521 complete(&priv->fw_loaded);
522
523 if (err) {
524 struct device *parent = pdev->dev.parent;
525
526 if (parent)
527 device_lock(parent);
528
529 /*
530 * This will indirectly result in a call to p54p_remove.
531 * Hence, we don't need to bother with freeing any
532 * allocated ressources at all.
533 */
534 device_release_driver(&pdev->dev);
535
536 if (parent)
537 device_unlock(parent);
538 }
539
540 pci_dev_put(pdev);
541}
542
491static int __devinit p54p_probe(struct pci_dev *pdev, 543static int __devinit p54p_probe(struct pci_dev *pdev,
492 const struct pci_device_id *id) 544 const struct pci_device_id *id)
493{ 545{
@@ -496,6 +548,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
496 unsigned long mem_addr, mem_len; 548 unsigned long mem_addr, mem_len;
497 int err; 549 int err;
498 550
551 pci_dev_get(pdev);
499 err = pci_enable_device(pdev); 552 err = pci_enable_device(pdev);
500 if (err) { 553 if (err) {
501 dev_err(&pdev->dev, "Cannot enable new PCI device\n"); 554 dev_err(&pdev->dev, "Cannot enable new PCI device\n");
@@ -537,6 +590,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
537 priv = dev->priv; 590 priv = dev->priv;
538 priv->pdev = pdev; 591 priv->pdev = pdev;
539 592
593 init_completion(&priv->fw_loaded);
540 SET_IEEE80211_DEV(dev, &pdev->dev); 594 SET_IEEE80211_DEV(dev, &pdev->dev);
541 pci_set_drvdata(pdev, dev); 595 pci_set_drvdata(pdev, dev);
542 596
@@ -561,32 +615,12 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
561 spin_lock_init(&priv->lock); 615 spin_lock_init(&priv->lock);
562 tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev); 616 tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
563 617
564 err = request_firmware(&priv->firmware, "isl3886pci", 618 err = request_firmware_nowait(THIS_MODULE, 1, "isl3886pci",
565 &priv->pdev->dev); 619 &priv->pdev->dev, GFP_KERNEL,
566 if (err) { 620 priv, p54p_firmware_step2);
567 dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n"); 621 if (!err)
568 err = request_firmware(&priv->firmware, "isl3886", 622 return 0;
569 &priv->pdev->dev);
570 if (err)
571 goto err_free_common;
572 }
573
574 err = p54p_open(dev);
575 if (err)
576 goto err_free_common;
577 err = p54_read_eeprom(dev);
578 p54p_stop(dev);
579 if (err)
580 goto err_free_common;
581
582 err = p54_register_common(dev, &pdev->dev);
583 if (err)
584 goto err_free_common;
585
586 return 0;
587 623
588 err_free_common:
589 release_firmware(priv->firmware);
590 pci_free_consistent(pdev, sizeof(*priv->ring_control), 624 pci_free_consistent(pdev, sizeof(*priv->ring_control),
591 priv->ring_control, priv->ring_control_dma); 625 priv->ring_control, priv->ring_control_dma);
592 626
@@ -601,6 +635,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
601 pci_release_regions(pdev); 635 pci_release_regions(pdev);
602 err_disable_dev: 636 err_disable_dev:
603 pci_disable_device(pdev); 637 pci_disable_device(pdev);
638 pci_dev_put(pdev);
604 return err; 639 return err;
605} 640}
606 641
@@ -612,8 +647,9 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
612 if (!dev) 647 if (!dev)
613 return; 648 return;
614 649
615 p54_unregister_common(dev);
616 priv = dev->priv; 650 priv = dev->priv;
651 wait_for_completion(&priv->fw_loaded);
652 p54_unregister_common(dev);
617 release_firmware(priv->firmware); 653 release_firmware(priv->firmware);
618 pci_free_consistent(pdev, sizeof(*priv->ring_control), 654 pci_free_consistent(pdev, sizeof(*priv->ring_control),
619 priv->ring_control, priv->ring_control_dma); 655 priv->ring_control, priv->ring_control_dma);
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h
index 7aa509f7e387..68405c142f97 100644
--- a/drivers/net/wireless/p54/p54pci.h
+++ b/drivers/net/wireless/p54/p54pci.h
@@ -105,6 +105,7 @@ struct p54p_priv {
105 struct sk_buff *tx_buf_data[32]; 105 struct sk_buff *tx_buf_data[32];
106 struct sk_buff *tx_buf_mgmt[4]; 106 struct sk_buff *tx_buf_mgmt[4];
107 struct completion boot_comp; 107 struct completion boot_comp;
108 struct completion fw_loaded;
108}; 109};
109 110
110#endif /* P54USB_H */ 111#endif /* P54USB_H */
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 7e2ddc042f5b..c6250867a95d 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -190,16 +190,30 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
190{ 190{
191 struct ssb_bus *bus = mcore->dev->bus; 191 struct ssb_bus *bus = mcore->dev->bus;
192 192
193 mcore->flash_buswidth = 2; 193 /* When there is no chipcommon on the bus there is 4MB flash */
194 if (bus->chipco.dev) { 194 if (!bus->chipco.dev) {
195 mcore->flash_window = 0x1c000000; 195 mcore->flash_buswidth = 2;
196 mcore->flash_window_size = 0x02000000; 196 mcore->flash_window = SSB_FLASH1;
197 mcore->flash_window_size = SSB_FLASH1_SZ;
198 return;
199 }
200
201 /* There is ChipCommon, so use it to read info about flash */
202 switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
203 case SSB_CHIPCO_FLASHT_STSER:
204 case SSB_CHIPCO_FLASHT_ATSER:
205 pr_err("Serial flash not supported\n");
206 break;
207 case SSB_CHIPCO_FLASHT_PARA:
208 pr_debug("Found parallel flash\n");
209 mcore->flash_window = SSB_FLASH2;
210 mcore->flash_window_size = SSB_FLASH2_SZ;
197 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) 211 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
198 & SSB_CHIPCO_CFG_DS16) == 0) 212 & SSB_CHIPCO_CFG_DS16) == 0)
199 mcore->flash_buswidth = 1; 213 mcore->flash_buswidth = 1;
200 } else { 214 else
201 mcore->flash_window = 0x1fc00000; 215 mcore->flash_buswidth = 2;
202 mcore->flash_window_size = 0x00400000; 216 break;
203 } 217 }
204} 218}
205 219
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index d323a4b4143c..3fb8bbafe5e7 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -100,6 +100,7 @@
100#define BCMA_CC_CHIPST_4706_SFLASH_TYPE BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */ 100#define BCMA_CC_CHIPST_4706_SFLASH_TYPE BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
101#define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */ 101#define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */
102#define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */ 102#define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */
103#define BCMA_CC_CHIPST_5357_NAND_BOOT BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */
103#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ 104#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
104#define BCMA_CC_JCMD_START 0x80000000 105#define BCMA_CC_JCMD_START 0x80000000
105#define BCMA_CC_JCMD_BUSY 0x80000000 106#define BCMA_CC_JCMD_BUSY 0x80000000
@@ -266,6 +267,29 @@
266#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004 267#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
267#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1 268#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1
268#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001 269#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001
270/* Block 0x140 - 0x190 registers are chipset specific */
271#define BCMA_CC_4706_FLASHSCFG 0x18C /* Flash struct configuration */
272#define BCMA_CC_4706_FLASHSCFG_MASK 0x000000ff
273#define BCMA_CC_4706_FLASHSCFG_SF1 0x00000001 /* 2nd serial flash present */
274#define BCMA_CC_4706_FLASHSCFG_PF1 0x00000002 /* 2nd parallel flash present */
275#define BCMA_CC_4706_FLASHSCFG_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */
276#define BCMA_CC_4706_FLASHSCFG_NF1 0x00000008 /* 2nd NAND flash present */
277#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_MASK 0x000000f0
278#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */
279#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */
280#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */
281#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */
282#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */
283#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */
284#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */
285/* NAND flash registers for BCM4706 (corerev = 31) */
286#define BCMA_CC_NFLASH_CTL 0x01A0
287#define BCMA_CC_NFLASH_CTL_ERR 0x08000000
288#define BCMA_CC_NFLASH_CONF 0x01A4
289#define BCMA_CC_NFLASH_COL_ADDR 0x01A8
290#define BCMA_CC_NFLASH_ROW_ADDR 0x01AC
291#define BCMA_CC_NFLASH_DATA 0x01B0
292#define BCMA_CC_NFLASH_WAITCNT0 0x01B4
269/* 0x1E0 is defined as shared BCMA_CLKCTLST */ 293/* 0x1E0 is defined as shared BCMA_CLKCTLST */
270#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ 294#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
271#define BCMA_CC_UART0_DATA 0x0300 295#define BCMA_CC_UART0_DATA 0x0300
@@ -325,6 +349,60 @@
325#define BCMA_CC_PLLCTL_ADDR 0x0660 349#define BCMA_CC_PLLCTL_ADDR 0x0660
326#define BCMA_CC_PLLCTL_DATA 0x0664 350#define BCMA_CC_PLLCTL_DATA 0x0664
327#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ 351#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
352/* NAND flash MLC controller registers (corerev >= 38) */
353#define BCMA_CC_NAND_REVISION 0x0C00
354#define BCMA_CC_NAND_CMD_START 0x0C04
355#define BCMA_CC_NAND_CMD_ADDR_X 0x0C08
356#define BCMA_CC_NAND_CMD_ADDR 0x0C0C
357#define BCMA_CC_NAND_CMD_END_ADDR 0x0C10
358#define BCMA_CC_NAND_CS_NAND_SELECT 0x0C14
359#define BCMA_CC_NAND_CS_NAND_XOR 0x0C18
360#define BCMA_CC_NAND_SPARE_RD0 0x0C20
361#define BCMA_CC_NAND_SPARE_RD4 0x0C24
362#define BCMA_CC_NAND_SPARE_RD8 0x0C28
363#define BCMA_CC_NAND_SPARE_RD12 0x0C2C
364#define BCMA_CC_NAND_SPARE_WR0 0x0C30
365#define BCMA_CC_NAND_SPARE_WR4 0x0C34
366#define BCMA_CC_NAND_SPARE_WR8 0x0C38
367#define BCMA_CC_NAND_SPARE_WR12 0x0C3C
368#define BCMA_CC_NAND_ACC_CONTROL 0x0C40
369#define BCMA_CC_NAND_CONFIG 0x0C48
370#define BCMA_CC_NAND_TIMING_1 0x0C50
371#define BCMA_CC_NAND_TIMING_2 0x0C54
372#define BCMA_CC_NAND_SEMAPHORE 0x0C58
373#define BCMA_CC_NAND_DEVID 0x0C60
374#define BCMA_CC_NAND_DEVID_X 0x0C64
375#define BCMA_CC_NAND_BLOCK_LOCK_STATUS 0x0C68
376#define BCMA_CC_NAND_INTFC_STATUS 0x0C6C
377#define BCMA_CC_NAND_ECC_CORR_ADDR_X 0x0C70
378#define BCMA_CC_NAND_ECC_CORR_ADDR 0x0C74
379#define BCMA_CC_NAND_ECC_UNC_ADDR_X 0x0C78
380#define BCMA_CC_NAND_ECC_UNC_ADDR 0x0C7C
381#define BCMA_CC_NAND_READ_ERROR_COUNT 0x0C80
382#define BCMA_CC_NAND_CORR_STAT_THRESHOLD 0x0C84
383#define BCMA_CC_NAND_READ_ADDR_X 0x0C90
384#define BCMA_CC_NAND_READ_ADDR 0x0C94
385#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR_X 0x0C98
386#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR 0x0C9C
387#define BCMA_CC_NAND_COPY_BACK_ADDR_X 0x0CA0
388#define BCMA_CC_NAND_COPY_BACK_ADDR 0x0CA4
389#define BCMA_CC_NAND_BLOCK_ERASE_ADDR_X 0x0CA8
390#define BCMA_CC_NAND_BLOCK_ERASE_ADDR 0x0CAC
391#define BCMA_CC_NAND_INV_READ_ADDR_X 0x0CB0
392#define BCMA_CC_NAND_INV_READ_ADDR 0x0CB4
393#define BCMA_CC_NAND_BLK_WR_PROTECT 0x0CC0
394#define BCMA_CC_NAND_ACC_CONTROL_CS1 0x0CD0
395#define BCMA_CC_NAND_CONFIG_CS1 0x0CD4
396#define BCMA_CC_NAND_TIMING_1_CS1 0x0CD8
397#define BCMA_CC_NAND_TIMING_2_CS1 0x0CDC
398#define BCMA_CC_NAND_SPARE_RD16 0x0D30
399#define BCMA_CC_NAND_SPARE_RD20 0x0D34
400#define BCMA_CC_NAND_SPARE_RD24 0x0D38
401#define BCMA_CC_NAND_SPARE_RD28 0x0D3C
402#define BCMA_CC_NAND_CACHE_ADDR 0x0D40
403#define BCMA_CC_NAND_CACHE_DATA 0x0D44
404#define BCMA_CC_NAND_CTRL_CONFIG 0x0D48
405#define BCMA_CC_NAND_CTRL_STATUS 0x0D4C
328 406
329/* Divider allocation in 4716/47162/5356 */ 407/* Divider allocation in 4716/47162/5356 */
330#define BCMA_CC_PMU5_MAINPLL_CPU 1 408#define BCMA_CC_PMU5_MAINPLL_CPU 1
@@ -415,6 +493,13 @@
415/* 4313 Chip specific ChipControl register bits */ 493/* 4313 Chip specific ChipControl register bits */
416#define BCMA_CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ 494#define BCMA_CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */
417 495
496/* BCM5357 ChipControl register bits */
497#define BCMA_CHIPCTL_5357_EXTPA BIT(14)
498#define BCMA_CHIPCTL_5357_ANT_MUX_2O3 BIT(15)
499#define BCMA_CHIPCTL_5357_NFLASH BIT(16)
500#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18)
501#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19)
502
418/* Data for the PMU, if available. 503/* Data for the PMU, if available.
419 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) 504 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
420 */ 505 */
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h
index 5a71d5719640..a393e82bf7bf 100644
--- a/include/linux/bcma/bcma_regs.h
+++ b/include/linux/bcma/bcma_regs.h
@@ -11,11 +11,13 @@
11#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ 11#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
12#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ 12#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
13#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */ 13#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
14#define BCMA_CLKCTLST_EXTRESREQ_SHIFT 8
14#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */ 15#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
15#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */ 16#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
16#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */ 17#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
17#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */ 18#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
18#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */ 19#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
20#define BCMA_CLKCTLST_EXTRESST_SHIFT 24
19/* Is there any BCM4328 on BCMA bus? */ 21/* Is there any BCM4328 on BCMA bus? */
20#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */ 22#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
21#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */ 23#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 1a6b0045b06b..c2b02a5c86ae 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -504,7 +504,9 @@
504#define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */ 504#define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */
505#define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */ 505#define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */
506#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */ 506#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */
507#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */ 507#define SSB_CHIPCO_FLASHCTL_ST_RES 0x03AB /* Read Electronic Signature */
508#define SSB_CHIPCO_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */
509#define SSB_CHIPCO_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */
508 510
509/* Status register bits for ST flashes */ 511/* Status register bits for ST flashes */
510#define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */ 512#define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 565d4bee1e49..ede036977ae8 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -27,6 +27,7 @@
27 27
28#include <linux/poll.h> 28#include <linux/poll.h>
29#include <net/sock.h> 29#include <net/sock.h>
30#include <linux/seq_file.h>
30 31
31#ifndef AF_BLUETOOTH 32#ifndef AF_BLUETOOTH
32#define AF_BLUETOOTH 31 33#define AF_BLUETOOTH 31
@@ -202,6 +203,10 @@ enum {
202struct bt_sock_list { 203struct bt_sock_list {
203 struct hlist_head head; 204 struct hlist_head head;
204 rwlock_t lock; 205 rwlock_t lock;
206#ifdef CONFIG_PROC_FS
207 struct file_operations fops;
208 int (* custom_seq_show)(struct seq_file *, void *);
209#endif
205}; 210};
206 211
207int bt_sock_register(int proto, const struct net_proto_family *ops); 212int bt_sock_register(int proto, const struct net_proto_family *ops);
@@ -292,6 +297,11 @@ extern void hci_sock_cleanup(void);
292extern int bt_sysfs_init(void); 297extern int bt_sysfs_init(void);
293extern void bt_sysfs_cleanup(void); 298extern void bt_sysfs_cleanup(void);
294 299
300extern int bt_procfs_init(struct module* module, struct net *net, const char *name,
301 struct bt_sock_list* sk_list,
302 int (* seq_show)(struct seq_file *, void *));
303extern void bt_procfs_cleanup(struct net *net, const char *name);
304
295extern struct dentry *bt_debugfs; 305extern struct dentry *bt_debugfs;
296 306
297int l2cap_init(void); 307int l2cap_init(void);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ccd723e0f783..23cf413e2acf 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -62,6 +62,15 @@
62/* First BR/EDR Controller shall have ID = 0 */ 62/* First BR/EDR Controller shall have ID = 0 */
63#define HCI_BREDR_ID 0 63#define HCI_BREDR_ID 0
64 64
65/* AMP controller status */
66#define AMP_CTRL_POWERED_DOWN 0x00
67#define AMP_CTRL_BLUETOOTH_ONLY 0x01
68#define AMP_CTRL_NO_CAPACITY 0x02
69#define AMP_CTRL_LOW_CAPACITY 0x03
70#define AMP_CTRL_MEDIUM_CAPACITY 0x04
71#define AMP_CTRL_HIGH_CAPACITY 0x05
72#define AMP_CTRL_FULL_CAPACITY 0x06
73
65/* HCI device quirks */ 74/* HCI device quirks */
66enum { 75enum {
67 HCI_QUIRK_RESET_ON_CLOSE, 76 HCI_QUIRK_RESET_ON_CLOSE,
@@ -1295,6 +1304,8 @@ struct hci_ev_num_comp_blocks {
1295} __packed; 1304} __packed;
1296 1305
1297/* Low energy meta events */ 1306/* Low energy meta events */
1307#define LE_CONN_ROLE_MASTER 0x00
1308
1298#define HCI_EV_LE_CONN_COMPLETE 0x01 1309#define HCI_EV_LE_CONN_COMPLETE 0x01
1299struct hci_ev_le_conn_complete { 1310struct hci_ev_le_conn_complete {
1300 __u8 status; 1311 __u8 status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 475b8c04ba52..41d943926d2c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -115,12 +115,6 @@ struct oob_data {
115 u8 randomizer[16]; 115 u8 randomizer[16];
116}; 116};
117 117
118struct adv_entry {
119 struct list_head list;
120 bdaddr_t bdaddr;
121 u8 bdaddr_type;
122};
123
124struct le_scan_params { 118struct le_scan_params {
125 u8 type; 119 u8 type;
126 u16 interval; 120 u16 interval;
@@ -356,16 +350,16 @@ extern rwlock_t hci_cb_list_lock;
356 350
357/* ----- HCI interface to upper protocols ----- */ 351/* ----- HCI interface to upper protocols ----- */
358extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 352extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
359extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); 353extern void l2cap_connect_cfm(struct hci_conn *hcon, u8 status);
360extern int l2cap_disconn_ind(struct hci_conn *hcon); 354extern int l2cap_disconn_ind(struct hci_conn *hcon);
361extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); 355extern void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason);
362extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); 356extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
363extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, 357extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
364 u16 flags); 358 u16 flags);
365 359
366extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 360extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
367extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); 361extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
368extern int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); 362extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
369extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); 363extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
370 364
371/* ----- Inquiry cache ----- */ 365/* ----- Inquiry cache ----- */
@@ -587,8 +581,7 @@ void hci_conn_put_device(struct hci_conn *conn);
587 581
588static inline void hci_conn_hold(struct hci_conn *conn) 582static inline void hci_conn_hold(struct hci_conn *conn)
589{ 583{
590 BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), 584 BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
591 atomic_read(&conn->refcnt) + 1);
592 585
593 atomic_inc(&conn->refcnt); 586 atomic_inc(&conn->refcnt);
594 cancel_delayed_work(&conn->disc_work); 587 cancel_delayed_work(&conn->disc_work);
@@ -596,8 +589,7 @@ static inline void hci_conn_hold(struct hci_conn *conn)
596 589
597static inline void hci_conn_put(struct hci_conn *conn) 590static inline void hci_conn_put(struct hci_conn *conn)
598{ 591{
599 BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), 592 BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
600 atomic_read(&conn->refcnt) - 1);
601 593
602 if (atomic_dec_and_test(&conn->refcnt)) { 594 if (atomic_dec_and_test(&conn->refcnt)) {
603 unsigned long timeo; 595 unsigned long timeo;
@@ -1056,7 +1048,7 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
1056int mgmt_interleaved_discovery(struct hci_dev *hdev); 1048int mgmt_interleaved_discovery(struct hci_dev *hdev);
1057int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1049int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1058int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1050int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1059 1051bool mgmt_valid_hdev(struct hci_dev *hdev);
1060int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); 1052int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
1061 1053
1062/* HCI info for socket */ 1054/* HCI info for socket */
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index a7679f8913d2..d206296137e2 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -671,20 +671,8 @@ enum {
671 L2CAP_EV_RECV_FRAME, 671 L2CAP_EV_RECV_FRAME,
672}; 672};
673 673
674static inline void l2cap_chan_hold(struct l2cap_chan *c) 674void l2cap_chan_hold(struct l2cap_chan *c);
675{ 675void l2cap_chan_put(struct l2cap_chan *c);
676 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
677
678 atomic_inc(&c->refcnt);
679}
680
681static inline void l2cap_chan_put(struct l2cap_chan *c)
682{
683 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
684
685 if (atomic_dec_and_test(&c->refcnt))
686 kfree(c);
687}
688 676
689static inline void l2cap_chan_lock(struct l2cap_chan *chan) 677static inline void l2cap_chan_lock(struct l2cap_chan *chan)
690{ 678{
@@ -771,7 +759,6 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
771 759
772struct l2cap_chan *l2cap_chan_create(void); 760struct l2cap_chan *l2cap_chan_create(void);
773void l2cap_chan_close(struct l2cap_chan *chan, int reason); 761void l2cap_chan_close(struct l2cap_chan *chan, int reason);
774void l2cap_chan_destroy(struct l2cap_chan *chan);
775int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, 762int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
776 bdaddr_t *dst, u8 dst_type); 763 bdaddr_t *dst, u8 dst_type);
777int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, 764int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index ca356a734920..50993a531d45 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -108,8 +108,8 @@ struct smp_cmd_security_req {
108#define SMP_CONFIRM_FAILED 0x04 108#define SMP_CONFIRM_FAILED 0x04
109#define SMP_PAIRING_NOTSUPP 0x05 109#define SMP_PAIRING_NOTSUPP 0x05
110#define SMP_ENC_KEY_SIZE 0x06 110#define SMP_ENC_KEY_SIZE 0x06
111#define SMP_CMD_NOTSUPP 0x07 111#define SMP_CMD_NOTSUPP 0x07
112#define SMP_UNSPECIFIED 0x08 112#define SMP_UNSPECIFIED 0x08
113#define SMP_REPEATED_ATTEMPTS 0x09 113#define SMP_REPEATED_ATTEMPTS 0x09
114 114
115#define SMP_MIN_ENC_KEY_SIZE 7 115#define SMP_MIN_ENC_KEY_SIZE 7
@@ -123,8 +123,8 @@ struct smp_chan {
123 struct l2cap_conn *conn; 123 struct l2cap_conn *conn;
124 u8 preq[7]; /* SMP Pairing Request */ 124 u8 preq[7]; /* SMP Pairing Request */
125 u8 prsp[7]; /* SMP Pairing Response */ 125 u8 prsp[7]; /* SMP Pairing Response */
126 u8 prnd[16]; /* SMP Pairing Random (local) */ 126 u8 prnd[16]; /* SMP Pairing Random (local) */
127 u8 rrnd[16]; /* SMP Pairing Random (remote) */ 127 u8 rrnd[16]; /* SMP Pairing Random (remote) */
128 u8 pcnf[16]; /* SMP Pairing Confirm */ 128 u8 pcnf[16]; /* SMP Pairing Confirm */
129 u8 tk[16]; /* SMP Temporary Key */ 129 u8 tk[16]; /* SMP Temporary Key */
130 u8 enc_key_size; 130 u8 enc_key_size;
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 4ff0bf3ba9a5..0760d1fed6f0 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -316,7 +316,7 @@ send_rsp:
316static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb, 316static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
317 struct a2mp_cmd *hdr) 317 struct a2mp_cmd *hdr)
318{ 318{
319 BT_DBG("ident %d code %d", hdr->ident, hdr->code); 319 BT_DBG("ident %d code 0x%2.2x", hdr->ident, hdr->code);
320 320
321 skb_pull(skb, le16_to_cpu(hdr->len)); 321 skb_pull(skb, le16_to_cpu(hdr->len));
322 return 0; 322 return 0;
@@ -325,17 +325,19 @@ static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
325/* Handle A2MP signalling */ 325/* Handle A2MP signalling */
326static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 326static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
327{ 327{
328 struct a2mp_cmd *hdr = (void *) skb->data; 328 struct a2mp_cmd *hdr;
329 struct amp_mgr *mgr = chan->data; 329 struct amp_mgr *mgr = chan->data;
330 int err = 0; 330 int err = 0;
331 331
332 amp_mgr_get(mgr); 332 amp_mgr_get(mgr);
333 333
334 while (skb->len >= sizeof(*hdr)) { 334 while (skb->len >= sizeof(*hdr)) {
335 struct a2mp_cmd *hdr = (void *) skb->data; 335 u16 len;
336 u16 len = le16_to_cpu(hdr->len);
337 336
338 BT_DBG("code 0x%02x id %d len %d", hdr->code, hdr->ident, len); 337 hdr = (void *) skb->data;
338 len = le16_to_cpu(hdr->len);
339
340 BT_DBG("code 0x%2.2x id %d len %u", hdr->code, hdr->ident, len);
339 341
340 skb_pull(skb, sizeof(*hdr)); 342 skb_pull(skb, sizeof(*hdr));
341 343
@@ -393,7 +395,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
393 395
394 if (err) { 396 if (err) {
395 struct a2mp_cmd_rej rej; 397 struct a2mp_cmd_rej rej;
398
396 rej.reason = __constant_cpu_to_le16(0); 399 rej.reason = __constant_cpu_to_le16(0);
400 hdr = (void *) skb->data;
397 401
398 BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); 402 BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err);
399 403
@@ -412,7 +416,7 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
412 416
413static void a2mp_chan_close_cb(struct l2cap_chan *chan) 417static void a2mp_chan_close_cb(struct l2cap_chan *chan)
414{ 418{
415 l2cap_chan_destroy(chan); 419 l2cap_chan_put(chan);
416} 420}
417 421
418static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state) 422static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index f7db5792ec64..58f9762b339a 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -28,6 +28,7 @@
28#include <asm/ioctls.h> 28#include <asm/ioctls.h>
29 29
30#include <net/bluetooth/bluetooth.h> 30#include <net/bluetooth/bluetooth.h>
31#include <linux/proc_fs.h>
31 32
32#define VERSION "2.16" 33#define VERSION "2.16"
33 34
@@ -532,6 +533,146 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
532} 533}
533EXPORT_SYMBOL(bt_sock_wait_state); 534EXPORT_SYMBOL(bt_sock_wait_state);
534 535
536#ifdef CONFIG_PROC_FS
537struct bt_seq_state {
538 struct bt_sock_list *l;
539};
540
541static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
542 __acquires(seq->private->l->lock)
543{
544 struct bt_seq_state *s = seq->private;
545 struct bt_sock_list *l = s->l;
546
547 read_lock(&l->lock);
548 return seq_hlist_start_head(&l->head, *pos);
549}
550
551static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
552{
553 struct bt_seq_state *s = seq->private;
554 struct bt_sock_list *l = s->l;
555
556 return seq_hlist_next(v, &l->head, pos);
557}
558
559static void bt_seq_stop(struct seq_file *seq, void *v)
560 __releases(seq->private->l->lock)
561{
562 struct bt_seq_state *s = seq->private;
563 struct bt_sock_list *l = s->l;
564
565 read_unlock(&l->lock);
566}
567
568static int bt_seq_show(struct seq_file *seq, void *v)
569{
570 struct sock *sk;
571 struct bt_sock *bt;
572 struct bt_seq_state *s = seq->private;
573 struct bt_sock_list *l = s->l;
574 bdaddr_t src_baswapped, dst_baswapped;
575
576 if (v == SEQ_START_TOKEN) {
577 seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent");
578
579 if (l->custom_seq_show) {
580 seq_putc(seq, ' ');
581 l->custom_seq_show(seq, v);
582 }
583
584 seq_putc(seq, '\n');
585 } else {
586 sk = sk_entry(v);
587 bt = bt_sk(sk);
588 baswap(&src_baswapped, &bt->src);
589 baswap(&dst_baswapped, &bt->dst);
590
591 seq_printf(seq, "%pK %-6d %-6u %-6u %-6u %-6lu %pM %pM %-6lu",
592 sk,
593 atomic_read(&sk->sk_refcnt),
594 sk_rmem_alloc_get(sk),
595 sk_wmem_alloc_get(sk),
596 sock_i_uid(sk),
597 sock_i_ino(sk),
598 &src_baswapped,
599 &dst_baswapped,
600 bt->parent? sock_i_ino(bt->parent): 0LU);
601
602 if (l->custom_seq_show) {
603 seq_putc(seq, ' ');
604 l->custom_seq_show(seq, v);
605 }
606
607 seq_putc(seq, '\n');
608 }
609 return 0;
610}
611
612static struct seq_operations bt_seq_ops = {
613 .start = bt_seq_start,
614 .next = bt_seq_next,
615 .stop = bt_seq_stop,
616 .show = bt_seq_show,
617};
618
619static int bt_seq_open(struct inode *inode, struct file *file)
620{
621 struct bt_sock_list *sk_list;
622 struct bt_seq_state *s;
623
624 sk_list = PDE(inode)->data;
625 s = __seq_open_private(file, &bt_seq_ops,
626 sizeof(struct bt_seq_state));
627 if (s == NULL)
628 return -ENOMEM;
629
630 s->l = sk_list;
631 return 0;
632}
633
634int bt_procfs_init(struct module* module, struct net *net, const char *name,
635 struct bt_sock_list* sk_list,
636 int (* seq_show)(struct seq_file *, void *))
637{
638 struct proc_dir_entry * pde;
639
640 sk_list->custom_seq_show = seq_show;
641
642 sk_list->fops.owner = module;
643 sk_list->fops.open = bt_seq_open;
644 sk_list->fops.read = seq_read;
645 sk_list->fops.llseek = seq_lseek;
646 sk_list->fops.release = seq_release_private;
647
648 pde = proc_net_fops_create(net, name, 0, &sk_list->fops);
649 if (pde == NULL)
650 return -ENOMEM;
651
652 pde->data = sk_list;
653
654 return 0;
655}
656
657void bt_procfs_cleanup(struct net *net, const char *name)
658{
659 proc_net_remove(net, name);
660}
661#else
662int bt_procfs_init(struct module* module, struct net *net, const char *name,
663 struct bt_sock_list* sk_list,
664 int (* seq_show)(struct seq_file *, void *))
665{
666 return 0;
667}
668
669void bt_procfs_cleanup(struct net *net, const char *name)
670{
671}
672#endif
673EXPORT_SYMBOL(bt_procfs_init);
674EXPORT_SYMBOL(bt_procfs_cleanup);
675
535static struct net_proto_family bt_sock_family_ops = { 676static struct net_proto_family bt_sock_family_ops = {
536 .owner = THIS_MODULE, 677 .owner = THIS_MODULE,
537 .family = PF_BLUETOOTH, 678 .family = PF_BLUETOOTH,
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 5e5f5b410e0b..5b6cc0bf4dec 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -29,6 +29,10 @@
29 29
30#include "bnep.h" 30#include "bnep.h"
31 31
32static struct bt_sock_list bnep_sk_list = {
33 .lock = __RW_LOCK_UNLOCKED(bnep_sk_list.lock)
34};
35
32static int bnep_sock_release(struct socket *sock) 36static int bnep_sock_release(struct socket *sock)
33{ 37{
34 struct sock *sk = sock->sk; 38 struct sock *sk = sock->sk;
@@ -38,6 +42,8 @@ static int bnep_sock_release(struct socket *sock)
38 if (!sk) 42 if (!sk)
39 return 0; 43 return 0;
40 44
45 bt_sock_unlink(&bnep_sk_list, sk);
46
41 sock_orphan(sk); 47 sock_orphan(sk);
42 sock_put(sk); 48 sock_put(sk);
43 return 0; 49 return 0;
@@ -204,6 +210,7 @@ static int bnep_sock_create(struct net *net, struct socket *sock, int protocol,
204 sk->sk_protocol = protocol; 210 sk->sk_protocol = protocol;
205 sk->sk_state = BT_OPEN; 211 sk->sk_state = BT_OPEN;
206 212
213 bt_sock_link(&bnep_sk_list, sk);
207 return 0; 214 return 0;
208} 215}
209 216
@@ -222,19 +229,30 @@ int __init bnep_sock_init(void)
222 return err; 229 return err;
223 230
224 err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops); 231 err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
225 if (err < 0) 232 if (err < 0) {
233 BT_ERR("Can't register BNEP socket");
226 goto error; 234 goto error;
235 }
236
237 err = bt_procfs_init(THIS_MODULE, &init_net, "bnep", &bnep_sk_list, NULL);
238 if (err < 0) {
239 BT_ERR("Failed to create BNEP proc file");
240 bt_sock_unregister(BTPROTO_BNEP);
241 goto error;
242 }
243
244 BT_INFO("BNEP socket layer initialized");
227 245
228 return 0; 246 return 0;
229 247
230error: 248error:
231 BT_ERR("Can't register BNEP socket");
232 proto_unregister(&bnep_proto); 249 proto_unregister(&bnep_proto);
233 return err; 250 return err;
234} 251}
235 252
236void __exit bnep_sock_cleanup(void) 253void __exit bnep_sock_cleanup(void)
237{ 254{
255 bt_procfs_cleanup(&init_net, "bnep");
238 if (bt_sock_unregister(BTPROTO_BNEP) < 0) 256 if (bt_sock_unregister(BTPROTO_BNEP) < 0)
239 BT_ERR("Can't unregister BNEP socket"); 257 BT_ERR("Can't unregister BNEP socket");
240 258
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 311668d14571..d5cacef52748 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -42,6 +42,10 @@
42 42
43#include "cmtp.h" 43#include "cmtp.h"
44 44
45static struct bt_sock_list cmtp_sk_list = {
46 .lock = __RW_LOCK_UNLOCKED(cmtp_sk_list.lock)
47};
48
45static int cmtp_sock_release(struct socket *sock) 49static int cmtp_sock_release(struct socket *sock)
46{ 50{
47 struct sock *sk = sock->sk; 51 struct sock *sk = sock->sk;
@@ -51,6 +55,8 @@ static int cmtp_sock_release(struct socket *sock)
51 if (!sk) 55 if (!sk)
52 return 0; 56 return 0;
53 57
58 bt_sock_unlink(&cmtp_sk_list, sk);
59
54 sock_orphan(sk); 60 sock_orphan(sk);
55 sock_put(sk); 61 sock_put(sk);
56 62
@@ -214,6 +220,8 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
214 sk->sk_protocol = protocol; 220 sk->sk_protocol = protocol;
215 sk->sk_state = BT_OPEN; 221 sk->sk_state = BT_OPEN;
216 222
223 bt_sock_link(&cmtp_sk_list, sk);
224
217 return 0; 225 return 0;
218} 226}
219 227
@@ -232,19 +240,30 @@ int cmtp_init_sockets(void)
232 return err; 240 return err;
233 241
234 err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops); 242 err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
235 if (err < 0) 243 if (err < 0) {
244 BT_ERR("Can't register CMTP socket");
236 goto error; 245 goto error;
246 }
247
248 err = bt_procfs_init(THIS_MODULE, &init_net, "cmtp", &cmtp_sk_list, NULL);
249 if (err < 0) {
250 BT_ERR("Failed to create CMTP proc file");
251 bt_sock_unregister(BTPROTO_HIDP);
252 goto error;
253 }
254
255 BT_INFO("CMTP socket layer initialized");
237 256
238 return 0; 257 return 0;
239 258
240error: 259error:
241 BT_ERR("Can't register CMTP socket");
242 proto_unregister(&cmtp_proto); 260 proto_unregister(&cmtp_proto);
243 return err; 261 return err;
244} 262}
245 263
246void cmtp_cleanup_sockets(void) 264void cmtp_cleanup_sockets(void)
247{ 265{
266 bt_procfs_cleanup(&init_net, "cmtp");
248 if (bt_sock_unregister(BTPROTO_CMTP) < 0) 267 if (bt_sock_unregister(BTPROTO_CMTP) < 0)
249 BT_ERR("Can't unregister CMTP socket"); 268 BT_ERR("Can't unregister CMTP socket");
250 269
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d4de5db18d5a..fa974a19d365 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -696,7 +696,8 @@ int hci_dev_open(__u16 dev)
696 hci_dev_hold(hdev); 696 hci_dev_hold(hdev);
697 set_bit(HCI_UP, &hdev->flags); 697 set_bit(HCI_UP, &hdev->flags);
698 hci_notify(hdev, HCI_DEV_UP); 698 hci_notify(hdev, HCI_DEV_UP);
699 if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 699 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
700 mgmt_valid_hdev(hdev)) {
700 hci_dev_lock(hdev); 701 hci_dev_lock(hdev);
701 mgmt_powered(hdev, 1); 702 mgmt_powered(hdev, 1);
702 hci_dev_unlock(hdev); 703 hci_dev_unlock(hdev);
@@ -797,7 +798,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
797 * and no tasks are scheduled. */ 798 * and no tasks are scheduled. */
798 hdev->close(hdev); 799 hdev->close(hdev);
799 800
800 if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 801 if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
802 mgmt_valid_hdev(hdev)) {
801 hci_dev_lock(hdev); 803 hci_dev_lock(hdev);
802 mgmt_powered(hdev, 0); 804 mgmt_powered(hdev, 0);
803 hci_dev_unlock(hdev); 805 hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 41ff978a33f9..32e21ad36a68 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -513,7 +513,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
513 if (hdev->features[3] & LMP_RSSI_INQ) 513 if (hdev->features[3] & LMP_RSSI_INQ)
514 events[4] |= 0x02; /* Inquiry Result with RSSI */ 514 events[4] |= 0x02; /* Inquiry Result with RSSI */
515 515
516 if (hdev->features[5] & LMP_SNIFF_SUBR) 516 if (lmp_sniffsubr_capable(hdev))
517 events[5] |= 0x20; /* Sniff Subrating */ 517 events[5] |= 0x20; /* Sniff Subrating */
518 518
519 if (hdev->features[5] & LMP_PAUSE_ENC) 519 if (hdev->features[5] & LMP_PAUSE_ENC)
@@ -522,13 +522,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
522 if (hdev->features[6] & LMP_EXT_INQ) 522 if (hdev->features[6] & LMP_EXT_INQ)
523 events[5] |= 0x40; /* Extended Inquiry Result */ 523 events[5] |= 0x40; /* Extended Inquiry Result */
524 524
525 if (hdev->features[6] & LMP_NO_FLUSH) 525 if (lmp_no_flush_capable(hdev))
526 events[7] |= 0x01; /* Enhanced Flush Complete */ 526 events[7] |= 0x01; /* Enhanced Flush Complete */
527 527
528 if (hdev->features[7] & LMP_LSTO) 528 if (hdev->features[7] & LMP_LSTO)
529 events[6] |= 0x80; /* Link Supervision Timeout Changed */ 529 events[6] |= 0x80; /* Link Supervision Timeout Changed */
530 530
531 if (hdev->features[6] & LMP_SIMPLE_PAIR) { 531 if (lmp_ssp_capable(hdev)) {
532 events[6] |= 0x01; /* IO Capability Request */ 532 events[6] |= 0x01; /* IO Capability Request */
533 events[6] |= 0x02; /* IO Capability Response */ 533 events[6] |= 0x02; /* IO Capability Response */
534 events[6] |= 0x04; /* User Confirmation Request */ 534 events[6] |= 0x04; /* User Confirmation Request */
@@ -541,7 +541,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
541 * Features Notification */ 541 * Features Notification */
542 } 542 }
543 543
544 if (hdev->features[4] & LMP_LE) 544 if (lmp_le_capable(hdev))
545 events[7] |= 0x20; /* LE Meta-Event */ 545 events[7] |= 0x20; /* LE Meta-Event */
546 546
547 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 547 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
@@ -623,11 +623,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev)
623 struct hci_cp_write_def_link_policy cp; 623 struct hci_cp_write_def_link_policy cp;
624 u16 link_policy = 0; 624 u16 link_policy = 0;
625 625
626 if (hdev->features[0] & LMP_RSWITCH) 626 if (lmp_rswitch_capable(hdev))
627 link_policy |= HCI_LP_RSWITCH; 627 link_policy |= HCI_LP_RSWITCH;
628 if (hdev->features[0] & LMP_HOLD) 628 if (hdev->features[0] & LMP_HOLD)
629 link_policy |= HCI_LP_HOLD; 629 link_policy |= HCI_LP_HOLD;
630 if (hdev->features[0] & LMP_SNIFF) 630 if (lmp_sniff_capable(hdev))
631 link_policy |= HCI_LP_SNIFF; 631 link_policy |= HCI_LP_SNIFF;
632 if (hdev->features[1] & LMP_PARK) 632 if (hdev->features[1] & LMP_PARK)
633 link_policy |= HCI_LP_PARK; 633 link_policy |= HCI_LP_PARK;
@@ -686,7 +686,7 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
686 hdev->esco_type |= (ESCO_HV3); 686 hdev->esco_type |= (ESCO_HV3);
687 } 687 }
688 688
689 if (hdev->features[3] & LMP_ESCO) 689 if (lmp_esco_capable(hdev))
690 hdev->esco_type |= (ESCO_EV3); 690 hdev->esco_type |= (ESCO_EV3);
691 691
692 if (hdev->features[4] & LMP_EV4) 692 if (hdev->features[4] & LMP_EV4)
@@ -746,7 +746,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
746 break; 746 break;
747 } 747 }
748 748
749 if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE) 749 if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev))
750 hci_set_le_support(hdev); 750 hci_set_le_support(hdev);
751 751
752done: 752done:
@@ -1614,43 +1614,30 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1614 1614
1615static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) 1615static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1616{ 1616{
1617 struct hci_cp_le_create_conn *cp;
1618 struct hci_conn *conn; 1617 struct hci_conn *conn;
1619 1618
1620 BT_DBG("%s status 0x%2.2x", hdev->name, status); 1619 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1621 1620
1622 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1621 if (status) {
1623 if (!cp) 1622 hci_dev_lock(hdev);
1624 return;
1625 1623
1626 hci_dev_lock(hdev); 1624 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
1625 if (!conn) {
1626 hci_dev_unlock(hdev);
1627 return;
1628 }
1627 1629
1628 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1630 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst),
1631 conn);
1629 1632
1630 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), 1633 conn->state = BT_CLOSED;
1631 conn); 1634 mgmt_connect_failed(hdev, &conn->dst, conn->type,
1635 conn->dst_type, status);
1636 hci_proto_connect_cfm(conn, status);
1637 hci_conn_del(conn);
1632 1638
1633 if (status) { 1639 hci_dev_unlock(hdev);
1634 if (conn && conn->state == BT_CONNECT) {
1635 conn->state = BT_CLOSED;
1636 mgmt_connect_failed(hdev, &cp->peer_addr, conn->type,
1637 conn->dst_type, status);
1638 hci_proto_connect_cfm(conn, status);
1639 hci_conn_del(conn);
1640 }
1641 } else {
1642 if (!conn) {
1643 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1644 if (conn) {
1645 conn->dst_type = cp->peer_addr_type;
1646 conn->out = true;
1647 } else {
1648 BT_ERR("No memory for new connection");
1649 }
1650 }
1651 } 1640 }
1652
1653 hci_dev_unlock(hdev);
1654} 1641}
1655 1642
1656static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 1643static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
@@ -3252,12 +3239,8 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3252 3239
3253 BT_DBG("%s", hdev->name); 3240 BT_DBG("%s", hdev->name);
3254 3241
3255 hci_dev_lock(hdev);
3256
3257 if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3242 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3258 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 3243 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
3259
3260 hci_dev_unlock(hdev);
3261} 3244}
3262 3245
3263static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 3246static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
@@ -3350,11 +3333,23 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3350 3333
3351 hci_dev_lock(hdev); 3334 hci_dev_lock(hdev);
3352 3335
3353 if (ev->status) { 3336 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
3354 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 3337 if (!conn) {
3355 if (!conn) 3338 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3339 if (!conn) {
3340 BT_ERR("No memory for new connection");
3356 goto unlock; 3341 goto unlock;
3342 }
3357 3343
3344 conn->dst_type = ev->bdaddr_type;
3345
3346 if (ev->role == LE_CONN_ROLE_MASTER) {
3347 conn->out = true;
3348 conn->link_mode |= HCI_LM_MASTER;
3349 }
3350 }
3351
3352 if (ev->status) {
3358 mgmt_connect_failed(hdev, &conn->dst, conn->type, 3353 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3359 conn->dst_type, ev->status); 3354 conn->dst_type, ev->status);
3360 hci_proto_connect_cfm(conn, ev->status); 3355 hci_proto_connect_cfm(conn, ev->status);
@@ -3363,18 +3358,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3363 goto unlock; 3358 goto unlock;
3364 } 3359 }
3365 3360
3366 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
3367 if (!conn) {
3368 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3369 if (!conn) {
3370 BT_ERR("No memory for new connection");
3371 hci_dev_unlock(hdev);
3372 return;
3373 }
3374
3375 conn->dst_type = ev->bdaddr_type;
3376 }
3377
3378 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3361 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3379 mgmt_device_connected(hdev, &ev->bdaddr, conn->type, 3362 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3380 conn->dst_type, 0, NULL, 0, NULL); 3363 conn->dst_type, 0, NULL, 0, NULL);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index a7f04de03d79..7c3d6c7c6ddb 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1100,21 +1100,30 @@ int __init hci_sock_init(void)
1100 return err; 1100 return err;
1101 1101
1102 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops); 1102 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
1103 if (err < 0) 1103 if (err < 0) {
1104 BT_ERR("HCI socket registration failed");
1104 goto error; 1105 goto error;
1106 }
1107
1108 err = bt_procfs_init(THIS_MODULE, &init_net, "hci", &hci_sk_list, NULL);
1109 if (err < 0) {
1110 BT_ERR("Failed to create HCI proc file");
1111 bt_sock_unregister(BTPROTO_HCI);
1112 goto error;
1113 }
1105 1114
1106 BT_INFO("HCI socket layer initialized"); 1115 BT_INFO("HCI socket layer initialized");
1107 1116
1108 return 0; 1117 return 0;
1109 1118
1110error: 1119error:
1111 BT_ERR("HCI socket registration failed");
1112 proto_unregister(&hci_sk_proto); 1120 proto_unregister(&hci_sk_proto);
1113 return err; 1121 return err;
1114} 1122}
1115 1123
1116void hci_sock_cleanup(void) 1124void hci_sock_cleanup(void)
1117{ 1125{
1126 bt_procfs_cleanup(&init_net, "hci");
1118 if (bt_sock_unregister(BTPROTO_HCI) < 0) 1127 if (bt_sock_unregister(BTPROTO_HCI) < 0)
1119 BT_ERR("HCI socket unregistration failed"); 1128 BT_ERR("HCI socket unregistration failed");
1120 1129
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 18b3f6892a36..eca3889371c4 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -25,6 +25,10 @@
25 25
26#include "hidp.h" 26#include "hidp.h"
27 27
28static struct bt_sock_list hidp_sk_list = {
29 .lock = __RW_LOCK_UNLOCKED(hidp_sk_list.lock)
30};
31
28static int hidp_sock_release(struct socket *sock) 32static int hidp_sock_release(struct socket *sock)
29{ 33{
30 struct sock *sk = sock->sk; 34 struct sock *sk = sock->sk;
@@ -34,6 +38,8 @@ static int hidp_sock_release(struct socket *sock)
34 if (!sk) 38 if (!sk)
35 return 0; 39 return 0;
36 40
41 bt_sock_unlink(&hidp_sk_list, sk);
42
37 sock_orphan(sk); 43 sock_orphan(sk);
38 sock_put(sk); 44 sock_put(sk);
39 45
@@ -253,6 +259,8 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
253 sk->sk_protocol = protocol; 259 sk->sk_protocol = protocol;
254 sk->sk_state = BT_OPEN; 260 sk->sk_state = BT_OPEN;
255 261
262 bt_sock_link(&hidp_sk_list, sk);
263
256 return 0; 264 return 0;
257} 265}
258 266
@@ -271,8 +279,19 @@ int __init hidp_init_sockets(void)
271 return err; 279 return err;
272 280
273 err = bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops); 281 err = bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops);
274 if (err < 0) 282 if (err < 0) {
283 BT_ERR("Can't register HIDP socket");
275 goto error; 284 goto error;
285 }
286
287 err = bt_procfs_init(THIS_MODULE, &init_net, "hidp", &hidp_sk_list, NULL);
288 if (err < 0) {
289 BT_ERR("Failed to create HIDP proc file");
290 bt_sock_unregister(BTPROTO_HIDP);
291 goto error;
292 }
293
294 BT_INFO("HIDP socket layer initialized");
276 295
277 return 0; 296 return 0;
278 297
@@ -284,6 +303,7 @@ error:
284 303
285void __exit hidp_cleanup_sockets(void) 304void __exit hidp_cleanup_sockets(void)
286{ 305{
306 bt_procfs_cleanup(&init_net, "hidp");
287 if (bt_sock_unregister(BTPROTO_HIDP) < 0) 307 if (bt_sock_unregister(BTPROTO_HIDP) < 0)
288 BT_ERR("Can't unregister HIDP socket"); 308 BT_ERR("Can't unregister HIDP socket");
289 309
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a8964db04bfb..9f8b29ef5b68 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -416,13 +416,30 @@ struct l2cap_chan *l2cap_chan_create(void)
416 return chan; 416 return chan;
417} 417}
418 418
419void l2cap_chan_destroy(struct l2cap_chan *chan) 419static void l2cap_chan_destroy(struct l2cap_chan *chan)
420{ 420{
421 BT_DBG("chan %p", chan);
422
421 write_lock(&chan_list_lock); 423 write_lock(&chan_list_lock);
422 list_del(&chan->global_l); 424 list_del(&chan->global_l);
423 write_unlock(&chan_list_lock); 425 write_unlock(&chan_list_lock);
424 426
425 l2cap_chan_put(chan); 427 kfree(chan);
428}
429
430void l2cap_chan_hold(struct l2cap_chan *c)
431{
432 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
433
434 atomic_inc(&c->refcnt);
435}
436
437void l2cap_chan_put(struct l2cap_chan *c)
438{
439 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
440
441 if (atomic_dec_and_test(&c->refcnt))
442 l2cap_chan_destroy(c);
426} 443}
427 444
428void l2cap_chan_set_defaults(struct l2cap_chan *chan) 445void l2cap_chan_set_defaults(struct l2cap_chan *chan)
@@ -5329,7 +5346,7 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
5329 return exact ? lm1 : lm2; 5346 return exact ? lm1 : lm2;
5330} 5347}
5331 5348
5332int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) 5349void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
5333{ 5350{
5334 struct l2cap_conn *conn; 5351 struct l2cap_conn *conn;
5335 5352
@@ -5342,7 +5359,6 @@ int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
5342 } else 5359 } else
5343 l2cap_conn_del(hcon, bt_to_errno(status)); 5360 l2cap_conn_del(hcon, bt_to_errno(status));
5344 5361
5345 return 0;
5346} 5362}
5347 5363
5348int l2cap_disconn_ind(struct hci_conn *hcon) 5364int l2cap_disconn_ind(struct hci_conn *hcon)
@@ -5356,12 +5372,11 @@ int l2cap_disconn_ind(struct hci_conn *hcon)
5356 return conn->disc_reason; 5372 return conn->disc_reason;
5357} 5373}
5358 5374
5359int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) 5375void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
5360{ 5376{
5361 BT_DBG("hcon %p reason %d", hcon, reason); 5377 BT_DBG("hcon %p reason %d", hcon, reason);
5362 5378
5363 l2cap_conn_del(hcon, bt_to_errno(reason)); 5379 l2cap_conn_del(hcon, bt_to_errno(reason));
5364 return 0;
5365} 5380}
5366 5381
5367static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) 5382static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
@@ -5404,6 +5419,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
5404 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, 5419 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5405 state_to_string(chan->state)); 5420 state_to_string(chan->state));
5406 5421
5422 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5423 l2cap_chan_unlock(chan);
5424 continue;
5425 }
5426
5407 if (chan->scid == L2CAP_CID_LE_DATA) { 5427 if (chan->scid == L2CAP_CID_LE_DATA) {
5408 if (!status && encrypt) { 5428 if (!status && encrypt) {
5409 chan->sec_level = hcon->sec_level; 5429 chan->sec_level = hcon->sec_level;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a4bb27e8427e..13f6a9816feb 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -34,6 +34,10 @@
34#include <net/bluetooth/l2cap.h> 34#include <net/bluetooth/l2cap.h>
35#include <net/bluetooth/smp.h> 35#include <net/bluetooth/smp.h>
36 36
37static struct bt_sock_list l2cap_sk_list = {
38 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
39};
40
37static const struct proto_ops l2cap_sock_ops; 41static const struct proto_ops l2cap_sock_ops;
38static void l2cap_sock_init(struct sock *sk, struct sock *parent); 42static void l2cap_sock_init(struct sock *sk, struct sock *parent);
39static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); 43static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
@@ -823,7 +827,7 @@ static void l2cap_sock_kill(struct sock *sk)
823 827
824 /* Kill poor orphan */ 828 /* Kill poor orphan */
825 829
826 l2cap_chan_destroy(l2cap_pi(sk)->chan); 830 l2cap_chan_put(l2cap_pi(sk)->chan);
827 sock_set_flag(sk, SOCK_DEAD); 831 sock_set_flag(sk, SOCK_DEAD);
828 sock_put(sk); 832 sock_put(sk);
829} 833}
@@ -886,6 +890,8 @@ static int l2cap_sock_release(struct socket *sock)
886 if (!sk) 890 if (!sk)
887 return 0; 891 return 0;
888 892
893 bt_sock_unlink(&l2cap_sk_list, sk);
894
889 err = l2cap_sock_shutdown(sock, 2); 895 err = l2cap_sock_shutdown(sock, 2);
890 896
891 sock_orphan(sk); 897 sock_orphan(sk);
@@ -1210,6 +1216,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
1210 return -ENOMEM; 1216 return -ENOMEM;
1211 1217
1212 l2cap_sock_init(sk, NULL); 1218 l2cap_sock_init(sk, NULL);
1219 bt_sock_link(&l2cap_sk_list, sk);
1213 return 0; 1220 return 0;
1214} 1221}
1215 1222
@@ -1248,21 +1255,30 @@ int __init l2cap_init_sockets(void)
1248 return err; 1255 return err;
1249 1256
1250 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); 1257 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
1251 if (err < 0) 1258 if (err < 0) {
1259 BT_ERR("L2CAP socket registration failed");
1252 goto error; 1260 goto error;
1261 }
1262
1263 err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, NULL);
1264 if (err < 0) {
1265 BT_ERR("Failed to create L2CAP proc file");
1266 bt_sock_unregister(BTPROTO_L2CAP);
1267 goto error;
1268 }
1253 1269
1254 BT_INFO("L2CAP socket layer initialized"); 1270 BT_INFO("L2CAP socket layer initialized");
1255 1271
1256 return 0; 1272 return 0;
1257 1273
1258error: 1274error:
1259 BT_ERR("L2CAP socket registration failed");
1260 proto_unregister(&l2cap_proto); 1275 proto_unregister(&l2cap_proto);
1261 return err; 1276 return err;
1262} 1277}
1263 1278
1264void l2cap_cleanup_sockets(void) 1279void l2cap_cleanup_sockets(void)
1265{ 1280{
1281 bt_procfs_cleanup(&init_net, "l2cap");
1266 if (bt_sock_unregister(BTPROTO_L2CAP) < 0) 1282 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
1267 BT_ERR("L2CAP socket unregistration failed"); 1283 BT_ERR("L2CAP socket unregistration failed");
1268 1284
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ad6613d17ca6..a3329cbd3e4d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -193,6 +193,11 @@ static u8 mgmt_status_table[] = {
193 MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */ 193 MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */
194}; 194};
195 195
196bool mgmt_valid_hdev(struct hci_dev *hdev)
197{
198 return hdev->dev_type == HCI_BREDR;
199}
200
196static u8 mgmt_status(u8 hci_status) 201static u8 mgmt_status(u8 hci_status)
197{ 202{
198 if (hci_status < ARRAY_SIZE(mgmt_status_table)) 203 if (hci_status < ARRAY_SIZE(mgmt_status_table))
@@ -317,7 +322,6 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
317 u16 data_len) 322 u16 data_len)
318{ 323{
319 struct mgmt_rp_read_index_list *rp; 324 struct mgmt_rp_read_index_list *rp;
320 struct list_head *p;
321 struct hci_dev *d; 325 struct hci_dev *d;
322 size_t rp_len; 326 size_t rp_len;
323 u16 count; 327 u16 count;
@@ -328,7 +332,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
328 read_lock(&hci_dev_list_lock); 332 read_lock(&hci_dev_list_lock);
329 333
330 count = 0; 334 count = 0;
331 list_for_each(p, &hci_dev_list) { 335 list_for_each_entry(d, &hci_dev_list, list) {
336 if (!mgmt_valid_hdev(d))
337 continue;
338
332 count++; 339 count++;
333 } 340 }
334 341
@@ -346,6 +353,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
346 if (test_bit(HCI_SETUP, &d->dev_flags)) 353 if (test_bit(HCI_SETUP, &d->dev_flags))
347 continue; 354 continue;
348 355
356 if (!mgmt_valid_hdev(d))
357 continue;
358
349 rp->index[i++] = cpu_to_le16(d->id); 359 rp->index[i++] = cpu_to_le16(d->id);
350 BT_DBG("Added hci%u", d->id); 360 BT_DBG("Added hci%u", d->id);
351 } 361 }
@@ -370,10 +380,10 @@ static u32 get_supported_settings(struct hci_dev *hdev)
370 settings |= MGMT_SETTING_DISCOVERABLE; 380 settings |= MGMT_SETTING_DISCOVERABLE;
371 settings |= MGMT_SETTING_PAIRABLE; 381 settings |= MGMT_SETTING_PAIRABLE;
372 382
373 if (hdev->features[6] & LMP_SIMPLE_PAIR) 383 if (lmp_ssp_capable(hdev))
374 settings |= MGMT_SETTING_SSP; 384 settings |= MGMT_SETTING_SSP;
375 385
376 if (!(hdev->features[4] & LMP_NO_BREDR)) { 386 if (lmp_bredr_capable(hdev)) {
377 settings |= MGMT_SETTING_BREDR; 387 settings |= MGMT_SETTING_BREDR;
378 settings |= MGMT_SETTING_LINK_SECURITY; 388 settings |= MGMT_SETTING_LINK_SECURITY;
379 } 389 }
@@ -381,7 +391,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
381 if (enable_hs) 391 if (enable_hs)
382 settings |= MGMT_SETTING_HS; 392 settings |= MGMT_SETTING_HS;
383 393
384 if (hdev->features[4] & LMP_LE) 394 if (lmp_le_capable(hdev))
385 settings |= MGMT_SETTING_LE; 395 settings |= MGMT_SETTING_LE;
386 396
387 return settings; 397 return settings;
@@ -403,7 +413,7 @@ static u32 get_current_settings(struct hci_dev *hdev)
403 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags)) 413 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags))
404 settings |= MGMT_SETTING_PAIRABLE; 414 settings |= MGMT_SETTING_PAIRABLE;
405 415
406 if (!(hdev->features[4] & LMP_NO_BREDR)) 416 if (lmp_bredr_capable(hdev))
407 settings |= MGMT_SETTING_BREDR; 417 settings |= MGMT_SETTING_BREDR;
408 418
409 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) 419 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
@@ -1111,7 +1121,7 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1111 1121
1112 hci_dev_lock(hdev); 1122 hci_dev_lock(hdev);
1113 1123
1114 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { 1124 if (!lmp_ssp_capable(hdev)) {
1115 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, 1125 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
1116 MGMT_STATUS_NOT_SUPPORTED); 1126 MGMT_STATUS_NOT_SUPPORTED);
1117 goto failed; 1127 goto failed;
@@ -1195,7 +1205,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1195 1205
1196 hci_dev_lock(hdev); 1206 hci_dev_lock(hdev);
1197 1207
1198 if (!(hdev->features[4] & LMP_LE)) { 1208 if (!lmp_le_capable(hdev)) {
1199 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 1209 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
1200 MGMT_STATUS_NOT_SUPPORTED); 1210 MGMT_STATUS_NOT_SUPPORTED);
1201 goto unlock; 1211 goto unlock;
@@ -2191,7 +2201,7 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
2191 goto unlock; 2201 goto unlock;
2192 } 2202 }
2193 2203
2194 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { 2204 if (!lmp_ssp_capable(hdev)) {
2195 err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 2205 err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
2196 MGMT_STATUS_NOT_SUPPORTED); 2206 MGMT_STATUS_NOT_SUPPORTED);
2197 goto unlock; 2207 goto unlock;
@@ -2820,6 +2830,9 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
2820 2830
2821int mgmt_index_added(struct hci_dev *hdev) 2831int mgmt_index_added(struct hci_dev *hdev)
2822{ 2832{
2833 if (!mgmt_valid_hdev(hdev))
2834 return -ENOTSUPP;
2835
2823 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); 2836 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
2824} 2837}
2825 2838
@@ -2827,6 +2840,9 @@ int mgmt_index_removed(struct hci_dev *hdev)
2827{ 2840{
2828 u8 status = MGMT_STATUS_INVALID_INDEX; 2841 u8 status = MGMT_STATUS_INVALID_INDEX;
2829 2842
2843 if (!mgmt_valid_hdev(hdev))
2844 return -ENOTSUPP;
2845
2830 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 2846 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
2831 2847
2832 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); 2848 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 7e1e59645c05..260821a2d6e7 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1033,8 +1033,17 @@ int __init rfcomm_init_sockets(void)
1033 return err; 1033 return err;
1034 1034
1035 err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops); 1035 err = bt_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops);
1036 if (err < 0) 1036 if (err < 0) {
1037 BT_ERR("RFCOMM socket layer registration failed");
1038 goto error;
1039 }
1040
1041 err = bt_procfs_init(THIS_MODULE, &init_net, "rfcomm", &rfcomm_sk_list, NULL);
1042 if (err < 0) {
1043 BT_ERR("Failed to create RFCOMM proc file");
1044 bt_sock_unregister(BTPROTO_RFCOMM);
1037 goto error; 1045 goto error;
1046 }
1038 1047
1039 if (bt_debugfs) { 1048 if (bt_debugfs) {
1040 rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, 1049 rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
@@ -1048,13 +1057,14 @@ int __init rfcomm_init_sockets(void)
1048 return 0; 1057 return 0;
1049 1058
1050error: 1059error:
1051 BT_ERR("RFCOMM socket layer registration failed");
1052 proto_unregister(&rfcomm_proto); 1060 proto_unregister(&rfcomm_proto);
1053 return err; 1061 return err;
1054} 1062}
1055 1063
1056void __exit rfcomm_cleanup_sockets(void) 1064void __exit rfcomm_cleanup_sockets(void)
1057{ 1065{
1066 bt_procfs_cleanup(&init_net, "rfcomm");
1067
1058 debugfs_remove(rfcomm_sock_debugfs); 1068 debugfs_remove(rfcomm_sock_debugfs);
1059 1069
1060 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) 1070 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 40bbe25dcff7..caa109df6452 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -913,7 +913,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
913 return lm; 913 return lm;
914} 914}
915 915
916int sco_connect_cfm(struct hci_conn *hcon, __u8 status) 916void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
917{ 917{
918 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); 918 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
919 if (!status) { 919 if (!status) {
@@ -924,16 +924,13 @@ int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
924 sco_conn_ready(conn); 924 sco_conn_ready(conn);
925 } else 925 } else
926 sco_conn_del(hcon, bt_to_errno(status)); 926 sco_conn_del(hcon, bt_to_errno(status));
927
928 return 0;
929} 927}
930 928
931int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) 929void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
932{ 930{
933 BT_DBG("hcon %p reason %d", hcon, reason); 931 BT_DBG("hcon %p reason %d", hcon, reason);
934 932
935 sco_conn_del(hcon, bt_to_errno(reason)); 933 sco_conn_del(hcon, bt_to_errno(reason));
936 return 0;
937} 934}
938 935
939int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) 936int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
@@ -1026,6 +1023,13 @@ int __init sco_init(void)
1026 goto error; 1023 goto error;
1027 } 1024 }
1028 1025
1026 err = bt_procfs_init(THIS_MODULE, &init_net, "sco", &sco_sk_list, NULL);
1027 if (err < 0) {
1028 BT_ERR("Failed to create SCO proc file");
1029 bt_sock_unregister(BTPROTO_SCO);
1030 goto error;
1031 }
1032
1029 if (bt_debugfs) { 1033 if (bt_debugfs) {
1030 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs, 1034 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1031 NULL, &sco_debugfs_fops); 1035 NULL, &sco_debugfs_fops);
@@ -1044,6 +1048,8 @@ error:
1044 1048
1045void __exit sco_exit(void) 1049void __exit sco_exit(void)
1046{ 1050{
1051 bt_procfs_cleanup(&init_net, "sco");
1052
1047 debugfs_remove(sco_debugfs); 1053 debugfs_remove(sco_debugfs);
1048 1054
1049 if (bt_sock_unregister(BTPROTO_SCO) < 0) 1055 if (bt_sock_unregister(BTPROTO_SCO) < 0)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 85572353a7e3..0e2f83e71277 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -136,10 +136,13 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons 136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons
137 * 137 *
138 * @sdata: mesh interface in which mesh beacons are going to be updated 138 * @sdata: mesh interface in which mesh beacons are going to be updated
139 *
140 * Returns: beacon changed flag if the beacon content changed.
139 */ 141 */
140void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) 142u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
141{ 143{
142 bool free_plinks; 144 bool free_plinks;
145 u32 changed = 0;
143 146
144 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0, 147 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0,
145 * the mesh interface might be able to establish plinks with peers that 148 * the mesh interface might be able to establish plinks with peers that
@@ -149,8 +152,12 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
149 */ 152 */
150 free_plinks = mesh_plink_availables(sdata); 153 free_plinks = mesh_plink_availables(sdata);
151 154
152 if (free_plinks != sdata->u.mesh.accepting_plinks) 155 if (free_plinks != sdata->u.mesh.accepting_plinks) {
153 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 156 sdata->u.mesh.accepting_plinks = free_plinks;
157 changed = BSS_CHANGED_BEACON;
158 }
159
160 return changed;
154} 161}
155 162
156int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 163int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -262,7 +269,6 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
262 neighbors = (neighbors > 15) ? 15 : neighbors; 269 neighbors = (neighbors > 15) ? 15 : neighbors;
263 *pos++ = neighbors << 1; 270 *pos++ = neighbors << 1;
264 /* Mesh capability */ 271 /* Mesh capability */
265 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
266 *pos = MESHCONF_CAPAB_FORWARDING; 272 *pos = MESHCONF_CAPAB_FORWARDING;
267 *pos |= ifmsh->accepting_plinks ? 273 *pos |= ifmsh->accepting_plinks ?
268 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 274 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
@@ -521,14 +527,13 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
521static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 527static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
522 struct ieee80211_if_mesh *ifmsh) 528 struct ieee80211_if_mesh *ifmsh)
523{ 529{
524 bool free_plinks; 530 u32 changed;
525 531
526 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 532 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
527 mesh_path_expire(sdata); 533 mesh_path_expire(sdata);
528 534
529 free_plinks = mesh_plink_availables(sdata); 535 changed = mesh_accept_plinks_update(sdata);
530 if (free_plinks != sdata->u.mesh.accepting_plinks) 536 ieee80211_bss_info_change_notify(sdata, changed);
531 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
532 537
533 mod_timer(&ifmsh->housekeeping_timer, 538 mod_timer(&ifmsh->housekeeping_timer,
534 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 539 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index faaa39bcfd10..13fd5b5fdb0a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -282,7 +282,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
282 u8 *hw_addr, 282 u8 *hw_addr,
283 struct ieee802_11_elems *ie); 283 struct ieee802_11_elems *ie);
284bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 284bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
285void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 285u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
286void mesh_plink_broken(struct sta_info *sta); 286void mesh_plink_broken(struct sta_info *sta);
287void mesh_plink_deactivate(struct sta_info *sta); 287void mesh_plink_deactivate(struct sta_info *sta);
288int mesh_plink_open(struct sta_info *sta); 288int mesh_plink_open(struct sta_info *sta);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index af671b984df3..f20e9f26d137 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -48,17 +48,17 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
48 u8 *da, __le16 llid, __le16 plid, __le16 reason); 48 u8 *da, __le16 llid, __le16 plid, __le16 reason);
49 49
50static inline 50static inline
51void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 51u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
52{ 52{
53 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); 53 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
54 mesh_accept_plinks_update(sdata); 54 return mesh_accept_plinks_update(sdata);
55} 55}
56 56
57static inline 57static inline
58void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 58u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
59{ 59{
60 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); 60 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
61 mesh_accept_plinks_update(sdata); 61 return mesh_accept_plinks_update(sdata);
62} 62}
63 63
64/** 64/**
@@ -170,22 +170,21 @@ out:
170 * @sta: mesh peer link to deactivate 170 * @sta: mesh peer link to deactivate
171 * 171 *
172 * All mesh paths with this peer as next hop will be flushed 172 * All mesh paths with this peer as next hop will be flushed
173 * Returns beacon changed flag if the beacon content changed.
173 * 174 *
174 * Locking: the caller must hold sta->lock 175 * Locking: the caller must hold sta->lock
175 */ 176 */
176static bool __mesh_plink_deactivate(struct sta_info *sta) 177static u32 __mesh_plink_deactivate(struct sta_info *sta)
177{ 178{
178 struct ieee80211_sub_if_data *sdata = sta->sdata; 179 struct ieee80211_sub_if_data *sdata = sta->sdata;
179 bool deactivated = false; 180 u32 changed = 0;
180 181
181 if (sta->plink_state == NL80211_PLINK_ESTAB) { 182 if (sta->plink_state == NL80211_PLINK_ESTAB)
182 mesh_plink_dec_estab_count(sdata); 183 changed = mesh_plink_dec_estab_count(sdata);
183 deactivated = true;
184 }
185 sta->plink_state = NL80211_PLINK_BLOCKED; 184 sta->plink_state = NL80211_PLINK_BLOCKED;
186 mesh_path_flush_by_nexthop(sta); 185 mesh_path_flush_by_nexthop(sta);
187 186
188 return deactivated; 187 return changed;
189} 188}
190 189
191/** 190/**
@@ -198,18 +197,17 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
198void mesh_plink_deactivate(struct sta_info *sta) 197void mesh_plink_deactivate(struct sta_info *sta)
199{ 198{
200 struct ieee80211_sub_if_data *sdata = sta->sdata; 199 struct ieee80211_sub_if_data *sdata = sta->sdata;
201 bool deactivated; 200 u32 changed;
202 201
203 spin_lock_bh(&sta->lock); 202 spin_lock_bh(&sta->lock);
204 deactivated = __mesh_plink_deactivate(sta); 203 changed = __mesh_plink_deactivate(sta);
205 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 204 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
206 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 205 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
207 sta->sta.addr, sta->llid, sta->plid, 206 sta->sta.addr, sta->llid, sta->plid,
208 sta->reason); 207 sta->reason);
209 spin_unlock_bh(&sta->lock); 208 spin_unlock_bh(&sta->lock);
210 209
211 if (deactivated) 210 ieee80211_bss_info_change_notify(sdata, changed);
212 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
213} 211}
214 212
215static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 213static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
@@ -541,15 +539,14 @@ int mesh_plink_open(struct sta_info *sta)
541void mesh_plink_block(struct sta_info *sta) 539void mesh_plink_block(struct sta_info *sta)
542{ 540{
543 struct ieee80211_sub_if_data *sdata = sta->sdata; 541 struct ieee80211_sub_if_data *sdata = sta->sdata;
544 bool deactivated; 542 u32 changed;
545 543
546 spin_lock_bh(&sta->lock); 544 spin_lock_bh(&sta->lock);
547 deactivated = __mesh_plink_deactivate(sta); 545 changed = __mesh_plink_deactivate(sta);
548 sta->plink_state = NL80211_PLINK_BLOCKED; 546 sta->plink_state = NL80211_PLINK_BLOCKED;
549 spin_unlock_bh(&sta->lock); 547 spin_unlock_bh(&sta->lock);
550 548
551 if (deactivated) 549 ieee80211_bss_info_change_notify(sdata, changed);
552 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
553} 550}
554 551
555 552
@@ -852,9 +849,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
852 del_timer(&sta->plink_timer); 849 del_timer(&sta->plink_timer);
853 sta->plink_state = NL80211_PLINK_ESTAB; 850 sta->plink_state = NL80211_PLINK_ESTAB;
854 spin_unlock_bh(&sta->lock); 851 spin_unlock_bh(&sta->lock);
855 mesh_plink_inc_estab_count(sdata); 852 changed |= mesh_plink_inc_estab_count(sdata);
856 changed |= mesh_set_ht_prot_mode(sdata); 853 changed |= mesh_set_ht_prot_mode(sdata);
857 changed |= BSS_CHANGED_BEACON;
858 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 854 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
859 sta->sta.addr); 855 sta->sta.addr);
860 break; 856 break;
@@ -888,9 +884,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
888 del_timer(&sta->plink_timer); 884 del_timer(&sta->plink_timer);
889 sta->plink_state = NL80211_PLINK_ESTAB; 885 sta->plink_state = NL80211_PLINK_ESTAB;
890 spin_unlock_bh(&sta->lock); 886 spin_unlock_bh(&sta->lock);
891 mesh_plink_inc_estab_count(sdata); 887 changed |= mesh_plink_inc_estab_count(sdata);
892 changed |= mesh_set_ht_prot_mode(sdata); 888 changed |= mesh_set_ht_prot_mode(sdata);
893 changed |= BSS_CHANGED_BEACON;
894 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 889 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
895 sta->sta.addr); 890 sta->sta.addr);
896 mesh_plink_frame_tx(sdata, 891 mesh_plink_frame_tx(sdata,
@@ -908,13 +903,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
908 case CLS_ACPT: 903 case CLS_ACPT:
909 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 904 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
910 sta->reason = reason; 905 sta->reason = reason;
911 __mesh_plink_deactivate(sta); 906 changed |= __mesh_plink_deactivate(sta);
912 sta->plink_state = NL80211_PLINK_HOLDING; 907 sta->plink_state = NL80211_PLINK_HOLDING;
913 llid = sta->llid; 908 llid = sta->llid;
914 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 909 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
915 spin_unlock_bh(&sta->lock); 910 spin_unlock_bh(&sta->lock);
916 changed |= mesh_set_ht_prot_mode(sdata); 911 changed |= mesh_set_ht_prot_mode(sdata);
917 changed |= BSS_CHANGED_BEACON;
918 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 912 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
919 sta->sta.addr, llid, plid, reason); 913 sta->sta.addr, llid, plid, reason);
920 break; 914 break;