diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-28 13:18:21 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-28 13:18:21 -0400 |
commit | 57ed5cd695d7373b8ae0ae9f10fe945e774d58f0 (patch) | |
tree | 7ee6244ea7c0be81a541d4e57783f83c4dfd7d66 | |
parent | 5e6700b3bf98fe98d630bf9c939ad4c85ce95592 (diff) | |
parent | 0f817ed52d07873cd39c9d3f6d87fae962dc742f (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
net/wireless/nl80211.c
119 files changed, 3772 insertions, 3098 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 79595a001204..0215f9ad755c 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -22,6 +22,8 @@ | |||
22 | struct bcma_bus; | 22 | struct bcma_bus; |
23 | 23 | ||
24 | /* main.c */ | 24 | /* main.c */ |
25 | bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, | ||
26 | int timeout); | ||
25 | int bcma_bus_register(struct bcma_bus *bus); | 27 | int bcma_bus_register(struct bcma_bus *bus); |
26 | void bcma_bus_unregister(struct bcma_bus *bus); | 28 | void bcma_bus_unregister(struct bcma_bus *bus); |
27 | int __init bcma_bus_early_register(struct bcma_bus *bus, | 29 | int __init bcma_bus_early_register(struct bcma_bus *bus, |
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index 036c6744b39b..b068f98920a8 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c | |||
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) | |||
140 | bcma_core_chipcommon_early_init(cc); | 140 | bcma_core_chipcommon_early_init(cc); |
141 | 141 | ||
142 | if (cc->core->id.rev >= 20) { | 142 | if (cc->core->id.rev >= 20) { |
143 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); | 143 | u32 pullup = 0, pulldown = 0; |
144 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); | 144 | |
145 | if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { | ||
146 | pullup = 0x402e0; | ||
147 | pulldown = 0x20500; | ||
148 | } | ||
149 | |||
150 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); | ||
151 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); | ||
145 | } | 152 | } |
146 | 153 | ||
147 | if (cc->capabilities & BCMA_CC_CAP_PMU) | 154 | if (cc->capabilities & BCMA_CC_CAP_PMU) |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index edca73af3cc0..5081a8c439cc 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); | 57 | EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); |
58 | 58 | ||
59 | static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) | ||
60 | { | ||
61 | u32 ilp_ctl, alp_hz; | ||
62 | |||
63 | if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & | ||
64 | BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) | ||
65 | return 0; | ||
66 | |||
67 | bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, | ||
68 | BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); | ||
69 | usleep_range(1000, 2000); | ||
70 | |||
71 | ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); | ||
72 | ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; | ||
73 | |||
74 | bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); | ||
75 | |||
76 | alp_hz = ilp_ctl * 32768 / 4; | ||
77 | return (alp_hz + 50000) / 100000 * 100; | ||
78 | } | ||
79 | |||
80 | static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) | ||
81 | { | ||
82 | struct bcma_bus *bus = cc->core->bus; | ||
83 | u32 freq_tgt_target = 0, freq_tgt_current; | ||
84 | u32 pll0, mask; | ||
85 | |||
86 | switch (bus->chipinfo.id) { | ||
87 | case BCMA_CHIP_ID_BCM43142: | ||
88 | /* pmu2_xtaltab0_adfll_485 */ | ||
89 | switch (xtalfreq) { | ||
90 | case 12000: | ||
91 | freq_tgt_target = 0x50D52; | ||
92 | break; | ||
93 | case 20000: | ||
94 | freq_tgt_target = 0x307FE; | ||
95 | break; | ||
96 | case 26000: | ||
97 | freq_tgt_target = 0x254EA; | ||
98 | break; | ||
99 | case 37400: | ||
100 | freq_tgt_target = 0x19EF8; | ||
101 | break; | ||
102 | case 52000: | ||
103 | freq_tgt_target = 0x12A75; | ||
104 | break; | ||
105 | } | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | if (!freq_tgt_target) { | ||
110 | bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n", | ||
111 | xtalfreq); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0); | ||
116 | freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >> | ||
117 | BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; | ||
118 | |||
119 | if (freq_tgt_current == freq_tgt_target) { | ||
120 | bcma_debug(bus, "Target TGT frequency already set\n"); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | /* Turn off PLL */ | ||
125 | switch (bus->chipinfo.id) { | ||
126 | case BCMA_CHIP_ID_BCM43142: | ||
127 | mask = (u32)~(BCMA_RES_4314_HT_AVAIL | | ||
128 | BCMA_RES_4314_MACPHY_CLK_AVAIL); | ||
129 | |||
130 | bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); | ||
131 | bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); | ||
132 | bcma_wait_value(cc->core, BCMA_CLKCTLST, | ||
133 | BCMA_CLKCTLST_HAVEHT, 0, 20000); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK; | ||
138 | pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; | ||
139 | bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0); | ||
140 | |||
141 | /* Flush */ | ||
142 | if (cc->pmu.rev >= 2) | ||
143 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); | ||
144 | |||
145 | /* TODO: Do we need to update OTP? */ | ||
146 | } | ||
147 | |||
148 | static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) | ||
149 | { | ||
150 | struct bcma_bus *bus = cc->core->bus; | ||
151 | u32 xtalfreq = bcma_pmu_xtalfreq(cc); | ||
152 | |||
153 | switch (bus->chipinfo.id) { | ||
154 | case BCMA_CHIP_ID_BCM43142: | ||
155 | if (xtalfreq == 0) | ||
156 | xtalfreq = 20000; | ||
157 | bcma_pmu2_pll_init0(cc, xtalfreq); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
59 | static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | 162 | static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) |
60 | { | 163 | { |
61 | struct bcma_bus *bus = cc->core->bus; | 164 | struct bcma_bus *bus = cc->core->bus; |
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |||
66 | min_msk = 0x200D; | 169 | min_msk = 0x200D; |
67 | max_msk = 0xFFFF; | 170 | max_msk = 0xFFFF; |
68 | break; | 171 | break; |
172 | case BCMA_CHIP_ID_BCM43142: | ||
173 | min_msk = BCMA_RES_4314_LPLDO_PU | | ||
174 | BCMA_RES_4314_PMU_SLEEP_DIS | | ||
175 | BCMA_RES_4314_PMU_BG_PU | | ||
176 | BCMA_RES_4314_CBUCK_LPOM_PU | | ||
177 | BCMA_RES_4314_CBUCK_PFM_PU | | ||
178 | BCMA_RES_4314_CLDO_PU | | ||
179 | BCMA_RES_4314_LPLDO2_LVM | | ||
180 | BCMA_RES_4314_WL_PMU_PU | | ||
181 | BCMA_RES_4314_LDO3P3_PU | | ||
182 | BCMA_RES_4314_OTP_PU | | ||
183 | BCMA_RES_4314_WL_PWRSW_PU | | ||
184 | BCMA_RES_4314_LQ_AVAIL | | ||
185 | BCMA_RES_4314_LOGIC_RET | | ||
186 | BCMA_RES_4314_MEM_SLEEP | | ||
187 | BCMA_RES_4314_MACPHY_RET | | ||
188 | BCMA_RES_4314_WL_CORE_READY; | ||
189 | max_msk = 0x3FFFFFFF; | ||
190 | break; | ||
69 | default: | 191 | default: |
70 | bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", | 192 | bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", |
71 | bus->chipinfo.id); | 193 | bus->chipinfo.id); |
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc) | |||
165 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, | 287 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, |
166 | BCMA_CC_PMU_CTL_NOILPONW); | 288 | BCMA_CC_PMU_CTL_NOILPONW); |
167 | 289 | ||
290 | bcma_pmu_pll_init(cc); | ||
168 | bcma_pmu_resources_init(cc); | 291 | bcma_pmu_resources_init(cc); |
169 | bcma_pmu_workarounds(cc); | 292 | bcma_pmu_workarounds(cc); |
170 | } | 293 | } |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index fbf2759e7e4e..a355e63a3838 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | |||
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, | 275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, |
276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, | 276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, |
277 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, | 277 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, |
278 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, | ||
278 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 279 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
279 | { 0, }, | 280 | { 0, }, |
280 | }; | 281 | }; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index f72f52b4b1dd..0067422ec17d 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, | |||
93 | return NULL; | 93 | return NULL; |
94 | } | 94 | } |
95 | 95 | ||
96 | bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, | ||
97 | int timeout) | ||
98 | { | ||
99 | unsigned long deadline = jiffies + timeout; | ||
100 | u32 val; | ||
101 | |||
102 | do { | ||
103 | val = bcma_read32(core, reg); | ||
104 | if ((val & mask) == value) | ||
105 | return true; | ||
106 | cpu_relax(); | ||
107 | udelay(10); | ||
108 | } while (!time_after_eq(jiffies, deadline)); | ||
109 | |||
110 | bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); | ||
111 | |||
112 | return false; | ||
113 | } | ||
114 | |||
96 | static void bcma_release_core_dev(struct device *dev) | 115 | static void bcma_release_core_dev(struct device *dev) |
97 | { | 116 | { |
98 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); | 117 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index de15b4f4b237..72bf4540f565 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | |||
503 | case BCMA_CHIP_ID_BCM4331: | 503 | case BCMA_CHIP_ID_BCM4331: |
504 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; | 504 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; |
505 | break; | 505 | break; |
506 | case BCMA_CHIP_ID_BCM43142: | ||
506 | case BCMA_CHIP_ID_BCM43224: | 507 | case BCMA_CHIP_ID_BCM43224: |
507 | case BCMA_CHIP_ID_BCM43225: | 508 | case BCMA_CHIP_ID_BCM43225: |
508 | /* for these chips OTP is always available */ | 509 | /* for these chips OTP is always available */ |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 81f12757a842..de4cf4daa2f4 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -1619,6 +1619,7 @@ static struct usb_driver btusb_driver = { | |||
1619 | #ifdef CONFIG_PM | 1619 | #ifdef CONFIG_PM |
1620 | .suspend = btusb_suspend, | 1620 | .suspend = btusb_suspend, |
1621 | .resume = btusb_resume, | 1621 | .resume = btusb_resume, |
1622 | .reset_resume = btusb_resume, | ||
1622 | #endif | 1623 | #endif |
1623 | .id_table = btusb_table, | 1624 | .id_table = btusb_table, |
1624 | .supports_autosuspend = 1, | 1625 | .supports_autosuspend = 1, |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3446c989d6a6..da5c333d0d4b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -54,7 +54,6 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
54 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; | 54 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; |
55 | break; | 55 | break; |
56 | case WLAN_CIPHER_SUITE_TKIP: | 56 | case WLAN_CIPHER_SUITE_TKIP: |
57 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
58 | arg.key_cipher = WMI_CIPHER_TKIP; | 57 | arg.key_cipher = WMI_CIPHER_TKIP; |
59 | arg.key_txmic_len = 8; | 58 | arg.key_txmic_len = 8; |
60 | arg.key_rxmic_len = 8; | 59 | arg.key_rxmic_len = 8; |
@@ -237,6 +236,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef) | |||
237 | case NL80211_CHAN_WIDTH_40: | 236 | case NL80211_CHAN_WIDTH_40: |
238 | phymode = MODE_11NG_HT40; | 237 | phymode = MODE_11NG_HT40; |
239 | break; | 238 | break; |
239 | case NL80211_CHAN_WIDTH_5: | ||
240 | case NL80211_CHAN_WIDTH_10: | ||
240 | case NL80211_CHAN_WIDTH_80: | 241 | case NL80211_CHAN_WIDTH_80: |
241 | case NL80211_CHAN_WIDTH_80P80: | 242 | case NL80211_CHAN_WIDTH_80P80: |
242 | case NL80211_CHAN_WIDTH_160: | 243 | case NL80211_CHAN_WIDTH_160: |
@@ -258,6 +259,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef) | |||
258 | case NL80211_CHAN_WIDTH_80: | 259 | case NL80211_CHAN_WIDTH_80: |
259 | phymode = MODE_11AC_VHT80; | 260 | phymode = MODE_11AC_VHT80; |
260 | break; | 261 | break; |
262 | case NL80211_CHAN_WIDTH_5: | ||
263 | case NL80211_CHAN_WIDTH_10: | ||
261 | case NL80211_CHAN_WIDTH_80P80: | 264 | case NL80211_CHAN_WIDTH_80P80: |
262 | case NL80211_CHAN_WIDTH_160: | 265 | case NL80211_CHAN_WIDTH_160: |
263 | phymode = MODE_UNKNOWN; | 266 | phymode = MODE_UNKNOWN; |
@@ -2721,30 +2724,30 @@ static const struct ieee80211_channel ath10k_2ghz_channels[] = { | |||
2721 | }; | 2724 | }; |
2722 | 2725 | ||
2723 | static const struct ieee80211_channel ath10k_5ghz_channels[] = { | 2726 | static const struct ieee80211_channel ath10k_5ghz_channels[] = { |
2724 | CHAN5G(36, 5180, 14), | 2727 | CHAN5G(36, 5180, 0), |
2725 | CHAN5G(40, 5200, 15), | 2728 | CHAN5G(40, 5200, 0), |
2726 | CHAN5G(44, 5220, 16), | 2729 | CHAN5G(44, 5220, 0), |
2727 | CHAN5G(48, 5240, 17), | 2730 | CHAN5G(48, 5240, 0), |
2728 | CHAN5G(52, 5260, 18), | 2731 | CHAN5G(52, 5260, 0), |
2729 | CHAN5G(56, 5280, 19), | 2732 | CHAN5G(56, 5280, 0), |
2730 | CHAN5G(60, 5300, 20), | 2733 | CHAN5G(60, 5300, 0), |
2731 | CHAN5G(64, 5320, 21), | 2734 | CHAN5G(64, 5320, 0), |
2732 | CHAN5G(100, 5500, 22), | 2735 | CHAN5G(100, 5500, 0), |
2733 | CHAN5G(104, 5520, 23), | 2736 | CHAN5G(104, 5520, 0), |
2734 | CHAN5G(108, 5540, 24), | 2737 | CHAN5G(108, 5540, 0), |
2735 | CHAN5G(112, 5560, 25), | 2738 | CHAN5G(112, 5560, 0), |
2736 | CHAN5G(116, 5580, 26), | 2739 | CHAN5G(116, 5580, 0), |
2737 | CHAN5G(120, 5600, 27), | 2740 | CHAN5G(120, 5600, 0), |
2738 | CHAN5G(124, 5620, 28), | 2741 | CHAN5G(124, 5620, 0), |
2739 | CHAN5G(128, 5640, 29), | 2742 | CHAN5G(128, 5640, 0), |
2740 | CHAN5G(132, 5660, 30), | 2743 | CHAN5G(132, 5660, 0), |
2741 | CHAN5G(136, 5680, 31), | 2744 | CHAN5G(136, 5680, 0), |
2742 | CHAN5G(140, 5700, 32), | 2745 | CHAN5G(140, 5700, 0), |
2743 | CHAN5G(149, 5745, 33), | 2746 | CHAN5G(149, 5745, 0), |
2744 | CHAN5G(153, 5765, 34), | 2747 | CHAN5G(153, 5765, 0), |
2745 | CHAN5G(157, 5785, 35), | 2748 | CHAN5G(157, 5785, 0), |
2746 | CHAN5G(161, 5805, 36), | 2749 | CHAN5G(161, 5805, 0), |
2747 | CHAN5G(165, 5825, 37), | 2750 | CHAN5G(165, 5825, 0), |
2748 | }; | 2751 | }; |
2749 | 2752 | ||
2750 | static struct ieee80211_rate ath10k_rates[] = { | 2753 | static struct ieee80211_rate ath10k_rates[] = { |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index c8e905669701..33af4672c909 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -1883,9 +1883,10 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num) | |||
1883 | ath10k_warn("request_irq(%d) failed %d\n", | 1883 | ath10k_warn("request_irq(%d) failed %d\n", |
1884 | ar_pci->pdev->irq + i, ret); | 1884 | ar_pci->pdev->irq + i, ret); |
1885 | 1885 | ||
1886 | for (; i >= MSI_ASSIGN_CE_INITIAL; i--) | 1886 | for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) |
1887 | free_irq(ar_pci->pdev->irq, ar); | 1887 | free_irq(ar_pci->pdev->irq + i, ar); |
1888 | 1888 | ||
1889 | free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar); | ||
1889 | pci_disable_msi(ar_pci->pdev); | 1890 | pci_disable_msi(ar_pci->pdev); |
1890 | return ret; | 1891 | return ret; |
1891 | } | 1892 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 1e86977d3322..d105e43d22e1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3606,7 +3606,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3606 | * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE | 3606 | * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE |
3607 | * SWITCH_TABLE_COM_SPDT_WLAN_IDLE | 3607 | * SWITCH_TABLE_COM_SPDT_WLAN_IDLE |
3608 | */ | 3608 | */ |
3609 | if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) { | 3609 | if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) { |
3610 | value = ar9003_switch_com_spdt_get(ah, is2ghz); | 3610 | value = ar9003_switch_com_spdt_get(ah, is2ghz); |
3611 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, | 3611 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, |
3612 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); | 3612 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); |
@@ -4059,8 +4059,9 @@ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah) | |||
4059 | { | 4059 | { |
4060 | u32 data, ko, kg; | 4060 | u32 data, ko, kg; |
4061 | 4061 | ||
4062 | if (!AR_SREV_9462_20(ah)) | 4062 | if (!AR_SREV_9462_20_OR_LATER(ah)) |
4063 | return; | 4063 | return; |
4064 | |||
4064 | ar9300_otp_read_word(ah, 1, &data); | 4065 | ar9300_otp_read_word(ah, 1, &data); |
4065 | ko = data & 0xff; | 4066 | ko = data & 0xff; |
4066 | kg = (data >> 8) & 0xff; | 4067 | kg = (data >> 8) & 0xff; |
@@ -4752,7 +4753,7 @@ tempslope: | |||
4752 | AR_PHY_TPC_19_ALPHA_THERM, temp_slope); | 4753 | AR_PHY_TPC_19_ALPHA_THERM, temp_slope); |
4753 | } | 4754 | } |
4754 | 4755 | ||
4755 | if (AR_SREV_9462_20(ah)) | 4756 | if (AR_SREV_9462_20_OR_LATER(ah)) |
4756 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | 4757 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, |
4757 | AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope); | 4758 | AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope); |
4758 | 4759 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 671aaa7e7337..d402cb32283f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "ar955x_1p0_initvals.h" | 24 | #include "ar955x_1p0_initvals.h" |
25 | #include "ar9580_1p0_initvals.h" | 25 | #include "ar9580_1p0_initvals.h" |
26 | #include "ar9462_2p0_initvals.h" | 26 | #include "ar9462_2p0_initvals.h" |
27 | #include "ar9462_2p1_initvals.h" | ||
27 | #include "ar9565_1p0_initvals.h" | 28 | #include "ar9565_1p0_initvals.h" |
28 | 29 | ||
29 | /* General hardware code for the AR9003 hadware family */ | 30 | /* General hardware code for the AR9003 hadware family */ |
@@ -197,6 +198,31 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
197 | 198 | ||
198 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 199 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
199 | ar9485_1_1_pcie_phy_clkreq_disable_L1); | 200 | ar9485_1_1_pcie_phy_clkreq_disable_L1); |
201 | } else if (AR_SREV_9462_21(ah)) { | ||
202 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
203 | ar9462_2p1_mac_core); | ||
204 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
205 | ar9462_2p1_mac_postamble); | ||
206 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
207 | ar9462_2p1_baseband_core); | ||
208 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
209 | ar9462_2p1_baseband_postamble); | ||
210 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
211 | ar9462_2p1_radio_core); | ||
212 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||
213 | ar9462_2p1_radio_postamble); | ||
214 | INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant, | ||
215 | ar9462_2p1_radio_postamble_sys2ant); | ||
216 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
217 | ar9462_2p1_soc_preamble); | ||
218 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
219 | ar9462_2p1_soc_postamble); | ||
220 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
221 | ar9462_2p1_common_rx_gain); | ||
222 | INIT_INI_ARRAY(&ah->iniModesFastClock, | ||
223 | ar9462_2p1_modes_fast_clock); | ||
224 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
225 | ar9462_2p1_baseband_core_txfir_coeff_japan_2484); | ||
200 | } else if (AR_SREV_9462_20(ah)) { | 226 | } else if (AR_SREV_9462_20(ah)) { |
201 | 227 | ||
202 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); | 228 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); |
@@ -407,6 +433,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) | |||
407 | else if (AR_SREV_9580(ah)) | 433 | else if (AR_SREV_9580(ah)) |
408 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 434 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
409 | ar9580_1p0_lowest_ob_db_tx_gain_table); | 435 | ar9580_1p0_lowest_ob_db_tx_gain_table); |
436 | else if (AR_SREV_9462_21(ah)) | ||
437 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
438 | ar9462_2p1_modes_low_ob_db_tx_gain); | ||
410 | else if (AR_SREV_9462_20(ah)) | 439 | else if (AR_SREV_9462_20(ah)) |
411 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 440 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
412 | ar9462_modes_low_ob_db_tx_gain_table_2p0); | 441 | ar9462_modes_low_ob_db_tx_gain_table_2p0); |
@@ -438,6 +467,9 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) | |||
438 | else if (AR_SREV_9550(ah)) | 467 | else if (AR_SREV_9550(ah)) |
439 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 468 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
440 | ar955x_1p0_modes_no_xpa_tx_gain_table); | 469 | ar955x_1p0_modes_no_xpa_tx_gain_table); |
470 | else if (AR_SREV_9462_21(ah)) | ||
471 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
472 | ar9462_2p1_modes_high_ob_db_tx_gain); | ||
441 | else if (AR_SREV_9462_20(ah)) | 473 | else if (AR_SREV_9462_20(ah)) |
442 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 474 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
443 | ar9462_modes_high_ob_db_tx_gain_table_2p0); | 475 | ar9462_modes_high_ob_db_tx_gain_table_2p0); |
@@ -507,6 +539,12 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah) | |||
507 | else if (AR_SREV_9580(ah)) | 539 | else if (AR_SREV_9580(ah)) |
508 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 540 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
509 | ar9580_1p0_mixed_ob_db_tx_gain_table); | 541 | ar9580_1p0_mixed_ob_db_tx_gain_table); |
542 | else if (AR_SREV_9462_21(ah)) | ||
543 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
544 | ar9462_2p1_modes_mix_ob_db_tx_gain); | ||
545 | else if (AR_SREV_9462_20(ah)) | ||
546 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
547 | ar9462_modes_mix_ob_db_tx_gain_table_2p0); | ||
510 | else | 548 | else |
511 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 549 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
512 | ar9300Modes_mixed_ob_db_tx_gain_table_2p2); | 550 | ar9300Modes_mixed_ob_db_tx_gain_table_2p2); |
@@ -584,6 +622,9 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) | |||
584 | } else if (AR_SREV_9580(ah)) | 622 | } else if (AR_SREV_9580(ah)) |
585 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 623 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
586 | ar9580_1p0_rx_gain_table); | 624 | ar9580_1p0_rx_gain_table); |
625 | else if (AR_SREV_9462_21(ah)) | ||
626 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
627 | ar9462_2p1_common_rx_gain); | ||
587 | else if (AR_SREV_9462_20(ah)) | 628 | else if (AR_SREV_9462_20(ah)) |
588 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 629 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
589 | ar9462_common_rx_gain_table_2p0); | 630 | ar9462_common_rx_gain_table_2p0); |
@@ -606,6 +647,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) | |||
606 | else if (AR_SREV_9485_11(ah)) | 647 | else if (AR_SREV_9485_11(ah)) |
607 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 648 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
608 | ar9485Common_wo_xlna_rx_gain_1_1); | 649 | ar9485Common_wo_xlna_rx_gain_1_1); |
650 | else if (AR_SREV_9462_21(ah)) | ||
651 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
652 | ar9462_2p1_common_wo_xlna_rx_gain); | ||
609 | else if (AR_SREV_9462_20(ah)) | 653 | else if (AR_SREV_9462_20(ah)) |
610 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 654 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
611 | ar9462_common_wo_xlna_rx_gain_table_2p0); | 655 | ar9462_common_wo_xlna_rx_gain_table_2p0); |
@@ -627,7 +671,16 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) | |||
627 | 671 | ||
628 | static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) | 672 | static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) |
629 | { | 673 | { |
630 | if (AR_SREV_9462_20(ah)) { | 674 | if (AR_SREV_9462_21(ah)) { |
675 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
676 | ar9462_2p1_common_mixed_rx_gain); | ||
677 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, | ||
678 | ar9462_2p1_baseband_core_mix_rxgain); | ||
679 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble, | ||
680 | ar9462_2p1_baseband_postamble_mix_rxgain); | ||
681 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, | ||
682 | ar9462_2p1_baseband_postamble_5g_xlna); | ||
683 | } else if (AR_SREV_9462_20(ah)) { | ||
631 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 684 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
632 | ar9462_common_mixed_rx_gain_table_2p0); | 685 | ar9462_common_mixed_rx_gain_table_2p0); |
633 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, | 686 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, |
@@ -641,7 +694,12 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) | |||
641 | 694 | ||
642 | static void ar9003_rx_gain_table_mode3(struct ath_hw *ah) | 695 | static void ar9003_rx_gain_table_mode3(struct ath_hw *ah) |
643 | { | 696 | { |
644 | if (AR_SREV_9462_20(ah)) { | 697 | if (AR_SREV_9462_21(ah)) { |
698 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
699 | ar9462_2p1_common_5g_xlna_only_rx_gain); | ||
700 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, | ||
701 | ar9462_2p1_baseband_postamble_5g_xlna); | ||
702 | } else if (AR_SREV_9462_20(ah)) { | ||
645 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 703 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
646 | ar9462_2p0_5g_xlna_only_rxgain); | 704 | ar9462_2p0_5g_xlna_only_rxgain); |
647 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, | 705 | INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index df84d20e1092..1f694ab3cc78 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -743,7 +743,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
743 | ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); | 743 | ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); |
744 | ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); | 744 | ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); |
745 | ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); | 745 | ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); |
746 | if (i == ATH_INI_POST && AR_SREV_9462_20(ah)) | 746 | if (i == ATH_INI_POST && AR_SREV_9462_20_OR_LATER(ah)) |
747 | ar9003_hw_prog_ini(ah, | 747 | ar9003_hw_prog_ini(ah, |
748 | &ah->ini_radio_post_sys2ant, | 748 | &ah->ini_radio_post_sys2ant, |
749 | modesIndex); | 749 | modesIndex); |
@@ -754,7 +754,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
754 | */ | 754 | */ |
755 | REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); | 755 | REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); |
756 | 756 | ||
757 | if (AR_SREV_9462_20(ah)) { | 757 | if (AR_SREV_9462_20_OR_LATER(ah)) { |
758 | /* | 758 | /* |
759 | * CUS217 mix LNA mode. | 759 | * CUS217 mix LNA mode. |
760 | */ | 760 | */ |
@@ -1512,7 +1512,7 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, | |||
1512 | ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); | 1512 | ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); |
1513 | ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); | 1513 | ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); |
1514 | 1514 | ||
1515 | if (AR_SREV_9462_20(ah)) | 1515 | if (AR_SREV_9462_20_OR_LATER(ah)) |
1516 | ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, | 1516 | ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, |
1517 | modesIndex); | 1517 | modesIndex); |
1518 | 1518 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 5013c731f9f6..d4d39f305a0b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -954,7 +954,7 @@ | |||
954 | #define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) | 954 | #define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) |
955 | #define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) | 955 | #define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) |
956 | #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) | 956 | #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) |
957 | #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \ | 957 | #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_9462_20_OR_LATER(ah) ? \ |
958 | 0x280 : 0x240)) | 958 | 0x280 : 0x240)) |
959 | #define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) | 959 | #define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) |
960 | #define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff | 960 | #define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff |
@@ -1048,7 +1048,7 @@ | |||
1048 | #define AR_GLB_GPIO_CONTROL (AR_GLB_BASE) | 1048 | #define AR_GLB_GPIO_CONTROL (AR_GLB_BASE) |
1049 | #define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) | 1049 | #define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) |
1050 | #define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ | 1050 | #define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ |
1051 | (AR_SREV_9462_20(_ah) ? 0x4c : 0x50)) | 1051 | (AR_SREV_9462_20_OR_LATER(_ah) ? 0x4c : 0x50)) |
1052 | #define AR_GLB_STATUS (AR_GLB_BASE + 0x48) | 1052 | #define AR_GLB_STATUS (AR_GLB_BASE + 0x48) |
1053 | 1053 | ||
1054 | /* | 1054 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1d6b705ba110..092b9d412e7f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -879,6 +879,69 @@ static const u32 ar9462_2p0_radio_postamble[][5] = { | |||
879 | {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, | 879 | {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, |
880 | }; | 880 | }; |
881 | 881 | ||
882 | static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = { | ||
883 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
884 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
885 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
886 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
887 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
888 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
889 | {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de}, | ||
890 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
891 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
892 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, | ||
893 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | ||
894 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | ||
895 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | ||
896 | {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400}, | ||
897 | {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402}, | ||
898 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, | ||
899 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603}, | ||
900 | {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02}, | ||
901 | {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04}, | ||
902 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20}, | ||
903 | {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20}, | ||
904 | {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22}, | ||
905 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24}, | ||
906 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640}, | ||
907 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660}, | ||
908 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861}, | ||
909 | {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81}, | ||
910 | {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83}, | ||
911 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84}, | ||
912 | {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3}, | ||
913 | {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5}, | ||
914 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9}, | ||
915 | {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb}, | ||
916 | {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec}, | ||
917 | {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0}, | ||
918 | {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4}, | ||
919 | {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
920 | {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
921 | {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
922 | {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
923 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
924 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
925 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
926 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
927 | {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, | ||
928 | {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, | ||
929 | {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, | ||
930 | {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, | ||
931 | {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, | ||
932 | {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, | ||
933 | {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, | ||
934 | {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
935 | {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
936 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
937 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
938 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
939 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
940 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
941 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
942 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
943 | }; | ||
944 | |||
882 | static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { | 945 | static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { |
883 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 946 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
884 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | 947 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h new file mode 100644 index 000000000000..4dbc294df7e3 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h | |||
@@ -0,0 +1,1774 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * Copyright (c) 2011-2012 Qualcomm Atheros Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef INITVALS_9462_2P1_H | ||
19 | #define INITVALS_9462_2P1_H | ||
20 | |||
21 | /* AR9462 2.1 */ | ||
22 | |||
23 | static const u32 ar9462_2p1_mac_core[][2] = { | ||
24 | /* Addr allmodes */ | ||
25 | {0x00000008, 0x00000000}, | ||
26 | {0x00000030, 0x000e0085}, | ||
27 | {0x00000034, 0x00000005}, | ||
28 | {0x00000040, 0x00000000}, | ||
29 | {0x00000044, 0x00000000}, | ||
30 | {0x00000048, 0x00000008}, | ||
31 | {0x0000004c, 0x00000010}, | ||
32 | {0x00000050, 0x00000000}, | ||
33 | {0x00001040, 0x002ffc0f}, | ||
34 | {0x00001044, 0x002ffc0f}, | ||
35 | {0x00001048, 0x002ffc0f}, | ||
36 | {0x0000104c, 0x002ffc0f}, | ||
37 | {0x00001050, 0x002ffc0f}, | ||
38 | {0x00001054, 0x002ffc0f}, | ||
39 | {0x00001058, 0x002ffc0f}, | ||
40 | {0x0000105c, 0x002ffc0f}, | ||
41 | {0x00001060, 0x002ffc0f}, | ||
42 | {0x00001064, 0x002ffc0f}, | ||
43 | {0x000010f0, 0x00000100}, | ||
44 | {0x00001270, 0x00000000}, | ||
45 | {0x000012b0, 0x00000000}, | ||
46 | {0x000012f0, 0x00000000}, | ||
47 | {0x0000143c, 0x00000000}, | ||
48 | {0x0000147c, 0x00000000}, | ||
49 | {0x00001810, 0x0f000003}, | ||
50 | {0x00008000, 0x00000000}, | ||
51 | {0x00008004, 0x00000000}, | ||
52 | {0x00008008, 0x00000000}, | ||
53 | {0x0000800c, 0x00000000}, | ||
54 | {0x00008018, 0x00000000}, | ||
55 | {0x00008020, 0x00000000}, | ||
56 | {0x00008038, 0x00000000}, | ||
57 | {0x0000803c, 0x00080000}, | ||
58 | {0x00008040, 0x00000000}, | ||
59 | {0x00008044, 0x00000000}, | ||
60 | {0x00008048, 0x00000000}, | ||
61 | {0x0000804c, 0xffffffff}, | ||
62 | {0x00008054, 0x00000000}, | ||
63 | {0x00008058, 0x00000000}, | ||
64 | {0x0000805c, 0x000fc78f}, | ||
65 | {0x00008060, 0x0000000f}, | ||
66 | {0x00008064, 0x00000000}, | ||
67 | {0x00008070, 0x00000310}, | ||
68 | {0x00008074, 0x00000020}, | ||
69 | {0x00008078, 0x00000000}, | ||
70 | {0x0000809c, 0x0000000f}, | ||
71 | {0x000080a0, 0x00000000}, | ||
72 | {0x000080a4, 0x02ff0000}, | ||
73 | {0x000080a8, 0x0e070605}, | ||
74 | {0x000080ac, 0x0000000d}, | ||
75 | {0x000080b0, 0x00000000}, | ||
76 | {0x000080b4, 0x00000000}, | ||
77 | {0x000080b8, 0x00000000}, | ||
78 | {0x000080bc, 0x00000000}, | ||
79 | {0x000080c0, 0x2a800000}, | ||
80 | {0x000080c4, 0x06900168}, | ||
81 | {0x000080c8, 0x13881c20}, | ||
82 | {0x000080cc, 0x01f40000}, | ||
83 | {0x000080d0, 0x00252500}, | ||
84 | {0x000080d4, 0x00b00005}, | ||
85 | {0x000080d8, 0x00400002}, | ||
86 | {0x000080dc, 0x00000000}, | ||
87 | {0x000080e0, 0xffffffff}, | ||
88 | {0x000080e4, 0x0000ffff}, | ||
89 | {0x000080e8, 0x3f3f3f3f}, | ||
90 | {0x000080ec, 0x00000000}, | ||
91 | {0x000080f0, 0x00000000}, | ||
92 | {0x000080f4, 0x00000000}, | ||
93 | {0x000080fc, 0x00020000}, | ||
94 | {0x00008100, 0x00000000}, | ||
95 | {0x00008108, 0x00000052}, | ||
96 | {0x0000810c, 0x00000000}, | ||
97 | {0x00008110, 0x00000000}, | ||
98 | {0x00008114, 0x000007ff}, | ||
99 | {0x00008118, 0x000000aa}, | ||
100 | {0x0000811c, 0x00003210}, | ||
101 | {0x00008124, 0x00000000}, | ||
102 | {0x00008128, 0x00000000}, | ||
103 | {0x0000812c, 0x00000000}, | ||
104 | {0x00008130, 0x00000000}, | ||
105 | {0x00008134, 0x00000000}, | ||
106 | {0x00008138, 0x00000000}, | ||
107 | {0x0000813c, 0x0000ffff}, | ||
108 | {0x00008144, 0xffffffff}, | ||
109 | {0x00008168, 0x00000000}, | ||
110 | {0x0000816c, 0x00000000}, | ||
111 | {0x00008170, 0x18486e00}, | ||
112 | {0x00008174, 0x33332210}, | ||
113 | {0x00008178, 0x00000000}, | ||
114 | {0x0000817c, 0x00020000}, | ||
115 | {0x000081c4, 0x33332210}, | ||
116 | {0x000081c8, 0x00000000}, | ||
117 | {0x000081cc, 0x00000000}, | ||
118 | {0x000081d4, 0x00000000}, | ||
119 | {0x000081ec, 0x00000000}, | ||
120 | {0x000081f0, 0x00000000}, | ||
121 | {0x000081f4, 0x00000000}, | ||
122 | {0x000081f8, 0x00000000}, | ||
123 | {0x000081fc, 0x00000000}, | ||
124 | {0x00008240, 0x00100000}, | ||
125 | {0x00008244, 0x0010f400}, | ||
126 | {0x00008248, 0x00000800}, | ||
127 | {0x0000824c, 0x0001e800}, | ||
128 | {0x00008250, 0x00000000}, | ||
129 | {0x00008254, 0x00000000}, | ||
130 | {0x00008258, 0x00000000}, | ||
131 | {0x0000825c, 0x40000000}, | ||
132 | {0x00008260, 0x00080922}, | ||
133 | {0x00008264, 0x99c00010}, | ||
134 | {0x00008268, 0xffffffff}, | ||
135 | {0x0000826c, 0x0000ffff}, | ||
136 | {0x00008270, 0x00000000}, | ||
137 | {0x00008274, 0x40000000}, | ||
138 | {0x00008278, 0x003e4180}, | ||
139 | {0x0000827c, 0x00000004}, | ||
140 | {0x00008284, 0x0000002c}, | ||
141 | {0x00008288, 0x0000002c}, | ||
142 | {0x0000828c, 0x000000ff}, | ||
143 | {0x00008294, 0x00000000}, | ||
144 | {0x00008298, 0x00000000}, | ||
145 | {0x0000829c, 0x00000000}, | ||
146 | {0x00008300, 0x00000140}, | ||
147 | {0x00008314, 0x00000000}, | ||
148 | {0x0000831c, 0x0000010d}, | ||
149 | {0x00008328, 0x00000000}, | ||
150 | {0x0000832c, 0x0000001f}, | ||
151 | {0x00008330, 0x00000302}, | ||
152 | {0x00008334, 0x00000700}, | ||
153 | {0x00008338, 0xffff0000}, | ||
154 | {0x0000833c, 0x02400000}, | ||
155 | {0x00008340, 0x000107ff}, | ||
156 | {0x00008344, 0xaa48107b}, | ||
157 | {0x00008348, 0x008f0000}, | ||
158 | {0x0000835c, 0x00000000}, | ||
159 | {0x00008360, 0xffffffff}, | ||
160 | {0x00008364, 0xffffffff}, | ||
161 | {0x00008368, 0x00000000}, | ||
162 | {0x00008370, 0x00000000}, | ||
163 | {0x00008374, 0x000000ff}, | ||
164 | {0x00008378, 0x00000000}, | ||
165 | {0x0000837c, 0x00000000}, | ||
166 | {0x00008380, 0xffffffff}, | ||
167 | {0x00008384, 0xffffffff}, | ||
168 | {0x00008390, 0xffffffff}, | ||
169 | {0x00008394, 0xffffffff}, | ||
170 | {0x00008398, 0x00000000}, | ||
171 | {0x0000839c, 0x00000000}, | ||
172 | {0x000083a4, 0x0000fa14}, | ||
173 | {0x000083a8, 0x000f0c00}, | ||
174 | {0x000083ac, 0x33332210}, | ||
175 | {0x000083b0, 0x33332210}, | ||
176 | {0x000083b4, 0x33332210}, | ||
177 | {0x000083b8, 0x33332210}, | ||
178 | {0x000083bc, 0x00000000}, | ||
179 | {0x000083c0, 0x00000000}, | ||
180 | {0x000083c4, 0x00000000}, | ||
181 | {0x000083c8, 0x00000000}, | ||
182 | {0x000083cc, 0x00000200}, | ||
183 | {0x000083d0, 0x000301ff}, | ||
184 | }; | ||
185 | |||
186 | static const u32 ar9462_2p1_mac_postamble[][5] = { | ||
187 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
188 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
189 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
190 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
191 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
192 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
193 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
194 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
195 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
196 | }; | ||
197 | |||
198 | static const u32 ar9462_2p1_baseband_core[][2] = { | ||
199 | /* Addr allmodes */ | ||
200 | {0x00009800, 0xafe68e30}, | ||
201 | {0x00009804, 0xfd14e000}, | ||
202 | {0x00009808, 0x9c0a9f6b}, | ||
203 | {0x0000980c, 0x04900000}, | ||
204 | {0x00009814, 0x9280c00a}, | ||
205 | {0x00009818, 0x00000000}, | ||
206 | {0x0000981c, 0x00020028}, | ||
207 | {0x00009834, 0x6400a290}, | ||
208 | {0x00009838, 0x0108ecff}, | ||
209 | {0x0000983c, 0x0d000600}, | ||
210 | {0x00009880, 0x201fff00}, | ||
211 | {0x00009884, 0x00001042}, | ||
212 | {0x000098a4, 0x00200400}, | ||
213 | {0x000098b0, 0x32440bbe}, | ||
214 | {0x000098d0, 0x004b6a8e}, | ||
215 | {0x000098d4, 0x00000820}, | ||
216 | {0x000098dc, 0x00000000}, | ||
217 | {0x000098e4, 0x01ffffff}, | ||
218 | {0x000098e8, 0x01ffffff}, | ||
219 | {0x000098ec, 0x01ffffff}, | ||
220 | {0x000098f0, 0x00000000}, | ||
221 | {0x000098f4, 0x00000000}, | ||
222 | {0x00009bf0, 0x80000000}, | ||
223 | {0x00009c04, 0xff55ff55}, | ||
224 | {0x00009c08, 0x0320ff55}, | ||
225 | {0x00009c0c, 0x00000000}, | ||
226 | {0x00009c10, 0x00000000}, | ||
227 | {0x00009c14, 0x00046384}, | ||
228 | {0x00009c18, 0x05b6b440}, | ||
229 | {0x00009c1c, 0x00b6b440}, | ||
230 | {0x00009d00, 0xc080a333}, | ||
231 | {0x00009d04, 0x40206c10}, | ||
232 | {0x00009d08, 0x009c4060}, | ||
233 | {0x00009d0c, 0x9883800a}, | ||
234 | {0x00009d10, 0x01834061}, | ||
235 | {0x00009d14, 0x00c0040b}, | ||
236 | {0x00009d18, 0x00000000}, | ||
237 | {0x00009e08, 0x0038230c}, | ||
238 | {0x00009e24, 0x990bb515}, | ||
239 | {0x00009e28, 0x0c6f0000}, | ||
240 | {0x00009e30, 0x06336f77}, | ||
241 | {0x00009e34, 0x6af6532f}, | ||
242 | {0x00009e38, 0x0cc80c00}, | ||
243 | {0x00009e40, 0x15262820}, | ||
244 | {0x00009e4c, 0x00001004}, | ||
245 | {0x00009e50, 0x00ff03f1}, | ||
246 | {0x00009e54, 0xe4c555c2}, | ||
247 | {0x00009e58, 0xfd857722}, | ||
248 | {0x00009e5c, 0xe9198724}, | ||
249 | {0x00009fc0, 0x803e4788}, | ||
250 | {0x00009fc4, 0x0001efb5}, | ||
251 | {0x00009fcc, 0x40000014}, | ||
252 | {0x00009fd0, 0x0a193b93}, | ||
253 | {0x0000a20c, 0x00000000}, | ||
254 | {0x0000a220, 0x00000000}, | ||
255 | {0x0000a224, 0x00000000}, | ||
256 | {0x0000a228, 0x10002310}, | ||
257 | {0x0000a23c, 0x00000000}, | ||
258 | {0x0000a244, 0x0c000000}, | ||
259 | {0x0000a2a0, 0x00000001}, | ||
260 | {0x0000a2c0, 0x00000001}, | ||
261 | {0x0000a2c8, 0x00000000}, | ||
262 | {0x0000a2cc, 0x18c43433}, | ||
263 | {0x0000a2d4, 0x00000000}, | ||
264 | {0x0000a2ec, 0x00000000}, | ||
265 | {0x0000a2f0, 0x00000000}, | ||
266 | {0x0000a2f4, 0x00000000}, | ||
267 | {0x0000a2f8, 0x00000000}, | ||
268 | {0x0000a344, 0x00000000}, | ||
269 | {0x0000a34c, 0x00000000}, | ||
270 | {0x0000a350, 0x0000a000}, | ||
271 | {0x0000a364, 0x00000000}, | ||
272 | {0x0000a370, 0x00000000}, | ||
273 | {0x0000a390, 0x00000001}, | ||
274 | {0x0000a394, 0x00000444}, | ||
275 | {0x0000a398, 0x001f0e0f}, | ||
276 | {0x0000a39c, 0x0075393f}, | ||
277 | {0x0000a3a0, 0xb79f6427}, | ||
278 | {0x0000a3c0, 0x20202020}, | ||
279 | {0x0000a3c4, 0x22222220}, | ||
280 | {0x0000a3c8, 0x20200020}, | ||
281 | {0x0000a3cc, 0x20202020}, | ||
282 | {0x0000a3d0, 0x20202020}, | ||
283 | {0x0000a3d4, 0x20202020}, | ||
284 | {0x0000a3d8, 0x20202020}, | ||
285 | {0x0000a3dc, 0x20202020}, | ||
286 | {0x0000a3e0, 0x20202020}, | ||
287 | {0x0000a3e4, 0x20202020}, | ||
288 | {0x0000a3e8, 0x20202020}, | ||
289 | {0x0000a3ec, 0x20202020}, | ||
290 | {0x0000a3f0, 0x00000000}, | ||
291 | {0x0000a3f4, 0x00000006}, | ||
292 | {0x0000a3f8, 0x0c9bd380}, | ||
293 | {0x0000a3fc, 0x000f0f01}, | ||
294 | {0x0000a400, 0x8fa91f01}, | ||
295 | {0x0000a404, 0x00000000}, | ||
296 | {0x0000a408, 0x0e79e5c6}, | ||
297 | {0x0000a40c, 0x00820820}, | ||
298 | {0x0000a414, 0x1ce739ce}, | ||
299 | {0x0000a418, 0x2d001dce}, | ||
300 | {0x0000a434, 0x00000000}, | ||
301 | {0x0000a438, 0x00001801}, | ||
302 | {0x0000a43c, 0x00100000}, | ||
303 | {0x0000a444, 0x00000000}, | ||
304 | {0x0000a448, 0x05000080}, | ||
305 | {0x0000a44c, 0x00000001}, | ||
306 | {0x0000a450, 0x00010000}, | ||
307 | {0x0000a454, 0x07000000}, | ||
308 | {0x0000a644, 0xbfad9d74}, | ||
309 | {0x0000a648, 0x0048060a}, | ||
310 | {0x0000a64c, 0x00002037}, | ||
311 | {0x0000a670, 0x03020100}, | ||
312 | {0x0000a674, 0x09080504}, | ||
313 | {0x0000a678, 0x0d0c0b0a}, | ||
314 | {0x0000a67c, 0x13121110}, | ||
315 | {0x0000a680, 0x31301514}, | ||
316 | {0x0000a684, 0x35343332}, | ||
317 | {0x0000a688, 0x00000036}, | ||
318 | {0x0000a690, 0x00000838}, | ||
319 | {0x0000a6b0, 0x0000000a}, | ||
320 | {0x0000a6b4, 0x00512c01}, | ||
321 | {0x0000a7c0, 0x00000000}, | ||
322 | {0x0000a7c4, 0xfffffffc}, | ||
323 | {0x0000a7c8, 0x00000000}, | ||
324 | {0x0000a7cc, 0x00000000}, | ||
325 | {0x0000a7d0, 0x00000000}, | ||
326 | {0x0000a7d4, 0x00000004}, | ||
327 | {0x0000a7dc, 0x00000000}, | ||
328 | {0x0000a7f0, 0x80000000}, | ||
329 | {0x0000a8d0, 0x004b6a8e}, | ||
330 | {0x0000a8d4, 0x00000820}, | ||
331 | {0x0000a8dc, 0x00000000}, | ||
332 | {0x0000a8f0, 0x00000000}, | ||
333 | {0x0000a8f4, 0x00000000}, | ||
334 | {0x0000abf0, 0x80000000}, | ||
335 | {0x0000b2d0, 0x00000080}, | ||
336 | {0x0000b2d4, 0x00000000}, | ||
337 | {0x0000b2ec, 0x00000000}, | ||
338 | {0x0000b2f0, 0x00000000}, | ||
339 | {0x0000b2f4, 0x00000000}, | ||
340 | {0x0000b2f8, 0x00000000}, | ||
341 | {0x0000b408, 0x0e79e5c0}, | ||
342 | {0x0000b40c, 0x00820820}, | ||
343 | {0x0000b420, 0x00000000}, | ||
344 | {0x0000b6b0, 0x0000000a}, | ||
345 | {0x0000b6b4, 0x00000001}, | ||
346 | }; | ||
347 | |||
348 | static const u32 ar9462_2p1_baseband_postamble[][5] = { | ||
349 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
350 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, | ||
351 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, | ||
352 | {0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, | ||
353 | {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81}, | ||
354 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
355 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | ||
356 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, | ||
357 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2}, | ||
358 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | ||
359 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, | ||
360 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, | ||
361 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, | ||
362 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
363 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
364 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
365 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
366 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | ||
367 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, | ||
368 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
369 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
370 | {0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0}, | ||
371 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
372 | {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, | ||
373 | {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, | ||
374 | {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, | ||
375 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
376 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
377 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
378 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
379 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
380 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | ||
381 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
382 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
383 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
384 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, | ||
385 | {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, | ||
386 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
387 | {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, | ||
388 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, | ||
389 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
390 | {0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000}, | ||
391 | {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}, | ||
392 | {0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00}, | ||
393 | {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
394 | {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, | ||
395 | {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
396 | {0x0000a428, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, | ||
397 | {0x0000a42c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
398 | {0x0000a430, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
399 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
400 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | ||
401 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
402 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
403 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
404 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, | ||
405 | }; | ||
406 | |||
407 | static const u32 ar9462_2p1_radio_core[][2] = { | ||
408 | /* Addr allmodes */ | ||
409 | {0x00016000, 0x36db6db6}, | ||
410 | {0x00016004, 0x6db6db40}, | ||
411 | {0x00016008, 0x73f00000}, | ||
412 | {0x0001600c, 0x00000000}, | ||
413 | {0x00016010, 0x6d820001}, | ||
414 | {0x00016040, 0x7f80fff8}, | ||
415 | {0x0001604c, 0x2699e04f}, | ||
416 | {0x00016050, 0x6db6db6c}, | ||
417 | {0x00016058, 0x6c200000}, | ||
418 | {0x00016080, 0x000c0000}, | ||
419 | {0x00016084, 0x9a68048c}, | ||
420 | {0x00016088, 0x54214514}, | ||
421 | {0x0001608c, 0x1203040b}, | ||
422 | {0x00016090, 0x24926490}, | ||
423 | {0x00016098, 0xd2888888}, | ||
424 | {0x000160a0, 0x0a108ffe}, | ||
425 | {0x000160a4, 0x812fc491}, | ||
426 | {0x000160a8, 0x423c8000}, | ||
427 | {0x000160b4, 0x92000000}, | ||
428 | {0x000160b8, 0x0285dddc}, | ||
429 | {0x000160bc, 0x02908888}, | ||
430 | {0x000160c0, 0x00adb6d0}, | ||
431 | {0x000160c4, 0x6db6db60}, | ||
432 | {0x000160c8, 0x6db6db6c}, | ||
433 | {0x000160cc, 0x0de6c1b0}, | ||
434 | {0x00016100, 0x3fffbe04}, | ||
435 | {0x00016104, 0xfff80000}, | ||
436 | {0x00016108, 0x00200400}, | ||
437 | {0x00016110, 0x00000000}, | ||
438 | {0x00016144, 0x02084080}, | ||
439 | {0x00016148, 0x000080c0}, | ||
440 | {0x00016280, 0x050a0001}, | ||
441 | {0x00016284, 0x3d841418}, | ||
442 | {0x00016288, 0x00000000}, | ||
443 | {0x0001628c, 0xe3000000}, | ||
444 | {0x00016290, 0xa1005080}, | ||
445 | {0x00016294, 0x00000020}, | ||
446 | {0x00016298, 0x54a82900}, | ||
447 | {0x00016340, 0x121e4276}, | ||
448 | {0x00016344, 0x00300000}, | ||
449 | {0x00016400, 0x36db6db6}, | ||
450 | {0x00016404, 0x6db6db40}, | ||
451 | {0x00016408, 0x73f00000}, | ||
452 | {0x0001640c, 0x00000000}, | ||
453 | {0x00016410, 0x6c800001}, | ||
454 | {0x00016440, 0x7f80fff8}, | ||
455 | {0x0001644c, 0x4699e04f}, | ||
456 | {0x00016450, 0x6db6db6c}, | ||
457 | {0x00016500, 0x3fffbe04}, | ||
458 | {0x00016504, 0xfff80000}, | ||
459 | {0x00016508, 0x00200400}, | ||
460 | {0x00016510, 0x00000000}, | ||
461 | {0x00016544, 0x02084080}, | ||
462 | {0x00016548, 0x000080c0}, | ||
463 | }; | ||
464 | |||
465 | static const u32 ar9462_2p1_radio_postamble[][5] = { | ||
466 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
467 | {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, | ||
468 | {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, | ||
469 | {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, | ||
470 | {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, | ||
471 | }; | ||
472 | |||
473 | static const u32 ar9462_2p1_soc_preamble[][2] = { | ||
474 | /* Addr allmodes */ | ||
475 | {0x000040a4, 0x00a0c1c9}, | ||
476 | {0x00007020, 0x00000000}, | ||
477 | {0x00007034, 0x00000002}, | ||
478 | {0x00007038, 0x000004c2}, | ||
479 | }; | ||
480 | |||
481 | static const u32 ar9462_2p1_soc_postamble[][5] = { | ||
482 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
483 | {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, | ||
484 | }; | ||
485 | |||
486 | static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = { | ||
487 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
488 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, | ||
489 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, | ||
490 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, | ||
491 | }; | ||
492 | |||
493 | static const u32 ar9462_2p1_common_rx_gain[][2] = { | ||
494 | /* Addr allmodes */ | ||
495 | {0x0000a000, 0x00010000}, | ||
496 | {0x0000a004, 0x00030002}, | ||
497 | {0x0000a008, 0x00050004}, | ||
498 | {0x0000a00c, 0x00810080}, | ||
499 | {0x0000a010, 0x00830082}, | ||
500 | {0x0000a014, 0x01810180}, | ||
501 | {0x0000a018, 0x01830182}, | ||
502 | {0x0000a01c, 0x01850184}, | ||
503 | {0x0000a020, 0x01890188}, | ||
504 | {0x0000a024, 0x018b018a}, | ||
505 | {0x0000a028, 0x018d018c}, | ||
506 | {0x0000a02c, 0x01910190}, | ||
507 | {0x0000a030, 0x01930192}, | ||
508 | {0x0000a034, 0x01950194}, | ||
509 | {0x0000a038, 0x038a0196}, | ||
510 | {0x0000a03c, 0x038c038b}, | ||
511 | {0x0000a040, 0x0390038d}, | ||
512 | {0x0000a044, 0x03920391}, | ||
513 | {0x0000a048, 0x03940393}, | ||
514 | {0x0000a04c, 0x03960395}, | ||
515 | {0x0000a050, 0x00000000}, | ||
516 | {0x0000a054, 0x00000000}, | ||
517 | {0x0000a058, 0x00000000}, | ||
518 | {0x0000a05c, 0x00000000}, | ||
519 | {0x0000a060, 0x00000000}, | ||
520 | {0x0000a064, 0x00000000}, | ||
521 | {0x0000a068, 0x00000000}, | ||
522 | {0x0000a06c, 0x00000000}, | ||
523 | {0x0000a070, 0x00000000}, | ||
524 | {0x0000a074, 0x00000000}, | ||
525 | {0x0000a078, 0x00000000}, | ||
526 | {0x0000a07c, 0x00000000}, | ||
527 | {0x0000a080, 0x22222229}, | ||
528 | {0x0000a084, 0x1d1d1d1d}, | ||
529 | {0x0000a088, 0x1d1d1d1d}, | ||
530 | {0x0000a08c, 0x1d1d1d1d}, | ||
531 | {0x0000a090, 0x171d1d1d}, | ||
532 | {0x0000a094, 0x11111717}, | ||
533 | {0x0000a098, 0x00030311}, | ||
534 | {0x0000a09c, 0x00000000}, | ||
535 | {0x0000a0a0, 0x00000000}, | ||
536 | {0x0000a0a4, 0x00000000}, | ||
537 | {0x0000a0a8, 0x00000000}, | ||
538 | {0x0000a0ac, 0x00000000}, | ||
539 | {0x0000a0b0, 0x00000000}, | ||
540 | {0x0000a0b4, 0x00000000}, | ||
541 | {0x0000a0b8, 0x00000000}, | ||
542 | {0x0000a0bc, 0x00000000}, | ||
543 | {0x0000a0c0, 0x001f0000}, | ||
544 | {0x0000a0c4, 0x01000101}, | ||
545 | {0x0000a0c8, 0x011e011f}, | ||
546 | {0x0000a0cc, 0x011c011d}, | ||
547 | {0x0000a0d0, 0x02030204}, | ||
548 | {0x0000a0d4, 0x02010202}, | ||
549 | {0x0000a0d8, 0x021f0200}, | ||
550 | {0x0000a0dc, 0x0302021e}, | ||
551 | {0x0000a0e0, 0x03000301}, | ||
552 | {0x0000a0e4, 0x031e031f}, | ||
553 | {0x0000a0e8, 0x0402031d}, | ||
554 | {0x0000a0ec, 0x04000401}, | ||
555 | {0x0000a0f0, 0x041e041f}, | ||
556 | {0x0000a0f4, 0x0502041d}, | ||
557 | {0x0000a0f8, 0x05000501}, | ||
558 | {0x0000a0fc, 0x051e051f}, | ||
559 | {0x0000a100, 0x06010602}, | ||
560 | {0x0000a104, 0x061f0600}, | ||
561 | {0x0000a108, 0x061d061e}, | ||
562 | {0x0000a10c, 0x07020703}, | ||
563 | {0x0000a110, 0x07000701}, | ||
564 | {0x0000a114, 0x00000000}, | ||
565 | {0x0000a118, 0x00000000}, | ||
566 | {0x0000a11c, 0x00000000}, | ||
567 | {0x0000a120, 0x00000000}, | ||
568 | {0x0000a124, 0x00000000}, | ||
569 | {0x0000a128, 0x00000000}, | ||
570 | {0x0000a12c, 0x00000000}, | ||
571 | {0x0000a130, 0x00000000}, | ||
572 | {0x0000a134, 0x00000000}, | ||
573 | {0x0000a138, 0x00000000}, | ||
574 | {0x0000a13c, 0x00000000}, | ||
575 | {0x0000a140, 0x001f0000}, | ||
576 | {0x0000a144, 0x01000101}, | ||
577 | {0x0000a148, 0x011e011f}, | ||
578 | {0x0000a14c, 0x011c011d}, | ||
579 | {0x0000a150, 0x02030204}, | ||
580 | {0x0000a154, 0x02010202}, | ||
581 | {0x0000a158, 0x021f0200}, | ||
582 | {0x0000a15c, 0x0302021e}, | ||
583 | {0x0000a160, 0x03000301}, | ||
584 | {0x0000a164, 0x031e031f}, | ||
585 | {0x0000a168, 0x0402031d}, | ||
586 | {0x0000a16c, 0x04000401}, | ||
587 | {0x0000a170, 0x041e041f}, | ||
588 | {0x0000a174, 0x0502041d}, | ||
589 | {0x0000a178, 0x05000501}, | ||
590 | {0x0000a17c, 0x051e051f}, | ||
591 | {0x0000a180, 0x06010602}, | ||
592 | {0x0000a184, 0x061f0600}, | ||
593 | {0x0000a188, 0x061d061e}, | ||
594 | {0x0000a18c, 0x07020703}, | ||
595 | {0x0000a190, 0x07000701}, | ||
596 | {0x0000a194, 0x00000000}, | ||
597 | {0x0000a198, 0x00000000}, | ||
598 | {0x0000a19c, 0x00000000}, | ||
599 | {0x0000a1a0, 0x00000000}, | ||
600 | {0x0000a1a4, 0x00000000}, | ||
601 | {0x0000a1a8, 0x00000000}, | ||
602 | {0x0000a1ac, 0x00000000}, | ||
603 | {0x0000a1b0, 0x00000000}, | ||
604 | {0x0000a1b4, 0x00000000}, | ||
605 | {0x0000a1b8, 0x00000000}, | ||
606 | {0x0000a1bc, 0x00000000}, | ||
607 | {0x0000a1c0, 0x00000000}, | ||
608 | {0x0000a1c4, 0x00000000}, | ||
609 | {0x0000a1c8, 0x00000000}, | ||
610 | {0x0000a1cc, 0x00000000}, | ||
611 | {0x0000a1d0, 0x00000000}, | ||
612 | {0x0000a1d4, 0x00000000}, | ||
613 | {0x0000a1d8, 0x00000000}, | ||
614 | {0x0000a1dc, 0x00000000}, | ||
615 | {0x0000a1e0, 0x00000000}, | ||
616 | {0x0000a1e4, 0x00000000}, | ||
617 | {0x0000a1e8, 0x00000000}, | ||
618 | {0x0000a1ec, 0x00000000}, | ||
619 | {0x0000a1f0, 0x00000396}, | ||
620 | {0x0000a1f4, 0x00000396}, | ||
621 | {0x0000a1f8, 0x00000396}, | ||
622 | {0x0000a1fc, 0x00000196}, | ||
623 | {0x0000b000, 0x00010000}, | ||
624 | {0x0000b004, 0x00030002}, | ||
625 | {0x0000b008, 0x00050004}, | ||
626 | {0x0000b00c, 0x00810080}, | ||
627 | {0x0000b010, 0x00830082}, | ||
628 | {0x0000b014, 0x01810180}, | ||
629 | {0x0000b018, 0x01830182}, | ||
630 | {0x0000b01c, 0x01850184}, | ||
631 | {0x0000b020, 0x02810280}, | ||
632 | {0x0000b024, 0x02830282}, | ||
633 | {0x0000b028, 0x02850284}, | ||
634 | {0x0000b02c, 0x02890288}, | ||
635 | {0x0000b030, 0x028b028a}, | ||
636 | {0x0000b034, 0x0388028c}, | ||
637 | {0x0000b038, 0x038a0389}, | ||
638 | {0x0000b03c, 0x038c038b}, | ||
639 | {0x0000b040, 0x0390038d}, | ||
640 | {0x0000b044, 0x03920391}, | ||
641 | {0x0000b048, 0x03940393}, | ||
642 | {0x0000b04c, 0x03960395}, | ||
643 | {0x0000b050, 0x00000000}, | ||
644 | {0x0000b054, 0x00000000}, | ||
645 | {0x0000b058, 0x00000000}, | ||
646 | {0x0000b05c, 0x00000000}, | ||
647 | {0x0000b060, 0x00000000}, | ||
648 | {0x0000b064, 0x00000000}, | ||
649 | {0x0000b068, 0x00000000}, | ||
650 | {0x0000b06c, 0x00000000}, | ||
651 | {0x0000b070, 0x00000000}, | ||
652 | {0x0000b074, 0x00000000}, | ||
653 | {0x0000b078, 0x00000000}, | ||
654 | {0x0000b07c, 0x00000000}, | ||
655 | {0x0000b080, 0x2a2d2f32}, | ||
656 | {0x0000b084, 0x21232328}, | ||
657 | {0x0000b088, 0x19191c1e}, | ||
658 | {0x0000b08c, 0x12141417}, | ||
659 | {0x0000b090, 0x07070e0e}, | ||
660 | {0x0000b094, 0x03030305}, | ||
661 | {0x0000b098, 0x00000003}, | ||
662 | {0x0000b09c, 0x00000000}, | ||
663 | {0x0000b0a0, 0x00000000}, | ||
664 | {0x0000b0a4, 0x00000000}, | ||
665 | {0x0000b0a8, 0x00000000}, | ||
666 | {0x0000b0ac, 0x00000000}, | ||
667 | {0x0000b0b0, 0x00000000}, | ||
668 | {0x0000b0b4, 0x00000000}, | ||
669 | {0x0000b0b8, 0x00000000}, | ||
670 | {0x0000b0bc, 0x00000000}, | ||
671 | {0x0000b0c0, 0x003f0020}, | ||
672 | {0x0000b0c4, 0x00400041}, | ||
673 | {0x0000b0c8, 0x0140005f}, | ||
674 | {0x0000b0cc, 0x0160015f}, | ||
675 | {0x0000b0d0, 0x017e017f}, | ||
676 | {0x0000b0d4, 0x02410242}, | ||
677 | {0x0000b0d8, 0x025f0240}, | ||
678 | {0x0000b0dc, 0x027f0260}, | ||
679 | {0x0000b0e0, 0x0341027e}, | ||
680 | {0x0000b0e4, 0x035f0340}, | ||
681 | {0x0000b0e8, 0x037f0360}, | ||
682 | {0x0000b0ec, 0x04400441}, | ||
683 | {0x0000b0f0, 0x0460045f}, | ||
684 | {0x0000b0f4, 0x0541047f}, | ||
685 | {0x0000b0f8, 0x055f0540}, | ||
686 | {0x0000b0fc, 0x057f0560}, | ||
687 | {0x0000b100, 0x06400641}, | ||
688 | {0x0000b104, 0x0660065f}, | ||
689 | {0x0000b108, 0x067e067f}, | ||
690 | {0x0000b10c, 0x07410742}, | ||
691 | {0x0000b110, 0x075f0740}, | ||
692 | {0x0000b114, 0x077f0760}, | ||
693 | {0x0000b118, 0x07800781}, | ||
694 | {0x0000b11c, 0x07a0079f}, | ||
695 | {0x0000b120, 0x07c107bf}, | ||
696 | {0x0000b124, 0x000007c0}, | ||
697 | {0x0000b128, 0x00000000}, | ||
698 | {0x0000b12c, 0x00000000}, | ||
699 | {0x0000b130, 0x00000000}, | ||
700 | {0x0000b134, 0x00000000}, | ||
701 | {0x0000b138, 0x00000000}, | ||
702 | {0x0000b13c, 0x00000000}, | ||
703 | {0x0000b140, 0x003f0020}, | ||
704 | {0x0000b144, 0x00400041}, | ||
705 | {0x0000b148, 0x0140005f}, | ||
706 | {0x0000b14c, 0x0160015f}, | ||
707 | {0x0000b150, 0x017e017f}, | ||
708 | {0x0000b154, 0x02410242}, | ||
709 | {0x0000b158, 0x025f0240}, | ||
710 | {0x0000b15c, 0x027f0260}, | ||
711 | {0x0000b160, 0x0341027e}, | ||
712 | {0x0000b164, 0x035f0340}, | ||
713 | {0x0000b168, 0x037f0360}, | ||
714 | {0x0000b16c, 0x04400441}, | ||
715 | {0x0000b170, 0x0460045f}, | ||
716 | {0x0000b174, 0x0541047f}, | ||
717 | {0x0000b178, 0x055f0540}, | ||
718 | {0x0000b17c, 0x057f0560}, | ||
719 | {0x0000b180, 0x06400641}, | ||
720 | {0x0000b184, 0x0660065f}, | ||
721 | {0x0000b188, 0x067e067f}, | ||
722 | {0x0000b18c, 0x07410742}, | ||
723 | {0x0000b190, 0x075f0740}, | ||
724 | {0x0000b194, 0x077f0760}, | ||
725 | {0x0000b198, 0x07800781}, | ||
726 | {0x0000b19c, 0x07a0079f}, | ||
727 | {0x0000b1a0, 0x07c107bf}, | ||
728 | {0x0000b1a4, 0x000007c0}, | ||
729 | {0x0000b1a8, 0x00000000}, | ||
730 | {0x0000b1ac, 0x00000000}, | ||
731 | {0x0000b1b0, 0x00000000}, | ||
732 | {0x0000b1b4, 0x00000000}, | ||
733 | {0x0000b1b8, 0x00000000}, | ||
734 | {0x0000b1bc, 0x00000000}, | ||
735 | {0x0000b1c0, 0x00000000}, | ||
736 | {0x0000b1c4, 0x00000000}, | ||
737 | {0x0000b1c8, 0x00000000}, | ||
738 | {0x0000b1cc, 0x00000000}, | ||
739 | {0x0000b1d0, 0x00000000}, | ||
740 | {0x0000b1d4, 0x00000000}, | ||
741 | {0x0000b1d8, 0x00000000}, | ||
742 | {0x0000b1dc, 0x00000000}, | ||
743 | {0x0000b1e0, 0x00000000}, | ||
744 | {0x0000b1e4, 0x00000000}, | ||
745 | {0x0000b1e8, 0x00000000}, | ||
746 | {0x0000b1ec, 0x00000000}, | ||
747 | {0x0000b1f0, 0x00000396}, | ||
748 | {0x0000b1f4, 0x00000396}, | ||
749 | {0x0000b1f8, 0x00000396}, | ||
750 | {0x0000b1fc, 0x00000196}, | ||
751 | }; | ||
752 | |||
753 | static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = { | ||
754 | /* Addr allmodes */ | ||
755 | {0x0000a000, 0x00010000}, | ||
756 | {0x0000a004, 0x00030002}, | ||
757 | {0x0000a008, 0x00050004}, | ||
758 | {0x0000a00c, 0x00810080}, | ||
759 | {0x0000a010, 0x00830082}, | ||
760 | {0x0000a014, 0x01810180}, | ||
761 | {0x0000a018, 0x01830182}, | ||
762 | {0x0000a01c, 0x01850184}, | ||
763 | {0x0000a020, 0x01890188}, | ||
764 | {0x0000a024, 0x018b018a}, | ||
765 | {0x0000a028, 0x018d018c}, | ||
766 | {0x0000a02c, 0x03820190}, | ||
767 | {0x0000a030, 0x03840383}, | ||
768 | {0x0000a034, 0x03880385}, | ||
769 | {0x0000a038, 0x038a0389}, | ||
770 | {0x0000a03c, 0x038c038b}, | ||
771 | {0x0000a040, 0x0390038d}, | ||
772 | {0x0000a044, 0x03920391}, | ||
773 | {0x0000a048, 0x03940393}, | ||
774 | {0x0000a04c, 0x03960395}, | ||
775 | {0x0000a050, 0x00000000}, | ||
776 | {0x0000a054, 0x00000000}, | ||
777 | {0x0000a058, 0x00000000}, | ||
778 | {0x0000a05c, 0x00000000}, | ||
779 | {0x0000a060, 0x00000000}, | ||
780 | {0x0000a064, 0x00000000}, | ||
781 | {0x0000a068, 0x00000000}, | ||
782 | {0x0000a06c, 0x00000000}, | ||
783 | {0x0000a070, 0x00000000}, | ||
784 | {0x0000a074, 0x00000000}, | ||
785 | {0x0000a078, 0x00000000}, | ||
786 | {0x0000a07c, 0x00000000}, | ||
787 | {0x0000a080, 0x29292929}, | ||
788 | {0x0000a084, 0x29292929}, | ||
789 | {0x0000a088, 0x29292929}, | ||
790 | {0x0000a08c, 0x29292929}, | ||
791 | {0x0000a090, 0x22292929}, | ||
792 | {0x0000a094, 0x1d1d2222}, | ||
793 | {0x0000a098, 0x0c111117}, | ||
794 | {0x0000a09c, 0x00030303}, | ||
795 | {0x0000a0a0, 0x00000000}, | ||
796 | {0x0000a0a4, 0x00000000}, | ||
797 | {0x0000a0a8, 0x00000000}, | ||
798 | {0x0000a0ac, 0x00000000}, | ||
799 | {0x0000a0b0, 0x00000000}, | ||
800 | {0x0000a0b4, 0x00000000}, | ||
801 | {0x0000a0b8, 0x00000000}, | ||
802 | {0x0000a0bc, 0x00000000}, | ||
803 | {0x0000a0c0, 0x001f0000}, | ||
804 | {0x0000a0c4, 0x01000101}, | ||
805 | {0x0000a0c8, 0x011e011f}, | ||
806 | {0x0000a0cc, 0x011c011d}, | ||
807 | {0x0000a0d0, 0x02030204}, | ||
808 | {0x0000a0d4, 0x02010202}, | ||
809 | {0x0000a0d8, 0x021f0200}, | ||
810 | {0x0000a0dc, 0x0302021e}, | ||
811 | {0x0000a0e0, 0x03000301}, | ||
812 | {0x0000a0e4, 0x031e031f}, | ||
813 | {0x0000a0e8, 0x0402031d}, | ||
814 | {0x0000a0ec, 0x04000401}, | ||
815 | {0x0000a0f0, 0x041e041f}, | ||
816 | {0x0000a0f4, 0x0502041d}, | ||
817 | {0x0000a0f8, 0x05000501}, | ||
818 | {0x0000a0fc, 0x051e051f}, | ||
819 | {0x0000a100, 0x06010602}, | ||
820 | {0x0000a104, 0x061f0600}, | ||
821 | {0x0000a108, 0x061d061e}, | ||
822 | {0x0000a10c, 0x07020703}, | ||
823 | {0x0000a110, 0x07000701}, | ||
824 | {0x0000a114, 0x00000000}, | ||
825 | {0x0000a118, 0x00000000}, | ||
826 | {0x0000a11c, 0x00000000}, | ||
827 | {0x0000a120, 0x00000000}, | ||
828 | {0x0000a124, 0x00000000}, | ||
829 | {0x0000a128, 0x00000000}, | ||
830 | {0x0000a12c, 0x00000000}, | ||
831 | {0x0000a130, 0x00000000}, | ||
832 | {0x0000a134, 0x00000000}, | ||
833 | {0x0000a138, 0x00000000}, | ||
834 | {0x0000a13c, 0x00000000}, | ||
835 | {0x0000a140, 0x001f0000}, | ||
836 | {0x0000a144, 0x01000101}, | ||
837 | {0x0000a148, 0x011e011f}, | ||
838 | {0x0000a14c, 0x011c011d}, | ||
839 | {0x0000a150, 0x02030204}, | ||
840 | {0x0000a154, 0x02010202}, | ||
841 | {0x0000a158, 0x021f0200}, | ||
842 | {0x0000a15c, 0x0302021e}, | ||
843 | {0x0000a160, 0x03000301}, | ||
844 | {0x0000a164, 0x031e031f}, | ||
845 | {0x0000a168, 0x0402031d}, | ||
846 | {0x0000a16c, 0x04000401}, | ||
847 | {0x0000a170, 0x041e041f}, | ||
848 | {0x0000a174, 0x0502041d}, | ||
849 | {0x0000a178, 0x05000501}, | ||
850 | {0x0000a17c, 0x051e051f}, | ||
851 | {0x0000a180, 0x06010602}, | ||
852 | {0x0000a184, 0x061f0600}, | ||
853 | {0x0000a188, 0x061d061e}, | ||
854 | {0x0000a18c, 0x07020703}, | ||
855 | {0x0000a190, 0x07000701}, | ||
856 | {0x0000a194, 0x00000000}, | ||
857 | {0x0000a198, 0x00000000}, | ||
858 | {0x0000a19c, 0x00000000}, | ||
859 | {0x0000a1a0, 0x00000000}, | ||
860 | {0x0000a1a4, 0x00000000}, | ||
861 | {0x0000a1a8, 0x00000000}, | ||
862 | {0x0000a1ac, 0x00000000}, | ||
863 | {0x0000a1b0, 0x00000000}, | ||
864 | {0x0000a1b4, 0x00000000}, | ||
865 | {0x0000a1b8, 0x00000000}, | ||
866 | {0x0000a1bc, 0x00000000}, | ||
867 | {0x0000a1c0, 0x00000000}, | ||
868 | {0x0000a1c4, 0x00000000}, | ||
869 | {0x0000a1c8, 0x00000000}, | ||
870 | {0x0000a1cc, 0x00000000}, | ||
871 | {0x0000a1d0, 0x00000000}, | ||
872 | {0x0000a1d4, 0x00000000}, | ||
873 | {0x0000a1d8, 0x00000000}, | ||
874 | {0x0000a1dc, 0x00000000}, | ||
875 | {0x0000a1e0, 0x00000000}, | ||
876 | {0x0000a1e4, 0x00000000}, | ||
877 | {0x0000a1e8, 0x00000000}, | ||
878 | {0x0000a1ec, 0x00000000}, | ||
879 | {0x0000a1f0, 0x00000396}, | ||
880 | {0x0000a1f4, 0x00000396}, | ||
881 | {0x0000a1f8, 0x00000396}, | ||
882 | {0x0000a1fc, 0x00000196}, | ||
883 | {0x0000b000, 0x00010000}, | ||
884 | {0x0000b004, 0x00030002}, | ||
885 | {0x0000b008, 0x00050004}, | ||
886 | {0x0000b00c, 0x00810080}, | ||
887 | {0x0000b010, 0x00830082}, | ||
888 | {0x0000b014, 0x01810180}, | ||
889 | {0x0000b018, 0x01830182}, | ||
890 | {0x0000b01c, 0x01850184}, | ||
891 | {0x0000b020, 0x02810280}, | ||
892 | {0x0000b024, 0x02830282}, | ||
893 | {0x0000b028, 0x02850284}, | ||
894 | {0x0000b02c, 0x02890288}, | ||
895 | {0x0000b030, 0x028b028a}, | ||
896 | {0x0000b034, 0x0388028c}, | ||
897 | {0x0000b038, 0x038a0389}, | ||
898 | {0x0000b03c, 0x038c038b}, | ||
899 | {0x0000b040, 0x0390038d}, | ||
900 | {0x0000b044, 0x03920391}, | ||
901 | {0x0000b048, 0x03940393}, | ||
902 | {0x0000b04c, 0x03960395}, | ||
903 | {0x0000b050, 0x00000000}, | ||
904 | {0x0000b054, 0x00000000}, | ||
905 | {0x0000b058, 0x00000000}, | ||
906 | {0x0000b05c, 0x00000000}, | ||
907 | {0x0000b060, 0x00000000}, | ||
908 | {0x0000b064, 0x00000000}, | ||
909 | {0x0000b068, 0x00000000}, | ||
910 | {0x0000b06c, 0x00000000}, | ||
911 | {0x0000b070, 0x00000000}, | ||
912 | {0x0000b074, 0x00000000}, | ||
913 | {0x0000b078, 0x00000000}, | ||
914 | {0x0000b07c, 0x00000000}, | ||
915 | {0x0000b080, 0x2a2d2f32}, | ||
916 | {0x0000b084, 0x21232328}, | ||
917 | {0x0000b088, 0x19191c1e}, | ||
918 | {0x0000b08c, 0x12141417}, | ||
919 | {0x0000b090, 0x07070e0e}, | ||
920 | {0x0000b094, 0x03030305}, | ||
921 | {0x0000b098, 0x00000003}, | ||
922 | {0x0000b09c, 0x00000000}, | ||
923 | {0x0000b0a0, 0x00000000}, | ||
924 | {0x0000b0a4, 0x00000000}, | ||
925 | {0x0000b0a8, 0x00000000}, | ||
926 | {0x0000b0ac, 0x00000000}, | ||
927 | {0x0000b0b0, 0x00000000}, | ||
928 | {0x0000b0b4, 0x00000000}, | ||
929 | {0x0000b0b8, 0x00000000}, | ||
930 | {0x0000b0bc, 0x00000000}, | ||
931 | {0x0000b0c0, 0x003f0020}, | ||
932 | {0x0000b0c4, 0x00400041}, | ||
933 | {0x0000b0c8, 0x0140005f}, | ||
934 | {0x0000b0cc, 0x0160015f}, | ||
935 | {0x0000b0d0, 0x017e017f}, | ||
936 | {0x0000b0d4, 0x02410242}, | ||
937 | {0x0000b0d8, 0x025f0240}, | ||
938 | {0x0000b0dc, 0x027f0260}, | ||
939 | {0x0000b0e0, 0x0341027e}, | ||
940 | {0x0000b0e4, 0x035f0340}, | ||
941 | {0x0000b0e8, 0x037f0360}, | ||
942 | {0x0000b0ec, 0x04400441}, | ||
943 | {0x0000b0f0, 0x0460045f}, | ||
944 | {0x0000b0f4, 0x0541047f}, | ||
945 | {0x0000b0f8, 0x055f0540}, | ||
946 | {0x0000b0fc, 0x057f0560}, | ||
947 | {0x0000b100, 0x06400641}, | ||
948 | {0x0000b104, 0x0660065f}, | ||
949 | {0x0000b108, 0x067e067f}, | ||
950 | {0x0000b10c, 0x07410742}, | ||
951 | {0x0000b110, 0x075f0740}, | ||
952 | {0x0000b114, 0x077f0760}, | ||
953 | {0x0000b118, 0x07800781}, | ||
954 | {0x0000b11c, 0x07a0079f}, | ||
955 | {0x0000b120, 0x07c107bf}, | ||
956 | {0x0000b124, 0x000007c0}, | ||
957 | {0x0000b128, 0x00000000}, | ||
958 | {0x0000b12c, 0x00000000}, | ||
959 | {0x0000b130, 0x00000000}, | ||
960 | {0x0000b134, 0x00000000}, | ||
961 | {0x0000b138, 0x00000000}, | ||
962 | {0x0000b13c, 0x00000000}, | ||
963 | {0x0000b140, 0x003f0020}, | ||
964 | {0x0000b144, 0x00400041}, | ||
965 | {0x0000b148, 0x0140005f}, | ||
966 | {0x0000b14c, 0x0160015f}, | ||
967 | {0x0000b150, 0x017e017f}, | ||
968 | {0x0000b154, 0x02410242}, | ||
969 | {0x0000b158, 0x025f0240}, | ||
970 | {0x0000b15c, 0x027f0260}, | ||
971 | {0x0000b160, 0x0341027e}, | ||
972 | {0x0000b164, 0x035f0340}, | ||
973 | {0x0000b168, 0x037f0360}, | ||
974 | {0x0000b16c, 0x04400441}, | ||
975 | {0x0000b170, 0x0460045f}, | ||
976 | {0x0000b174, 0x0541047f}, | ||
977 | {0x0000b178, 0x055f0540}, | ||
978 | {0x0000b17c, 0x057f0560}, | ||
979 | {0x0000b180, 0x06400641}, | ||
980 | {0x0000b184, 0x0660065f}, | ||
981 | {0x0000b188, 0x067e067f}, | ||
982 | {0x0000b18c, 0x07410742}, | ||
983 | {0x0000b190, 0x075f0740}, | ||
984 | {0x0000b194, 0x077f0760}, | ||
985 | {0x0000b198, 0x07800781}, | ||
986 | {0x0000b19c, 0x07a0079f}, | ||
987 | {0x0000b1a0, 0x07c107bf}, | ||
988 | {0x0000b1a4, 0x000007c0}, | ||
989 | {0x0000b1a8, 0x00000000}, | ||
990 | {0x0000b1ac, 0x00000000}, | ||
991 | {0x0000b1b0, 0x00000000}, | ||
992 | {0x0000b1b4, 0x00000000}, | ||
993 | {0x0000b1b8, 0x00000000}, | ||
994 | {0x0000b1bc, 0x00000000}, | ||
995 | {0x0000b1c0, 0x00000000}, | ||
996 | {0x0000b1c4, 0x00000000}, | ||
997 | {0x0000b1c8, 0x00000000}, | ||
998 | {0x0000b1cc, 0x00000000}, | ||
999 | {0x0000b1d0, 0x00000000}, | ||
1000 | {0x0000b1d4, 0x00000000}, | ||
1001 | {0x0000b1d8, 0x00000000}, | ||
1002 | {0x0000b1dc, 0x00000000}, | ||
1003 | {0x0000b1e0, 0x00000000}, | ||
1004 | {0x0000b1e4, 0x00000000}, | ||
1005 | {0x0000b1e8, 0x00000000}, | ||
1006 | {0x0000b1ec, 0x00000000}, | ||
1007 | {0x0000b1f0, 0x00000396}, | ||
1008 | {0x0000b1f4, 0x00000396}, | ||
1009 | {0x0000b1f8, 0x00000396}, | ||
1010 | {0x0000b1fc, 0x00000196}, | ||
1011 | }; | ||
1012 | |||
1013 | static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = { | ||
1014 | /* Addr allmodes */ | ||
1015 | {0x00009fd0, 0x0a2d6b93}, | ||
1016 | }; | ||
1017 | |||
1018 | static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = { | ||
1019 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1020 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae}, | ||
1021 | {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da}, | ||
1022 | {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81}, | ||
1023 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8}, | ||
1024 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e}, | ||
1025 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e}, | ||
1026 | }; | ||
1027 | |||
1028 | static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = { | ||
1029 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1030 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | ||
1031 | }; | ||
1032 | |||
1033 | static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = { | ||
1034 | /* Addr allmodes */ | ||
1035 | {0x0000a000, 0x00010000}, | ||
1036 | {0x0000a004, 0x00030002}, | ||
1037 | {0x0000a008, 0x00050004}, | ||
1038 | {0x0000a00c, 0x00810080}, | ||
1039 | {0x0000a010, 0x00830082}, | ||
1040 | {0x0000a014, 0x01810180}, | ||
1041 | {0x0000a018, 0x01830182}, | ||
1042 | {0x0000a01c, 0x01850184}, | ||
1043 | {0x0000a020, 0x01890188}, | ||
1044 | {0x0000a024, 0x018b018a}, | ||
1045 | {0x0000a028, 0x018d018c}, | ||
1046 | {0x0000a02c, 0x03820190}, | ||
1047 | {0x0000a030, 0x03840383}, | ||
1048 | {0x0000a034, 0x03880385}, | ||
1049 | {0x0000a038, 0x038a0389}, | ||
1050 | {0x0000a03c, 0x038c038b}, | ||
1051 | {0x0000a040, 0x0390038d}, | ||
1052 | {0x0000a044, 0x03920391}, | ||
1053 | {0x0000a048, 0x03940393}, | ||
1054 | {0x0000a04c, 0x03960395}, | ||
1055 | {0x0000a050, 0x00000000}, | ||
1056 | {0x0000a054, 0x00000000}, | ||
1057 | {0x0000a058, 0x00000000}, | ||
1058 | {0x0000a05c, 0x00000000}, | ||
1059 | {0x0000a060, 0x00000000}, | ||
1060 | {0x0000a064, 0x00000000}, | ||
1061 | {0x0000a068, 0x00000000}, | ||
1062 | {0x0000a06c, 0x00000000}, | ||
1063 | {0x0000a070, 0x00000000}, | ||
1064 | {0x0000a074, 0x00000000}, | ||
1065 | {0x0000a078, 0x00000000}, | ||
1066 | {0x0000a07c, 0x00000000}, | ||
1067 | {0x0000a080, 0x29292929}, | ||
1068 | {0x0000a084, 0x29292929}, | ||
1069 | {0x0000a088, 0x29292929}, | ||
1070 | {0x0000a08c, 0x29292929}, | ||
1071 | {0x0000a090, 0x22292929}, | ||
1072 | {0x0000a094, 0x1d1d2222}, | ||
1073 | {0x0000a098, 0x0c111117}, | ||
1074 | {0x0000a09c, 0x00030303}, | ||
1075 | {0x0000a0a0, 0x00000000}, | ||
1076 | {0x0000a0a4, 0x00000000}, | ||
1077 | {0x0000a0a8, 0x00000000}, | ||
1078 | {0x0000a0ac, 0x00000000}, | ||
1079 | {0x0000a0b0, 0x00000000}, | ||
1080 | {0x0000a0b4, 0x00000000}, | ||
1081 | {0x0000a0b8, 0x00000000}, | ||
1082 | {0x0000a0bc, 0x00000000}, | ||
1083 | {0x0000a0c0, 0x001f0000}, | ||
1084 | {0x0000a0c4, 0x01000101}, | ||
1085 | {0x0000a0c8, 0x011e011f}, | ||
1086 | {0x0000a0cc, 0x011c011d}, | ||
1087 | {0x0000a0d0, 0x02030204}, | ||
1088 | {0x0000a0d4, 0x02010202}, | ||
1089 | {0x0000a0d8, 0x021f0200}, | ||
1090 | {0x0000a0dc, 0x0302021e}, | ||
1091 | {0x0000a0e0, 0x03000301}, | ||
1092 | {0x0000a0e4, 0x031e031f}, | ||
1093 | {0x0000a0e8, 0x0402031d}, | ||
1094 | {0x0000a0ec, 0x04000401}, | ||
1095 | {0x0000a0f0, 0x041e041f}, | ||
1096 | {0x0000a0f4, 0x0502041d}, | ||
1097 | {0x0000a0f8, 0x05000501}, | ||
1098 | {0x0000a0fc, 0x051e051f}, | ||
1099 | {0x0000a100, 0x06010602}, | ||
1100 | {0x0000a104, 0x061f0600}, | ||
1101 | {0x0000a108, 0x061d061e}, | ||
1102 | {0x0000a10c, 0x07020703}, | ||
1103 | {0x0000a110, 0x07000701}, | ||
1104 | {0x0000a114, 0x00000000}, | ||
1105 | {0x0000a118, 0x00000000}, | ||
1106 | {0x0000a11c, 0x00000000}, | ||
1107 | {0x0000a120, 0x00000000}, | ||
1108 | {0x0000a124, 0x00000000}, | ||
1109 | {0x0000a128, 0x00000000}, | ||
1110 | {0x0000a12c, 0x00000000}, | ||
1111 | {0x0000a130, 0x00000000}, | ||
1112 | {0x0000a134, 0x00000000}, | ||
1113 | {0x0000a138, 0x00000000}, | ||
1114 | {0x0000a13c, 0x00000000}, | ||
1115 | {0x0000a140, 0x001f0000}, | ||
1116 | {0x0000a144, 0x01000101}, | ||
1117 | {0x0000a148, 0x011e011f}, | ||
1118 | {0x0000a14c, 0x011c011d}, | ||
1119 | {0x0000a150, 0x02030204}, | ||
1120 | {0x0000a154, 0x02010202}, | ||
1121 | {0x0000a158, 0x021f0200}, | ||
1122 | {0x0000a15c, 0x0302021e}, | ||
1123 | {0x0000a160, 0x03000301}, | ||
1124 | {0x0000a164, 0x031e031f}, | ||
1125 | {0x0000a168, 0x0402031d}, | ||
1126 | {0x0000a16c, 0x04000401}, | ||
1127 | {0x0000a170, 0x041e041f}, | ||
1128 | {0x0000a174, 0x0502041d}, | ||
1129 | {0x0000a178, 0x05000501}, | ||
1130 | {0x0000a17c, 0x051e051f}, | ||
1131 | {0x0000a180, 0x06010602}, | ||
1132 | {0x0000a184, 0x061f0600}, | ||
1133 | {0x0000a188, 0x061d061e}, | ||
1134 | {0x0000a18c, 0x07020703}, | ||
1135 | {0x0000a190, 0x07000701}, | ||
1136 | {0x0000a194, 0x00000000}, | ||
1137 | {0x0000a198, 0x00000000}, | ||
1138 | {0x0000a19c, 0x00000000}, | ||
1139 | {0x0000a1a0, 0x00000000}, | ||
1140 | {0x0000a1a4, 0x00000000}, | ||
1141 | {0x0000a1a8, 0x00000000}, | ||
1142 | {0x0000a1ac, 0x00000000}, | ||
1143 | {0x0000a1b0, 0x00000000}, | ||
1144 | {0x0000a1b4, 0x00000000}, | ||
1145 | {0x0000a1b8, 0x00000000}, | ||
1146 | {0x0000a1bc, 0x00000000}, | ||
1147 | {0x0000a1c0, 0x00000000}, | ||
1148 | {0x0000a1c4, 0x00000000}, | ||
1149 | {0x0000a1c8, 0x00000000}, | ||
1150 | {0x0000a1cc, 0x00000000}, | ||
1151 | {0x0000a1d0, 0x00000000}, | ||
1152 | {0x0000a1d4, 0x00000000}, | ||
1153 | {0x0000a1d8, 0x00000000}, | ||
1154 | {0x0000a1dc, 0x00000000}, | ||
1155 | {0x0000a1e0, 0x00000000}, | ||
1156 | {0x0000a1e4, 0x00000000}, | ||
1157 | {0x0000a1e8, 0x00000000}, | ||
1158 | {0x0000a1ec, 0x00000000}, | ||
1159 | {0x0000a1f0, 0x00000396}, | ||
1160 | {0x0000a1f4, 0x00000396}, | ||
1161 | {0x0000a1f8, 0x00000396}, | ||
1162 | {0x0000a1fc, 0x00000196}, | ||
1163 | {0x0000b000, 0x00010000}, | ||
1164 | {0x0000b004, 0x00030002}, | ||
1165 | {0x0000b008, 0x00050004}, | ||
1166 | {0x0000b00c, 0x00810080}, | ||
1167 | {0x0000b010, 0x00830082}, | ||
1168 | {0x0000b014, 0x01810180}, | ||
1169 | {0x0000b018, 0x01830182}, | ||
1170 | {0x0000b01c, 0x01850184}, | ||
1171 | {0x0000b020, 0x02810280}, | ||
1172 | {0x0000b024, 0x02830282}, | ||
1173 | {0x0000b028, 0x02850284}, | ||
1174 | {0x0000b02c, 0x02890288}, | ||
1175 | {0x0000b030, 0x028b028a}, | ||
1176 | {0x0000b034, 0x0388028c}, | ||
1177 | {0x0000b038, 0x038a0389}, | ||
1178 | {0x0000b03c, 0x038c038b}, | ||
1179 | {0x0000b040, 0x0390038d}, | ||
1180 | {0x0000b044, 0x03920391}, | ||
1181 | {0x0000b048, 0x03940393}, | ||
1182 | {0x0000b04c, 0x03960395}, | ||
1183 | {0x0000b050, 0x00000000}, | ||
1184 | {0x0000b054, 0x00000000}, | ||
1185 | {0x0000b058, 0x00000000}, | ||
1186 | {0x0000b05c, 0x00000000}, | ||
1187 | {0x0000b060, 0x00000000}, | ||
1188 | {0x0000b064, 0x00000000}, | ||
1189 | {0x0000b068, 0x00000000}, | ||
1190 | {0x0000b06c, 0x00000000}, | ||
1191 | {0x0000b070, 0x00000000}, | ||
1192 | {0x0000b074, 0x00000000}, | ||
1193 | {0x0000b078, 0x00000000}, | ||
1194 | {0x0000b07c, 0x00000000}, | ||
1195 | {0x0000b080, 0x32323232}, | ||
1196 | {0x0000b084, 0x2f2f3232}, | ||
1197 | {0x0000b088, 0x23282a2d}, | ||
1198 | {0x0000b08c, 0x1c1e2123}, | ||
1199 | {0x0000b090, 0x14171919}, | ||
1200 | {0x0000b094, 0x0e0e1214}, | ||
1201 | {0x0000b098, 0x03050707}, | ||
1202 | {0x0000b09c, 0x00030303}, | ||
1203 | {0x0000b0a0, 0x00000000}, | ||
1204 | {0x0000b0a4, 0x00000000}, | ||
1205 | {0x0000b0a8, 0x00000000}, | ||
1206 | {0x0000b0ac, 0x00000000}, | ||
1207 | {0x0000b0b0, 0x00000000}, | ||
1208 | {0x0000b0b4, 0x00000000}, | ||
1209 | {0x0000b0b8, 0x00000000}, | ||
1210 | {0x0000b0bc, 0x00000000}, | ||
1211 | {0x0000b0c0, 0x003f0020}, | ||
1212 | {0x0000b0c4, 0x00400041}, | ||
1213 | {0x0000b0c8, 0x0140005f}, | ||
1214 | {0x0000b0cc, 0x0160015f}, | ||
1215 | {0x0000b0d0, 0x017e017f}, | ||
1216 | {0x0000b0d4, 0x02410242}, | ||
1217 | {0x0000b0d8, 0x025f0240}, | ||
1218 | {0x0000b0dc, 0x027f0260}, | ||
1219 | {0x0000b0e0, 0x0341027e}, | ||
1220 | {0x0000b0e4, 0x035f0340}, | ||
1221 | {0x0000b0e8, 0x037f0360}, | ||
1222 | {0x0000b0ec, 0x04400441}, | ||
1223 | {0x0000b0f0, 0x0460045f}, | ||
1224 | {0x0000b0f4, 0x0541047f}, | ||
1225 | {0x0000b0f8, 0x055f0540}, | ||
1226 | {0x0000b0fc, 0x057f0560}, | ||
1227 | {0x0000b100, 0x06400641}, | ||
1228 | {0x0000b104, 0x0660065f}, | ||
1229 | {0x0000b108, 0x067e067f}, | ||
1230 | {0x0000b10c, 0x07410742}, | ||
1231 | {0x0000b110, 0x075f0740}, | ||
1232 | {0x0000b114, 0x077f0760}, | ||
1233 | {0x0000b118, 0x07800781}, | ||
1234 | {0x0000b11c, 0x07a0079f}, | ||
1235 | {0x0000b120, 0x07c107bf}, | ||
1236 | {0x0000b124, 0x000007c0}, | ||
1237 | {0x0000b128, 0x00000000}, | ||
1238 | {0x0000b12c, 0x00000000}, | ||
1239 | {0x0000b130, 0x00000000}, | ||
1240 | {0x0000b134, 0x00000000}, | ||
1241 | {0x0000b138, 0x00000000}, | ||
1242 | {0x0000b13c, 0x00000000}, | ||
1243 | {0x0000b140, 0x003f0020}, | ||
1244 | {0x0000b144, 0x00400041}, | ||
1245 | {0x0000b148, 0x0140005f}, | ||
1246 | {0x0000b14c, 0x0160015f}, | ||
1247 | {0x0000b150, 0x017e017f}, | ||
1248 | {0x0000b154, 0x02410242}, | ||
1249 | {0x0000b158, 0x025f0240}, | ||
1250 | {0x0000b15c, 0x027f0260}, | ||
1251 | {0x0000b160, 0x0341027e}, | ||
1252 | {0x0000b164, 0x035f0340}, | ||
1253 | {0x0000b168, 0x037f0360}, | ||
1254 | {0x0000b16c, 0x04400441}, | ||
1255 | {0x0000b170, 0x0460045f}, | ||
1256 | {0x0000b174, 0x0541047f}, | ||
1257 | {0x0000b178, 0x055f0540}, | ||
1258 | {0x0000b17c, 0x057f0560}, | ||
1259 | {0x0000b180, 0x06400641}, | ||
1260 | {0x0000b184, 0x0660065f}, | ||
1261 | {0x0000b188, 0x067e067f}, | ||
1262 | {0x0000b18c, 0x07410742}, | ||
1263 | {0x0000b190, 0x075f0740}, | ||
1264 | {0x0000b194, 0x077f0760}, | ||
1265 | {0x0000b198, 0x07800781}, | ||
1266 | {0x0000b19c, 0x07a0079f}, | ||
1267 | {0x0000b1a0, 0x07c107bf}, | ||
1268 | {0x0000b1a4, 0x000007c0}, | ||
1269 | {0x0000b1a8, 0x00000000}, | ||
1270 | {0x0000b1ac, 0x00000000}, | ||
1271 | {0x0000b1b0, 0x00000000}, | ||
1272 | {0x0000b1b4, 0x00000000}, | ||
1273 | {0x0000b1b8, 0x00000000}, | ||
1274 | {0x0000b1bc, 0x00000000}, | ||
1275 | {0x0000b1c0, 0x00000000}, | ||
1276 | {0x0000b1c4, 0x00000000}, | ||
1277 | {0x0000b1c8, 0x00000000}, | ||
1278 | {0x0000b1cc, 0x00000000}, | ||
1279 | {0x0000b1d0, 0x00000000}, | ||
1280 | {0x0000b1d4, 0x00000000}, | ||
1281 | {0x0000b1d8, 0x00000000}, | ||
1282 | {0x0000b1dc, 0x00000000}, | ||
1283 | {0x0000b1e0, 0x00000000}, | ||
1284 | {0x0000b1e4, 0x00000000}, | ||
1285 | {0x0000b1e8, 0x00000000}, | ||
1286 | {0x0000b1ec, 0x00000000}, | ||
1287 | {0x0000b1f0, 0x00000396}, | ||
1288 | {0x0000b1f4, 0x00000396}, | ||
1289 | {0x0000b1f8, 0x00000396}, | ||
1290 | {0x0000b1fc, 0x00000196}, | ||
1291 | }; | ||
1292 | |||
1293 | static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = { | ||
1294 | /* Addr allmodes */ | ||
1295 | {0x0000a000, 0x00010000}, | ||
1296 | {0x0000a004, 0x00030002}, | ||
1297 | {0x0000a008, 0x00050004}, | ||
1298 | {0x0000a00c, 0x00810080}, | ||
1299 | {0x0000a010, 0x00830082}, | ||
1300 | {0x0000a014, 0x01810180}, | ||
1301 | {0x0000a018, 0x01830182}, | ||
1302 | {0x0000a01c, 0x01850184}, | ||
1303 | {0x0000a020, 0x01890188}, | ||
1304 | {0x0000a024, 0x018b018a}, | ||
1305 | {0x0000a028, 0x018d018c}, | ||
1306 | {0x0000a02c, 0x03820190}, | ||
1307 | {0x0000a030, 0x03840383}, | ||
1308 | {0x0000a034, 0x03880385}, | ||
1309 | {0x0000a038, 0x038a0389}, | ||
1310 | {0x0000a03c, 0x038c038b}, | ||
1311 | {0x0000a040, 0x0390038d}, | ||
1312 | {0x0000a044, 0x03920391}, | ||
1313 | {0x0000a048, 0x03940393}, | ||
1314 | {0x0000a04c, 0x03960395}, | ||
1315 | {0x0000a050, 0x00000000}, | ||
1316 | {0x0000a054, 0x00000000}, | ||
1317 | {0x0000a058, 0x00000000}, | ||
1318 | {0x0000a05c, 0x00000000}, | ||
1319 | {0x0000a060, 0x00000000}, | ||
1320 | {0x0000a064, 0x00000000}, | ||
1321 | {0x0000a068, 0x00000000}, | ||
1322 | {0x0000a06c, 0x00000000}, | ||
1323 | {0x0000a070, 0x00000000}, | ||
1324 | {0x0000a074, 0x00000000}, | ||
1325 | {0x0000a078, 0x00000000}, | ||
1326 | {0x0000a07c, 0x00000000}, | ||
1327 | {0x0000a080, 0x29292929}, | ||
1328 | {0x0000a084, 0x29292929}, | ||
1329 | {0x0000a088, 0x29292929}, | ||
1330 | {0x0000a08c, 0x29292929}, | ||
1331 | {0x0000a090, 0x22292929}, | ||
1332 | {0x0000a094, 0x1d1d2222}, | ||
1333 | {0x0000a098, 0x0c111117}, | ||
1334 | {0x0000a09c, 0x00030303}, | ||
1335 | {0x0000a0a0, 0x00000000}, | ||
1336 | {0x0000a0a4, 0x00000000}, | ||
1337 | {0x0000a0a8, 0x00000000}, | ||
1338 | {0x0000a0ac, 0x00000000}, | ||
1339 | {0x0000a0b0, 0x00000000}, | ||
1340 | {0x0000a0b4, 0x00000000}, | ||
1341 | {0x0000a0b8, 0x00000000}, | ||
1342 | {0x0000a0bc, 0x00000000}, | ||
1343 | {0x0000a0c0, 0x001f0000}, | ||
1344 | {0x0000a0c4, 0x01000101}, | ||
1345 | {0x0000a0c8, 0x011e011f}, | ||
1346 | {0x0000a0cc, 0x011c011d}, | ||
1347 | {0x0000a0d0, 0x02030204}, | ||
1348 | {0x0000a0d4, 0x02010202}, | ||
1349 | {0x0000a0d8, 0x021f0200}, | ||
1350 | {0x0000a0dc, 0x0302021e}, | ||
1351 | {0x0000a0e0, 0x03000301}, | ||
1352 | {0x0000a0e4, 0x031e031f}, | ||
1353 | {0x0000a0e8, 0x0402031d}, | ||
1354 | {0x0000a0ec, 0x04000401}, | ||
1355 | {0x0000a0f0, 0x041e041f}, | ||
1356 | {0x0000a0f4, 0x0502041d}, | ||
1357 | {0x0000a0f8, 0x05000501}, | ||
1358 | {0x0000a0fc, 0x051e051f}, | ||
1359 | {0x0000a100, 0x06010602}, | ||
1360 | {0x0000a104, 0x061f0600}, | ||
1361 | {0x0000a108, 0x061d061e}, | ||
1362 | {0x0000a10c, 0x07020703}, | ||
1363 | {0x0000a110, 0x07000701}, | ||
1364 | {0x0000a114, 0x00000000}, | ||
1365 | {0x0000a118, 0x00000000}, | ||
1366 | {0x0000a11c, 0x00000000}, | ||
1367 | {0x0000a120, 0x00000000}, | ||
1368 | {0x0000a124, 0x00000000}, | ||
1369 | {0x0000a128, 0x00000000}, | ||
1370 | {0x0000a12c, 0x00000000}, | ||
1371 | {0x0000a130, 0x00000000}, | ||
1372 | {0x0000a134, 0x00000000}, | ||
1373 | {0x0000a138, 0x00000000}, | ||
1374 | {0x0000a13c, 0x00000000}, | ||
1375 | {0x0000a140, 0x001f0000}, | ||
1376 | {0x0000a144, 0x01000101}, | ||
1377 | {0x0000a148, 0x011e011f}, | ||
1378 | {0x0000a14c, 0x011c011d}, | ||
1379 | {0x0000a150, 0x02030204}, | ||
1380 | {0x0000a154, 0x02010202}, | ||
1381 | {0x0000a158, 0x021f0200}, | ||
1382 | {0x0000a15c, 0x0302021e}, | ||
1383 | {0x0000a160, 0x03000301}, | ||
1384 | {0x0000a164, 0x031e031f}, | ||
1385 | {0x0000a168, 0x0402031d}, | ||
1386 | {0x0000a16c, 0x04000401}, | ||
1387 | {0x0000a170, 0x041e041f}, | ||
1388 | {0x0000a174, 0x0502041d}, | ||
1389 | {0x0000a178, 0x05000501}, | ||
1390 | {0x0000a17c, 0x051e051f}, | ||
1391 | {0x0000a180, 0x06010602}, | ||
1392 | {0x0000a184, 0x061f0600}, | ||
1393 | {0x0000a188, 0x061d061e}, | ||
1394 | {0x0000a18c, 0x07020703}, | ||
1395 | {0x0000a190, 0x07000701}, | ||
1396 | {0x0000a194, 0x00000000}, | ||
1397 | {0x0000a198, 0x00000000}, | ||
1398 | {0x0000a19c, 0x00000000}, | ||
1399 | {0x0000a1a0, 0x00000000}, | ||
1400 | {0x0000a1a4, 0x00000000}, | ||
1401 | {0x0000a1a8, 0x00000000}, | ||
1402 | {0x0000a1ac, 0x00000000}, | ||
1403 | {0x0000a1b0, 0x00000000}, | ||
1404 | {0x0000a1b4, 0x00000000}, | ||
1405 | {0x0000a1b8, 0x00000000}, | ||
1406 | {0x0000a1bc, 0x00000000}, | ||
1407 | {0x0000a1c0, 0x00000000}, | ||
1408 | {0x0000a1c4, 0x00000000}, | ||
1409 | {0x0000a1c8, 0x00000000}, | ||
1410 | {0x0000a1cc, 0x00000000}, | ||
1411 | {0x0000a1d0, 0x00000000}, | ||
1412 | {0x0000a1d4, 0x00000000}, | ||
1413 | {0x0000a1d8, 0x00000000}, | ||
1414 | {0x0000a1dc, 0x00000000}, | ||
1415 | {0x0000a1e0, 0x00000000}, | ||
1416 | {0x0000a1e4, 0x00000000}, | ||
1417 | {0x0000a1e8, 0x00000000}, | ||
1418 | {0x0000a1ec, 0x00000000}, | ||
1419 | {0x0000a1f0, 0x00000396}, | ||
1420 | {0x0000a1f4, 0x00000396}, | ||
1421 | {0x0000a1f8, 0x00000396}, | ||
1422 | {0x0000a1fc, 0x00000196}, | ||
1423 | {0x0000b000, 0x00010000}, | ||
1424 | {0x0000b004, 0x00030002}, | ||
1425 | {0x0000b008, 0x00050004}, | ||
1426 | {0x0000b00c, 0x00810080}, | ||
1427 | {0x0000b010, 0x00830082}, | ||
1428 | {0x0000b014, 0x01810180}, | ||
1429 | {0x0000b018, 0x01830182}, | ||
1430 | {0x0000b01c, 0x01850184}, | ||
1431 | {0x0000b020, 0x02810280}, | ||
1432 | {0x0000b024, 0x02830282}, | ||
1433 | {0x0000b028, 0x02850284}, | ||
1434 | {0x0000b02c, 0x02890288}, | ||
1435 | {0x0000b030, 0x028b028a}, | ||
1436 | {0x0000b034, 0x0388028c}, | ||
1437 | {0x0000b038, 0x038a0389}, | ||
1438 | {0x0000b03c, 0x038c038b}, | ||
1439 | {0x0000b040, 0x0390038d}, | ||
1440 | {0x0000b044, 0x03920391}, | ||
1441 | {0x0000b048, 0x03940393}, | ||
1442 | {0x0000b04c, 0x03960395}, | ||
1443 | {0x0000b050, 0x00000000}, | ||
1444 | {0x0000b054, 0x00000000}, | ||
1445 | {0x0000b058, 0x00000000}, | ||
1446 | {0x0000b05c, 0x00000000}, | ||
1447 | {0x0000b060, 0x00000000}, | ||
1448 | {0x0000b064, 0x00000000}, | ||
1449 | {0x0000b068, 0x00000000}, | ||
1450 | {0x0000b06c, 0x00000000}, | ||
1451 | {0x0000b070, 0x00000000}, | ||
1452 | {0x0000b074, 0x00000000}, | ||
1453 | {0x0000b078, 0x00000000}, | ||
1454 | {0x0000b07c, 0x00000000}, | ||
1455 | {0x0000b080, 0x2a2d2f32}, | ||
1456 | {0x0000b084, 0x21232328}, | ||
1457 | {0x0000b088, 0x19191c1e}, | ||
1458 | {0x0000b08c, 0x12141417}, | ||
1459 | {0x0000b090, 0x07070e0e}, | ||
1460 | {0x0000b094, 0x03030305}, | ||
1461 | {0x0000b098, 0x00000003}, | ||
1462 | {0x0000b09c, 0x00000000}, | ||
1463 | {0x0000b0a0, 0x00000000}, | ||
1464 | {0x0000b0a4, 0x00000000}, | ||
1465 | {0x0000b0a8, 0x00000000}, | ||
1466 | {0x0000b0ac, 0x00000000}, | ||
1467 | {0x0000b0b0, 0x00000000}, | ||
1468 | {0x0000b0b4, 0x00000000}, | ||
1469 | {0x0000b0b8, 0x00000000}, | ||
1470 | {0x0000b0bc, 0x00000000}, | ||
1471 | {0x0000b0c0, 0x003f0020}, | ||
1472 | {0x0000b0c4, 0x00400041}, | ||
1473 | {0x0000b0c8, 0x0140005f}, | ||
1474 | {0x0000b0cc, 0x0160015f}, | ||
1475 | {0x0000b0d0, 0x017e017f}, | ||
1476 | {0x0000b0d4, 0x02410242}, | ||
1477 | {0x0000b0d8, 0x025f0240}, | ||
1478 | {0x0000b0dc, 0x027f0260}, | ||
1479 | {0x0000b0e0, 0x0341027e}, | ||
1480 | {0x0000b0e4, 0x035f0340}, | ||
1481 | {0x0000b0e8, 0x037f0360}, | ||
1482 | {0x0000b0ec, 0x04400441}, | ||
1483 | {0x0000b0f0, 0x0460045f}, | ||
1484 | {0x0000b0f4, 0x0541047f}, | ||
1485 | {0x0000b0f8, 0x055f0540}, | ||
1486 | {0x0000b0fc, 0x057f0560}, | ||
1487 | {0x0000b100, 0x06400641}, | ||
1488 | {0x0000b104, 0x0660065f}, | ||
1489 | {0x0000b108, 0x067e067f}, | ||
1490 | {0x0000b10c, 0x07410742}, | ||
1491 | {0x0000b110, 0x075f0740}, | ||
1492 | {0x0000b114, 0x077f0760}, | ||
1493 | {0x0000b118, 0x07800781}, | ||
1494 | {0x0000b11c, 0x07a0079f}, | ||
1495 | {0x0000b120, 0x07c107bf}, | ||
1496 | {0x0000b124, 0x000007c0}, | ||
1497 | {0x0000b128, 0x00000000}, | ||
1498 | {0x0000b12c, 0x00000000}, | ||
1499 | {0x0000b130, 0x00000000}, | ||
1500 | {0x0000b134, 0x00000000}, | ||
1501 | {0x0000b138, 0x00000000}, | ||
1502 | {0x0000b13c, 0x00000000}, | ||
1503 | {0x0000b140, 0x003f0020}, | ||
1504 | {0x0000b144, 0x00400041}, | ||
1505 | {0x0000b148, 0x0140005f}, | ||
1506 | {0x0000b14c, 0x0160015f}, | ||
1507 | {0x0000b150, 0x017e017f}, | ||
1508 | {0x0000b154, 0x02410242}, | ||
1509 | {0x0000b158, 0x025f0240}, | ||
1510 | {0x0000b15c, 0x027f0260}, | ||
1511 | {0x0000b160, 0x0341027e}, | ||
1512 | {0x0000b164, 0x035f0340}, | ||
1513 | {0x0000b168, 0x037f0360}, | ||
1514 | {0x0000b16c, 0x04400441}, | ||
1515 | {0x0000b170, 0x0460045f}, | ||
1516 | {0x0000b174, 0x0541047f}, | ||
1517 | {0x0000b178, 0x055f0540}, | ||
1518 | {0x0000b17c, 0x057f0560}, | ||
1519 | {0x0000b180, 0x06400641}, | ||
1520 | {0x0000b184, 0x0660065f}, | ||
1521 | {0x0000b188, 0x067e067f}, | ||
1522 | {0x0000b18c, 0x07410742}, | ||
1523 | {0x0000b190, 0x075f0740}, | ||
1524 | {0x0000b194, 0x077f0760}, | ||
1525 | {0x0000b198, 0x07800781}, | ||
1526 | {0x0000b19c, 0x07a0079f}, | ||
1527 | {0x0000b1a0, 0x07c107bf}, | ||
1528 | {0x0000b1a4, 0x000007c0}, | ||
1529 | {0x0000b1a8, 0x00000000}, | ||
1530 | {0x0000b1ac, 0x00000000}, | ||
1531 | {0x0000b1b0, 0x00000000}, | ||
1532 | {0x0000b1b4, 0x00000000}, | ||
1533 | {0x0000b1b8, 0x00000000}, | ||
1534 | {0x0000b1bc, 0x00000000}, | ||
1535 | {0x0000b1c0, 0x00000000}, | ||
1536 | {0x0000b1c4, 0x00000000}, | ||
1537 | {0x0000b1c8, 0x00000000}, | ||
1538 | {0x0000b1cc, 0x00000000}, | ||
1539 | {0x0000b1d0, 0x00000000}, | ||
1540 | {0x0000b1d4, 0x00000000}, | ||
1541 | {0x0000b1d8, 0x00000000}, | ||
1542 | {0x0000b1dc, 0x00000000}, | ||
1543 | {0x0000b1e0, 0x00000000}, | ||
1544 | {0x0000b1e4, 0x00000000}, | ||
1545 | {0x0000b1e8, 0x00000000}, | ||
1546 | {0x0000b1ec, 0x00000000}, | ||
1547 | {0x0000b1f0, 0x00000396}, | ||
1548 | {0x0000b1f4, 0x00000396}, | ||
1549 | {0x0000b1f8, 0x00000396}, | ||
1550 | {0x0000b1fc, 0x00000196}, | ||
1551 | }; | ||
1552 | |||
1553 | static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = { | ||
1554 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1555 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1556 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, | ||
1557 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, | ||
1558 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, | ||
1559 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1560 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
1561 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1562 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1563 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
1564 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
1565 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
1566 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
1567 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
1568 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
1569 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
1570 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
1571 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
1572 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
1573 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
1574 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
1575 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
1576 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
1577 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
1578 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
1579 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
1580 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
1581 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
1582 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
1583 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
1584 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
1585 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
1586 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
1587 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1588 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1589 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1590 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1591 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1592 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1593 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1594 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1595 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1596 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1597 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1598 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1599 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
1600 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | ||
1601 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, | ||
1602 | {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, | ||
1603 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | ||
1604 | {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, | ||
1605 | {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, | ||
1606 | {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | ||
1607 | {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | ||
1608 | {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | ||
1609 | {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | ||
1610 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, | ||
1611 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, | ||
1612 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, | ||
1613 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1614 | {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, | ||
1615 | {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, | ||
1616 | {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, | ||
1617 | {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, | ||
1618 | {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, | ||
1619 | {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, | ||
1620 | }; | ||
1621 | |||
1622 | static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = { | ||
1623 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1624 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1625 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
1626 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
1627 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
1628 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1629 | {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de}, | ||
1630 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1631 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
1632 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, | ||
1633 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | ||
1634 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | ||
1635 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | ||
1636 | {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, | ||
1637 | {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, | ||
1638 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, | ||
1639 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, | ||
1640 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, | ||
1641 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, | ||
1642 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, | ||
1643 | {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, | ||
1644 | {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, | ||
1645 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, | ||
1646 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, | ||
1647 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | ||
1648 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | ||
1649 | {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81}, | ||
1650 | {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83}, | ||
1651 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84}, | ||
1652 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | ||
1653 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | ||
1654 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | ||
1655 | {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, | ||
1656 | {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec}, | ||
1657 | {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0}, | ||
1658 | {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4}, | ||
1659 | {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, | ||
1660 | {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, | ||
1661 | {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, | ||
1662 | {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, | ||
1663 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1664 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1665 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1666 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1667 | {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, | ||
1668 | {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, | ||
1669 | {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, | ||
1670 | {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, | ||
1671 | {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, | ||
1672 | {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, | ||
1673 | {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, | ||
1674 | {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1675 | {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1676 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1677 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1678 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1679 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
1680 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
1681 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
1682 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1683 | {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, | ||
1684 | {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, | ||
1685 | {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, | ||
1686 | {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, | ||
1687 | {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, | ||
1688 | {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, | ||
1689 | }; | ||
1690 | |||
1691 | static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = { | ||
1692 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1693 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1694 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
1695 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
1696 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
1697 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1698 | {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de}, | ||
1699 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1700 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
1701 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, | ||
1702 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | ||
1703 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | ||
1704 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | ||
1705 | {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400}, | ||
1706 | {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402}, | ||
1707 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, | ||
1708 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603}, | ||
1709 | {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02}, | ||
1710 | {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04}, | ||
1711 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20}, | ||
1712 | {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20}, | ||
1713 | {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22}, | ||
1714 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24}, | ||
1715 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640}, | ||
1716 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660}, | ||
1717 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861}, | ||
1718 | {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81}, | ||
1719 | {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83}, | ||
1720 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84}, | ||
1721 | {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3}, | ||
1722 | {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5}, | ||
1723 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9}, | ||
1724 | {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb}, | ||
1725 | {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec}, | ||
1726 | {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0}, | ||
1727 | {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4}, | ||
1728 | {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
1729 | {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
1730 | {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
1731 | {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, | ||
1732 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1733 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1734 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1735 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1736 | {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, | ||
1737 | {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, | ||
1738 | {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, | ||
1739 | {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, | ||
1740 | {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, | ||
1741 | {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, | ||
1742 | {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, | ||
1743 | {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1744 | {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1745 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1746 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1747 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | ||
1748 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, | ||
1749 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, | ||
1750 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, | ||
1751 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
1752 | }; | ||
1753 | |||
1754 | static const u32 ar9462_2p1_modes_fast_clock[][3] = { | ||
1755 | /* Addr 5G_HT20 5G_HT40 */ | ||
1756 | {0x00001030, 0x00000268, 0x000004d0}, | ||
1757 | {0x00001070, 0x0000018c, 0x00000318}, | ||
1758 | {0x000010b0, 0x00000fd0, 0x00001fa0}, | ||
1759 | {0x00008014, 0x044c044c, 0x08980898}, | ||
1760 | {0x0000801c, 0x148ec02b, 0x148ec057}, | ||
1761 | {0x00008318, 0x000044c0, 0x00008980}, | ||
1762 | {0x00009e00, 0x0372131c, 0x0372131c}, | ||
1763 | {0x0000a230, 0x0000400b, 0x00004016}, | ||
1764 | {0x0000a254, 0x00000898, 0x00001130}, | ||
1765 | }; | ||
1766 | |||
1767 | static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = { | ||
1768 | /* Addr allmodes */ | ||
1769 | {0x0000a398, 0x00000000}, | ||
1770 | {0x0000a39c, 0x6f7f0301}, | ||
1771 | {0x0000a3a0, 0xca9228ee}, | ||
1772 | }; | ||
1773 | |||
1774 | #endif /* INITVALS_9462_2P1_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 04b2d3ea728f..c1224b5a257b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -634,6 +634,7 @@ void ath_ant_comb_update(struct ath_softc *sc); | |||
634 | #define ATH9K_PCI_CUS198 0x0001 | 634 | #define ATH9K_PCI_CUS198 0x0001 |
635 | #define ATH9K_PCI_CUS230 0x0002 | 635 | #define ATH9K_PCI_CUS230 0x0002 |
636 | #define ATH9K_PCI_CUS217 0x0004 | 636 | #define ATH9K_PCI_CUS217 0x0004 |
637 | #define ATH9K_PCI_WOW 0x0008 | ||
637 | 638 | ||
638 | /* | 639 | /* |
639 | * Default cache line size, in bytes. | 640 | * Default cache line size, in bytes. |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f5dda84176c3..9e582e14da74 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -234,10 +234,15 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, | |||
234 | struct sk_buff *skb; | 234 | struct sk_buff *skb; |
235 | 235 | ||
236 | while ((skb = __skb_dequeue(queue)) != NULL) { | 236 | while ((skb = __skb_dequeue(queue)) != NULL) { |
237 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
238 | int ln = skb->len; | ||
239 | #endif | ||
237 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | 240 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, |
238 | skb, txok); | 241 | skb, txok); |
239 | if (txok) | 242 | if (txok) { |
240 | TX_STAT_INC(skb_success); | 243 | TX_STAT_INC(skb_success); |
244 | TX_STAT_ADD(skb_success_bytes, ln); | ||
245 | } | ||
241 | else | 246 | else |
242 | TX_STAT_INC(skb_failed); | 247 | TX_STAT_INC(skb_failed); |
243 | } | 248 | } |
@@ -620,6 +625,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, | |||
620 | 625 | ||
621 | err: | 626 | err: |
622 | for (i = 0; i < pool_index; i++) { | 627 | for (i = 0; i < pool_index; i++) { |
628 | RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len); | ||
623 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], | 629 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], |
624 | skb_pool[i]->len, USB_WLAN_RX_PIPE); | 630 | skb_pool[i]->len, USB_WLAN_RX_PIPE); |
625 | RX_STAT_INC(skb_completed); | 631 | RX_STAT_INC(skb_completed); |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 69581031f2cd..055d7c25e090 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -324,7 +324,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) | |||
324 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 324 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
325 | 325 | ||
326 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) | 326 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) |
327 | #define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) | ||
327 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) | 328 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) |
329 | #define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c += a) | ||
328 | #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ | 330 | #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ |
329 | 331 | ||
330 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) | 332 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) |
@@ -337,6 +339,7 @@ struct ath_tx_stats { | |||
337 | u32 buf_completed; | 339 | u32 buf_completed; |
338 | u32 skb_queued; | 340 | u32 skb_queued; |
339 | u32 skb_success; | 341 | u32 skb_success; |
342 | u32 skb_success_bytes; | ||
340 | u32 skb_failed; | 343 | u32 skb_failed; |
341 | u32 cab_queued; | 344 | u32 cab_queued; |
342 | u32 queue_stats[IEEE80211_NUM_ACS]; | 345 | u32 queue_stats[IEEE80211_NUM_ACS]; |
@@ -345,6 +348,7 @@ struct ath_tx_stats { | |||
345 | struct ath_rx_stats { | 348 | struct ath_rx_stats { |
346 | u32 skb_allocated; | 349 | u32 skb_allocated; |
347 | u32 skb_completed; | 350 | u32 skb_completed; |
351 | u32 skb_completed_bytes; | ||
348 | u32 skb_dropped; | 352 | u32 skb_dropped; |
349 | u32 err_crc; | 353 | u32 err_crc; |
350 | u32 err_decrypt_crc; | 354 | u32 err_decrypt_crc; |
@@ -362,10 +366,20 @@ struct ath9k_debug { | |||
362 | struct ath_rx_stats rx_stats; | 366 | struct ath_rx_stats rx_stats; |
363 | }; | 367 | }; |
364 | 368 | ||
369 | void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, | ||
370 | struct ieee80211_vif *vif, | ||
371 | u32 sset, u8 *data); | ||
372 | int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw, | ||
373 | struct ieee80211_vif *vif, int sset); | ||
374 | void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, | ||
375 | struct ieee80211_vif *vif, | ||
376 | struct ethtool_stats *stats, u64 *data); | ||
365 | #else | 377 | #else |
366 | 378 | ||
367 | #define TX_STAT_INC(c) do { } while (0) | 379 | #define TX_STAT_INC(c) do { } while (0) |
380 | #define TX_STAT_ADD(c, a) do { } while (0) | ||
368 | #define RX_STAT_INC(c) do { } while (0) | 381 | #define RX_STAT_INC(c) do { } while (0) |
382 | #define RX_STAT_ADD(c, a) do { } while (0) | ||
369 | #define CAB_STAT_INC do { } while (0) | 383 | #define CAB_STAT_INC do { } while (0) |
370 | 384 | ||
371 | #define TX_QSTAT_INC(c) do { } while (0) | 385 | #define TX_QSTAT_INC(c) do { } while (0) |
@@ -583,6 +597,8 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | |||
583 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | 597 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); |
584 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); | 598 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); |
585 | 599 | ||
600 | struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv); | ||
601 | |||
586 | #ifdef CONFIG_MAC80211_LEDS | 602 | #ifdef CONFIG_MAC80211_LEDS |
587 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 603 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
588 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | 604 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index d08ef24e9696..c1b45e2f8481 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -496,21 +496,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | |||
496 | ssize_t retval = 0; | 496 | ssize_t retval = 0; |
497 | char *buf; | 497 | char *buf; |
498 | 498 | ||
499 | /* | 499 | pBase = ath9k_htc_get_eeprom_base(priv); |
500 | * This can be done since all the 3 EEPROM families have the | ||
501 | * same base header upto a certain point, and we are interested in | ||
502 | * the data only upto that point. | ||
503 | */ | ||
504 | |||
505 | if (AR_SREV_9271(priv->ah)) | ||
506 | pBase = (struct base_eep_header *) | ||
507 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
508 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
509 | pBase = (struct base_eep_header *) | ||
510 | &priv->ah->eeprom.def.baseEepHeader; | ||
511 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
512 | pBase = (struct base_eep_header *) | ||
513 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
514 | 500 | ||
515 | if (pBase == NULL) { | 501 | if (pBase == NULL) { |
516 | ath_err(common, "Unknown EEPROM type\n"); | 502 | ath_err(common, "Unknown EEPROM type\n"); |
@@ -916,6 +902,87 @@ static const struct file_operations fops_modal_eeprom = { | |||
916 | .llseek = default_llseek, | 902 | .llseek = default_llseek, |
917 | }; | 903 | }; |
918 | 904 | ||
905 | |||
906 | /* Ethtool support for get-stats */ | ||
907 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" | ||
908 | static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = { | ||
909 | "tx_pkts_nic", | ||
910 | "tx_bytes_nic", | ||
911 | "rx_pkts_nic", | ||
912 | "rx_bytes_nic", | ||
913 | |||
914 | AMKSTR(d_tx_pkts), | ||
915 | |||
916 | "d_rx_crc_err", | ||
917 | "d_rx_decrypt_crc_err", | ||
918 | "d_rx_phy_err", | ||
919 | "d_rx_mic_err", | ||
920 | "d_rx_pre_delim_crc_err", | ||
921 | "d_rx_post_delim_crc_err", | ||
922 | "d_rx_decrypt_busy_err", | ||
923 | |||
924 | "d_rx_phyerr_radar", | ||
925 | "d_rx_phyerr_ofdm_timing", | ||
926 | "d_rx_phyerr_cck_timing", | ||
927 | |||
928 | }; | ||
929 | #define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats) | ||
930 | |||
931 | void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, | ||
932 | struct ieee80211_vif *vif, | ||
933 | u32 sset, u8 *data) | ||
934 | { | ||
935 | if (sset == ETH_SS_STATS) | ||
936 | memcpy(data, *ath9k_htc_gstrings_stats, | ||
937 | sizeof(ath9k_htc_gstrings_stats)); | ||
938 | } | ||
939 | |||
940 | int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw, | ||
941 | struct ieee80211_vif *vif, int sset) | ||
942 | { | ||
943 | if (sset == ETH_SS_STATS) | ||
944 | return ATH9K_HTC_SSTATS_LEN; | ||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | #define STXBASE priv->debug.tx_stats | ||
949 | #define SRXBASE priv->debug.rx_stats | ||
950 | #define ASTXQ(a) \ | ||
951 | data[i++] = STXBASE.a[IEEE80211_AC_BE]; \ | ||
952 | data[i++] = STXBASE.a[IEEE80211_AC_BK]; \ | ||
953 | data[i++] = STXBASE.a[IEEE80211_AC_VI]; \ | ||
954 | data[i++] = STXBASE.a[IEEE80211_AC_VO] | ||
955 | |||
956 | void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, | ||
957 | struct ieee80211_vif *vif, | ||
958 | struct ethtool_stats *stats, u64 *data) | ||
959 | { | ||
960 | struct ath9k_htc_priv *priv = hw->priv; | ||
961 | int i = 0; | ||
962 | |||
963 | data[i++] = STXBASE.skb_success; | ||
964 | data[i++] = STXBASE.skb_success_bytes; | ||
965 | data[i++] = SRXBASE.skb_completed; | ||
966 | data[i++] = SRXBASE.skb_completed_bytes; | ||
967 | |||
968 | ASTXQ(queue_stats); | ||
969 | |||
970 | data[i++] = SRXBASE.err_crc; | ||
971 | data[i++] = SRXBASE.err_decrypt_crc; | ||
972 | data[i++] = SRXBASE.err_phy; | ||
973 | data[i++] = SRXBASE.err_mic; | ||
974 | data[i++] = SRXBASE.err_pre_delim; | ||
975 | data[i++] = SRXBASE.err_post_delim; | ||
976 | data[i++] = SRXBASE.err_decrypt_busy; | ||
977 | |||
978 | data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_RADAR]; | ||
979 | data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_OFDM_TIMING]; | ||
980 | data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_CCK_TIMING]; | ||
981 | |||
982 | WARN_ON(i != ATH9K_HTC_SSTATS_LEN); | ||
983 | } | ||
984 | |||
985 | |||
919 | int ath9k_htc_init_debug(struct ath_hw *ah) | 986 | int ath9k_htc_init_debug(struct ath_hw *ah) |
920 | { | 987 | { |
921 | struct ath_common *common = ath9k_hw_common(ah); | 988 | struct ath_common *common = ath9k_hw_common(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index bb0ba9e3e083..71a183ffc77f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -701,8 +701,10 @@ static const struct ieee80211_iface_limit if_limits[] = { | |||
701 | { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | | 701 | { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | |
702 | BIT(NL80211_IFTYPE_P2P_CLIENT) }, | 702 | BIT(NL80211_IFTYPE_P2P_CLIENT) }, |
703 | { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | | 703 | { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | |
704 | BIT(NL80211_IFTYPE_P2P_GO) | | 704 | #ifdef CONFIG_MAC80211_MESH |
705 | BIT(NL80211_IFTYPE_MESH_POINT) }, | 705 | BIT(NL80211_IFTYPE_MESH_POINT) | |
706 | #endif | ||
707 | BIT(NL80211_IFTYPE_P2P_GO) }, | ||
706 | }; | 708 | }; |
707 | 709 | ||
708 | static const struct ieee80211_iface_combination if_comb = { | 710 | static const struct ieee80211_iface_combination if_comb = { |
@@ -716,6 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
716 | struct ieee80211_hw *hw) | 718 | struct ieee80211_hw *hw) |
717 | { | 719 | { |
718 | struct ath_common *common = ath9k_hw_common(priv->ah); | 720 | struct ath_common *common = ath9k_hw_common(priv->ah); |
721 | struct base_eep_header *pBase; | ||
719 | 722 | ||
720 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 723 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
721 | IEEE80211_HW_AMPDU_AGGREGATION | | 724 | IEEE80211_HW_AMPDU_AGGREGATION | |
@@ -771,6 +774,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
771 | &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 774 | &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
772 | } | 775 | } |
773 | 776 | ||
777 | pBase = ath9k_htc_get_eeprom_base(priv); | ||
778 | if (pBase) { | ||
779 | hw->wiphy->available_antennas_rx = pBase->rxMask; | ||
780 | hw->wiphy->available_antennas_tx = pBase->txMask; | ||
781 | } | ||
782 | |||
774 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 783 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
775 | } | 784 | } |
776 | 785 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index eaa94feb4333..5c1bec18c9e3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1183,7 +1183,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1183 | mutex_lock(&priv->htc_pm_lock); | 1183 | mutex_lock(&priv->htc_pm_lock); |
1184 | 1184 | ||
1185 | priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1185 | priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
1186 | if (priv->ps_idle) | 1186 | if (!priv->ps_idle) |
1187 | chip_reset = true; | 1187 | chip_reset = true; |
1188 | 1188 | ||
1189 | mutex_unlock(&priv->htc_pm_lock); | 1189 | mutex_unlock(&priv->htc_pm_lock); |
@@ -1774,6 +1774,43 @@ static int ath9k_htc_get_stats(struct ieee80211_hw *hw, | |||
1774 | return 0; | 1774 | return 0; |
1775 | } | 1775 | } |
1776 | 1776 | ||
1777 | struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv) | ||
1778 | { | ||
1779 | struct base_eep_header *pBase = NULL; | ||
1780 | /* | ||
1781 | * This can be done since all the 3 EEPROM families have the | ||
1782 | * same base header upto a certain point, and we are interested in | ||
1783 | * the data only upto that point. | ||
1784 | */ | ||
1785 | |||
1786 | if (AR_SREV_9271(priv->ah)) | ||
1787 | pBase = (struct base_eep_header *) | ||
1788 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
1789 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
1790 | pBase = (struct base_eep_header *) | ||
1791 | &priv->ah->eeprom.def.baseEepHeader; | ||
1792 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
1793 | pBase = (struct base_eep_header *) | ||
1794 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
1795 | return pBase; | ||
1796 | } | ||
1797 | |||
1798 | |||
1799 | static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, | ||
1800 | u32 *rx_ant) | ||
1801 | { | ||
1802 | struct ath9k_htc_priv *priv = hw->priv; | ||
1803 | struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv); | ||
1804 | if (pBase) { | ||
1805 | *tx_ant = pBase->txMask; | ||
1806 | *rx_ant = pBase->rxMask; | ||
1807 | } else { | ||
1808 | *tx_ant = 0; | ||
1809 | *rx_ant = 0; | ||
1810 | } | ||
1811 | return 0; | ||
1812 | } | ||
1813 | |||
1777 | struct ieee80211_ops ath9k_htc_ops = { | 1814 | struct ieee80211_ops ath9k_htc_ops = { |
1778 | .tx = ath9k_htc_tx, | 1815 | .tx = ath9k_htc_tx, |
1779 | .start = ath9k_htc_start, | 1816 | .start = ath9k_htc_start, |
@@ -1799,4 +1836,11 @@ struct ieee80211_ops ath9k_htc_ops = { | |||
1799 | .set_coverage_class = ath9k_htc_set_coverage_class, | 1836 | .set_coverage_class = ath9k_htc_set_coverage_class, |
1800 | .set_bitrate_mask = ath9k_htc_set_bitrate_mask, | 1837 | .set_bitrate_mask = ath9k_htc_set_bitrate_mask, |
1801 | .get_stats = ath9k_htc_get_stats, | 1838 | .get_stats = ath9k_htc_get_stats, |
1839 | .get_antenna = ath9k_htc_get_antenna, | ||
1840 | |||
1841 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
1842 | .get_et_sset_count = ath9k_htc_get_et_sset_count, | ||
1843 | .get_et_stats = ath9k_htc_get_et_stats, | ||
1844 | .get_et_strings = ath9k_htc_get_et_strings, | ||
1845 | #endif | ||
1802 | }; | 1846 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5324c3346af8..4ca0cb060106 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2599,7 +2599,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2599 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) | 2599 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) |
2600 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; | 2600 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; |
2601 | 2601 | ||
2602 | if (AR_SREV_9462_20(ah)) | 2602 | if (AR_SREV_9462_20_OR_LATER(ah)) |
2603 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | 2603 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; |
2604 | } | 2604 | } |
2605 | 2605 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1e555d899469..16f8b201642b 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -837,6 +837,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
837 | 837 | ||
838 | #ifdef CONFIG_PM_SLEEP | 838 | #ifdef CONFIG_PM_SLEEP |
839 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && | 839 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && |
840 | (sc->driver_data & ATH9K_PCI_WOW) && | ||
840 | device_can_wakeup(sc->dev)) | 841 | device_can_wakeup(sc->dev)) |
841 | hw->wiphy->wowlan = &ath9k_wowlan_support; | 842 | hw->wiphy->wowlan = &ath9k_wowlan_support; |
842 | 843 | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index b096bb2c28c8..c585c9b35973 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -79,6 +79,63 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
79 | 0x6661), | 79 | 0x6661), |
80 | .driver_data = ATH9K_PCI_CUS217 }, | 80 | .driver_data = ATH9K_PCI_CUS217 }, |
81 | 81 | ||
82 | /* AR9462 with WoW support */ | ||
83 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
84 | 0x0034, | ||
85 | PCI_VENDOR_ID_ATHEROS, | ||
86 | 0x3117), | ||
87 | .driver_data = ATH9K_PCI_WOW }, | ||
88 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
89 | 0x0034, | ||
90 | PCI_VENDOR_ID_LENOVO, | ||
91 | 0x3214), | ||
92 | .driver_data = ATH9K_PCI_WOW }, | ||
93 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
94 | 0x0034, | ||
95 | PCI_VENDOR_ID_ATTANSIC, | ||
96 | 0x0091), | ||
97 | .driver_data = ATH9K_PCI_WOW }, | ||
98 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
99 | 0x0034, | ||
100 | PCI_VENDOR_ID_AZWAVE, | ||
101 | 0x2110), | ||
102 | .driver_data = ATH9K_PCI_WOW }, | ||
103 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
104 | 0x0034, | ||
105 | PCI_VENDOR_ID_ASUSTEK, | ||
106 | 0x850E), | ||
107 | .driver_data = ATH9K_PCI_WOW }, | ||
108 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
109 | 0x0034, | ||
110 | 0x11AD, /* LITEON */ | ||
111 | 0x6631), | ||
112 | .driver_data = ATH9K_PCI_WOW }, | ||
113 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
114 | 0x0034, | ||
115 | 0x11AD, /* LITEON */ | ||
116 | 0x6641), | ||
117 | .driver_data = ATH9K_PCI_WOW }, | ||
118 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
119 | 0x0034, | ||
120 | PCI_VENDOR_ID_HP, | ||
121 | 0x1864), | ||
122 | .driver_data = ATH9K_PCI_WOW }, | ||
123 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
124 | 0x0034, | ||
125 | 0x14CD, /* USI */ | ||
126 | 0x0063), | ||
127 | .driver_data = ATH9K_PCI_WOW }, | ||
128 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
129 | 0x0034, | ||
130 | 0x14CD, /* USI */ | ||
131 | 0x0064), | ||
132 | .driver_data = ATH9K_PCI_WOW }, | ||
133 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
134 | 0x0034, | ||
135 | 0x10CF, /* Fujitsu */ | ||
136 | 0x1783), | ||
137 | .driver_data = ATH9K_PCI_WOW }, | ||
138 | |||
82 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ | 139 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ |
83 | { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ | 140 | { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ |
84 | { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ | 141 | { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index f7c90cc58d56..5af97442ac37 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -806,6 +806,7 @@ | |||
806 | #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ | 806 | #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ |
807 | #define AR_SREV_VERSION_9462 0x280 | 807 | #define AR_SREV_VERSION_9462 0x280 |
808 | #define AR_SREV_REVISION_9462_20 2 | 808 | #define AR_SREV_REVISION_9462_20 2 |
809 | #define AR_SREV_REVISION_9462_21 3 | ||
809 | #define AR_SREV_VERSION_9565 0x2C0 | 810 | #define AR_SREV_VERSION_9565 0x2C0 |
810 | #define AR_SREV_REVISION_9565_10 0 | 811 | #define AR_SREV_REVISION_9565_10 0 |
811 | #define AR_SREV_VERSION_9550 0x400 | 812 | #define AR_SREV_VERSION_9550 0x400 |
@@ -911,10 +912,18 @@ | |||
911 | 912 | ||
912 | #define AR_SREV_9462(_ah) \ | 913 | #define AR_SREV_9462(_ah) \ |
913 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) | 914 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) |
914 | |||
915 | #define AR_SREV_9462_20(_ah) \ | 915 | #define AR_SREV_9462_20(_ah) \ |
916 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | 916 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ |
917 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) | 917 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) |
918 | #define AR_SREV_9462_21(_ah) \ | ||
919 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | ||
920 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21)) | ||
921 | #define AR_SREV_9462_20_OR_LATER(_ah) \ | ||
922 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | ||
923 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) | ||
924 | #define AR_SREV_9462_21_OR_LATER(_ah) \ | ||
925 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | ||
926 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21)) | ||
918 | 927 | ||
919 | #define AR_SREV_9565(_ah) \ | 928 | #define AR_SREV_9565(_ah) \ |
920 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) | 929 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 7e19d9b5214e..c59ae43b9b35 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1673,6 +1673,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
1673 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) | 1673 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) |
1674 | return; | 1674 | return; |
1675 | 1675 | ||
1676 | rcu_read_lock(); | ||
1677 | |||
1676 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); | 1678 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); |
1677 | last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); | 1679 | last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); |
1678 | 1680 | ||
@@ -1711,8 +1713,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
1711 | 1713 | ||
1712 | if (ac == last_ac || | 1714 | if (ac == last_ac || |
1713 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) | 1715 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) |
1714 | return; | 1716 | break; |
1715 | } | 1717 | } |
1718 | |||
1719 | rcu_read_unlock(); | ||
1716 | } | 1720 | } |
1717 | 1721 | ||
1718 | /***********/ | 1722 | /***********/ |
@@ -1778,9 +1782,13 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1778 | } | 1782 | } |
1779 | 1783 | ||
1780 | if (!internal) { | 1784 | if (!internal) { |
1781 | txq->axq_depth++; | 1785 | while (bf) { |
1782 | if (bf_is_ampdu_not_probing(bf)) | 1786 | txq->axq_depth++; |
1783 | txq->axq_ampdu_depth++; | 1787 | if (bf_is_ampdu_not_probing(bf)) |
1788 | txq->axq_ampdu_depth++; | ||
1789 | |||
1790 | bf = bf->bf_lastbf->bf_next; | ||
1791 | } | ||
1784 | } | 1792 | } |
1785 | } | 1793 | } |
1786 | 1794 | ||
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index e1c492b9dfef..d240b24e1ccf 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -621,7 +621,8 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, | |||
621 | return NULL; | 621 | return NULL; |
622 | } | 622 | } |
623 | 623 | ||
624 | static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len) | 624 | static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, |
625 | int vring_index) | ||
625 | { | 626 | { |
626 | wil_desc_addr_set(&d->dma.addr, pa); | 627 | wil_desc_addr_set(&d->dma.addr, pa); |
627 | d->dma.ip_length = 0; | 628 | d->dma.ip_length = 0; |
@@ -630,7 +631,7 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len) | |||
630 | d->dma.error = 0; | 631 | d->dma.error = 0; |
631 | d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ | 632 | d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ |
632 | d->dma.length = cpu_to_le16((u16)len); | 633 | d->dma.length = cpu_to_le16((u16)len); |
633 | d->dma.d0 = 0; | 634 | d->dma.d0 = (vring_index << DMA_CFG_DESC_TX_0_QID_POS); |
634 | d->mac.d[0] = 0; | 635 | d->mac.d[0] = 0; |
635 | d->mac.d[1] = 0; | 636 | d->mac.d[1] = 0; |
636 | d->mac.d[2] = 0; | 637 | d->mac.d[2] = 0; |
@@ -684,7 +685,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
684 | if (unlikely(dma_mapping_error(dev, pa))) | 685 | if (unlikely(dma_mapping_error(dev, pa))) |
685 | return -EINVAL; | 686 | return -EINVAL; |
686 | /* 1-st segment */ | 687 | /* 1-st segment */ |
687 | wil_tx_desc_map(d, pa, skb_headlen(skb)); | 688 | wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); |
688 | d->mac.d[2] |= ((nr_frags + 1) << | 689 | d->mac.d[2] |= ((nr_frags + 1) << |
689 | MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); | 690 | MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); |
690 | if (nr_frags) | 691 | if (nr_frags) |
@@ -701,15 +702,14 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
701 | DMA_TO_DEVICE); | 702 | DMA_TO_DEVICE); |
702 | if (unlikely(dma_mapping_error(dev, pa))) | 703 | if (unlikely(dma_mapping_error(dev, pa))) |
703 | goto dma_error; | 704 | goto dma_error; |
704 | wil_tx_desc_map(d, pa, len); | 705 | wil_tx_desc_map(d, pa, len, vring_index); |
705 | vring->ctx[i] = NULL; | 706 | vring->ctx[i] = NULL; |
706 | *_d = *d; | 707 | *_d = *d; |
707 | } | 708 | } |
708 | /* for the last seg only */ | 709 | /* for the last seg only */ |
709 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); | 710 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); |
710 | d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ | 711 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS); |
711 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); | 712 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); |
712 | d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS); | ||
713 | *_d = *d; | 713 | *_d = *d; |
714 | 714 | ||
715 | wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, | 715 | wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index 23c0781cdb93..859aea68a1fa 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h | |||
@@ -201,6 +201,10 @@ struct vring_tx_mac { | |||
201 | #define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1 | 201 | #define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1 |
202 | #define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100 | 202 | #define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100 |
203 | 203 | ||
204 | #define DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS 9 | ||
205 | #define DMA_CFG_DESC_TX_0_CMD_MARK_WB_LEN 1 | ||
206 | #define DMA_CFG_DESC_TX_0_CMD_MARK_WB_MSK 0x200 | ||
207 | |||
204 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10 | 208 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10 |
205 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1 | 209 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1 |
206 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400 | 210 | #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400 |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 3f21e0ba39ba..51ff0b198d0a 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -31,12 +31,6 @@ config B43_BCMA | |||
31 | depends on B43 && (BCMA = y || BCMA = B43) | 31 | depends on B43 && (BCMA = y || BCMA = B43) |
32 | default y | 32 | default y |
33 | 33 | ||
34 | config B43_BCMA_EXTRA | ||
35 | bool "Hardware support that overlaps with the brcmsmac driver" | ||
36 | depends on B43_BCMA | ||
37 | default n if BRCMSMAC | ||
38 | default y | ||
39 | |||
40 | config B43_SSB | 34 | config B43_SSB |
41 | bool | 35 | bool |
42 | depends on B43 && (SSB = y || SSB = B43) | 36 | depends on B43 && (SSB = y || SSB = B43) |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index a95b77ab360e..0e933bb71543 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -113,13 +113,15 @@ static int b43_modparam_pio = 0; | |||
113 | module_param_named(pio, b43_modparam_pio, int, 0644); | 113 | module_param_named(pio, b43_modparam_pio, int, 0644); |
114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); | 114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); |
115 | 115 | ||
116 | static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC); | ||
117 | module_param_named(allhwsupport, modparam_allhwsupport, int, 0444); | ||
118 | MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)"); | ||
119 | |||
116 | #ifdef CONFIG_B43_BCMA | 120 | #ifdef CONFIG_B43_BCMA |
117 | static const struct bcma_device_id b43_bcma_tbl[] = { | 121 | static const struct bcma_device_id b43_bcma_tbl[] = { |
118 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), | 122 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), |
119 | #ifdef CONFIG_B43_BCMA_EXTRA | ||
120 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), | 123 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), |
121 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), | 124 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), |
122 | #endif | ||
123 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), | 125 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), |
124 | BCMA_CORETABLE_END | 126 | BCMA_CORETABLE_END |
125 | }; | 127 | }; |
@@ -5396,6 +5398,12 @@ static int b43_bcma_probe(struct bcma_device *core) | |||
5396 | struct b43_wl *wl; | 5398 | struct b43_wl *wl; |
5397 | int err; | 5399 | int err; |
5398 | 5400 | ||
5401 | if (!modparam_allhwsupport && | ||
5402 | (core->id.rev == 0x17 || core->id.rev == 0x18)) { | ||
5403 | pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n"); | ||
5404 | return -ENOTSUPP; | ||
5405 | } | ||
5406 | |||
5399 | dev = b43_bus_dev_bcma_init(core); | 5407 | dev = b43_bus_dev_bcma_init(core); |
5400 | if (!dev) | 5408 | if (!dev) |
5401 | return -ENODEV; | 5409 | return -ENODEV; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3f8e69c29146..e3f3c48f86d4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -162,7 +162,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | int | 165 | static int |
166 | brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | 166 | brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) |
167 | { | 167 | { |
168 | int err = 0, i; | 168 | int err = 0, i; |
@@ -193,12 +193,33 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | |||
193 | return err; | 193 | return err; |
194 | } | 194 | } |
195 | 195 | ||
196 | static int | ||
197 | brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) | ||
198 | { | ||
199 | uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; | ||
200 | int err = 0; | ||
201 | |||
202 | if (bar0 != sdiodev->sbwad) { | ||
203 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); | ||
204 | if (err) | ||
205 | return err; | ||
206 | |||
207 | sdiodev->sbwad = bar0; | ||
208 | } | ||
209 | |||
210 | *addr &= SBSDIO_SB_OFT_ADDR_MASK; | ||
211 | |||
212 | if (width == 4) | ||
213 | *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
196 | int | 218 | int |
197 | brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | 219 | brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, |
198 | void *data, bool write) | 220 | void *data, bool write) |
199 | { | 221 | { |
200 | u8 func_num, reg_size; | 222 | u8 func_num, reg_size; |
201 | u32 bar; | ||
202 | s32 retry = 0; | 223 | s32 retry = 0; |
203 | int ret; | 224 | int ret; |
204 | 225 | ||
@@ -218,18 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
218 | func_num = SDIO_FUNC_1; | 239 | func_num = SDIO_FUNC_1; |
219 | reg_size = 4; | 240 | reg_size = 4; |
220 | 241 | ||
221 | /* Set the window for SB core register */ | 242 | brcmf_sdio_addrprep(sdiodev, reg_size, &addr); |
222 | bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | ||
223 | if (bar != sdiodev->sbwad) { | ||
224 | ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar); | ||
225 | if (ret != 0) { | ||
226 | memset(data, 0xFF, reg_size); | ||
227 | return ret; | ||
228 | } | ||
229 | sdiodev->sbwad = bar; | ||
230 | } | ||
231 | addr &= SBSDIO_SB_OFT_ADDR_MASK; | ||
232 | addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | ||
233 | } | 243 | } |
234 | 244 | ||
235 | do { | 245 | do { |
@@ -321,10 +331,11 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
321 | bool write, u32 addr, struct sk_buff_head *pktlist) | 331 | bool write, u32 addr, struct sk_buff_head *pktlist) |
322 | { | 332 | { |
323 | unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; | 333 | unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; |
324 | unsigned int max_blks, max_req_sz; | 334 | unsigned int max_blks, max_req_sz, orig_offset, dst_offset; |
325 | unsigned short max_seg_sz, seg_sz; | 335 | unsigned short max_seg_sz, seg_sz; |
326 | unsigned char *pkt_data; | 336 | unsigned char *pkt_data, *orig_data, *dst_data; |
327 | struct sk_buff *pkt_next = NULL; | 337 | struct sk_buff *pkt_next = NULL, *local_pkt_next; |
338 | struct sk_buff_head local_list, *target_list; | ||
328 | struct mmc_request mmc_req; | 339 | struct mmc_request mmc_req; |
329 | struct mmc_command mmc_cmd; | 340 | struct mmc_command mmc_cmd; |
330 | struct mmc_data mmc_dat; | 341 | struct mmc_data mmc_dat; |
@@ -361,6 +372,32 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
361 | req_sz); | 372 | req_sz); |
362 | } | 373 | } |
363 | 374 | ||
375 | target_list = pktlist; | ||
376 | /* for host with broken sg support, prepare a page aligned list */ | ||
377 | __skb_queue_head_init(&local_list); | ||
378 | if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { | ||
379 | req_sz = 0; | ||
380 | skb_queue_walk(pktlist, pkt_next) | ||
381 | req_sz += pkt_next->len; | ||
382 | req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize); | ||
383 | while (req_sz > PAGE_SIZE) { | ||
384 | pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE); | ||
385 | if (pkt_next == NULL) { | ||
386 | ret = -ENOMEM; | ||
387 | goto exit; | ||
388 | } | ||
389 | __skb_queue_tail(&local_list, pkt_next); | ||
390 | req_sz -= PAGE_SIZE; | ||
391 | } | ||
392 | pkt_next = brcmu_pkt_buf_get_skb(req_sz); | ||
393 | if (pkt_next == NULL) { | ||
394 | ret = -ENOMEM; | ||
395 | goto exit; | ||
396 | } | ||
397 | __skb_queue_tail(&local_list, pkt_next); | ||
398 | target_list = &local_list; | ||
399 | } | ||
400 | |||
364 | host = sdiodev->func[fn]->card->host; | 401 | host = sdiodev->func[fn]->card->host; |
365 | func_blk_sz = sdiodev->func[fn]->cur_blksize; | 402 | func_blk_sz = sdiodev->func[fn]->cur_blksize; |
366 | /* Blocks per command is limited by host count, host transfer | 403 | /* Blocks per command is limited by host count, host transfer |
@@ -370,13 +407,15 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
370 | max_req_sz = min_t(unsigned int, host->max_req_size, | 407 | max_req_sz = min_t(unsigned int, host->max_req_size, |
371 | max_blks * func_blk_sz); | 408 | max_blks * func_blk_sz); |
372 | max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); | 409 | max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); |
373 | max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen); | 410 | max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen); |
374 | seg_sz = pktlist->qlen; | 411 | seg_sz = target_list->qlen; |
375 | pkt_offset = 0; | 412 | pkt_offset = 0; |
376 | pkt_next = pktlist->next; | 413 | pkt_next = target_list->next; |
377 | 414 | ||
378 | if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) | 415 | if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) { |
379 | return -ENOMEM; | 416 | ret = -ENOMEM; |
417 | goto exit; | ||
418 | } | ||
380 | 419 | ||
381 | while (seg_sz) { | 420 | while (seg_sz) { |
382 | req_sz = 0; | 421 | req_sz = 0; |
@@ -386,7 +425,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
386 | memset(&mmc_dat, 0, sizeof(struct mmc_data)); | 425 | memset(&mmc_dat, 0, sizeof(struct mmc_data)); |
387 | sgl = st.sgl; | 426 | sgl = st.sgl; |
388 | /* prep sg table */ | 427 | /* prep sg table */ |
389 | while (pkt_next != (struct sk_buff *)pktlist) { | 428 | while (pkt_next != (struct sk_buff *)target_list) { |
390 | pkt_data = pkt_next->data + pkt_offset; | 429 | pkt_data = pkt_next->data + pkt_offset; |
391 | sg_data_sz = pkt_next->len - pkt_offset; | 430 | sg_data_sz = pkt_next->len - pkt_offset; |
392 | if (sg_data_sz > host->max_seg_size) | 431 | if (sg_data_sz > host->max_seg_size) |
@@ -413,8 +452,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
413 | if (req_sz % func_blk_sz != 0) { | 452 | if (req_sz % func_blk_sz != 0) { |
414 | brcmf_err("sg request length %u is not %u aligned\n", | 453 | brcmf_err("sg request length %u is not %u aligned\n", |
415 | req_sz, func_blk_sz); | 454 | req_sz, func_blk_sz); |
416 | sg_free_table(&st); | 455 | ret = -ENOTBLK; |
417 | return -ENOTBLK; | 456 | goto exit; |
418 | } | 457 | } |
419 | mmc_dat.sg = st.sgl; | 458 | mmc_dat.sg = st.sgl; |
420 | mmc_dat.sg_len = sg_cnt; | 459 | mmc_dat.sg_len = sg_cnt; |
@@ -447,35 +486,36 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
447 | } | 486 | } |
448 | } | 487 | } |
449 | 488 | ||
450 | sg_free_table(&st); | 489 | if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { |
451 | 490 | local_pkt_next = local_list.next; | |
452 | return ret; | 491 | orig_offset = 0; |
453 | } | 492 | skb_queue_walk(pktlist, pkt_next) { |
454 | 493 | dst_offset = 0; | |
455 | static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, | 494 | do { |
456 | uint flags, uint width, u32 *addr) | 495 | req_sz = local_pkt_next->len - orig_offset; |
457 | { | 496 | req_sz = min_t(uint, pkt_next->len - dst_offset, |
458 | uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; | 497 | req_sz); |
459 | int err = 0; | 498 | orig_data = local_pkt_next->data + orig_offset; |
460 | 499 | dst_data = pkt_next->data + dst_offset; | |
461 | /* Async not implemented yet */ | 500 | memcpy(dst_data, orig_data, req_sz); |
462 | if (flags & SDIO_REQ_ASYNC) | 501 | orig_offset += req_sz; |
463 | return -ENOTSUPP; | 502 | dst_offset += req_sz; |
464 | 503 | if (orig_offset == local_pkt_next->len) { | |
465 | if (bar0 != sdiodev->sbwad) { | 504 | orig_offset = 0; |
466 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); | 505 | local_pkt_next = local_pkt_next->next; |
467 | if (err) | 506 | } |
468 | return err; | 507 | if (dst_offset == pkt_next->len) |
469 | 508 | break; | |
470 | sdiodev->sbwad = bar0; | 509 | } while (!skb_queue_empty(&local_list)); |
510 | } | ||
471 | } | 511 | } |
472 | 512 | ||
473 | *addr &= SBSDIO_SB_OFT_ADDR_MASK; | 513 | exit: |
474 | 514 | sg_free_table(&st); | |
475 | if (width == 4) | 515 | while ((pkt_next = __skb_dequeue(&local_list)) != NULL) |
476 | *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | 516 | brcmu_pkt_buf_free_skb(pkt_next); |
477 | 517 | ||
478 | return 0; | 518 | return ret; |
479 | } | 519 | } |
480 | 520 | ||
481 | int | 521 | int |
@@ -512,7 +552,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
512 | fn, addr, pkt->len); | 552 | fn, addr, pkt->len); |
513 | 553 | ||
514 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 554 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
515 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 555 | err = brcmf_sdio_addrprep(sdiodev, width, &addr); |
516 | if (err) | 556 | if (err) |
517 | goto done; | 557 | goto done; |
518 | 558 | ||
@@ -536,7 +576,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
536 | fn, addr, pktq->qlen); | 576 | fn, addr, pktq->qlen); |
537 | 577 | ||
538 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 578 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
539 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 579 | err = brcmf_sdio_addrprep(sdiodev, width, &addr); |
540 | if (err) | 580 | if (err) |
541 | goto done; | 581 | goto done; |
542 | 582 | ||
@@ -574,37 +614,20 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
574 | uint flags, struct sk_buff *pkt) | 614 | uint flags, struct sk_buff *pkt) |
575 | { | 615 | { |
576 | uint width; | 616 | uint width; |
577 | uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | ||
578 | int err = 0; | 617 | int err = 0; |
579 | struct sk_buff_head pkt_list; | 618 | struct sk_buff_head pkt_list; |
580 | 619 | ||
581 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", | 620 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", |
582 | fn, addr, pkt->len); | 621 | fn, addr, pkt->len); |
583 | 622 | ||
584 | /* Async not implemented yet */ | ||
585 | if (flags & SDIO_REQ_ASYNC) | ||
586 | return -ENOTSUPP; | ||
587 | |||
588 | if (bar0 != sdiodev->sbwad) { | ||
589 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); | ||
590 | if (err) | ||
591 | goto done; | ||
592 | |||
593 | sdiodev->sbwad = bar0; | ||
594 | } | ||
595 | |||
596 | addr &= SBSDIO_SB_OFT_ADDR_MASK; | ||
597 | |||
598 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 623 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
599 | if (width == 4) | 624 | brcmf_sdio_addrprep(sdiodev, width, &addr); |
600 | addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | ||
601 | 625 | ||
602 | skb_queue_head_init(&pkt_list); | 626 | skb_queue_head_init(&pkt_list); |
603 | skb_queue_tail(&pkt_list, pkt); | 627 | skb_queue_tail(&pkt_list, pkt); |
604 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); | 628 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); |
605 | skb_dequeue_tail(&pkt_list); | 629 | skb_dequeue_tail(&pkt_list); |
606 | 630 | ||
607 | done: | ||
608 | return err; | 631 | return err; |
609 | } | 632 | } |
610 | 633 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 8c402e7b97eb..8e8975562ec3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -281,8 +281,6 @@ void brcmf_txflowblock(struct device *dev, bool state) | |||
281 | 281 | ||
282 | void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) | 282 | void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) |
283 | { | 283 | { |
284 | unsigned char *eth; | ||
285 | uint len; | ||
286 | struct sk_buff *skb, *pnext; | 284 | struct sk_buff *skb, *pnext; |
287 | struct brcmf_if *ifp; | 285 | struct brcmf_if *ifp; |
288 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 286 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
@@ -306,33 +304,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) | |||
306 | continue; | 304 | continue; |
307 | } | 305 | } |
308 | 306 | ||
309 | /* Get the protocol, maintain skb around eth_type_trans() | ||
310 | * The main reason for this hack is for the limitation of | ||
311 | * Linux 2.4 where 'eth_type_trans' uses the | ||
312 | * 'net->hard_header_len' | ||
313 | * to perform skb_pull inside vs ETH_HLEN. Since to avoid | ||
314 | * coping of the packet coming from the network stack to add | ||
315 | * BDC, Hardware header etc, during network interface | ||
316 | * registration | ||
317 | * we set the 'net->hard_header_len' to ETH_HLEN + extra space | ||
318 | * required | ||
319 | * for BDC, Hardware header etc. and not just the ETH_HLEN | ||
320 | */ | ||
321 | eth = skb->data; | ||
322 | len = skb->len; | ||
323 | |||
324 | skb->dev = ifp->ndev; | 307 | skb->dev = ifp->ndev; |
325 | skb->protocol = eth_type_trans(skb, skb->dev); | 308 | skb->protocol = eth_type_trans(skb, skb->dev); |
326 | 309 | ||
327 | if (skb->pkt_type == PACKET_MULTICAST) | 310 | if (skb->pkt_type == PACKET_MULTICAST) |
328 | ifp->stats.multicast++; | 311 | ifp->stats.multicast++; |
329 | 312 | ||
330 | skb->data = eth; | ||
331 | skb->len = len; | ||
332 | |||
333 | /* Strip header, count, deliver upward */ | ||
334 | skb_pull(skb, ETH_HLEN); | ||
335 | |||
336 | /* Process special event packets */ | 313 | /* Process special event packets */ |
337 | brcmf_fweh_process_skb(drvr, skb); | 314 | brcmf_fweh_process_skb(drvr, skb); |
338 | 315 | ||
@@ -348,10 +325,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) | |||
348 | netif_rx(skb); | 325 | netif_rx(skb); |
349 | else | 326 | else |
350 | /* If the receive is not processed inside an ISR, | 327 | /* If the receive is not processed inside an ISR, |
351 | * the softirqd must be woken explicitly to service | 328 | * the softirqd must be woken explicitly to service the |
352 | * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled | 329 | * NET_RX_SOFTIRQ. This is handled by netif_rx_ni(). |
353 | * by netif_rx_ni(), but in earlier kernels, we need | ||
354 | * to do it manually. | ||
355 | */ | 330 | */ |
356 | netif_rx_ni(skb); | 331 | netif_rx_ni(skb); |
357 | } | 332 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 13e75c4b1a6b..f0d9f7f6c83d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
@@ -796,9 +796,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) | |||
796 | u8 fillers; | 796 | u8 fillers; |
797 | __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); | 797 | __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); |
798 | 798 | ||
799 | brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u (%u), pkttag=0x%08X, hslot=%d\n", | 799 | brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n", |
800 | entry->ea, entry->interface_id, | 800 | entry->name, brcmf_skb_if_flags_get_field(skb, INDEX), |
801 | brcmf_skb_if_flags_get_field(skb, INDEX), | ||
802 | le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); | 801 | le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); |
803 | if (entry->send_tim_signal) | 802 | if (entry->send_tim_signal) |
804 | data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; | 803 | data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; |
@@ -822,8 +821,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) | |||
822 | wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; | 821 | wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; |
823 | wlh[2] = entry->mac_handle; | 822 | wlh[2] = entry->mac_handle; |
824 | wlh[3] = entry->traffic_pending_bmp; | 823 | wlh[3] = entry->traffic_pending_bmp; |
825 | brcmf_dbg(TRACE, "adding TIM info: %02X:%02X:%02X:%02X\n", | 824 | brcmf_dbg(TRACE, "adding TIM info: handle %d bmp 0x%X\n", |
826 | wlh[0], wlh[1], wlh[2], wlh[3]); | 825 | entry->mac_handle, entry->traffic_pending_bmp); |
827 | wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2; | 826 | wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2; |
828 | entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; | 827 | entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; |
829 | } | 828 | } |
@@ -906,10 +905,26 @@ static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) | |||
906 | return 0; | 905 | return 0; |
907 | } | 906 | } |
908 | 907 | ||
908 | /* using macro so sparse checking does not complain | ||
909 | * about locking imbalance. | ||
910 | */ | ||
911 | #define brcmf_fws_lock(drvr, flags) \ | ||
912 | do { \ | ||
913 | flags = 0; \ | ||
914 | spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \ | ||
915 | } while (0) | ||
916 | |||
917 | /* using macro so sparse checking does not complain | ||
918 | * about locking imbalance. | ||
919 | */ | ||
920 | #define brcmf_fws_unlock(drvr, flags) \ | ||
921 | spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags)) | ||
922 | |||
909 | static | 923 | static |
910 | int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | 924 | int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) |
911 | { | 925 | { |
912 | struct brcmf_fws_mac_descriptor *entry, *existing; | 926 | struct brcmf_fws_mac_descriptor *entry, *existing; |
927 | ulong flags; | ||
913 | u8 mac_handle; | 928 | u8 mac_handle; |
914 | u8 ifidx; | 929 | u8 ifidx; |
915 | u8 *addr; | 930 | u8 *addr; |
@@ -923,8 +938,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | |||
923 | if (entry->occupied) { | 938 | if (entry->occupied) { |
924 | brcmf_dbg(TRACE, "deleting %s mac %pM\n", | 939 | brcmf_dbg(TRACE, "deleting %s mac %pM\n", |
925 | entry->name, addr); | 940 | entry->name, addr); |
941 | brcmf_fws_lock(fws->drvr, flags); | ||
926 | brcmf_fws_macdesc_cleanup(fws, entry, -1); | 942 | brcmf_fws_macdesc_cleanup(fws, entry, -1); |
927 | brcmf_fws_macdesc_deinit(entry); | 943 | brcmf_fws_macdesc_deinit(entry); |
944 | brcmf_fws_unlock(fws->drvr, flags); | ||
928 | } else | 945 | } else |
929 | fws->stats.mac_update_failed++; | 946 | fws->stats.mac_update_failed++; |
930 | return 0; | 947 | return 0; |
@@ -933,11 +950,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | |||
933 | existing = brcmf_fws_macdesc_lookup(fws, addr); | 950 | existing = brcmf_fws_macdesc_lookup(fws, addr); |
934 | if (IS_ERR(existing)) { | 951 | if (IS_ERR(existing)) { |
935 | if (!entry->occupied) { | 952 | if (!entry->occupied) { |
953 | brcmf_fws_lock(fws->drvr, flags); | ||
936 | entry->mac_handle = mac_handle; | 954 | entry->mac_handle = mac_handle; |
937 | brcmf_fws_macdesc_init(entry, addr, ifidx); | 955 | brcmf_fws_macdesc_init(entry, addr, ifidx); |
938 | brcmf_fws_macdesc_set_name(fws, entry); | 956 | brcmf_fws_macdesc_set_name(fws, entry); |
939 | brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, | 957 | brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, |
940 | BRCMF_FWS_PSQ_LEN); | 958 | BRCMF_FWS_PSQ_LEN); |
959 | brcmf_fws_unlock(fws->drvr, flags); | ||
941 | brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr); | 960 | brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr); |
942 | } else { | 961 | } else { |
943 | fws->stats.mac_update_failed++; | 962 | fws->stats.mac_update_failed++; |
@@ -945,11 +964,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | |||
945 | } else { | 964 | } else { |
946 | if (entry != existing) { | 965 | if (entry != existing) { |
947 | brcmf_dbg(TRACE, "copy mac %s\n", existing->name); | 966 | brcmf_dbg(TRACE, "copy mac %s\n", existing->name); |
967 | brcmf_fws_lock(fws->drvr, flags); | ||
948 | memcpy(entry, existing, | 968 | memcpy(entry, existing, |
949 | offsetof(struct brcmf_fws_mac_descriptor, psq)); | 969 | offsetof(struct brcmf_fws_mac_descriptor, psq)); |
950 | entry->mac_handle = mac_handle; | 970 | entry->mac_handle = mac_handle; |
951 | brcmf_fws_macdesc_deinit(existing); | 971 | brcmf_fws_macdesc_deinit(existing); |
952 | brcmf_fws_macdesc_set_name(fws, entry); | 972 | brcmf_fws_macdesc_set_name(fws, entry); |
973 | brcmf_fws_unlock(fws->drvr, flags); | ||
953 | brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name, | 974 | brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name, |
954 | addr); | 975 | addr); |
955 | } else { | 976 | } else { |
@@ -965,7 +986,9 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws, | |||
965 | u8 type, u8 *data) | 986 | u8 type, u8 *data) |
966 | { | 987 | { |
967 | struct brcmf_fws_mac_descriptor *entry; | 988 | struct brcmf_fws_mac_descriptor *entry; |
989 | ulong flags; | ||
968 | u8 mac_handle; | 990 | u8 mac_handle; |
991 | int ret; | ||
969 | 992 | ||
970 | mac_handle = data[0]; | 993 | mac_handle = data[0]; |
971 | entry = &fws->desc.nodes[mac_handle & 0x1F]; | 994 | entry = &fws->desc.nodes[mac_handle & 0x1F]; |
@@ -973,26 +996,30 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws, | |||
973 | fws->stats.mac_ps_update_failed++; | 996 | fws->stats.mac_ps_update_failed++; |
974 | return -ESRCH; | 997 | return -ESRCH; |
975 | } | 998 | } |
999 | brcmf_fws_lock(fws->drvr, flags); | ||
976 | /* a state update should wipe old credits */ | 1000 | /* a state update should wipe old credits */ |
977 | entry->requested_credit = 0; | 1001 | entry->requested_credit = 0; |
978 | entry->requested_packet = 0; | 1002 | entry->requested_packet = 0; |
979 | if (type == BRCMF_FWS_TYPE_MAC_OPEN) { | 1003 | if (type == BRCMF_FWS_TYPE_MAC_OPEN) { |
980 | entry->state = BRCMF_FWS_STATE_OPEN; | 1004 | entry->state = BRCMF_FWS_STATE_OPEN; |
981 | return BRCMF_FWS_RET_OK_SCHEDULE; | 1005 | ret = BRCMF_FWS_RET_OK_SCHEDULE; |
982 | } else { | 1006 | } else { |
983 | entry->state = BRCMF_FWS_STATE_CLOSE; | 1007 | entry->state = BRCMF_FWS_STATE_CLOSE; |
984 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false); | 1008 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false); |
985 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false); | 1009 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false); |
986 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false); | 1010 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false); |
987 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true); | 1011 | brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true); |
1012 | ret = BRCMF_FWS_RET_OK_NOSCHEDULE; | ||
988 | } | 1013 | } |
989 | return BRCMF_FWS_RET_OK_NOSCHEDULE; | 1014 | brcmf_fws_unlock(fws->drvr, flags); |
1015 | return ret; | ||
990 | } | 1016 | } |
991 | 1017 | ||
992 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | 1018 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, |
993 | u8 type, u8 *data) | 1019 | u8 type, u8 *data) |
994 | { | 1020 | { |
995 | struct brcmf_fws_mac_descriptor *entry; | 1021 | struct brcmf_fws_mac_descriptor *entry; |
1022 | ulong flags; | ||
996 | u8 ifidx; | 1023 | u8 ifidx; |
997 | int ret; | 1024 | int ret; |
998 | 1025 | ||
@@ -1011,17 +1038,24 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | |||
1011 | 1038 | ||
1012 | brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type, | 1039 | brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type, |
1013 | entry->name); | 1040 | entry->name); |
1041 | brcmf_fws_lock(fws->drvr, flags); | ||
1014 | switch (type) { | 1042 | switch (type) { |
1015 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | 1043 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: |
1016 | entry->state = BRCMF_FWS_STATE_OPEN; | 1044 | entry->state = BRCMF_FWS_STATE_OPEN; |
1017 | return BRCMF_FWS_RET_OK_SCHEDULE; | 1045 | ret = BRCMF_FWS_RET_OK_SCHEDULE; |
1046 | break; | ||
1018 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | 1047 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: |
1019 | entry->state = BRCMF_FWS_STATE_CLOSE; | 1048 | entry->state = BRCMF_FWS_STATE_CLOSE; |
1020 | return BRCMF_FWS_RET_OK_NOSCHEDULE; | 1049 | ret = BRCMF_FWS_RET_OK_NOSCHEDULE; |
1050 | break; | ||
1021 | default: | 1051 | default: |
1022 | ret = -EINVAL; | 1052 | ret = -EINVAL; |
1023 | break; | 1053 | brcmf_fws_unlock(fws->drvr, flags); |
1054 | goto fail; | ||
1024 | } | 1055 | } |
1056 | brcmf_fws_unlock(fws->drvr, flags); | ||
1057 | return ret; | ||
1058 | |||
1025 | fail: | 1059 | fail: |
1026 | fws->stats.if_update_failed++; | 1060 | fws->stats.if_update_failed++; |
1027 | return ret; | 1061 | return ret; |
@@ -1031,6 +1065,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type, | |||
1031 | u8 *data) | 1065 | u8 *data) |
1032 | { | 1066 | { |
1033 | struct brcmf_fws_mac_descriptor *entry; | 1067 | struct brcmf_fws_mac_descriptor *entry; |
1068 | ulong flags; | ||
1034 | 1069 | ||
1035 | entry = &fws->desc.nodes[data[1] & 0x1F]; | 1070 | entry = &fws->desc.nodes[data[1] & 0x1F]; |
1036 | if (!entry->occupied) { | 1071 | if (!entry->occupied) { |
@@ -1044,12 +1079,14 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type, | |||
1044 | brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n", | 1079 | brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n", |
1045 | brcmf_fws_get_tlv_name(type), type, entry->name, | 1080 | brcmf_fws_get_tlv_name(type), type, entry->name, |
1046 | data[0], data[2]); | 1081 | data[0], data[2]); |
1082 | brcmf_fws_lock(fws->drvr, flags); | ||
1047 | if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT) | 1083 | if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT) |
1048 | entry->requested_credit = data[0]; | 1084 | entry->requested_credit = data[0]; |
1049 | else | 1085 | else |
1050 | entry->requested_packet = data[0]; | 1086 | entry->requested_packet = data[0]; |
1051 | 1087 | ||
1052 | entry->ac_bitmap = data[2]; | 1088 | entry->ac_bitmap = data[2]; |
1089 | brcmf_fws_unlock(fws->drvr, flags); | ||
1053 | return BRCMF_FWS_RET_OK_SCHEDULE; | 1090 | return BRCMF_FWS_RET_OK_SCHEDULE; |
1054 | } | 1091 | } |
1055 | 1092 | ||
@@ -1346,6 +1383,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, | |||
1346 | static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, | 1383 | static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, |
1347 | u8 *data) | 1384 | u8 *data) |
1348 | { | 1385 | { |
1386 | ulong flags; | ||
1349 | int i; | 1387 | int i; |
1350 | 1388 | ||
1351 | if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { | 1389 | if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { |
@@ -1354,16 +1392,19 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, | |||
1354 | } | 1392 | } |
1355 | 1393 | ||
1356 | brcmf_dbg(DATA, "enter: data %pM\n", data); | 1394 | brcmf_dbg(DATA, "enter: data %pM\n", data); |
1395 | brcmf_fws_lock(fws->drvr, flags); | ||
1357 | for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++) | 1396 | for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++) |
1358 | brcmf_fws_return_credits(fws, i, data[i]); | 1397 | brcmf_fws_return_credits(fws, i, data[i]); |
1359 | 1398 | ||
1360 | brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map, | 1399 | brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map, |
1361 | fws->fifo_delay_map); | 1400 | fws->fifo_delay_map); |
1401 | brcmf_fws_unlock(fws->drvr, flags); | ||
1362 | return BRCMF_FWS_RET_OK_SCHEDULE; | 1402 | return BRCMF_FWS_RET_OK_SCHEDULE; |
1363 | } | 1403 | } |
1364 | 1404 | ||
1365 | static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) | 1405 | static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) |
1366 | { | 1406 | { |
1407 | ulong lflags; | ||
1367 | __le32 status_le; | 1408 | __le32 status_le; |
1368 | u32 status; | 1409 | u32 status; |
1369 | u32 hslot; | 1410 | u32 hslot; |
@@ -1377,7 +1418,10 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) | |||
1377 | hslot = brcmf_txstatus_get_field(status, HSLOT); | 1418 | hslot = brcmf_txstatus_get_field(status, HSLOT); |
1378 | genbit = brcmf_txstatus_get_field(status, GENERATION); | 1419 | genbit = brcmf_txstatus_get_field(status, GENERATION); |
1379 | 1420 | ||
1380 | return brcmf_fws_txs_process(fws, flags, hslot, genbit); | 1421 | brcmf_fws_lock(fws->drvr, lflags); |
1422 | brcmf_fws_txs_process(fws, flags, hslot, genbit); | ||
1423 | brcmf_fws_unlock(fws->drvr, lflags); | ||
1424 | return BRCMF_FWS_RET_OK_NOSCHEDULE; | ||
1381 | } | 1425 | } |
1382 | 1426 | ||
1383 | static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) | 1427 | static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) |
@@ -1390,21 +1434,6 @@ static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) | |||
1390 | return 0; | 1434 | return 0; |
1391 | } | 1435 | } |
1392 | 1436 | ||
1393 | /* using macro so sparse checking does not complain | ||
1394 | * about locking imbalance. | ||
1395 | */ | ||
1396 | #define brcmf_fws_lock(drvr, flags) \ | ||
1397 | do { \ | ||
1398 | flags = 0; \ | ||
1399 | spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \ | ||
1400 | } while (0) | ||
1401 | |||
1402 | /* using macro so sparse checking does not complain | ||
1403 | * about locking imbalance. | ||
1404 | */ | ||
1405 | #define brcmf_fws_unlock(drvr, flags) \ | ||
1406 | spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags)) | ||
1407 | |||
1408 | static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp, | 1437 | static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp, |
1409 | const struct brcmf_event_msg *e, | 1438 | const struct brcmf_event_msg *e, |
1410 | void *data) | 1439 | void *data) |
@@ -1455,7 +1484,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
1455 | struct sk_buff *skb) | 1484 | struct sk_buff *skb) |
1456 | { | 1485 | { |
1457 | struct brcmf_fws_info *fws = drvr->fws; | 1486 | struct brcmf_fws_info *fws = drvr->fws; |
1458 | ulong flags; | ||
1459 | u8 *signal_data; | 1487 | u8 *signal_data; |
1460 | s16 data_len; | 1488 | s16 data_len; |
1461 | u8 type; | 1489 | u8 type; |
@@ -1475,9 +1503,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
1475 | return 0; | 1503 | return 0; |
1476 | } | 1504 | } |
1477 | 1505 | ||
1478 | /* lock during tlv parsing */ | ||
1479 | brcmf_fws_lock(drvr, flags); | ||
1480 | |||
1481 | fws->stats.header_pulls++; | 1506 | fws->stats.header_pulls++; |
1482 | data_len = signal_len; | 1507 | data_len = signal_len; |
1483 | signal_data = skb->data; | 1508 | signal_data = skb->data; |
@@ -1571,25 +1596,17 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
1571 | if (skb->len == 0) | 1596 | if (skb->len == 0) |
1572 | fws->stats.header_only_pkt++; | 1597 | fws->stats.header_only_pkt++; |
1573 | 1598 | ||
1574 | brcmf_fws_unlock(drvr, flags); | ||
1575 | return 0; | 1599 | return 0; |
1576 | } | 1600 | } |
1577 | 1601 | ||
1578 | static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, | 1602 | static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, |
1579 | struct sk_buff *p) | 1603 | struct sk_buff *p) |
1580 | { | 1604 | { |
1581 | struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); | 1605 | struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); |
1582 | struct brcmf_fws_mac_descriptor *entry = skcb->mac; | 1606 | struct brcmf_fws_mac_descriptor *entry = skcb->mac; |
1583 | int rc = 0; | ||
1584 | bool first_time; | ||
1585 | int hslot = BRCMF_FWS_HANGER_MAXITEMS; | ||
1586 | u8 free_ctr; | ||
1587 | u8 flags; | 1607 | u8 flags; |
1588 | 1608 | ||
1589 | first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED; | ||
1590 | |||
1591 | brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); | 1609 | brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); |
1592 | brcmf_skb_htod_tag_set_field(p, FIFO, fifo); | ||
1593 | brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); | 1610 | brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); |
1594 | flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; | 1611 | flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; |
1595 | if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { | 1612 | if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { |
@@ -1600,80 +1617,36 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, | |||
1600 | flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; | 1617 | flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; |
1601 | } | 1618 | } |
1602 | brcmf_skb_htod_tag_set_field(p, FLAGS, flags); | 1619 | brcmf_skb_htod_tag_set_field(p, FLAGS, flags); |
1603 | if (first_time) { | 1620 | brcmf_fws_hdrpush(fws, p); |
1604 | /* obtaining free slot may fail, but that will be caught | ||
1605 | * by the hanger push. This assures the packet has a BDC | ||
1606 | * header upon return. | ||
1607 | */ | ||
1608 | hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); | ||
1609 | free_ctr = entry->seq[fifo]; | ||
1610 | brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); | ||
1611 | brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr); | ||
1612 | rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot); | ||
1613 | if (rc) | ||
1614 | brcmf_err("hanger push failed: rc=%d\n", rc); | ||
1615 | } | ||
1616 | |||
1617 | if (rc == 0) | ||
1618 | brcmf_fws_hdrpush(fws, p); | ||
1619 | |||
1620 | return rc; | ||
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | static void | 1623 | static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, |
1624 | brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, | 1624 | struct sk_buff *skb, int fifo) |
1625 | struct sk_buff *skb, int fifo) | ||
1626 | { | 1625 | { |
1627 | /* | ||
1628 | put the packet back to the head of queue | ||
1629 | |||
1630 | - suppressed packet goes back to suppress sub-queue | ||
1631 | - pull out the header, if new or delayed packet | ||
1632 | |||
1633 | Note: hslot is used only when header removal is done. | ||
1634 | */ | ||
1635 | struct brcmf_fws_mac_descriptor *entry; | 1626 | struct brcmf_fws_mac_descriptor *entry; |
1636 | enum brcmf_fws_skb_state state; | ||
1637 | struct sk_buff *pktout; | 1627 | struct sk_buff *pktout; |
1628 | int qidx, hslot; | ||
1638 | int rc = 0; | 1629 | int rc = 0; |
1639 | int hslot; | ||
1640 | 1630 | ||
1641 | state = brcmf_skbcb(skb)->state; | ||
1642 | entry = brcmf_skbcb(skb)->mac; | 1631 | entry = brcmf_skbcb(skb)->mac; |
1643 | hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); | 1632 | if (entry->occupied) { |
1644 | 1633 | qidx = 2 * fifo; | |
1645 | if (entry != NULL) { | 1634 | if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_SUPPRESSED) |
1646 | if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { | 1635 | qidx++; |
1647 | /* wl-header is saved for suppressed packets */ | 1636 | |
1648 | pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1, | 1637 | pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb); |
1649 | skb); | 1638 | if (pktout == NULL) { |
1650 | if (pktout == NULL) { | 1639 | brcmf_err("%s queue %d full\n", entry->name, qidx); |
1651 | brcmf_err("suppress queue full\n"); | 1640 | rc = -ENOSPC; |
1652 | rc = -ENOSPC; | ||
1653 | } | ||
1654 | } else { | ||
1655 | /* delay-q packets are going to delay-q */ | ||
1656 | pktout = brcmu_pktq_penq_head(&entry->psq, | ||
1657 | 2 * fifo, skb); | ||
1658 | if (pktout == NULL) { | ||
1659 | brcmf_err("delay queue full\n"); | ||
1660 | rc = -ENOSPC; | ||
1661 | } | ||
1662 | |||
1663 | /* free the hanger slot */ | ||
1664 | brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout, | ||
1665 | true); | ||
1666 | |||
1667 | /* decrement sequence count */ | ||
1668 | entry->seq[fifo]--; | ||
1669 | } | 1641 | } |
1670 | } else { | 1642 | } else { |
1671 | brcmf_err("no mac entry linked\n"); | 1643 | brcmf_err("%s entry removed\n", entry->name); |
1672 | rc = -ENOENT; | 1644 | rc = -ENOENT; |
1673 | } | 1645 | } |
1674 | 1646 | ||
1675 | if (rc) { | 1647 | if (rc) { |
1676 | fws->stats.rollback_failed++; | 1648 | fws->stats.rollback_failed++; |
1649 | hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); | ||
1677 | brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, | 1650 | brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, |
1678 | hslot, 0); | 1651 | hslot, 0); |
1679 | } else { | 1652 | } else { |
@@ -1707,37 +1680,6 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws) | |||
1707 | return -ENAVAIL; | 1680 | return -ENAVAIL; |
1708 | } | 1681 | } |
1709 | 1682 | ||
1710 | static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo, | ||
1711 | struct sk_buff *skb) | ||
1712 | { | ||
1713 | struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; | ||
1714 | int *credit = &fws->fifo_credit[fifo]; | ||
1715 | |||
1716 | if (fifo != BRCMF_FWS_FIFO_AC_BE) | ||
1717 | fws->borrow_defer_timestamp = jiffies + | ||
1718 | BRCMF_FWS_BORROW_DEFER_PERIOD; | ||
1719 | |||
1720 | if (!(*credit)) { | ||
1721 | /* Try to borrow a credit from other queue */ | ||
1722 | if (fifo != BRCMF_FWS_FIFO_AC_BE || | ||
1723 | (brcmf_fws_borrow_credit(fws) != 0)) { | ||
1724 | brcmf_dbg(DATA, "ac=%d, credits depleted\n", fifo); | ||
1725 | return -ENAVAIL; | ||
1726 | } | ||
1727 | } else { | ||
1728 | (*credit)--; | ||
1729 | if (!(*credit)) | ||
1730 | fws->fifo_credit_map &= ~(1 << fifo); | ||
1731 | } | ||
1732 | |||
1733 | brcmf_fws_macdesc_use_req_credit(entry, skb); | ||
1734 | |||
1735 | brcmf_dbg(DATA, "ac=%d, credits=%02d:%02d:%02d:%02d\n", fifo, | ||
1736 | fws->fifo_credit[0], fws->fifo_credit[1], | ||
1737 | fws->fifo_credit[2], fws->fifo_credit[3]); | ||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1741 | static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, | 1683 | static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, |
1742 | struct sk_buff *skb) | 1684 | struct sk_buff *skb) |
1743 | { | 1685 | { |
@@ -1751,15 +1693,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, | |||
1751 | if (IS_ERR(entry)) | 1693 | if (IS_ERR(entry)) |
1752 | return PTR_ERR(entry); | 1694 | return PTR_ERR(entry); |
1753 | 1695 | ||
1754 | rc = brcmf_fws_precommit_skb(fws, fifo, skb); | 1696 | brcmf_fws_precommit_skb(fws, fifo, skb); |
1755 | if (rc < 0) { | ||
1756 | fws->stats.generic_error++; | ||
1757 | goto rollback; | ||
1758 | } | ||
1759 | |||
1760 | brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, | ||
1761 | skcb->htod); | ||
1762 | rc = brcmf_bus_txdata(bus, skb); | 1697 | rc = brcmf_bus_txdata(bus, skb); |
1698 | brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name, | ||
1699 | skcb->if_flags, skcb->htod, rc); | ||
1763 | if (rc < 0) { | 1700 | if (rc < 0) { |
1764 | brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); | 1701 | brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); |
1765 | goto rollback; | 1702 | goto rollback; |
@@ -1768,7 +1705,6 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, | |||
1768 | entry->transit_count++; | 1705 | entry->transit_count++; |
1769 | if (entry->suppressed) | 1706 | if (entry->suppressed) |
1770 | entry->suppr_transit_count++; | 1707 | entry->suppr_transit_count++; |
1771 | entry->seq[fifo]++; | ||
1772 | fws->stats.pkt2bus++; | 1708 | fws->stats.pkt2bus++; |
1773 | fws->stats.send_pkts[fifo]++; | 1709 | fws->stats.send_pkts[fifo]++; |
1774 | if (brcmf_skb_if_flags_get_field(skb, REQUESTED)) | 1710 | if (brcmf_skb_if_flags_get_field(skb, REQUESTED)) |
@@ -1781,6 +1717,24 @@ rollback: | |||
1781 | return rc; | 1717 | return rc; |
1782 | } | 1718 | } |
1783 | 1719 | ||
1720 | static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p, | ||
1721 | int fifo) | ||
1722 | { | ||
1723 | struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); | ||
1724 | int rc, hslot; | ||
1725 | |||
1726 | hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); | ||
1727 | brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); | ||
1728 | brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]); | ||
1729 | brcmf_skb_htod_tag_set_field(p, FIFO, fifo); | ||
1730 | rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot); | ||
1731 | if (!rc) | ||
1732 | skcb->mac->seq[fifo]++; | ||
1733 | else | ||
1734 | fws->stats.generic_error++; | ||
1735 | return rc; | ||
1736 | } | ||
1737 | |||
1784 | int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | 1738 | int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) |
1785 | { | 1739 | { |
1786 | struct brcmf_pub *drvr = ifp->drvr; | 1740 | struct brcmf_pub *drvr = ifp->drvr; |
@@ -1809,33 +1763,25 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
1809 | 1763 | ||
1810 | /* set control buffer information */ | 1764 | /* set control buffer information */ |
1811 | skcb->if_flags = 0; | 1765 | skcb->if_flags = 0; |
1812 | skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest); | ||
1813 | skcb->state = BRCMF_FWS_SKBSTATE_NEW; | 1766 | skcb->state = BRCMF_FWS_SKBSTATE_NEW; |
1814 | brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); | 1767 | brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); |
1815 | if (!multicast) | 1768 | if (!multicast) |
1816 | fifo = brcmf_fws_prio2fifo[skb->priority]; | 1769 | fifo = brcmf_fws_prio2fifo[skb->priority]; |
1817 | 1770 | ||
1771 | brcmf_fws_lock(drvr, flags); | ||
1772 | if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC) | ||
1773 | fws->borrow_defer_timestamp = jiffies + | ||
1774 | BRCMF_FWS_BORROW_DEFER_PERIOD; | ||
1775 | |||
1776 | skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest); | ||
1818 | brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name, | 1777 | brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name, |
1819 | eh->h_dest, multicast, fifo); | 1778 | eh->h_dest, multicast, fifo); |
1820 | 1779 | if (!brcmf_fws_assign_htod(fws, skb, fifo)) { | |
1821 | brcmf_fws_lock(drvr, flags); | ||
1822 | /* multicast credit support is conditional, setting | ||
1823 | * flag to false to assure credit is consumed below. | ||
1824 | */ | ||
1825 | if (fws->bcmc_credit_check) | ||
1826 | multicast = false; | ||
1827 | |||
1828 | if (skcb->mac->suppressed || | ||
1829 | fws->bus_flow_blocked || | ||
1830 | brcmf_fws_macdesc_closed(fws, skcb->mac, fifo) || | ||
1831 | brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) || | ||
1832 | (!multicast && | ||
1833 | brcmf_fws_consume_credit(fws, fifo, skb) < 0)) { | ||
1834 | /* enqueue the packet in delayQ */ | ||
1835 | drvr->fws->fifo_delay_map |= 1 << fifo; | ||
1836 | brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); | 1780 | brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); |
1781 | brcmf_fws_schedule_deq(fws); | ||
1837 | } else { | 1782 | } else { |
1838 | brcmf_fws_commit_skb(fws, fifo, skb); | 1783 | brcmf_err("drop skb: no hanger slot\n"); |
1784 | brcmu_pkt_buf_free_skb(skb); | ||
1839 | } | 1785 | } |
1840 | brcmf_fws_unlock(drvr, flags); | 1786 | brcmf_fws_unlock(drvr, flags); |
1841 | return 0; | 1787 | return 0; |
@@ -1895,7 +1841,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) | |||
1895 | fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work); | 1841 | fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work); |
1896 | 1842 | ||
1897 | brcmf_fws_lock(fws->drvr, flags); | 1843 | brcmf_fws_lock(fws->drvr, flags); |
1898 | for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked; | 1844 | for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked; |
1899 | fifo--) { | 1845 | fifo--) { |
1900 | while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) && | 1846 | while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) && |
1901 | (fifo == BRCMF_FWS_FIFO_BCMC))) { | 1847 | (fifo == BRCMF_FWS_FIFO_BCMC))) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 793df66fe0bf..09786a539950 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
@@ -229,8 +229,6 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
229 | #define SDIO_REQ_4BYTE 0x1 | 229 | #define SDIO_REQ_4BYTE 0x1 |
230 | /* Fixed address (FIFO) (vs. incrementing address) */ | 230 | /* Fixed address (FIFO) (vs. incrementing address) */ |
231 | #define SDIO_REQ_FIXED 0x2 | 231 | #define SDIO_REQ_FIXED 0x2 |
232 | /* Async request (vs. sync request) */ | ||
233 | #define SDIO_REQ_ASYNC 0x4 | ||
234 | 232 | ||
235 | /* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). | 233 | /* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). |
236 | * rw: read or write (0/1) | 234 | * rw: read or write (0/1) |
@@ -251,9 +249,6 @@ extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); | |||
251 | extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); | 249 | extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); |
252 | extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); | 250 | extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); |
253 | 251 | ||
254 | extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, | ||
255 | u32 address); | ||
256 | |||
257 | /* attach, return handler on success, NULL if failed. | 252 | /* attach, return handler on success, NULL if failed. |
258 | * The handler shall be provided by all subsequent calls. No local cache | 253 | * The handler shall be provided by all subsequent calls. No local cache |
259 | * cfghdl points to the starting address of pci device mapped memory | 254 | * cfghdl points to the starting address of pci device mapped memory |
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h index 243e96353d13..1ad7d3602520 100644 --- a/drivers/net/wireless/cw1200/cw1200.h +++ b/drivers/net/wireless/cw1200/cw1200.h | |||
@@ -267,7 +267,7 @@ struct cw1200_common { | |||
267 | struct delayed_work bss_loss_work; | 267 | struct delayed_work bss_loss_work; |
268 | spinlock_t bss_loss_lock; /* Protect BSS loss state */ | 268 | spinlock_t bss_loss_lock; /* Protect BSS loss state */ |
269 | int bss_loss_state; | 269 | int bss_loss_state; |
270 | int bss_loss_confirm_id; | 270 | u32 bss_loss_confirm_id; |
271 | int delayed_link_loss; | 271 | int delayed_link_loss; |
272 | struct work_struct bss_params_work; | 272 | struct work_struct bss_params_work; |
273 | 273 | ||
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index 953bd1904d3d..d06376014bcd 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c | |||
@@ -61,7 +61,7 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self, | |||
61 | void *dst, int count) | 61 | void *dst, int count) |
62 | { | 62 | { |
63 | int ret, i; | 63 | int ret, i; |
64 | uint16_t regaddr; | 64 | u16 regaddr; |
65 | struct spi_message m; | 65 | struct spi_message m; |
66 | 66 | ||
67 | struct spi_transfer t_addr = { | 67 | struct spi_transfer t_addr = { |
@@ -76,15 +76,18 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self, | |||
76 | regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; | 76 | regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; |
77 | regaddr |= SET_READ; | 77 | regaddr |= SET_READ; |
78 | regaddr |= (count>>1); | 78 | regaddr |= (count>>1); |
79 | regaddr = cpu_to_le16(regaddr); | ||
80 | 79 | ||
81 | #ifdef SPI_DEBUG | 80 | #ifdef SPI_DEBUG |
82 | pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, | 81 | pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr); |
83 | le16_to_cpu(regaddr)); | ||
84 | #endif | 82 | #endif |
85 | 83 | ||
84 | /* Header is LE16 */ | ||
85 | regaddr = cpu_to_le16(regaddr); | ||
86 | |||
87 | /* We have to byteswap if the SPI bus is limited to 8b operation | ||
88 | or we are running on a Big Endian system | ||
89 | */ | ||
86 | #if defined(__LITTLE_ENDIAN) | 90 | #if defined(__LITTLE_ENDIAN) |
87 | /* We have to byteswap if the SPI bus is limited to 8b operation */ | ||
88 | if (self->func->bits_per_word == 8) | 91 | if (self->func->bits_per_word == 8) |
89 | #endif | 92 | #endif |
90 | regaddr = swab16(regaddr); | 93 | regaddr = swab16(regaddr); |
@@ -104,8 +107,10 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self, | |||
104 | printk("\n"); | 107 | printk("\n"); |
105 | #endif | 108 | #endif |
106 | 109 | ||
110 | /* We have to byteswap if the SPI bus is limited to 8b operation | ||
111 | or we are running on a Big Endian system | ||
112 | */ | ||
107 | #if defined(__LITTLE_ENDIAN) | 113 | #if defined(__LITTLE_ENDIAN) |
108 | /* We have to byteswap if the SPI bus is limited to 8b operation */ | ||
109 | if (self->func->bits_per_word == 8) | 114 | if (self->func->bits_per_word == 8) |
110 | #endif | 115 | #endif |
111 | { | 116 | { |
@@ -122,7 +127,7 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self, | |||
122 | const void *src, int count) | 127 | const void *src, int count) |
123 | { | 128 | { |
124 | int rval, i; | 129 | int rval, i; |
125 | uint16_t regaddr; | 130 | u16 regaddr; |
126 | struct spi_transfer t_addr = { | 131 | struct spi_transfer t_addr = { |
127 | .tx_buf = ®addr, | 132 | .tx_buf = ®addr, |
128 | .len = sizeof(regaddr), | 133 | .len = sizeof(regaddr), |
@@ -136,20 +141,23 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self, | |||
136 | regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; | 141 | regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; |
137 | regaddr &= SET_WRITE; | 142 | regaddr &= SET_WRITE; |
138 | regaddr |= (count>>1); | 143 | regaddr |= (count>>1); |
139 | regaddr = cpu_to_le16(regaddr); | ||
140 | 144 | ||
141 | #ifdef SPI_DEBUG | 145 | #ifdef SPI_DEBUG |
142 | pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, | 146 | pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, regaddr); |
143 | le16_to_cpu(regaddr)); | ||
144 | #endif | 147 | #endif |
145 | 148 | ||
149 | /* Header is LE16 */ | ||
150 | regaddr = cpu_to_le16(regaddr); | ||
151 | |||
152 | /* We have to byteswap if the SPI bus is limited to 8b operation | ||
153 | or we are running on a Big Endian system | ||
154 | */ | ||
146 | #if defined(__LITTLE_ENDIAN) | 155 | #if defined(__LITTLE_ENDIAN) |
147 | /* We have to byteswap if the SPI bus is limited to 8b operation */ | ||
148 | if (self->func->bits_per_word == 8) | 156 | if (self->func->bits_per_word == 8) |
149 | #endif | 157 | #endif |
150 | { | 158 | { |
151 | uint16_t *buf = (uint16_t *)src; | 159 | uint16_t *buf = (uint16_t *)src; |
152 | regaddr = swab16(regaddr); | 160 | regaddr = swab16(regaddr); |
153 | for (i = 0; i < ((count + 1) >> 1); i++) | 161 | for (i = 0; i < ((count + 1) >> 1); i++) |
154 | buf[i] = swab16(buf[i]); | 162 | buf[i] = swab16(buf[i]); |
155 | } | 163 | } |
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c index dad3fb331818..ff230b7aeedd 100644 --- a/drivers/net/wireless/cw1200/hwio.c +++ b/drivers/net/wireless/cw1200/hwio.c | |||
@@ -69,31 +69,33 @@ static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr, | |||
69 | static inline int __cw1200_reg_read_32(struct cw1200_common *priv, | 69 | static inline int __cw1200_reg_read_32(struct cw1200_common *priv, |
70 | u16 addr, u32 *val) | 70 | u16 addr, u32 *val) |
71 | { | 71 | { |
72 | int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); | 72 | __le32 tmp; |
73 | *val = le32_to_cpu(*val); | 73 | int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0); |
74 | *val = le32_to_cpu(tmp); | ||
74 | return i; | 75 | return i; |
75 | } | 76 | } |
76 | 77 | ||
77 | static inline int __cw1200_reg_write_32(struct cw1200_common *priv, | 78 | static inline int __cw1200_reg_write_32(struct cw1200_common *priv, |
78 | u16 addr, u32 val) | 79 | u16 addr, u32 val) |
79 | { | 80 | { |
80 | val = cpu_to_le32(val); | 81 | __le32 tmp = cpu_to_le32(val); |
81 | return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); | 82 | return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0); |
82 | } | 83 | } |
83 | 84 | ||
84 | static inline int __cw1200_reg_read_16(struct cw1200_common *priv, | 85 | static inline int __cw1200_reg_read_16(struct cw1200_common *priv, |
85 | u16 addr, u16 *val) | 86 | u16 addr, u16 *val) |
86 | { | 87 | { |
87 | int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); | 88 | __le16 tmp; |
88 | *val = le16_to_cpu(*val); | 89 | int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0); |
90 | *val = le16_to_cpu(tmp); | ||
89 | return i; | 91 | return i; |
90 | } | 92 | } |
91 | 93 | ||
92 | static inline int __cw1200_reg_write_16(struct cw1200_common *priv, | 94 | static inline int __cw1200_reg_write_16(struct cw1200_common *priv, |
93 | u16 addr, u16 val) | 95 | u16 addr, u16 val) |
94 | { | 96 | { |
95 | val = cpu_to_le16(val); | 97 | __le16 tmp = cpu_to_le16(val); |
96 | return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); | 98 | return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0); |
97 | } | 99 | } |
98 | 100 | ||
99 | int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf, | 101 | int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf, |
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h index 563329cfead6..ddf52669dc5b 100644 --- a/drivers/net/wireless/cw1200/hwio.h +++ b/drivers/net/wireless/cw1200/hwio.h | |||
@@ -169,35 +169,34 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr, | |||
169 | static inline int cw1200_reg_read_16(struct cw1200_common *priv, | 169 | static inline int cw1200_reg_read_16(struct cw1200_common *priv, |
170 | u16 addr, u16 *val) | 170 | u16 addr, u16 *val) |
171 | { | 171 | { |
172 | u32 tmp; | 172 | __le32 tmp; |
173 | int i; | 173 | int i; |
174 | i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); | 174 | i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); |
175 | tmp = le32_to_cpu(tmp); | 175 | *val = le32_to_cpu(tmp) & 0xfffff; |
176 | *val = tmp & 0xffff; | ||
177 | return i; | 176 | return i; |
178 | } | 177 | } |
179 | 178 | ||
180 | static inline int cw1200_reg_write_16(struct cw1200_common *priv, | 179 | static inline int cw1200_reg_write_16(struct cw1200_common *priv, |
181 | u16 addr, u16 val) | 180 | u16 addr, u16 val) |
182 | { | 181 | { |
183 | u32 tmp = val; | 182 | __le32 tmp = cpu_to_le32((u32)val); |
184 | tmp = cpu_to_le32(tmp); | ||
185 | return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); | 183 | return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); |
186 | } | 184 | } |
187 | 185 | ||
188 | static inline int cw1200_reg_read_32(struct cw1200_common *priv, | 186 | static inline int cw1200_reg_read_32(struct cw1200_common *priv, |
189 | u16 addr, u32 *val) | 187 | u16 addr, u32 *val) |
190 | { | 188 | { |
191 | int i = cw1200_reg_read(priv, addr, val, sizeof(*val)); | 189 | __le32 tmp; |
192 | *val = le32_to_cpu(*val); | 190 | int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); |
191 | *val = le32_to_cpu(tmp); | ||
193 | return i; | 192 | return i; |
194 | } | 193 | } |
195 | 194 | ||
196 | static inline int cw1200_reg_write_32(struct cw1200_common *priv, | 195 | static inline int cw1200_reg_write_32(struct cw1200_common *priv, |
197 | u16 addr, u32 val) | 196 | u16 addr, u32 val) |
198 | { | 197 | { |
199 | val = cpu_to_le32(val); | 198 | __le32 tmp = cpu_to_le32(val); |
200 | return cw1200_reg_write(priv, addr, &val, sizeof(val)); | 199 | return cw1200_reg_write(priv, addr, &tmp, sizeof(val)); |
201 | } | 200 | } |
202 | 201 | ||
203 | int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, | 202 | int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, |
@@ -224,22 +223,24 @@ static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr, | |||
224 | static inline int cw1200_apb_read_32(struct cw1200_common *priv, | 223 | static inline int cw1200_apb_read_32(struct cw1200_common *priv, |
225 | u32 addr, u32 *val) | 224 | u32 addr, u32 *val) |
226 | { | 225 | { |
227 | int i = cw1200_apb_read(priv, addr, val, sizeof(*val)); | 226 | __le32 tmp; |
228 | *val = le32_to_cpu(*val); | 227 | int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp)); |
228 | *val = le32_to_cpu(tmp); | ||
229 | return i; | 229 | return i; |
230 | } | 230 | } |
231 | 231 | ||
232 | static inline int cw1200_apb_write_32(struct cw1200_common *priv, | 232 | static inline int cw1200_apb_write_32(struct cw1200_common *priv, |
233 | u32 addr, u32 val) | 233 | u32 addr, u32 val) |
234 | { | 234 | { |
235 | val = cpu_to_le32(val); | 235 | __le32 tmp = cpu_to_le32(val); |
236 | return cw1200_apb_write(priv, addr, &val, sizeof(val)); | 236 | return cw1200_apb_write(priv, addr, &tmp, sizeof(val)); |
237 | } | 237 | } |
238 | static inline int cw1200_ahb_read_32(struct cw1200_common *priv, | 238 | static inline int cw1200_ahb_read_32(struct cw1200_common *priv, |
239 | u32 addr, u32 *val) | 239 | u32 addr, u32 *val) |
240 | { | 240 | { |
241 | int i = cw1200_ahb_read(priv, addr, val, sizeof(*val)); | 241 | __le32 tmp; |
242 | *val = le32_to_cpu(*val); | 242 | int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp)); |
243 | *val = le32_to_cpu(tmp); | ||
243 | return i; | 244 | return i; |
244 | } | 245 | } |
245 | 246 | ||
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c index da885036ca5f..3724e739cbf4 100644 --- a/drivers/net/wireless/cw1200/main.c +++ b/drivers/net/wireless/cw1200/main.c | |||
@@ -238,8 +238,8 @@ static const struct ieee80211_ops cw1200_ops = { | |||
238 | /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */ | 238 | /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */ |
239 | }; | 239 | }; |
240 | 240 | ||
241 | int cw1200_ba_rx_tids = -1; | 241 | static int cw1200_ba_rx_tids = -1; |
242 | int cw1200_ba_tx_tids = -1; | 242 | static int cw1200_ba_tx_tids = -1; |
243 | module_param(cw1200_ba_rx_tids, int, 0644); | 243 | module_param(cw1200_ba_rx_tids, int, 0644); |
244 | module_param(cw1200_ba_tx_tids, int, 0644); | 244 | module_param(cw1200_ba_tx_tids, int, 0644); |
245 | MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs"); | 245 | MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs"); |
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c index 8510454d5db1..9c3925f58d79 100644 --- a/drivers/net/wireless/cw1200/queue.c +++ b/drivers/net/wireless/cw1200/queue.c | |||
@@ -355,7 +355,7 @@ int cw1200_queue_get(struct cw1200_queue *queue, | |||
355 | *tx = (struct wsm_tx *)item->skb->data; | 355 | *tx = (struct wsm_tx *)item->skb->data; |
356 | *tx_info = IEEE80211_SKB_CB(item->skb); | 356 | *tx_info = IEEE80211_SKB_CB(item->skb); |
357 | *txpriv = &item->txpriv; | 357 | *txpriv = &item->txpriv; |
358 | (*tx)->packet_id = __cpu_to_le32(item->packet_id); | 358 | (*tx)->packet_id = item->packet_id; |
359 | list_move_tail(&item->head, &queue->pending); | 359 | list_move_tail(&item->head, &queue->pending); |
360 | ++queue->num_pending; | 360 | ++queue->num_pending; |
361 | --queue->link_map_cache[item->txpriv.link_id]; | 361 | --queue->link_map_cache[item->txpriv.link_id]; |
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c index 4cd0352b508d..7365674366f4 100644 --- a/drivers/net/wireless/cw1200/sta.c +++ b/drivers/net/wireless/cw1200/sta.c | |||
@@ -621,7 +621,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif, | |||
621 | mutex_lock(&priv->conf_mutex); | 621 | mutex_lock(&priv->conf_mutex); |
622 | 622 | ||
623 | if (queue < dev->queues) { | 623 | if (queue < dev->queues) { |
624 | old_uapsd_flags = priv->uapsd_info.uapsd_flags; | 624 | old_uapsd_flags = le16_to_cpu(priv->uapsd_info.uapsd_flags); |
625 | 625 | ||
626 | WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0); | 626 | WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0); |
627 | ret = wsm_set_tx_queue_params(priv, | 627 | ret = wsm_set_tx_queue_params(priv, |
@@ -645,7 +645,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif, | |||
645 | ret = cw1200_set_uapsd_param(priv, &priv->edca); | 645 | ret = cw1200_set_uapsd_param(priv, &priv->edca); |
646 | if (!ret && priv->setbssparams_done && | 646 | if (!ret && priv->setbssparams_done && |
647 | (priv->join_status == CW1200_JOIN_STATUS_STA) && | 647 | (priv->join_status == CW1200_JOIN_STATUS_STA) && |
648 | (old_uapsd_flags != priv->uapsd_info.uapsd_flags)) | 648 | (old_uapsd_flags != le16_to_cpu(priv->uapsd_info.uapsd_flags))) |
649 | ret = cw1200_set_pm(priv, &priv->powersave_mode); | 649 | ret = cw1200_set_pm(priv, &priv->powersave_mode); |
650 | } | 650 | } |
651 | } else { | 651 | } else { |
@@ -1089,18 +1089,18 @@ static int cw1200_parse_sdd_file(struct cw1200_common *priv) | |||
1089 | ret = -1; | 1089 | ret = -1; |
1090 | break; | 1090 | break; |
1091 | } | 1091 | } |
1092 | v = le16_to_cpu(*((u16 *)(p + 2))); | 1092 | v = le16_to_cpu(*((__le16 *)(p + 2))); |
1093 | if (!v) /* non-zero means this is enabled */ | 1093 | if (!v) /* non-zero means this is enabled */ |
1094 | break; | 1094 | break; |
1095 | 1095 | ||
1096 | v = le16_to_cpu(*((u16 *)(p + 4))); | 1096 | v = le16_to_cpu(*((__le16 *)(p + 4))); |
1097 | priv->conf_listen_interval = (v >> 7) & 0x1F; | 1097 | priv->conf_listen_interval = (v >> 7) & 0x1F; |
1098 | pr_debug("PTA found; Listen Interval %d\n", | 1098 | pr_debug("PTA found; Listen Interval %d\n", |
1099 | priv->conf_listen_interval); | 1099 | priv->conf_listen_interval); |
1100 | break; | 1100 | break; |
1101 | } | 1101 | } |
1102 | case SDD_REFERENCE_FREQUENCY_ELT_ID: { | 1102 | case SDD_REFERENCE_FREQUENCY_ELT_ID: { |
1103 | u16 clk = le16_to_cpu(*((u16 *)(p + 2))); | 1103 | u16 clk = le16_to_cpu(*((__le16 *)(p + 2))); |
1104 | if (clk != priv->hw_refclk) | 1104 | if (clk != priv->hw_refclk) |
1105 | pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n", | 1105 | pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n", |
1106 | clk, priv->hw_refclk); | 1106 | clk, priv->hw_refclk); |
@@ -1785,9 +1785,9 @@ static int cw1200_set_btcoexinfo(struct cw1200_common *priv) | |||
1785 | } else { | 1785 | } else { |
1786 | pr_debug("[STA] STA has non ERP rates\n"); | 1786 | pr_debug("[STA] STA has non ERP rates\n"); |
1787 | /* B only mode */ | 1787 | /* B only mode */ |
1788 | arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set)); | 1788 | arg.internalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set))); |
1789 | } | 1789 | } |
1790 | arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set)); | 1790 | arg.nonErpInternalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set))); |
1791 | } else { | 1791 | } else { |
1792 | /* P2P mode */ | 1792 | /* P2P mode */ |
1793 | arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF)); | 1793 | arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF)); |
@@ -1908,7 +1908,7 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev, | |||
1908 | 1908 | ||
1909 | if (info->assoc || info->ibss_joined) { | 1909 | if (info->assoc || info->ibss_joined) { |
1910 | struct ieee80211_sta *sta = NULL; | 1910 | struct ieee80211_sta *sta = NULL; |
1911 | u32 val = 0; | 1911 | __le32 htprot = 0; |
1912 | 1912 | ||
1913 | if (info->dtim_period) | 1913 | if (info->dtim_period) |
1914 | priv->join_dtim_period = info->dtim_period; | 1914 | priv->join_dtim_period = info->dtim_period; |
@@ -1935,19 +1935,18 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev, | |||
1935 | /* Non Greenfield stations present */ | 1935 | /* Non Greenfield stations present */ |
1936 | if (priv->ht_info.operation_mode & | 1936 | if (priv->ht_info.operation_mode & |
1937 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) | 1937 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) |
1938 | val |= WSM_NON_GREENFIELD_STA_PRESENT; | 1938 | htprot |= cpu_to_le32(WSM_NON_GREENFIELD_STA_PRESENT); |
1939 | 1939 | ||
1940 | /* Set HT protection method */ | 1940 | /* Set HT protection method */ |
1941 | val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2; | 1941 | htprot |= cpu_to_le32((priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2); |
1942 | 1942 | ||
1943 | /* TODO: | 1943 | /* TODO: |
1944 | * STBC_param.dual_cts | 1944 | * STBC_param.dual_cts |
1945 | * STBC_param.LSIG_TXOP_FILL | 1945 | * STBC_param.LSIG_TXOP_FILL |
1946 | */ | 1946 | */ |
1947 | 1947 | ||
1948 | val = cpu_to_le32(val); | ||
1949 | wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION, | 1948 | wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION, |
1950 | &val, sizeof(val)); | 1949 | &htprot, sizeof(htprot)); |
1951 | 1950 | ||
1952 | priv->association_mode.greenfield = | 1951 | priv->association_mode.greenfield = |
1953 | cw1200_ht_greenfield(&priv->ht_info); | 1952 | cw1200_ht_greenfield(&priv->ht_info); |
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c index 44ca10cb0d39..5862c373d714 100644 --- a/drivers/net/wireless/cw1200/txrx.c +++ b/drivers/net/wireless/cw1200/txrx.c | |||
@@ -599,15 +599,15 @@ cw1200_tx_h_bt(struct cw1200_common *priv, | |||
599 | } else if (ieee80211_is_data(t->hdr->frame_control)) { | 599 | } else if (ieee80211_is_data(t->hdr->frame_control)) { |
600 | /* Skip LLC SNAP header (+6) */ | 600 | /* Skip LLC SNAP header (+6) */ |
601 | u8 *payload = &t->skb->data[t->hdrlen]; | 601 | u8 *payload = &t->skb->data[t->hdrlen]; |
602 | u16 *ethertype = (u16 *)&payload[6]; | 602 | __be16 *ethertype = (__be16 *)&payload[6]; |
603 | if (*ethertype == __be16_to_cpu(ETH_P_PAE)) | 603 | if (be16_to_cpu(*ethertype) == ETH_P_PAE) |
604 | priority = WSM_EPTA_PRIORITY_EAPOL; | 604 | priority = WSM_EPTA_PRIORITY_EAPOL; |
605 | } else if (ieee80211_is_assoc_req(t->hdr->frame_control) || | 605 | } else if (ieee80211_is_assoc_req(t->hdr->frame_control) || |
606 | ieee80211_is_reassoc_req(t->hdr->frame_control)) { | 606 | ieee80211_is_reassoc_req(t->hdr->frame_control)) { |
607 | struct ieee80211_mgmt *mgt_frame = | 607 | struct ieee80211_mgmt *mgt_frame = |
608 | (struct ieee80211_mgmt *)t->hdr; | 608 | (struct ieee80211_mgmt *)t->hdr; |
609 | 609 | ||
610 | if (mgt_frame->u.assoc_req.listen_interval < | 610 | if (le16_to_cpu(mgt_frame->u.assoc_req.listen_interval) < |
611 | priv->listen_interval) { | 611 | priv->listen_interval) { |
612 | pr_debug("Modified Listen Interval to %d from %d\n", | 612 | pr_debug("Modified Listen Interval to %d from %d\n", |
613 | priv->listen_interval, | 613 | priv->listen_interval, |
@@ -615,8 +615,7 @@ cw1200_tx_h_bt(struct cw1200_common *priv, | |||
615 | /* Replace listen interval derieved from | 615 | /* Replace listen interval derieved from |
616 | * the one read from SDD | 616 | * the one read from SDD |
617 | */ | 617 | */ |
618 | mgt_frame->u.assoc_req.listen_interval = | 618 | mgt_frame->u.assoc_req.listen_interval = cpu_to_le16(priv->listen_interval); |
619 | priv->listen_interval; | ||
620 | } | 619 | } |
621 | } | 620 | } |
622 | 621 | ||
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c index d95094fdcc50..cbb74d7a9be5 100644 --- a/drivers/net/wireless/cw1200/wsm.c +++ b/drivers/net/wireless/cw1200/wsm.c | |||
@@ -42,19 +42,19 @@ | |||
42 | (buf)->data += size; \ | 42 | (buf)->data += size; \ |
43 | } while (0) | 43 | } while (0) |
44 | 44 | ||
45 | #define __WSM_GET(buf, type, cvt) \ | 45 | #define __WSM_GET(buf, type, type2, cvt) \ |
46 | ({ \ | 46 | ({ \ |
47 | type val; \ | 47 | type val; \ |
48 | if ((buf)->data + sizeof(type) > (buf)->end) \ | 48 | if ((buf)->data + sizeof(type) > (buf)->end) \ |
49 | goto underflow; \ | 49 | goto underflow; \ |
50 | val = cvt(*(type *)(buf)->data); \ | 50 | val = cvt(*(type2 *)(buf)->data); \ |
51 | (buf)->data += sizeof(type); \ | 51 | (buf)->data += sizeof(type); \ |
52 | val; \ | 52 | val; \ |
53 | }) | 53 | }) |
54 | 54 | ||
55 | #define WSM_GET8(buf) __WSM_GET(buf, u8, (u8)) | 55 | #define WSM_GET8(buf) __WSM_GET(buf, u8, u8, (u8)) |
56 | #define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu) | 56 | #define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu) |
57 | #define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu) | 57 | #define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu) |
58 | 58 | ||
59 | #define WSM_PUT(buf, ptr, size) \ | 59 | #define WSM_PUT(buf, ptr, size) \ |
60 | do { \ | 60 | do { \ |
@@ -65,18 +65,18 @@ | |||
65 | (buf)->data += size; \ | 65 | (buf)->data += size; \ |
66 | } while (0) | 66 | } while (0) |
67 | 67 | ||
68 | #define __WSM_PUT(buf, val, type, cvt) \ | 68 | #define __WSM_PUT(buf, val, type, type2, cvt) \ |
69 | do { \ | 69 | do { \ |
70 | if ((buf)->data + sizeof(type) > (buf)->end) \ | 70 | if ((buf)->data + sizeof(type) > (buf)->end) \ |
71 | if (wsm_buf_reserve((buf), sizeof(type))) \ | 71 | if (wsm_buf_reserve((buf), sizeof(type))) \ |
72 | goto nomem; \ | 72 | goto nomem; \ |
73 | *(type *)(buf)->data = cvt(val); \ | 73 | *(type2 *)(buf)->data = cvt(val); \ |
74 | (buf)->data += sizeof(type); \ | 74 | (buf)->data += sizeof(type); \ |
75 | } while (0) | 75 | } while (0) |
76 | 76 | ||
77 | #define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8)) | 77 | #define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, u8, (u8)) |
78 | #define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16) | 78 | #define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16) |
79 | #define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32) | 79 | #define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32) |
80 | 80 | ||
81 | static void wsm_buf_reset(struct wsm_buf *buf); | 81 | static void wsm_buf_reset(struct wsm_buf *buf); |
82 | static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size); | 82 | static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size); |
@@ -931,8 +931,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf) | |||
931 | if (!event) | 931 | if (!event) |
932 | return -ENOMEM; | 932 | return -ENOMEM; |
933 | 933 | ||
934 | event->evt.id = __le32_to_cpu(WSM_GET32(buf)); | 934 | event->evt.id = WSM_GET32(buf); |
935 | event->evt.data = __le32_to_cpu(WSM_GET32(buf)); | 935 | event->evt.data = WSM_GET32(buf); |
936 | 936 | ||
937 | pr_debug("[WSM] Event: %d(%d)\n", | 937 | pr_debug("[WSM] Event: %d(%d)\n", |
938 | event->evt.id, event->evt.data); | 938 | event->evt.id, event->evt.data); |
@@ -1311,7 +1311,7 @@ int wsm_handle_rx(struct cw1200_common *priv, u16 id, | |||
1311 | 1311 | ||
1312 | wsm_buf.begin = (u8 *)&wsm[0]; | 1312 | wsm_buf.begin = (u8 *)&wsm[0]; |
1313 | wsm_buf.data = (u8 *)&wsm[1]; | 1313 | wsm_buf.data = (u8 *)&wsm[1]; |
1314 | wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)]; | 1314 | wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)]; |
1315 | 1315 | ||
1316 | pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, | 1316 | pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, |
1317 | wsm_buf.end - wsm_buf.begin); | 1317 | wsm_buf.end - wsm_buf.begin); |
@@ -1550,7 +1550,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv, | |||
1550 | */ | 1550 | */ |
1551 | pr_debug("[WSM] Convert probe request to scan.\n"); | 1551 | pr_debug("[WSM] Convert probe request to scan.\n"); |
1552 | wsm_lock_tx_async(priv); | 1552 | wsm_lock_tx_async(priv); |
1553 | priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); | 1553 | priv->pending_frame_id = wsm->packet_id; |
1554 | if (queue_delayed_work(priv->workqueue, | 1554 | if (queue_delayed_work(priv->workqueue, |
1555 | &priv->scan.probe_work, 0) <= 0) | 1555 | &priv->scan.probe_work, 0) <= 0) |
1556 | wsm_unlock_tx(priv); | 1556 | wsm_unlock_tx(priv); |
@@ -1558,15 +1558,14 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv, | |||
1558 | break; | 1558 | break; |
1559 | case do_drop: | 1559 | case do_drop: |
1560 | pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl); | 1560 | pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl); |
1561 | BUG_ON(cw1200_queue_remove(queue, | 1561 | BUG_ON(cw1200_queue_remove(queue, wsm->packet_id)); |
1562 | __le32_to_cpu(wsm->packet_id))); | ||
1563 | handled = true; | 1562 | handled = true; |
1564 | break; | 1563 | break; |
1565 | case do_wep: | 1564 | case do_wep: |
1566 | pr_debug("[WSM] Issue set_default_wep_key.\n"); | 1565 | pr_debug("[WSM] Issue set_default_wep_key.\n"); |
1567 | wsm_lock_tx_async(priv); | 1566 | wsm_lock_tx_async(priv); |
1568 | priv->wep_default_key_id = tx_info->control.hw_key->keyidx; | 1567 | priv->wep_default_key_id = tx_info->control.hw_key->keyidx; |
1569 | priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); | 1568 | priv->pending_frame_id = wsm->packet_id; |
1570 | if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0) | 1569 | if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0) |
1571 | wsm_unlock_tx(priv); | 1570 | wsm_unlock_tx(priv); |
1572 | handled = true; | 1571 | handled = true; |
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h index 2816171f7a1d..7afc613c3706 100644 --- a/drivers/net/wireless/cw1200/wsm.h +++ b/drivers/net/wireless/cw1200/wsm.h | |||
@@ -806,7 +806,7 @@ struct wsm_tx { | |||
806 | struct wsm_hdr hdr; | 806 | struct wsm_hdr hdr; |
807 | 807 | ||
808 | /* Packet identifier that meant to be used in completion. */ | 808 | /* Packet identifier that meant to be used in completion. */ |
809 | __le32 packet_id; | 809 | u32 packet_id; /* Note this is actually a cookie */ |
810 | 810 | ||
811 | /* WSM_TRANSMIT_RATE_... */ | 811 | /* WSM_TRANSMIT_RATE_... */ |
812 | u8 max_tx_rate; | 812 | u8 max_tx_rate; |
@@ -825,18 +825,18 @@ struct wsm_tx { | |||
825 | u8 flags; | 825 | u8 flags; |
826 | 826 | ||
827 | /* Should be 0. */ | 827 | /* Should be 0. */ |
828 | __le32 reserved; | 828 | u32 reserved; |
829 | 829 | ||
830 | /* The elapsed time in TUs, after the initial transmission */ | 830 | /* The elapsed time in TUs, after the initial transmission */ |
831 | /* of an MSDU, after which further attempts to transmit */ | 831 | /* of an MSDU, after which further attempts to transmit */ |
832 | /* the MSDU shall be terminated. Overrides the global */ | 832 | /* the MSDU shall be terminated. Overrides the global */ |
833 | /* dot11MaxTransmitMsduLifeTime setting [optional] */ | 833 | /* dot11MaxTransmitMsduLifeTime setting [optional] */ |
834 | /* Device will set the default value if this is 0. */ | 834 | /* Device will set the default value if this is 0. */ |
835 | __le32 expire_time; | 835 | u32 expire_time; |
836 | 836 | ||
837 | /* WSM_HT_TX_... */ | 837 | /* WSM_HT_TX_... */ |
838 | __le32 ht_tx_parameters; | 838 | __le32 ht_tx_parameters; |
839 | }; | 839 | } __packed; |
840 | 840 | ||
841 | /* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */ | 841 | /* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */ |
842 | #define WSM_TX_EXTRA_HEADROOM (28) | 842 | #define WSM_TX_EXTRA_HEADROOM (28) |
@@ -846,10 +846,10 @@ struct wsm_tx { | |||
846 | 846 | ||
847 | struct wsm_rx { | 847 | struct wsm_rx { |
848 | /* WSM_STATUS_... */ | 848 | /* WSM_STATUS_... */ |
849 | __le32 status; | 849 | u32 status; |
850 | 850 | ||
851 | /* Specifies the channel of the received packet. */ | 851 | /* Specifies the channel of the received packet. */ |
852 | __le16 channel_number; | 852 | u16 channel_number; |
853 | 853 | ||
854 | /* WSM_TRANSMIT_RATE_... */ | 854 | /* WSM_TRANSMIT_RATE_... */ |
855 | u8 rx_rate; | 855 | u8 rx_rate; |
@@ -859,11 +859,8 @@ struct wsm_rx { | |||
859 | u8 rcpi_rssi; | 859 | u8 rcpi_rssi; |
860 | 860 | ||
861 | /* WSM_RX_STATUS_... */ | 861 | /* WSM_RX_STATUS_... */ |
862 | __le32 flags; | 862 | u32 flags; |
863 | 863 | }; | |
864 | /* Payload */ | ||
865 | u8 data[0]; | ||
866 | } __packed; | ||
867 | 864 | ||
868 | /* = sizeof(generic hi hdr) + sizeof(wsm hdr) */ | 865 | /* = sizeof(generic hi hdr) + sizeof(wsm hdr) */ |
869 | #define WSM_RX_EXTRA_HEADROOM (16) | 866 | #define WSM_RX_EXTRA_HEADROOM (16) |
@@ -1119,22 +1116,22 @@ int wsm_set_tx_queue_params(struct cw1200_common *priv, | |||
1119 | #define WSM_EDCA_PARAMS_RESP_ID 0x0413 | 1116 | #define WSM_EDCA_PARAMS_RESP_ID 0x0413 |
1120 | struct wsm_edca_queue_params { | 1117 | struct wsm_edca_queue_params { |
1121 | /* CWmin (in slots) for the access class. */ | 1118 | /* CWmin (in slots) for the access class. */ |
1122 | __le16 cwmin; | 1119 | u16 cwmin; |
1123 | 1120 | ||
1124 | /* CWmax (in slots) for the access class. */ | 1121 | /* CWmax (in slots) for the access class. */ |
1125 | __le16 cwmax; | 1122 | u16 cwmax; |
1126 | 1123 | ||
1127 | /* AIFS (in slots) for the access class. */ | 1124 | /* AIFS (in slots) for the access class. */ |
1128 | __le16 aifns; | 1125 | u16 aifns; |
1129 | 1126 | ||
1130 | /* TX OP Limit (in microseconds) for the access class. */ | 1127 | /* TX OP Limit (in microseconds) for the access class. */ |
1131 | __le16 txop_limit; | 1128 | u16 txop_limit; |
1132 | 1129 | ||
1133 | /* dot11MaxReceiveLifetime to be used for the specified */ | 1130 | /* dot11MaxReceiveLifetime to be used for the specified */ |
1134 | /* the access class. Overrides the global */ | 1131 | /* the access class. Overrides the global */ |
1135 | /* dot11MaxReceiveLifetime value */ | 1132 | /* dot11MaxReceiveLifetime value */ |
1136 | __le32 max_rx_lifetime; | 1133 | u32 max_rx_lifetime; |
1137 | } __packed; | 1134 | }; |
1138 | 1135 | ||
1139 | struct wsm_edca_params { | 1136 | struct wsm_edca_params { |
1140 | /* NOTE: index is a linux queue id. */ | 1137 | /* NOTE: index is a linux queue id. */ |
@@ -1147,12 +1144,12 @@ struct wsm_edca_params { | |||
1147 | __uapsd) \ | 1144 | __uapsd) \ |
1148 | do { \ | 1145 | do { \ |
1149 | struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \ | 1146 | struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \ |
1150 | p->cwmin = (__cw_min); \ | 1147 | p->cwmin = __cw_min; \ |
1151 | p->cwmax = (__cw_max); \ | 1148 | p->cwmax = __cw_max; \ |
1152 | p->aifns = (__aifs); \ | 1149 | p->aifns = __aifs; \ |
1153 | p->txop_limit = ((__txop) * TXOP_UNIT); \ | 1150 | p->txop_limit = ((__txop) * TXOP_UNIT); \ |
1154 | p->max_rx_lifetime = (__lifetime); \ | 1151 | p->max_rx_lifetime = __lifetime; \ |
1155 | (__edca)->uapsd_enable[__queue] = (__uapsd); \ | 1152 | (__edca)->uapsd_enable[__queue] = (__uapsd); \ |
1156 | } while (0) | 1153 | } while (0) |
1157 | 1154 | ||
1158 | int wsm_set_edca_params(struct cw1200_common *priv, | 1155 | int wsm_set_edca_params(struct cw1200_common *priv, |
@@ -1475,7 +1472,7 @@ static inline int wsm_set_template_frame(struct cw1200_common *priv, | |||
1475 | u8 *p = skb_push(arg->skb, 4); | 1472 | u8 *p = skb_push(arg->skb, 4); |
1476 | p[0] = arg->frame_type; | 1473 | p[0] = arg->frame_type; |
1477 | p[1] = arg->rate; | 1474 | p[1] = arg->rate; |
1478 | ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4); | 1475 | ((__le16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4); |
1479 | ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len); | 1476 | ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len); |
1480 | skb_pull(arg->skb, 4); | 1477 | skb_pull(arg->skb, 4); |
1481 | return ret; | 1478 | return ret; |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index d96257b79a84..312fa0e42e6f 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -3548,6 +3548,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
3548 | ipw_rx_queue_reset(priv, priv->rxq); | 3548 | ipw_rx_queue_reset(priv, priv->rxq); |
3549 | if (!priv->rxq) { | 3549 | if (!priv->rxq) { |
3550 | IPW_ERROR("Unable to initialize Rx queue\n"); | 3550 | IPW_ERROR("Unable to initialize Rx queue\n"); |
3551 | rc = -ENOMEM; | ||
3551 | goto error; | 3552 | goto error; |
3552 | } | 3553 | } |
3553 | 3554 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 95a1ca1e895c..9ffe65931b29 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -1195,7 +1195,7 @@ static int libipw_parse_info_param(struct libipw_info_element | |||
1195 | #ifdef CONFIG_LIBIPW_DEBUG | 1195 | #ifdef CONFIG_LIBIPW_DEBUG |
1196 | p += snprintf(p, sizeof(rates_str) - | 1196 | p += snprintf(p, sizeof(rates_str) - |
1197 | (p - rates_str), "%02X ", | 1197 | (p - rates_str), "%02X ", |
1198 | network->rates[i]); | 1198 | network->rates_ex[i]); |
1199 | #endif | 1199 | #endif |
1200 | if (libipw_is_ofdm_rate | 1200 | if (libipw_is_ofdm_rate |
1201 | (info_element->data[i])) { | 1201 | (info_element->data[i])) { |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 56c2040a955b..cbaa5c2c410f 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -128,16 +128,6 @@ config IWLWIFI_DEVICE_TRACING | |||
128 | occur. | 128 | occur. |
129 | endmenu | 129 | endmenu |
130 | 130 | ||
131 | config IWLWIFI_DEVICE_TESTMODE | ||
132 | def_bool y | ||
133 | depends on IWLWIFI | ||
134 | depends on NL80211_TESTMODE | ||
135 | help | ||
136 | This option enables the testmode support for iwlwifi device through | ||
137 | NL80211_TESTMODE. This provide the capabilities of enable user space | ||
138 | validation applications to interacts with the device through the | ||
139 | generic netlink message via NL80211_TESTMODE channel. | ||
140 | |||
141 | config IWLWIFI_P2P | 131 | config IWLWIFI_P2P |
142 | def_bool y | 132 | def_bool y |
143 | bool "iwlwifi experimental P2P support" | 133 | bool "iwlwifi experimental P2P support" |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index f55a758b87f6..1fa64429bcc2 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -13,7 +13,6 @@ iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o | |||
13 | iwlwifi-objs += $(iwlwifi-m) | 13 | iwlwifi-objs += $(iwlwifi-m) |
14 | 14 | ||
15 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 15 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
16 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o | ||
17 | 16 | ||
18 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src) | 17 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src) |
19 | 18 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile index 5ff76b204141..dce7ab2e0c4b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/Makefile +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile | |||
@@ -8,6 +8,5 @@ iwldvm-objs += scan.o led.o | |||
8 | iwldvm-objs += rxon.o devices.o | 8 | iwldvm-objs += rxon.o devices.o |
9 | 9 | ||
10 | iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o | 10 | iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o |
11 | iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o | ||
12 | 11 | ||
13 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ | 12 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index de2c9514bef6..18355110deff 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -405,43 +405,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
405 | 405 | ||
406 | extern int iwl_alive_start(struct iwl_priv *priv); | 406 | extern int iwl_alive_start(struct iwl_priv *priv); |
407 | 407 | ||
408 | /* testmode support */ | ||
409 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
410 | |||
411 | extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, | ||
412 | int len); | ||
413 | extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, | ||
414 | struct sk_buff *skb, | ||
415 | struct netlink_callback *cb, | ||
416 | void *data, int len); | ||
417 | extern void iwl_testmode_init(struct iwl_priv *priv); | ||
418 | extern void iwl_testmode_free(struct iwl_priv *priv); | ||
419 | |||
420 | #else | ||
421 | |||
422 | static inline | ||
423 | int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | ||
424 | { | ||
425 | return -ENOSYS; | ||
426 | } | ||
427 | |||
428 | static inline | ||
429 | int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
430 | struct netlink_callback *cb, | ||
431 | void *data, int len) | ||
432 | { | ||
433 | return -ENOSYS; | ||
434 | } | ||
435 | |||
436 | static inline void iwl_testmode_init(struct iwl_priv *priv) | ||
437 | { | ||
438 | } | ||
439 | |||
440 | static inline void iwl_testmode_free(struct iwl_priv *priv) | ||
441 | { | ||
442 | } | ||
443 | #endif | ||
444 | |||
445 | #ifdef CONFIG_IWLWIFI_DEBUG | 408 | #ifdef CONFIG_IWLWIFI_DEBUG |
446 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, | 409 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, |
447 | enum iwl_rxon_context_id ctxid); | 410 | enum iwl_rxon_context_id ctxid); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 5cd87f949266..60a4e0d15715 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h | |||
@@ -52,8 +52,6 @@ | |||
52 | #include "rs.h" | 52 | #include "rs.h" |
53 | #include "tt.h" | 53 | #include "tt.h" |
54 | 54 | ||
55 | #include "iwl-test.h" | ||
56 | |||
57 | /* CT-KILL constants */ | 55 | /* CT-KILL constants */ |
58 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ | 56 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ |
59 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ | 57 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ |
@@ -691,10 +689,6 @@ struct iwl_priv { | |||
691 | struct iwl_spectrum_notification measure_report; | 689 | struct iwl_spectrum_notification measure_report; |
692 | u8 measurement_status; | 690 | u8 measurement_status; |
693 | 691 | ||
694 | #define IWL_OWNERSHIP_DRIVER 0 | ||
695 | #define IWL_OWNERSHIP_TM 1 | ||
696 | u8 ucode_owner; | ||
697 | |||
698 | /* ucode beacon time */ | 692 | /* ucode beacon time */ |
699 | u32 ucode_beacon_time; | 693 | u32 ucode_beacon_time; |
700 | int missed_beacon_threshold; | 694 | int missed_beacon_threshold; |
@@ -889,7 +883,7 @@ struct iwl_priv { | |||
889 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 883 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
890 | 884 | ||
891 | struct iwl_nvm_data *nvm_data; | 885 | struct iwl_nvm_data *nvm_data; |
892 | /* eeprom blob for debugfs/testmode */ | 886 | /* eeprom blob for debugfs */ |
893 | u8 *eeprom_blob; | 887 | u8 *eeprom_blob; |
894 | size_t eeprom_blob_size; | 888 | size_t eeprom_blob_size; |
895 | 889 | ||
@@ -905,11 +899,6 @@ struct iwl_priv { | |||
905 | unsigned long blink_on, blink_off; | 899 | unsigned long blink_on, blink_off; |
906 | bool led_registered; | 900 | bool led_registered; |
907 | 901 | ||
908 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
909 | struct iwl_test tst; | ||
910 | u32 tm_fixed_rate; | ||
911 | #endif | ||
912 | |||
913 | /* WoWLAN GTK rekey data */ | 902 | /* WoWLAN GTK rekey data */ |
914 | u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; | 903 | u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; |
915 | __le64 replay_ctr; | 904 | __le64 replay_ctr; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 9879550a0fea..3d5bdc4217a8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -1288,12 +1288,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1288 | if (!(cmd->flags & CMD_ASYNC)) | 1288 | if (!(cmd->flags & CMD_ASYNC)) |
1289 | lockdep_assert_held(&priv->mutex); | 1289 | lockdep_assert_held(&priv->mutex); |
1290 | 1290 | ||
1291 | if (priv->ucode_owner == IWL_OWNERSHIP_TM && | ||
1292 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
1293 | IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); | ||
1294 | return -EIO; | ||
1295 | } | ||
1296 | |||
1297 | return iwl_trans_send_cmd(priv->trans, cmd); | 1291 | return iwl_trans_send_cmd(priv->trans, cmd); |
1298 | } | 1292 | } |
1299 | 1293 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index eef64bb854f7..822f1a00efbb 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1766,8 +1766,6 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1766 | .remain_on_channel = iwlagn_mac_remain_on_channel, | 1766 | .remain_on_channel = iwlagn_mac_remain_on_channel, |
1767 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, | 1767 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, |
1768 | .rssi_callback = iwlagn_mac_rssi_callback, | 1768 | .rssi_callback = iwlagn_mac_rssi_callback, |
1769 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | ||
1770 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | ||
1771 | .set_tim = iwlagn_mac_set_tim, | 1769 | .set_tim = iwlagn_mac_set_tim, |
1772 | }; | 1770 | }; |
1773 | 1771 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7aa9c8dc33ef..3952ddf2ddb2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -1105,8 +1105,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1105 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 1105 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
1106 | priv->agg_tids_count = 0; | 1106 | priv->agg_tids_count = 0; |
1107 | 1107 | ||
1108 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
1109 | |||
1110 | priv->rx_statistics_jiffies = jiffies; | 1108 | priv->rx_statistics_jiffies = jiffies; |
1111 | 1109 | ||
1112 | /* Choose which receivers/antennas to use */ | 1110 | /* Choose which receivers/antennas to use */ |
@@ -1172,12 +1170,6 @@ static void iwl_option_config(struct iwl_priv *priv) | |||
1172 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); | 1170 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); |
1173 | #endif | 1171 | #endif |
1174 | 1172 | ||
1175 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
1176 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n"); | ||
1177 | #else | ||
1178 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n"); | ||
1179 | #endif | ||
1180 | |||
1181 | #ifdef CONFIG_IWLWIFI_P2P | 1173 | #ifdef CONFIG_IWLWIFI_P2P |
1182 | IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n"); | 1174 | IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n"); |
1183 | #else | 1175 | #else |
@@ -1355,8 +1347,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1355 | IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? | 1347 | IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? |
1356 | true : false; | 1348 | true : false; |
1357 | 1349 | ||
1358 | /* enable/disable bt channel inhibition */ | 1350 | /* bt channel inhibition enabled*/ |
1359 | priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce; | 1351 | priv->bt_ch_announce = true; |
1360 | IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", | 1352 | IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", |
1361 | (priv->bt_ch_announce) ? "On" : "Off"); | 1353 | (priv->bt_ch_announce) ? "On" : "Off"); |
1362 | 1354 | ||
@@ -1451,7 +1443,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1451 | ********************/ | 1443 | ********************/ |
1452 | iwl_setup_deferred_work(priv); | 1444 | iwl_setup_deferred_work(priv); |
1453 | iwl_setup_rx_handlers(priv); | 1445 | iwl_setup_rx_handlers(priv); |
1454 | iwl_testmode_init(priv); | ||
1455 | 1446 | ||
1456 | iwl_power_initialize(priv); | 1447 | iwl_power_initialize(priv); |
1457 | iwl_tt_initialize(priv); | 1448 | iwl_tt_initialize(priv); |
@@ -1488,7 +1479,6 @@ out_mac80211_unregister: | |||
1488 | iwlagn_mac_unregister(priv); | 1479 | iwlagn_mac_unregister(priv); |
1489 | out_destroy_workqueue: | 1480 | out_destroy_workqueue: |
1490 | iwl_tt_exit(priv); | 1481 | iwl_tt_exit(priv); |
1491 | iwl_testmode_free(priv); | ||
1492 | iwl_cancel_deferred_work(priv); | 1482 | iwl_cancel_deferred_work(priv); |
1493 | destroy_workqueue(priv->workqueue); | 1483 | destroy_workqueue(priv->workqueue); |
1494 | priv->workqueue = NULL; | 1484 | priv->workqueue = NULL; |
@@ -1510,7 +1500,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1510 | 1500 | ||
1511 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 1501 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
1512 | 1502 | ||
1513 | iwl_testmode_free(priv); | ||
1514 | iwlagn_mac_unregister(priv); | 1503 | iwlagn_mac_unregister(priv); |
1515 | 1504 | ||
1516 | iwl_tt_exit(priv); | 1505 | iwl_tt_exit(priv); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 8fe76dc4f373..1b693944123b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -351,12 +351,6 @@ static void rs_program_fix_rate(struct iwl_priv *priv, | |||
351 | lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | 351 | lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ |
352 | lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ | 352 | lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ |
353 | 353 | ||
354 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
355 | /* testmode has higher priority to overwirte the fixed rate */ | ||
356 | if (priv->tm_fixed_rate) | ||
357 | lq_sta->dbg_fixed_rate = priv->tm_fixed_rate; | ||
358 | #endif | ||
359 | |||
360 | IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", | 354 | IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", |
361 | lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); | 355 | lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); |
362 | 356 | ||
@@ -419,23 +413,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
419 | 413 | ||
420 | load = rs_tl_get_load(lq_data, tid); | 414 | load = rs_tl_get_load(lq_data, tid); |
421 | 415 | ||
422 | if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { | 416 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
423 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 417 | sta->addr, tid); |
424 | sta->addr, tid); | 418 | ret = ieee80211_start_tx_ba_session(sta, tid, 5000); |
425 | ret = ieee80211_start_tx_ba_session(sta, tid, 5000); | 419 | if (ret == -EAGAIN) { |
426 | if (ret == -EAGAIN) { | 420 | /* |
427 | /* | 421 | * driver and mac80211 is out of sync |
428 | * driver and mac80211 is out of sync | 422 | * this might be cause by reloading firmware |
429 | * this might be cause by reloading firmware | 423 | * stop the tx ba session here |
430 | * stop the tx ba session here | 424 | */ |
431 | */ | 425 | IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", |
432 | IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", | 426 | tid); |
433 | tid); | 427 | ieee80211_stop_tx_ba_session(sta, tid); |
434 | ieee80211_stop_tx_ba_session(sta, tid); | ||
435 | } | ||
436 | } else { | ||
437 | IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d " | ||
438 | "because load = %u\n", tid, load); | ||
439 | } | 428 | } |
440 | return ret; | 429 | return ret; |
441 | } | 430 | } |
@@ -1083,11 +1072,6 @@ done: | |||
1083 | if (sta && sta->supp_rates[sband->band]) | 1072 | if (sta && sta->supp_rates[sband->band]) |
1084 | rs_rate_scale_perform(priv, skb, sta, lq_sta); | 1073 | rs_rate_scale_perform(priv, skb, sta, lq_sta); |
1085 | 1074 | ||
1086 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE) | ||
1087 | if ((priv->tm_fixed_rate) && | ||
1088 | (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) | ||
1089 | rs_program_fix_rate(priv, lq_sta); | ||
1090 | #endif | ||
1091 | if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) | 1075 | if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) |
1092 | rs_bt_update_lq(priv, ctx, lq_sta); | 1076 | rs_bt_update_lq(priv, ctx, lq_sta); |
1093 | } | 1077 | } |
@@ -2913,9 +2897,6 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2913 | if (sband->band == IEEE80211_BAND_5GHZ) | 2897 | if (sband->band == IEEE80211_BAND_5GHZ) |
2914 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 2898 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2915 | lq_sta->is_agg = 0; | 2899 | lq_sta->is_agg = 0; |
2916 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
2917 | priv->tm_fixed_rate = 0; | ||
2918 | #endif | ||
2919 | #ifdef CONFIG_MAC80211_DEBUGFS | 2900 | #ifdef CONFIG_MAC80211_DEBUGFS |
2920 | lq_sta->dbg_fixed_rate = 0; | 2901 | lq_sta->dbg_fixed_rate = 0; |
2921 | #endif | 2902 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index 2f3fd160ab44..d71776dd1e6a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -335,8 +335,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | |||
335 | if (msecs < 99) | 335 | if (msecs < 99) |
336 | return; | 336 | return; |
337 | 337 | ||
338 | if (iwlwifi_mod_params.plcp_check && | 338 | if (!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) |
339 | !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | ||
340 | iwl_force_rf_reset(priv, false); | 339 | iwl_force_rf_reset(priv, false); |
341 | } | 340 | } |
342 | 341 | ||
@@ -1120,32 +1119,17 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, | |||
1120 | */ | 1119 | */ |
1121 | iwl_notification_wait_notify(&priv->notif_wait, pkt); | 1120 | iwl_notification_wait_notify(&priv->notif_wait, pkt); |
1122 | 1121 | ||
1123 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 1122 | /* Based on type of command response or notification, |
1124 | /* | 1123 | * handle those that need handling via function in |
1125 | * RX data may be forwarded to userspace in one | 1124 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
1126 | * of two cases: the user owns the fw through testmode or when | 1125 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
1127 | * the user requested to monitor the rx w/o affecting the regular flow. | 1126 | priv->rx_handlers_stats[pkt->hdr.cmd]++; |
1128 | * In these cases the iwl_test object will handle forwarding the rx | 1127 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); |
1129 | * data to user space. | 1128 | } else { |
1130 | * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow | 1129 | /* No handling needed */ |
1131 | * continues. | 1130 | IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", |
1132 | */ | 1131 | iwl_dvm_get_cmd_string(pkt->hdr.cmd), |
1133 | iwl_test_rx(&priv->tst, rxb); | 1132 | pkt->hdr.cmd); |
1134 | #endif | ||
1135 | |||
1136 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { | ||
1137 | /* Based on type of command response or notification, | ||
1138 | * handle those that need handling via function in | ||
1139 | * rx_handlers table. See iwl_setup_rx_handlers() */ | ||
1140 | if (priv->rx_handlers[pkt->hdr.cmd]) { | ||
1141 | priv->rx_handlers_stats[pkt->hdr.cmd]++; | ||
1142 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); | ||
1143 | } else { | ||
1144 | /* No handling needed */ | ||
1145 | IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", | ||
1146 | iwl_dvm_get_cmd_string(pkt->hdr.cmd), | ||
1147 | pkt->hdr.cmd); | ||
1148 | } | ||
1149 | } | 1133 | } |
1150 | return err; | 1134 | return err; |
1151 | } | 1135 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c deleted file mode 100644 index b89b9d9b9969..000000000000 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | |||
64 | #include <linux/init.h> | ||
65 | #include <linux/kernel.h> | ||
66 | #include <linux/module.h> | ||
67 | #include <linux/dma-mapping.h> | ||
68 | #include <net/net_namespace.h> | ||
69 | #include <linux/netdevice.h> | ||
70 | #include <net/cfg80211.h> | ||
71 | #include <net/mac80211.h> | ||
72 | #include <net/netlink.h> | ||
73 | |||
74 | #include "iwl-debug.h" | ||
75 | #include "iwl-trans.h" | ||
76 | #include "dev.h" | ||
77 | #include "agn.h" | ||
78 | #include "iwl-test.h" | ||
79 | #include "iwl-testmode.h" | ||
80 | |||
81 | static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode, | ||
82 | struct iwl_host_cmd *cmd) | ||
83 | { | ||
84 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
85 | return iwl_dvm_send_cmd(priv, cmd); | ||
86 | } | ||
87 | |||
88 | static bool iwl_testmode_valid_hw_addr(u32 addr) | ||
89 | { | ||
90 | if (iwlagn_hw_valid_rtc_data_addr(addr)) | ||
91 | return true; | ||
92 | |||
93 | if (IWLAGN_RTC_INST_LOWER_BOUND <= addr && | ||
94 | addr < IWLAGN_RTC_INST_UPPER_BOUND) | ||
95 | return true; | ||
96 | |||
97 | return false; | ||
98 | } | ||
99 | |||
100 | static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode) | ||
101 | { | ||
102 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
103 | return priv->fw->ucode_ver; | ||
104 | } | ||
105 | |||
106 | static struct sk_buff* | ||
107 | iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len) | ||
108 | { | ||
109 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
110 | return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len); | ||
111 | } | ||
112 | |||
113 | static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb) | ||
114 | { | ||
115 | return cfg80211_testmode_reply(skb); | ||
116 | } | ||
117 | |||
118 | static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode, | ||
119 | int len) | ||
120 | { | ||
121 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
122 | return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len, | ||
123 | GFP_ATOMIC); | ||
124 | } | ||
125 | |||
126 | static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb) | ||
127 | { | ||
128 | return cfg80211_testmode_event(skb, GFP_ATOMIC); | ||
129 | } | ||
130 | |||
131 | static struct iwl_test_ops tst_ops = { | ||
132 | .send_cmd = iwl_testmode_send_cmd, | ||
133 | .valid_hw_addr = iwl_testmode_valid_hw_addr, | ||
134 | .get_fw_ver = iwl_testmode_get_fw_ver, | ||
135 | .alloc_reply = iwl_testmode_alloc_reply, | ||
136 | .reply = iwl_testmode_reply, | ||
137 | .alloc_event = iwl_testmode_alloc_event, | ||
138 | .event = iwl_testmode_event, | ||
139 | }; | ||
140 | |||
141 | void iwl_testmode_init(struct iwl_priv *priv) | ||
142 | { | ||
143 | iwl_test_init(&priv->tst, priv->trans, &tst_ops); | ||
144 | } | ||
145 | |||
146 | void iwl_testmode_free(struct iwl_priv *priv) | ||
147 | { | ||
148 | iwl_test_free(&priv->tst); | ||
149 | } | ||
150 | |||
151 | static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | ||
152 | { | ||
153 | struct iwl_notification_wait calib_wait; | ||
154 | static const u8 calib_complete[] = { | ||
155 | CALIBRATION_COMPLETE_NOTIFICATION | ||
156 | }; | ||
157 | int ret; | ||
158 | |||
159 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, | ||
160 | calib_complete, ARRAY_SIZE(calib_complete), | ||
161 | NULL, NULL); | ||
162 | ret = iwl_init_alive_start(priv); | ||
163 | if (ret) { | ||
164 | IWL_ERR(priv, "Fail init calibration: %d\n", ret); | ||
165 | goto cfg_init_calib_error; | ||
166 | } | ||
167 | |||
168 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); | ||
169 | if (ret) | ||
170 | IWL_ERR(priv, "Error detecting" | ||
171 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); | ||
172 | return ret; | ||
173 | |||
174 | cfg_init_calib_error: | ||
175 | iwl_remove_notification(&priv->notif_wait, &calib_wait); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * This function handles the user application commands for driver. | ||
181 | * | ||
182 | * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the | ||
183 | * handlers respectively. | ||
184 | * | ||
185 | * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned | ||
186 | * value of the actual command execution is replied to the user application. | ||
187 | * | ||
188 | * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP | ||
189 | * is used for carry the message while IWL_TM_ATTR_COMMAND must set to | ||
190 | * IWL_TM_CMD_DEV2APP_SYNC_RSP. | ||
191 | * | ||
192 | * @hw: ieee80211_hw object that represents the device | ||
193 | * @tb: gnl message fields from the user space | ||
194 | */ | ||
195 | static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | ||
196 | { | ||
197 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
198 | struct iwl_trans *trans = priv->trans; | ||
199 | struct sk_buff *skb; | ||
200 | unsigned char *rsp_data_ptr = NULL; | ||
201 | int status = 0, rsp_data_len = 0; | ||
202 | u32 inst_size = 0, data_size = 0; | ||
203 | const struct fw_img *img; | ||
204 | |||
205 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | ||
206 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: | ||
207 | rsp_data_ptr = (unsigned char *)priv->cfg->name; | ||
208 | rsp_data_len = strlen(priv->cfg->name); | ||
209 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
210 | rsp_data_len + 20); | ||
211 | if (!skb) { | ||
212 | IWL_ERR(priv, "Memory allocation fail\n"); | ||
213 | return -ENOMEM; | ||
214 | } | ||
215 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | ||
216 | IWL_TM_CMD_DEV2APP_SYNC_RSP) || | ||
217 | nla_put(skb, IWL_TM_ATTR_SYNC_RSP, | ||
218 | rsp_data_len, rsp_data_ptr)) | ||
219 | goto nla_put_failure; | ||
220 | status = cfg80211_testmode_reply(skb); | ||
221 | if (status < 0) | ||
222 | IWL_ERR(priv, "Error sending msg : %d\n", status); | ||
223 | break; | ||
224 | |||
225 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | ||
226 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); | ||
227 | if (status) | ||
228 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); | ||
229 | break; | ||
230 | |||
231 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | ||
232 | iwl_testmode_cfg_init_calib(priv); | ||
233 | priv->ucode_loaded = false; | ||
234 | iwl_trans_stop_device(trans); | ||
235 | break; | ||
236 | |||
237 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | ||
238 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); | ||
239 | if (status) { | ||
240 | IWL_ERR(priv, | ||
241 | "Error loading runtime ucode: %d\n", status); | ||
242 | break; | ||
243 | } | ||
244 | status = iwl_alive_start(priv); | ||
245 | if (status) | ||
246 | IWL_ERR(priv, | ||
247 | "Error starting the device: %d\n", status); | ||
248 | break; | ||
249 | |||
250 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | ||
251 | iwl_scan_cancel_timeout(priv, 200); | ||
252 | priv->ucode_loaded = false; | ||
253 | iwl_trans_stop_device(trans); | ||
254 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | ||
255 | if (status) { | ||
256 | IWL_ERR(priv, | ||
257 | "Error loading WOWLAN ucode: %d\n", status); | ||
258 | break; | ||
259 | } | ||
260 | status = iwl_alive_start(priv); | ||
261 | if (status) | ||
262 | IWL_ERR(priv, | ||
263 | "Error starting the device: %d\n", status); | ||
264 | break; | ||
265 | |||
266 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | ||
267 | if (priv->eeprom_blob) { | ||
268 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
269 | priv->eeprom_blob_size + 20); | ||
270 | if (!skb) { | ||
271 | IWL_ERR(priv, "Memory allocation fail\n"); | ||
272 | return -ENOMEM; | ||
273 | } | ||
274 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | ||
275 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || | ||
276 | nla_put(skb, IWL_TM_ATTR_EEPROM, | ||
277 | priv->eeprom_blob_size, | ||
278 | priv->eeprom_blob)) | ||
279 | goto nla_put_failure; | ||
280 | status = cfg80211_testmode_reply(skb); | ||
281 | if (status < 0) | ||
282 | IWL_ERR(priv, "Error sending msg : %d\n", | ||
283 | status); | ||
284 | } else | ||
285 | return -ENODATA; | ||
286 | break; | ||
287 | |||
288 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | ||
289 | if (!tb[IWL_TM_ATTR_FIXRATE]) { | ||
290 | IWL_ERR(priv, "Missing fixrate setting\n"); | ||
291 | return -ENOMSG; | ||
292 | } | ||
293 | priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); | ||
294 | break; | ||
295 | |||
296 | case IWL_TM_CMD_APP2DEV_GET_FW_INFO: | ||
297 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); | ||
298 | if (!skb) { | ||
299 | IWL_ERR(priv, "Memory allocation fail\n"); | ||
300 | return -ENOMEM; | ||
301 | } | ||
302 | if (!priv->ucode_loaded) { | ||
303 | IWL_ERR(priv, "No uCode has not been loaded\n"); | ||
304 | return -EINVAL; | ||
305 | } else { | ||
306 | img = &priv->fw->img[priv->cur_ucode]; | ||
307 | inst_size = img->sec[IWL_UCODE_SECTION_INST].len; | ||
308 | data_size = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
309 | } | ||
310 | if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) || | ||
311 | nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) || | ||
312 | nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size)) | ||
313 | goto nla_put_failure; | ||
314 | status = cfg80211_testmode_reply(skb); | ||
315 | if (status < 0) | ||
316 | IWL_ERR(priv, "Error sending msg : %d\n", status); | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | IWL_ERR(priv, "Unknown testmode driver command ID\n"); | ||
321 | return -ENOSYS; | ||
322 | } | ||
323 | return status; | ||
324 | |||
325 | nla_put_failure: | ||
326 | kfree_skb(skb); | ||
327 | return -EMSGSIZE; | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * This function handles the user application switch ucode ownership. | ||
332 | * | ||
333 | * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and | ||
334 | * decide who the current owner of the uCode | ||
335 | * | ||
336 | * If the current owner is OWNERSHIP_TM, then the only host command | ||
337 | * can deliver to uCode is from testmode, all the other host commands | ||
338 | * will dropped. | ||
339 | * | ||
340 | * default driver is the owner of uCode in normal operational mode | ||
341 | * | ||
342 | * @hw: ieee80211_hw object that represents the device | ||
343 | * @tb: gnl message fields from the user space | ||
344 | */ | ||
345 | static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) | ||
346 | { | ||
347 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
348 | u8 owner; | ||
349 | |||
350 | if (!tb[IWL_TM_ATTR_UCODE_OWNER]) { | ||
351 | IWL_ERR(priv, "Missing ucode owner\n"); | ||
352 | return -ENOMSG; | ||
353 | } | ||
354 | |||
355 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); | ||
356 | if (owner == IWL_OWNERSHIP_DRIVER) { | ||
357 | priv->ucode_owner = owner; | ||
358 | iwl_test_enable_notifications(&priv->tst, false); | ||
359 | } else if (owner == IWL_OWNERSHIP_TM) { | ||
360 | priv->ucode_owner = owner; | ||
361 | iwl_test_enable_notifications(&priv->tst, true); | ||
362 | } else { | ||
363 | IWL_ERR(priv, "Invalid owner\n"); | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /* The testmode gnl message handler that takes the gnl message from the | ||
370 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | ||
371 | * invoke the corresponding handlers. | ||
372 | * | ||
373 | * This function is invoked when there is user space application sending | ||
374 | * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated | ||
375 | * by nl80211. | ||
376 | * | ||
377 | * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before | ||
378 | * dispatching it to the corresponding handler. | ||
379 | * | ||
380 | * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application; | ||
381 | * -ENOSYS is replied to the user application if the command is unknown; | ||
382 | * Otherwise, the command is dispatched to the respective handler. | ||
383 | * | ||
384 | * @hw: ieee80211_hw object that represents the device | ||
385 | * @data: pointer to user space message | ||
386 | * @len: length in byte of @data | ||
387 | */ | ||
388 | int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | ||
389 | { | ||
390 | struct nlattr *tb[IWL_TM_ATTR_MAX]; | ||
391 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
392 | int result; | ||
393 | |||
394 | result = iwl_test_parse(&priv->tst, tb, data, len); | ||
395 | if (result) | ||
396 | return result; | ||
397 | |||
398 | /* in case multiple accesses to the device happens */ | ||
399 | mutex_lock(&priv->mutex); | ||
400 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | ||
401 | case IWL_TM_CMD_APP2DEV_UCODE: | ||
402 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: | ||
403 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: | ||
404 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: | ||
405 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | ||
406 | case IWL_TM_CMD_APP2DEV_END_TRACE: | ||
407 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: | ||
408 | case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
409 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: | ||
410 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: | ||
411 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: | ||
412 | result = iwl_test_handle_cmd(&priv->tst, tb); | ||
413 | break; | ||
414 | |||
415 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: | ||
416 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | ||
417 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | ||
418 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | ||
419 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | ||
420 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | ||
421 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | ||
422 | case IWL_TM_CMD_APP2DEV_GET_FW_INFO: | ||
423 | IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); | ||
424 | result = iwl_testmode_driver(hw, tb); | ||
425 | break; | ||
426 | |||
427 | case IWL_TM_CMD_APP2DEV_OWNERSHIP: | ||
428 | IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n"); | ||
429 | result = iwl_testmode_ownership(hw, tb); | ||
430 | break; | ||
431 | |||
432 | default: | ||
433 | IWL_ERR(priv, "Unknown testmode command\n"); | ||
434 | result = -ENOSYS; | ||
435 | break; | ||
436 | } | ||
437 | mutex_unlock(&priv->mutex); | ||
438 | |||
439 | if (result) | ||
440 | IWL_ERR(priv, "Test cmd failed result=%d\n", result); | ||
441 | return result; | ||
442 | } | ||
443 | |||
444 | int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
445 | struct netlink_callback *cb, | ||
446 | void *data, int len) | ||
447 | { | ||
448 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
449 | int result; | ||
450 | u32 cmd; | ||
451 | |||
452 | if (cb->args[3]) { | ||
453 | /* offset by 1 since commands start at 0 */ | ||
454 | cmd = cb->args[3] - 1; | ||
455 | } else { | ||
456 | struct nlattr *tb[IWL_TM_ATTR_MAX]; | ||
457 | |||
458 | result = iwl_test_parse(&priv->tst, tb, data, len); | ||
459 | if (result) | ||
460 | return result; | ||
461 | |||
462 | cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); | ||
463 | cb->args[3] = cmd + 1; | ||
464 | } | ||
465 | |||
466 | /* in case multiple accesses to the device happens */ | ||
467 | mutex_lock(&priv->mutex); | ||
468 | result = iwl_test_dump(&priv->tst, cmd, skb, cb); | ||
469 | mutex_unlock(&priv->mutex); | ||
470 | return result; | ||
471 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 353a053b4eb1..5ee983faa679 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -162,18 +162,6 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
162 | if (ieee80211_is_data(fc)) { | 162 | if (ieee80211_is_data(fc)) { |
163 | tx_cmd->initial_rate_index = 0; | 163 | tx_cmd->initial_rate_index = 0; |
164 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; | 164 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; |
165 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | ||
166 | if (priv->tm_fixed_rate) { | ||
167 | /* | ||
168 | * rate overwrite by testmode | ||
169 | * we not only send lq command to change rate | ||
170 | * we also re-enforce per data pkt base. | ||
171 | */ | ||
172 | tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK; | ||
173 | memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate, | ||
174 | sizeof(tx_cmd->rate_n_flags)); | ||
175 | } | ||
176 | #endif | ||
177 | return; | 165 | return; |
178 | } else if (ieee80211_is_back_req(fc)) | 166 | } else if (ieee80211_is_back_req(fc)) |
179 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; | 167 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index d4f3b4864ab1..22b7fa5b971a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -67,16 +67,16 @@ | |||
67 | #include "iwl-agn-hw.h" | 67 | #include "iwl-agn-hw.h" |
68 | 68 | ||
69 | /* Highest firmware API version supported */ | 69 | /* Highest firmware API version supported */ |
70 | #define IWL7260_UCODE_API_MAX 6 | 70 | #define IWL7260_UCODE_API_MAX 7 |
71 | #define IWL3160_UCODE_API_MAX 6 | 71 | #define IWL3160_UCODE_API_MAX 7 |
72 | 72 | ||
73 | /* Oldest version we won't warn about */ | 73 | /* Oldest version we won't warn about */ |
74 | #define IWL7260_UCODE_API_OK 6 | 74 | #define IWL7260_UCODE_API_OK 7 |
75 | #define IWL3160_UCODE_API_OK 6 | 75 | #define IWL3160_UCODE_API_OK 7 |
76 | 76 | ||
77 | /* Lowest firmware API version supported */ | 77 | /* Lowest firmware API version supported */ |
78 | #define IWL7260_UCODE_API_MIN 6 | 78 | #define IWL7260_UCODE_API_MIN 7 |
79 | #define IWL3160_UCODE_API_MIN 6 | 79 | #define IWL3160_UCODE_API_MIN 7 |
80 | 80 | ||
81 | /* NVM versions */ | 81 | /* NVM versions */ |
82 | #define IWL7260_NVM_VERSION 0x0a1d | 82 | #define IWL7260_NVM_VERSION 0x0a1d |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 0189b9050f22..83b9ff6ff3ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -222,6 +222,7 @@ struct iwl_cfg { | |||
222 | const u32 max_inst_size; | 222 | const u32 max_inst_size; |
223 | u8 valid_tx_ant; | 223 | u8 valid_tx_ant; |
224 | u8 valid_rx_ant; | 224 | u8 valid_rx_ant; |
225 | bool bt_shared_single_ant; | ||
225 | u16 nvm_ver; | 226 | u16 nvm_ver; |
226 | u16 nvm_calib_ver; | 227 | u16 nvm_calib_ver; |
227 | /* params not likely to change within a device family */ | 228 | /* params not likely to change within a device family */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 2f690e578b5c..d0162d426f88 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1111,11 +1111,8 @@ void iwl_drv_stop(struct iwl_drv *drv) | |||
1111 | /* shared module parameters */ | 1111 | /* shared module parameters */ |
1112 | struct iwl_mod_params iwlwifi_mod_params = { | 1112 | struct iwl_mod_params iwlwifi_mod_params = { |
1113 | .restart_fw = true, | 1113 | .restart_fw = true, |
1114 | .plcp_check = true, | ||
1115 | .bt_coex_active = true, | 1114 | .bt_coex_active = true, |
1116 | .power_level = IWL_POWER_INDEX_1, | 1115 | .power_level = IWL_POWER_INDEX_1, |
1117 | .bt_ch_announce = true, | ||
1118 | .auto_agg = true, | ||
1119 | .wd_disable = true, | 1116 | .wd_disable = true, |
1120 | /* the rest are 0 by default */ | 1117 | /* the rest are 0 by default */ |
1121 | }; | 1118 | }; |
@@ -1223,14 +1220,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, | |||
1223 | MODULE_PARM_DESC(antenna_coupling, | 1220 | MODULE_PARM_DESC(antenna_coupling, |
1224 | "specify antenna coupling in dB (defualt: 0 dB)"); | 1221 | "specify antenna coupling in dB (defualt: 0 dB)"); |
1225 | 1222 | ||
1226 | module_param_named(bt_ch_inhibition, iwlwifi_mod_params.bt_ch_announce, | ||
1227 | bool, S_IRUGO); | ||
1228 | MODULE_PARM_DESC(bt_ch_inhibition, | ||
1229 | "Enable BT channel inhibition (default: enable)"); | ||
1230 | |||
1231 | module_param_named(plcp_check, iwlwifi_mod_params.plcp_check, bool, S_IRUGO); | ||
1232 | MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | ||
1233 | |||
1234 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); | 1223 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); |
1235 | MODULE_PARM_DESC(wd_disable, | 1224 | MODULE_PARM_DESC(wd_disable, |
1236 | "Disable stuck queue watchdog timer 0=system default, " | 1225 | "Disable stuck queue watchdog timer 0=system default, " |
@@ -1272,8 +1261,3 @@ module_param_named(power_level, iwlwifi_mod_params.power_level, | |||
1272 | int, S_IRUGO); | 1261 | int, S_IRUGO); |
1273 | MODULE_PARM_DESC(power_level, | 1262 | MODULE_PARM_DESC(power_level, |
1274 | "default power save level (range from 1 - 5, default: 1)"); | 1263 | "default power save level (range from 1 - 5, default: 1)"); |
1275 | |||
1276 | module_param_named(auto_agg, iwlwifi_mod_params.auto_agg, | ||
1277 | bool, S_IRUGO); | ||
1278 | MODULE_PARM_DESC(auto_agg, | ||
1279 | "enable agg w/o check traffic load (default: enable)"); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index d4ad505b0a4b..a1f580c0c6c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
@@ -93,7 +93,6 @@ enum iwl_power_level { | |||
93 | * use IWL_DISABLE_HT_* constants | 93 | * use IWL_DISABLE_HT_* constants |
94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 | 94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
95 | * @restart_fw: restart firmware, default = 1 | 95 | * @restart_fw: restart firmware, default = 1 |
96 | * @plcp_check: enable plcp health check, default = true | ||
97 | * @wd_disable: enable stuck queue check, default = 0 | 96 | * @wd_disable: enable stuck queue check, default = 0 |
98 | * @bt_coex_active: enable bt coex, default = true | 97 | * @bt_coex_active: enable bt coex, default = true |
99 | * @led_mode: system default, default = 0 | 98 | * @led_mode: system default, default = 0 |
@@ -101,15 +100,12 @@ enum iwl_power_level { | |||
101 | * @power_level: power level, default = 1 | 100 | * @power_level: power level, default = 1 |
102 | * @debug_level: levels are IWL_DL_* | 101 | * @debug_level: levels are IWL_DL_* |
103 | * @ant_coupling: antenna coupling in dB, default = 0 | 102 | * @ant_coupling: antenna coupling in dB, default = 0 |
104 | * @bt_ch_announce: BT channel inhibition, default = enable | ||
105 | * @auto_agg: enable agg. without check, default = true | ||
106 | */ | 103 | */ |
107 | struct iwl_mod_params { | 104 | struct iwl_mod_params { |
108 | int sw_crypto; | 105 | int sw_crypto; |
109 | unsigned int disable_11n; | 106 | unsigned int disable_11n; |
110 | int amsdu_size_8K; | 107 | int amsdu_size_8K; |
111 | bool restart_fw; | 108 | bool restart_fw; |
112 | bool plcp_check; | ||
113 | int wd_disable; | 109 | int wd_disable; |
114 | bool bt_coex_active; | 110 | bool bt_coex_active; |
115 | int led_mode; | 111 | int led_mode; |
@@ -119,8 +115,6 @@ struct iwl_mod_params { | |||
119 | u32 debug_level; | 115 | u32 debug_level; |
120 | #endif | 116 | #endif |
121 | int ant_coupling; | 117 | int ant_coupling; |
122 | bool bt_ch_announce; | ||
123 | bool auto_agg; | ||
124 | char *nvm_file; | 118 | char *nvm_file; |
125 | }; | 119 | }; |
126 | 120 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c deleted file mode 100644 index 5cfd55b86ed3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ /dev/null | |||
@@ -1,852 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | |||
64 | #include <linux/export.h> | ||
65 | #include <net/netlink.h> | ||
66 | |||
67 | #include "iwl-drv.h" | ||
68 | #include "iwl-io.h" | ||
69 | #include "iwl-fh.h" | ||
70 | #include "iwl-prph.h" | ||
71 | #include "iwl-trans.h" | ||
72 | #include "iwl-test.h" | ||
73 | #include "iwl-csr.h" | ||
74 | #include "iwl-testmode.h" | ||
75 | |||
76 | /* | ||
77 | * Periphery registers absolute lower bound. This is used in order to | ||
78 | * differentiate registery access through HBUS_TARG_PRPH_* and | ||
79 | * HBUS_TARG_MEM_* accesses. | ||
80 | */ | ||
81 | #define IWL_ABS_PRPH_START (0xA00000) | ||
82 | |||
83 | /* | ||
84 | * The TLVs used in the gnl message policy between the kernel module and | ||
85 | * user space application. iwl_testmode_gnl_msg_policy is to be carried | ||
86 | * through the NL80211_CMD_TESTMODE channel regulated by nl80211. | ||
87 | * See iwl-testmode.h | ||
88 | */ | ||
89 | static | ||
90 | struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | ||
91 | [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, }, | ||
92 | |||
93 | [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, }, | ||
94 | [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, }, | ||
95 | |||
96 | [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, }, | ||
97 | [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, }, | ||
98 | [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, }, | ||
99 | |||
100 | [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, | ||
101 | [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, | ||
102 | |||
103 | [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, | ||
104 | |||
105 | [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, | ||
106 | [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, | ||
107 | [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, | ||
108 | |||
109 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, | ||
110 | |||
111 | [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, | ||
112 | |||
113 | [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, }, | ||
114 | [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, }, | ||
115 | [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, }, | ||
116 | |||
117 | [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, | ||
118 | [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, | ||
119 | [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, | ||
120 | [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, | ||
121 | [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, | ||
122 | |||
123 | [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, | ||
124 | }; | ||
125 | |||
126 | static inline void iwl_test_trace_clear(struct iwl_test *tst) | ||
127 | { | ||
128 | memset(&tst->trace, 0, sizeof(struct iwl_test_trace)); | ||
129 | } | ||
130 | |||
131 | static void iwl_test_trace_stop(struct iwl_test *tst) | ||
132 | { | ||
133 | if (!tst->trace.enabled) | ||
134 | return; | ||
135 | |||
136 | if (tst->trace.cpu_addr && tst->trace.dma_addr) | ||
137 | dma_free_coherent(tst->trans->dev, | ||
138 | tst->trace.tsize, | ||
139 | tst->trace.cpu_addr, | ||
140 | tst->trace.dma_addr); | ||
141 | |||
142 | iwl_test_trace_clear(tst); | ||
143 | } | ||
144 | |||
145 | static inline void iwl_test_mem_clear(struct iwl_test *tst) | ||
146 | { | ||
147 | memset(&tst->mem, 0, sizeof(struct iwl_test_mem)); | ||
148 | } | ||
149 | |||
150 | static inline void iwl_test_mem_stop(struct iwl_test *tst) | ||
151 | { | ||
152 | if (!tst->mem.in_read) | ||
153 | return; | ||
154 | |||
155 | iwl_test_mem_clear(tst); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Initializes the test object | ||
160 | * During the lifetime of the test object it is assumed that the transport is | ||
161 | * started. The test object should be stopped before the transport is stopped. | ||
162 | */ | ||
163 | void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans, | ||
164 | struct iwl_test_ops *ops) | ||
165 | { | ||
166 | tst->trans = trans; | ||
167 | tst->ops = ops; | ||
168 | |||
169 | iwl_test_trace_clear(tst); | ||
170 | iwl_test_mem_clear(tst); | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(iwl_test_init); | ||
173 | |||
174 | /* | ||
175 | * Stop the test object | ||
176 | */ | ||
177 | void iwl_test_free(struct iwl_test *tst) | ||
178 | { | ||
179 | iwl_test_mem_stop(tst); | ||
180 | iwl_test_trace_stop(tst); | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(iwl_test_free); | ||
183 | |||
184 | static inline int iwl_test_send_cmd(struct iwl_test *tst, | ||
185 | struct iwl_host_cmd *cmd) | ||
186 | { | ||
187 | return tst->ops->send_cmd(tst->trans->op_mode, cmd); | ||
188 | } | ||
189 | |||
190 | static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr) | ||
191 | { | ||
192 | return tst->ops->valid_hw_addr(addr); | ||
193 | } | ||
194 | |||
195 | static inline u32 iwl_test_fw_ver(struct iwl_test *tst) | ||
196 | { | ||
197 | return tst->ops->get_fw_ver(tst->trans->op_mode); | ||
198 | } | ||
199 | |||
200 | static inline struct sk_buff* | ||
201 | iwl_test_alloc_reply(struct iwl_test *tst, int len) | ||
202 | { | ||
203 | return tst->ops->alloc_reply(tst->trans->op_mode, len); | ||
204 | } | ||
205 | |||
206 | static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb) | ||
207 | { | ||
208 | return tst->ops->reply(tst->trans->op_mode, skb); | ||
209 | } | ||
210 | |||
211 | static inline struct sk_buff* | ||
212 | iwl_test_alloc_event(struct iwl_test *tst, int len) | ||
213 | { | ||
214 | return tst->ops->alloc_event(tst->trans->op_mode, len); | ||
215 | } | ||
216 | |||
217 | static inline void | ||
218 | iwl_test_event(struct iwl_test *tst, struct sk_buff *skb) | ||
219 | { | ||
220 | return tst->ops->event(tst->trans->op_mode, skb); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * This function handles the user application commands to the fw. The fw | ||
225 | * commands are sent in a synchronuous manner. In case that the user requested | ||
226 | * to get commands response, it is send to the user. | ||
227 | */ | ||
228 | static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb) | ||
229 | { | ||
230 | struct iwl_host_cmd cmd; | ||
231 | struct iwl_rx_packet *pkt; | ||
232 | struct sk_buff *skb; | ||
233 | void *reply_buf; | ||
234 | u32 reply_len; | ||
235 | int ret; | ||
236 | bool cmd_want_skb; | ||
237 | |||
238 | memset(&cmd, 0, sizeof(struct iwl_host_cmd)); | ||
239 | |||
240 | if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] || | ||
241 | !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) { | ||
242 | IWL_ERR(tst->trans, "Missing fw command mandatory fields\n"); | ||
243 | return -ENOMSG; | ||
244 | } | ||
245 | |||
246 | cmd.flags = CMD_ON_DEMAND | CMD_SYNC; | ||
247 | cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]); | ||
248 | if (cmd_want_skb) | ||
249 | cmd.flags |= CMD_WANT_SKB; | ||
250 | |||
251 | cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); | ||
252 | cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); | ||
253 | cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); | ||
254 | cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | ||
255 | IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n", | ||
256 | cmd.id, cmd.flags, cmd.len[0]); | ||
257 | |||
258 | ret = iwl_test_send_cmd(tst, &cmd); | ||
259 | if (ret) { | ||
260 | IWL_ERR(tst->trans, "Failed to send hcmd\n"); | ||
261 | return ret; | ||
262 | } | ||
263 | if (!cmd_want_skb) | ||
264 | return ret; | ||
265 | |||
266 | /* Handling return of SKB to the user */ | ||
267 | pkt = cmd.resp_pkt; | ||
268 | if (!pkt) { | ||
269 | IWL_ERR(tst->trans, "HCMD received a null response packet\n"); | ||
270 | return ret; | ||
271 | } | ||
272 | |||
273 | reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
274 | skb = iwl_test_alloc_reply(tst, reply_len + 20); | ||
275 | reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL); | ||
276 | if (!skb || !reply_buf) { | ||
277 | kfree_skb(skb); | ||
278 | kfree(reply_buf); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | /* The reply is in a page, that we cannot send to user space. */ | ||
283 | iwl_free_resp(&cmd); | ||
284 | |||
285 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | ||
286 | IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || | ||
287 | nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf)) | ||
288 | goto nla_put_failure; | ||
289 | return iwl_test_reply(tst, skb); | ||
290 | |||
291 | nla_put_failure: | ||
292 | IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n"); | ||
293 | kfree(reply_buf); | ||
294 | kfree_skb(skb); | ||
295 | return -ENOMSG; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * Handles the user application commands for register access. | ||
300 | */ | ||
301 | static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb) | ||
302 | { | ||
303 | u32 ofs, val32, cmd; | ||
304 | u8 val8; | ||
305 | struct sk_buff *skb; | ||
306 | int status = 0; | ||
307 | struct iwl_trans *trans = tst->trans; | ||
308 | |||
309 | if (!tb[IWL_TM_ATTR_REG_OFFSET]) { | ||
310 | IWL_ERR(trans, "Missing reg offset\n"); | ||
311 | return -ENOMSG; | ||
312 | } | ||
313 | |||
314 | ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); | ||
315 | IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs); | ||
316 | |||
317 | cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); | ||
318 | |||
319 | /* | ||
320 | * Allow access only to FH/CSR/HBUS in direct mode. | ||
321 | * Since we don't have the upper bounds for the CSR and HBUS segments, | ||
322 | * we will use only the upper bound of FH for sanity check. | ||
323 | */ | ||
324 | if (ofs >= FH_MEM_UPPER_BOUND) { | ||
325 | IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n", | ||
326 | FH_MEM_UPPER_BOUND); | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | |||
330 | switch (cmd) { | ||
331 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: | ||
332 | val32 = iwl_read_direct32(tst->trans, ofs); | ||
333 | IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32); | ||
334 | |||
335 | skb = iwl_test_alloc_reply(tst, 20); | ||
336 | if (!skb) { | ||
337 | IWL_ERR(trans, "Memory allocation fail\n"); | ||
338 | return -ENOMEM; | ||
339 | } | ||
340 | if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32)) | ||
341 | goto nla_put_failure; | ||
342 | status = iwl_test_reply(tst, skb); | ||
343 | if (status < 0) | ||
344 | IWL_ERR(trans, "Error sending msg : %d\n", status); | ||
345 | break; | ||
346 | |||
347 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: | ||
348 | if (!tb[IWL_TM_ATTR_REG_VALUE32]) { | ||
349 | IWL_ERR(trans, "Missing value to write\n"); | ||
350 | return -ENOMSG; | ||
351 | } else { | ||
352 | val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); | ||
353 | IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32); | ||
354 | iwl_write_direct32(tst->trans, ofs, val32); | ||
355 | } | ||
356 | break; | ||
357 | |||
358 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: | ||
359 | if (!tb[IWL_TM_ATTR_REG_VALUE8]) { | ||
360 | IWL_ERR(trans, "Missing value to write\n"); | ||
361 | return -ENOMSG; | ||
362 | } else { | ||
363 | val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); | ||
364 | IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8); | ||
365 | iwl_write8(tst->trans, ofs, val8); | ||
366 | } | ||
367 | break; | ||
368 | |||
369 | default: | ||
370 | IWL_ERR(trans, "Unknown test register cmd ID\n"); | ||
371 | return -ENOMSG; | ||
372 | } | ||
373 | |||
374 | return status; | ||
375 | |||
376 | nla_put_failure: | ||
377 | kfree_skb(skb); | ||
378 | return -EMSGSIZE; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Handles the request to start FW tracing. Allocates of the trace buffer | ||
383 | * and sends a reply to user space with the address of the allocated buffer. | ||
384 | */ | ||
385 | static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb) | ||
386 | { | ||
387 | struct sk_buff *skb; | ||
388 | int status = 0; | ||
389 | |||
390 | if (tst->trace.enabled) | ||
391 | return -EBUSY; | ||
392 | |||
393 | if (!tb[IWL_TM_ATTR_TRACE_SIZE]) | ||
394 | tst->trace.size = TRACE_BUFF_SIZE_DEF; | ||
395 | else | ||
396 | tst->trace.size = | ||
397 | nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); | ||
398 | |||
399 | if (!tst->trace.size) | ||
400 | return -EINVAL; | ||
401 | |||
402 | if (tst->trace.size < TRACE_BUFF_SIZE_MIN || | ||
403 | tst->trace.size > TRACE_BUFF_SIZE_MAX) | ||
404 | return -EINVAL; | ||
405 | |||
406 | tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD; | ||
407 | tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev, | ||
408 | tst->trace.tsize, | ||
409 | &tst->trace.dma_addr, | ||
410 | GFP_KERNEL); | ||
411 | if (!tst->trace.cpu_addr) | ||
412 | return -ENOMEM; | ||
413 | |||
414 | tst->trace.enabled = true; | ||
415 | tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100); | ||
416 | |||
417 | memset(tst->trace.trace_addr, 0x03B, tst->trace.size); | ||
418 | |||
419 | skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20); | ||
420 | if (!skb) { | ||
421 | IWL_ERR(tst->trans, "Memory allocation fail\n"); | ||
422 | iwl_test_trace_stop(tst); | ||
423 | return -ENOMEM; | ||
424 | } | ||
425 | |||
426 | if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR, | ||
427 | sizeof(tst->trace.dma_addr), | ||
428 | (u64 *)&tst->trace.dma_addr)) | ||
429 | goto nla_put_failure; | ||
430 | |||
431 | status = iwl_test_reply(tst, skb); | ||
432 | if (status < 0) | ||
433 | IWL_ERR(tst->trans, "Error sending msg : %d\n", status); | ||
434 | |||
435 | tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size, | ||
436 | DUMP_CHUNK_SIZE); | ||
437 | |||
438 | return status; | ||
439 | |||
440 | nla_put_failure: | ||
441 | kfree_skb(skb); | ||
442 | if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) == | ||
443 | IWL_TM_CMD_APP2DEV_BEGIN_TRACE) | ||
444 | iwl_test_trace_stop(tst); | ||
445 | return -EMSGSIZE; | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Handles indirect read from the periphery or the SRAM. The read is performed | ||
450 | * to a temporary buffer. The user space application should later issue a dump | ||
451 | */ | ||
452 | static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) | ||
453 | { | ||
454 | struct iwl_trans *trans = tst->trans; | ||
455 | unsigned long flags; | ||
456 | int i; | ||
457 | |||
458 | if (size & 0x3) | ||
459 | return -EINVAL; | ||
460 | |||
461 | tst->mem.size = size; | ||
462 | tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL); | ||
463 | if (tst->mem.addr == NULL) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | /* Hard-coded periphery absolute address */ | ||
467 | if (IWL_ABS_PRPH_START <= addr && | ||
468 | addr < IWL_ABS_PRPH_START + PRPH_END) { | ||
469 | if (!iwl_trans_grab_nic_access(trans, false, &flags)) { | ||
470 | return -EIO; | ||
471 | } | ||
472 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, | ||
473 | addr | (3 << 24)); | ||
474 | for (i = 0; i < size; i += 4) | ||
475 | *(u32 *)(tst->mem.addr + i) = | ||
476 | iwl_read32(trans, HBUS_TARG_PRPH_RDAT); | ||
477 | iwl_trans_release_nic_access(trans, &flags); | ||
478 | } else { /* target memory (SRAM) */ | ||
479 | iwl_trans_read_mem(trans, addr, tst->mem.addr, | ||
480 | tst->mem.size / 4); | ||
481 | } | ||
482 | |||
483 | tst->mem.nchunks = | ||
484 | DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE); | ||
485 | tst->mem.in_read = true; | ||
486 | return 0; | ||
487 | |||
488 | } | ||
489 | |||
490 | /* | ||
491 | * Handles indirect write to the periphery or SRAM. The is performed to a | ||
492 | * temporary buffer. | ||
493 | */ | ||
494 | static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, | ||
495 | u32 size, unsigned char *buf) | ||
496 | { | ||
497 | struct iwl_trans *trans = tst->trans; | ||
498 | u32 val, i; | ||
499 | unsigned long flags; | ||
500 | |||
501 | if (IWL_ABS_PRPH_START <= addr && | ||
502 | addr < IWL_ABS_PRPH_START + PRPH_END) { | ||
503 | /* Periphery writes can be 1-3 bytes long, or DWORDs */ | ||
504 | if (size < 4) { | ||
505 | memcpy(&val, buf, size); | ||
506 | if (!iwl_trans_grab_nic_access(trans, false, &flags)) | ||
507 | return -EIO; | ||
508 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | ||
509 | (addr & 0x0000FFFF) | | ||
510 | ((size - 1) << 24)); | ||
511 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | ||
512 | iwl_trans_release_nic_access(trans, &flags); | ||
513 | } else { | ||
514 | if (size % 4) | ||
515 | return -EINVAL; | ||
516 | for (i = 0; i < size; i += 4) | ||
517 | iwl_write_prph(trans, addr+i, | ||
518 | *(u32 *)(buf+i)); | ||
519 | } | ||
520 | } else if (iwl_test_valid_hw_addr(tst, addr)) { | ||
521 | iwl_trans_write_mem(trans, addr, buf, size / 4); | ||
522 | } else { | ||
523 | return -EINVAL; | ||
524 | } | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Handles the user application commands for indirect read/write | ||
530 | * to/from the periphery or the SRAM. | ||
531 | */ | ||
532 | static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb) | ||
533 | { | ||
534 | u32 addr, size, cmd; | ||
535 | unsigned char *buf; | ||
536 | |||
537 | /* Both read and write should be blocked, for atomicity */ | ||
538 | if (tst->mem.in_read) | ||
539 | return -EBUSY; | ||
540 | |||
541 | cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); | ||
542 | if (!tb[IWL_TM_ATTR_MEM_ADDR]) { | ||
543 | IWL_ERR(tst->trans, "Error finding memory offset address\n"); | ||
544 | return -ENOMSG; | ||
545 | } | ||
546 | addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]); | ||
547 | if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) { | ||
548 | IWL_ERR(tst->trans, "Error finding size for memory reading\n"); | ||
549 | return -ENOMSG; | ||
550 | } | ||
551 | size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]); | ||
552 | |||
553 | if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) { | ||
554 | return iwl_test_indirect_read(tst, addr, size); | ||
555 | } else { | ||
556 | if (!tb[IWL_TM_ATTR_BUFFER_DUMP]) | ||
557 | return -EINVAL; | ||
558 | buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]); | ||
559 | return iwl_test_indirect_write(tst, addr, size, buf); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * Enable notifications to user space | ||
565 | */ | ||
566 | static int iwl_test_notifications(struct iwl_test *tst, | ||
567 | struct nlattr **tb) | ||
568 | { | ||
569 | tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); | ||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * Handles the request to get the device id | ||
575 | */ | ||
576 | static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb) | ||
577 | { | ||
578 | u32 devid = tst->trans->hw_id; | ||
579 | struct sk_buff *skb; | ||
580 | int status; | ||
581 | |||
582 | IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid); | ||
583 | |||
584 | skb = iwl_test_alloc_reply(tst, 20); | ||
585 | if (!skb) { | ||
586 | IWL_ERR(tst->trans, "Memory allocation fail\n"); | ||
587 | return -ENOMEM; | ||
588 | } | ||
589 | |||
590 | if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid)) | ||
591 | goto nla_put_failure; | ||
592 | status = iwl_test_reply(tst, skb); | ||
593 | if (status < 0) | ||
594 | IWL_ERR(tst->trans, "Error sending msg : %d\n", status); | ||
595 | |||
596 | return 0; | ||
597 | |||
598 | nla_put_failure: | ||
599 | kfree_skb(skb); | ||
600 | return -EMSGSIZE; | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * Handles the request to get the FW version | ||
605 | */ | ||
606 | static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb) | ||
607 | { | ||
608 | struct sk_buff *skb; | ||
609 | int status; | ||
610 | u32 ver = iwl_test_fw_ver(tst); | ||
611 | |||
612 | IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver); | ||
613 | |||
614 | skb = iwl_test_alloc_reply(tst, 20); | ||
615 | if (!skb) { | ||
616 | IWL_ERR(tst->trans, "Memory allocation fail\n"); | ||
617 | return -ENOMEM; | ||
618 | } | ||
619 | |||
620 | if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver)) | ||
621 | goto nla_put_failure; | ||
622 | |||
623 | status = iwl_test_reply(tst, skb); | ||
624 | if (status < 0) | ||
625 | IWL_ERR(tst->trans, "Error sending msg : %d\n", status); | ||
626 | |||
627 | return 0; | ||
628 | |||
629 | nla_put_failure: | ||
630 | kfree_skb(skb); | ||
631 | return -EMSGSIZE; | ||
632 | } | ||
633 | |||
634 | /* | ||
635 | * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists | ||
636 | */ | ||
637 | int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, | ||
638 | void *data, int len) | ||
639 | { | ||
640 | int result; | ||
641 | |||
642 | result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, | ||
643 | iwl_testmode_gnl_msg_policy); | ||
644 | if (result) { | ||
645 | IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result); | ||
646 | return result; | ||
647 | } | ||
648 | |||
649 | /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ | ||
650 | if (!tb[IWL_TM_ATTR_COMMAND]) { | ||
651 | IWL_ERR(tst->trans, "Missing testmode command type\n"); | ||
652 | return -ENOMSG; | ||
653 | } | ||
654 | return 0; | ||
655 | } | ||
656 | IWL_EXPORT_SYMBOL(iwl_test_parse); | ||
657 | |||
658 | /* | ||
659 | * Handle test commands. | ||
660 | * Returns 1 for unknown commands (not handled by the test object); negative | ||
661 | * value in case of error. | ||
662 | */ | ||
663 | int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb) | ||
664 | { | ||
665 | int result; | ||
666 | |||
667 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | ||
668 | case IWL_TM_CMD_APP2DEV_UCODE: | ||
669 | IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n"); | ||
670 | result = iwl_test_fw_cmd(tst, tb); | ||
671 | break; | ||
672 | |||
673 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: | ||
674 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: | ||
675 | case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: | ||
676 | IWL_DEBUG_INFO(tst->trans, "test cmd to register\n"); | ||
677 | result = iwl_test_reg(tst, tb); | ||
678 | break; | ||
679 | |||
680 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | ||
681 | IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n"); | ||
682 | result = iwl_test_trace_begin(tst, tb); | ||
683 | break; | ||
684 | |||
685 | case IWL_TM_CMD_APP2DEV_END_TRACE: | ||
686 | iwl_test_trace_stop(tst); | ||
687 | result = 0; | ||
688 | break; | ||
689 | |||
690 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: | ||
691 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: | ||
692 | IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n"); | ||
693 | result = iwl_test_indirect_mem(tst, tb); | ||
694 | break; | ||
695 | |||
696 | case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
697 | IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n"); | ||
698 | result = iwl_test_notifications(tst, tb); | ||
699 | break; | ||
700 | |||
701 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: | ||
702 | IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n"); | ||
703 | result = iwl_test_get_fw_ver(tst, tb); | ||
704 | break; | ||
705 | |||
706 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: | ||
707 | IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n"); | ||
708 | result = iwl_test_get_dev_id(tst, tb); | ||
709 | break; | ||
710 | |||
711 | default: | ||
712 | IWL_DEBUG_INFO(tst->trans, "Unknown test command\n"); | ||
713 | result = 1; | ||
714 | break; | ||
715 | } | ||
716 | return result; | ||
717 | } | ||
718 | IWL_EXPORT_SYMBOL(iwl_test_handle_cmd); | ||
719 | |||
720 | static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, | ||
721 | struct netlink_callback *cb) | ||
722 | { | ||
723 | int idx, length; | ||
724 | |||
725 | if (!tst->trace.enabled || !tst->trace.trace_addr) | ||
726 | return -EFAULT; | ||
727 | |||
728 | idx = cb->args[4]; | ||
729 | if (idx >= tst->trace.nchunks) | ||
730 | return -ENOENT; | ||
731 | |||
732 | length = DUMP_CHUNK_SIZE; | ||
733 | if (((idx + 1) == tst->trace.nchunks) && | ||
734 | (tst->trace.size % DUMP_CHUNK_SIZE)) | ||
735 | length = tst->trace.size % | ||
736 | DUMP_CHUNK_SIZE; | ||
737 | |||
738 | if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length, | ||
739 | tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx))) | ||
740 | goto nla_put_failure; | ||
741 | |||
742 | cb->args[4] = ++idx; | ||
743 | return 0; | ||
744 | |||
745 | nla_put_failure: | ||
746 | return -ENOBUFS; | ||
747 | } | ||
748 | |||
749 | static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb, | ||
750 | struct netlink_callback *cb) | ||
751 | { | ||
752 | int idx, length; | ||
753 | |||
754 | if (!tst->mem.in_read) | ||
755 | return -EFAULT; | ||
756 | |||
757 | idx = cb->args[4]; | ||
758 | if (idx >= tst->mem.nchunks) { | ||
759 | iwl_test_mem_stop(tst); | ||
760 | return -ENOENT; | ||
761 | } | ||
762 | |||
763 | length = DUMP_CHUNK_SIZE; | ||
764 | if (((idx + 1) == tst->mem.nchunks) && | ||
765 | (tst->mem.size % DUMP_CHUNK_SIZE)) | ||
766 | length = tst->mem.size % DUMP_CHUNK_SIZE; | ||
767 | |||
768 | if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length, | ||
769 | tst->mem.addr + (DUMP_CHUNK_SIZE * idx))) | ||
770 | goto nla_put_failure; | ||
771 | |||
772 | cb->args[4] = ++idx; | ||
773 | return 0; | ||
774 | |||
775 | nla_put_failure: | ||
776 | return -ENOBUFS; | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * Handle dump commands. | ||
781 | * Returns 1 for unknown commands (not handled by the test object); negative | ||
782 | * value in case of error. | ||
783 | */ | ||
784 | int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, | ||
785 | struct netlink_callback *cb) | ||
786 | { | ||
787 | int result; | ||
788 | |||
789 | switch (cmd) { | ||
790 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
791 | IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n"); | ||
792 | result = iwl_test_trace_dump(tst, skb, cb); | ||
793 | break; | ||
794 | |||
795 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: | ||
796 | IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n"); | ||
797 | result = iwl_test_buffer_dump(tst, skb, cb); | ||
798 | break; | ||
799 | |||
800 | default: | ||
801 | result = 1; | ||
802 | break; | ||
803 | } | ||
804 | return result; | ||
805 | } | ||
806 | IWL_EXPORT_SYMBOL(iwl_test_dump); | ||
807 | |||
808 | /* | ||
809 | * Multicast a spontaneous messages from the device to the user space. | ||
810 | */ | ||
811 | static void iwl_test_send_rx(struct iwl_test *tst, | ||
812 | struct iwl_rx_cmd_buffer *rxb) | ||
813 | { | ||
814 | struct sk_buff *skb; | ||
815 | struct iwl_rx_packet *data; | ||
816 | int length; | ||
817 | |||
818 | data = rxb_addr(rxb); | ||
819 | length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
820 | |||
821 | /* the length doesn't include len_n_flags field, so add it manually */ | ||
822 | length += sizeof(__le32); | ||
823 | |||
824 | skb = iwl_test_alloc_event(tst, length + 20); | ||
825 | if (skb == NULL) { | ||
826 | IWL_ERR(tst->trans, "Out of memory for message to user\n"); | ||
827 | return; | ||
828 | } | ||
829 | |||
830 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | ||
831 | IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) || | ||
832 | nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data)) | ||
833 | goto nla_put_failure; | ||
834 | |||
835 | iwl_test_event(tst, skb); | ||
836 | return; | ||
837 | |||
838 | nla_put_failure: | ||
839 | kfree_skb(skb); | ||
840 | IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n"); | ||
841 | } | ||
842 | |||
843 | /* | ||
844 | * Called whenever a Rx frames is recevied from the device. If notifications to | ||
845 | * the user space are requested, sends the frames to the user. | ||
846 | */ | ||
847 | void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) | ||
848 | { | ||
849 | if (tst->notify) | ||
850 | iwl_test_send_rx(tst, rxb); | ||
851 | } | ||
852 | IWL_EXPORT_SYMBOL(iwl_test_rx); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h deleted file mode 100644 index 8fbd21704840..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-test.h +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | |||
64 | #ifndef __IWL_TEST_H__ | ||
65 | #define __IWL_TEST_H__ | ||
66 | |||
67 | #include <linux/types.h> | ||
68 | #include "iwl-trans.h" | ||
69 | |||
70 | struct iwl_test_trace { | ||
71 | u32 size; | ||
72 | u32 tsize; | ||
73 | u32 nchunks; | ||
74 | u8 *cpu_addr; | ||
75 | u8 *trace_addr; | ||
76 | dma_addr_t dma_addr; | ||
77 | bool enabled; | ||
78 | }; | ||
79 | |||
80 | struct iwl_test_mem { | ||
81 | u32 size; | ||
82 | u32 nchunks; | ||
83 | u8 *addr; | ||
84 | bool in_read; | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * struct iwl_test_ops: callback to the op mode | ||
89 | * | ||
90 | * The structure defines the callbacks that the op_mode should handle, | ||
91 | * inorder to handle logic that is out of the scope of iwl_test. The | ||
92 | * op_mode must set all the callbacks. | ||
93 | |||
94 | * @send_cmd: handler that is used by the test object to request the | ||
95 | * op_mode to send a command to the fw. | ||
96 | * | ||
97 | * @valid_hw_addr: handler that is used by the test object to request the | ||
98 | * op_mode to check if the given address is a valid address. | ||
99 | * | ||
100 | * @get_fw_ver: handler used to get the FW version. | ||
101 | * | ||
102 | * @alloc_reply: handler used by the test object to request the op_mode | ||
103 | * to allocate an skb for sending a reply to the user, and initialize | ||
104 | * the skb. It is assumed that the test object only fills the required | ||
105 | * attributes. | ||
106 | * | ||
107 | * @reply: handler used by the test object to request the op_mode to reply | ||
108 | * to a request. The skb is an skb previously allocated by the the | ||
109 | * alloc_reply callback. | ||
110 | I | ||
111 | * @alloc_event: handler used by the test object to request the op_mode | ||
112 | * to allocate an skb for sending an event, and initialize | ||
113 | * the skb. It is assumed that the test object only fills the required | ||
114 | * attributes. | ||
115 | * | ||
116 | * @reply: handler used by the test object to request the op_mode to send | ||
117 | * an event. The skb is an skb previously allocated by the the | ||
118 | * alloc_event callback. | ||
119 | */ | ||
120 | struct iwl_test_ops { | ||
121 | int (*send_cmd)(struct iwl_op_mode *op_modes, | ||
122 | struct iwl_host_cmd *cmd); | ||
123 | bool (*valid_hw_addr)(u32 addr); | ||
124 | u32 (*get_fw_ver)(struct iwl_op_mode *op_mode); | ||
125 | |||
126 | struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len); | ||
127 | int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
128 | struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len); | ||
129 | void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
130 | }; | ||
131 | |||
132 | struct iwl_test { | ||
133 | struct iwl_trans *trans; | ||
134 | struct iwl_test_ops *ops; | ||
135 | struct iwl_test_trace trace; | ||
136 | struct iwl_test_mem mem; | ||
137 | bool notify; | ||
138 | }; | ||
139 | |||
140 | void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans, | ||
141 | struct iwl_test_ops *ops); | ||
142 | |||
143 | void iwl_test_free(struct iwl_test *tst); | ||
144 | |||
145 | int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, | ||
146 | void *data, int len); | ||
147 | |||
148 | int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb); | ||
149 | |||
150 | int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, | ||
151 | struct netlink_callback *cb); | ||
152 | |||
153 | void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb); | ||
154 | |||
155 | static inline void iwl_test_enable_notifications(struct iwl_test *tst, | ||
156 | bool enable) | ||
157 | { | ||
158 | tst->notify = enable; | ||
159 | } | ||
160 | |||
161 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h deleted file mode 100644 index 98f48a9afc98..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ /dev/null | |||
@@ -1,309 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | #ifndef __IWL_TESTMODE_H__ | ||
64 | #define __IWL_TESTMODE_H__ | ||
65 | |||
66 | #include <linux/types.h> | ||
67 | |||
68 | |||
69 | /* | ||
70 | * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and | ||
71 | * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX). | ||
72 | * The command ID is carried with IWL_TM_ATTR_COMMAND. | ||
73 | * | ||
74 | * @IWL_TM_CMD_APP2DEV_UCODE: | ||
75 | * commands from user application to the uCode, | ||
76 | * the actual uCode host command ID is carried with | ||
77 | * IWL_TM_ATTR_UCODE_CMD_ID | ||
78 | * | ||
79 | * @IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: | ||
80 | * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: | ||
81 | * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: | ||
82 | * commands from user applicaiton to access register | ||
83 | * | ||
84 | * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name | ||
85 | * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image | ||
86 | * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration | ||
87 | * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image | ||
88 | * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data | ||
89 | * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS | ||
90 | * commands fom user space for pure driver level operations | ||
91 | * | ||
92 | * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | ||
93 | * @IWL_TM_CMD_APP2DEV_END_TRACE: | ||
94 | * @IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
95 | * commands fom user space for uCode trace operations | ||
96 | * | ||
97 | * @IWL_TM_CMD_DEV2APP_SYNC_RSP: | ||
98 | * commands from kernel space to carry the synchronous response | ||
99 | * to user application | ||
100 | * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT: | ||
101 | * commands from kernel space to multicast the spontaneous messages | ||
102 | * to user application, or reply of host commands | ||
103 | * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: | ||
104 | * commands from kernel space to carry the eeprom response | ||
105 | * to user application | ||
106 | * | ||
107 | * @IWL_TM_CMD_APP2DEV_OWNERSHIP: | ||
108 | * commands from user application to own change the ownership of the uCode | ||
109 | * if application has the ownership, the only host command from | ||
110 | * testmode will deliver to uCode. Default owner is driver | ||
111 | * | ||
112 | * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image | ||
113 | * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version | ||
114 | * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device | ||
115 | * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: | ||
116 | * retrieve information of existing loaded uCode image | ||
117 | * | ||
118 | * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: | ||
119 | * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: | ||
120 | * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: | ||
121 | * Commands to read/write data from periphery or SRAM memory ranges. | ||
122 | * Fore reading, a READ command is sent from the userspace and the data | ||
123 | * is returned when the user calls a DUMP command. | ||
124 | * For writing, only a WRITE command is used. | ||
125 | * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
126 | * Command to enable/disable notifications (currently RX packets) from the | ||
127 | * driver to userspace. | ||
128 | */ | ||
129 | enum iwl_tm_cmd_t { | ||
130 | IWL_TM_CMD_APP2DEV_UCODE = 1, | ||
131 | IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 = 2, | ||
132 | IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 = 3, | ||
133 | IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8 = 4, | ||
134 | IWL_TM_CMD_APP2DEV_GET_DEVICENAME = 5, | ||
135 | IWL_TM_CMD_APP2DEV_LOAD_INIT_FW = 6, | ||
136 | IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB = 7, | ||
137 | IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW = 8, | ||
138 | IWL_TM_CMD_APP2DEV_GET_EEPROM = 9, | ||
139 | IWL_TM_CMD_APP2DEV_FIXRATE_REQ = 10, | ||
140 | IWL_TM_CMD_APP2DEV_BEGIN_TRACE = 11, | ||
141 | IWL_TM_CMD_APP2DEV_END_TRACE = 12, | ||
142 | IWL_TM_CMD_APP2DEV_READ_TRACE = 13, | ||
143 | IWL_TM_CMD_DEV2APP_SYNC_RSP = 14, | ||
144 | IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15, | ||
145 | IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16, | ||
146 | IWL_TM_CMD_APP2DEV_OWNERSHIP = 17, | ||
147 | RESERVED_18 = 18, | ||
148 | RESERVED_19 = 19, | ||
149 | RESERVED_20 = 20, | ||
150 | RESERVED_21 = 21, | ||
151 | IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22, | ||
152 | IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23, | ||
153 | IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24, | ||
154 | IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25, | ||
155 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, | ||
156 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, | ||
157 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, | ||
158 | IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29, | ||
159 | IWL_TM_CMD_MAX = 30, | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * Atrribute filed in testmode command | ||
164 | * See enum iwl_tm_cmd_t. | ||
165 | * | ||
166 | * @IWL_TM_ATTR_NOT_APPLICABLE: | ||
167 | * The attribute is not applicable or invalid | ||
168 | * @IWL_TM_ATTR_COMMAND: | ||
169 | * From user space to kernel space: | ||
170 | * the command either destines to ucode, driver, or register; | ||
171 | * From kernel space to user space: | ||
172 | * the command either carries synchronous response, | ||
173 | * or the spontaneous message multicast from the device; | ||
174 | * | ||
175 | * @IWL_TM_ATTR_UCODE_CMD_ID: | ||
176 | * @IWL_TM_ATTR_UCODE_CMD_DATA: | ||
177 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE, | ||
178 | * The mandatory fields are : | ||
179 | * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID; | ||
180 | * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload | ||
181 | * to the ucode | ||
182 | * | ||
183 | * @IWL_TM_ATTR_REG_OFFSET: | ||
184 | * @IWL_TM_ATTR_REG_VALUE8: | ||
185 | * @IWL_TM_ATTR_REG_VALUE32: | ||
186 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX, | ||
187 | * The mandatory fields are: | ||
188 | * IWL_TM_ATTR_REG_OFFSET for the offset of the target register; | ||
189 | * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value | ||
190 | * | ||
191 | * @IWL_TM_ATTR_SYNC_RSP: | ||
192 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP, | ||
193 | * The mandatory fields are: | ||
194 | * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user | ||
195 | * application command | ||
196 | * | ||
197 | * @IWL_TM_ATTR_UCODE_RX_PKT: | ||
198 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, | ||
199 | * The mandatory fields are: | ||
200 | * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user | ||
201 | * application | ||
202 | * | ||
203 | * @IWL_TM_ATTR_EEPROM: | ||
204 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM, | ||
205 | * The mandatory fields are: | ||
206 | * IWL_TM_ATTR_EEPROM for the data content responging to the user | ||
207 | * application | ||
208 | * | ||
209 | * @IWL_TM_ATTR_TRACE_ADDR: | ||
210 | * @IWL_TM_ATTR_TRACE_SIZE: | ||
211 | * @IWL_TM_ATTR_TRACE_DUMP: | ||
212 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, | ||
213 | * The mandatory fields are: | ||
214 | * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address | ||
215 | * IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size | ||
216 | * IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump | ||
217 | * | ||
218 | * @IWL_TM_ATTR_FIXRATE: | ||
219 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, | ||
220 | * The mandatory fields are: | ||
221 | * IWL_TM_ATTR_FIXRATE for the fixed rate | ||
222 | * | ||
223 | * @IWL_TM_ATTR_UCODE_OWNER: | ||
224 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP, | ||
225 | * The mandatory fields are: | ||
226 | * IWL_TM_ATTR_UCODE_OWNER for the new owner | ||
227 | * | ||
228 | * @IWL_TM_ATTR_MEM_ADDR: | ||
229 | * @IWL_TM_ATTR_BUFFER_SIZE: | ||
230 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ | ||
231 | * or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE. | ||
232 | * The mandatory fields are: | ||
233 | * IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write | ||
234 | * IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write. | ||
235 | * | ||
236 | * @IWL_TM_ATTR_BUFFER_DUMP: | ||
237 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP, | ||
238 | * IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read. | ||
239 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE, | ||
240 | * this attribute contains the data to write. | ||
241 | * | ||
242 | * @IWL_TM_ATTR_FW_VERSION: | ||
243 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION, | ||
244 | * IWL_TM_ATTR_FW_VERSION for the uCode version | ||
245 | * | ||
246 | * @IWL_TM_ATTR_DEVICE_ID: | ||
247 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID, | ||
248 | * IWL_TM_ATTR_DEVICE_ID for the device ID information | ||
249 | * | ||
250 | * @IWL_TM_ATTR_FW_TYPE: | ||
251 | * @IWL_TM_ATTR_FW_INST_SIZE: | ||
252 | * @IWL_TM_ATTR_FW_DATA_SIZE: | ||
253 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO, | ||
254 | * The mandatory fields are: | ||
255 | * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...) | ||
256 | * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section | ||
257 | * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section | ||
258 | * | ||
259 | * @IWL_TM_ATTR_UCODE_CMD_SKB: | ||
260 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag | ||
261 | * indicates that the user wants to receive the response of the command | ||
262 | * in a reply SKB. If it's not present, the response is not returned. | ||
263 | * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS: | ||
264 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this | ||
265 | * flag enables (if present) or disables (if not) the forwarding | ||
266 | * to userspace. | ||
267 | */ | ||
268 | enum iwl_tm_attr_t { | ||
269 | IWL_TM_ATTR_NOT_APPLICABLE = 0, | ||
270 | IWL_TM_ATTR_COMMAND = 1, | ||
271 | IWL_TM_ATTR_UCODE_CMD_ID = 2, | ||
272 | IWL_TM_ATTR_UCODE_CMD_DATA = 3, | ||
273 | IWL_TM_ATTR_REG_OFFSET = 4, | ||
274 | IWL_TM_ATTR_REG_VALUE8 = 5, | ||
275 | IWL_TM_ATTR_REG_VALUE32 = 6, | ||
276 | IWL_TM_ATTR_SYNC_RSP = 7, | ||
277 | IWL_TM_ATTR_UCODE_RX_PKT = 8, | ||
278 | IWL_TM_ATTR_EEPROM = 9, | ||
279 | IWL_TM_ATTR_TRACE_ADDR = 10, | ||
280 | IWL_TM_ATTR_TRACE_SIZE = 11, | ||
281 | IWL_TM_ATTR_TRACE_DUMP = 12, | ||
282 | IWL_TM_ATTR_FIXRATE = 13, | ||
283 | IWL_TM_ATTR_UCODE_OWNER = 14, | ||
284 | IWL_TM_ATTR_MEM_ADDR = 15, | ||
285 | IWL_TM_ATTR_BUFFER_SIZE = 16, | ||
286 | IWL_TM_ATTR_BUFFER_DUMP = 17, | ||
287 | IWL_TM_ATTR_FW_VERSION = 18, | ||
288 | IWL_TM_ATTR_DEVICE_ID = 19, | ||
289 | IWL_TM_ATTR_FW_TYPE = 20, | ||
290 | IWL_TM_ATTR_FW_INST_SIZE = 21, | ||
291 | IWL_TM_ATTR_FW_DATA_SIZE = 22, | ||
292 | IWL_TM_ATTR_UCODE_CMD_SKB = 23, | ||
293 | IWL_TM_ATTR_ENABLE_NOTIFICATION = 24, | ||
294 | IWL_TM_ATTR_MAX = 25, | ||
295 | }; | ||
296 | |||
297 | /* uCode trace buffer */ | ||
298 | #define TRACE_BUFF_SIZE_MAX 0x200000 | ||
299 | #define TRACE_BUFF_SIZE_MIN 0x20000 | ||
300 | #define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN | ||
301 | #define TRACE_BUFF_PADD 0x2000 | ||
302 | |||
303 | /* Maximum data size of each dump it packet */ | ||
304 | #define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024) | ||
305 | |||
306 | /* Address offset of data segment in SRAM */ | ||
307 | #define SRAM_DATA_SEG_OFFSET 0x800000 | ||
308 | |||
309 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index be4b2ac3dbbf..8d91422c5982 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -183,14 +183,12 @@ struct iwl_rx_packet { | |||
183 | * @CMD_ASYNC: Return right away and don't want for the response | 183 | * @CMD_ASYNC: Return right away and don't want for the response |
184 | * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the | 184 | * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the |
185 | * response. The caller needs to call iwl_free_resp when done. | 185 | * response. The caller needs to call iwl_free_resp when done. |
186 | * @CMD_ON_DEMAND: This command is sent by the test mode pipe. | ||
187 | */ | 186 | */ |
188 | enum CMD_MODE { | 187 | enum CMD_MODE { |
189 | CMD_SYNC = 0, | 188 | CMD_SYNC = 0, |
190 | CMD_ASYNC = BIT(0), | 189 | CMD_ASYNC = BIT(0), |
191 | CMD_WANT_SKB = BIT(1), | 190 | CMD_WANT_SKB = BIT(1), |
192 | CMD_SEND_IN_RFKILL = BIT(2), | 191 | CMD_SEND_IN_RFKILL = BIT(2), |
193 | CMD_ON_DEMAND = BIT(3), | ||
194 | }; | 192 | }; |
195 | 193 | ||
196 | #define DEF_CMD_PAYLOAD_SIZE 320 | 194 | #define DEF_CMD_PAYLOAD_SIZE 320 |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 9a4d94a1f90d..dbd622a3929c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
@@ -202,6 +202,22 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { | |||
202 | cpu_to_le32(0x00000000), | 202 | cpu_to_le32(0x00000000), |
203 | }; | 203 | }; |
204 | 204 | ||
205 | /* single shared antenna */ | ||
206 | static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = { | ||
207 | cpu_to_le32(0x40000000), | ||
208 | cpu_to_le32(0x00000000), | ||
209 | cpu_to_le32(0x44000000), | ||
210 | cpu_to_le32(0x00000000), | ||
211 | cpu_to_le32(0x40000000), | ||
212 | cpu_to_le32(0x00000000), | ||
213 | cpu_to_le32(0x44000000), | ||
214 | cpu_to_le32(0x00000000), | ||
215 | cpu_to_le32(0xC0004000), | ||
216 | cpu_to_le32(0xF0005000), | ||
217 | cpu_to_le32(0xC0004000), | ||
218 | cpu_to_le32(0xF0005000), | ||
219 | }; | ||
220 | |||
205 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | 221 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) |
206 | { | 222 | { |
207 | struct iwl_bt_coex_cmd cmd = { | 223 | struct iwl_bt_coex_cmd cmd = { |
@@ -225,7 +241,10 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
225 | BT_VALID_REDUCED_TX_POWER | | 241 | BT_VALID_REDUCED_TX_POWER | |
226 | BT_VALID_LUT); | 242 | BT_VALID_LUT); |
227 | 243 | ||
228 | if (is_loose_coex()) | 244 | if (mvm->cfg->bt_shared_single_ant) |
245 | memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup, | ||
246 | sizeof(iwl_single_shared_ant_lookup)); | ||
247 | else if (is_loose_coex()) | ||
229 | memcpy(&cmd.decision_lut, iwl_loose_lookup, | 248 | memcpy(&cmd.decision_lut, iwl_loose_lookup, |
230 | sizeof(iwl_tight_lookup)); | 249 | sizeof(iwl_tight_lookup)); |
231 | else | 250 | else |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 8c49db02c9c1..7e5e5c2f9f87 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -1026,6 +1026,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, | |||
1026 | if (ret) | 1026 | if (ret) |
1027 | goto out; | 1027 | goto out; |
1028 | 1028 | ||
1029 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1030 | if (mvm->d3_wake_sysassert) | ||
1031 | d3_cfg_cmd_data.wakeup_flags |= | ||
1032 | cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR); | ||
1033 | #endif | ||
1034 | |||
1029 | /* must be last -- this switches firmware state */ | 1035 | /* must be last -- this switches firmware state */ |
1030 | ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); | 1036 | ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); |
1031 | if (ret) | 1037 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index b7643c16201f..e56ed2a84888 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -344,6 +344,13 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, | |||
344 | case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: | 344 | case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: |
345 | IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); | 345 | IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); |
346 | dbgfs_pm->disable_power_off = val; | 346 | dbgfs_pm->disable_power_off = val; |
347 | case MVM_DEBUGFS_PM_LPRX_ENA: | ||
348 | IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled"); | ||
349 | dbgfs_pm->lprx_ena = val; | ||
350 | break; | ||
351 | case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD: | ||
352 | IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val); | ||
353 | dbgfs_pm->lprx_rssi_threshold = val; | ||
347 | break; | 354 | break; |
348 | } | 355 | } |
349 | } | 356 | } |
@@ -387,6 +394,17 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file, | |||
387 | if (sscanf(buf + 18, "%d", &val) != 1) | 394 | if (sscanf(buf + 18, "%d", &val) != 1) |
388 | return -EINVAL; | 395 | return -EINVAL; |
389 | param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; | 396 | param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; |
397 | } else if (!strncmp("lprx=", buf, 5)) { | ||
398 | if (sscanf(buf + 5, "%d", &val) != 1) | ||
399 | return -EINVAL; | ||
400 | param = MVM_DEBUGFS_PM_LPRX_ENA; | ||
401 | } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) { | ||
402 | if (sscanf(buf + 20, "%d", &val) != 1) | ||
403 | return -EINVAL; | ||
404 | if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val < | ||
405 | POWER_LPRX_RSSI_THRESHOLD_MIN) | ||
406 | return -EINVAL; | ||
407 | param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD; | ||
390 | } else { | 408 | } else { |
391 | return -EINVAL; | 409 | return -EINVAL; |
392 | } | 410 | } |
@@ -421,7 +439,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file, | |||
421 | le32_to_cpu(cmd.skip_dtim_periods)); | 439 | le32_to_cpu(cmd.skip_dtim_periods)); |
422 | pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", | 440 | pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", |
423 | iwlmvm_mod_params.power_scheme); | 441 | iwlmvm_mod_params.power_scheme); |
424 | pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n", | 442 | pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", |
425 | le16_to_cpu(cmd.flags)); | 443 | le16_to_cpu(cmd.flags)); |
426 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", | 444 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", |
427 | cmd.keep_alive_seconds); | 445 | cmd.keep_alive_seconds); |
@@ -435,6 +453,10 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file, | |||
435 | le32_to_cpu(cmd.rx_data_timeout)); | 453 | le32_to_cpu(cmd.rx_data_timeout)); |
436 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", | 454 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", |
437 | le32_to_cpu(cmd.tx_data_timeout)); | 455 | le32_to_cpu(cmd.tx_data_timeout)); |
456 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
457 | pos += scnprintf(buf+pos, bufsz-pos, | ||
458 | "lprx_rssi_threshold = %d\n", | ||
459 | le32_to_cpu(cmd.lprx_rssi_threshold)); | ||
438 | } | 460 | } |
439 | 461 | ||
440 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 462 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
@@ -939,6 +961,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
939 | #ifdef CONFIG_PM_SLEEP | 961 | #ifdef CONFIG_PM_SLEEP |
940 | MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 962 | MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); |
941 | MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); | 963 | MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); |
964 | if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, | ||
965 | mvm->debugfs_dir, &mvm->d3_wake_sysassert)) | ||
966 | goto err; | ||
942 | #endif | 967 | #endif |
943 | 968 | ||
944 | /* | 969 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index d8e19290b0f3..a6da359a80c3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
@@ -66,6 +66,11 @@ | |||
66 | 66 | ||
67 | /* Power Management Commands, Responses, Notifications */ | 67 | /* Power Management Commands, Responses, Notifications */ |
68 | 68 | ||
69 | /* Radio LP RX Energy Threshold measured in dBm */ | ||
70 | #define POWER_LPRX_RSSI_THRESHOLD 75 | ||
71 | #define POWER_LPRX_RSSI_THRESHOLD_MAX 94 | ||
72 | #define POWER_LPRX_RSSI_THRESHOLD_MIN 30 | ||
73 | |||
69 | /** | 74 | /** |
70 | * enum iwl_scan_flags - masks for power table command flags | 75 | * enum iwl_scan_flags - masks for power table command flags |
71 | * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off | 76 | * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 273b0cc197ab..94aae9c8562c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -865,6 +865,30 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, | |||
865 | return ret; | 865 | return ret; |
866 | } | 866 | } |
867 | 867 | ||
868 | struct iwl_mvm_mac_ap_iterator_data { | ||
869 | struct iwl_mvm *mvm; | ||
870 | struct ieee80211_vif *vif; | ||
871 | u32 beacon_device_ts; | ||
872 | u16 beacon_int; | ||
873 | }; | ||
874 | |||
875 | /* Find the beacon_device_ts and beacon_int for a managed interface */ | ||
876 | static void iwl_mvm_mac_ap_iterator(void *_data, u8 *mac, | ||
877 | struct ieee80211_vif *vif) | ||
878 | { | ||
879 | struct iwl_mvm_mac_ap_iterator_data *data = _data; | ||
880 | |||
881 | if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) | ||
882 | return; | ||
883 | |||
884 | /* Station client has higher priority over P2P client*/ | ||
885 | if (vif->p2p && data->beacon_device_ts) | ||
886 | return; | ||
887 | |||
888 | data->beacon_device_ts = vif->bss_conf.sync_device_ts; | ||
889 | data->beacon_int = vif->bss_conf.beacon_int; | ||
890 | } | ||
891 | |||
868 | /* | 892 | /* |
869 | * Fill the specific data for mac context of type AP of P2P GO | 893 | * Fill the specific data for mac context of type AP of P2P GO |
870 | */ | 894 | */ |
@@ -874,6 +898,11 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, | |||
874 | bool add) | 898 | bool add) |
875 | { | 899 | { |
876 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 900 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
901 | struct iwl_mvm_mac_ap_iterator_data data = { | ||
902 | .mvm = mvm, | ||
903 | .vif = vif, | ||
904 | .beacon_device_ts = 0 | ||
905 | }; | ||
877 | 906 | ||
878 | ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); | 907 | ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); |
879 | ctxt_ap->bi_reciprocal = | 908 | ctxt_ap->bi_reciprocal = |
@@ -887,16 +916,33 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, | |||
887 | ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); | 916 | ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); |
888 | 917 | ||
889 | /* | 918 | /* |
890 | * Only read the system time when the MAC is being added, when we | 919 | * Only set the beacon time when the MAC is being added, when we |
891 | * just modify the MAC then we should keep the time -- the firmware | 920 | * just modify the MAC then we should keep the time -- the firmware |
892 | * can otherwise have a "jumping" TBTT. | 921 | * can otherwise have a "jumping" TBTT. |
893 | */ | 922 | */ |
894 | if (add) | 923 | if (add) { |
895 | mvmvif->ap_beacon_time = | 924 | /* |
896 | iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); | 925 | * If there is a station/P2P client interface which is |
926 | * associated, set the AP's TBTT far enough from the station's | ||
927 | * TBTT. Otherwise, set it to the current system time | ||
928 | */ | ||
929 | ieee80211_iterate_active_interfaces_atomic( | ||
930 | mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, | ||
931 | iwl_mvm_mac_ap_iterator, &data); | ||
932 | |||
933 | if (data.beacon_device_ts) { | ||
934 | u32 rand = (prandom_u32() % (80 - 20)) + 20; | ||
935 | mvmvif->ap_beacon_time = data.beacon_device_ts + | ||
936 | ieee80211_tu_to_usec(data.beacon_int * rand / | ||
937 | 100); | ||
938 | } else { | ||
939 | mvmvif->ap_beacon_time = | ||
940 | iwl_read_prph(mvm->trans, | ||
941 | DEVICE_SYSTEM_TIME_REG); | ||
942 | } | ||
943 | } | ||
897 | 944 | ||
898 | ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); | 945 | ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); |
899 | |||
900 | ctxt_ap->beacon_tsf = 0; /* unused */ | 946 | ctxt_ap->beacon_tsf = 0; /* unused */ |
901 | 947 | ||
902 | /* TODO: Assume that the beacon id == mac context id */ | 948 | /* TODO: Assume that the beacon id == mac context id */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index c7409f159a36..d40d7db185d6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -73,7 +73,6 @@ | |||
73 | #include "iwl-trans.h" | 73 | #include "iwl-trans.h" |
74 | #include "iwl-notif-wait.h" | 74 | #include "iwl-notif-wait.h" |
75 | #include "iwl-eeprom-parse.h" | 75 | #include "iwl-eeprom-parse.h" |
76 | #include "iwl-test.h" | ||
77 | #include "iwl-trans.h" | 76 | #include "iwl-trans.h" |
78 | #include "sta.h" | 77 | #include "sta.h" |
79 | #include "fw-api.h" | 78 | #include "fw-api.h" |
@@ -159,6 +158,8 @@ enum iwl_dbgfs_pm_mask { | |||
159 | MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), | 158 | MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), |
160 | MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), | 159 | MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), |
161 | MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), | 160 | MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), |
161 | MVM_DEBUGFS_PM_LPRX_ENA = BIT(6), | ||
162 | MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), | ||
162 | }; | 163 | }; |
163 | 164 | ||
164 | struct iwl_dbgfs_pm { | 165 | struct iwl_dbgfs_pm { |
@@ -168,6 +169,8 @@ struct iwl_dbgfs_pm { | |||
168 | bool skip_over_dtim; | 169 | bool skip_over_dtim; |
169 | u8 skip_dtim_periods; | 170 | u8 skip_dtim_periods; |
170 | bool disable_power_off; | 171 | bool disable_power_off; |
172 | bool lprx_ena; | ||
173 | u32 lprx_rssi_threshold; | ||
171 | int mask; | 174 | int mask; |
172 | }; | 175 | }; |
173 | 176 | ||
@@ -353,12 +356,14 @@ struct iwl_tt_params { | |||
353 | * @dynamic_smps: Is thermal throttling enabled dynamic_smps? | 356 | * @dynamic_smps: Is thermal throttling enabled dynamic_smps? |
354 | * @tx_backoff: The current thremal throttling tx backoff in uSec. | 357 | * @tx_backoff: The current thremal throttling tx backoff in uSec. |
355 | * @params: Parameters to configure the thermal throttling algorithm. | 358 | * @params: Parameters to configure the thermal throttling algorithm. |
359 | * @throttle: Is thermal throttling is active? | ||
356 | */ | 360 | */ |
357 | struct iwl_mvm_tt_mgmt { | 361 | struct iwl_mvm_tt_mgmt { |
358 | struct delayed_work ct_kill_exit; | 362 | struct delayed_work ct_kill_exit; |
359 | bool dynamic_smps; | 363 | bool dynamic_smps; |
360 | u32 tx_backoff; | 364 | u32 tx_backoff; |
361 | const struct iwl_tt_params *params; | 365 | const struct iwl_tt_params *params; |
366 | bool throttle; | ||
362 | }; | 367 | }; |
363 | 368 | ||
364 | struct iwl_mvm { | 369 | struct iwl_mvm { |
@@ -461,6 +466,7 @@ struct iwl_mvm { | |||
461 | struct wiphy_wowlan_support wowlan; | 466 | struct wiphy_wowlan_support wowlan; |
462 | int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; | 467 | int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; |
463 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 468 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
469 | u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ | ||
464 | bool d3_test_active; | 470 | bool d3_test_active; |
465 | bool store_d3_resume_sram; | 471 | bool store_d3_resume_sram; |
466 | void *d3_resume_sram; | 472 | void *d3_resume_sram; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 3760a33ca3a4..e7ca965a89b8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -137,11 +137,12 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm, | |||
137 | le32_to_cpu(cmd->rx_data_timeout)); | 137 | le32_to_cpu(cmd->rx_data_timeout)); |
138 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | 138 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", |
139 | le32_to_cpu(cmd->tx_data_timeout)); | 139 | le32_to_cpu(cmd->tx_data_timeout)); |
140 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
141 | cmd->lprx_rssi_threshold); | ||
142 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) | 140 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) |
143 | IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", | 141 | IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", |
144 | le32_to_cpu(cmd->skip_dtim_periods)); | 142 | le32_to_cpu(cmd->skip_dtim_periods)); |
143 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
144 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
145 | le32_to_cpu(cmd->lprx_rssi_threshold)); | ||
145 | } | 146 | } |
146 | } | 147 | } |
147 | 148 | ||
@@ -181,6 +182,14 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
181 | 182 | ||
182 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | 183 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); |
183 | 184 | ||
185 | if (vif->bss_conf.beacon_rate && | ||
186 | (vif->bss_conf.beacon_rate->bitrate == 10 || | ||
187 | vif->bss_conf.beacon_rate->bitrate == 60)) { | ||
188 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | ||
189 | cmd->lprx_rssi_threshold = | ||
190 | cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD); | ||
191 | } | ||
192 | |||
184 | dtimper = hw->conf.ps_dtim_period ?: 1; | 193 | dtimper = hw->conf.ps_dtim_period ?: 1; |
185 | 194 | ||
186 | /* Check if radar detection is required on current channel */ | 195 | /* Check if radar detection is required on current channel */ |
@@ -236,6 +245,15 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
236 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) | 245 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) |
237 | cmd->skip_dtim_periods = | 246 | cmd->skip_dtim_periods = |
238 | cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); | 247 | cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); |
248 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) { | ||
249 | if (mvmvif->dbgfs_pm.lprx_ena) | ||
250 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | ||
251 | else | ||
252 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK); | ||
253 | } | ||
254 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) | ||
255 | cmd->lprx_rssi_threshold = | ||
256 | cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold); | ||
239 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 257 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
240 | } | 258 | } |
241 | 259 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 31587a318f8b..b328a988c130 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -412,24 +412,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, | |||
412 | return ret; | 412 | return ret; |
413 | } | 413 | } |
414 | 414 | ||
415 | if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { | 415 | IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", |
416 | IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", | 416 | sta->addr, tid); |
417 | sta->addr, tid); | 417 | ret = ieee80211_start_tx_ba_session(sta, tid, 5000); |
418 | ret = ieee80211_start_tx_ba_session(sta, tid, 5000); | 418 | if (ret == -EAGAIN) { |
419 | if (ret == -EAGAIN) { | 419 | /* |
420 | /* | 420 | * driver and mac80211 is out of sync |
421 | * driver and mac80211 is out of sync | 421 | * this might be cause by reloading firmware |
422 | * this might be cause by reloading firmware | 422 | * stop the tx ba session here |
423 | * stop the tx ba session here | 423 | */ |
424 | */ | 424 | IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n", |
425 | IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n", | 425 | tid); |
426 | tid); | 426 | ieee80211_stop_tx_ba_session(sta, tid); |
427 | ieee80211_stop_tx_ba_session(sta, tid); | ||
428 | } | ||
429 | } else { | ||
430 | IWL_DEBUG_HT(mvm, | ||
431 | "Aggregation not enabled for tid %d because load = %u\n", | ||
432 | tid, load); | ||
433 | } | 427 | } |
434 | return ret; | 428 | return ret; |
435 | } | 429 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index a7e3b8ddf22b..d6ae7f16ac11 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c | |||
@@ -427,6 +427,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
427 | const struct iwl_tt_params *params = mvm->thermal_throttle.params; | 427 | const struct iwl_tt_params *params = mvm->thermal_throttle.params; |
428 | struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; | 428 | struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; |
429 | s32 temperature = mvm->temperature; | 429 | s32 temperature = mvm->temperature; |
430 | bool throttle_enable = false; | ||
430 | int i; | 431 | int i; |
431 | u32 tx_backoff; | 432 | u32 tx_backoff; |
432 | 433 | ||
@@ -445,6 +446,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
445 | ieee80211_iterate_active_interfaces_atomic( | 446 | ieee80211_iterate_active_interfaces_atomic( |
446 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | 447 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, |
447 | iwl_mvm_tt_smps_iterator, mvm); | 448 | iwl_mvm_tt_smps_iterator, mvm); |
449 | throttle_enable = true; | ||
448 | } else if (tt->dynamic_smps && | 450 | } else if (tt->dynamic_smps && |
449 | temperature <= params->dynamic_smps_exit) { | 451 | temperature <= params->dynamic_smps_exit) { |
450 | IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n"); | 452 | IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n"); |
@@ -456,10 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
456 | } | 458 | } |
457 | 459 | ||
458 | if (params->support_tx_protection) { | 460 | if (params->support_tx_protection) { |
459 | if (temperature >= params->tx_protection_entry) | 461 | if (temperature >= params->tx_protection_entry) { |
460 | iwl_mvm_tt_tx_protection(mvm, true); | 462 | iwl_mvm_tt_tx_protection(mvm, true); |
461 | else if (temperature <= params->tx_protection_exit) | 463 | throttle_enable = true; |
464 | } else if (temperature <= params->tx_protection_exit) { | ||
462 | iwl_mvm_tt_tx_protection(mvm, false); | 465 | iwl_mvm_tt_tx_protection(mvm, false); |
466 | } | ||
463 | } | 467 | } |
464 | 468 | ||
465 | if (params->support_tx_backoff) { | 469 | if (params->support_tx_backoff) { |
@@ -469,9 +473,22 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
469 | break; | 473 | break; |
470 | tx_backoff = params->tx_backoff[i].backoff; | 474 | tx_backoff = params->tx_backoff[i].backoff; |
471 | } | 475 | } |
476 | if (tx_backoff != 0) | ||
477 | throttle_enable = true; | ||
472 | if (tt->tx_backoff != tx_backoff) | 478 | if (tt->tx_backoff != tx_backoff) |
473 | iwl_mvm_tt_tx_backoff(mvm, tx_backoff); | 479 | iwl_mvm_tt_tx_backoff(mvm, tx_backoff); |
474 | } | 480 | } |
481 | |||
482 | if (!tt->throttle && throttle_enable) { | ||
483 | IWL_WARN(mvm, | ||
484 | "Due to high temperature thermal throttling initiated\n"); | ||
485 | tt->throttle = true; | ||
486 | } else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == 0 && | ||
487 | temperature <= params->tx_protection_exit) { | ||
488 | IWL_WARN(mvm, | ||
489 | "Temperature is back to normal thermal throttling stopped\n"); | ||
490 | tt->throttle = false; | ||
491 | } | ||
475 | } | 492 | } |
476 | 493 | ||
477 | static const struct iwl_tt_params iwl7000_tt_params = { | 494 | static const struct iwl_tt_params iwl7000_tt_params = { |
@@ -502,6 +519,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm) | |||
502 | 519 | ||
503 | IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n"); | 520 | IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n"); |
504 | tt->params = &iwl7000_tt_params; | 521 | tt->params = &iwl7000_tt_params; |
522 | tt->throttle = false; | ||
505 | INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); | 523 | INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); |
506 | } | 524 | } |
507 | 525 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 3688dc5ba1ac..fd848cd1583e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -110,9 +110,10 @@ | |||
110 | /* | 110 | /* |
111 | * iwl_rxq_space - Return number of free slots available in queue. | 111 | * iwl_rxq_space - Return number of free slots available in queue. |
112 | */ | 112 | */ |
113 | static int iwl_rxq_space(const struct iwl_rxq *q) | 113 | static int iwl_rxq_space(const struct iwl_rxq *rxq) |
114 | { | 114 | { |
115 | int s = q->read - q->write; | 115 | int s = rxq->read - rxq->write; |
116 | |||
116 | if (s <= 0) | 117 | if (s <= 0) |
117 | s += RX_QUEUE_SIZE; | 118 | s += RX_QUEUE_SIZE; |
118 | /* keep some buffer to not confuse full and empty queue */ | 119 | /* keep some buffer to not confuse full and empty queue */ |
@@ -143,21 +144,22 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans) | |||
143 | /* | 144 | /* |
144 | * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue | 145 | * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue |
145 | */ | 146 | */ |
146 | static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) | 147 | static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, |
148 | struct iwl_rxq *rxq) | ||
147 | { | 149 | { |
148 | unsigned long flags; | 150 | unsigned long flags; |
149 | u32 reg; | 151 | u32 reg; |
150 | 152 | ||
151 | spin_lock_irqsave(&q->lock, flags); | 153 | spin_lock_irqsave(&rxq->lock, flags); |
152 | 154 | ||
153 | if (q->need_update == 0) | 155 | if (rxq->need_update == 0) |
154 | goto exit_unlock; | 156 | goto exit_unlock; |
155 | 157 | ||
156 | if (trans->cfg->base_params->shadow_reg_enable) { | 158 | if (trans->cfg->base_params->shadow_reg_enable) { |
157 | /* shadow register enabled */ | 159 | /* shadow register enabled */ |
158 | /* Device expects a multiple of 8 */ | 160 | /* Device expects a multiple of 8 */ |
159 | q->write_actual = (q->write & ~0x7); | 161 | rxq->write_actual = (rxq->write & ~0x7); |
160 | iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); | 162 | iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual); |
161 | } else { | 163 | } else { |
162 | struct iwl_trans_pcie *trans_pcie = | 164 | struct iwl_trans_pcie *trans_pcie = |
163 | IWL_TRANS_GET_PCIE_TRANS(trans); | 165 | IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -175,22 +177,22 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) | |||
175 | goto exit_unlock; | 177 | goto exit_unlock; |
176 | } | 178 | } |
177 | 179 | ||
178 | q->write_actual = (q->write & ~0x7); | 180 | rxq->write_actual = (rxq->write & ~0x7); |
179 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, | 181 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, |
180 | q->write_actual); | 182 | rxq->write_actual); |
181 | 183 | ||
182 | /* Else device is assumed to be awake */ | 184 | /* Else device is assumed to be awake */ |
183 | } else { | 185 | } else { |
184 | /* Device expects a multiple of 8 */ | 186 | /* Device expects a multiple of 8 */ |
185 | q->write_actual = (q->write & ~0x7); | 187 | rxq->write_actual = (rxq->write & ~0x7); |
186 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, | 188 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, |
187 | q->write_actual); | 189 | rxq->write_actual); |
188 | } | 190 | } |
189 | } | 191 | } |
190 | q->need_update = 0; | 192 | rxq->need_update = 0; |
191 | 193 | ||
192 | exit_unlock: | 194 | exit_unlock: |
193 | spin_unlock_irqrestore(&q->lock, flags); | 195 | spin_unlock_irqrestore(&rxq->lock, flags); |
194 | } | 196 | } |
195 | 197 | ||
196 | /* | 198 | /* |
@@ -355,19 +357,16 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | |||
355 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 357 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
356 | int i; | 358 | int i; |
357 | 359 | ||
358 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | 360 | lockdep_assert_held(&rxq->lock); |
361 | |||
359 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | 362 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
360 | /* In the reset function, these buffers may have been allocated | 363 | if (!rxq->pool[i].page) |
361 | * to an SKB, so we need to unmap and free potential storage */ | 364 | continue; |
362 | if (rxq->pool[i].page != NULL) { | 365 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, |
363 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | 366 | PAGE_SIZE << trans_pcie->rx_page_order, |
364 | PAGE_SIZE << trans_pcie->rx_page_order, | 367 | DMA_FROM_DEVICE); |
365 | DMA_FROM_DEVICE); | 368 | __free_pages(rxq->pool[i].page, trans_pcie->rx_page_order); |
366 | __free_pages(rxq->pool[i].page, | 369 | rxq->pool[i].page = NULL; |
367 | trans_pcie->rx_page_order); | ||
368 | rxq->pool[i].page = NULL; | ||
369 | } | ||
370 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
371 | } | 370 | } |
372 | } | 371 | } |
373 | 372 | ||
@@ -491,6 +490,20 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | |||
491 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | 490 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); |
492 | } | 491 | } |
493 | 492 | ||
493 | static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) | ||
494 | { | ||
495 | int i; | ||
496 | |||
497 | lockdep_assert_held(&rxq->lock); | ||
498 | |||
499 | INIT_LIST_HEAD(&rxq->rx_free); | ||
500 | INIT_LIST_HEAD(&rxq->rx_used); | ||
501 | rxq->free_count = 0; | ||
502 | |||
503 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | ||
504 | list_add(&rxq->pool[i].list, &rxq->rx_used); | ||
505 | } | ||
506 | |||
494 | int iwl_pcie_rx_init(struct iwl_trans *trans) | 507 | int iwl_pcie_rx_init(struct iwl_trans *trans) |
495 | { | 508 | { |
496 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 509 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -505,13 +518,12 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
505 | } | 518 | } |
506 | 519 | ||
507 | spin_lock_irqsave(&rxq->lock, flags); | 520 | spin_lock_irqsave(&rxq->lock, flags); |
508 | INIT_LIST_HEAD(&rxq->rx_free); | ||
509 | INIT_LIST_HEAD(&rxq->rx_used); | ||
510 | 521 | ||
511 | INIT_WORK(&trans_pcie->rx_replenish, | 522 | INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work); |
512 | iwl_pcie_rx_replenish_work); | ||
513 | 523 | ||
524 | /* free all first - we might be reconfigured for a different size */ | ||
514 | iwl_pcie_rxq_free_rbs(trans); | 525 | iwl_pcie_rxq_free_rbs(trans); |
526 | iwl_pcie_rx_init_rxb_lists(rxq); | ||
515 | 527 | ||
516 | for (i = 0; i < RX_QUEUE_SIZE; i++) | 528 | for (i = 0; i < RX_QUEUE_SIZE; i++) |
517 | rxq->queue[i] = NULL; | 529 | rxq->queue[i] = NULL; |
@@ -520,7 +532,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
520 | * not restocked the Rx queue with fresh buffers */ | 532 | * not restocked the Rx queue with fresh buffers */ |
521 | rxq->read = rxq->write = 0; | 533 | rxq->read = rxq->write = 0; |
522 | rxq->write_actual = 0; | 534 | rxq->write_actual = 0; |
523 | rxq->free_count = 0; | ||
524 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); | 535 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); |
525 | spin_unlock_irqrestore(&rxq->lock, flags); | 536 | spin_unlock_irqrestore(&rxq->lock, flags); |
526 | 537 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 197dbe0a868c..826c15602c46 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -838,8 +838,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
838 | unsigned long *flags) | 838 | unsigned long *flags) |
839 | { | 839 | { |
840 | int ret; | 840 | int ret; |
841 | struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); | 841 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
842 | spin_lock_irqsave(&pcie_trans->reg_lock, *flags); | 842 | |
843 | spin_lock_irqsave(&trans_pcie->reg_lock, *flags); | ||
843 | 844 | ||
844 | /* this bit wakes up the NIC */ | 845 | /* this bit wakes up the NIC */ |
845 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, | 846 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, |
@@ -875,7 +876,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
875 | WARN_ONCE(1, | 876 | WARN_ONCE(1, |
876 | "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", | 877 | "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", |
877 | val); | 878 | val); |
878 | spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); | 879 | spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); |
879 | return false; | 880 | return false; |
880 | } | 881 | } |
881 | } | 882 | } |
@@ -884,22 +885,22 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
884 | * Fool sparse by faking we release the lock - sparse will | 885 | * Fool sparse by faking we release the lock - sparse will |
885 | * track nic_access anyway. | 886 | * track nic_access anyway. |
886 | */ | 887 | */ |
887 | __release(&pcie_trans->reg_lock); | 888 | __release(&trans_pcie->reg_lock); |
888 | return true; | 889 | return true; |
889 | } | 890 | } |
890 | 891 | ||
891 | static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, | 892 | static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, |
892 | unsigned long *flags) | 893 | unsigned long *flags) |
893 | { | 894 | { |
894 | struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); | 895 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
895 | 896 | ||
896 | lockdep_assert_held(&pcie_trans->reg_lock); | 897 | lockdep_assert_held(&trans_pcie->reg_lock); |
897 | 898 | ||
898 | /* | 899 | /* |
899 | * Fool sparse by faking we acquiring the lock - sparse will | 900 | * Fool sparse by faking we acquiring the lock - sparse will |
900 | * track nic_access anyway. | 901 | * track nic_access anyway. |
901 | */ | 902 | */ |
902 | __acquire(&pcie_trans->reg_lock); | 903 | __acquire(&trans_pcie->reg_lock); |
903 | 904 | ||
904 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | 905 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, |
905 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 906 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -910,7 +911,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, | |||
910 | * scheduled on different CPUs (after we drop reg_lock). | 911 | * scheduled on different CPUs (after we drop reg_lock). |
911 | */ | 912 | */ |
912 | mmiowb(); | 913 | mmiowb(); |
913 | spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); | 914 | spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); |
914 | } | 915 | } |
915 | 916 | ||
916 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, | 917 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index a7630d5ec892..d78c495a86a0 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -100,7 +100,7 @@ | |||
100 | #define CSR_REG_BASE 0x1000 | 100 | #define CSR_REG_BASE 0x1000 |
101 | #define CSR_REG_SIZE 0x0800 | 101 | #define CSR_REG_SIZE 0x0800 |
102 | #define EEPROM_BASE 0x0000 | 102 | #define EEPROM_BASE 0x0000 |
103 | #define EEPROM_SIZE 0x0110 | 103 | #define EEPROM_SIZE 0x0200 |
104 | #define BBP_BASE 0x0000 | 104 | #define BBP_BASE 0x0000 |
105 | #define BBP_SIZE 0x00ff | 105 | #define BBP_SIZE 0x00ff |
106 | #define RF_BASE 0x0004 | 106 | #define RF_BASE 0x0004 |
@@ -2625,11 +2625,13 @@ struct mac_iveiv_entry { | |||
2625 | /* | 2625 | /* |
2626 | * DMA descriptor defines. | 2626 | * DMA descriptor defines. |
2627 | */ | 2627 | */ |
2628 | #define TXWI_DESC_SIZE (4 * sizeof(__le32)) | ||
2629 | #define RXWI_DESC_SIZE (4 * sizeof(__le32)) | ||
2630 | 2628 | ||
2631 | #define TXWI_DESC_SIZE_5592 (5 * sizeof(__le32)) | 2629 | #define TXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32)) |
2632 | #define RXWI_DESC_SIZE_5592 (6 * sizeof(__le32)) | 2630 | #define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32)) |
2631 | |||
2632 | #define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32)) | ||
2633 | #define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32)) | ||
2634 | |||
2633 | /* | 2635 | /* |
2634 | * TX WI structure | 2636 | * TX WI structure |
2635 | */ | 2637 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3aa30ddcbfea..1f80ea5e29dd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, | |||
2392 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | 2392 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); |
2393 | 2393 | ||
2394 | rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); | 2394 | rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); |
2395 | if (info->default_power1 > power_bound) | 2395 | if (info->default_power2 > power_bound) |
2396 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); | 2396 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); |
2397 | else | 2397 | else |
2398 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); | 2398 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); |
@@ -2678,30 +2678,53 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
2678 | 2678 | ||
2679 | tx_pin = 0; | 2679 | tx_pin = 0; |
2680 | 2680 | ||
2681 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 2681 | switch (rt2x00dev->default_ant.tx_chain_num) { |
2682 | if (rt2x00dev->default_ant.tx_chain_num == 2) { | 2682 | case 3: |
2683 | /* Turn on tertiary PAs */ | ||
2684 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN, | ||
2685 | rf->channel > 14); | ||
2686 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, | ||
2687 | rf->channel <= 14); | ||
2688 | /* fall-through */ | ||
2689 | case 2: | ||
2690 | /* Turn on secondary PAs */ | ||
2683 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, | 2691 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, |
2684 | rf->channel > 14); | 2692 | rf->channel > 14); |
2685 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, | 2693 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, |
2686 | rf->channel <= 14); | 2694 | rf->channel <= 14); |
2695 | /* fall-through */ | ||
2696 | case 1: | ||
2697 | /* Turn on primary PAs */ | ||
2698 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, | ||
2699 | rf->channel > 14); | ||
2700 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) | ||
2701 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); | ||
2702 | else | ||
2703 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, | ||
2704 | rf->channel <= 14); | ||
2705 | break; | ||
2687 | } | 2706 | } |
2688 | 2707 | ||
2689 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 2708 | switch (rt2x00dev->default_ant.rx_chain_num) { |
2690 | if (rt2x00dev->default_ant.rx_chain_num == 2) { | 2709 | case 3: |
2710 | /* Turn on tertiary LNAs */ | ||
2711 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1); | ||
2712 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1); | ||
2713 | /* fall-through */ | ||
2714 | case 2: | ||
2715 | /* Turn on secondary LNAs */ | ||
2691 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); | 2716 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); |
2692 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); | 2717 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); |
2718 | /* fall-through */ | ||
2719 | case 1: | ||
2720 | /* Turn on primary LNAs */ | ||
2721 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); | ||
2722 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); | ||
2723 | break; | ||
2693 | } | 2724 | } |
2694 | 2725 | ||
2695 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); | ||
2696 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); | ||
2697 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); | 2726 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); |
2698 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); | 2727 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); |
2699 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) | ||
2700 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); | ||
2701 | else | ||
2702 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, | ||
2703 | rf->channel <= 14); | ||
2704 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); | ||
2705 | 2728 | ||
2706 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); | 2729 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); |
2707 | 2730 | ||
@@ -6254,8 +6277,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
6254 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 6277 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); |
6255 | 6278 | ||
6256 | for (i = 14; i < spec->num_channels; i++) { | 6279 | for (i = 14; i < spec->num_channels; i++) { |
6257 | info[i].default_power1 = default_power1[i]; | 6280 | info[i].default_power1 = default_power1[i - 14]; |
6258 | info[i].default_power2 = default_power2[i]; | 6281 | info[i].default_power2 = default_power2[i - 14]; |
6259 | } | 6282 | } |
6260 | } | 6283 | } |
6261 | 6284 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 7c7478219bbc..00055627eb8d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -637,6 +637,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, | |||
637 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; | 637 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
638 | __le32 *txd = entry_priv->desc; | 638 | __le32 *txd = entry_priv->desc; |
639 | u32 word; | 639 | u32 word; |
640 | const unsigned int txwi_size = entry->queue->winfo_size; | ||
640 | 641 | ||
641 | /* | 642 | /* |
642 | * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 | 643 | * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 |
@@ -659,14 +660,14 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, | |||
659 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 660 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
660 | rt2x00_set_field32(&word, TXD_W1_BURST, | 661 | rt2x00_set_field32(&word, TXD_W1_BURST, |
661 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 662 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
662 | rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE); | 663 | rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size); |
663 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); | 664 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); |
664 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); | 665 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); |
665 | rt2x00_desc_write(txd, 1, word); | 666 | rt2x00_desc_write(txd, 1, word); |
666 | 667 | ||
667 | word = 0; | 668 | word = 0; |
668 | rt2x00_set_field32(&word, TXD_W2_SD_PTR1, | 669 | rt2x00_set_field32(&word, TXD_W2_SD_PTR1, |
669 | skbdesc->skb_dma + TXWI_DESC_SIZE); | 670 | skbdesc->skb_dma + txwi_size); |
670 | rt2x00_desc_write(txd, 2, word); | 671 | rt2x00_desc_write(txd, 2, word); |
671 | 672 | ||
672 | word = 0; | 673 | word = 0; |
@@ -1193,7 +1194,7 @@ static void rt2800pci_queue_init(struct data_queue *queue) | |||
1193 | queue->limit = 128; | 1194 | queue->limit = 128; |
1194 | queue->data_size = AGGREGATION_SIZE; | 1195 | queue->data_size = AGGREGATION_SIZE; |
1195 | queue->desc_size = RXD_DESC_SIZE; | 1196 | queue->desc_size = RXD_DESC_SIZE; |
1196 | queue->winfo_size = RXWI_DESC_SIZE; | 1197 | queue->winfo_size = RXWI_DESC_SIZE_4WORDS; |
1197 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); | 1198 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); |
1198 | break; | 1199 | break; |
1199 | 1200 | ||
@@ -1204,7 +1205,7 @@ static void rt2800pci_queue_init(struct data_queue *queue) | |||
1204 | queue->limit = 64; | 1205 | queue->limit = 64; |
1205 | queue->data_size = AGGREGATION_SIZE; | 1206 | queue->data_size = AGGREGATION_SIZE; |
1206 | queue->desc_size = TXD_DESC_SIZE; | 1207 | queue->desc_size = TXD_DESC_SIZE; |
1207 | queue->winfo_size = TXWI_DESC_SIZE; | 1208 | queue->winfo_size = TXWI_DESC_SIZE_4WORDS; |
1208 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); | 1209 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); |
1209 | break; | 1210 | break; |
1210 | 1211 | ||
@@ -1212,7 +1213,7 @@ static void rt2800pci_queue_init(struct data_queue *queue) | |||
1212 | queue->limit = 8; | 1213 | queue->limit = 8; |
1213 | queue->data_size = 0; /* No DMA required for beacons */ | 1214 | queue->data_size = 0; /* No DMA required for beacons */ |
1214 | queue->desc_size = TXD_DESC_SIZE; | 1215 | queue->desc_size = TXD_DESC_SIZE; |
1215 | queue->winfo_size = TXWI_DESC_SIZE; | 1216 | queue->winfo_size = TXWI_DESC_SIZE_4WORDS; |
1216 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); | 1217 | queue->priv_size = sizeof(struct queue_entry_priv_mmio); |
1217 | break; | 1218 | break; |
1218 | 1219 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 7edd903dd749..840833b26bfa 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -855,11 +855,11 @@ static void rt2800usb_queue_init(struct data_queue *queue) | |||
855 | unsigned short txwi_size, rxwi_size; | 855 | unsigned short txwi_size, rxwi_size; |
856 | 856 | ||
857 | if (rt2x00_rt(rt2x00dev, RT5592)) { | 857 | if (rt2x00_rt(rt2x00dev, RT5592)) { |
858 | txwi_size = TXWI_DESC_SIZE_5592; | 858 | txwi_size = TXWI_DESC_SIZE_5WORDS; |
859 | rxwi_size = RXWI_DESC_SIZE_5592; | 859 | rxwi_size = RXWI_DESC_SIZE_6WORDS; |
860 | } else { | 860 | } else { |
861 | txwi_size = TXWI_DESC_SIZE; | 861 | txwi_size = TXWI_DESC_SIZE_4WORDS; |
862 | rxwi_size = RXWI_DESC_SIZE; | 862 | rxwi_size = RXWI_DESC_SIZE_4WORDS; |
863 | } | 863 | } |
864 | 864 | ||
865 | switch (queue->qid) { | 865 | switch (queue->qid) { |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 53754bc66d05..54d3ddfc9888 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2825,7 +2825,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2825 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2825 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2826 | for (i = 14; i < spec->num_channels; i++) { | 2826 | for (i = 14; i < spec->num_channels; i++) { |
2827 | info[i].max_power = MAX_TXPOWER; | 2827 | info[i].max_power = MAX_TXPOWER; |
2828 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2828 | info[i].default_power1 = |
2829 | TXPOWER_FROM_DEV(tx_power[i - 14]); | ||
2829 | } | 2830 | } |
2830 | } | 2831 | } |
2831 | 2832 | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 1616ed484ceb..1d3880e09a13 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2167 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2167 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2168 | for (i = 14; i < spec->num_channels; i++) { | 2168 | for (i = 14; i < spec->num_channels; i++) { |
2169 | info[i].max_power = MAX_TXPOWER; | 2169 | info[i].max_power = MAX_TXPOWER; |
2170 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2170 | info[i].default_power1 = |
2171 | TXPOWER_FROM_DEV(tx_power[i - 14]); | ||
2171 | } | 2172 | } |
2172 | } | 2173 | } |
2173 | 2174 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c index e4c4cdc3eb67..d9ee2efffe5f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c | |||
@@ -251,7 +251,7 @@ static struct rtl_hal_cfg rtl8723ae_hal_cfg = { | |||
251 | .bar_id = 2, | 251 | .bar_id = 2, |
252 | .write_readback = true, | 252 | .write_readback = true, |
253 | .name = "rtl8723ae_pci", | 253 | .name = "rtl8723ae_pci", |
254 | .fw_name = "rtlwifi/rtl8723aefw.bin", | 254 | .fw_name = "rtlwifi/rtl8723fw.bin", |
255 | .ops = &rtl8723ae_hal_ops, | 255 | .ops = &rtl8723ae_hal_ops, |
256 | .mod_params = &rtl8723ae_mod_params, | 256 | .mod_params = &rtl8723ae_mod_params, |
257 | .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, | 257 | .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, |
@@ -353,8 +353,8 @@ MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | |||
353 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | 353 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); |
354 | MODULE_LICENSE("GPL"); | 354 | MODULE_LICENSE("GPL"); |
355 | MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); | 355 | MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); |
356 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); | 356 | MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin"); |
357 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); | 357 | MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin"); |
358 | 358 | ||
359 | module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); | 359 | module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); |
360 | module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); | 360 | module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 2e34db82a643..622fc505d3e1 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -144,6 +144,7 @@ struct bcma_host_ops { | |||
144 | 144 | ||
145 | /* Chip IDs of PCIe devices */ | 145 | /* Chip IDs of PCIe devices */ |
146 | #define BCMA_CHIP_ID_BCM4313 0x4313 | 146 | #define BCMA_CHIP_ID_BCM4313 0x4313 |
147 | #define BCMA_CHIP_ID_BCM43142 43142 | ||
147 | #define BCMA_CHIP_ID_BCM43224 43224 | 148 | #define BCMA_CHIP_ID_BCM43224 43224 |
148 | #define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8 | 149 | #define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8 |
149 | #define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa | 150 | #define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index b8b09eac60a4..c49e1a159e6e 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -330,6 +330,8 @@ | |||
330 | #define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ | 330 | #define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ |
331 | #define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ | 331 | #define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ |
332 | #define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ | 332 | #define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ |
333 | #define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100 | ||
334 | #define BCMA_CC_PMU_STAT_WDRESET 0x00000080 | ||
333 | #define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ | 335 | #define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ |
334 | #define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ | 336 | #define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ |
335 | #define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ | 337 | #define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ |
@@ -355,6 +357,11 @@ | |||
355 | #define BCMA_CC_REGCTL_DATA 0x065C | 357 | #define BCMA_CC_REGCTL_DATA 0x065C |
356 | #define BCMA_CC_PLLCTL_ADDR 0x0660 | 358 | #define BCMA_CC_PLLCTL_ADDR 0x0660 |
357 | #define BCMA_CC_PLLCTL_DATA 0x0664 | 359 | #define BCMA_CC_PLLCTL_DATA 0x0664 |
360 | #define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */ | ||
361 | #define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */ | ||
362 | #define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF | ||
363 | #define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000 | ||
364 | #define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31 | ||
358 | #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ | 365 | #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ |
359 | /* NAND flash MLC controller registers (corerev >= 38) */ | 366 | /* NAND flash MLC controller registers (corerev >= 38) */ |
360 | #define BCMA_CC_NAND_REVISION 0x0C00 | 367 | #define BCMA_CC_NAND_REVISION 0x0C00 |
@@ -435,6 +442,23 @@ | |||
435 | #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 | 442 | #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 |
436 | #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0 | 443 | #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0 |
437 | 444 | ||
445 | /* PMU rev 15 */ | ||
446 | #define BCMA_CC_PMU15_PLL_PLLCTL0 0 | ||
447 | #define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 | ||
448 | #define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0 | ||
449 | #define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC | ||
450 | #define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2 | ||
451 | #define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 | ||
452 | #define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22 | ||
453 | #define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 | ||
454 | #define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24 | ||
455 | #define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 | ||
456 | #define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 | ||
457 | #define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 | ||
458 | #define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30 | ||
459 | #define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 | ||
460 | #define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 | ||
461 | |||
438 | /* ALP clock on pre-PMU chips */ | 462 | /* ALP clock on pre-PMU chips */ |
439 | #define BCMA_CC_PMU_ALP_CLOCK 20000000 | 463 | #define BCMA_CC_PMU_ALP_CLOCK 20000000 |
440 | /* HT clock for systems with PMU-enabled chipcommon */ | 464 | /* HT clock for systems with PMU-enabled chipcommon */ |
@@ -507,6 +531,37 @@ | |||
507 | #define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18) | 531 | #define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18) |
508 | #define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19) | 532 | #define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19) |
509 | 533 | ||
534 | #define BCMA_RES_4314_LPLDO_PU BIT(0) | ||
535 | #define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1) | ||
536 | #define BCMA_RES_4314_PMU_BG_PU BIT(2) | ||
537 | #define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3) | ||
538 | #define BCMA_RES_4314_CBUCK_PFM_PU BIT(4) | ||
539 | #define BCMA_RES_4314_CLDO_PU BIT(5) | ||
540 | #define BCMA_RES_4314_LPLDO2_LVM BIT(6) | ||
541 | #define BCMA_RES_4314_WL_PMU_PU BIT(7) | ||
542 | #define BCMA_RES_4314_LNLDO_PU BIT(8) | ||
543 | #define BCMA_RES_4314_LDO3P3_PU BIT(9) | ||
544 | #define BCMA_RES_4314_OTP_PU BIT(10) | ||
545 | #define BCMA_RES_4314_XTAL_PU BIT(11) | ||
546 | #define BCMA_RES_4314_WL_PWRSW_PU BIT(12) | ||
547 | #define BCMA_RES_4314_LQ_AVAIL BIT(13) | ||
548 | #define BCMA_RES_4314_LOGIC_RET BIT(14) | ||
549 | #define BCMA_RES_4314_MEM_SLEEP BIT(15) | ||
550 | #define BCMA_RES_4314_MACPHY_RET BIT(16) | ||
551 | #define BCMA_RES_4314_WL_CORE_READY BIT(17) | ||
552 | #define BCMA_RES_4314_ILP_REQ BIT(18) | ||
553 | #define BCMA_RES_4314_ALP_AVAIL BIT(19) | ||
554 | #define BCMA_RES_4314_MISC_PWRSW_PU BIT(20) | ||
555 | #define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21) | ||
556 | #define BCMA_RES_4314_RX_PWRSW_PU BIT(22) | ||
557 | #define BCMA_RES_4314_RADIO_PU BIT(23) | ||
558 | #define BCMA_RES_4314_VCO_LDO_PU BIT(24) | ||
559 | #define BCMA_RES_4314_AFE_LDO_PU BIT(25) | ||
560 | #define BCMA_RES_4314_RX_LDO_PU BIT(26) | ||
561 | #define BCMA_RES_4314_TX_LDO_PU BIT(27) | ||
562 | #define BCMA_RES_4314_HT_AVAIL BIT(28) | ||
563 | #define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29) | ||
564 | |||
510 | /* Data for the PMU, if available. | 565 | /* Data for the PMU, if available. |
511 | * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) | 566 | * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) |
512 | */ | 567 | */ |
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h index 1ade657d5fc1..b7174998c24a 100644 --- a/include/linux/platform_data/brcmfmac-sdio.h +++ b/include/linux/platform_data/brcmfmac-sdio.h | |||
@@ -90,6 +90,10 @@ void __init brcmfmac_init_pdata(void) | |||
90 | * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are | 90 | * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are |
91 | * used for registering the irq using request_irq function. | 91 | * used for registering the irq using request_irq function. |
92 | * | 92 | * |
93 | * broken_sg_support: flag for broken sg list support of SDIO host controller. | ||
94 | * Set this to true if the SDIO host controller has higher align requirement | ||
95 | * than 32 bytes for each scatterlist item. | ||
96 | * | ||
93 | * power_on: This function is called by the brcmfmac when the module gets | 97 | * power_on: This function is called by the brcmfmac when the module gets |
94 | * loaded. This can be particularly useful for low power devices. The platform | 98 | * loaded. This can be particularly useful for low power devices. The platform |
95 | * spcific routine may for example decide to power up the complete device. | 99 | * spcific routine may for example decide to power up the complete device. |
@@ -116,6 +120,7 @@ struct brcmfmac_sdio_platform_data { | |||
116 | bool oob_irq_supported; | 120 | bool oob_irq_supported; |
117 | unsigned int oob_irq_nr; | 121 | unsigned int oob_irq_nr; |
118 | unsigned long oob_irq_flags; | 122 | unsigned long oob_irq_flags; |
123 | bool broken_sg_support; | ||
119 | void (*power_on)(void); | 124 | void (*power_on)(void); |
120 | void (*power_off)(void); | 125 | void (*power_off)(void); |
121 | void (*reset)(void); | 126 | void (*reset)(void); |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e0512aaef4b8..3c592cf473da 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -107,7 +107,6 @@ enum { | |||
107 | HCI_MGMT, | 107 | HCI_MGMT, |
108 | HCI_PAIRABLE, | 108 | HCI_PAIRABLE, |
109 | HCI_SERVICE_CACHE, | 109 | HCI_SERVICE_CACHE, |
110 | HCI_LINK_KEYS, | ||
111 | HCI_DEBUG_KEYS, | 110 | HCI_DEBUG_KEYS, |
112 | HCI_UNREGISTER, | 111 | HCI_UNREGISTER, |
113 | 112 | ||
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7cb6d360d147..f77885ea78c2 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -117,13 +117,6 @@ struct oob_data { | |||
117 | u8 randomizer[16]; | 117 | u8 randomizer[16]; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | struct le_scan_params { | ||
121 | u8 type; | ||
122 | u16 interval; | ||
123 | u16 window; | ||
124 | int timeout; | ||
125 | }; | ||
126 | |||
127 | #define HCI_MAX_SHORT_NAME_LENGTH 10 | 120 | #define HCI_MAX_SHORT_NAME_LENGTH 10 |
128 | 121 | ||
129 | struct amp_assoc { | 122 | struct amp_assoc { |
@@ -283,9 +276,6 @@ struct hci_dev { | |||
283 | 276 | ||
284 | struct delayed_work le_scan_disable; | 277 | struct delayed_work le_scan_disable; |
285 | 278 | ||
286 | struct work_struct le_scan; | ||
287 | struct le_scan_params le_scan_params; | ||
288 | |||
289 | __s8 adv_tx_power; | 279 | __s8 adv_tx_power; |
290 | __u8 adv_data[HCI_MAX_AD_LENGTH]; | 280 | __u8 adv_data[HCI_MAX_AD_LENGTH]; |
291 | __u8 adv_data_len; | 281 | __u8 adv_data_len; |
@@ -432,6 +422,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, | |||
432 | struct inquiry_entry *ie); | 422 | struct inquiry_entry *ie); |
433 | bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, | 423 | bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, |
434 | bool name_known, bool *ssp); | 424 | bool name_known, bool *ssp); |
425 | void hci_inquiry_cache_flush(struct hci_dev *hdev); | ||
435 | 426 | ||
436 | /* ----- HCI Connections ----- */ | 427 | /* ----- HCI Connections ----- */ |
437 | enum { | 428 | enum { |
@@ -1114,6 +1105,16 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); | |||
1114 | BIT(BDADDR_LE_PUBLIC) | \ | 1105 | BIT(BDADDR_LE_PUBLIC) | \ |
1115 | BIT(BDADDR_LE_RANDOM)) | 1106 | BIT(BDADDR_LE_RANDOM)) |
1116 | 1107 | ||
1108 | /* These LE scan and inquiry parameters were chosen according to LE General | ||
1109 | * Discovery Procedure specification. | ||
1110 | */ | ||
1111 | #define DISCOV_LE_SCAN_WIN 0x12 | ||
1112 | #define DISCOV_LE_SCAN_INT 0x12 | ||
1113 | #define DISCOV_LE_TIMEOUT msecs_to_jiffies(10240) | ||
1114 | #define DISCOV_INTERLEAVED_TIMEOUT msecs_to_jiffies(5120) | ||
1115 | #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 | ||
1116 | #define DISCOV_BREDR_INQUIRY_LEN 0x08 | ||
1117 | |||
1117 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 1118 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
1118 | int mgmt_index_added(struct hci_dev *hdev); | 1119 | int mgmt_index_added(struct hci_dev *hdev); |
1119 | int mgmt_index_removed(struct hci_dev *hdev); | 1120 | int mgmt_index_removed(struct hci_dev *hdev); |
@@ -1169,10 +1170,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
1169 | u8 ssp, u8 *eir, u16 eir_len); | 1170 | u8 ssp, u8 *eir, u16 eir_len); |
1170 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1171 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
1171 | u8 addr_type, s8 rssi, u8 *name, u8 name_len); | 1172 | u8 addr_type, s8 rssi, u8 *name, u8 name_len); |
1172 | int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status); | ||
1173 | int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status); | ||
1174 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering); | 1173 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering); |
1175 | int mgmt_interleaved_discovery(struct hci_dev *hdev); | ||
1176 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); | 1174 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
1177 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); | 1175 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
1178 | bool mgmt_valid_hdev(struct hci_dev *hdev); | 1176 | bool mgmt_valid_hdev(struct hci_dev *hdev); |
@@ -1212,11 +1210,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | |||
1212 | u16 latency, u16 to_multiplier); | 1210 | u16 latency, u16 to_multiplier); |
1213 | void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | 1211 | void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], |
1214 | __u8 ltk[16]); | 1212 | __u8 ltk[16]); |
1215 | int hci_do_inquiry(struct hci_dev *hdev, u8 length); | ||
1216 | int hci_cancel_inquiry(struct hci_dev *hdev); | ||
1217 | int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, | ||
1218 | int timeout); | ||
1219 | int hci_cancel_le_scan(struct hci_dev *hdev); | ||
1220 | 1213 | ||
1221 | u8 bdaddr_to_le(u8 bdaddr_type); | 1214 | u8 bdaddr_to_le(u8 bdaddr_type); |
1222 | 1215 | ||
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index fb94cf13c777..1a966afbbfa8 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -242,7 +242,7 @@ struct l2cap_conn_rsp { | |||
242 | #define L2CAP_CID_SIGNALING 0x0001 | 242 | #define L2CAP_CID_SIGNALING 0x0001 |
243 | #define L2CAP_CID_CONN_LESS 0x0002 | 243 | #define L2CAP_CID_CONN_LESS 0x0002 |
244 | #define L2CAP_CID_A2MP 0x0003 | 244 | #define L2CAP_CID_A2MP 0x0003 |
245 | #define L2CAP_CID_LE_DATA 0x0004 | 245 | #define L2CAP_CID_ATT 0x0004 |
246 | #define L2CAP_CID_LE_SIGNALING 0x0005 | 246 | #define L2CAP_CID_LE_SIGNALING 0x0005 |
247 | #define L2CAP_CID_SMP 0x0006 | 247 | #define L2CAP_CID_SMP 0x0006 |
248 | #define L2CAP_CID_DYN_START 0x0040 | 248 | #define L2CAP_CID_DYN_START 0x0040 |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6a43c34ce96f..7b0730aeb892 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -188,6 +188,8 @@ struct ieee80211_channel { | |||
188 | * when used with 802.11g (on the 2.4 GHz band); filled by the | 188 | * when used with 802.11g (on the 2.4 GHz band); filled by the |
189 | * core code when registering the wiphy. | 189 | * core code when registering the wiphy. |
190 | * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. | 190 | * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. |
191 | * @IEEE80211_RATE_SUPPORTS_5MHZ: Rate can be used in 5 MHz mode | ||
192 | * @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode | ||
191 | */ | 193 | */ |
192 | enum ieee80211_rate_flags { | 194 | enum ieee80211_rate_flags { |
193 | IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, | 195 | IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, |
@@ -195,6 +197,8 @@ enum ieee80211_rate_flags { | |||
195 | IEEE80211_RATE_MANDATORY_B = 1<<2, | 197 | IEEE80211_RATE_MANDATORY_B = 1<<2, |
196 | IEEE80211_RATE_MANDATORY_G = 1<<3, | 198 | IEEE80211_RATE_MANDATORY_G = 1<<3, |
197 | IEEE80211_RATE_ERP_G = 1<<4, | 199 | IEEE80211_RATE_ERP_G = 1<<4, |
200 | IEEE80211_RATE_SUPPORTS_5MHZ = 1<<5, | ||
201 | IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6, | ||
198 | }; | 202 | }; |
199 | 203 | ||
200 | /** | 204 | /** |
@@ -433,6 +437,30 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
433 | u32 prohibited_flags); | 437 | u32 prohibited_flags); |
434 | 438 | ||
435 | /** | 439 | /** |
440 | * ieee80211_chandef_rate_flags - returns rate flags for a channel | ||
441 | * | ||
442 | * In some channel types, not all rates may be used - for example CCK | ||
443 | * rates may not be used in 5/10 MHz channels. | ||
444 | * | ||
445 | * @chandef: channel definition for the channel | ||
446 | * | ||
447 | * Returns: rate flags which apply for this channel | ||
448 | */ | ||
449 | static inline enum ieee80211_rate_flags | ||
450 | ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef) | ||
451 | { | ||
452 | switch (chandef->width) { | ||
453 | case NL80211_CHAN_WIDTH_5: | ||
454 | return IEEE80211_RATE_SUPPORTS_5MHZ; | ||
455 | case NL80211_CHAN_WIDTH_10: | ||
456 | return IEEE80211_RATE_SUPPORTS_10MHZ; | ||
457 | default: | ||
458 | break; | ||
459 | } | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | /** | ||
436 | * enum survey_info_flags - survey information flags | 464 | * enum survey_info_flags - survey information flags |
437 | * | 465 | * |
438 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in | 466 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in |
@@ -1431,7 +1459,8 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); | |||
1431 | * This structure provides information needed to complete IEEE 802.11 | 1459 | * This structure provides information needed to complete IEEE 802.11 |
1432 | * authentication. | 1460 | * authentication. |
1433 | * | 1461 | * |
1434 | * @bss: The BSS to authenticate with. | 1462 | * @bss: The BSS to authenticate with, the callee must obtain a reference |
1463 | * to it if it needs to keep it. | ||
1435 | * @auth_type: Authentication type (algorithm) | 1464 | * @auth_type: Authentication type (algorithm) |
1436 | * @ie: Extra IEs to add to Authentication frame or %NULL | 1465 | * @ie: Extra IEs to add to Authentication frame or %NULL |
1437 | * @ie_len: Length of ie buffer in octets | 1466 | * @ie_len: Length of ie buffer in octets |
@@ -1469,11 +1498,10 @@ enum cfg80211_assoc_req_flags { | |||
1469 | * | 1498 | * |
1470 | * This structure provides information needed to complete IEEE 802.11 | 1499 | * This structure provides information needed to complete IEEE 802.11 |
1471 | * (re)association. | 1500 | * (re)association. |
1472 | * @bss: The BSS to associate with. If the call is successful the driver | 1501 | * @bss: The BSS to associate with. If the call is successful the driver is |
1473 | * is given a reference that it must release, normally via a call to | 1502 | * given a reference that it must give back to cfg80211_send_rx_assoc() |
1474 | * cfg80211_send_rx_assoc(), or, if association timed out, with a | 1503 | * or to cfg80211_assoc_timeout(). To ensure proper refcounting, new |
1475 | * call to cfg80211_put_bss() (in addition to calling | 1504 | * association requests while already associating must be rejected. |
1476 | * cfg80211_send_assoc_timeout()) | ||
1477 | * @ie: Extra IEs to add to (Re)Association Request frame or %NULL | 1505 | * @ie: Extra IEs to add to (Re)Association Request frame or %NULL |
1478 | * @ie_len: Length of ie buffer in octets | 1506 | * @ie_len: Length of ie buffer in octets |
1479 | * @use_mfp: Use management frame protection (IEEE 802.11w) in this association | 1507 | * @use_mfp: Use management frame protection (IEEE 802.11w) in this association |
@@ -2342,6 +2370,7 @@ struct cfg80211_ops { | |||
2342 | * responds to probe-requests in hardware. | 2370 | * responds to probe-requests in hardware. |
2343 | * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. | 2371 | * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. |
2344 | * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. | 2372 | * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. |
2373 | * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. | ||
2345 | */ | 2374 | */ |
2346 | enum wiphy_flags { | 2375 | enum wiphy_flags { |
2347 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 2376 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -2365,6 +2394,7 @@ enum wiphy_flags { | |||
2365 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), | 2394 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), |
2366 | WIPHY_FLAG_OFFCHAN_TX = BIT(20), | 2395 | WIPHY_FLAG_OFFCHAN_TX = BIT(20), |
2367 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), | 2396 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), |
2397 | WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22), | ||
2368 | }; | 2398 | }; |
2369 | 2399 | ||
2370 | /** | 2400 | /** |
@@ -3492,11 +3522,11 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, | |||
3492 | /** | 3522 | /** |
3493 | * cfg80211_assoc_timeout - notification of timed out association | 3523 | * cfg80211_assoc_timeout - notification of timed out association |
3494 | * @dev: network device | 3524 | * @dev: network device |
3495 | * @addr: The MAC address of the device with which the association timed out | 3525 | * @bss: The BSS entry with which association timed out. |
3496 | * | 3526 | * |
3497 | * This function may sleep. The caller must hold the corresponding wdev's mutex. | 3527 | * This function may sleep. The caller must hold the corresponding wdev's mutex. |
3498 | */ | 3528 | */ |
3499 | void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr); | 3529 | void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss); |
3500 | 3530 | ||
3501 | /** | 3531 | /** |
3502 | * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame | 3532 | * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a405a7a9775c..5b7a3dadadde 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -305,6 +305,7 @@ enum ieee80211_rssi_event { | |||
305 | * @basic_rates: bitmap of basic rates, each bit stands for an | 305 | * @basic_rates: bitmap of basic rates, each bit stands for an |
306 | * index into the rate table configured by the driver in | 306 | * index into the rate table configured by the driver in |
307 | * the current band. | 307 | * the current band. |
308 | * @beacon_rate: associated AP's beacon TX rate | ||
308 | * @mcast_rate: per-band multicast rate index + 1 (0: disabled) | 309 | * @mcast_rate: per-band multicast rate index + 1 (0: disabled) |
309 | * @bssid: The BSSID for this BSS | 310 | * @bssid: The BSSID for this BSS |
310 | * @enable_beacon: whether beaconing should be enabled or not | 311 | * @enable_beacon: whether beaconing should be enabled or not |
@@ -352,6 +353,7 @@ struct ieee80211_bss_conf { | |||
352 | u32 sync_device_ts; | 353 | u32 sync_device_ts; |
353 | u8 sync_dtim_count; | 354 | u8 sync_dtim_count; |
354 | u32 basic_rates; | 355 | u32 basic_rates; |
356 | struct ieee80211_rate *beacon_rate; | ||
355 | int mcast_rate[IEEE80211_NUM_BANDS]; | 357 | int mcast_rate[IEEE80211_NUM_BANDS]; |
356 | u16 ht_operation_mode; | 358 | u16 ht_operation_mode; |
357 | s32 cqm_rssi_thold; | 359 | s32 cqm_rssi_thold; |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ca6facf4df0c..861e5eba3953 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -2758,6 +2758,8 @@ enum nl80211_channel_type { | |||
2758 | * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well | 2758 | * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well |
2759 | * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 | 2759 | * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 |
2760 | * attribute must be provided as well | 2760 | * attribute must be provided as well |
2761 | * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel | ||
2762 | * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel | ||
2761 | */ | 2763 | */ |
2762 | enum nl80211_chan_width { | 2764 | enum nl80211_chan_width { |
2763 | NL80211_CHAN_WIDTH_20_NOHT, | 2765 | NL80211_CHAN_WIDTH_20_NOHT, |
@@ -2766,6 +2768,8 @@ enum nl80211_chan_width { | |||
2766 | NL80211_CHAN_WIDTH_80, | 2768 | NL80211_CHAN_WIDTH_80, |
2767 | NL80211_CHAN_WIDTH_80P80, | 2769 | NL80211_CHAN_WIDTH_80P80, |
2768 | NL80211_CHAN_WIDTH_160, | 2770 | NL80211_CHAN_WIDTH_160, |
2771 | NL80211_CHAN_WIDTH_5, | ||
2772 | NL80211_CHAN_WIDTH_10, | ||
2769 | }; | 2773 | }; |
2770 | 2774 | ||
2771 | /** | 2775 | /** |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ace5e55fe5a3..061523eb52a1 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -597,7 +597,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
597 | struct hci_dev *hdev = req->hdev; | 597 | struct hci_dev *hdev = req->hdev; |
598 | u8 p; | 598 | u8 p; |
599 | 599 | ||
600 | /* Only send HCI_Delete_Stored_Link_Key if it is supported */ | 600 | /* Some Broadcom based Bluetooth controllers do not support the |
601 | * Delete Stored Link Key command. They are clearly indicating its | ||
602 | * absence in the bit mask of supported commands. | ||
603 | * | ||
604 | * Check the supported commands and only if the the command is marked | ||
605 | * as supported send it. If not supported assume that the controller | ||
606 | * does not have actual support for stored link keys which makes this | ||
607 | * command redundant anyway. | ||
608 | */ | ||
601 | if (hdev->commands[6] & 0x80) { | 609 | if (hdev->commands[6] & 0x80) { |
602 | struct hci_cp_delete_stored_link_key cp; | 610 | struct hci_cp_delete_stored_link_key cp; |
603 | 611 | ||
@@ -751,7 +759,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state) | |||
751 | hdev->discovery.state = state; | 759 | hdev->discovery.state = state; |
752 | } | 760 | } |
753 | 761 | ||
754 | static void inquiry_cache_flush(struct hci_dev *hdev) | 762 | void hci_inquiry_cache_flush(struct hci_dev *hdev) |
755 | { | 763 | { |
756 | struct discovery_state *cache = &hdev->discovery; | 764 | struct discovery_state *cache = &hdev->discovery; |
757 | struct inquiry_entry *p, *n; | 765 | struct inquiry_entry *p, *n; |
@@ -964,7 +972,7 @@ int hci_inquiry(void __user *arg) | |||
964 | hci_dev_lock(hdev); | 972 | hci_dev_lock(hdev); |
965 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || | 973 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || |
966 | inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { | 974 | inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { |
967 | inquiry_cache_flush(hdev); | 975 | hci_inquiry_cache_flush(hdev); |
968 | do_inquiry = 1; | 976 | do_inquiry = 1; |
969 | } | 977 | } |
970 | hci_dev_unlock(hdev); | 978 | hci_dev_unlock(hdev); |
@@ -1201,8 +1209,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1201 | { | 1209 | { |
1202 | BT_DBG("%s %p", hdev->name, hdev); | 1210 | BT_DBG("%s %p", hdev->name, hdev); |
1203 | 1211 | ||
1204 | cancel_work_sync(&hdev->le_scan); | ||
1205 | |||
1206 | cancel_delayed_work(&hdev->power_off); | 1212 | cancel_delayed_work(&hdev->power_off); |
1207 | 1213 | ||
1208 | hci_req_cancel(hdev, ENODEV); | 1214 | hci_req_cancel(hdev, ENODEV); |
@@ -1230,7 +1236,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1230 | cancel_delayed_work_sync(&hdev->le_scan_disable); | 1236 | cancel_delayed_work_sync(&hdev->le_scan_disable); |
1231 | 1237 | ||
1232 | hci_dev_lock(hdev); | 1238 | hci_dev_lock(hdev); |
1233 | inquiry_cache_flush(hdev); | 1239 | hci_inquiry_cache_flush(hdev); |
1234 | hci_conn_hash_flush(hdev); | 1240 | hci_conn_hash_flush(hdev); |
1235 | hci_dev_unlock(hdev); | 1241 | hci_dev_unlock(hdev); |
1236 | 1242 | ||
@@ -1331,7 +1337,7 @@ int hci_dev_reset(__u16 dev) | |||
1331 | skb_queue_purge(&hdev->cmd_q); | 1337 | skb_queue_purge(&hdev->cmd_q); |
1332 | 1338 | ||
1333 | hci_dev_lock(hdev); | 1339 | hci_dev_lock(hdev); |
1334 | inquiry_cache_flush(hdev); | 1340 | hci_inquiry_cache_flush(hdev); |
1335 | hci_conn_hash_flush(hdev); | 1341 | hci_conn_hash_flush(hdev); |
1336 | hci_dev_unlock(hdev); | 1342 | hci_dev_unlock(hdev); |
1337 | 1343 | ||
@@ -1991,80 +1997,59 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
1991 | return mgmt_device_unblocked(hdev, bdaddr, type); | 1997 | return mgmt_device_unblocked(hdev, bdaddr, type); |
1992 | } | 1998 | } |
1993 | 1999 | ||
1994 | static void le_scan_param_req(struct hci_request *req, unsigned long opt) | 2000 | static void inquiry_complete(struct hci_dev *hdev, u8 status) |
1995 | { | 2001 | { |
1996 | struct le_scan_params *param = (struct le_scan_params *) opt; | 2002 | if (status) { |
1997 | struct hci_cp_le_set_scan_param cp; | 2003 | BT_ERR("Failed to start inquiry: status %d", status); |
1998 | |||
1999 | memset(&cp, 0, sizeof(cp)); | ||
2000 | cp.type = param->type; | ||
2001 | cp.interval = cpu_to_le16(param->interval); | ||
2002 | cp.window = cpu_to_le16(param->window); | ||
2003 | 2004 | ||
2004 | hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); | 2005 | hci_dev_lock(hdev); |
2005 | } | 2006 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
2006 | 2007 | hci_dev_unlock(hdev); | |
2007 | static void le_scan_enable_req(struct hci_request *req, unsigned long opt) | 2008 | return; |
2008 | { | 2009 | } |
2009 | struct hci_cp_le_set_scan_enable cp; | ||
2010 | |||
2011 | memset(&cp, 0, sizeof(cp)); | ||
2012 | cp.enable = LE_SCAN_ENABLE; | ||
2013 | cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
2014 | |||
2015 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2016 | } | 2010 | } |
2017 | 2011 | ||
2018 | static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, | 2012 | static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) |
2019 | u16 window, int timeout) | ||
2020 | { | 2013 | { |
2021 | long timeo = msecs_to_jiffies(3000); | 2014 | /* General inquiry access code (GIAC) */ |
2022 | struct le_scan_params param; | 2015 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; |
2016 | struct hci_request req; | ||
2017 | struct hci_cp_inquiry cp; | ||
2023 | int err; | 2018 | int err; |
2024 | 2019 | ||
2025 | BT_DBG("%s", hdev->name); | 2020 | if (status) { |
2026 | 2021 | BT_ERR("Failed to disable LE scanning: status %d", status); | |
2027 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | 2022 | return; |
2028 | return -EINPROGRESS; | 2023 | } |
2029 | |||
2030 | param.type = type; | ||
2031 | param.interval = interval; | ||
2032 | param.window = window; | ||
2033 | |||
2034 | hci_req_lock(hdev); | ||
2035 | |||
2036 | err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) ¶m, | ||
2037 | timeo); | ||
2038 | if (!err) | ||
2039 | err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo); | ||
2040 | |||
2041 | hci_req_unlock(hdev); | ||
2042 | 2024 | ||
2043 | if (err < 0) | 2025 | switch (hdev->discovery.type) { |
2044 | return err; | 2026 | case DISCOV_TYPE_LE: |
2027 | hci_dev_lock(hdev); | ||
2028 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2029 | hci_dev_unlock(hdev); | ||
2030 | break; | ||
2045 | 2031 | ||
2046 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | 2032 | case DISCOV_TYPE_INTERLEAVED: |
2047 | timeout); | 2033 | hci_req_init(&req, hdev); |
2048 | 2034 | ||
2049 | return 0; | 2035 | memset(&cp, 0, sizeof(cp)); |
2050 | } | 2036 | memcpy(&cp.lap, lap, sizeof(cp.lap)); |
2037 | cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; | ||
2038 | hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
2051 | 2039 | ||
2052 | int hci_cancel_le_scan(struct hci_dev *hdev) | 2040 | hci_dev_lock(hdev); |
2053 | { | ||
2054 | BT_DBG("%s", hdev->name); | ||
2055 | 2041 | ||
2056 | if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | 2042 | hci_inquiry_cache_flush(hdev); |
2057 | return -EALREADY; | ||
2058 | 2043 | ||
2059 | if (cancel_delayed_work(&hdev->le_scan_disable)) { | 2044 | err = hci_req_run(&req, inquiry_complete); |
2060 | struct hci_cp_le_set_scan_enable cp; | 2045 | if (err) { |
2046 | BT_ERR("Inquiry request failed: err %d", err); | ||
2047 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2048 | } | ||
2061 | 2049 | ||
2062 | /* Send HCI command to disable LE Scan */ | 2050 | hci_dev_unlock(hdev); |
2063 | memset(&cp, 0, sizeof(cp)); | 2051 | break; |
2064 | hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2065 | } | 2052 | } |
2066 | |||
2067 | return 0; | ||
2068 | } | 2053 | } |
2069 | 2054 | ||
2070 | static void le_scan_disable_work(struct work_struct *work) | 2055 | static void le_scan_disable_work(struct work_struct *work) |
@@ -2072,46 +2057,20 @@ static void le_scan_disable_work(struct work_struct *work) | |||
2072 | struct hci_dev *hdev = container_of(work, struct hci_dev, | 2057 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
2073 | le_scan_disable.work); | 2058 | le_scan_disable.work); |
2074 | struct hci_cp_le_set_scan_enable cp; | 2059 | struct hci_cp_le_set_scan_enable cp; |
2060 | struct hci_request req; | ||
2061 | int err; | ||
2075 | 2062 | ||
2076 | BT_DBG("%s", hdev->name); | 2063 | BT_DBG("%s", hdev->name); |
2077 | 2064 | ||
2078 | memset(&cp, 0, sizeof(cp)); | 2065 | hci_req_init(&req, hdev); |
2079 | |||
2080 | hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2081 | } | ||
2082 | |||
2083 | static void le_scan_work(struct work_struct *work) | ||
2084 | { | ||
2085 | struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); | ||
2086 | struct le_scan_params *param = &hdev->le_scan_params; | ||
2087 | 2066 | ||
2088 | BT_DBG("%s", hdev->name); | 2067 | memset(&cp, 0, sizeof(cp)); |
2068 | cp.enable = LE_SCAN_DISABLE; | ||
2069 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2089 | 2070 | ||
2090 | hci_do_le_scan(hdev, param->type, param->interval, param->window, | 2071 | err = hci_req_run(&req, le_scan_disable_work_complete); |
2091 | param->timeout); | 2072 | if (err) |
2092 | } | 2073 | BT_ERR("Disable LE scanning request failed: err %d", err); |
2093 | |||
2094 | int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, | ||
2095 | int timeout) | ||
2096 | { | ||
2097 | struct le_scan_params *param = &hdev->le_scan_params; | ||
2098 | |||
2099 | BT_DBG("%s", hdev->name); | ||
2100 | |||
2101 | if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) | ||
2102 | return -ENOTSUPP; | ||
2103 | |||
2104 | if (work_busy(&hdev->le_scan)) | ||
2105 | return -EINPROGRESS; | ||
2106 | |||
2107 | param->type = type; | ||
2108 | param->interval = interval; | ||
2109 | param->window = window; | ||
2110 | param->timeout = timeout; | ||
2111 | |||
2112 | queue_work(system_long_wq, &hdev->le_scan); | ||
2113 | |||
2114 | return 0; | ||
2115 | } | 2074 | } |
2116 | 2075 | ||
2117 | /* Alloc HCI device */ | 2076 | /* Alloc HCI device */ |
@@ -2148,7 +2107,6 @@ struct hci_dev *hci_alloc_dev(void) | |||
2148 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); | 2107 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); |
2149 | INIT_WORK(&hdev->tx_work, hci_tx_work); | 2108 | INIT_WORK(&hdev->tx_work, hci_tx_work); |
2150 | INIT_WORK(&hdev->power_on, hci_power_on); | 2109 | INIT_WORK(&hdev->power_on, hci_power_on); |
2151 | INIT_WORK(&hdev->le_scan, le_scan_work); | ||
2152 | 2110 | ||
2153 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); | 2111 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); |
2154 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | 2112 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); |
@@ -3551,36 +3509,6 @@ static void hci_cmd_work(struct work_struct *work) | |||
3551 | } | 3509 | } |
3552 | } | 3510 | } |
3553 | 3511 | ||
3554 | int hci_do_inquiry(struct hci_dev *hdev, u8 length) | ||
3555 | { | ||
3556 | /* General inquiry access code (GIAC) */ | ||
3557 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
3558 | struct hci_cp_inquiry cp; | ||
3559 | |||
3560 | BT_DBG("%s", hdev->name); | ||
3561 | |||
3562 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | ||
3563 | return -EINPROGRESS; | ||
3564 | |||
3565 | inquiry_cache_flush(hdev); | ||
3566 | |||
3567 | memset(&cp, 0, sizeof(cp)); | ||
3568 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
3569 | cp.length = length; | ||
3570 | |||
3571 | return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
3572 | } | ||
3573 | |||
3574 | int hci_cancel_inquiry(struct hci_dev *hdev) | ||
3575 | { | ||
3576 | BT_DBG("%s", hdev->name); | ||
3577 | |||
3578 | if (!test_bit(HCI_INQUIRY, &hdev->flags)) | ||
3579 | return -EALREADY; | ||
3580 | |||
3581 | return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
3582 | } | ||
3583 | |||
3584 | u8 bdaddr_to_le(u8 bdaddr_type) | 3512 | u8 bdaddr_to_le(u8 bdaddr_type) |
3585 | { | 3513 | { |
3586 | switch (bdaddr_type) { | 3514 | switch (bdaddr_type) { |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b93cd2eb5d58..0437200d92f4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -40,21 +40,13 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
40 | 40 | ||
41 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 41 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
42 | 42 | ||
43 | if (status) { | 43 | if (status) |
44 | hci_dev_lock(hdev); | ||
45 | mgmt_stop_discovery_failed(hdev, status); | ||
46 | hci_dev_unlock(hdev); | ||
47 | return; | 44 | return; |
48 | } | ||
49 | 45 | ||
50 | clear_bit(HCI_INQUIRY, &hdev->flags); | 46 | clear_bit(HCI_INQUIRY, &hdev->flags); |
51 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ | 47 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ |
52 | wake_up_bit(&hdev->flags, HCI_INQUIRY); | 48 | wake_up_bit(&hdev->flags, HCI_INQUIRY); |
53 | 49 | ||
54 | hci_dev_lock(hdev); | ||
55 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
56 | hci_dev_unlock(hdev); | ||
57 | |||
58 | hci_conn_check_pending(hdev); | 50 | hci_conn_check_pending(hdev); |
59 | } | 51 | } |
60 | 52 | ||
@@ -937,20 +929,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
937 | hci_dev_unlock(hdev); | 929 | hci_dev_unlock(hdev); |
938 | } | 930 | } |
939 | 931 | ||
940 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | ||
941 | { | ||
942 | __u8 status = *((__u8 *) skb->data); | ||
943 | |||
944 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
945 | |||
946 | if (status) { | ||
947 | hci_dev_lock(hdev); | ||
948 | mgmt_start_discovery_failed(hdev, status); | ||
949 | hci_dev_unlock(hdev); | ||
950 | return; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 932 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
955 | struct sk_buff *skb) | 933 | struct sk_buff *skb) |
956 | { | 934 | { |
@@ -963,41 +941,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
963 | if (!cp) | 941 | if (!cp) |
964 | return; | 942 | return; |
965 | 943 | ||
944 | if (status) | ||
945 | return; | ||
946 | |||
966 | switch (cp->enable) { | 947 | switch (cp->enable) { |
967 | case LE_SCAN_ENABLE: | 948 | case LE_SCAN_ENABLE: |
968 | if (status) { | ||
969 | hci_dev_lock(hdev); | ||
970 | mgmt_start_discovery_failed(hdev, status); | ||
971 | hci_dev_unlock(hdev); | ||
972 | return; | ||
973 | } | ||
974 | |||
975 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); | 949 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); |
976 | |||
977 | hci_dev_lock(hdev); | ||
978 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
979 | hci_dev_unlock(hdev); | ||
980 | break; | 950 | break; |
981 | 951 | ||
982 | case LE_SCAN_DISABLE: | 952 | case LE_SCAN_DISABLE: |
983 | if (status) { | ||
984 | hci_dev_lock(hdev); | ||
985 | mgmt_stop_discovery_failed(hdev, status); | ||
986 | hci_dev_unlock(hdev); | ||
987 | return; | ||
988 | } | ||
989 | |||
990 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); | 953 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); |
991 | |||
992 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && | ||
993 | hdev->discovery.state == DISCOVERY_FINDING) { | ||
994 | mgmt_interleaved_discovery(hdev); | ||
995 | } else { | ||
996 | hci_dev_lock(hdev); | ||
997 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
998 | hci_dev_unlock(hdev); | ||
999 | } | ||
1000 | |||
1001 | break; | 954 | break; |
1002 | 955 | ||
1003 | default: | 956 | default: |
@@ -1077,18 +1030,10 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
1077 | 1030 | ||
1078 | if (status) { | 1031 | if (status) { |
1079 | hci_conn_check_pending(hdev); | 1032 | hci_conn_check_pending(hdev); |
1080 | hci_dev_lock(hdev); | ||
1081 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
1082 | mgmt_start_discovery_failed(hdev, status); | ||
1083 | hci_dev_unlock(hdev); | ||
1084 | return; | 1033 | return; |
1085 | } | 1034 | } |
1086 | 1035 | ||
1087 | set_bit(HCI_INQUIRY, &hdev->flags); | 1036 | set_bit(HCI_INQUIRY, &hdev->flags); |
1088 | |||
1089 | hci_dev_lock(hdev); | ||
1090 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
1091 | hci_dev_unlock(hdev); | ||
1092 | } | 1037 | } |
1093 | 1038 | ||
1094 | static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 1039 | static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -2298,10 +2243,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2298 | hci_cc_user_passkey_neg_reply(hdev, skb); | 2243 | hci_cc_user_passkey_neg_reply(hdev, skb); |
2299 | break; | 2244 | break; |
2300 | 2245 | ||
2301 | case HCI_OP_LE_SET_SCAN_PARAM: | ||
2302 | hci_cc_le_set_scan_param(hdev, skb); | ||
2303 | break; | ||
2304 | |||
2305 | case HCI_OP_LE_SET_ADV_ENABLE: | 2246 | case HCI_OP_LE_SET_ADV_ENABLE: |
2306 | hci_cc_le_set_adv_enable(hdev, skb); | 2247 | hci_cc_le_set_adv_enable(hdev, skb); |
2307 | break; | 2248 | break; |
@@ -2670,7 +2611,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2670 | 2611 | ||
2671 | BT_DBG("%s", hdev->name); | 2612 | BT_DBG("%s", hdev->name); |
2672 | 2613 | ||
2673 | if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) | 2614 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) |
2674 | return; | 2615 | return; |
2675 | 2616 | ||
2676 | hci_dev_lock(hdev); | 2617 | hci_dev_lock(hdev); |
@@ -2746,7 +2687,7 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2746 | hci_conn_drop(conn); | 2687 | hci_conn_drop(conn); |
2747 | } | 2688 | } |
2748 | 2689 | ||
2749 | if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) | 2690 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
2750 | hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, | 2691 | hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, |
2751 | ev->key_type, pin_len); | 2692 | ev->key_type, pin_len); |
2752 | 2693 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 940f5acb6694..f13a8da441a8 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -76,25 +76,19 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo | |||
76 | ci->flags = session->flags; | 76 | ci->flags = session->flags; |
77 | ci->state = BT_CONNECTED; | 77 | ci->state = BT_CONNECTED; |
78 | 78 | ||
79 | ci->vendor = 0x0000; | ||
80 | ci->product = 0x0000; | ||
81 | ci->version = 0x0000; | ||
82 | |||
83 | if (session->input) { | 79 | if (session->input) { |
84 | ci->vendor = session->input->id.vendor; | 80 | ci->vendor = session->input->id.vendor; |
85 | ci->product = session->input->id.product; | 81 | ci->product = session->input->id.product; |
86 | ci->version = session->input->id.version; | 82 | ci->version = session->input->id.version; |
87 | if (session->input->name) | 83 | if (session->input->name) |
88 | strncpy(ci->name, session->input->name, 128); | 84 | strlcpy(ci->name, session->input->name, 128); |
89 | else | 85 | else |
90 | strncpy(ci->name, "HID Boot Device", 128); | 86 | strlcpy(ci->name, "HID Boot Device", 128); |
91 | } | 87 | } else if (session->hid) { |
92 | |||
93 | if (session->hid) { | ||
94 | ci->vendor = session->hid->vendor; | 88 | ci->vendor = session->hid->vendor; |
95 | ci->product = session->hid->product; | 89 | ci->product = session->hid->product; |
96 | ci->version = session->hid->version; | 90 | ci->version = session->hid->version; |
97 | strncpy(ci->name, session->hid->name, 128); | 91 | strlcpy(ci->name, session->hid->name, 128); |
98 | } | 92 | } |
99 | } | 93 | } |
100 | 94 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4be6a264b475..8c3499bec893 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -504,8 +504,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
504 | if (conn->hcon->type == LE_LINK) { | 504 | if (conn->hcon->type == LE_LINK) { |
505 | /* LE connection */ | 505 | /* LE connection */ |
506 | chan->omtu = L2CAP_DEFAULT_MTU; | 506 | chan->omtu = L2CAP_DEFAULT_MTU; |
507 | chan->scid = L2CAP_CID_LE_DATA; | 507 | if (chan->dcid == L2CAP_CID_ATT) |
508 | chan->dcid = L2CAP_CID_LE_DATA; | 508 | chan->scid = L2CAP_CID_ATT; |
509 | else | ||
510 | chan->scid = l2cap_alloc_cid(conn); | ||
509 | } else { | 511 | } else { |
510 | /* Alloc CID for connection-oriented socket */ | 512 | /* Alloc CID for connection-oriented socket */ |
511 | chan->scid = l2cap_alloc_cid(conn); | 513 | chan->scid = l2cap_alloc_cid(conn); |
@@ -543,6 +545,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
543 | 545 | ||
544 | l2cap_chan_hold(chan); | 546 | l2cap_chan_hold(chan); |
545 | 547 | ||
548 | hci_conn_hold(conn->hcon); | ||
549 | |||
546 | list_add(&chan->list, &conn->chan_l); | 550 | list_add(&chan->list, &conn->chan_l); |
547 | } | 551 | } |
548 | 552 | ||
@@ -1338,17 +1342,21 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, | |||
1338 | 1342 | ||
1339 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 1343 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
1340 | { | 1344 | { |
1341 | struct sock *parent, *sk; | 1345 | struct sock *parent; |
1342 | struct l2cap_chan *chan, *pchan; | 1346 | struct l2cap_chan *chan, *pchan; |
1343 | 1347 | ||
1344 | BT_DBG(""); | 1348 | BT_DBG(""); |
1345 | 1349 | ||
1346 | /* Check if we have socket listening on cid */ | 1350 | /* Check if we have socket listening on cid */ |
1347 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, | 1351 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, |
1348 | conn->src, conn->dst); | 1352 | conn->src, conn->dst); |
1349 | if (!pchan) | 1353 | if (!pchan) |
1350 | return; | 1354 | return; |
1351 | 1355 | ||
1356 | /* Client ATT sockets should override the server one */ | ||
1357 | if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) | ||
1358 | return; | ||
1359 | |||
1352 | parent = pchan->sk; | 1360 | parent = pchan->sk; |
1353 | 1361 | ||
1354 | lock_sock(parent); | 1362 | lock_sock(parent); |
@@ -1357,17 +1365,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1357 | if (!chan) | 1365 | if (!chan) |
1358 | goto clean; | 1366 | goto clean; |
1359 | 1367 | ||
1360 | sk = chan->sk; | 1368 | chan->dcid = L2CAP_CID_ATT; |
1361 | 1369 | ||
1362 | hci_conn_hold(conn->hcon); | 1370 | bacpy(&bt_sk(chan->sk)->src, conn->src); |
1363 | conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; | 1371 | bacpy(&bt_sk(chan->sk)->dst, conn->dst); |
1364 | 1372 | ||
1365 | bacpy(&bt_sk(sk)->src, conn->src); | 1373 | __l2cap_chan_add(conn, chan); |
1366 | bacpy(&bt_sk(sk)->dst, conn->dst); | ||
1367 | |||
1368 | l2cap_chan_add(conn, chan); | ||
1369 | |||
1370 | l2cap_chan_ready(chan); | ||
1371 | 1374 | ||
1372 | clean: | 1375 | clean: |
1373 | release_sock(parent); | 1376 | release_sock(parent); |
@@ -1380,14 +1383,17 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1380 | 1383 | ||
1381 | BT_DBG("conn %p", conn); | 1384 | BT_DBG("conn %p", conn); |
1382 | 1385 | ||
1383 | if (!hcon->out && hcon->type == LE_LINK) | 1386 | /* For outgoing pairing which doesn't necessarily have an |
1384 | l2cap_le_conn_ready(conn); | 1387 | * associated socket (e.g. mgmt_pair_device). |
1385 | 1388 | */ | |
1386 | if (hcon->out && hcon->type == LE_LINK) | 1389 | if (hcon->out && hcon->type == LE_LINK) |
1387 | smp_conn_security(hcon, hcon->pending_sec_level); | 1390 | smp_conn_security(hcon, hcon->pending_sec_level); |
1388 | 1391 | ||
1389 | mutex_lock(&conn->chan_lock); | 1392 | mutex_lock(&conn->chan_lock); |
1390 | 1393 | ||
1394 | if (hcon->type == LE_LINK) | ||
1395 | l2cap_le_conn_ready(conn); | ||
1396 | |||
1391 | list_for_each_entry(chan, &conn->chan_l, list) { | 1397 | list_for_each_entry(chan, &conn->chan_l, list) { |
1392 | 1398 | ||
1393 | l2cap_chan_lock(chan); | 1399 | l2cap_chan_lock(chan); |
@@ -1792,7 +1798,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1792 | 1798 | ||
1793 | auth_type = l2cap_get_auth_type(chan); | 1799 | auth_type = l2cap_get_auth_type(chan); |
1794 | 1800 | ||
1795 | if (chan->dcid == L2CAP_CID_LE_DATA) | 1801 | if (bdaddr_type_is_le(dst_type)) |
1796 | hcon = hci_connect(hdev, LE_LINK, dst, dst_type, | 1802 | hcon = hci_connect(hdev, LE_LINK, dst, dst_type, |
1797 | chan->sec_level, auth_type); | 1803 | chan->sec_level, auth_type); |
1798 | else | 1804 | else |
@@ -1811,16 +1817,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1811 | goto done; | 1817 | goto done; |
1812 | } | 1818 | } |
1813 | 1819 | ||
1814 | if (hcon->type == LE_LINK) { | 1820 | if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { |
1815 | err = 0; | 1821 | hci_conn_drop(hcon); |
1816 | 1822 | err = -EBUSY; | |
1817 | if (!list_empty(&conn->chan_l)) { | 1823 | goto done; |
1818 | err = -EBUSY; | ||
1819 | hci_conn_drop(hcon); | ||
1820 | } | ||
1821 | |||
1822 | if (err) | ||
1823 | goto done; | ||
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | /* Update source addr of the socket */ | 1826 | /* Update source addr of the socket */ |
@@ -1830,6 +1830,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1830 | l2cap_chan_add(conn, chan); | 1830 | l2cap_chan_add(conn, chan); |
1831 | l2cap_chan_lock(chan); | 1831 | l2cap_chan_lock(chan); |
1832 | 1832 | ||
1833 | /* l2cap_chan_add takes its own ref so we can drop this one */ | ||
1834 | hci_conn_drop(hcon); | ||
1835 | |||
1833 | l2cap_state_change(chan, BT_CONNECT); | 1836 | l2cap_state_change(chan, BT_CONNECT); |
1834 | __set_chan_timer(chan, sk->sk_sndtimeo); | 1837 | __set_chan_timer(chan, sk->sk_sndtimeo); |
1835 | 1838 | ||
@@ -3751,8 +3754,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3751 | 3754 | ||
3752 | sk = chan->sk; | 3755 | sk = chan->sk; |
3753 | 3756 | ||
3754 | hci_conn_hold(conn->hcon); | ||
3755 | |||
3756 | bacpy(&bt_sk(sk)->src, conn->src); | 3757 | bacpy(&bt_sk(sk)->src, conn->src); |
3757 | bacpy(&bt_sk(sk)->dst, conn->dst); | 3758 | bacpy(&bt_sk(sk)->dst, conn->dst); |
3758 | chan->psm = psm; | 3759 | chan->psm = psm; |
@@ -4333,7 +4334,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, | |||
4333 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 4334 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
4334 | u16 type, result; | 4335 | u16 type, result; |
4335 | 4336 | ||
4336 | if (cmd_len != sizeof(*rsp)) | 4337 | if (cmd_len < sizeof(*rsp)) |
4337 | return -EPROTO; | 4338 | return -EPROTO; |
4338 | 4339 | ||
4339 | type = __le16_to_cpu(rsp->type); | 4340 | type = __le16_to_cpu(rsp->type); |
@@ -5292,6 +5293,51 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | |||
5292 | } | 5293 | } |
5293 | } | 5294 | } |
5294 | 5295 | ||
5296 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, | ||
5297 | struct sk_buff *skb) | ||
5298 | { | ||
5299 | u8 *data = skb->data; | ||
5300 | int len = skb->len; | ||
5301 | struct l2cap_cmd_hdr cmd; | ||
5302 | int err; | ||
5303 | |||
5304 | l2cap_raw_recv(conn, skb); | ||
5305 | |||
5306 | while (len >= L2CAP_CMD_HDR_SIZE) { | ||
5307 | u16 cmd_len; | ||
5308 | memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); | ||
5309 | data += L2CAP_CMD_HDR_SIZE; | ||
5310 | len -= L2CAP_CMD_HDR_SIZE; | ||
5311 | |||
5312 | cmd_len = le16_to_cpu(cmd.len); | ||
5313 | |||
5314 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, | ||
5315 | cmd.ident); | ||
5316 | |||
5317 | if (cmd_len > len || !cmd.ident) { | ||
5318 | BT_DBG("corrupted command"); | ||
5319 | break; | ||
5320 | } | ||
5321 | |||
5322 | err = l2cap_le_sig_cmd(conn, &cmd, data); | ||
5323 | if (err) { | ||
5324 | struct l2cap_cmd_rej_unk rej; | ||
5325 | |||
5326 | BT_ERR("Wrong link type (%d)", err); | ||
5327 | |||
5328 | /* FIXME: Map err to a valid reason */ | ||
5329 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5330 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, | ||
5331 | sizeof(rej), &rej); | ||
5332 | } | ||
5333 | |||
5334 | data += cmd_len; | ||
5335 | len -= cmd_len; | ||
5336 | } | ||
5337 | |||
5338 | kfree_skb(skb); | ||
5339 | } | ||
5340 | |||
5295 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, | 5341 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, |
5296 | struct sk_buff *skb) | 5342 | struct sk_buff *skb) |
5297 | { | 5343 | { |
@@ -5318,11 +5364,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5318 | break; | 5364 | break; |
5319 | } | 5365 | } |
5320 | 5366 | ||
5321 | if (conn->hcon->type == LE_LINK) | 5367 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
5322 | err = l2cap_le_sig_cmd(conn, &cmd, data); | ||
5323 | else | ||
5324 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); | ||
5325 | |||
5326 | if (err) { | 5368 | if (err) { |
5327 | struct l2cap_cmd_rej_unk rej; | 5369 | struct l2cap_cmd_rej_unk rej; |
5328 | 5370 | ||
@@ -6356,16 +6398,13 @@ static void l2cap_att_channel(struct l2cap_conn *conn, | |||
6356 | { | 6398 | { |
6357 | struct l2cap_chan *chan; | 6399 | struct l2cap_chan *chan; |
6358 | 6400 | ||
6359 | chan = l2cap_global_chan_by_scid(0, L2CAP_CID_LE_DATA, | 6401 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, |
6360 | conn->src, conn->dst); | 6402 | conn->src, conn->dst); |
6361 | if (!chan) | 6403 | if (!chan) |
6362 | goto drop; | 6404 | goto drop; |
6363 | 6405 | ||
6364 | BT_DBG("chan %p, len %d", chan, skb->len); | 6406 | BT_DBG("chan %p, len %d", chan, skb->len); |
6365 | 6407 | ||
6366 | if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) | ||
6367 | goto drop; | ||
6368 | |||
6369 | if (chan->imtu < skb->len) | 6408 | if (chan->imtu < skb->len) |
6370 | goto drop; | 6409 | goto drop; |
6371 | 6410 | ||
@@ -6395,6 +6434,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6395 | 6434 | ||
6396 | switch (cid) { | 6435 | switch (cid) { |
6397 | case L2CAP_CID_LE_SIGNALING: | 6436 | case L2CAP_CID_LE_SIGNALING: |
6437 | l2cap_le_sig_channel(conn, skb); | ||
6438 | break; | ||
6398 | case L2CAP_CID_SIGNALING: | 6439 | case L2CAP_CID_SIGNALING: |
6399 | l2cap_sig_channel(conn, skb); | 6440 | l2cap_sig_channel(conn, skb); |
6400 | break; | 6441 | break; |
@@ -6405,7 +6446,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6405 | l2cap_conless_channel(conn, psm, skb); | 6446 | l2cap_conless_channel(conn, psm, skb); |
6406 | break; | 6447 | break; |
6407 | 6448 | ||
6408 | case L2CAP_CID_LE_DATA: | 6449 | case L2CAP_CID_ATT: |
6409 | l2cap_att_channel(conn, skb); | 6450 | l2cap_att_channel(conn, skb); |
6410 | break; | 6451 | break; |
6411 | 6452 | ||
@@ -6531,7 +6572,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
6531 | continue; | 6572 | continue; |
6532 | } | 6573 | } |
6533 | 6574 | ||
6534 | if (chan->scid == L2CAP_CID_LE_DATA) { | 6575 | if (chan->scid == L2CAP_CID_ATT) { |
6535 | if (!status && encrypt) { | 6576 | if (!status && encrypt) { |
6536 | chan->sec_level = hcon->sec_level; | 6577 | chan->sec_level = hcon->sec_level; |
6537 | l2cap_chan_ready(chan); | 6578 | l2cap_chan_ready(chan); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 36fed40c162c..0098af80b213 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -466,7 +466,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, | |||
466 | static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) | 466 | static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) |
467 | { | 467 | { |
468 | switch (chan->scid) { | 468 | switch (chan->scid) { |
469 | case L2CAP_CID_LE_DATA: | 469 | case L2CAP_CID_ATT: |
470 | if (mtu < L2CAP_LE_MIN_MTU) | 470 | if (mtu < L2CAP_LE_MIN_MTU) |
471 | return false; | 471 | return false; |
472 | break; | 472 | break; |
@@ -630,7 +630,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |||
630 | conn = chan->conn; | 630 | conn = chan->conn; |
631 | 631 | ||
632 | /*change security for LE channels */ | 632 | /*change security for LE channels */ |
633 | if (chan->scid == L2CAP_CID_LE_DATA) { | 633 | if (chan->scid == L2CAP_CID_ATT) { |
634 | if (!conn->hcon->out) { | 634 | if (!conn->hcon->out) { |
635 | err = -EINVAL; | 635 | err = -EINVAL; |
636 | break; | 636 | break; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f8ecbc70293d..fedc5399d465 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -102,18 +102,6 @@ static const u16 mgmt_events[] = { | |||
102 | MGMT_EV_PASSKEY_NOTIFY, | 102 | MGMT_EV_PASSKEY_NOTIFY, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* | ||
106 | * These LE scan and inquiry parameters were chosen according to LE General | ||
107 | * Discovery Procedure specification. | ||
108 | */ | ||
109 | #define LE_SCAN_WIN 0x12 | ||
110 | #define LE_SCAN_INT 0x12 | ||
111 | #define LE_SCAN_TIMEOUT_LE_ONLY msecs_to_jiffies(10240) | ||
112 | #define LE_SCAN_TIMEOUT_BREDR_LE msecs_to_jiffies(5120) | ||
113 | |||
114 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | ||
115 | #define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */ | ||
116 | |||
117 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) | 105 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) |
118 | 106 | ||
119 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ | 107 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ |
@@ -1748,8 +1736,6 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1748 | 1736 | ||
1749 | hci_link_keys_clear(hdev); | 1737 | hci_link_keys_clear(hdev); |
1750 | 1738 | ||
1751 | set_bit(HCI_LINK_KEYS, &hdev->dev_flags); | ||
1752 | |||
1753 | if (cp->debug_keys) | 1739 | if (cp->debug_keys) |
1754 | set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | 1740 | set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); |
1755 | else | 1741 | else |
@@ -2633,28 +2619,72 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
2633 | return err; | 2619 | return err; |
2634 | } | 2620 | } |
2635 | 2621 | ||
2636 | int mgmt_interleaved_discovery(struct hci_dev *hdev) | 2622 | static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) |
2637 | { | 2623 | { |
2624 | struct pending_cmd *cmd; | ||
2625 | u8 type; | ||
2638 | int err; | 2626 | int err; |
2639 | 2627 | ||
2640 | BT_DBG("%s", hdev->name); | 2628 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
2641 | 2629 | ||
2642 | hci_dev_lock(hdev); | 2630 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); |
2631 | if (!cmd) | ||
2632 | return -ENOENT; | ||
2643 | 2633 | ||
2644 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE); | 2634 | type = hdev->discovery.type; |
2645 | if (err < 0) | ||
2646 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2647 | 2635 | ||
2648 | hci_dev_unlock(hdev); | 2636 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), |
2637 | &type, sizeof(type)); | ||
2638 | mgmt_pending_remove(cmd); | ||
2649 | 2639 | ||
2650 | return err; | 2640 | return err; |
2651 | } | 2641 | } |
2652 | 2642 | ||
2643 | static void start_discovery_complete(struct hci_dev *hdev, u8 status) | ||
2644 | { | ||
2645 | BT_DBG("status %d", status); | ||
2646 | |||
2647 | if (status) { | ||
2648 | hci_dev_lock(hdev); | ||
2649 | mgmt_start_discovery_failed(hdev, status); | ||
2650 | hci_dev_unlock(hdev); | ||
2651 | return; | ||
2652 | } | ||
2653 | |||
2654 | hci_dev_lock(hdev); | ||
2655 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
2656 | hci_dev_unlock(hdev); | ||
2657 | |||
2658 | switch (hdev->discovery.type) { | ||
2659 | case DISCOV_TYPE_LE: | ||
2660 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | ||
2661 | DISCOV_LE_TIMEOUT); | ||
2662 | break; | ||
2663 | |||
2664 | case DISCOV_TYPE_INTERLEAVED: | ||
2665 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | ||
2666 | DISCOV_INTERLEAVED_TIMEOUT); | ||
2667 | break; | ||
2668 | |||
2669 | case DISCOV_TYPE_BREDR: | ||
2670 | break; | ||
2671 | |||
2672 | default: | ||
2673 | BT_ERR("Invalid discovery type %d", hdev->discovery.type); | ||
2674 | } | ||
2675 | } | ||
2676 | |||
2653 | static int start_discovery(struct sock *sk, struct hci_dev *hdev, | 2677 | static int start_discovery(struct sock *sk, struct hci_dev *hdev, |
2654 | void *data, u16 len) | 2678 | void *data, u16 len) |
2655 | { | 2679 | { |
2656 | struct mgmt_cp_start_discovery *cp = data; | 2680 | struct mgmt_cp_start_discovery *cp = data; |
2657 | struct pending_cmd *cmd; | 2681 | struct pending_cmd *cmd; |
2682 | struct hci_cp_le_set_scan_param param_cp; | ||
2683 | struct hci_cp_le_set_scan_enable enable_cp; | ||
2684 | struct hci_cp_inquiry inq_cp; | ||
2685 | struct hci_request req; | ||
2686 | /* General inquiry access code (GIAC) */ | ||
2687 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
2658 | int err; | 2688 | int err; |
2659 | 2689 | ||
2660 | BT_DBG("%s", hdev->name); | 2690 | BT_DBG("%s", hdev->name); |
@@ -2687,6 +2717,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2687 | 2717 | ||
2688 | hdev->discovery.type = cp->type; | 2718 | hdev->discovery.type = cp->type; |
2689 | 2719 | ||
2720 | hci_req_init(&req, hdev); | ||
2721 | |||
2690 | switch (hdev->discovery.type) { | 2722 | switch (hdev->discovery.type) { |
2691 | case DISCOV_TYPE_BREDR: | 2723 | case DISCOV_TYPE_BREDR: |
2692 | if (!lmp_bredr_capable(hdev)) { | 2724 | if (!lmp_bredr_capable(hdev)) { |
@@ -2696,10 +2728,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2696 | goto failed; | 2728 | goto failed; |
2697 | } | 2729 | } |
2698 | 2730 | ||
2699 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); | 2731 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { |
2732 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | ||
2733 | MGMT_STATUS_BUSY); | ||
2734 | mgmt_pending_remove(cmd); | ||
2735 | goto failed; | ||
2736 | } | ||
2737 | |||
2738 | hci_inquiry_cache_flush(hdev); | ||
2739 | |||
2740 | memset(&inq_cp, 0, sizeof(inq_cp)); | ||
2741 | memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); | ||
2742 | inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; | ||
2743 | hci_req_add(&req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp); | ||
2700 | break; | 2744 | break; |
2701 | 2745 | ||
2702 | case DISCOV_TYPE_LE: | 2746 | case DISCOV_TYPE_LE: |
2747 | case DISCOV_TYPE_INTERLEAVED: | ||
2703 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | 2748 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2749 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2705 | MGMT_STATUS_NOT_SUPPORTED); | 2750 | MGMT_STATUS_NOT_SUPPORTED); |
@@ -2707,20 +2752,40 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2707 | goto failed; | 2752 | goto failed; |
2708 | } | 2753 | } |
2709 | 2754 | ||
2710 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, | 2755 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && |
2711 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); | 2756 | !lmp_bredr_capable(hdev)) { |
2712 | break; | ||
2713 | |||
2714 | case DISCOV_TYPE_INTERLEAVED: | ||
2715 | if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) { | ||
2716 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2757 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2717 | MGMT_STATUS_NOT_SUPPORTED); | 2758 | MGMT_STATUS_NOT_SUPPORTED); |
2718 | mgmt_pending_remove(cmd); | 2759 | mgmt_pending_remove(cmd); |
2719 | goto failed; | 2760 | goto failed; |
2720 | } | 2761 | } |
2721 | 2762 | ||
2722 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, | 2763 | if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) { |
2723 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_BREDR_LE); | 2764 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2765 | MGMT_STATUS_REJECTED); | ||
2766 | mgmt_pending_remove(cmd); | ||
2767 | goto failed; | ||
2768 | } | ||
2769 | |||
2770 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { | ||
2771 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | ||
2772 | MGMT_STATUS_BUSY); | ||
2773 | mgmt_pending_remove(cmd); | ||
2774 | goto failed; | ||
2775 | } | ||
2776 | |||
2777 | memset(¶m_cp, 0, sizeof(param_cp)); | ||
2778 | param_cp.type = LE_SCAN_ACTIVE; | ||
2779 | param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); | ||
2780 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); | ||
2781 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), | ||
2782 | ¶m_cp); | ||
2783 | |||
2784 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
2785 | enable_cp.enable = LE_SCAN_ENABLE; | ||
2786 | enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
2787 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), | ||
2788 | &enable_cp); | ||
2724 | break; | 2789 | break; |
2725 | 2790 | ||
2726 | default: | 2791 | default: |
@@ -2730,6 +2795,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2730 | goto failed; | 2795 | goto failed; |
2731 | } | 2796 | } |
2732 | 2797 | ||
2798 | err = hci_req_run(&req, start_discovery_complete); | ||
2733 | if (err < 0) | 2799 | if (err < 0) |
2734 | mgmt_pending_remove(cmd); | 2800 | mgmt_pending_remove(cmd); |
2735 | else | 2801 | else |
@@ -2740,6 +2806,39 @@ failed: | |||
2740 | return err; | 2806 | return err; |
2741 | } | 2807 | } |
2742 | 2808 | ||
2809 | static int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status) | ||
2810 | { | ||
2811 | struct pending_cmd *cmd; | ||
2812 | int err; | ||
2813 | |||
2814 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
2815 | if (!cmd) | ||
2816 | return -ENOENT; | ||
2817 | |||
2818 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
2819 | &hdev->discovery.type, sizeof(hdev->discovery.type)); | ||
2820 | mgmt_pending_remove(cmd); | ||
2821 | |||
2822 | return err; | ||
2823 | } | ||
2824 | |||
2825 | static void stop_discovery_complete(struct hci_dev *hdev, u8 status) | ||
2826 | { | ||
2827 | BT_DBG("status %d", status); | ||
2828 | |||
2829 | hci_dev_lock(hdev); | ||
2830 | |||
2831 | if (status) { | ||
2832 | mgmt_stop_discovery_failed(hdev, status); | ||
2833 | goto unlock; | ||
2834 | } | ||
2835 | |||
2836 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2837 | |||
2838 | unlock: | ||
2839 | hci_dev_unlock(hdev); | ||
2840 | } | ||
2841 | |||
2743 | static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | 2842 | static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, |
2744 | u16 len) | 2843 | u16 len) |
2745 | { | 2844 | { |
@@ -2747,6 +2846,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2747 | struct pending_cmd *cmd; | 2846 | struct pending_cmd *cmd; |
2748 | struct hci_cp_remote_name_req_cancel cp; | 2847 | struct hci_cp_remote_name_req_cancel cp; |
2749 | struct inquiry_entry *e; | 2848 | struct inquiry_entry *e; |
2849 | struct hci_request req; | ||
2850 | struct hci_cp_le_set_scan_enable enable_cp; | ||
2750 | int err; | 2851 | int err; |
2751 | 2852 | ||
2752 | BT_DBG("%s", hdev->name); | 2853 | BT_DBG("%s", hdev->name); |
@@ -2773,12 +2874,20 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2773 | goto unlock; | 2874 | goto unlock; |
2774 | } | 2875 | } |
2775 | 2876 | ||
2877 | hci_req_init(&req, hdev); | ||
2878 | |||
2776 | switch (hdev->discovery.state) { | 2879 | switch (hdev->discovery.state) { |
2777 | case DISCOVERY_FINDING: | 2880 | case DISCOVERY_FINDING: |
2778 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | 2881 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { |
2779 | err = hci_cancel_inquiry(hdev); | 2882 | hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL); |
2780 | else | 2883 | } else { |
2781 | err = hci_cancel_le_scan(hdev); | 2884 | cancel_delayed_work(&hdev->le_scan_disable); |
2885 | |||
2886 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
2887 | enable_cp.enable = LE_SCAN_DISABLE; | ||
2888 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, | ||
2889 | sizeof(enable_cp), &enable_cp); | ||
2890 | } | ||
2782 | 2891 | ||
2783 | break; | 2892 | break; |
2784 | 2893 | ||
@@ -2796,16 +2905,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2796 | } | 2905 | } |
2797 | 2906 | ||
2798 | bacpy(&cp.bdaddr, &e->data.bdaddr); | 2907 | bacpy(&cp.bdaddr, &e->data.bdaddr); |
2799 | err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL, | 2908 | hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), |
2800 | sizeof(cp), &cp); | 2909 | &cp); |
2801 | 2910 | ||
2802 | break; | 2911 | break; |
2803 | 2912 | ||
2804 | default: | 2913 | default: |
2805 | BT_DBG("unknown discovery state %u", hdev->discovery.state); | 2914 | BT_DBG("unknown discovery state %u", hdev->discovery.state); |
2806 | err = -EFAULT; | 2915 | |
2916 | mgmt_pending_remove(cmd); | ||
2917 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, | ||
2918 | MGMT_STATUS_FAILED, &mgmt_cp->type, | ||
2919 | sizeof(mgmt_cp->type)); | ||
2920 | goto unlock; | ||
2807 | } | 2921 | } |
2808 | 2922 | ||
2923 | err = hci_req_run(&req, stop_discovery_complete); | ||
2809 | if (err < 0) | 2924 | if (err < 0) |
2810 | mgmt_pending_remove(cmd); | 2925 | mgmt_pending_remove(cmd); |
2811 | else | 2926 | else |
@@ -4063,6 +4178,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4063 | struct mgmt_ev_device_found *ev = (void *) buf; | 4178 | struct mgmt_ev_device_found *ev = (void *) buf; |
4064 | size_t ev_size; | 4179 | size_t ev_size; |
4065 | 4180 | ||
4181 | if (!hci_discovery_active(hdev)) | ||
4182 | return -EPERM; | ||
4183 | |||
4066 | /* Leave 5 bytes for a potential CoD field */ | 4184 | /* Leave 5 bytes for a potential CoD field */ |
4067 | if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) | 4185 | if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) |
4068 | return -EINVAL; | 4186 | return -EINVAL; |
@@ -4114,43 +4232,6 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4114 | sizeof(*ev) + eir_len, NULL); | 4232 | sizeof(*ev) + eir_len, NULL); |
4115 | } | 4233 | } |
4116 | 4234 | ||
4117 | int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) | ||
4118 | { | ||
4119 | struct pending_cmd *cmd; | ||
4120 | u8 type; | ||
4121 | int err; | ||
4122 | |||
4123 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
4124 | |||
4125 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
4126 | if (!cmd) | ||
4127 | return -ENOENT; | ||
4128 | |||
4129 | type = hdev->discovery.type; | ||
4130 | |||
4131 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
4132 | &type, sizeof(type)); | ||
4133 | mgmt_pending_remove(cmd); | ||
4134 | |||
4135 | return err; | ||
4136 | } | ||
4137 | |||
4138 | int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status) | ||
4139 | { | ||
4140 | struct pending_cmd *cmd; | ||
4141 | int err; | ||
4142 | |||
4143 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
4144 | if (!cmd) | ||
4145 | return -ENOENT; | ||
4146 | |||
4147 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
4148 | &hdev->discovery.type, sizeof(hdev->discovery.type)); | ||
4149 | mgmt_pending_remove(cmd); | ||
4150 | |||
4151 | return err; | ||
4152 | } | ||
4153 | |||
4154 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) | 4235 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) |
4155 | { | 4236 | { |
4156 | struct mgmt_ev_discovering ev; | 4237 | struct mgmt_ev_discovering ev; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 082f270b5912..8184d121ff09 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2827,7 +2827,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2827 | !rcu_access_pointer(sdata->bss->beacon)) | 2827 | !rcu_access_pointer(sdata->bss->beacon)) |
2828 | need_offchan = true; | 2828 | need_offchan = true; |
2829 | if (!ieee80211_is_action(mgmt->frame_control) || | 2829 | if (!ieee80211_is_action(mgmt->frame_control) || |
2830 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | 2830 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC || |
2831 | mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED) | ||
2831 | break; | 2832 | break; |
2832 | rcu_read_lock(); | 2833 | rcu_read_lock(); |
2833 | sta = sta_info_get(sdata, mgmt->da); | 2834 | sta = sta_info_get(sdata, mgmt->da); |
@@ -2930,19 +2931,8 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | |||
2930 | u16 frame_type, bool reg) | 2931 | u16 frame_type, bool reg) |
2931 | { | 2932 | { |
2932 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2933 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2933 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
2934 | 2934 | ||
2935 | switch (frame_type) { | 2935 | switch (frame_type) { |
2936 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: | ||
2937 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
2938 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
2939 | |||
2940 | if (reg) | ||
2941 | ifibss->auth_frame_registrations++; | ||
2942 | else | ||
2943 | ifibss->auth_frame_registrations--; | ||
2944 | } | ||
2945 | break; | ||
2946 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: | 2936 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: |
2947 | if (reg) | 2937 | if (reg) |
2948 | local->probe_req_reg++; | 2938 | local->probe_req_reg++; |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 75dff338f581..f83534f6a2ee 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
281 | sta, tid, WLAN_BACK_RECIPIENT, | 281 | sta, tid, WLAN_BACK_RECIPIENT, |
282 | WLAN_REASON_UNSPECIFIED, true); | 282 | WLAN_REASON_UNSPECIFIED, true); |
283 | 283 | ||
284 | spin_lock_bh(&sta->lock); | ||
285 | |||
284 | tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; | 286 | tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; |
285 | if (tid_tx) { | 287 | if (tid_tx) { |
286 | /* | 288 | /* |
287 | * Assign it over to the normal tid_tx array | 289 | * Assign it over to the normal tid_tx array |
288 | * where it "goes live". | 290 | * where it "goes live". |
289 | */ | 291 | */ |
290 | spin_lock_bh(&sta->lock); | ||
291 | 292 | ||
292 | sta->ampdu_mlme.tid_start_tx[tid] = NULL; | 293 | sta->ampdu_mlme.tid_start_tx[tid] = NULL; |
293 | /* could there be a race? */ | 294 | /* could there be a race? */ |
@@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
300 | ieee80211_tx_ba_session_handle_start(sta, tid); | 301 | ieee80211_tx_ba_session_handle_start(sta, tid); |
301 | continue; | 302 | continue; |
302 | } | 303 | } |
304 | spin_unlock_bh(&sta->lock); | ||
303 | 305 | ||
304 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 306 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
305 | if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, | 307 | if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index caa4b4f7f6e4..ea7b9c2c7e66 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -81,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
81 | 81 | ||
82 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 82 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
83 | 83 | ||
84 | cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); | 84 | chandef = ifibss->chandef; |
85 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | 85 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { |
86 | chandef.width = NL80211_CHAN_WIDTH_20; | 86 | chandef.width = NL80211_CHAN_WIDTH_20; |
87 | chandef.center_freq1 = chan->center_freq; | 87 | chandef.center_freq1 = chan->center_freq; |
@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
176 | 176 | ||
177 | /* add HT capability and information IEs */ | 177 | /* add HT capability and information IEs */ |
178 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 178 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
179 | chandef.width != NL80211_CHAN_WIDTH_5 && | ||
180 | chandef.width != NL80211_CHAN_WIDTH_10 && | ||
179 | sband->ht_cap.ht_supported) { | 181 | sband->ht_cap.ht_supported) { |
180 | pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, | 182 | pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, |
181 | sband->ht_cap.cap); | 183 | sband->ht_cap.cap); |
@@ -298,8 +300,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
298 | tsf, false); | 300 | tsf, false); |
299 | } | 301 | } |
300 | 302 | ||
301 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | 303 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) |
302 | bool auth) | ||
303 | __acquires(RCU) | 304 | __acquires(RCU) |
304 | { | 305 | { |
305 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 306 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
@@ -321,20 +322,12 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
321 | /* If it fails, maybe we raced another insertion? */ | 322 | /* If it fails, maybe we raced another insertion? */ |
322 | if (sta_info_insert_rcu(sta)) | 323 | if (sta_info_insert_rcu(sta)) |
323 | return sta_info_get(sdata, addr); | 324 | return sta_info_get(sdata, addr); |
324 | if (auth && !sdata->u.ibss.auth_frame_registrations) { | ||
325 | ibss_dbg(sdata, | ||
326 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", | ||
327 | sdata->vif.addr, addr, sdata->u.ibss.bssid); | ||
328 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, | ||
329 | addr, sdata->u.ibss.bssid, NULL, 0, 0, 0); | ||
330 | } | ||
331 | return sta; | 325 | return sta; |
332 | } | 326 | } |
333 | 327 | ||
334 | static struct sta_info * | 328 | static struct sta_info * |
335 | ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 329 | ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid, |
336 | const u8 *bssid, const u8 *addr, | 330 | const u8 *addr, u32 supp_rates) |
337 | u32 supp_rates, bool auth) | ||
338 | __acquires(RCU) | 331 | __acquires(RCU) |
339 | { | 332 | { |
340 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 333 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
@@ -385,7 +378,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
385 | sta->sta.supp_rates[band] = supp_rates | | 378 | sta->sta.supp_rates[band] = supp_rates | |
386 | ieee80211_mandatory_rates(sband); | 379 | ieee80211_mandatory_rates(sband); |
387 | 380 | ||
388 | return ieee80211_ibss_finish_sta(sta, auth); | 381 | return ieee80211_ibss_finish_sta(sta); |
389 | } | 382 | } |
390 | 383 | ||
391 | static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, | 384 | static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, |
@@ -407,8 +400,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
407 | size_t len) | 400 | size_t len) |
408 | { | 401 | { |
409 | u16 auth_alg, auth_transaction; | 402 | u16 auth_alg, auth_transaction; |
410 | struct sta_info *sta; | ||
411 | u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | ||
412 | 403 | ||
413 | sdata_assert_lock(sdata); | 404 | sdata_assert_lock(sdata); |
414 | 405 | ||
@@ -425,22 +416,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
425 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | 416 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
426 | return; | 417 | return; |
427 | 418 | ||
428 | sta_info_destroy_addr(sdata, mgmt->sa); | ||
429 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | ||
430 | rcu_read_unlock(); | ||
431 | |||
432 | /* | ||
433 | * if we have any problem in allocating the new station, we reply with a | ||
434 | * DEAUTH frame to tell the other end that we had a problem | ||
435 | */ | ||
436 | if (!sta) { | ||
437 | ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid, | ||
438 | IEEE80211_STYPE_DEAUTH, | ||
439 | WLAN_REASON_UNSPECIFIED, true, | ||
440 | deauth_frame_buf); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | /* | 419 | /* |
445 | * IEEE 802.11 standard does not require authentication in IBSS | 420 | * IEEE 802.11 standard does not require authentication in IBSS |
446 | * networks and most implementations do not seem to use it. | 421 | * networks and most implementations do not seem to use it. |
@@ -506,7 +481,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
506 | } else { | 481 | } else { |
507 | rcu_read_unlock(); | 482 | rcu_read_unlock(); |
508 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, | 483 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, |
509 | mgmt->sa, supp_rates, true); | 484 | mgmt->sa, supp_rates); |
510 | } | 485 | } |
511 | } | 486 | } |
512 | 487 | ||
@@ -514,7 +489,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
514 | set_sta_flag(sta, WLAN_STA_WME); | 489 | set_sta_flag(sta, WLAN_STA_WME); |
515 | 490 | ||
516 | if (sta && elems->ht_operation && elems->ht_cap_elem && | 491 | if (sta && elems->ht_operation && elems->ht_cap_elem && |
517 | sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { | 492 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
493 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 && | ||
494 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) { | ||
518 | /* we both use HT */ | 495 | /* we both use HT */ |
519 | struct ieee80211_ht_cap htcap_ie; | 496 | struct ieee80211_ht_cap htcap_ie; |
520 | struct cfg80211_chan_def chandef; | 497 | struct cfg80211_chan_def chandef; |
@@ -529,8 +506,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
529 | * fall back to HT20 if we don't use or use | 506 | * fall back to HT20 if we don't use or use |
530 | * the other extension channel | 507 | * the other extension channel |
531 | */ | 508 | */ |
532 | if (cfg80211_get_chandef_type(&chandef) != | 509 | if (chandef.center_freq1 != |
533 | sdata->u.ibss.channel_type) | 510 | sdata->u.ibss.chandef.center_freq1) |
534 | htcap_ie.cap_info &= | 511 | htcap_ie.cap_info &= |
535 | cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); | 512 | cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); |
536 | 513 | ||
@@ -569,7 +546,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
569 | 546 | ||
570 | /* different channel */ | 547 | /* different channel */ |
571 | if (sdata->u.ibss.fixed_channel && | 548 | if (sdata->u.ibss.fixed_channel && |
572 | sdata->u.ibss.channel != cbss->channel) | 549 | sdata->u.ibss.chandef.chan != cbss->channel) |
573 | goto put_bss; | 550 | goto put_bss; |
574 | 551 | ||
575 | /* different SSID */ | 552 | /* different SSID */ |
@@ -610,7 +587,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
610 | ieee80211_sta_join_ibss(sdata, bss); | 587 | ieee80211_sta_join_ibss(sdata, bss); |
611 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); | 588 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); |
612 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 589 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, |
613 | supp_rates, true); | 590 | supp_rates); |
614 | rcu_read_unlock(); | 591 | rcu_read_unlock(); |
615 | } | 592 | } |
616 | 593 | ||
@@ -759,7 +736,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
759 | sdata->drop_unencrypted = 0; | 736 | sdata->drop_unencrypted = 0; |
760 | 737 | ||
761 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 738 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
762 | ifibss->channel, ifibss->basic_rates, | 739 | ifibss->chandef.chan, ifibss->basic_rates, |
763 | capability, 0, true); | 740 | capability, 0, true); |
764 | } | 741 | } |
765 | 742 | ||
@@ -791,7 +768,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
791 | if (ifibss->fixed_bssid) | 768 | if (ifibss->fixed_bssid) |
792 | bssid = ifibss->bssid; | 769 | bssid = ifibss->bssid; |
793 | if (ifibss->fixed_channel) | 770 | if (ifibss->fixed_channel) |
794 | chan = ifibss->channel; | 771 | chan = ifibss->chandef.chan; |
795 | if (!is_zero_ether_addr(ifibss->bssid)) | 772 | if (!is_zero_ether_addr(ifibss->bssid)) |
796 | bssid = ifibss->bssid; | 773 | bssid = ifibss->bssid; |
797 | cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, | 774 | cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, |
@@ -982,7 +959,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | |||
982 | list_del(&sta->list); | 959 | list_del(&sta->list); |
983 | spin_unlock_bh(&ifibss->incomplete_lock); | 960 | spin_unlock_bh(&ifibss->incomplete_lock); |
984 | 961 | ||
985 | ieee80211_ibss_finish_sta(sta, true); | 962 | ieee80211_ibss_finish_sta(sta); |
986 | rcu_read_unlock(); | 963 | rcu_read_unlock(); |
987 | spin_lock_bh(&ifibss->incomplete_lock); | 964 | spin_lock_bh(&ifibss->incomplete_lock); |
988 | } | 965 | } |
@@ -1058,9 +1035,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1058 | 1035 | ||
1059 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; | 1036 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; |
1060 | 1037 | ||
1061 | sdata->u.ibss.channel = params->chandef.chan; | 1038 | sdata->u.ibss.chandef = params->chandef; |
1062 | sdata->u.ibss.channel_type = | ||
1063 | cfg80211_get_chandef_type(¶ms->chandef); | ||
1064 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 1039 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
1065 | 1040 | ||
1066 | if (params->ie) { | 1041 | if (params->ie) { |
@@ -1119,7 +1094,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1119 | if (ifibss->privacy) | 1094 | if (ifibss->privacy) |
1120 | capability |= WLAN_CAPABILITY_PRIVACY; | 1095 | capability |= WLAN_CAPABILITY_PRIVACY; |
1121 | 1096 | ||
1122 | cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->channel, | 1097 | cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan, |
1123 | ifibss->bssid, ifibss->ssid, | 1098 | ifibss->bssid, ifibss->ssid, |
1124 | ifibss->ssid_len, WLAN_CAPABILITY_IBSS | | 1099 | ifibss->ssid_len, WLAN_CAPABILITY_IBSS | |
1125 | WLAN_CAPABILITY_PRIVACY, | 1100 | WLAN_CAPABILITY_PRIVACY, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f97cd9d9105f..8412a303993a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -94,6 +94,7 @@ struct ieee80211_bss { | |||
94 | #define IEEE80211_MAX_SUPP_RATES 32 | 94 | #define IEEE80211_MAX_SUPP_RATES 32 |
95 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 95 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
96 | size_t supp_rates_len; | 96 | size_t supp_rates_len; |
97 | struct ieee80211_rate *beacon_rate; | ||
97 | 98 | ||
98 | /* | 99 | /* |
99 | * During association, we save an ERP value from a probe response so | 100 | * During association, we save an ERP value from a probe response so |
@@ -497,14 +498,12 @@ struct ieee80211_if_ibss { | |||
497 | bool privacy; | 498 | bool privacy; |
498 | 499 | ||
499 | bool control_port; | 500 | bool control_port; |
500 | unsigned int auth_frame_registrations; | ||
501 | 501 | ||
502 | u8 bssid[ETH_ALEN] __aligned(2); | 502 | u8 bssid[ETH_ALEN] __aligned(2); |
503 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 503 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
504 | u8 ssid_len, ie_len; | 504 | u8 ssid_len, ie_len; |
505 | u8 *ie; | 505 | u8 *ie; |
506 | struct ieee80211_channel *channel; | 506 | struct cfg80211_chan_def chandef; |
507 | enum nl80211_channel_type channel_type; | ||
508 | 507 | ||
509 | unsigned long ibss_join_req; | 508 | unsigned long ibss_join_req; |
510 | /* probe response/beacon for IBSS */ | 509 | /* probe response/beacon for IBSS */ |
@@ -543,6 +542,7 @@ struct ieee80211_if_mesh { | |||
543 | struct timer_list mesh_path_root_timer; | 542 | struct timer_list mesh_path_root_timer; |
544 | 543 | ||
545 | unsigned long wrkq_flags; | 544 | unsigned long wrkq_flags; |
545 | unsigned long mbss_changed; | ||
546 | 546 | ||
547 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; | 547 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; |
548 | size_t mesh_id_len; | 548 | size_t mesh_id_len; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 6c33af482df4..447f41bbe744 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -161,11 +161,8 @@ void mesh_sta_cleanup(struct sta_info *sta) | |||
161 | del_timer_sync(&sta->plink_timer); | 161 | del_timer_sync(&sta->plink_timer); |
162 | } | 162 | } |
163 | 163 | ||
164 | if (changed) { | 164 | if (changed) |
165 | sdata_lock(sdata); | ||
166 | ieee80211_mbss_info_change_notify(sdata, changed); | 165 | ieee80211_mbss_info_change_notify(sdata, changed); |
167 | sdata_unlock(sdata); | ||
168 | } | ||
169 | } | 166 | } |
170 | 167 | ||
171 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 168 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) |
@@ -419,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata, | |||
419 | 416 | ||
420 | sband = local->hw.wiphy->bands[band]; | 417 | sband = local->hw.wiphy->bands[band]; |
421 | if (!sband->ht_cap.ht_supported || | 418 | if (!sband->ht_cap.ht_supported || |
422 | sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) | 419 | sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || |
420 | sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 || | ||
421 | sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10) | ||
423 | return 0; | 422 | return 0; |
424 | 423 | ||
425 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) | 424 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) |
@@ -719,14 +718,18 @@ ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata) | |||
719 | void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 718 | void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
720 | u32 changed) | 719 | u32 changed) |
721 | { | 720 | { |
722 | if (sdata->vif.bss_conf.enable_beacon && | 721 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
723 | (changed & (BSS_CHANGED_BEACON | | 722 | unsigned long bits = changed; |
724 | BSS_CHANGED_HT | | 723 | u32 bit; |
725 | BSS_CHANGED_BASIC_RATES | | 724 | |
726 | BSS_CHANGED_BEACON_INT))) | 725 | if (!bits) |
727 | if (ieee80211_mesh_rebuild_beacon(sdata)) | 726 | return; |
728 | return; | 727 | |
729 | ieee80211_bss_info_change_notify(sdata, changed); | 728 | /* if we race with running work, worst case this work becomes a noop */ |
729 | for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) | ||
730 | set_bit(bit, &ifmsh->mbss_changed); | ||
731 | set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); | ||
732 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | ||
730 | } | 733 | } |
731 | 734 | ||
732 | int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | 735 | int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) |
@@ -799,6 +802,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
799 | del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); | 802 | del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); |
800 | del_timer_sync(&sdata->u.mesh.mesh_path_timer); | 803 | del_timer_sync(&sdata->u.mesh.mesh_path_timer); |
801 | 804 | ||
805 | /* clear any mesh work (for next join) we may have accrued */ | ||
806 | ifmsh->wrkq_flags = 0; | ||
807 | ifmsh->mbss_changed = 0; | ||
808 | |||
802 | local->fif_other_bss--; | 809 | local->fif_other_bss--; |
803 | atomic_dec(&local->iff_allmultis); | 810 | atomic_dec(&local->iff_allmultis); |
804 | ieee80211_configure_filter(local); | 811 | ieee80211_configure_filter(local); |
@@ -965,6 +972,28 @@ out: | |||
965 | sdata_unlock(sdata); | 972 | sdata_unlock(sdata); |
966 | } | 973 | } |
967 | 974 | ||
975 | static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata) | ||
976 | { | ||
977 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
978 | u32 bit, changed = 0; | ||
979 | |||
980 | for_each_set_bit(bit, &ifmsh->mbss_changed, | ||
981 | sizeof(changed) * BITS_PER_BYTE) { | ||
982 | clear_bit(bit, &ifmsh->mbss_changed); | ||
983 | changed |= BIT(bit); | ||
984 | } | ||
985 | |||
986 | if (sdata->vif.bss_conf.enable_beacon && | ||
987 | (changed & (BSS_CHANGED_BEACON | | ||
988 | BSS_CHANGED_HT | | ||
989 | BSS_CHANGED_BASIC_RATES | | ||
990 | BSS_CHANGED_BEACON_INT))) | ||
991 | if (ieee80211_mesh_rebuild_beacon(sdata)) | ||
992 | return; | ||
993 | |||
994 | ieee80211_bss_info_change_notify(sdata, changed); | ||
995 | } | ||
996 | |||
968 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) | 997 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) |
969 | { | 998 | { |
970 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 999 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
@@ -995,6 +1024,8 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) | |||
995 | if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) | 1024 | if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) |
996 | mesh_sync_adjust_tbtt(sdata); | 1025 | mesh_sync_adjust_tbtt(sdata); |
997 | 1026 | ||
1027 | if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags)) | ||
1028 | mesh_bss_info_changed(sdata); | ||
998 | out: | 1029 | out: |
999 | sdata_unlock(sdata); | 1030 | sdata_unlock(sdata); |
1000 | } | 1031 | } |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 01a28bca6e9b..2bc7fd2f787d 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -58,6 +58,7 @@ enum mesh_path_flags { | |||
58 | * @MESH_WORK_ROOT: the mesh root station needs to send a frame | 58 | * @MESH_WORK_ROOT: the mesh root station needs to send a frame |
59 | * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other | 59 | * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other |
60 | * mesh nodes | 60 | * mesh nodes |
61 | * @MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes | ||
61 | */ | 62 | */ |
62 | enum mesh_deferred_task_flags { | 63 | enum mesh_deferred_task_flags { |
63 | MESH_WORK_HOUSEKEEPING, | 64 | MESH_WORK_HOUSEKEEPING, |
@@ -65,6 +66,7 @@ enum mesh_deferred_task_flags { | |||
65 | MESH_WORK_GROW_MPP_TABLE, | 66 | MESH_WORK_GROW_MPP_TABLE, |
66 | MESH_WORK_ROOT, | 67 | MESH_WORK_ROOT, |
67 | MESH_WORK_DRIFT_ADJUST, | 68 | MESH_WORK_DRIFT_ADJUST, |
69 | MESH_WORK_MBSS_CHANGED, | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | /** | 72 | /** |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 09bebed99416..02c05fa15c20 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) | |||
154 | u16 ht_opmode; | 154 | u16 ht_opmode; |
155 | bool non_ht_sta = false, ht20_sta = false; | 155 | bool non_ht_sta = false, ht20_sta = false; |
156 | 156 | ||
157 | if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) | 157 | switch (sdata->vif.bss_conf.chandef.width) { |
158 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
159 | case NL80211_CHAN_WIDTH_5: | ||
160 | case NL80211_CHAN_WIDTH_10: | ||
158 | return 0; | 161 | return 0; |
162 | default: | ||
163 | break; | ||
164 | } | ||
159 | 165 | ||
160 | rcu_read_lock(); | 166 | rcu_read_lock(); |
161 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 167 | list_for_each_entry_rcu(sta, &local->sta_list, list) { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9e49f557fa5c..ae31968d42d3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c) | |||
190 | c->width = NL80211_CHAN_WIDTH_20_NOHT; | 190 | c->width = NL80211_CHAN_WIDTH_20_NOHT; |
191 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; | 191 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; |
192 | break; | 192 | break; |
193 | case NL80211_CHAN_WIDTH_5: | ||
194 | case NL80211_CHAN_WIDTH_10: | ||
195 | WARN_ON_ONCE(1); | ||
196 | /* keep c->width */ | ||
197 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; | ||
198 | break; | ||
193 | } | 199 | } |
194 | 200 | ||
195 | WARN_ON_ONCE(!cfg80211_chandef_valid(c)); | 201 | WARN_ON_ONCE(!cfg80211_chandef_valid(c)); |
@@ -1779,8 +1785,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1779 | * probably just won't work at all. | 1785 | * probably just won't work at all. |
1780 | */ | 1786 | */ |
1781 | bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; | 1787 | bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; |
1788 | bss_conf->beacon_rate = bss->beacon_rate; | ||
1782 | bss_info_changed |= BSS_CHANGED_BEACON_INFO; | 1789 | bss_info_changed |= BSS_CHANGED_BEACON_INFO; |
1783 | } else { | 1790 | } else { |
1791 | bss_conf->beacon_rate = NULL; | ||
1784 | bss_conf->dtim_period = 0; | 1792 | bss_conf->dtim_period = 0; |
1785 | } | 1793 | } |
1786 | 1794 | ||
@@ -1903,6 +1911,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1903 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | 1911 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
1904 | 1912 | ||
1905 | sdata->vif.bss_conf.dtim_period = 0; | 1913 | sdata->vif.bss_conf.dtim_period = 0; |
1914 | sdata->vif.bss_conf.beacon_rate = NULL; | ||
1915 | |||
1906 | ifmgd->have_beacon = false; | 1916 | ifmgd->have_beacon = false; |
1907 | 1917 | ||
1908 | ifmgd->flags = 0; | 1918 | ifmgd->flags = 0; |
@@ -2785,8 +2795,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2785 | if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { | 2795 | if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { |
2786 | /* oops -- internal error -- send timeout for now */ | 2796 | /* oops -- internal error -- send timeout for now */ |
2787 | ieee80211_destroy_assoc_data(sdata, false); | 2797 | ieee80211_destroy_assoc_data(sdata, false); |
2788 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); | 2798 | cfg80211_assoc_timeout(sdata->dev, bss); |
2789 | cfg80211_assoc_timeout(sdata->dev, mgmt->bssid); | ||
2790 | return; | 2799 | return; |
2791 | } | 2800 | } |
2792 | sdata_info(sdata, "associated\n"); | 2801 | sdata_info(sdata, "associated\n"); |
@@ -2827,8 +2836,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2827 | 2836 | ||
2828 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, | 2837 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, |
2829 | channel); | 2838 | channel); |
2830 | if (bss) | 2839 | if (bss) { |
2831 | ieee80211_rx_bss_put(local, bss); | 2840 | ieee80211_rx_bss_put(local, bss); |
2841 | sdata->vif.bss_conf.beacon_rate = bss->beacon_rate; | ||
2842 | } | ||
2832 | 2843 | ||
2833 | if (!sdata->u.mgd.associated || | 2844 | if (!sdata->u.mgd.associated || |
2834 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) | 2845 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) |
@@ -3501,13 +3512,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3501 | time_after(jiffies, ifmgd->assoc_data->timeout)) { | 3512 | time_after(jiffies, ifmgd->assoc_data->timeout)) { |
3502 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || | 3513 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || |
3503 | ieee80211_do_assoc(sdata)) { | 3514 | ieee80211_do_assoc(sdata)) { |
3504 | u8 bssid[ETH_ALEN]; | 3515 | struct cfg80211_bss *bss = ifmgd->assoc_data->bss; |
3505 | |||
3506 | memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN); | ||
3507 | 3516 | ||
3508 | ieee80211_destroy_assoc_data(sdata, false); | 3517 | ieee80211_destroy_assoc_data(sdata, false); |
3509 | 3518 | cfg80211_assoc_timeout(sdata->dev, bss); | |
3510 | cfg80211_assoc_timeout(sdata->dev, bssid); | ||
3511 | } | 3519 | } |
3512 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) | 3520 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3513 | run_again(sdata, ifmgd->assoc_data->timeout); | 3521 | run_again(sdata, ifmgd->assoc_data->timeout); |
@@ -3838,6 +3846,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3838 | */ | 3846 | */ |
3839 | ret = ieee80211_vif_use_channel(sdata, &chandef, | 3847 | ret = ieee80211_vif_use_channel(sdata, &chandef, |
3840 | IEEE80211_CHANCTX_SHARED); | 3848 | IEEE80211_CHANCTX_SHARED); |
3849 | |||
3850 | /* don't downgrade for 5 and 10 MHz channels, though. */ | ||
3851 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | ||
3852 | chandef.width == NL80211_CHAN_WIDTH_10) | ||
3853 | return ret; | ||
3854 | |||
3841 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { | 3855 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { |
3842 | ifmgd->flags |= chandef_downgrade(&chandef); | 3856 | ifmgd->flags |= chandef_downgrade(&chandef); |
3843 | ret = ieee80211_vif_use_channel(sdata, &chandef, | 3857 | ret = ieee80211_vif_use_channel(sdata, &chandef, |
@@ -4427,8 +4441,11 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) | |||
4427 | cancel_work_sync(&ifmgd->chswitch_work); | 4441 | cancel_work_sync(&ifmgd->chswitch_work); |
4428 | 4442 | ||
4429 | sdata_lock(sdata); | 4443 | sdata_lock(sdata); |
4430 | if (ifmgd->assoc_data) | 4444 | if (ifmgd->assoc_data) { |
4445 | struct cfg80211_bss *bss = ifmgd->assoc_data->bss; | ||
4431 | ieee80211_destroy_assoc_data(sdata, false); | 4446 | ieee80211_destroy_assoc_data(sdata, false); |
4447 | cfg80211_assoc_timeout(sdata->dev, bss); | ||
4448 | } | ||
4432 | if (ifmgd->auth_data) | 4449 | if (ifmgd->auth_data) |
4433 | ieee80211_destroy_auth_data(sdata, false); | 4450 | ieee80211_destroy_auth_data(sdata, false); |
4434 | del_timer_sync(&ifmgd->timer); | 4451 | del_timer_sync(&ifmgd->timer); |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index a02bef35b134..30d58d2d13e2 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, | |||
397 | return; | 397 | return; |
398 | 398 | ||
399 | /* if HT BSS, and we handle a data frame, also try HT rates */ | 399 | /* if HT BSS, and we handle a data frame, also try HT rates */ |
400 | if (chan_width == NL80211_CHAN_WIDTH_20_NOHT) | 400 | switch (chan_width) { |
401 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
402 | case NL80211_CHAN_WIDTH_5: | ||
403 | case NL80211_CHAN_WIDTH_10: | ||
401 | return; | 404 | return; |
405 | default: | ||
406 | break; | ||
407 | } | ||
402 | 408 | ||
403 | alt_rate.idx = 0; | 409 | alt_rate.idx = 0; |
404 | /* keep protection flags */ | 410 | /* keep protection flags */ |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 99b103921a4b..1b122a79b0d8 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -140,6 +140,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
140 | bss->valid_data |= IEEE80211_BSS_VALID_WMM; | 140 | bss->valid_data |= IEEE80211_BSS_VALID_WMM; |
141 | } | 141 | } |
142 | 142 | ||
143 | if (beacon) { | ||
144 | struct ieee80211_supported_band *sband = | ||
145 | local->hw.wiphy->bands[rx_status->band]; | ||
146 | if (!(rx_status->flag & RX_FLAG_HT) && | ||
147 | !(rx_status->flag & RX_FLAG_VHT)) | ||
148 | bss->beacon_rate = | ||
149 | &sband->bitrates[rx_status->rate_idx]; | ||
150 | } | ||
151 | |||
143 | return bss; | 152 | return bss; |
144 | } | 153 | } |
145 | 154 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index b4297982d34a..aeb967a0aeed 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -149,6 +149,7 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
149 | * directly by station destruction. | 149 | * directly by station destruction. |
150 | */ | 150 | */ |
151 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 151 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
152 | kfree(sta->ampdu_mlme.tid_start_tx[i]); | ||
152 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); | 153 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); |
153 | if (!tid_tx) | 154 | if (!tid_tx) |
154 | continue; | 155 | continue; |
@@ -346,6 +347,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
346 | if (ieee80211_vif_is_mesh(&sdata->vif) && | 347 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
347 | !sdata->u.mesh.user_mpm) | 348 | !sdata->u.mesh.user_mpm) |
348 | init_timer(&sta->plink_timer); | 349 | init_timer(&sta->plink_timer); |
350 | sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; | ||
349 | #endif | 351 | #endif |
350 | 352 | ||
351 | memcpy(sta->sta.addr, addr, ETH_ALEN); | 353 | memcpy(sta->sta.addr, addr, ETH_ALEN); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index bd12fc54266c..4208dbd5861f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -203,6 +203,7 @@ struct tid_ampdu_rx { | |||
203 | * driver requested to close until the work for it runs | 203 | * driver requested to close until the work for it runs |
204 | * @mtx: mutex to protect all TX data (except non-NULL assignments | 204 | * @mtx: mutex to protect all TX data (except non-NULL assignments |
205 | * to tid_tx[idx], which are protected by the sta spinlock) | 205 | * to tid_tx[idx], which are protected by the sta spinlock) |
206 | * tid_start_tx is also protected by sta->lock. | ||
206 | */ | 207 | */ |
207 | struct sta_ampdu_mlme { | 208 | struct sta_ampdu_mlme { |
208 | struct mutex mtx; | 209 | struct mutex mtx; |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 171344d4eb7c..97c289414e32 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -396,7 +396,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | |||
396 | new_bw = ieee80211_sta_cur_vht_bw(sta); | 396 | new_bw = ieee80211_sta_cur_vht_bw(sta); |
397 | if (new_bw != sta->sta.bandwidth) { | 397 | if (new_bw != sta->sta.bandwidth) { |
398 | sta->sta.bandwidth = new_bw; | 398 | sta->sta.bandwidth = new_bw; |
399 | changed |= IEEE80211_RC_NSS_CHANGED; | 399 | changed |= IEEE80211_RC_BW_CHANGED; |
400 | } | 400 | } |
401 | 401 | ||
402 | change: | 402 | change: |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index fd556ac05fdb..50f6195c8b70 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -54,6 +54,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) | |||
54 | control_freq = chandef->chan->center_freq; | 54 | control_freq = chandef->chan->center_freq; |
55 | 55 | ||
56 | switch (chandef->width) { | 56 | switch (chandef->width) { |
57 | case NL80211_CHAN_WIDTH_5: | ||
58 | case NL80211_CHAN_WIDTH_10: | ||
57 | case NL80211_CHAN_WIDTH_20: | 59 | case NL80211_CHAN_WIDTH_20: |
58 | case NL80211_CHAN_WIDTH_20_NOHT: | 60 | case NL80211_CHAN_WIDTH_20_NOHT: |
59 | if (chandef->center_freq1 != control_freq) | 61 | if (chandef->center_freq1 != control_freq) |
@@ -152,6 +154,12 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c) | |||
152 | int width; | 154 | int width; |
153 | 155 | ||
154 | switch (c->width) { | 156 | switch (c->width) { |
157 | case NL80211_CHAN_WIDTH_5: | ||
158 | width = 5; | ||
159 | break; | ||
160 | case NL80211_CHAN_WIDTH_10: | ||
161 | width = 10; | ||
162 | break; | ||
155 | case NL80211_CHAN_WIDTH_20: | 163 | case NL80211_CHAN_WIDTH_20: |
156 | case NL80211_CHAN_WIDTH_20_NOHT: | 164 | case NL80211_CHAN_WIDTH_20_NOHT: |
157 | width = 20; | 165 | width = 20; |
@@ -194,6 +202,16 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1, | |||
194 | if (c1->width == c2->width) | 202 | if (c1->width == c2->width) |
195 | return NULL; | 203 | return NULL; |
196 | 204 | ||
205 | /* | ||
206 | * can't be compatible if one of them is 5 or 10 MHz, | ||
207 | * but they don't have the same width. | ||
208 | */ | ||
209 | if (c1->width == NL80211_CHAN_WIDTH_5 || | ||
210 | c1->width == NL80211_CHAN_WIDTH_10 || | ||
211 | c2->width == NL80211_CHAN_WIDTH_5 || | ||
212 | c2->width == NL80211_CHAN_WIDTH_10) | ||
213 | return NULL; | ||
214 | |||
197 | if (c1->width == NL80211_CHAN_WIDTH_20_NOHT || | 215 | if (c1->width == NL80211_CHAN_WIDTH_20_NOHT || |
198 | c1->width == NL80211_CHAN_WIDTH_20) | 216 | c1->width == NL80211_CHAN_WIDTH_20) |
199 | return c2; | 217 | return c2; |
@@ -264,11 +282,17 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, | |||
264 | u32 bandwidth) | 282 | u32 bandwidth) |
265 | { | 283 | { |
266 | struct ieee80211_channel *c; | 284 | struct ieee80211_channel *c; |
267 | u32 freq; | 285 | u32 freq, start_freq, end_freq; |
286 | |||
287 | if (bandwidth <= 20) { | ||
288 | start_freq = center_freq; | ||
289 | end_freq = center_freq; | ||
290 | } else { | ||
291 | start_freq = center_freq - bandwidth/2 + 10; | ||
292 | end_freq = center_freq + bandwidth/2 - 10; | ||
293 | } | ||
268 | 294 | ||
269 | for (freq = center_freq - bandwidth/2 + 10; | 295 | for (freq = start_freq; freq <= end_freq; freq += 20) { |
270 | freq <= center_freq + bandwidth/2 - 10; | ||
271 | freq += 20) { | ||
272 | c = ieee80211_get_channel(wiphy, freq); | 296 | c = ieee80211_get_channel(wiphy, freq); |
273 | if (!c) | 297 | if (!c) |
274 | return -EINVAL; | 298 | return -EINVAL; |
@@ -310,11 +334,17 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, | |||
310 | u32 prohibited_flags) | 334 | u32 prohibited_flags) |
311 | { | 335 | { |
312 | struct ieee80211_channel *c; | 336 | struct ieee80211_channel *c; |
313 | u32 freq; | 337 | u32 freq, start_freq, end_freq; |
338 | |||
339 | if (bandwidth <= 20) { | ||
340 | start_freq = center_freq; | ||
341 | end_freq = center_freq; | ||
342 | } else { | ||
343 | start_freq = center_freq - bandwidth/2 + 10; | ||
344 | end_freq = center_freq + bandwidth/2 - 10; | ||
345 | } | ||
314 | 346 | ||
315 | for (freq = center_freq - bandwidth/2 + 10; | 347 | for (freq = start_freq; freq <= end_freq; freq += 20) { |
316 | freq <= center_freq + bandwidth/2 - 10; | ||
317 | freq += 20) { | ||
318 | c = ieee80211_get_channel(wiphy, freq); | 348 | c = ieee80211_get_channel(wiphy, freq); |
319 | if (!c) | 349 | if (!c) |
320 | return false; | 350 | return false; |
@@ -349,6 +379,12 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
349 | control_freq = chandef->chan->center_freq; | 379 | control_freq = chandef->chan->center_freq; |
350 | 380 | ||
351 | switch (chandef->width) { | 381 | switch (chandef->width) { |
382 | case NL80211_CHAN_WIDTH_5: | ||
383 | width = 5; | ||
384 | break; | ||
385 | case NL80211_CHAN_WIDTH_10: | ||
386 | width = 10; | ||
387 | break; | ||
352 | case NL80211_CHAN_WIDTH_20: | 388 | case NL80211_CHAN_WIDTH_20: |
353 | if (!ht_cap->ht_supported) | 389 | if (!ht_cap->ht_supported) |
354 | return false; | 390 | return false; |
@@ -405,6 +441,11 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
405 | if (width > 20) | 441 | if (width > 20) |
406 | prohibited_flags |= IEEE80211_CHAN_NO_OFDM; | 442 | prohibited_flags |= IEEE80211_CHAN_NO_OFDM; |
407 | 443 | ||
444 | /* 5 and 10 MHz are only defined for the OFDM PHY */ | ||
445 | if (width < 20) | ||
446 | prohibited_flags |= IEEE80211_CHAN_NO_OFDM; | ||
447 | |||
448 | |||
408 | if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, | 449 | if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, |
409 | width, prohibited_flags)) | 450 | width, prohibited_flags)) |
410 | return false; | 451 | return false; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index f277246080b5..4f9f216665e9 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -933,6 +933,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
933 | * freed. | 933 | * freed. |
934 | */ | 934 | */ |
935 | cfg80211_process_wdev_events(wdev); | 935 | cfg80211_process_wdev_events(wdev); |
936 | |||
937 | if (WARN_ON(wdev->current_bss)) { | ||
938 | cfg80211_unhold_bss(wdev->current_bss); | ||
939 | cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); | ||
940 | wdev->current_bss = NULL; | ||
941 | } | ||
936 | break; | 942 | break; |
937 | case NETDEV_PRE_UP: | 943 | case NETDEV_PRE_UP: |
938 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 944 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index a61a44bc6cf0..bfac5e186f57 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | |||
38 | * frame instead of reassoc. | 38 | * frame instead of reassoc. |
39 | */ | 39 | */ |
40 | if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { | 40 | if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { |
41 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
41 | cfg80211_put_bss(wiphy, bss); | 42 | cfg80211_put_bss(wiphy, bss); |
42 | return; | 43 | return; |
43 | } | 44 | } |
@@ -131,16 +132,19 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr) | |||
131 | } | 132 | } |
132 | EXPORT_SYMBOL(cfg80211_auth_timeout); | 133 | EXPORT_SYMBOL(cfg80211_auth_timeout); |
133 | 134 | ||
134 | void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr) | 135 | void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss) |
135 | { | 136 | { |
136 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 137 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
137 | struct wiphy *wiphy = wdev->wiphy; | 138 | struct wiphy *wiphy = wdev->wiphy; |
138 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 139 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
139 | 140 | ||
140 | trace_cfg80211_send_assoc_timeout(dev, addr); | 141 | trace_cfg80211_send_assoc_timeout(dev, bss->bssid); |
141 | 142 | ||
142 | nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); | 143 | nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL); |
143 | cfg80211_sme_assoc_timeout(wdev); | 144 | cfg80211_sme_assoc_timeout(wdev); |
145 | |||
146 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
147 | cfg80211_put_bss(wiphy, bss); | ||
144 | } | 148 | } |
145 | EXPORT_SYMBOL(cfg80211_assoc_timeout); | 149 | EXPORT_SYMBOL(cfg80211_assoc_timeout); |
146 | 150 | ||
@@ -307,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
307 | goto out; | 311 | goto out; |
308 | 312 | ||
309 | err = rdev_assoc(rdev, dev, req); | 313 | err = rdev_assoc(rdev, dev, req); |
314 | if (!err) | ||
315 | cfg80211_hold_bss(bss_from_pub(req->bss)); | ||
310 | 316 | ||
311 | out: | 317 | out: |
312 | if (err) | 318 | if (err) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e545023e2871..1cc47aca7f05 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1111,10 +1111,16 @@ nl80211_send_mgmt_stypes(struct sk_buff *msg, | |||
1111 | return 0; | 1111 | return 0; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | struct nl80211_dump_wiphy_state { | ||
1115 | s64 filter_wiphy; | ||
1116 | long start; | ||
1117 | long split_start, band_start, chan_start; | ||
1118 | bool split; | ||
1119 | }; | ||
1120 | |||
1114 | static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | 1121 | static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, |
1115 | struct sk_buff *msg, u32 portid, u32 seq, | 1122 | struct sk_buff *msg, u32 portid, u32 seq, |
1116 | int flags, bool split, long *split_start, | 1123 | int flags, struct nl80211_dump_wiphy_state *state) |
1117 | long *band_start, long *chan_start) | ||
1118 | { | 1124 | { |
1119 | void *hdr; | 1125 | void *hdr; |
1120 | struct nlattr *nl_bands, *nl_band; | 1126 | struct nlattr *nl_bands, *nl_band; |
@@ -1125,19 +1131,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1125 | int i; | 1131 | int i; |
1126 | const struct ieee80211_txrx_stypes *mgmt_stypes = | 1132 | const struct ieee80211_txrx_stypes *mgmt_stypes = |
1127 | dev->wiphy.mgmt_stypes; | 1133 | dev->wiphy.mgmt_stypes; |
1128 | long start = 0, start_chan = 0, start_band = 0; | ||
1129 | u32 features; | 1134 | u32 features; |
1130 | 1135 | ||
1131 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); | 1136 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); |
1132 | if (!hdr) | 1137 | if (!hdr) |
1133 | return -ENOBUFS; | 1138 | return -ENOBUFS; |
1134 | 1139 | ||
1135 | /* allow always using the variables */ | 1140 | if (WARN_ON(!state)) |
1136 | if (!split) { | 1141 | return -EINVAL; |
1137 | split_start = &start; | ||
1138 | band_start = &start_band; | ||
1139 | chan_start = &start_chan; | ||
1140 | } | ||
1141 | 1142 | ||
1142 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || | 1143 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || |
1143 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, | 1144 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, |
@@ -1146,7 +1147,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1146 | cfg80211_rdev_list_generation)) | 1147 | cfg80211_rdev_list_generation)) |
1147 | goto nla_put_failure; | 1148 | goto nla_put_failure; |
1148 | 1149 | ||
1149 | switch (*split_start) { | 1150 | switch (state->split_start) { |
1150 | case 0: | 1151 | case 0: |
1151 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, | 1152 | if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, |
1152 | dev->wiphy.retry_short) || | 1153 | dev->wiphy.retry_short) || |
@@ -1188,9 +1189,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1188 | if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && | 1189 | if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && |
1189 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) | 1190 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) |
1190 | goto nla_put_failure; | 1191 | goto nla_put_failure; |
1192 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && | ||
1193 | nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ)) | ||
1194 | goto nla_put_failure; | ||
1191 | 1195 | ||
1192 | (*split_start)++; | 1196 | state->split_start++; |
1193 | if (split) | 1197 | if (state->split) |
1194 | break; | 1198 | break; |
1195 | case 1: | 1199 | case 1: |
1196 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, | 1200 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, |
@@ -1234,22 +1238,23 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1234 | } | 1238 | } |
1235 | } | 1239 | } |
1236 | 1240 | ||
1237 | (*split_start)++; | 1241 | state->split_start++; |
1238 | if (split) | 1242 | if (state->split) |
1239 | break; | 1243 | break; |
1240 | case 2: | 1244 | case 2: |
1241 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, | 1245 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, |
1242 | dev->wiphy.interface_modes)) | 1246 | dev->wiphy.interface_modes)) |
1243 | goto nla_put_failure; | 1247 | goto nla_put_failure; |
1244 | (*split_start)++; | 1248 | state->split_start++; |
1245 | if (split) | 1249 | if (state->split) |
1246 | break; | 1250 | break; |
1247 | case 3: | 1251 | case 3: |
1248 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); | 1252 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); |
1249 | if (!nl_bands) | 1253 | if (!nl_bands) |
1250 | goto nla_put_failure; | 1254 | goto nla_put_failure; |
1251 | 1255 | ||
1252 | for (band = *band_start; band < IEEE80211_NUM_BANDS; band++) { | 1256 | for (band = state->band_start; |
1257 | band < IEEE80211_NUM_BANDS; band++) { | ||
1253 | struct ieee80211_supported_band *sband; | 1258 | struct ieee80211_supported_band *sband; |
1254 | 1259 | ||
1255 | sband = dev->wiphy.bands[band]; | 1260 | sband = dev->wiphy.bands[band]; |
@@ -1261,12 +1266,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1261 | if (!nl_band) | 1266 | if (!nl_band) |
1262 | goto nla_put_failure; | 1267 | goto nla_put_failure; |
1263 | 1268 | ||
1264 | switch (*chan_start) { | 1269 | switch (state->chan_start) { |
1265 | case 0: | 1270 | case 0: |
1266 | if (nl80211_send_band_rateinfo(msg, sband)) | 1271 | if (nl80211_send_band_rateinfo(msg, sband)) |
1267 | goto nla_put_failure; | 1272 | goto nla_put_failure; |
1268 | (*chan_start)++; | 1273 | state->chan_start++; |
1269 | if (split) | 1274 | if (state->split) |
1270 | break; | 1275 | break; |
1271 | default: | 1276 | default: |
1272 | /* add frequencies */ | 1277 | /* add frequencies */ |
@@ -1275,7 +1280,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1275 | if (!nl_freqs) | 1280 | if (!nl_freqs) |
1276 | goto nla_put_failure; | 1281 | goto nla_put_failure; |
1277 | 1282 | ||
1278 | for (i = *chan_start - 1; | 1283 | for (i = state->chan_start - 1; |
1279 | i < sband->n_channels; | 1284 | i < sband->n_channels; |
1280 | i++) { | 1285 | i++) { |
1281 | nl_freq = nla_nest_start(msg, i); | 1286 | nl_freq = nla_nest_start(msg, i); |
@@ -1284,26 +1289,27 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1284 | 1289 | ||
1285 | chan = &sband->channels[i]; | 1290 | chan = &sband->channels[i]; |
1286 | 1291 | ||
1287 | if (nl80211_msg_put_channel(msg, chan, | 1292 | if (nl80211_msg_put_channel( |
1288 | split)) | 1293 | msg, chan, |
1294 | state->split)) | ||
1289 | goto nla_put_failure; | 1295 | goto nla_put_failure; |
1290 | 1296 | ||
1291 | nla_nest_end(msg, nl_freq); | 1297 | nla_nest_end(msg, nl_freq); |
1292 | if (split) | 1298 | if (state->split) |
1293 | break; | 1299 | break; |
1294 | } | 1300 | } |
1295 | if (i < sband->n_channels) | 1301 | if (i < sband->n_channels) |
1296 | *chan_start = i + 2; | 1302 | state->chan_start = i + 2; |
1297 | else | 1303 | else |
1298 | *chan_start = 0; | 1304 | state->chan_start = 0; |
1299 | nla_nest_end(msg, nl_freqs); | 1305 | nla_nest_end(msg, nl_freqs); |
1300 | } | 1306 | } |
1301 | 1307 | ||
1302 | nla_nest_end(msg, nl_band); | 1308 | nla_nest_end(msg, nl_band); |
1303 | 1309 | ||
1304 | if (split) { | 1310 | if (state->split) { |
1305 | /* start again here */ | 1311 | /* start again here */ |
1306 | if (*chan_start) | 1312 | if (state->chan_start) |
1307 | band--; | 1313 | band--; |
1308 | break; | 1314 | break; |
1309 | } | 1315 | } |
@@ -1311,14 +1317,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1311 | nla_nest_end(msg, nl_bands); | 1317 | nla_nest_end(msg, nl_bands); |
1312 | 1318 | ||
1313 | if (band < IEEE80211_NUM_BANDS) | 1319 | if (band < IEEE80211_NUM_BANDS) |
1314 | *band_start = band + 1; | 1320 | state->band_start = band + 1; |
1315 | else | 1321 | else |
1316 | *band_start = 0; | 1322 | state->band_start = 0; |
1317 | 1323 | ||
1318 | /* if bands & channels are done, continue outside */ | 1324 | /* if bands & channels are done, continue outside */ |
1319 | if (*band_start == 0 && *chan_start == 0) | 1325 | if (state->band_start == 0 && state->chan_start == 0) |
1320 | (*split_start)++; | 1326 | state->split_start++; |
1321 | if (split) | 1327 | if (state->split) |
1322 | break; | 1328 | break; |
1323 | case 4: | 1329 | case 4: |
1324 | nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); | 1330 | nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); |
@@ -1384,7 +1390,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1384 | } | 1390 | } |
1385 | CMD(start_p2p_device, START_P2P_DEVICE); | 1391 | CMD(start_p2p_device, START_P2P_DEVICE); |
1386 | CMD(set_mcast_rate, SET_MCAST_RATE); | 1392 | CMD(set_mcast_rate, SET_MCAST_RATE); |
1387 | if (split) { | 1393 | if (state->split) { |
1388 | CMD(crit_proto_start, CRIT_PROTOCOL_START); | 1394 | CMD(crit_proto_start, CRIT_PROTOCOL_START); |
1389 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); | 1395 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); |
1390 | } | 1396 | } |
@@ -1408,8 +1414,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1408 | } | 1414 | } |
1409 | 1415 | ||
1410 | nla_nest_end(msg, nl_cmds); | 1416 | nla_nest_end(msg, nl_cmds); |
1411 | (*split_start)++; | 1417 | state->split_start++; |
1412 | if (split) | 1418 | if (state->split) |
1413 | break; | 1419 | break; |
1414 | case 5: | 1420 | case 5: |
1415 | if (dev->ops->remain_on_channel && | 1421 | if (dev->ops->remain_on_channel && |
@@ -1425,29 +1431,30 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1425 | 1431 | ||
1426 | if (nl80211_send_mgmt_stypes(msg, mgmt_stypes)) | 1432 | if (nl80211_send_mgmt_stypes(msg, mgmt_stypes)) |
1427 | goto nla_put_failure; | 1433 | goto nla_put_failure; |
1428 | (*split_start)++; | 1434 | state->split_start++; |
1429 | if (split) | 1435 | if (state->split) |
1430 | break; | 1436 | break; |
1431 | case 6: | 1437 | case 6: |
1432 | #ifdef CONFIG_PM | 1438 | #ifdef CONFIG_PM |
1433 | if (nl80211_send_wowlan(msg, dev, split)) | 1439 | if (nl80211_send_wowlan(msg, dev, state->split)) |
1434 | goto nla_put_failure; | 1440 | goto nla_put_failure; |
1435 | (*split_start)++; | 1441 | state->split_start++; |
1436 | if (split) | 1442 | if (state->split) |
1437 | break; | 1443 | break; |
1438 | #else | 1444 | #else |
1439 | (*split_start)++; | 1445 | state->split_start++; |
1440 | #endif | 1446 | #endif |
1441 | case 7: | 1447 | case 7: |
1442 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, | 1448 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, |
1443 | dev->wiphy.software_iftypes)) | 1449 | dev->wiphy.software_iftypes)) |
1444 | goto nla_put_failure; | 1450 | goto nla_put_failure; |
1445 | 1451 | ||
1446 | if (nl80211_put_iface_combinations(&dev->wiphy, msg, split)) | 1452 | if (nl80211_put_iface_combinations(&dev->wiphy, msg, |
1453 | state->split)) | ||
1447 | goto nla_put_failure; | 1454 | goto nla_put_failure; |
1448 | 1455 | ||
1449 | (*split_start)++; | 1456 | state->split_start++; |
1450 | if (split) | 1457 | if (state->split) |
1451 | break; | 1458 | break; |
1452 | case 8: | 1459 | case 8: |
1453 | if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && | 1460 | if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && |
@@ -1461,7 +1468,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1461 | * dump is split, otherwise it makes it too big. Therefore | 1468 | * dump is split, otherwise it makes it too big. Therefore |
1462 | * only advertise it in that case. | 1469 | * only advertise it in that case. |
1463 | */ | 1470 | */ |
1464 | if (split) | 1471 | if (state->split) |
1465 | features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS; | 1472 | features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS; |
1466 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) | 1473 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) |
1467 | goto nla_put_failure; | 1474 | goto nla_put_failure; |
@@ -1488,7 +1495,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1488 | * case we'll continue with more data in the next round, | 1495 | * case we'll continue with more data in the next round, |
1489 | * but break unconditionally so unsplit data stops here. | 1496 | * but break unconditionally so unsplit data stops here. |
1490 | */ | 1497 | */ |
1491 | (*split_start)++; | 1498 | state->split_start++; |
1492 | break; | 1499 | break; |
1493 | case 9: | 1500 | case 9: |
1494 | if (dev->wiphy.extended_capabilities && | 1501 | if (dev->wiphy.extended_capabilities && |
@@ -1507,7 +1514,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1507 | goto nla_put_failure; | 1514 | goto nla_put_failure; |
1508 | 1515 | ||
1509 | /* done */ | 1516 | /* done */ |
1510 | *split_start = 0; | 1517 | state->split_start = 0; |
1511 | break; | 1518 | break; |
1512 | } | 1519 | } |
1513 | return genlmsg_end(msg, hdr); | 1520 | return genlmsg_end(msg, hdr); |
@@ -1517,67 +1524,78 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1517 | return -EMSGSIZE; | 1524 | return -EMSGSIZE; |
1518 | } | 1525 | } |
1519 | 1526 | ||
1527 | static int nl80211_dump_wiphy_parse(struct sk_buff *skb, | ||
1528 | struct netlink_callback *cb, | ||
1529 | struct nl80211_dump_wiphy_state *state) | ||
1530 | { | ||
1531 | struct nlattr **tb = nl80211_fam.attrbuf; | ||
1532 | int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | ||
1533 | tb, nl80211_fam.maxattr, nl80211_policy); | ||
1534 | /* ignore parse errors for backward compatibility */ | ||
1535 | if (ret) | ||
1536 | return 0; | ||
1537 | |||
1538 | state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; | ||
1539 | if (tb[NL80211_ATTR_WIPHY]) | ||
1540 | state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); | ||
1541 | if (tb[NL80211_ATTR_WDEV]) | ||
1542 | state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32; | ||
1543 | if (tb[NL80211_ATTR_IFINDEX]) { | ||
1544 | struct net_device *netdev; | ||
1545 | struct cfg80211_registered_device *rdev; | ||
1546 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); | ||
1547 | |||
1548 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | ||
1549 | if (!netdev) | ||
1550 | return -ENODEV; | ||
1551 | if (netdev->ieee80211_ptr) { | ||
1552 | rdev = wiphy_to_dev( | ||
1553 | netdev->ieee80211_ptr->wiphy); | ||
1554 | state->filter_wiphy = rdev->wiphy_idx; | ||
1555 | } | ||
1556 | dev_put(netdev); | ||
1557 | } | ||
1558 | |||
1559 | return 0; | ||
1560 | } | ||
1561 | |||
1520 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | 1562 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) |
1521 | { | 1563 | { |
1522 | int idx = 0, ret; | 1564 | int idx = 0, ret; |
1523 | int start = cb->args[0]; | 1565 | struct nl80211_dump_wiphy_state *state = (void *)cb->args[0]; |
1524 | struct cfg80211_registered_device *dev; | 1566 | struct cfg80211_registered_device *dev; |
1525 | s64 filter_wiphy = -1; | ||
1526 | bool split = false; | ||
1527 | struct nlattr **tb; | ||
1528 | int res; | ||
1529 | |||
1530 | /* will be zeroed in nlmsg_parse() */ | ||
1531 | tb = kmalloc(sizeof(*tb) * (NL80211_ATTR_MAX + 1), GFP_KERNEL); | ||
1532 | if (!tb) | ||
1533 | return -ENOMEM; | ||
1534 | 1567 | ||
1535 | rtnl_lock(); | 1568 | rtnl_lock(); |
1536 | 1569 | if (!state) { | |
1537 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 1570 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
1538 | tb, NL80211_ATTR_MAX, nl80211_policy); | 1571 | if (!state) { |
1539 | if (res == 0) { | 1572 | rtnl_unlock(); |
1540 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; | 1573 | return -ENOMEM; |
1541 | if (tb[NL80211_ATTR_WIPHY]) | ||
1542 | filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); | ||
1543 | if (tb[NL80211_ATTR_WDEV]) | ||
1544 | filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32; | ||
1545 | if (tb[NL80211_ATTR_IFINDEX]) { | ||
1546 | struct net_device *netdev; | ||
1547 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); | ||
1548 | |||
1549 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | ||
1550 | if (!netdev) { | ||
1551 | rtnl_unlock(); | ||
1552 | kfree(tb); | ||
1553 | return -ENODEV; | ||
1554 | } | ||
1555 | if (netdev->ieee80211_ptr) { | ||
1556 | dev = wiphy_to_dev( | ||
1557 | netdev->ieee80211_ptr->wiphy); | ||
1558 | filter_wiphy = dev->wiphy_idx; | ||
1559 | } | ||
1560 | dev_put(netdev); | ||
1561 | } | 1574 | } |
1575 | state->filter_wiphy = -1; | ||
1576 | ret = nl80211_dump_wiphy_parse(skb, cb, state); | ||
1577 | if (ret) { | ||
1578 | kfree(state); | ||
1579 | rtnl_unlock(); | ||
1580 | return ret; | ||
1581 | } | ||
1582 | cb->args[0] = (long)state; | ||
1562 | } | 1583 | } |
1563 | kfree(tb); | ||
1564 | 1584 | ||
1565 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1585 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { |
1566 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1586 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) |
1567 | continue; | 1587 | continue; |
1568 | if (++idx <= start) | 1588 | if (++idx <= state->start) |
1569 | continue; | 1589 | continue; |
1570 | if (filter_wiphy != -1 && dev->wiphy_idx != filter_wiphy) | 1590 | if (state->filter_wiphy != -1 && |
1591 | state->filter_wiphy != dev->wiphy_idx) | ||
1571 | continue; | 1592 | continue; |
1572 | /* attempt to fit multiple wiphy data chunks into the skb */ | 1593 | /* attempt to fit multiple wiphy data chunks into the skb */ |
1573 | do { | 1594 | do { |
1574 | ret = nl80211_send_wiphy(dev, skb, | 1595 | ret = nl80211_send_wiphy(dev, skb, |
1575 | NETLINK_CB(cb->skb).portid, | 1596 | NETLINK_CB(cb->skb).portid, |
1576 | cb->nlh->nlmsg_seq, | 1597 | cb->nlh->nlmsg_seq, |
1577 | NLM_F_MULTI, | 1598 | NLM_F_MULTI, state); |
1578 | split, &cb->args[1], | ||
1579 | &cb->args[2], | ||
1580 | &cb->args[3]); | ||
1581 | if (ret < 0) { | 1599 | if (ret < 0) { |
1582 | /* | 1600 | /* |
1583 | * If sending the wiphy data didn't fit (ENOBUFS | 1601 | * If sending the wiphy data didn't fit (ENOBUFS |
@@ -1602,27 +1620,34 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1602 | idx--; | 1620 | idx--; |
1603 | break; | 1621 | break; |
1604 | } | 1622 | } |
1605 | } while (cb->args[1] > 0); | 1623 | } while (state->split_start > 0); |
1606 | break; | 1624 | break; |
1607 | } | 1625 | } |
1608 | rtnl_unlock(); | 1626 | rtnl_unlock(); |
1609 | 1627 | ||
1610 | cb->args[0] = idx; | 1628 | state->start = idx; |
1611 | 1629 | ||
1612 | return skb->len; | 1630 | return skb->len; |
1613 | } | 1631 | } |
1614 | 1632 | ||
1633 | static int nl80211_dump_wiphy_done(struct netlink_callback *cb) | ||
1634 | { | ||
1635 | kfree((void *)cb->args[0]); | ||
1636 | return 0; | ||
1637 | } | ||
1638 | |||
1615 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | 1639 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) |
1616 | { | 1640 | { |
1617 | struct sk_buff *msg; | 1641 | struct sk_buff *msg; |
1618 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1642 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1643 | struct nl80211_dump_wiphy_state state = {}; | ||
1619 | 1644 | ||
1620 | msg = nlmsg_new(4096, GFP_KERNEL); | 1645 | msg = nlmsg_new(4096, GFP_KERNEL); |
1621 | if (!msg) | 1646 | if (!msg) |
1622 | return -ENOMEM; | 1647 | return -ENOMEM; |
1623 | 1648 | ||
1624 | if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0, | 1649 | if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0, |
1625 | false, NULL, NULL, NULL) < 0) { | 1650 | &state) < 0) { |
1626 | nlmsg_free(msg); | 1651 | nlmsg_free(msg); |
1627 | return -ENOBUFS; | 1652 | return -ENOBUFS; |
1628 | } | 1653 | } |
@@ -1739,6 +1764,11 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, | |||
1739 | IEEE80211_CHAN_DISABLED)) | 1764 | IEEE80211_CHAN_DISABLED)) |
1740 | return -EINVAL; | 1765 | return -EINVAL; |
1741 | 1766 | ||
1767 | if ((chandef->width == NL80211_CHAN_WIDTH_5 || | ||
1768 | chandef->width == NL80211_CHAN_WIDTH_10) && | ||
1769 | !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) | ||
1770 | return -EINVAL; | ||
1771 | |||
1742 | return 0; | 1772 | return 0; |
1743 | } | 1773 | } |
1744 | 1774 | ||
@@ -2890,61 +2920,58 @@ static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info) | |||
2890 | return err; | 2920 | return err; |
2891 | } | 2921 | } |
2892 | 2922 | ||
2893 | static int nl80211_parse_beacon(struct genl_info *info, | 2923 | static int nl80211_parse_beacon(struct nlattr *attrs[], |
2894 | struct cfg80211_beacon_data *bcn) | 2924 | struct cfg80211_beacon_data *bcn) |
2895 | { | 2925 | { |
2896 | bool haveinfo = false; | 2926 | bool haveinfo = false; |
2897 | 2927 | ||
2898 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || | 2928 | if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) || |
2899 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || | 2929 | !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) || |
2900 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || | 2930 | !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) || |
2901 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) | 2931 | !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP])) |
2902 | return -EINVAL; | 2932 | return -EINVAL; |
2903 | 2933 | ||
2904 | memset(bcn, 0, sizeof(*bcn)); | 2934 | memset(bcn, 0, sizeof(*bcn)); |
2905 | 2935 | ||
2906 | if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { | 2936 | if (attrs[NL80211_ATTR_BEACON_HEAD]) { |
2907 | bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); | 2937 | bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]); |
2908 | bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); | 2938 | bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]); |
2909 | if (!bcn->head_len) | 2939 | if (!bcn->head_len) |
2910 | return -EINVAL; | 2940 | return -EINVAL; |
2911 | haveinfo = true; | 2941 | haveinfo = true; |
2912 | } | 2942 | } |
2913 | 2943 | ||
2914 | if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { | 2944 | if (attrs[NL80211_ATTR_BEACON_TAIL]) { |
2915 | bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); | 2945 | bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]); |
2916 | bcn->tail_len = | 2946 | bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]); |
2917 | nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); | ||
2918 | haveinfo = true; | 2947 | haveinfo = true; |
2919 | } | 2948 | } |
2920 | 2949 | ||
2921 | if (!haveinfo) | 2950 | if (!haveinfo) |
2922 | return -EINVAL; | 2951 | return -EINVAL; |
2923 | 2952 | ||
2924 | if (info->attrs[NL80211_ATTR_IE]) { | 2953 | if (attrs[NL80211_ATTR_IE]) { |
2925 | bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); | 2954 | bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]); |
2926 | bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 2955 | bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]); |
2927 | } | 2956 | } |
2928 | 2957 | ||
2929 | if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { | 2958 | if (attrs[NL80211_ATTR_IE_PROBE_RESP]) { |
2930 | bcn->proberesp_ies = | 2959 | bcn->proberesp_ies = |
2931 | nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | 2960 | nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]); |
2932 | bcn->proberesp_ies_len = | 2961 | bcn->proberesp_ies_len = |
2933 | nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | 2962 | nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]); |
2934 | } | 2963 | } |
2935 | 2964 | ||
2936 | if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { | 2965 | if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) { |
2937 | bcn->assocresp_ies = | 2966 | bcn->assocresp_ies = |
2938 | nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2967 | nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2939 | bcn->assocresp_ies_len = | 2968 | bcn->assocresp_ies_len = |
2940 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2969 | nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2941 | } | 2970 | } |
2942 | 2971 | ||
2943 | if (info->attrs[NL80211_ATTR_PROBE_RESP]) { | 2972 | if (attrs[NL80211_ATTR_PROBE_RESP]) { |
2944 | bcn->probe_resp = | 2973 | bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]); |
2945 | nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); | 2974 | bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]); |
2946 | bcn->probe_resp_len = | ||
2947 | nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]); | ||
2948 | } | 2975 | } |
2949 | 2976 | ||
2950 | return 0; | 2977 | return 0; |
@@ -3023,7 +3050,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
3023 | !info->attrs[NL80211_ATTR_BEACON_HEAD]) | 3050 | !info->attrs[NL80211_ATTR_BEACON_HEAD]) |
3024 | return -EINVAL; | 3051 | return -EINVAL; |
3025 | 3052 | ||
3026 | err = nl80211_parse_beacon(info, ¶ms.beacon); | 3053 | err = nl80211_parse_beacon(info->attrs, ¶ms.beacon); |
3027 | if (err) | 3054 | if (err) |
3028 | return err; | 3055 | return err; |
3029 | 3056 | ||
@@ -3175,7 +3202,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) | |||
3175 | if (!wdev->beacon_interval) | 3202 | if (!wdev->beacon_interval) |
3176 | return -EINVAL; | 3203 | return -EINVAL; |
3177 | 3204 | ||
3178 | err = nl80211_parse_beacon(info, ¶ms); | 3205 | err = nl80211_parse_beacon(info->attrs, ¶ms); |
3179 | if (err) | 3206 | if (err) |
3180 | return err; | 3207 | return err; |
3181 | 3208 | ||
@@ -6291,11 +6318,16 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
6291 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) | 6318 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) |
6292 | return -EINVAL; | 6319 | return -EINVAL; |
6293 | 6320 | ||
6294 | if (ibss.chandef.width > NL80211_CHAN_WIDTH_40) | 6321 | switch (ibss.chandef.width) { |
6295 | return -EINVAL; | 6322 | case NL80211_CHAN_WIDTH_20_NOHT: |
6296 | if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 6323 | break; |
6297 | !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) | 6324 | case NL80211_CHAN_WIDTH_20: |
6325 | case NL80211_CHAN_WIDTH_40: | ||
6326 | if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS) | ||
6327 | break; | ||
6328 | default: | ||
6298 | return -EINVAL; | 6329 | return -EINVAL; |
6330 | } | ||
6299 | 6331 | ||
6300 | ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; | 6332 | ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; |
6301 | ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; | 6333 | ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; |
@@ -8409,6 +8441,7 @@ static struct genl_ops nl80211_ops[] = { | |||
8409 | .cmd = NL80211_CMD_GET_WIPHY, | 8441 | .cmd = NL80211_CMD_GET_WIPHY, |
8410 | .doit = nl80211_get_wiphy, | 8442 | .doit = nl80211_get_wiphy, |
8411 | .dumpit = nl80211_dump_wiphy, | 8443 | .dumpit = nl80211_dump_wiphy, |
8444 | .done = nl80211_dump_wiphy_done, | ||
8412 | .policy = nl80211_policy, | 8445 | .policy = nl80211_policy, |
8413 | /* can be retrieved by unprivileged users */ | 8446 | /* can be retrieved by unprivileged users */ |
8414 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 8447 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
@@ -9029,13 +9062,13 @@ static struct genl_multicast_group nl80211_regulatory_mcgrp = { | |||
9029 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 9062 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) |
9030 | { | 9063 | { |
9031 | struct sk_buff *msg; | 9064 | struct sk_buff *msg; |
9065 | struct nl80211_dump_wiphy_state state = {}; | ||
9032 | 9066 | ||
9033 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 9067 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
9034 | if (!msg) | 9068 | if (!msg) |
9035 | return; | 9069 | return; |
9036 | 9070 | ||
9037 | if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, | 9071 | if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) { |
9038 | false, NULL, NULL, NULL) < 0) { | ||
9039 | nlmsg_free(msg); | 9072 | nlmsg_free(msg); |
9040 | return; | 9073 | return; |
9041 | } | 9074 | } |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index dd01b58fa78c..ae8c186b50d6 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -523,6 +523,7 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
523 | } | 523 | } |
524 | } | 524 | } |
525 | 525 | ||
526 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | ||
526 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 527 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
527 | struct ieee80211_channel *channel, | 528 | struct ieee80211_channel *channel, |
528 | const u8 *bssid, | 529 | const u8 *bssid, |
@@ -678,6 +679,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, | |||
678 | return true; | 679 | return true; |
679 | } | 680 | } |
680 | 681 | ||
682 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | ||
681 | static struct cfg80211_internal_bss * | 683 | static struct cfg80211_internal_bss * |
682 | cfg80211_bss_update(struct cfg80211_registered_device *dev, | 684 | cfg80211_bss_update(struct cfg80211_registered_device *dev, |
683 | struct cfg80211_internal_bss *tmp) | 685 | struct cfg80211_internal_bss *tmp) |
@@ -866,6 +868,7 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, | |||
866 | return channel; | 868 | return channel; |
867 | } | 869 | } |
868 | 870 | ||
871 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | ||
869 | struct cfg80211_bss* | 872 | struct cfg80211_bss* |
870 | cfg80211_inform_bss(struct wiphy *wiphy, | 873 | cfg80211_inform_bss(struct wiphy *wiphy, |
871 | struct ieee80211_channel *channel, | 874 | struct ieee80211_channel *channel, |
@@ -923,6 +926,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, | |||
923 | } | 926 | } |
924 | EXPORT_SYMBOL(cfg80211_inform_bss); | 927 | EXPORT_SYMBOL(cfg80211_inform_bss); |
925 | 928 | ||
929 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | ||
926 | struct cfg80211_bss * | 930 | struct cfg80211_bss * |
927 | cfg80211_inform_bss_frame(struct wiphy *wiphy, | 931 | cfg80211_inform_bss_frame(struct wiphy *wiphy, |
928 | struct ieee80211_channel *channel, | 932 | struct ieee80211_channel *channel, |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index ae7e2cbf45cb..1d3cfb1a3f28 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -239,6 +239,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
239 | rtnl_unlock(); | 239 | rtnl_unlock(); |
240 | } | 240 | } |
241 | 241 | ||
242 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | ||
242 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | 243 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) |
243 | { | 244 | { |
244 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 245 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
@@ -557,6 +558,7 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); | |||
557 | * SME event handling | 558 | * SME event handling |
558 | */ | 559 | */ |
559 | 560 | ||
561 | /* This method must consume bss one way or another */ | ||
560 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 562 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
561 | const u8 *req_ie, size_t req_ie_len, | 563 | const u8 *req_ie, size_t req_ie_len, |
562 | const u8 *resp_ie, size_t resp_ie_len, | 564 | const u8 *resp_ie, size_t resp_ie_len, |
@@ -572,8 +574,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
572 | ASSERT_WDEV_LOCK(wdev); | 574 | ASSERT_WDEV_LOCK(wdev); |
573 | 575 | ||
574 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && | 576 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && |
575 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) | 577 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) { |
578 | cfg80211_put_bss(wdev->wiphy, bss); | ||
576 | return; | 579 | return; |
580 | } | ||
577 | 581 | ||
578 | nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, | 582 | nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, |
579 | bssid, req_ie, req_ie_len, | 583 | bssid, req_ie, req_ie_len, |
@@ -615,19 +619,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
615 | kfree(wdev->connect_keys); | 619 | kfree(wdev->connect_keys); |
616 | wdev->connect_keys = NULL; | 620 | wdev->connect_keys = NULL; |
617 | wdev->ssid_len = 0; | 621 | wdev->ssid_len = 0; |
618 | cfg80211_put_bss(wdev->wiphy, bss); | 622 | if (bss) { |
623 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
624 | cfg80211_put_bss(wdev->wiphy, bss); | ||
625 | } | ||
619 | return; | 626 | return; |
620 | } | 627 | } |
621 | 628 | ||
622 | if (!bss) | 629 | if (!bss) { |
630 | WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect); | ||
623 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 631 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
624 | wdev->ssid, wdev->ssid_len, | 632 | wdev->ssid, wdev->ssid_len, |
625 | WLAN_CAPABILITY_ESS, | 633 | WLAN_CAPABILITY_ESS, |
626 | WLAN_CAPABILITY_ESS); | 634 | WLAN_CAPABILITY_ESS); |
627 | if (WARN_ON(!bss)) | 635 | if (WARN_ON(!bss)) |
628 | return; | 636 | return; |
637 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
638 | } | ||
629 | 639 | ||
630 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
631 | wdev->current_bss = bss_from_pub(bss); | 640 | wdev->current_bss = bss_from_pub(bss); |
632 | 641 | ||
633 | cfg80211_upload_connect_keys(wdev); | 642 | cfg80211_upload_connect_keys(wdev); |
@@ -691,6 +700,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
691 | } | 700 | } |
692 | EXPORT_SYMBOL(cfg80211_connect_result); | 701 | EXPORT_SYMBOL(cfg80211_connect_result); |
693 | 702 | ||
703 | /* Consumes bss object one way or another */ | ||
694 | void __cfg80211_roamed(struct wireless_dev *wdev, | 704 | void __cfg80211_roamed(struct wireless_dev *wdev, |
695 | struct cfg80211_bss *bss, | 705 | struct cfg80211_bss *bss, |
696 | const u8 *req_ie, size_t req_ie_len, | 706 | const u8 *req_ie, size_t req_ie_len, |
@@ -767,6 +777,7 @@ void cfg80211_roamed(struct net_device *dev, | |||
767 | } | 777 | } |
768 | EXPORT_SYMBOL(cfg80211_roamed); | 778 | EXPORT_SYMBOL(cfg80211_roamed); |
769 | 779 | ||
780 | /* Consumes bss object one way or another */ | ||
770 | void cfg80211_roamed_bss(struct net_device *dev, | 781 | void cfg80211_roamed_bss(struct net_device *dev, |
771 | struct cfg80211_bss *bss, const u8 *req_ie, | 782 | struct cfg80211_bss *bss, const u8 *req_ie, |
772 | size_t req_ie_len, const u8 *resp_ie, | 783 | size_t req_ie_len, const u8 *resp_ie, |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 360a42c6f694..a23253e06358 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -83,6 +83,7 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | #ifdef CONFIG_PM | ||
86 | static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) | 87 | static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) |
87 | { | 88 | { |
88 | struct wireless_dev *wdev; | 89 | struct wireless_dev *wdev; |
@@ -91,7 +92,6 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) | |||
91 | cfg80211_leave(rdev, wdev); | 92 | cfg80211_leave(rdev, wdev); |
92 | } | 93 | } |
93 | 94 | ||
94 | #ifdef CONFIG_PM | ||
95 | static int wiphy_suspend(struct device *dev, pm_message_t state) | 95 | static int wiphy_suspend(struct device *dev, pm_message_t state) |
96 | { | 96 | { |
97 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); | 97 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); |