aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-06-04 06:56:01 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-06-04 07:02:42 -0400
commit51217cee3a94d5409d6ee2ac090ae96bc9a06757 (patch)
tree373c5ebf9e87ef81feb1d02feaf06f673fcf9a13
parentff40b425f04144771920b79672d6691910c7def7 (diff)
parent99e94940697adec4f84758adb2db71f4a82c7ba5 (diff)
Merge remote-tracking branch 'wireless-next/master' into HEAD
Merge to get the wil6210 changes that a cfg80211 change needs. A conflict in drivers/net/wireless/ath/ath9k/init.c was just whitespace changes. Also fix a semantic conflict due to cw1200 using WoWLAN which I had modified in my tree. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/bcma/sprom.c71
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c418
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h59
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c47
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c168
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig12
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile21
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c69
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c29
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c24
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c54
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.c20
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.h235
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c175
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h32
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h27
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c2
-rw-r--r--drivers/net/wireless/cw1200/Kconfig45
-rw-r--r--drivers/net/wireless/cw1200/Makefile22
-rw-r--r--drivers/net/wireless/cw1200/bh.c616
-rw-r--r--drivers/net/wireless/cw1200/bh.h28
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h331
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c424
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c465
-rw-r--r--drivers/net/wireless/cw1200/debug.c658
-rw-r--r--drivers/net/wireless/cw1200/debug.h98
-rw-r--r--drivers/net/wireless/cw1200/fwio.c525
-rw-r--r--drivers/net/wireless/cw1200/fwio.h39
-rw-r--r--drivers/net/wireless/cw1200/hwbus.h33
-rw-r--r--drivers/net/wireless/cw1200/hwio.c311
-rw-r--r--drivers/net/wireless/cw1200/hwio.h247
-rw-r--r--drivers/net/wireless/cw1200/itp.c730
-rw-r--r--drivers/net/wireless/cw1200/itp.h144
-rw-r--r--drivers/net/wireless/cw1200/main.c633
-rw-r--r--drivers/net/wireless/cw1200/pm.c367
-rw-r--r--drivers/net/wireless/cw1200/pm.h43
-rw-r--r--drivers/net/wireless/cw1200/queue.c583
-rw-r--r--drivers/net/wireless/cw1200/queue.h116
-rw-r--r--drivers/net/wireless/cw1200/scan.c461
-rw-r--r--drivers/net/wireless/cw1200/scan.h56
-rw-r--r--drivers/net/wireless/cw1200/sta.c2406
-rw-r--r--drivers/net/wireless/cw1200/sta.h123
-rw-r--r--drivers/net/wireless/cw1200/txrx.c1474
-rw-r--r--drivers/net/wireless/cw1200/txrx.h106
-rw-r--r--drivers/net/wireless/cw1200/wsm.c1883
-rw-r--r--drivers/net/wireless/cw1200/wsm.h1879
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h21
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h57
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c107
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c20
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c14
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c45
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c427
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h260
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c42
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c244
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h197
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c212
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c183
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c509
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c48
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c31
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c50
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c32
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c8
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig4
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c77
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h17
-rw-r--r--drivers/net/wireless/mwifiex/init.c53
-rw-r--r--drivers/net/wireless/mwifiex/join.c5
-rw-r--r--drivers/net/wireless/mwifiex/main.c14
-rw-r--r--drivers/net/wireless/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c23
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c463
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h340
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c62
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c17
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c21
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c25
-rw-r--r--drivers/net/wireless/mwl8k.c11
-rw-r--r--drivers/net/wireless/p54/p54spi.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c782
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--include/linux/platform_data/net-cw1200.h81
-rw-r--r--include/linux/ssb/ssb_regs.h1
161 files changed, 19929 insertions, 1995 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 3d7782b9f90d..e5069c223391 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2299,6 +2299,11 @@ M: Jaya Kumar <jayakumar.alsa@gmail.com>
2299S: Maintained 2299S: Maintained
2300F: sound/pci/cs5535audio/ 2300F: sound/pci/cs5535audio/
2301 2301
2302CW1200 WLAN driver
2303M: Solomon Peachy <pizza@shaftnet.org>
2304S: Maintained
2305F: drivers/net/wireless/cw1200/
2306
2302CX18 VIDEO4LINUX DRIVER 2307CX18 VIDEO4LINUX DRIVER
2303M: Andy Walls <awalls@md.metrocast.net> 2308M: Andy Walls <awalls@md.metrocast.net>
2304L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 2309L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 8934298a638d..de15b4f4b237 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -72,12 +72,12 @@ fail:
72 * R/W ops. 72 * R/W ops.
73 **************************************************/ 73 **************************************************/
74 74
75static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom) 75static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
76 size_t words)
76{ 77{
77 int i; 78 int i;
78 for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++) 79 for (i = 0; i < words; i++)
79 sprom[i] = bcma_read16(bus->drv_cc.core, 80 sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
80 offset + (i * 2));
81} 81}
82 82
83/************************************************** 83/**************************************************
@@ -124,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 data)
124 return t[crc ^ data]; 124 return t[crc ^ data];
125} 125}
126 126
127static u8 bcma_sprom_crc(const u16 *sprom) 127static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
128{ 128{
129 int word; 129 int word;
130 u8 crc = 0xFF; 130 u8 crc = 0xFF;
131 131
132 for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) { 132 for (word = 0; word < words - 1; word++) {
133 crc = bcma_crc8(crc, sprom[word] & 0x00FF); 133 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
134 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8); 134 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
135 } 135 }
136 crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF); 136 crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
137 crc ^= 0xFF; 137 crc ^= 0xFF;
138 138
139 return crc; 139 return crc;
140} 140}
141 141
142static int bcma_sprom_check_crc(const u16 *sprom) 142static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
143{ 143{
144 u8 crc; 144 u8 crc;
145 u8 expected_crc; 145 u8 expected_crc;
146 u16 tmp; 146 u16 tmp;
147 147
148 crc = bcma_sprom_crc(sprom); 148 crc = bcma_sprom_crc(sprom, words);
149 tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC; 149 tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
150 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; 150 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
151 if (crc != expected_crc) 151 if (crc != expected_crc)
152 return -EPROTO; 152 return -EPROTO;
@@ -154,21 +154,25 @@ static int bcma_sprom_check_crc(const u16 *sprom)
154 return 0; 154 return 0;
155} 155}
156 156
157static int bcma_sprom_valid(const u16 *sprom) 157static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
158 size_t words)
158{ 159{
159 u16 revision; 160 u16 revision;
160 int err; 161 int err;
161 162
162 err = bcma_sprom_check_crc(sprom); 163 err = bcma_sprom_check_crc(sprom, words);
163 if (err) 164 if (err)
164 return err; 165 return err;
165 166
166 revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; 167 revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
167 if (revision != 8 && revision != 9) { 168 if (revision != 8 && revision != 9 && revision != 10) {
168 pr_err("Unsupported SPROM revision: %d\n", revision); 169 pr_err("Unsupported SPROM revision: %d\n", revision);
169 return -ENOENT; 170 return -ENOENT;
170 } 171 }
171 172
173 bus->sprom.revision = revision;
174 bcma_debug(bus, "Found SPROM revision %d\n", revision);
175
172 return 0; 176 return 0;
173} 177}
174 178
@@ -208,9 +212,6 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
208 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != 212 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
209 ARRAY_SIZE(bus->sprom.core_pwr_info)); 213 ARRAY_SIZE(bus->sprom.core_pwr_info));
210 214
211 bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
212 SSB_SPROM_REVISION_REV;
213
214 for (i = 0; i < 3; i++) { 215 for (i = 0; i < 3; i++) {
215 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; 216 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
216 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); 217 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
@@ -502,7 +503,6 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
502 case BCMA_CHIP_ID_BCM4331: 503 case BCMA_CHIP_ID_BCM4331:
503 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; 504 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
504 break; 505 break;
505
506 case BCMA_CHIP_ID_BCM43224: 506 case BCMA_CHIP_ID_BCM43224:
507 case BCMA_CHIP_ID_BCM43225: 507 case BCMA_CHIP_ID_BCM43225:
508 /* for these chips OTP is always available */ 508 /* for these chips OTP is always available */
@@ -550,7 +550,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
550{ 550{
551 u16 offset = BCMA_CC_SPROM; 551 u16 offset = BCMA_CC_SPROM;
552 u16 *sprom; 552 u16 *sprom;
553 int err = 0; 553 size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
554 SSB_SPROMSIZE_WORDS_R10, };
555 int i, err = 0;
554 556
555 if (!bus->drv_cc.core) 557 if (!bus->drv_cc.core)
556 return -EOPNOTSUPP; 558 return -EOPNOTSUPP;
@@ -579,32 +581,37 @@ int bcma_sprom_get(struct bcma_bus *bus)
579 } 581 }
580 } 582 }
581 583
582 sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
583 GFP_KERNEL);
584 if (!sprom)
585 return -ENOMEM;
586
587 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || 584 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
588 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) 585 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
589 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); 586 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
590 587
591 bcma_debug(bus, "SPROM offset 0x%x\n", offset); 588 bcma_debug(bus, "SPROM offset 0x%x\n", offset);
592 bcma_sprom_read(bus, offset, sprom); 589 for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
590 size_t words = sprom_sizes[i];
591
592 sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
593 if (!sprom)
594 return -ENOMEM;
595
596 bcma_sprom_read(bus, offset, sprom, words);
597 err = bcma_sprom_valid(bus, sprom, words);
598 if (!err)
599 break;
600
601 kfree(sprom);
602 }
593 603
594 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || 604 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
595 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) 605 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
596 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); 606 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
597 607
598 err = bcma_sprom_valid(sprom);
599 if (err) { 608 if (err) {
600 bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n"); 609 bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
601 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); 610 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
602 goto out; 611 } else {
612 bcma_sprom_extract_r8(bus, sprom);
613 kfree(sprom);
603 } 614 }
604 615
605 bcma_sprom_extract_r8(bus, sprom);
606
607out:
608 kfree(sprom);
609 return err; 616 return err;
610} 617}
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f8f0156dff4e..200020eb3005 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -280,5 +280,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig"
280source "drivers/net/wireless/ti/Kconfig" 280source "drivers/net/wireless/ti/Kconfig"
281source "drivers/net/wireless/zd1211rw/Kconfig" 281source "drivers/net/wireless/zd1211rw/Kconfig"
282source "drivers/net/wireless/mwifiex/Kconfig" 282source "drivers/net/wireless/mwifiex/Kconfig"
283source "drivers/net/wireless/cw1200/Kconfig"
283 284
284endif # WLAN 285endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 67156efe14c4..0fab227025be 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -57,3 +57,5 @@ obj-$(CONFIG_MWIFIEX) += mwifiex/
57 57
58obj-$(CONFIG_BRCMFMAC) += brcm80211/ 58obj-$(CONFIG_BRCMFMAC) += brcm80211/
59obj-$(CONFIG_BRCMSMAC) += brcm80211/ 59obj-$(CONFIG_BRCMSMAC) += brcm80211/
60
61obj-$(CONFIG_CW1200) += cw1200/
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 17507dc8a1e7..ec33c8007b29 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -84,14 +84,6 @@ config ATH9K_DFS_CERTIFIED
84 developed. At this point enabling this option won't do anything 84 developed. At this point enabling this option won't do anything
85 except increase code size. 85 except increase code size.
86 86
87config ATH9K_MAC_DEBUG
88 bool "Atheros MAC statistics"
89 depends on ATH9K_DEBUGFS
90 default y
91 ---help---
92 This option enables collection of statistics for Rx/Tx status
93 data and some other MAC related statistics
94
95config ATH9K_RATE_CONTROL 87config ATH9K_RATE_CONTROL
96 bool "Atheros ath9k rate control" 88 bool "Atheros ath9k rate control"
97 depends on ATH9K 89 depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 7ecd40f07a74..e91725bf401c 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -118,10 +118,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
118{ 118{
119 struct ar5416AniState *aniState; 119 struct ar5416AniState *aniState;
120 120
121 if (!DO_ANI(ah)) 121 if (!ah->curchan)
122 return; 122 return;
123 123
124 aniState = &ah->curchan->ani; 124 aniState = &ah->ani;
125 aniState->listenTime = 0; 125 aniState->listenTime = 0;
126 126
127 ENABLE_REGWRITE_BUFFER(ah); 127 ENABLE_REGWRITE_BUFFER(ah);
@@ -143,7 +143,7 @@ static void ath9k_ani_restart(struct ath_hw *ah)
143static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, 143static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
144 bool scan) 144 bool scan)
145{ 145{
146 struct ar5416AniState *aniState = &ah->curchan->ani; 146 struct ar5416AniState *aniState = &ah->ani;
147 struct ath_common *common = ath9k_hw_common(ah); 147 struct ath_common *common = ath9k_hw_common(ah);
148 const struct ani_ofdm_level_entry *entry_ofdm; 148 const struct ani_ofdm_level_entry *entry_ofdm;
149 const struct ani_cck_level_entry *entry_cck; 149 const struct ani_cck_level_entry *entry_cck;
@@ -195,10 +195,10 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
195{ 195{
196 struct ar5416AniState *aniState; 196 struct ar5416AniState *aniState;
197 197
198 if (!DO_ANI(ah)) 198 if (!ah->curchan)
199 return; 199 return;
200 200
201 aniState = &ah->curchan->ani; 201 aniState = &ah->ani;
202 202
203 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) 203 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
204 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); 204 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -210,7 +210,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
210static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, 210static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
211 bool scan) 211 bool scan)
212{ 212{
213 struct ar5416AniState *aniState = &ah->curchan->ani; 213 struct ar5416AniState *aniState = &ah->ani;
214 struct ath_common *common = ath9k_hw_common(ah); 214 struct ath_common *common = ath9k_hw_common(ah);
215 const struct ani_ofdm_level_entry *entry_ofdm; 215 const struct ani_ofdm_level_entry *entry_ofdm;
216 const struct ani_cck_level_entry *entry_cck; 216 const struct ani_cck_level_entry *entry_cck;
@@ -251,10 +251,10 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
251{ 251{
252 struct ar5416AniState *aniState; 252 struct ar5416AniState *aniState;
253 253
254 if (!DO_ANI(ah)) 254 if (!ah->curchan)
255 return; 255 return;
256 256
257 aniState = &ah->curchan->ani; 257 aniState = &ah->ani;
258 258
259 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) 259 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
260 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, 260 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -269,7 +269,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
269{ 269{
270 struct ar5416AniState *aniState; 270 struct ar5416AniState *aniState;
271 271
272 aniState = &ah->curchan->ani; 272 aniState = &ah->ani;
273 273
274 /* lower OFDM noise immunity */ 274 /* lower OFDM noise immunity */
275 if (aniState->ofdmNoiseImmunityLevel > 0 && 275 if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -292,12 +292,12 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
292 */ 292 */
293void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) 293void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
294{ 294{
295 struct ar5416AniState *aniState = &ah->curchan->ani; 295 struct ar5416AniState *aniState = &ah->ani;
296 struct ath9k_channel *chan = ah->curchan; 296 struct ath9k_channel *chan = ah->curchan;
297 struct ath_common *common = ath9k_hw_common(ah); 297 struct ath_common *common = ath9k_hw_common(ah);
298 int ofdm_nil, cck_nil; 298 int ofdm_nil, cck_nil;
299 299
300 if (!DO_ANI(ah)) 300 if (!ah->curchan)
301 return; 301 return;
302 302
303 BUG_ON(aniState == NULL); 303 BUG_ON(aniState == NULL);
@@ -380,7 +380,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
380static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) 380static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
381{ 381{
382 struct ath_common *common = ath9k_hw_common(ah); 382 struct ath_common *common = ath9k_hw_common(ah);
383 struct ar5416AniState *aniState = &ah->curchan->ani; 383 struct ar5416AniState *aniState = &ah->ani;
384 u32 phyCnt1, phyCnt2; 384 u32 phyCnt1, phyCnt2;
385 int32_t listenTime; 385 int32_t listenTime;
386 386
@@ -415,10 +415,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
415 struct ath_common *common = ath9k_hw_common(ah); 415 struct ath_common *common = ath9k_hw_common(ah);
416 u32 ofdmPhyErrRate, cckPhyErrRate; 416 u32 ofdmPhyErrRate, cckPhyErrRate;
417 417
418 if (!DO_ANI(ah)) 418 if (!ah->curchan)
419 return; 419 return;
420 420
421 aniState = &ah->curchan->ani; 421 aniState = &ah->ani;
422 if (!ath9k_hw_ani_read_counters(ah)) 422 if (!ath9k_hw_ani_read_counters(ah))
423 return; 423 return;
424 424
@@ -490,32 +490,22 @@ EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
490void ath9k_hw_ani_init(struct ath_hw *ah) 490void ath9k_hw_ani_init(struct ath_hw *ah)
491{ 491{
492 struct ath_common *common = ath9k_hw_common(ah); 492 struct ath_common *common = ath9k_hw_common(ah);
493 int i; 493 struct ar5416AniState *ani = &ah->ani;
494 494
495 ath_dbg(common, ANI, "Initialize ANI\n"); 495 ath_dbg(common, ANI, "Initialize ANI\n");
496 496
497 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; 497 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
498 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; 498 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
499
500 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; 499 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
501 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; 500 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
502 501
503 for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { 502 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
504 struct ath9k_channel *chan = &ah->channels[i]; 503 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
505 struct ar5416AniState *ani = &chan->ani; 504 ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
506 505 ani->ofdmsTurn = true;
507 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 506 ani->ofdmWeakSigDetect = true;
508 507 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
509 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 508 ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
510
511 ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
512
513 ani->ofdmsTurn = true;
514
515 ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
516 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
517 ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
518 }
519 509
520 /* 510 /*
521 * since we expect some ongoing maintenance on the tables, let's sanity 511 * since we expect some ongoing maintenance on the tables, let's sanity
@@ -524,9 +514,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
524 ah->aniperiod = ATH9K_ANI_PERIOD; 514 ah->aniperiod = ATH9K_ANI_PERIOD;
525 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL; 515 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
526 516
527 if (ah->config.enable_ani)
528 ah->proc_phyerr |= HAL_PROCESS_ANI;
529
530 ath9k_ani_restart(ah); 517 ath9k_ani_restart(ah);
531 ath9k_enable_mib_counters(ah); 518 ath9k_enable_mib_counters(ah);
532} 519}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index dddb1361039a..78b9fa9f6455 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -17,10 +17,6 @@
17#ifndef ANI_H 17#ifndef ANI_H
18#define ANI_H 18#define ANI_H
19 19
20#define HAL_PROCESS_ANI 0x00000001
21
22#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
23
24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) 20#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
25 21
26/* units are errors per second */ 22/* units are errors per second */
@@ -38,11 +34,7 @@
38#define ATH9K_ANI_CCK_TRIG_LOW 300 34#define ATH9K_ANI_CCK_TRIG_LOW 300
39 35
40#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 36#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
41#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
42#define ATH9K_ANI_CCK_WEAK_SIG_THR false
43
44#define ATH9K_ANI_SPUR_IMMUNE_LVL 3 37#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
45
46#define ATH9K_ANI_FIRSTEP_LVL 2 38#define ATH9K_ANI_FIRSTEP_LVL 2
47 39
48#define ATH9K_ANI_RSSI_THR_HIGH 40 40#define ATH9K_ANI_RSSI_THR_HIGH 40
@@ -111,7 +103,7 @@ struct ar5416AniState {
111 u8 mrcCCK; 103 u8 mrcCCK;
112 u8 spurImmunityLevel; 104 u8 spurImmunityLevel;
113 u8 firstepLevel; 105 u8 firstepLevel;
114 u8 ofdmWeakSigDetect; 106 bool ofdmWeakSigDetect;
115 u32 listenTime; 107 u32 listenTime;
116 u32 ofdmPhyErrCount; 108 u32 ofdmPhyErrCount;
117 u32 cckPhyErrCount; 109 u32 cckPhyErrCount;
@@ -119,8 +111,6 @@ struct ar5416AniState {
119}; 111};
120 112
121struct ar5416Stats { 113struct ar5416Stats {
122 u32 ast_ani_niup;
123 u32 ast_ani_nidown;
124 u32 ast_ani_spurup; 114 u32 ast_ani_spurup;
125 u32 ast_ani_spurdown; 115 u32 ast_ani_spurdown;
126 u32 ast_ani_ofdmon; 116 u32 ast_ani_ofdmon;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 391da5ad6a99..d1acfe98918a 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -931,7 +931,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
931{ 931{
932 struct ath_common *common = ath9k_hw_common(ah); 932 struct ath_common *common = ath9k_hw_common(ah);
933 struct ath9k_channel *chan = ah->curchan; 933 struct ath9k_channel *chan = ah->curchan;
934 struct ar5416AniState *aniState = &chan->ani; 934 struct ar5416AniState *aniState = &ah->ani;
935 s32 value, value2; 935 s32 value, value2;
936 936
937 switch (cmd & ah->ani_function) { 937 switch (cmd & ah->ani_function) {
@@ -1207,7 +1207,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1207{ 1207{
1208 struct ath_common *common = ath9k_hw_common(ah); 1208 struct ath_common *common = ath9k_hw_common(ah);
1209 struct ath9k_channel *chan = ah->curchan; 1209 struct ath9k_channel *chan = ah->curchan;
1210 struct ar5416AniState *aniState = &chan->ani; 1210 struct ar5416AniState *aniState = &ah->ani;
1211 struct ath9k_ani_default *iniDef; 1211 struct ath9k_ani_default *iniDef;
1212 u32 val; 1212 u32 val;
1213 1213
@@ -1251,7 +1251,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1251 /* these levels just got reset to defaults by the INI */ 1251 /* these levels just got reset to defaults by the INI */
1252 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1252 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
1253 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1253 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
1254 aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; 1254 aniState->ofdmWeakSigDetect = true;
1255 aniState->mrcCCK = false; /* not available on pre AR9003 */ 1255 aniState->mrcCCK = false; /* not available on pre AR9003 */
1256} 1256}
1257 1257
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 830daa12feb6..8dc2d089cdef 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
38 else 38 else
39 INIT_INI_ARRAY(&ah->iniPcieSerdes, 39 INIT_INI_ARRAY(&ah->iniPcieSerdes,
40 ar9280PciePhy_clkreq_always_on_L1_9280); 40 ar9280PciePhy_clkreq_always_on_L1_9280);
41#ifdef CONFIG_PM_SLEEP
42 INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
43 ar9280PciePhy_awow);
44#endif
45 41
46 if (AR_SREV_9287_11_OR_LATER(ah)) { 42 if (AR_SREV_9287_11_OR_LATER(ah)) {
47 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1); 43 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index beb6162cf97c..4d18c66a6790 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
925 {0x00004044, 0x00000000}, 925 {0x00004044, 0x00000000},
926}; 926};
927 927
928static const u32 ar9280PciePhy_awow[][2] = {
929 /* Addr allmodes */
930 {0x00004040, 0x9248fd00},
931 {0x00004040, 0x24924924},
932 {0x00004040, 0xa8000019},
933 {0x00004040, 0x13160820},
934 {0x00004040, 0xe5980560},
935 {0x00004040, 0xc01dcffd},
936 {0x00004040, 0x1aaabe41},
937 {0x00004040, 0xbe105554},
938 {0x00004040, 0x00043007},
939 {0x00004044, 0x00000000},
940};
941
942static const u32 ar9285Modes_9285_1_2[][5] = { 928static const u32 ar9285Modes_9285_1_2[][5] = {
943 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 929 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
944 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 930 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 301bf72c53bf..5163abd3937c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -469,6 +469,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
469 469
470 rxs->rs_status = 0; 470 rxs->rs_status = 0;
471 rxs->rs_flags = 0; 471 rxs->rs_flags = 0;
472 rxs->flag = 0;
472 473
473 rxs->rs_datalen = rxsp->status2 & AR_DataLen; 474 rxs->rs_datalen = rxsp->status2 & AR_DataLen;
474 rxs->rs_tstamp = rxsp->status3; 475 rxs->rs_tstamp = rxsp->status3;
@@ -493,8 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
493 rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0; 494 rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
494 rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0; 495 rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
495 rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7); 496 rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
496 rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0; 497 rxs->flag |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
497 rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0; 498 rxs->flag |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
498 499
499 rxs->evm0 = rxsp->status6; 500 rxs->evm0 = rxsp->status6;
500 rxs->evm1 = rxsp->status7; 501 rxs->evm1 = rxsp->status7;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 09c1f9da67a0..6343cc91953e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -454,6 +454,8 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
454 if (accum_cnt <= thresh_accum_cnt) 454 if (accum_cnt <= thresh_accum_cnt)
455 continue; 455 continue;
456 456
457 max_index++;
458
457 /* sum(tx amplitude) */ 459 /* sum(tx amplitude) */
458 accum_tx = ((data_L[i] >> 16) & 0xffff) | 460 accum_tx = ((data_L[i] >> 16) & 0xffff) |
459 ((data_U[i] & 0x7ff) << 16); 461 ((data_U[i] & 0x7ff) << 16);
@@ -468,20 +470,21 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
468 470
469 accum_tx <<= scale_factor; 471 accum_tx <<= scale_factor;
470 accum_rx <<= scale_factor; 472 accum_rx <<= scale_factor;
471 x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >> 473 x_est[max_index] =
472 scale_factor; 474 (((accum_tx + accum_cnt) / accum_cnt) + 32) >>
475 scale_factor;
473 476
474 Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >> 477 Y[max_index] =
478 ((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
475 scale_factor) + 479 scale_factor) +
476 (1 << scale_factor) * max_index + 16; 480 (1 << scale_factor) * i + 16;
477 481
478 if (accum_ang >= (1 << 26)) 482 if (accum_ang >= (1 << 26))
479 accum_ang -= 1 << 27; 483 accum_ang -= 1 << 27;
480 484
481 theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) / 485 theta[max_index] =
482 accum_cnt; 486 ((accum_ang * (1 << scale_factor)) + accum_cnt) /
483 487 accum_cnt;
484 max_index++;
485 } 488 }
486 489
487 /* 490 /*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 2bf6548dd143..0d053503b8bf 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -904,7 +904,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
904{ 904{
905 struct ath_common *common = ath9k_hw_common(ah); 905 struct ath_common *common = ath9k_hw_common(ah);
906 struct ath9k_channel *chan = ah->curchan; 906 struct ath9k_channel *chan = ah->curchan;
907 struct ar5416AniState *aniState = &chan->ani; 907 struct ar5416AniState *aniState = &ah->ani;
908 s32 value, value2; 908 s32 value, value2;
909 909
910 switch (cmd & ah->ani_function) { 910 switch (cmd & ah->ani_function) {
@@ -1172,7 +1172,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1172 struct ath9k_ani_default *iniDef; 1172 struct ath9k_ani_default *iniDef;
1173 u32 val; 1173 u32 val;
1174 1174
1175 aniState = &ah->curchan->ani; 1175 aniState = &ah->ani;
1176 iniDef = &aniState->iniDef; 1176 iniDef = &aniState->iniDef;
1177 1177
1178 ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", 1178 ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
@@ -1213,7 +1213,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1213 /* these levels just got reset to defaults by the INI */ 1213 /* these levels just got reset to defaults by the INI */
1214 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1214 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
1215 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1215 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
1216 aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; 1216 aniState->ofdmWeakSigDetect = true;
1217 aniState->mrcCCK = true; 1217 aniState->mrcCCK = true;
1218} 1218}
1219 1219
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8a1888d02070..579ed9c40b3f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -646,6 +646,7 @@ enum sc_op_flags {
646 SC_OP_ANI_RUN, 646 SC_OP_ANI_RUN,
647 SC_OP_PRIM_STA_VIF, 647 SC_OP_PRIM_STA_VIF,
648 SC_OP_HW_RESET, 648 SC_OP_HW_RESET,
649 SC_OP_SCANNING,
649}; 650};
650 651
651/* Powersave flags */ 652/* Powersave flags */
@@ -759,7 +760,6 @@ struct ath_softc {
759 struct rchan *rfs_chan_spec_scan; 760 struct rchan *rfs_chan_spec_scan;
760 enum spectral_mode spectral_mode; 761 enum spectral_mode spectral_mode;
761 struct ath_spec_scan spec_config; 762 struct ath_spec_scan spec_config;
762 int scanning;
763 763
764#ifdef CONFIG_PM_SLEEP 764#ifdef CONFIG_PM_SLEEP
765 atomic_t wow_got_bmiss_intr; 765 atomic_t wow_got_bmiss_intr;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 2ff570f7f8ff..fd1eebab8647 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -39,7 +39,8 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
39 39
40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
41 41
42 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 42 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
43 sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
43 /* Always burst out beacon and CAB traffic. */ 44 /* Always burst out beacon and CAB traffic. */
44 qi.tqi_aifs = 1; 45 qi.tqi_aifs = 1;
45 qi.tqi_cwmin = 0; 46 qi.tqi_cwmin = 0;
@@ -273,7 +274,8 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
273 u64 tsf; 274 u64 tsf;
274 int slot; 275 int slot;
275 276
276 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) { 277 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP &&
278 sc->sc_ah->opmode != NL80211_IFTYPE_MESH_POINT) {
277 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n", 279 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
278 ath9k_hw_gettsf64(sc->sc_ah)); 280 ath9k_hw_gettsf64(sc->sc_ah));
279 return 0; 281 return 0;
@@ -765,10 +767,10 @@ void ath9k_set_beacon(struct ath_softc *sc)
765 767
766 switch (sc->sc_ah->opmode) { 768 switch (sc->sc_ah->opmode) {
767 case NL80211_IFTYPE_AP: 769 case NL80211_IFTYPE_AP:
770 case NL80211_IFTYPE_MESH_POINT:
768 ath9k_beacon_config_ap(sc, cur_conf); 771 ath9k_beacon_config_ap(sc, cur_conf);
769 break; 772 break;
770 case NL80211_IFTYPE_ADHOC: 773 case NL80211_IFTYPE_ADHOC:
771 case NL80211_IFTYPE_MESH_POINT:
772 ath9k_beacon_config_adhoc(sc, cur_conf); 774 ath9k_beacon_config_adhoc(sc, cur_conf);
773 break; 775 break;
774 case NL80211_IFTYPE_STATION: 776 case NL80211_IFTYPE_STATION:
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index e6307b86363a..7852f6e59964 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -173,25 +173,69 @@ static const struct file_operations fops_rx_chainmask = {
173 .llseek = default_llseek, 173 .llseek = default_llseek,
174}; 174};
175 175
176static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf, 176static ssize_t read_file_ani(struct file *file, char __user *user_buf,
177 size_t count, loff_t *ppos) 177 size_t count, loff_t *ppos)
178{ 178{
179 struct ath_softc *sc = file->private_data; 179 struct ath_softc *sc = file->private_data;
180 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 180 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
181 char buf[32]; 181 struct ath_hw *ah = sc->sc_ah;
182 unsigned int len; 182 unsigned int len = 0, size = 1024;
183 ssize_t retval = 0;
184 char *buf;
183 185
184 len = sprintf(buf, "%d\n", common->disable_ani); 186 buf = kzalloc(size, GFP_KERNEL);
185 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 187 if (buf == NULL)
188 return -ENOMEM;
189
190 if (common->disable_ani) {
191 len += snprintf(buf + len, size - len, "%s: %s\n",
192 "ANI", "DISABLED");
193 goto exit;
194 }
195
196 len += snprintf(buf + len, size - len, "%15s: %s\n",
197 "ANI", "ENABLED");
198 len += snprintf(buf + len, size - len, "%15s: %u\n",
199 "ANI RESET", ah->stats.ast_ani_reset);
200 len += snprintf(buf + len, size - len, "%15s: %u\n",
201 "SPUR UP", ah->stats.ast_ani_spurup);
202 len += snprintf(buf + len, size - len, "%15s: %u\n",
203 "SPUR DOWN", ah->stats.ast_ani_spurup);
204 len += snprintf(buf + len, size - len, "%15s: %u\n",
205 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
206 len += snprintf(buf + len, size - len, "%15s: %u\n",
207 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
208 len += snprintf(buf + len, size - len, "%15s: %u\n",
209 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
210 len += snprintf(buf + len, size - len, "%15s: %u\n",
211 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
212 len += snprintf(buf + len, size - len, "%15s: %u\n",
213 "FIR-STEP UP", ah->stats.ast_ani_stepup);
214 len += snprintf(buf + len, size - len, "%15s: %u\n",
215 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
216 len += snprintf(buf + len, size - len, "%15s: %u\n",
217 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
218 len += snprintf(buf + len, size - len, "%15s: %u\n",
219 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
220 len += snprintf(buf + len, size - len, "%15s: %u\n",
221 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
222exit:
223 if (len > size)
224 len = size;
225
226 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
227 kfree(buf);
228
229 return retval;
186} 230}
187 231
188static ssize_t write_file_disable_ani(struct file *file, 232static ssize_t write_file_ani(struct file *file,
189 const char __user *user_buf, 233 const char __user *user_buf,
190 size_t count, loff_t *ppos) 234 size_t count, loff_t *ppos)
191{ 235{
192 struct ath_softc *sc = file->private_data; 236 struct ath_softc *sc = file->private_data;
193 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 237 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
194 unsigned long disable_ani; 238 unsigned long ani;
195 char buf[32]; 239 char buf[32];
196 ssize_t len; 240 ssize_t len;
197 241
@@ -200,12 +244,15 @@ static ssize_t write_file_disable_ani(struct file *file,
200 return -EFAULT; 244 return -EFAULT;
201 245
202 buf[len] = '\0'; 246 buf[len] = '\0';
203 if (strict_strtoul(buf, 0, &disable_ani)) 247 if (strict_strtoul(buf, 0, &ani))
204 return -EINVAL; 248 return -EINVAL;
205 249
206 common->disable_ani = !!disable_ani; 250 if (ani < 0 || ani > 1)
251 return -EINVAL;
252
253 common->disable_ani = !ani;
207 254
208 if (disable_ani) { 255 if (common->disable_ani) {
209 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); 256 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
210 ath_stop_ani(sc); 257 ath_stop_ani(sc);
211 } else { 258 } else {
@@ -215,9 +262,9 @@ static ssize_t write_file_disable_ani(struct file *file,
215 return count; 262 return count;
216} 263}
217 264
218static const struct file_operations fops_disable_ani = { 265static const struct file_operations fops_ani = {
219 .read = read_file_disable_ani, 266 .read = read_file_ani,
220 .write = write_file_disable_ani, 267 .write = write_file_ani,
221 .open = simple_open, 268 .open = simple_open,
222 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
223 .llseek = default_llseek, 270 .llseek = default_llseek,
@@ -738,8 +785,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
738 struct ath_tx_status *ts, struct ath_txq *txq, 785 struct ath_tx_status *ts, struct ath_txq *txq,
739 unsigned int flags) 786 unsigned int flags)
740{ 787{
741#define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\
742 [sc->debug.tsidx].c)
743 int qnum = txq->axq_qnum; 788 int qnum = txq->axq_qnum;
744 789
745 TX_STAT_INC(qnum, tx_pkts_all); 790 TX_STAT_INC(qnum, tx_pkts_all);
@@ -771,37 +816,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
771 TX_STAT_INC(qnum, data_underrun); 816 TX_STAT_INC(qnum, data_underrun);
772 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) 817 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
773 TX_STAT_INC(qnum, delim_underrun); 818 TX_STAT_INC(qnum, delim_underrun);
774
775#ifdef CONFIG_ATH9K_MAC_DEBUG
776 spin_lock(&sc->debug.samp_lock);
777 TX_SAMP_DBG(jiffies) = jiffies;
778 TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
779 TX_SAMP_DBG(rssi_ctl1) = ts->ts_rssi_ctl1;
780 TX_SAMP_DBG(rssi_ctl2) = ts->ts_rssi_ctl2;
781 TX_SAMP_DBG(rssi_ext0) = ts->ts_rssi_ext0;
782 TX_SAMP_DBG(rssi_ext1) = ts->ts_rssi_ext1;
783 TX_SAMP_DBG(rssi_ext2) = ts->ts_rssi_ext2;
784 TX_SAMP_DBG(rateindex) = ts->ts_rateindex;
785 TX_SAMP_DBG(isok) = !!(ts->ts_status & ATH9K_TXERR_MASK);
786 TX_SAMP_DBG(rts_fail_cnt) = ts->ts_shortretry;
787 TX_SAMP_DBG(data_fail_cnt) = ts->ts_longretry;
788 TX_SAMP_DBG(rssi) = ts->ts_rssi;
789 TX_SAMP_DBG(tid) = ts->tid;
790 TX_SAMP_DBG(qid) = ts->qid;
791
792 if (ts->ts_flags & ATH9K_TX_BA) {
793 TX_SAMP_DBG(ba_low) = ts->ba_low;
794 TX_SAMP_DBG(ba_high) = ts->ba_high;
795 } else {
796 TX_SAMP_DBG(ba_low) = 0;
797 TX_SAMP_DBG(ba_high) = 0;
798 }
799
800 sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
801 spin_unlock(&sc->debug.samp_lock);
802#endif
803
804#undef TX_SAMP_DBG
805} 819}
806 820
807static const struct file_operations fops_xmit = { 821static const struct file_operations fops_xmit = {
@@ -915,8 +929,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
915void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 929void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
916{ 930{
917#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 931#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
918#define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
919 [sc->debug.rsidx].c)
920 932
921 RX_STAT_INC(rx_pkts_all); 933 RX_STAT_INC(rx_pkts_all);
922 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; 934 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
@@ -940,27 +952,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
940 RX_PHY_ERR_INC(rs->rs_phyerr); 952 RX_PHY_ERR_INC(rs->rs_phyerr);
941 } 953 }
942 954
943#ifdef CONFIG_ATH9K_MAC_DEBUG
944 spin_lock(&sc->debug.samp_lock);
945 RX_SAMP_DBG(jiffies) = jiffies;
946 RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
947 RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
948 RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
949 RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
950 RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
951 RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
952 RX_SAMP_DBG(antenna) = rs->rs_antenna;
953 RX_SAMP_DBG(rssi) = rs->rs_rssi;
954 RX_SAMP_DBG(rate) = rs->rs_rate;
955 RX_SAMP_DBG(is_mybeacon) = rs->is_mybeacon;
956
957 sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
958 spin_unlock(&sc->debug.samp_lock);
959
960#endif
961
962#undef RX_PHY_ERR_INC 955#undef RX_PHY_ERR_INC
963#undef RX_SAMP_DBG
964} 956}
965 957
966static const struct file_operations fops_recv = { 958static const struct file_operations fops_recv = {
@@ -1485,283 +1477,6 @@ static const struct file_operations fops_modal_eeprom = {
1485 .llseek = default_llseek, 1477 .llseek = default_llseek,
1486}; 1478};
1487 1479
1488#ifdef CONFIG_ATH9K_MAC_DEBUG
1489
1490void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
1491{
1492#define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
1493 struct ath_hw *ah = sc->sc_ah;
1494 struct ath_common *common = ath9k_hw_common(ah);
1495 unsigned long flags;
1496 int i;
1497
1498 ath9k_ps_wakeup(sc);
1499
1500 spin_lock_bh(&sc->debug.samp_lock);
1501
1502 spin_lock_irqsave(&common->cc_lock, flags);
1503 ath_hw_cycle_counters_update(common);
1504
1505 ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles;
1506 ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy;
1507 ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame;
1508 ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame;
1509 spin_unlock_irqrestore(&common->cc_lock, flags);
1510
1511 ATH_SAMP_DBG(noise) = ah->noise;
1512
1513 REG_WRITE_D(ah, AR_MACMISC,
1514 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1515 (AR_MACMISC_MISC_OBS_BUS_1 <<
1516 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1517
1518 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1519 ATH_SAMP_DBG(dma_dbg_reg_vals[i]) = REG_READ_D(ah,
1520 AR_DMADBG_0 + (i * sizeof(u32)));
1521
1522 ATH_SAMP_DBG(pcu_obs) = REG_READ_D(ah, AR_OBS_BUS_1);
1523 ATH_SAMP_DBG(pcu_cr) = REG_READ_D(ah, AR_CR);
1524
1525 memcpy(ATH_SAMP_DBG(nfCalHist), sc->caldata.nfCalHist,
1526 sizeof(ATH_SAMP_DBG(nfCalHist)));
1527
1528 sc->debug.sampidx = (sc->debug.sampidx + 1) % ATH_DBG_MAX_SAMPLES;
1529 spin_unlock_bh(&sc->debug.samp_lock);
1530 ath9k_ps_restore(sc);
1531
1532#undef ATH_SAMP_DBG
1533}
1534
1535static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
1536{
1537#define ATH_SAMP_DBG(c) bb_mac_samp[sampidx].c
1538 struct ath_softc *sc = inode->i_private;
1539 struct ath_hw *ah = sc->sc_ah;
1540 struct ath_common *common = ath9k_hw_common(ah);
1541 struct ieee80211_conf *conf = &common->hw->conf;
1542 struct ath_dbg_bb_mac_samp *bb_mac_samp;
1543 struct ath9k_nfcal_hist *h;
1544 int i, j, qcuOffset = 0, dcuOffset = 0;
1545 u32 *qcuBase, *dcuBase, size = 30000, len = 0;
1546 u32 sampidx = 0;
1547 u8 *buf;
1548 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
1549 u8 nread;
1550
1551 if (test_bit(SC_OP_INVALID, &sc->sc_flags))
1552 return -EAGAIN;
1553
1554 buf = vmalloc(size);
1555 if (!buf)
1556 return -ENOMEM;
1557 bb_mac_samp = vmalloc(sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
1558 if (!bb_mac_samp) {
1559 vfree(buf);
1560 return -ENOMEM;
1561 }
1562 /* Account the current state too */
1563 ath9k_debug_samp_bb_mac(sc);
1564
1565 spin_lock_bh(&sc->debug.samp_lock);
1566 memcpy(bb_mac_samp, sc->debug.bb_mac_samp,
1567 sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
1568 len += snprintf(buf + len, size - len,
1569 "Current Sample Index: %d\n", sc->debug.sampidx);
1570 spin_unlock_bh(&sc->debug.samp_lock);
1571
1572 len += snprintf(buf + len, size - len,
1573 "Raw DMA Debug Dump:\n");
1574 len += snprintf(buf + len, size - len, "Sample |\t");
1575 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1576 len += snprintf(buf + len, size - len, " DMA Reg%d |\t", i);
1577 len += snprintf(buf + len, size - len, "\n");
1578
1579 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1580 len += snprintf(buf + len, size - len, "%d\t", sampidx);
1581
1582 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1583 len += snprintf(buf + len, size - len, " %08x\t",
1584 ATH_SAMP_DBG(dma_dbg_reg_vals[i]));
1585 len += snprintf(buf + len, size - len, "\n");
1586 }
1587 len += snprintf(buf + len, size - len, "\n");
1588
1589 len += snprintf(buf + len, size - len,
1590 "Sample Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1591 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1592 qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
1593 dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
1594
1595 for (i = 0; i < ATH9K_NUM_QUEUES; i++,
1596 qcuOffset += 4, dcuOffset += 5) {
1597 if (i == 8) {
1598 qcuOffset = 0;
1599 qcuBase++;
1600 }
1601
1602 if (i == 6) {
1603 dcuOffset = 0;
1604 dcuBase++;
1605 }
1606 if (!sc->debug.stats.txstats[i].queued)
1607 continue;
1608
1609 len += snprintf(buf + len, size - len,
1610 "%4d %7d %2x %1x %2x %2x\n",
1611 sampidx, i,
1612 (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1613 (*qcuBase & (0x8 << qcuOffset)) >>
1614 (qcuOffset + 3),
1615 ATH_SAMP_DBG(dma_dbg_reg_vals[2]) &
1616 (0x7 << (i * 3)) >> (i * 3),
1617 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1618 }
1619 len += snprintf(buf + len, size - len, "\n");
1620 }
1621 len += snprintf(buf + len, size - len,
1622 "samp qcu_sh qcu_fh qcu_comp dcu_comp dcu_arb dcu_fp "
1623 "ch_idle_dur ch_idle_dur_val txfifo_val0 txfifo_val1 "
1624 "txfifo_dcu0 txfifo_dcu1 pcu_obs AR_CR\n");
1625
1626 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1627 qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
1628 dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
1629
1630 len += snprintf(buf + len, size - len, "%4d %5x %5x ", sampidx,
1631 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x003c0000) >> 18,
1632 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x03c00000) >> 22);
1633 len += snprintf(buf + len, size - len, "%7x %8x ",
1634 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x1c000000) >> 26,
1635 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x3));
1636 len += snprintf(buf + len, size - len, "%7x %7x ",
1637 (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x06000000) >> 25,
1638 (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x38000000) >> 27);
1639 len += snprintf(buf + len, size - len, "%7d %12d ",
1640 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x000003fc) >> 2,
1641 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000400) >> 10);
1642 len += snprintf(buf + len, size - len, "%12d %12d ",
1643 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000800) >> 11,
1644 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00001000) >> 12);
1645 len += snprintf(buf + len, size - len, "%12d %12d ",
1646 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x0001e000) >> 13,
1647 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x001e0000) >> 17);
1648 len += snprintf(buf + len, size - len, "0x%07x 0x%07x\n",
1649 ATH_SAMP_DBG(pcu_obs), ATH_SAMP_DBG(pcu_cr));
1650 }
1651
1652 len += snprintf(buf + len, size - len,
1653 "Sample ChNoise Chain privNF #Reading Readings\n");
1654 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1655 h = ATH_SAMP_DBG(nfCalHist);
1656 if (!ATH_SAMP_DBG(noise))
1657 continue;
1658
1659 for (i = 0; i < NUM_NF_READINGS; i++) {
1660 if (!(chainmask & (1 << i)) ||
1661 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
1662 continue;
1663
1664 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH -
1665 h[i].invalidNFcount;
1666 len += snprintf(buf + len, size - len,
1667 "%4d %5d %4d\t %d\t %d\t",
1668 sampidx, ATH_SAMP_DBG(noise),
1669 i, h[i].privNF, nread);
1670 for (j = 0; j < nread; j++)
1671 len += snprintf(buf + len, size - len,
1672 " %d", h[i].nfCalBuffer[j]);
1673 len += snprintf(buf + len, size - len, "\n");
1674 }
1675 }
1676 len += snprintf(buf + len, size - len, "\nCycle counters:\n"
1677 "Sample Total Rxbusy Rxframes Txframes\n");
1678 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1679 if (!ATH_SAMP_DBG(cc.cycles))
1680 continue;
1681 len += snprintf(buf + len, size - len,
1682 "%4d %08x %08x %08x %08x\n",
1683 sampidx, ATH_SAMP_DBG(cc.cycles),
1684 ATH_SAMP_DBG(cc.rx_busy),
1685 ATH_SAMP_DBG(cc.rx_frame),
1686 ATH_SAMP_DBG(cc.tx_frame));
1687 }
1688
1689 len += snprintf(buf + len, size - len, "Tx status Dump :\n");
1690 len += snprintf(buf + len, size - len,
1691 "Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb "
1692 "isok rts_fail data_fail rate tid qid "
1693 "ba_low ba_high tx_before(ms)\n");
1694 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1695 for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
1696 if (!ATH_SAMP_DBG(ts[i].jiffies))
1697 continue;
1698 len += snprintf(buf + len, size - len, "%-14d"
1699 "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-8d "
1700 "%-9d %-4d %-3d %-3d %08x %08x %-11d\n",
1701 sampidx,
1702 ATH_SAMP_DBG(ts[i].rssi_ctl0),
1703 ATH_SAMP_DBG(ts[i].rssi_ctl1),
1704 ATH_SAMP_DBG(ts[i].rssi_ctl2),
1705 ATH_SAMP_DBG(ts[i].rssi_ext0),
1706 ATH_SAMP_DBG(ts[i].rssi_ext1),
1707 ATH_SAMP_DBG(ts[i].rssi_ext2),
1708 ATH_SAMP_DBG(ts[i].rssi),
1709 ATH_SAMP_DBG(ts[i].isok),
1710 ATH_SAMP_DBG(ts[i].rts_fail_cnt),
1711 ATH_SAMP_DBG(ts[i].data_fail_cnt),
1712 ATH_SAMP_DBG(ts[i].rateindex),
1713 ATH_SAMP_DBG(ts[i].tid),
1714 ATH_SAMP_DBG(ts[i].qid),
1715 ATH_SAMP_DBG(ts[i].ba_low),
1716 ATH_SAMP_DBG(ts[i].ba_high),
1717 jiffies_to_msecs(jiffies -
1718 ATH_SAMP_DBG(ts[i].jiffies)));
1719 }
1720 }
1721
1722 len += snprintf(buf + len, size - len, "Rx status Dump :\n");
1723 len += snprintf(buf + len, size - len, "Sample rssi:- ctl0 ctl1 ctl2 "
1724 "ext0 ext1 ext2 comb beacon ant rate rx_before(ms)\n");
1725 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1726 for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
1727 if (!ATH_SAMP_DBG(rs[i].jiffies))
1728 continue;
1729 len += snprintf(buf + len, size - len, "%-14d"
1730 "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-9s %-2d %02x %-13d\n",
1731 sampidx,
1732 ATH_SAMP_DBG(rs[i].rssi_ctl0),
1733 ATH_SAMP_DBG(rs[i].rssi_ctl1),
1734 ATH_SAMP_DBG(rs[i].rssi_ctl2),
1735 ATH_SAMP_DBG(rs[i].rssi_ext0),
1736 ATH_SAMP_DBG(rs[i].rssi_ext1),
1737 ATH_SAMP_DBG(rs[i].rssi_ext2),
1738 ATH_SAMP_DBG(rs[i].rssi),
1739 ATH_SAMP_DBG(rs[i].is_mybeacon) ?
1740 "True" : "False",
1741 ATH_SAMP_DBG(rs[i].antenna),
1742 ATH_SAMP_DBG(rs[i].rate),
1743 jiffies_to_msecs(jiffies -
1744 ATH_SAMP_DBG(rs[i].jiffies)));
1745 }
1746 }
1747
1748 vfree(bb_mac_samp);
1749 file->private_data = buf;
1750
1751 return 0;
1752#undef ATH_SAMP_DBG
1753}
1754
1755static const struct file_operations fops_samps = {
1756 .open = open_file_bb_mac_samps,
1757 .read = ath9k_debugfs_read_buf,
1758 .release = ath9k_debugfs_release_buf,
1759 .owner = THIS_MODULE,
1760 .llseek = default_llseek,
1761};
1762
1763#endif
1764
1765#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1480#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1766static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, 1481static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1767 size_t count, loff_t *ppos) 1482 size_t count, loff_t *ppos)
@@ -2051,8 +1766,8 @@ int ath9k_init_debug(struct ath_hw *ah)
2051 sc->debug.debugfs_phy, sc, &fops_rx_chainmask); 1766 sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
2052 debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, 1767 debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
2053 sc->debug.debugfs_phy, sc, &fops_tx_chainmask); 1768 sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
2054 debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, 1769 debugfs_create_file("ani", S_IRUSR | S_IWUSR,
2055 sc->debug.debugfs_phy, sc, &fops_disable_ani); 1770 sc->debug.debugfs_phy, sc, &fops_ani);
2056 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1771 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
2057 &sc->sc_ah->config.enable_paprd); 1772 &sc->sc_ah->config.enable_paprd);
2058 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1773 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
@@ -2087,11 +1802,6 @@ int ath9k_init_debug(struct ath_hw *ah)
2087 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR, 1802 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR,
2088 sc->debug.debugfs_phy, sc, 1803 sc->debug.debugfs_phy, sc,
2089 &fops_spectral_fft_period); 1804 &fops_spectral_fft_period);
2090
2091#ifdef CONFIG_ATH9K_MAC_DEBUG
2092 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
2093 &fops_samps);
2094#endif
2095 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1805 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
2096 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1806 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
2097 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1807 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 794a7ec83a24..9719378f7c73 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -251,56 +251,10 @@ struct ath_stats {
251 u32 reset[__RESET_TYPE_MAX]; 251 u32 reset[__RESET_TYPE_MAX];
252}; 252};
253 253
254#define ATH_DBG_MAX_SAMPLES 10
255struct ath_dbg_bb_mac_samp {
256 u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS];
257 u32 pcu_obs, pcu_cr, noise;
258 struct {
259 u64 jiffies;
260 int8_t rssi_ctl0;
261 int8_t rssi_ctl1;
262 int8_t rssi_ctl2;
263 int8_t rssi_ext0;
264 int8_t rssi_ext1;
265 int8_t rssi_ext2;
266 int8_t rssi;
267 bool isok;
268 u8 rts_fail_cnt;
269 u8 data_fail_cnt;
270 u8 rateindex;
271 u8 qid;
272 u8 tid;
273 u32 ba_low;
274 u32 ba_high;
275 } ts[ATH_DBG_MAX_SAMPLES];
276 struct {
277 u64 jiffies;
278 int8_t rssi_ctl0;
279 int8_t rssi_ctl1;
280 int8_t rssi_ctl2;
281 int8_t rssi_ext0;
282 int8_t rssi_ext1;
283 int8_t rssi_ext2;
284 int8_t rssi;
285 bool is_mybeacon;
286 u8 antenna;
287 u8 rate;
288 } rs[ATH_DBG_MAX_SAMPLES];
289 struct ath_cycle_counters cc;
290 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
291};
292
293struct ath9k_debug { 254struct ath9k_debug {
294 struct dentry *debugfs_phy; 255 struct dentry *debugfs_phy;
295 u32 regidx; 256 u32 regidx;
296 struct ath_stats stats; 257 struct ath_stats stats;
297#ifdef CONFIG_ATH9K_MAC_DEBUG
298 spinlock_t samp_lock;
299 struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
300 u8 sampidx;
301 u8 tsidx;
302 u8 rsidx;
303#endif
304}; 258};
305 259
306int ath9k_init_debug(struct ath_hw *ah); 260int ath9k_init_debug(struct ath_hw *ah);
@@ -359,17 +313,4 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
359 313
360#endif /* CONFIG_ATH9K_DEBUGFS */ 314#endif /* CONFIG_ATH9K_DEBUGFS */
361 315
362#ifdef CONFIG_ATH9K_MAC_DEBUG
363
364void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
365
366#else
367
368static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
369{
370}
371
372#endif
373
374
375#endif /* DEBUG_H */ 316#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index d3b099d7898b..0085e643132f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -208,6 +208,9 @@ struct ath9k_htc_target_rx_stats {
208 case NL80211_IFTYPE_AP: \ 208 case NL80211_IFTYPE_AP: \
209 _priv->num_ap_vif++; \ 209 _priv->num_ap_vif++; \
210 break; \ 210 break; \
211 case NL80211_IFTYPE_MESH_POINT: \
212 _priv->num_mbss_vif++; \
213 break; \
211 default: \ 214 default: \
212 break; \ 215 break; \
213 } \ 216 } \
@@ -224,6 +227,9 @@ struct ath9k_htc_target_rx_stats {
224 case NL80211_IFTYPE_AP: \ 227 case NL80211_IFTYPE_AP: \
225 _priv->num_ap_vif--; \ 228 _priv->num_ap_vif--; \
226 break; \ 229 break; \
230 case NL80211_IFTYPE_MESH_POINT: \
231 _priv->num_mbss_vif--; \
232 break; \
227 default: \ 233 default: \
228 break; \ 234 break; \
229 } \ 235 } \
@@ -450,6 +456,7 @@ struct ath9k_htc_priv {
450 u8 sta_slot; 456 u8 sta_slot;
451 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; 457 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
452 u8 num_ibss_vif; 458 u8 num_ibss_vif;
459 u8 num_mbss_vif;
453 u8 num_sta_vif; 460 u8 num_sta_vif;
454 u8 num_sta_assoc_vif; 461 u8 num_sta_assoc_vif;
455 u8 num_ap_vif; 462 u8 num_ap_vif;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index f13f458dd656..e0c03bd64182 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -28,7 +28,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
28 28
29 ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); 29 ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
30 30
31 if (priv->ah->opmode == NL80211_IFTYPE_AP) { 31 if (priv->ah->opmode == NL80211_IFTYPE_AP ||
32 priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) {
32 qi.tqi_aifs = 1; 33 qi.tqi_aifs = 1;
33 qi.tqi_cwmin = 0; 34 qi.tqi_cwmin = 0;
34 qi.tqi_cwmax = 0; 35 qi.tqi_cwmax = 0;
@@ -628,6 +629,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
628 case NL80211_IFTYPE_ADHOC: 629 case NL80211_IFTYPE_ADHOC:
629 ath9k_htc_beacon_config_adhoc(priv, cur_conf); 630 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
630 break; 631 break;
632 case NL80211_IFTYPE_MESH_POINT:
631 case NL80211_IFTYPE_AP: 633 case NL80211_IFTYPE_AP:
632 ath9k_htc_beacon_config_ap(priv, cur_conf); 634 ath9k_htc_beacon_config_ap(priv, cur_conf);
633 break; 635 break;
@@ -649,6 +651,7 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
649 case NL80211_IFTYPE_ADHOC: 651 case NL80211_IFTYPE_ADHOC:
650 ath9k_htc_beacon_config_adhoc(priv, cur_conf); 652 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
651 break; 653 break;
654 case NL80211_IFTYPE_MESH_POINT:
652 case NL80211_IFTYPE_AP: 655 case NL80211_IFTYPE_AP:
653 ath9k_htc_beacon_config_ap(priv, cur_conf); 656 ath9k_htc_beacon_config_ap(priv, cur_conf);
654 break; 657 break;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index a47f5e05fc04..59f64367e8ca 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -698,7 +698,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
698 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | 698 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
699 BIT(NL80211_IFTYPE_P2P_CLIENT) }, 699 BIT(NL80211_IFTYPE_P2P_CLIENT) },
700 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | 700 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) |
701 BIT(NL80211_IFTYPE_P2P_GO) }, 701 BIT(NL80211_IFTYPE_P2P_GO) |
702 BIT(NL80211_IFTYPE_MESH_POINT) },
702}; 703};
703 704
704static const struct ieee80211_iface_combination if_comb = { 705static const struct ieee80211_iface_combination if_comb = {
@@ -721,6 +722,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
721 IEEE80211_HW_SUPPORTS_PS | 722 IEEE80211_HW_SUPPORTS_PS |
722 IEEE80211_HW_PS_NULLFUNC_STACK | 723 IEEE80211_HW_PS_NULLFUNC_STACK |
723 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 724 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
725 IEEE80211_HW_MFP_CAPABLE |
724 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 726 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
725 727
726 hw->wiphy->interface_modes = 728 hw->wiphy->interface_modes =
@@ -728,7 +730,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
728 BIT(NL80211_IFTYPE_ADHOC) | 730 BIT(NL80211_IFTYPE_ADHOC) |
729 BIT(NL80211_IFTYPE_AP) | 731 BIT(NL80211_IFTYPE_AP) |
730 BIT(NL80211_IFTYPE_P2P_GO) | 732 BIT(NL80211_IFTYPE_P2P_GO) |
731 BIT(NL80211_IFTYPE_P2P_CLIENT); 733 BIT(NL80211_IFTYPE_P2P_CLIENT) |
734 BIT(NL80211_IFTYPE_MESH_POINT);
732 735
733 hw->wiphy->iface_combinations = &if_comb; 736 hw->wiphy->iface_combinations = &if_comb;
734 hw->wiphy->n_iface_combinations = 1; 737 hw->wiphy->n_iface_combinations = 1;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 0743a47cef8f..34869c2405aa 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -113,7 +113,9 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
113 struct ath9k_htc_priv *priv = data; 113 struct ath9k_htc_priv *priv = data;
114 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 114 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
115 115
116 if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon) 116 if ((vif->type == NL80211_IFTYPE_AP ||
117 vif->type == NL80211_IFTYPE_MESH_POINT) &&
118 bss_conf->enable_beacon)
117 priv->reconfig_beacon = true; 119 priv->reconfig_beacon = true;
118 120
119 if (bss_conf->assoc) { 121 if (bss_conf->assoc) {
@@ -180,6 +182,8 @@ static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
180 priv->ah->opmode = NL80211_IFTYPE_ADHOC; 182 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
181 else if (priv->num_ap_vif) 183 else if (priv->num_ap_vif)
182 priv->ah->opmode = NL80211_IFTYPE_AP; 184 priv->ah->opmode = NL80211_IFTYPE_AP;
185 else if (priv->num_mbss_vif)
186 priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
183 else 187 else
184 priv->ah->opmode = NL80211_IFTYPE_STATION; 188 priv->ah->opmode = NL80211_IFTYPE_STATION;
185 189
@@ -810,8 +814,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
810 } 814 }
811 815
812 /* Verify whether we must check ANI */ 816 /* Verify whether we must check ANI */
813 if (ah->config.enable_ani && 817 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
814 (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
815 aniflag = true; 818 aniflag = true;
816 common->ani.checkani_timer = timestamp; 819 common->ani.checkani_timer = timestamp;
817 } 820 }
@@ -841,8 +844,7 @@ set_timer:
841 * short calibration and long calibration. 844 * short calibration and long calibration.
842 */ 845 */
843 cal_interval = ATH_LONG_CALINTERVAL; 846 cal_interval = ATH_LONG_CALINTERVAL;
844 if (ah->config.enable_ani) 847 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
845 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
846 if (!common->ani.caldone) 848 if (!common->ani.caldone)
847 cal_interval = min(cal_interval, (u32)short_cal_interval); 849 cal_interval = min(cal_interval, (u32)short_cal_interval);
848 850
@@ -1052,6 +1054,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1052 case NL80211_IFTYPE_AP: 1054 case NL80211_IFTYPE_AP:
1053 hvif.opmode = HTC_M_HOSTAP; 1055 hvif.opmode = HTC_M_HOSTAP;
1054 break; 1056 break;
1057 case NL80211_IFTYPE_MESH_POINT:
1058 hvif.opmode = HTC_M_WDS; /* close enough */
1059 break;
1055 default: 1060 default:
1056 ath_err(common, 1061 ath_err(common,
1057 "Interface type %d not yet supported\n", vif->type); 1062 "Interface type %d not yet supported\n", vif->type);
@@ -1084,6 +1089,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1084 INC_VIF(priv, vif->type); 1089 INC_VIF(priv, vif->type);
1085 1090
1086 if ((vif->type == NL80211_IFTYPE_AP) || 1091 if ((vif->type == NL80211_IFTYPE_AP) ||
1092 (vif->type == NL80211_IFTYPE_MESH_POINT) ||
1087 (vif->type == NL80211_IFTYPE_ADHOC)) 1093 (vif->type == NL80211_IFTYPE_ADHOC))
1088 ath9k_htc_assign_bslot(priv, vif); 1094 ath9k_htc_assign_bslot(priv, vif);
1089 1095
@@ -1134,6 +1140,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1134 DEC_VIF(priv, vif->type); 1140 DEC_VIF(priv, vif->type);
1135 1141
1136 if ((vif->type == NL80211_IFTYPE_AP) || 1142 if ((vif->type == NL80211_IFTYPE_AP) ||
1143 vif->type == NL80211_IFTYPE_MESH_POINT ||
1137 (vif->type == NL80211_IFTYPE_ADHOC)) 1144 (vif->type == NL80211_IFTYPE_ADHOC))
1138 ath9k_htc_remove_bslot(priv, vif); 1145 ath9k_htc_remove_bslot(priv, vif);
1139 1146
@@ -1525,9 +1532,10 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1525 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) { 1532 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1526 /* 1533 /*
1527 * Disable SWBA interrupt only if there are no 1534 * Disable SWBA interrupt only if there are no
1528 * AP/IBSS interfaces. 1535 * concurrent AP/mesh or IBSS interfaces.
1529 */ 1536 */
1530 if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) { 1537 if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
1538 priv->num_ibss_vif) {
1531 ath_dbg(common, CONFIG, 1539 ath_dbg(common, CONFIG,
1532 "Beacon disabled for BSS: %pM\n", 1540 "Beacon disabled for BSS: %pM\n",
1533 bss_conf->bssid); 1541 bss_conf->bssid);
@@ -1538,12 +1546,15 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1538 1546
1539 if (changed & BSS_CHANGED_BEACON_INT) { 1547 if (changed & BSS_CHANGED_BEACON_INT) {
1540 /* 1548 /*
1541 * Reset the HW TSF for the first AP interface. 1549 * Reset the HW TSF for the first AP or mesh interface.
1542 */ 1550 */
1543 if ((priv->ah->opmode == NL80211_IFTYPE_AP) && 1551 if (priv->nvifs == 1 &&
1544 (priv->nvifs == 1) && 1552 ((priv->ah->opmode == NL80211_IFTYPE_AP &&
1545 (priv->num_ap_vif == 1) && 1553 vif->type == NL80211_IFTYPE_AP &&
1546 (vif->type == NL80211_IFTYPE_AP)) { 1554 priv->num_ap_vif == 1) ||
1555 (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
1556 vif->type == NL80211_IFTYPE_MESH_POINT &&
1557 priv->num_mbss_vif == 1))) {
1547 set_bit(OP_TSF_RESET, &priv->op_flags); 1558 set_bit(OP_TSF_RESET, &priv->op_flags);
1548 } 1559 }
1549 ath_dbg(common, CONFIG, 1560 ath_dbg(common, CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 6bd0e92ea2aa..e602c9519709 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -887,7 +887,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
887 if (priv->rxfilter & FIF_PSPOLL) 887 if (priv->rxfilter & FIF_PSPOLL)
888 rfilt |= ATH9K_RX_FILTER_PSPOLL; 888 rfilt |= ATH9K_RX_FILTER_PSPOLL;
889 889
890 if (priv->nvifs > 1) 890 if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS)
891 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; 891 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
892 892
893 return rfilt; 893 return rfilt;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 7f25da8444fe..a13f6cea2ba7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -452,7 +452,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
452 ah->config.pcie_clock_req = 0; 452 ah->config.pcie_clock_req = 0;
453 ah->config.pcie_waen = 0; 453 ah->config.pcie_waen = 0;
454 ah->config.analog_shiftreg = 1; 454 ah->config.analog_shiftreg = 1;
455 ah->config.enable_ani = true;
456 455
457 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 456 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
458 ah->config.spurchans[i][0] = AR_NO_SPUR; 457 ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -549,8 +548,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
549 ah->eep_ops->get_eeprom_ver(ah), 548 ah->eep_ops->get_eeprom_ver(ah),
550 ah->eep_ops->get_eeprom_rev(ah)); 549 ah->eep_ops->get_eeprom_rev(ah));
551 550
552 if (ah->config.enable_ani) 551 ath9k_hw_ani_init(ah);
553 ath9k_hw_ani_init(ah);
554 552
555 return 0; 553 return 0;
556} 554}
@@ -1245,10 +1243,10 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1245 1243
1246 switch (opmode) { 1244 switch (opmode) {
1247 case NL80211_IFTYPE_ADHOC: 1245 case NL80211_IFTYPE_ADHOC:
1248 case NL80211_IFTYPE_MESH_POINT:
1249 set |= AR_STA_ID1_ADHOC; 1246 set |= AR_STA_ID1_ADHOC;
1250 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 1247 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1251 break; 1248 break;
1249 case NL80211_IFTYPE_MESH_POINT:
1252 case NL80211_IFTYPE_AP: 1250 case NL80211_IFTYPE_AP:
1253 set |= AR_STA_ID1_STA_AP; 1251 set |= AR_STA_ID1_STA_AP;
1254 /* fall through */ 1252 /* fall through */
@@ -2246,12 +2244,12 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2246 2244
2247 switch (ah->opmode) { 2245 switch (ah->opmode) {
2248 case NL80211_IFTYPE_ADHOC: 2246 case NL80211_IFTYPE_ADHOC:
2249 case NL80211_IFTYPE_MESH_POINT:
2250 REG_SET_BIT(ah, AR_TXCFG, 2247 REG_SET_BIT(ah, AR_TXCFG,
2251 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 2248 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
2252 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + 2249 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
2253 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); 2250 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
2254 flags |= AR_NDP_TIMER_EN; 2251 flags |= AR_NDP_TIMER_EN;
2252 case NL80211_IFTYPE_MESH_POINT:
2255 case NL80211_IFTYPE_AP: 2253 case NL80211_IFTYPE_AP:
2256 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); 2254 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
2257 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - 2255 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
@@ -2595,13 +2593,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2595 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2593 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2596 } 2594 }
2597 2595
2598 if (AR_SREV_9280_20_OR_LATER(ah)) { 2596 if (AR_SREV_9462(ah))
2599 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | 2597 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
2600 ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
2601
2602 if (AR_SREV_9280(ah))
2603 pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
2604 }
2605 2598
2606 if (AR_SREV_9300_20_OR_LATER(ah) && 2599 if (AR_SREV_9300_20_OR_LATER(ah) &&
2607 ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 2600 ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ae3034374bc4..7d259b7dc254 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -246,9 +246,7 @@ enum ath9k_hw_caps {
246 ATH9K_HW_CAP_MCI = BIT(15), 246 ATH9K_HW_CAP_MCI = BIT(15),
247 ATH9K_HW_CAP_DFS = BIT(16), 247 ATH9K_HW_CAP_DFS = BIT(16),
248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), 248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
249 ATH9K_HW_WOW_PATTERN_MATCH_EXACT = BIT(18), 249 ATH9K_HW_CAP_PAPRD = BIT(18),
250 ATH9K_HW_WOW_PATTERN_MATCH_DWORD = BIT(19),
251 ATH9K_HW_CAP_PAPRD = BIT(20),
252}; 250};
253 251
254/* 252/*
@@ -291,7 +289,6 @@ struct ath9k_ops_config {
291 u32 ofdm_trig_high; 289 u32 ofdm_trig_high;
292 u32 cck_trig_high; 290 u32 cck_trig_high;
293 u32 cck_trig_low; 291 u32 cck_trig_low;
294 u32 enable_ani;
295 u32 enable_paprd; 292 u32 enable_paprd;
296 int serialize_regmode; 293 int serialize_regmode;
297 bool rx_intr_mitigation; 294 bool rx_intr_mitigation;
@@ -423,7 +420,6 @@ struct ath9k_hw_cal_data {
423 420
424struct ath9k_channel { 421struct ath9k_channel {
425 struct ieee80211_channel *chan; 422 struct ieee80211_channel *chan;
426 struct ar5416AniState ani;
427 u16 channel; 423 u16 channel;
428 u32 channelFlags; 424 u32 channelFlags;
429 u32 chanmode; 425 u32 chanmode;
@@ -854,10 +850,10 @@ struct ath_hw {
854 u32 globaltxtimeout; 850 u32 globaltxtimeout;
855 851
856 /* ANI */ 852 /* ANI */
857 u32 proc_phyerr;
858 u32 aniperiod; 853 u32 aniperiod;
859 enum ath9k_ani_cmd ani_function; 854 enum ath9k_ani_cmd ani_function;
860 u32 ani_skip_count; 855 u32 ani_skip_count;
856 struct ar5416AniState ani;
861 857
862#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 858#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
863 struct ath_btcoex_hw btcoex_hw; 859 struct ath_btcoex_hw btcoex_hw;
@@ -882,9 +878,6 @@ struct ath_hw {
882 struct ar5416IniArray iniBank6; 878 struct ar5416IniArray iniBank6;
883 struct ar5416IniArray iniAddac; 879 struct ar5416IniArray iniAddac;
884 struct ar5416IniArray iniPcieSerdes; 880 struct ar5416IniArray iniPcieSerdes;
885#ifdef CONFIG_PM_SLEEP
886 struct ar5416IniArray iniPcieSerdesWow;
887#endif
888 struct ar5416IniArray iniPcieSerdesLowPower; 881 struct ar5416IniArray iniPcieSerdesLowPower;
889 struct ar5416IniArray iniModesFastClock; 882 struct ar5416IniArray iniModesFastClock;
890 struct ar5416IniArray iniAdditional; 883 struct ar5416IniArray iniAdditional;
@@ -1165,8 +1158,6 @@ static inline void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
1165} 1158}
1166#endif 1159#endif
1167 1160
1168
1169
1170#define ATH9K_CLOCK_RATE_CCK 22 1161#define ATH9K_CLOCK_RATE_CCK 22
1171#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 1162#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
1172#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 1163#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index f993362e9e13..f359b0d7078d 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -21,6 +21,7 @@
21#include <linux/ath9k_platform.h> 21#include <linux/ath9k_platform.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/relay.h> 23#include <linux/relay.h>
24#include <net/ieee80211_radiotap.h>
24 25
25#include "ath9k.h" 26#include "ath9k.h"
26 27
@@ -613,9 +614,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
613 spin_lock_init(&sc->sc_serial_rw); 614 spin_lock_init(&sc->sc_serial_rw);
614 spin_lock_init(&sc->sc_pm_lock); 615 spin_lock_init(&sc->sc_pm_lock);
615 mutex_init(&sc->mutex); 616 mutex_init(&sc->mutex);
616#ifdef CONFIG_ATH9K_MAC_DEBUG
617 spin_lock_init(&sc->debug.samp_lock);
618#endif
619 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 617 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
620 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 618 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
621 (unsigned long)sc); 619 (unsigned long)sc);
@@ -778,12 +776,19 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
778 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 776 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
779 IEEE80211_HW_SUPPORTS_RC_TABLE; 777 IEEE80211_HW_SUPPORTS_RC_TABLE;
780 778
781 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 779 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
782 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 780 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
781
782 if (AR_SREV_9280_20_OR_LATER(ah))
783 hw->radiotap_mcs_details |=
784 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
785 }
783 786
784 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) 787 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
785 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 788 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
786 789
790 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
791
787 hw->wiphy->interface_modes = 792 hw->wiphy->interface_modes =
788 BIT(NL80211_IFTYPE_P2P_GO) | 793 BIT(NL80211_IFTYPE_P2P_GO) |
789 BIT(NL80211_IFTYPE_P2P_CLIENT) | 794 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -804,14 +809,12 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
804 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 809 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
805 810
806#ifdef CONFIG_PM_SLEEP 811#ifdef CONFIG_PM_SLEEP
807
808 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 812 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
809 device_can_wakeup(sc->dev)) 813 device_can_wakeup(sc->dev))
810 hw->wiphy->wowlan = &ath9k_wowlan_support; 814 hw->wiphy->wowlan = &ath9k_wowlan_support;
811 815
812 atomic_set(&sc->wow_sleep_proc_intr, -1); 816 atomic_set(&sc->wow_sleep_proc_intr, -1);
813 atomic_set(&sc->wow_got_bmiss_intr, -1); 817 atomic_set(&sc->wow_got_bmiss_intr, -1);
814
815#endif 818#endif
816 819
817 hw->queues = 4; 820 hw->queues = 4;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 849259b07370..fff5d3ccc663 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long data)
390 } 390 }
391 391
392 /* Verify whether we must check ANI */ 392 /* Verify whether we must check ANI */
393 if (sc->sc_ah->config.enable_ani 393 if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
394 && (timestamp - common->ani.checkani_timer) >=
395 ah->config.ani_poll_interval) {
396 aniflag = true; 394 aniflag = true;
397 common->ani.checkani_timer = timestamp; 395 common->ani.checkani_timer = timestamp;
398 } 396 }
@@ -418,7 +416,6 @@ void ath_ani_calibrate(unsigned long data)
418 longcal ? "long" : "", shortcal ? "short" : "", 416 longcal ? "long" : "", shortcal ? "short" : "",
419 aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); 417 aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
420 418
421 ath9k_debug_samp_bb_mac(sc);
422 ath9k_ps_restore(sc); 419 ath9k_ps_restore(sc);
423 420
424set_timer: 421set_timer:
@@ -428,9 +425,7 @@ set_timer:
428 * short calibration and long calibration. 425 * short calibration and long calibration.
429 */ 426 */
430 cal_interval = ATH_LONG_CALINTERVAL; 427 cal_interval = ATH_LONG_CALINTERVAL;
431 if (sc->sc_ah->config.enable_ani) 428 cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
432 cal_interval = min(cal_interval,
433 (u32)ah->config.ani_poll_interval);
434 if (!common->ani.caldone) 429 if (!common->ani.caldone)
435 cal_interval = min(cal_interval, (u32)short_cal_interval); 430 cal_interval = min(cal_interval, (u32)short_cal_interval);
436 431
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 498fee04afa0..d055e389abfc 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -547,6 +547,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
547 547
548 rs->rs_status = 0; 548 rs->rs_status = 0;
549 rs->rs_flags = 0; 549 rs->rs_flags = 0;
550 rs->flag = 0;
550 551
551 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 552 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
552 rs->rs_tstamp = ads.AR_RcvTimestamp; 553 rs->rs_tstamp = ads.AR_RcvTimestamp;
@@ -586,10 +587,17 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
586 rs->rs_moreaggr = 587 rs->rs_moreaggr =
587 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 588 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
588 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 589 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
589 rs->rs_flags = 590
590 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 591 /* directly mapped flags for ieee80211_rx_status */
591 rs->rs_flags |= 592 rs->flag |=
592 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 593 (ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
594 rs->flag |=
595 (ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
596 if (AR_SREV_9280_20_OR_LATER(ah))
597 rs->flag |=
598 (ads.ds_rxstatus3 & AR_STBC) ?
599 /* we can only Nss=1 STBC */
600 (1 << RX_FLAG_STBC_SHIFT) : 0;
593 601
594 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 602 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
595 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 603 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 5865f92998e1..b02dfce964b4 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -149,6 +149,7 @@ struct ath_rx_status {
149 u32 evm2; 149 u32 evm2;
150 u32 evm3; 150 u32 evm3;
151 u32 evm4; 151 u32 evm4;
152 u32 flag; /* see enum mac80211_rx_flags */
152}; 153};
153 154
154struct ath_htc_rx_status { 155struct ath_htc_rx_status {
@@ -533,7 +534,8 @@ struct ar5416_desc {
533#define AR_2040 0x00000002 534#define AR_2040 0x00000002
534#define AR_Parallel40 0x00000004 535#define AR_Parallel40 0x00000004
535#define AR_Parallel40_S 2 536#define AR_Parallel40_S 2
536#define AR_RxStatusRsvd30 0x000000f8 537#define AR_STBC 0x00000008 /* on ar9280 and later */
538#define AR_RxStatusRsvd30 0x000000f0
537#define AR_RxAntenna 0xffffff00 539#define AR_RxAntenna 0xffffff00
538#define AR_RxAntenna_S 8 540#define AR_RxAntenna_S 8
539 541
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a18414b5948b..cc5a98b8d187 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -193,7 +193,6 @@ static bool ath_prepare_reset(struct ath_softc *sc)
193 ath_stop_ani(sc); 193 ath_stop_ani(sc);
194 del_timer_sync(&sc->rx_poll_timer); 194 del_timer_sync(&sc->rx_poll_timer);
195 195
196 ath9k_debug_samp_bb_mac(sc);
197 ath9k_hw_disable_interrupts(ah); 196 ath9k_hw_disable_interrupts(ah);
198 197
199 if (!ath_drain_all_txq(sc)) 198 if (!ath_drain_all_txq(sc))
@@ -1273,7 +1272,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1273 curchan->center_freq); 1272 curchan->center_freq);
1274 } else { 1273 } else {
1275 /* perform spectral scan if requested. */ 1274 /* perform spectral scan if requested. */
1276 if (sc->scanning && 1275 if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
1277 sc->spectral_mode == SPECTRAL_CHANSCAN) 1276 sc->spectral_mode == SPECTRAL_CHANSCAN)
1278 ath9k_spectral_scan_trigger(hw); 1277 ath9k_spectral_scan_trigger(hw);
1279 } 1278 }
@@ -1689,7 +1688,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1689 struct ath_softc *sc = hw->priv; 1688 struct ath_softc *sc = hw->priv;
1690 int ret = 0; 1689 int ret = 0;
1691 1690
1692 local_bh_disable(); 1691 mutex_lock(&sc->mutex);
1693 1692
1694 switch (action) { 1693 switch (action) {
1695 case IEEE80211_AMPDU_RX_START: 1694 case IEEE80211_AMPDU_RX_START:
@@ -1720,7 +1719,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1720 ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); 1719 ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
1721 } 1720 }
1722 1721
1723 local_bh_enable(); 1722 mutex_unlock(&sc->mutex);
1724 1723
1725 return ret; 1724 return ret;
1726} 1725}
@@ -2004,7 +2003,6 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2004{ 2003{
2005 struct ath_hw *ah = sc->sc_ah; 2004 struct ath_hw *ah = sc->sc_ah;
2006 struct ath_common *common = ath9k_hw_common(ah); 2005 struct ath_common *common = ath9k_hw_common(ah);
2007 struct ath9k_hw_capabilities *pcaps = &ah->caps;
2008 int pattern_count = 0; 2006 int pattern_count = 0;
2009 int i, byte_cnt; 2007 int i, byte_cnt;
2010 u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; 2008 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
@@ -2074,36 +2072,9 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2074 2072
2075 /* Create Disassociate pattern mask */ 2073 /* Create Disassociate pattern mask */
2076 2074
2077 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) { 2075 dis_deauth_mask[0] = 0xfe;
2078 2076 dis_deauth_mask[1] = 0x03;
2079 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) { 2077 dis_deauth_mask[2] = 0xc0;
2080 /*
2081 * for AR9280, because of hardware limitation, the
2082 * first 4 bytes have to be matched for all patterns.
2083 * the mask for disassociation and de-auth pattern
2084 * matching need to enable the first 4 bytes.
2085 * also the duration field needs to be filled.
2086 */
2087 dis_deauth_mask[0] = 0xf0;
2088
2089 /*
2090 * fill in duration field
2091 FIXME: what is the exact value ?
2092 */
2093 dis_deauth_pattern[2] = 0xff;
2094 dis_deauth_pattern[3] = 0xff;
2095 } else {
2096 dis_deauth_mask[0] = 0xfe;
2097 }
2098
2099 dis_deauth_mask[1] = 0x03;
2100 dis_deauth_mask[2] = 0xc0;
2101 } else {
2102 dis_deauth_mask[0] = 0xef;
2103 dis_deauth_mask[1] = 0x3f;
2104 dis_deauth_mask[2] = 0x00;
2105 dis_deauth_mask[3] = 0xfc;
2106 }
2107 2078
2108 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); 2079 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
2109 2080
@@ -2339,15 +2310,13 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
2339static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2310static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2340{ 2311{
2341 struct ath_softc *sc = hw->priv; 2312 struct ath_softc *sc = hw->priv;
2342 2313 set_bit(SC_OP_SCANNING, &sc->sc_flags);
2343 sc->scanning = 1;
2344} 2314}
2345 2315
2346static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) 2316static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2347{ 2317{
2348 struct ath_softc *sc = hw->priv; 2318 struct ath_softc *sc = hw->priv;
2349 2319 clear_bit(SC_OP_SCANNING, &sc->sc_flags);
2350 sc->scanning = 0;
2351} 2320}
2352 2321
2353struct ieee80211_ops ath9k_ops = { 2322struct ieee80211_ops ath9k_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8be2b5d8c155..865e043e8aa6 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -868,10 +868,7 @@ static int ath9k_process_rate(struct ath_common *common,
868 if (rx_stats->rs_rate & 0x80) { 868 if (rx_stats->rs_rate & 0x80) {
869 /* HT rate */ 869 /* HT rate */
870 rxs->flag |= RX_FLAG_HT; 870 rxs->flag |= RX_FLAG_HT;
871 if (rx_stats->rs_flags & ATH9K_RX_2040) 871 rxs->flag |= rx_stats->flag;
872 rxs->flag |= RX_FLAG_40MHZ;
873 if (rx_stats->rs_flags & ATH9K_RX_GI)
874 rxs->flag |= RX_FLAG_SHORT_GI;
875 rxs->rate_idx = rx_stats->rs_rate & 0x7f; 872 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
876 return 0; 873 return 0;
877 } 874 }
@@ -958,11 +955,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
958 if (rx_stats->rs_more) 955 if (rx_stats->rs_more)
959 return 0; 956 return 0;
960 957
961 ath9k_process_rssi(common, hw, hdr, rx_stats);
962
963 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) 958 if (ath9k_process_rate(common, hw, rx_stats, rx_status))
964 return -EINVAL; 959 return -EINVAL;
965 960
961 ath9k_process_rssi(common, hw, hdr, rx_stats);
962
966 rx_status->band = hw->conf.chandef.chan->band; 963 rx_status->band = hw->conf.chandef.chan->band;
967 rx_status->freq = hw->conf.chandef.chan->center_freq; 964 rx_status->freq = hw->conf.chandef.chan->center_freq;
968 rx_status->signal = ah->noise + rx_stats->rs_rssi; 965 rx_status->signal = ah->noise + rx_stats->rs_rssi;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 9f8563091bea..81c88dd606dc 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string(u32 wow_event)
34} 34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); 35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36 36
37static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
38{
39 int i;
40
41 for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
42 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
43 INI_RA(&ah->iniPcieSerdesWow, i, 1));
44
45 usleep_range(1000, 1500);
46}
47
48static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
49{ 38{
50 struct ath_common *common = ath9k_hw_common(ah); 39 struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
58 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
59 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); 48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
60 return; 49 return;
61 } else {
62 if (!AR_SREV_9300_20_OR_LATER(ah))
63 REG_WRITE(ah, AR_RXDP, 0x0);
64 } 50 }
65 51
66 /* AR9280 WoW has sleep issue, do not set it to sleep */
67 if (AR_SREV_9280_20(ah))
68 return;
69
70 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
71} 53}
72 54
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
84 66
85 /* set the transmit buffer */ 67 /* set the transmit buffer */
86 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); 68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
87
88 if (!(AR_SREV_9300_20_OR_LATER(ah)))
89 ctl[0] += (KAL_ANTENNA_MODE << 25);
90
91 ctl[1] = 0; 69 ctl[1] = 0;
92 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */ 70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
93 ctl[4] = 0; 71 ctl[4] = 0;
94 ctl[7] = (ah->txchainmask) << 2; 72 ctl[7] = (ah->txchainmask) << 2;
95 73 ctl[2] = 0xf << 16; /* tx_tries 0 */
96 if (AR_SREV_9300_20_OR_LATER(ah))
97 ctl[2] = 0xf << 16; /* tx_tries 0 */
98 else
99 ctl[2] = 0x7 << 16; /* tx_tries 0 */
100
101 74
102 for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
103 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
104 77
105 /* for AR9300 family 13 descriptor words */ 78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
106 if (AR_SREV_9300_20_OR_LATER(ah))
107 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
108 79
109 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
110 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
183 154
184 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
185 156
186 if (!AR_SREV_9285_12_OR_LATER(ah))
187 return;
188
189 if (pattern_count < 4) { 157 if (pattern_count < 4) {
190 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ 158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
191 set = (pattern_len & AR_WOW_LENGTH_MAX) << 159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
207{ 175{
208 u32 wow_status = 0; 176 u32 wow_status = 0;
209 u32 val = 0, rval; 177 u32 val = 0, rval;
178
210 /* 179 /*
211 * read the WoW status register to know 180 * read the WoW status register to know
212 * the wakeup reason 181 * the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
223 val &= ah->wow_event_mask; 192 val &= ah->wow_event_mask;
224 193
225 if (val) { 194 if (val) {
226
227 if (val & AR_WOW_MAGIC_PAT_FOUND) 195 if (val & AR_WOW_MAGIC_PAT_FOUND)
228 wow_status |= AH_WOW_MAGIC_PATTERN_EN; 196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
229
230 if (AR_WOW_PATTERN_FOUND(val)) 197 if (AR_WOW_PATTERN_FOUND(val))
231 wow_status |= AH_WOW_USER_PATTERN_EN; 198 wow_status |= AH_WOW_USER_PATTERN_EN;
232
233 if (val & AR_WOW_KEEP_ALIVE_FAIL) 199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
234 wow_status |= AH_WOW_LINK_CHANGE; 200 wow_status |= AH_WOW_LINK_CHANGE;
235
236 if (val & AR_WOW_BEACON_FAIL) 201 if (val & AR_WOW_BEACON_FAIL)
237 wow_status |= AH_WOW_BEACON_MISS; 202 wow_status |= AH_WOW_BEACON_MISS;
238
239 } 203 }
240 204
241 /* 205 /*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
255 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
256 220
257 /* 221 /*
258 * tie reset register for AR9002 family of chipsets
259 * NB: not tieing it back might have some repurcussions.
260 */
261
262 if (!AR_SREV_9300_20_OR_LATER(ah)) {
263 REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
264 AR_WA_POR_SHORT | AR_WA_RESET_EN);
265 }
266
267
268 /*
269 * restore the beacon threshold to init value 222 * restore the beacon threshold to init value
270 */ 223 */
271 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
277 * reset to our Chip's Power On Reset so that any PCI-E 230 * reset to our Chip's Power On Reset so that any PCI-E
278 * reset from the bus will not reset our chip 231 * reset from the bus will not reset our chip
279 */ 232 */
280 233 if (ah->is_pciexpress)
281 if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
282 ath9k_hw_configpcipowersave(ah, false); 234 ath9k_hw_configpcipowersave(ah, false);
283 235
284 ah->wow_event_mask = 0; 236 ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
298 * are from the 'pattern_enable' in this function and 250 * are from the 'pattern_enable' in this function and
299 * 'pattern_count' of ath9k_hw_wow_apply_pattern() 251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
300 */ 252 */
301
302 wow_event_mask = ah->wow_event_mask; 253 wow_event_mask = ah->wow_event_mask;
303 254
304 /* 255 /*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
306 * WOW sleep, we do want the Reset from the PCI-E to disturb 257 * WOW sleep, we do want the Reset from the PCI-E to disturb
307 * our hw state 258 * our hw state
308 */ 259 */
309
310 if (ah->is_pciexpress) { 260 if (ah->is_pciexpress) {
311
312 /* 261 /*
313 * we need to untie the internal POR (power-on-reset) 262 * we need to untie the internal POR (power-on-reset)
314 * to the external PCI-E reset. We also need to tie 263 * to the external PCI-E reset. We also need to tie
315 * the PCI-E Phy reset to the PCI-E reset. 264 * the PCI-E Phy reset to the PCI-E reset.
316 */ 265 */
317 266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
318 if (AR_SREV_9300_20_OR_LATER(ah)) { 267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
319 set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 268 REG_RMW(ah, AR_WA, set, clr);
320 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
321 REG_RMW(ah, AR_WA, set, clr);
322 } else {
323 if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
324 set = AR9285_WA_DEFAULT;
325 else
326 set = AR9280_WA_DEFAULT;
327
328 /*
329 * In AR9280 and AR9285, bit 14 in WA register
330 * (disable L1) should only be set when device
331 * enters D3 state and be cleared when device
332 * comes back to D0
333 */
334
335 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
336 set |= AR_WA_D3_L1_DISABLE;
337
338 clr = AR_WA_UNTIE_RESET_EN;
339 set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
340 REG_RMW(ah, AR_WA, set, clr);
341
342 /*
343 * for WoW sleep, we reprogram the SerDes so that the
344 * PLL and CLK REQ are both enabled. This uses more
345 * power but otherwise WoW sleep is unstable and the
346 * chip may disappear.
347 */
348
349 if (AR_SREV_9285_12_OR_LATER(ah))
350 ath9k_hw_config_serdes_wow_sleep(ah);
351
352 }
353 } 269 }
354 270
355 /* 271 /*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
378 * Program default values for pattern backoff, aifs/slot/KAL count, 294 * Program default values for pattern backoff, aifs/slot/KAL count,
379 * beacon miss timeout, KAL timeout, etc. 295 * beacon miss timeout, KAL timeout, etc.
380 */ 296 */
381
382 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF); 297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
383 REG_SET_BIT(ah, AR_WOW_PATTERN, set); 298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
384 299
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
398 /* 313 /*
399 * Keep alive timo in ms except AR9280 314 * Keep alive timo in ms except AR9280
400 */ 315 */
401 if (!pattern_enable || AR_SREV_9280(ah)) 316 if (!pattern_enable)
402 set = AR_WOW_KEEP_ALIVE_NEVER; 317 set = AR_WOW_KEEP_ALIVE_NEVER;
403 else 318 else
404 set = KAL_TIMEOUT * 32; 319 set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
420 /* 335 /*
421 * Configure MAC WoW Registers 336 * Configure MAC WoW Registers
422 */ 337 */
423
424 set = 0; 338 set = 0;
425 /* Send keep alive timeouts anyway */ 339 /* Send keep alive timeouts anyway */
426 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; 340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
430 else 344 else
431 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
432 346
433 /*
434 * FIXME: For now disable keep alive frame
435 * failure. This seems to sometimes trigger
436 * unnecessary wake up with AR9485 chipsets.
437 */
438 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
439
440 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
441 349
442
443 /* 350 /*
444 * we are relying on a bmiss failure. ensure we have 351 * we are relying on a bmiss failure. ensure we have
445 * enough threshold to prevent false positives 352 * enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
473 set |= AR_WOW_MAC_INTR_EN; 380 set |= AR_WOW_MAC_INTR_EN;
474 REG_RMW(ah, AR_WOW_PATTERN, set, clr); 381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
475 382
476 /* 383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
477 * For AR9285 and later version of chipsets 384 AR_WOW_PATTERN_SUPPORTED);
478 * enable WoW pattern match for packets less
479 * than 256 bytes for all patterns
480 */
481 if (AR_SREV_9285_12_OR_LATER(ah))
482 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
483 AR_WOW_PATTERN_SUPPORTED);
484 385
485 /* 386 /*
486 * Set the power states appropriately and enable PME 387 * Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
488 clr = 0; 389 clr = 0;
489 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | 390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
490 AR_PMCTRL_PWR_PM_CTRL_ENA; 391 AR_PMCTRL_PWR_PM_CTRL_ENA;
491 /*
492 * This is needed for AR9300 chipsets to wake-up
493 * the host.
494 */
495 if (AR_SREV_9300_20_OR_LATER(ah))
496 clr = AR_PCIE_PM_CTRL_ENA;
497 392
393 clr = AR_PCIE_PM_CTRL_ENA;
498 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
499 395
500 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 396 /*
501 /* 397 * this is needed to prevent the chip waking up
502 * this is needed to prevent the chip waking up 398 * the host within 3-4 seconds with certain
503 * the host within 3-4 seconds with certain 399 * platform/BIOS. The fix is to enable
504 * platform/BIOS. The fix is to enable 400 * D1 & D3 to match original definition and
505 * D1 & D3 to match original definition and 401 * also match the OTP value. Anyway this
506 * also match the OTP value. Anyway this 402 * is more related to SW WOW.
507 * is more related to SW WOW. 403 */
508 */ 404 clr = AR_PMCTRL_PWR_STATE_D1D3;
509 clr = AR_PMCTRL_PWR_STATE_D1D3; 405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
510 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
511
512 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
513 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
514 }
515
516 406
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
517 409
518 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
519 411
520 if (AR_SREV_9300_20_OR_LATER(ah)) { 412 /* to bring down WOW power low margin */
521 /* to bring down WOW power low margin */ 413 set = BIT(13);
522 set = BIT(13); 414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
523 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 415 /* HW WoW */
524 /* HW WoW */ 416 clr = BIT(5);
525 clr = BIT(5); 417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
526 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
527 }
528 418
529 ath9k_hw_set_powermode_wow_sleep(ah); 419 ath9k_hw_set_powermode_wow_sleep(ah);
530 ah->wow_event_mask = wow_event_mask; 420 ah->wow_event_mask = wow_event_mask;
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index bac3d98a0cfb..5644ac54facc 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -27,3 +27,15 @@ config WIL6210_ISR_COR
27 self-clear when accessed for debug purposes, it makes 27 self-clear when accessed for debug purposes, it makes
28 such monitoring impossible. 28 such monitoring impossible.
29 Say y unless you debug interrupts 29 Say y unless you debug interrupts
30
31config ATH6KL_TRACING
32 bool "wil6210 tracing support"
33 depends on WIL6210
34 depends on EVENT_TRACING
35 default y
36 ---help---
37 Say Y here to enable tracepoints for the wil6210 driver
38 using the kernel tracing infrastructure. Select this
39 option if you are interested in debugging the driver.
40
41 If unsure, say Y to make it easier to debug problems.
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index d288eea0a26a..f891d514d881 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -1,15 +1,20 @@
1obj-$(CONFIG_WIL6210) += wil6210.o 1obj-$(CONFIG_WIL6210) += wil6210.o
2 2
3wil6210-objs := main.o 3wil6210-y := main.o
4wil6210-objs += netdev.o 4wil6210-y += netdev.o
5wil6210-objs += cfg80211.o 5wil6210-y += cfg80211.o
6wil6210-objs += pcie_bus.o 6wil6210-y += pcie_bus.o
7wil6210-objs += debugfs.o 7wil6210-y += debugfs.o
8wil6210-objs += wmi.o 8wil6210-y += wmi.o
9wil6210-objs += interrupt.o 9wil6210-y += interrupt.o
10wil6210-objs += txrx.o 10wil6210-y += txrx.o
11wil6210-y += debug.o
12wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
11 13
12ifeq (, $(findstring -W,$(EXTRA_CFLAGS))) 14ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
13 subdir-ccflags-y += -Werror 15 subdir-ccflags-y += -Werror
14endif 16endif
17# for tracing framework to find trace.h
18CFLAGS_trace.o := -I$(src)
19
15subdir-ccflags-y += -D__CHECK_ENDIAN__ 20subdir-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index c5d4a87abaaf..4eb05d0818c3 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -322,12 +322,16 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
322 * FW don't support scan after connection attempt 322 * FW don't support scan after connection attempt
323 */ 323 */
324 set_bit(wil_status_dontscan, &wil->status); 324 set_bit(wil_status_dontscan, &wil->status);
325 set_bit(wil_status_fwconnecting, &wil->status);
325 326
326 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); 327 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
327 if (rc == 0) { 328 if (rc == 0) {
328 /* Connect can take lots of time */ 329 /* Connect can take lots of time */
329 mod_timer(&wil->connect_timer, 330 mod_timer(&wil->connect_timer,
330 jiffies + msecs_to_jiffies(2000)); 331 jiffies + msecs_to_jiffies(2000));
332 } else {
333 clear_bit(wil_status_dontscan, &wil->status);
334 clear_bit(wil_status_fwconnecting, &wil->status);
331 } 335 }
332 336
333 out: 337 out:
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c
new file mode 100644
index 000000000000..9eeabf4a5879
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/debug.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "wil6210.h"
18#include "trace.h"
19
20int wil_err(struct wil6210_priv *wil, const char *fmt, ...)
21{
22 struct net_device *ndev = wil_to_ndev(wil);
23 struct va_format vaf = {
24 .fmt = fmt,
25 };
26 va_list args;
27 int ret;
28
29 va_start(args, fmt);
30 vaf.va = &args;
31 ret = netdev_err(ndev, "%pV", &vaf);
32 trace_wil6210_log_err(&vaf);
33 va_end(args);
34
35 return ret;
36}
37
38int wil_info(struct wil6210_priv *wil, const char *fmt, ...)
39{
40 struct net_device *ndev = wil_to_ndev(wil);
41 struct va_format vaf = {
42 .fmt = fmt,
43 };
44 va_list args;
45 int ret;
46
47 va_start(args, fmt);
48 vaf.va = &args;
49 ret = netdev_info(ndev, "%pV", &vaf);
50 trace_wil6210_log_info(&vaf);
51 va_end(args);
52
53 return ret;
54}
55
56int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
57{
58 struct va_format vaf = {
59 .fmt = fmt,
60 };
61 va_list args;
62
63 va_start(args, fmt);
64 vaf.va = &args;
65 trace_wil6210_log_dbg(&vaf);
66 va_end(args);
67
68 return 0;
69}
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 727b1f53e6ad..e8308ec30970 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -418,9 +418,15 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
418 if (skb) { 418 if (skb) {
419 unsigned char printbuf[16 * 3 + 2]; 419 unsigned char printbuf[16 * 3 + 2];
420 int i = 0; 420 int i = 0;
421 int len = skb_headlen(skb); 421 int len = le16_to_cpu(d->dma.length);
422 void *p = skb->data; 422 void *p = skb->data;
423 423
424 if (len != skb_headlen(skb)) {
425 seq_printf(s, "!!! len: desc = %d skb = %d\n",
426 len, skb_headlen(skb));
427 len = min_t(int, len, skb_headlen(skb));
428 }
429
424 seq_printf(s, " len = %d\n", len); 430 seq_printf(s, " len = %d\n", len);
425 431
426 while (i < len) { 432 while (i < len) {
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index e3c1e7684f9c..8205d3e4ab66 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18 18
19#include "wil6210.h" 19#include "wil6210.h"
20#include "trace.h"
20 21
21/** 22/**
22 * Theory of operation: 23 * Theory of operation:
@@ -103,14 +104,14 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
103 clear_bit(wil_status_irqen, &wil->status); 104 clear_bit(wil_status_irqen, &wil->status);
104} 105}
105 106
106static void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 107void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
107{ 108{
108 iowrite32(WIL6210_IMC_TX, wil->csr + 109 iowrite32(WIL6210_IMC_TX, wil->csr +
109 HOSTADDR(RGF_DMA_EP_TX_ICR) + 110 HOSTADDR(RGF_DMA_EP_TX_ICR) +
110 offsetof(struct RGF_ICR, IMC)); 111 offsetof(struct RGF_ICR, IMC));
111} 112}
112 113
113static void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 114void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
114{ 115{
115 iowrite32(WIL6210_IMC_RX, wil->csr + 116 iowrite32(WIL6210_IMC_RX, wil->csr +
116 HOSTADDR(RGF_DMA_EP_RX_ICR) + 117 HOSTADDR(RGF_DMA_EP_RX_ICR) +
@@ -168,6 +169,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
168 HOSTADDR(RGF_DMA_EP_RX_ICR) + 169 HOSTADDR(RGF_DMA_EP_RX_ICR) +
169 offsetof(struct RGF_ICR, ICR)); 170 offsetof(struct RGF_ICR, ICR));
170 171
172 trace_wil6210_irq_rx(isr);
171 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 173 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
172 174
173 if (!isr) { 175 if (!isr) {
@@ -180,13 +182,14 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
180 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { 182 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
181 wil_dbg_irq(wil, "RX done\n"); 183 wil_dbg_irq(wil, "RX done\n");
182 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; 184 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
183 wil_rx_handle(wil); 185 wil_dbg_txrx(wil, "NAPI schedule\n");
186 napi_schedule(&wil->napi_rx);
184 } 187 }
185 188
186 if (isr) 189 if (isr)
187 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 190 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
188 191
189 wil6210_unmask_irq_rx(wil); 192 /* Rx IRQ will be enabled when NAPI processing finished */
190 193
191 return IRQ_HANDLED; 194 return IRQ_HANDLED;
192} 195}
@@ -198,6 +201,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
198 HOSTADDR(RGF_DMA_EP_TX_ICR) + 201 HOSTADDR(RGF_DMA_EP_TX_ICR) +
199 offsetof(struct RGF_ICR, ICR)); 202 offsetof(struct RGF_ICR, ICR));
200 203
204 trace_wil6210_irq_tx(isr);
201 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 205 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
202 206
203 if (!isr) { 207 if (!isr) {
@@ -208,23 +212,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
208 wil6210_mask_irq_tx(wil); 212 wil6210_mask_irq_tx(wil);
209 213
210 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 214 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
211 uint i;
212 wil_dbg_irq(wil, "TX done\n"); 215 wil_dbg_irq(wil, "TX done\n");
216 napi_schedule(&wil->napi_tx);
213 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 217 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
214 for (i = 0; i < 24; i++) { 218 /* clear also all VRING interrupts */
215 u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); 219 isr &= ~(BIT(25) - 1UL);
216 if (isr & mask) {
217 isr &= ~mask;
218 wil_dbg_irq(wil, "TX done(%i)\n", i);
219 wil_tx_complete(wil, i);
220 }
221 }
222 } 220 }
223 221
224 if (isr) 222 if (isr)
225 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 223 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
226 224
227 wil6210_unmask_irq_tx(wil); 225 /* Tx IRQ will be enabled when NAPI processing finished */
228 226
229 return IRQ_HANDLED; 227 return IRQ_HANDLED;
230} 228}
@@ -256,6 +254,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
256 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 254 HOSTADDR(RGF_DMA_EP_MISC_ICR) +
257 offsetof(struct RGF_ICR, ICR)); 255 offsetof(struct RGF_ICR, ICR));
258 256
257 trace_wil6210_irq_misc(isr);
259 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); 258 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr);
260 259
261 if (!isr) { 260 if (!isr) {
@@ -301,6 +300,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
301 struct wil6210_priv *wil = cookie; 300 struct wil6210_priv *wil = cookie;
302 u32 isr = wil->isr_misc; 301 u32 isr = wil->isr_misc;
303 302
303 trace_wil6210_irq_misc_thread(isr);
304 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); 304 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
305 305
306 if (isr & ISR_MISC_FW_ERROR) { 306 if (isr & ISR_MISC_FW_ERROR) {
@@ -408,6 +408,7 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
408 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 408 if (wil6210_debug_irq_mask(wil, pseudo_cause))
409 return IRQ_NONE; 409 return IRQ_NONE;
410 410
411 trace_wil6210_irq_pseudo(pseudo_cause);
411 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause); 412 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
412 413
413 wil6210_mask_irq_pseudo(wil); 414 wil6210_mask_irq_pseudo(wil);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index a0478e2f6868..c97b864667c5 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -56,27 +56,21 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
56{ 56{
57 uint i; 57 uint i;
58 struct net_device *ndev = wil_to_ndev(wil); 58 struct net_device *ndev = wil_to_ndev(wil);
59 struct wireless_dev *wdev = wil->wdev;
60 59
61 wil_dbg_misc(wil, "%s()\n", __func__); 60 wil_dbg_misc(wil, "%s()\n", __func__);
62 61
63 wil_link_off(wil); 62 wil_link_off(wil);
64 clear_bit(wil_status_fwconnected, &wil->status); 63 if (test_bit(wil_status_fwconnected, &wil->status)) {
65 64 clear_bit(wil_status_fwconnected, &wil->status);
66 switch (wdev->sme_state) { 65 cfg80211_disconnected(ndev,
67 case CFG80211_SME_CONNECTED: 66 WLAN_STATUS_UNSPECIFIED_FAILURE,
68 cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE,
69 NULL, 0, GFP_KERNEL); 67 NULL, 0, GFP_KERNEL);
70 break; 68 } else if (test_bit(wil_status_fwconnecting, &wil->status)) {
71 case CFG80211_SME_CONNECTING:
72 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 69 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
73 WLAN_STATUS_UNSPECIFIED_FAILURE, 70 WLAN_STATUS_UNSPECIFIED_FAILURE,
74 GFP_KERNEL); 71 GFP_KERNEL);
75 break;
76 default:
77 break;
78 } 72 }
79 73 clear_bit(wil_status_fwconnecting, &wil->status);
80 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) 74 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
81 wil_vring_fini_tx(wil, i); 75 wil_vring_fini_tx(wil, i);
82 76
@@ -365,6 +359,9 @@ static int __wil_up(struct wil6210_priv *wil)
365 /* Rx VRING. After MAC and beacon */ 359 /* Rx VRING. After MAC and beacon */
366 wil_rx_init(wil); 360 wil_rx_init(wil);
367 361
362 napi_enable(&wil->napi_rx);
363 napi_enable(&wil->napi_tx);
364
368 return 0; 365 return 0;
369} 366}
370 367
@@ -381,6 +378,9 @@ int wil_up(struct wil6210_priv *wil)
381 378
382static int __wil_down(struct wil6210_priv *wil) 379static int __wil_down(struct wil6210_priv *wil)
383{ 380{
381 napi_disable(&wil->napi_rx);
382 napi_disable(&wil->napi_tx);
383
384 if (wil->scan_request) { 384 if (wil->scan_request) {
385 cfg80211_scan_done(wil->scan_request, true); 385 cfg80211_scan_done(wil->scan_request, true);
386 wil->scan_request = NULL; 386 wil->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 098a8ec6b841..29dd1e58cb17 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -40,6 +40,55 @@ static const struct net_device_ops wil_netdev_ops = {
40 .ndo_validate_addr = eth_validate_addr, 40 .ndo_validate_addr = eth_validate_addr,
41}; 41};
42 42
43static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
44{
45 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
46 napi_rx);
47 int quota = budget;
48 int done;
49
50 wil_rx_handle(wil, &quota);
51 done = budget - quota;
52
53 if (done <= 1) { /* burst ends - only one packet processed */
54 napi_complete(napi);
55 wil6210_unmask_irq_rx(wil);
56 wil_dbg_txrx(wil, "NAPI RX complete\n");
57 }
58
59 wil_dbg_txrx(wil, "NAPI RX poll(%d) done %d\n", budget, done);
60
61 return done;
62}
63
64static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
65{
66 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
67 napi_tx);
68 int tx_done = 0;
69 uint i;
70
71 /* always process ALL Tx complete, regardless budget - it is fast */
72 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
73 struct vring *vring = &wil->vring_tx[i];
74
75 if (!vring->va)
76 continue;
77
78 tx_done += wil_tx_complete(wil, i);
79 }
80
81 if (tx_done <= 1) { /* burst ends - only one packet processed */
82 napi_complete(napi);
83 wil6210_unmask_irq_tx(wil);
84 wil_dbg_txrx(wil, "NAPI TX complete\n");
85 }
86
87 wil_dbg_txrx(wil, "NAPI TX poll(%d) done %d\n", budget, tx_done);
88
89 return min(tx_done, budget);
90}
91
43void *wil_if_alloc(struct device *dev, void __iomem *csr) 92void *wil_if_alloc(struct device *dev, void __iomem *csr)
44{ 93{
45 struct net_device *ndev; 94 struct net_device *ndev;
@@ -81,6 +130,11 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
81 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 130 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
82 wdev->netdev = ndev; 131 wdev->netdev = ndev;
83 132
133 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
134 WIL6210_NAPI_BUDGET);
135 netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
136 WIL6210_NAPI_BUDGET);
137
84 wil_link_off(wil); 138 wil_link_off(wil);
85 139
86 return wil; 140 return wil;
diff --git a/drivers/net/wireless/ath/wil6210/trace.c b/drivers/net/wireless/ath/wil6210/trace.c
new file mode 100644
index 000000000000..cd2534b9c5aa
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/trace.c
@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/module.h>
18
19#define CREATE_TRACE_POINTS
20#include "trace.h"
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
new file mode 100644
index 000000000000..eff1239be53a
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -0,0 +1,235 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#undef TRACE_SYSTEM
18#define TRACE_SYSTEM wil6210
19#if !defined(WIL6210_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
20#define WIL6210_TRACE_H
21
22#include <linux/tracepoint.h>
23#include "wil6210.h"
24#include "txrx.h"
25
26/* create empty functions when tracing is disabled */
27#if !defined(CONFIG_WIL6210_TRACING) || defined(__CHECKER__)
28
29#undef TRACE_EVENT
30#define TRACE_EVENT(name, proto, ...) \
31static inline void trace_ ## name(proto) {}
32#undef DECLARE_EVENT_CLASS
33#define DECLARE_EVENT_CLASS(...)
34#undef DEFINE_EVENT
35#define DEFINE_EVENT(evt_class, name, proto, ...) \
36static inline void trace_ ## name(proto) {}
37#endif /* !CONFIG_WIL6210_TRACING || defined(__CHECKER__) */
38
39DECLARE_EVENT_CLASS(wil6210_wmi,
40 TP_PROTO(u16 id, void *buf, u16 buf_len),
41
42 TP_ARGS(id, buf, buf_len),
43
44 TP_STRUCT__entry(
45 __field(u16, id)
46 __field(u16, buf_len)
47 __dynamic_array(u8, buf, buf_len)
48 ),
49
50 TP_fast_assign(
51 __entry->id = id;
52 __entry->buf_len = buf_len;
53 memcpy(__get_dynamic_array(buf), buf, buf_len);
54 ),
55
56 TP_printk(
57 "id 0x%04x len %d",
58 __entry->id, __entry->buf_len
59 )
60);
61
62DEFINE_EVENT(wil6210_wmi, wil6210_wmi_cmd,
63 TP_PROTO(u16 id, void *buf, u16 buf_len),
64 TP_ARGS(id, buf, buf_len)
65);
66
67DEFINE_EVENT(wil6210_wmi, wil6210_wmi_event,
68 TP_PROTO(u16 id, void *buf, u16 buf_len),
69 TP_ARGS(id, buf, buf_len)
70);
71
72#define WIL6210_MSG_MAX (200)
73
74DECLARE_EVENT_CLASS(wil6210_log_event,
75 TP_PROTO(struct va_format *vaf),
76 TP_ARGS(vaf),
77 TP_STRUCT__entry(
78 __dynamic_array(char, msg, WIL6210_MSG_MAX)
79 ),
80 TP_fast_assign(
81 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
82 WIL6210_MSG_MAX,
83 vaf->fmt,
84 *vaf->va) >= WIL6210_MSG_MAX);
85 ),
86 TP_printk("%s", __get_str(msg))
87);
88
89DEFINE_EVENT(wil6210_log_event, wil6210_log_err,
90 TP_PROTO(struct va_format *vaf),
91 TP_ARGS(vaf)
92);
93
94DEFINE_EVENT(wil6210_log_event, wil6210_log_info,
95 TP_PROTO(struct va_format *vaf),
96 TP_ARGS(vaf)
97);
98
99DEFINE_EVENT(wil6210_log_event, wil6210_log_dbg,
100 TP_PROTO(struct va_format *vaf),
101 TP_ARGS(vaf)
102);
103
104#define wil_pseudo_irq_cause(x) __print_flags(x, "|", \
105 {BIT_DMA_PSEUDO_CAUSE_RX, "Rx" }, \
106 {BIT_DMA_PSEUDO_CAUSE_TX, "Tx" }, \
107 {BIT_DMA_PSEUDO_CAUSE_MISC, "Misc" })
108
109TRACE_EVENT(wil6210_irq_pseudo,
110 TP_PROTO(u32 x),
111 TP_ARGS(x),
112 TP_STRUCT__entry(
113 __field(u32, x)
114 ),
115 TP_fast_assign(
116 __entry->x = x;
117 ),
118 TP_printk("cause 0x%08x : %s", __entry->x,
119 wil_pseudo_irq_cause(__entry->x))
120);
121
122DECLARE_EVENT_CLASS(wil6210_irq,
123 TP_PROTO(u32 x),
124 TP_ARGS(x),
125 TP_STRUCT__entry(
126 __field(u32, x)
127 ),
128 TP_fast_assign(
129 __entry->x = x;
130 ),
131 TP_printk("cause 0x%08x", __entry->x)
132);
133
134DEFINE_EVENT(wil6210_irq, wil6210_irq_rx,
135 TP_PROTO(u32 x),
136 TP_ARGS(x)
137);
138
139DEFINE_EVENT(wil6210_irq, wil6210_irq_tx,
140 TP_PROTO(u32 x),
141 TP_ARGS(x)
142);
143
144DEFINE_EVENT(wil6210_irq, wil6210_irq_misc,
145 TP_PROTO(u32 x),
146 TP_ARGS(x)
147);
148
149DEFINE_EVENT(wil6210_irq, wil6210_irq_misc_thread,
150 TP_PROTO(u32 x),
151 TP_ARGS(x)
152);
153
154TRACE_EVENT(wil6210_rx,
155 TP_PROTO(u16 index, struct vring_rx_desc *d),
156 TP_ARGS(index, d),
157 TP_STRUCT__entry(
158 __field(u16, index)
159 __field(unsigned int, len)
160 __field(u8, mid)
161 __field(u8, cid)
162 __field(u8, tid)
163 __field(u8, type)
164 __field(u8, subtype)
165 __field(u16, seq)
166 __field(u8, mcs)
167 ),
168 TP_fast_assign(
169 __entry->index = index;
170 __entry->len = d->dma.length;
171 __entry->mid = wil_rxdesc_mid(d);
172 __entry->cid = wil_rxdesc_cid(d);
173 __entry->tid = wil_rxdesc_tid(d);
174 __entry->type = wil_rxdesc_ftype(d);
175 __entry->subtype = wil_rxdesc_subtype(d);
176 __entry->seq = wil_rxdesc_seq(d);
177 __entry->mcs = wil_rxdesc_mcs(d);
178 ),
179 TP_printk("index %d len %d mid %d cid %d tid %d mcs %d seq 0x%03x"
180 " type 0x%1x subtype 0x%1x", __entry->index, __entry->len,
181 __entry->mid, __entry->cid, __entry->tid, __entry->mcs,
182 __entry->seq, __entry->type, __entry->subtype)
183);
184
185TRACE_EVENT(wil6210_tx,
186 TP_PROTO(u8 vring, u16 index, unsigned int len, u8 frags),
187 TP_ARGS(vring, index, len, frags),
188 TP_STRUCT__entry(
189 __field(u8, vring)
190 __field(u8, frags)
191 __field(u16, index)
192 __field(unsigned int, len)
193 ),
194 TP_fast_assign(
195 __entry->vring = vring;
196 __entry->frags = frags;
197 __entry->index = index;
198 __entry->len = len;
199 ),
200 TP_printk("vring %d index %d len %d frags %d",
201 __entry->vring, __entry->index, __entry->len, __entry->frags)
202);
203
204TRACE_EVENT(wil6210_tx_done,
205 TP_PROTO(u8 vring, u16 index, unsigned int len, u8 err),
206 TP_ARGS(vring, index, len, err),
207 TP_STRUCT__entry(
208 __field(u8, vring)
209 __field(u8, err)
210 __field(u16, index)
211 __field(unsigned int, len)
212 ),
213 TP_fast_assign(
214 __entry->vring = vring;
215 __entry->index = index;
216 __entry->len = len;
217 __entry->err = err;
218 ),
219 TP_printk("vring %d index %d len %d err 0x%02x",
220 __entry->vring, __entry->index, __entry->len,
221 __entry->err)
222);
223
224#endif /* WIL6210_TRACE_H || TRACE_HEADER_MULTI_READ*/
225
226#if defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__)
227/* we don't want to use include/trace/events */
228#undef TRACE_INCLUDE_PATH
229#define TRACE_INCLUDE_PATH .
230#undef TRACE_INCLUDE_FILE
231#define TRACE_INCLUDE_FILE trace
232
233/* This part must be outside protection */
234#include <trace/define_trace.h>
235#endif /* defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__) */
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 797024507c71..00dffeda983e 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -22,6 +22,7 @@
22#include "wil6210.h" 22#include "wil6210.h"
23#include "wmi.h" 23#include "wmi.h"
24#include "txrx.h" 24#include "txrx.h"
25#include "trace.h"
25 26
26static bool rtap_include_phy_info; 27static bool rtap_include_phy_info;
27module_param(rtap_include_phy_info, bool, S_IRUGO); 28module_param(rtap_include_phy_info, bool, S_IRUGO);
@@ -89,8 +90,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
89 * we can use any 90 * we can use any
90 */ 91 */
91 for (i = 0; i < vring->size; i++) { 92 for (i = 0; i < vring->size; i++) {
92 volatile struct vring_tx_desc *d = &(vring->va[i].tx); 93 volatile struct vring_tx_desc *_d = &(vring->va[i].tx);
93 d->dma.status = TX_DMA_STATUS_DU; 94 _d->dma.status = TX_DMA_STATUS_DU;
94 } 95 }
95 96
96 wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size, 97 wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
@@ -106,30 +107,39 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
106 size_t sz = vring->size * sizeof(vring->va[0]); 107 size_t sz = vring->size * sizeof(vring->va[0]);
107 108
108 while (!wil_vring_is_empty(vring)) { 109 while (!wil_vring_is_empty(vring)) {
110 dma_addr_t pa;
111 struct sk_buff *skb;
112 u16 dmalen;
113
109 if (tx) { 114 if (tx) {
110 volatile struct vring_tx_desc *d = 115 struct vring_tx_desc dd, *d = &dd;
116 volatile struct vring_tx_desc *_d =
111 &vring->va[vring->swtail].tx; 117 &vring->va[vring->swtail].tx;
112 dma_addr_t pa = d->dma.addr_low | 118
113 ((u64)d->dma.addr_high << 32); 119 *d = *_d;
114 struct sk_buff *skb = vring->ctx[vring->swtail]; 120 pa = wil_desc_addr(&d->dma.addr);
121 dmalen = le16_to_cpu(d->dma.length);
122 skb = vring->ctx[vring->swtail];
115 if (skb) { 123 if (skb) {
116 dma_unmap_single(dev, pa, d->dma.length, 124 dma_unmap_single(dev, pa, dmalen,
117 DMA_TO_DEVICE); 125 DMA_TO_DEVICE);
118 dev_kfree_skb_any(skb); 126 dev_kfree_skb_any(skb);
119 vring->ctx[vring->swtail] = NULL; 127 vring->ctx[vring->swtail] = NULL;
120 } else { 128 } else {
121 dma_unmap_page(dev, pa, d->dma.length, 129 dma_unmap_page(dev, pa, dmalen,
122 DMA_TO_DEVICE); 130 DMA_TO_DEVICE);
123 } 131 }
124 vring->swtail = wil_vring_next_tail(vring); 132 vring->swtail = wil_vring_next_tail(vring);
125 } else { /* rx */ 133 } else { /* rx */
126 volatile struct vring_rx_desc *d = 134 struct vring_rx_desc dd, *d = &dd;
135 volatile struct vring_rx_desc *_d =
127 &vring->va[vring->swtail].rx; 136 &vring->va[vring->swtail].rx;
128 dma_addr_t pa = d->dma.addr_low | 137
129 ((u64)d->dma.addr_high << 32); 138 *d = *_d;
130 struct sk_buff *skb = vring->ctx[vring->swhead]; 139 pa = wil_desc_addr(&d->dma.addr);
131 dma_unmap_single(dev, pa, d->dma.length, 140 dmalen = le16_to_cpu(d->dma.length);
132 DMA_FROM_DEVICE); 141 skb = vring->ctx[vring->swhead];
142 dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
133 kfree_skb(skb); 143 kfree_skb(skb);
134 wil_vring_advance_head(vring, 1); 144 wil_vring_advance_head(vring, 1);
135 } 145 }
@@ -151,7 +161,8 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
151{ 161{
152 struct device *dev = wil_to_dev(wil); 162 struct device *dev = wil_to_dev(wil);
153 unsigned int sz = RX_BUF_LEN; 163 unsigned int sz = RX_BUF_LEN;
154 volatile struct vring_rx_desc *d = &(vring->va[i].rx); 164 struct vring_rx_desc dd, *d = &dd;
165 volatile struct vring_rx_desc *_d = &(vring->va[i].rx);
155 dma_addr_t pa; 166 dma_addr_t pa;
156 167
157 /* TODO align */ 168 /* TODO align */
@@ -169,13 +180,13 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
169 } 180 }
170 181
171 d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT; 182 d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT;
172 d->dma.addr_low = lower_32_bits(pa); 183 wil_desc_addr_set(&d->dma.addr, pa);
173 d->dma.addr_high = (u16)upper_32_bits(pa);
174 /* ip_length don't care */ 184 /* ip_length don't care */
175 /* b11 don't care */ 185 /* b11 don't care */
176 /* error don't care */ 186 /* error don't care */
177 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 187 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
178 d->dma.length = sz; 188 d->dma.length = cpu_to_le16(sz);
189 *_d = *d;
179 vring->ctx[i] = skb; 190 vring->ctx[i] = skb;
180 191
181 return 0; 192 return 0;
@@ -321,11 +332,12 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
321{ 332{
322 struct device *dev = wil_to_dev(wil); 333 struct device *dev = wil_to_dev(wil);
323 struct net_device *ndev = wil_to_ndev(wil); 334 struct net_device *ndev = wil_to_ndev(wil);
324 volatile struct vring_rx_desc *d; 335 volatile struct vring_rx_desc *_d;
325 struct vring_rx_desc *d1; 336 struct vring_rx_desc *d;
326 struct sk_buff *skb; 337 struct sk_buff *skb;
327 dma_addr_t pa; 338 dma_addr_t pa;
328 unsigned int sz = RX_BUF_LEN; 339 unsigned int sz = RX_BUF_LEN;
340 u16 dmalen;
329 u8 ftype; 341 u8 ftype;
330 u8 ds_bits; 342 u8 ds_bits;
331 343
@@ -334,32 +346,44 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
334 if (wil_vring_is_empty(vring)) 346 if (wil_vring_is_empty(vring))
335 return NULL; 347 return NULL;
336 348
337 d = &(vring->va[vring->swhead].rx); 349 _d = &(vring->va[vring->swhead].rx);
338 if (!(d->dma.status & RX_DMA_STATUS_DU)) { 350 if (!(_d->dma.status & RX_DMA_STATUS_DU)) {
339 /* it is not error, we just reached end of Rx done area */ 351 /* it is not error, we just reached end of Rx done area */
340 return NULL; 352 return NULL;
341 } 353 }
342 354
343 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
344 skb = vring->ctx[vring->swhead]; 355 skb = vring->ctx[vring->swhead];
356 d = wil_skb_rxdesc(skb);
357 *d = *_d;
358 pa = wil_desc_addr(&d->dma.addr);
359 vring->ctx[vring->swhead] = NULL;
360 wil_vring_advance_head(vring, 1);
361
345 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); 362 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
346 skb_trim(skb, d->dma.length); 363 dmalen = le16_to_cpu(d->dma.length);
347 364
348 d1 = wil_skb_rxdesc(skb); 365 trace_wil6210_rx(vring->swhead, d);
349 *d1 = *d; 366 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, dmalen);
367 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
368 (const void *)d, sizeof(*d), false);
350 369
351 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1); 370 if (dmalen > sz) {
371 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
372 kfree_skb(skb);
373 return NULL;
374 }
375 skb_trim(skb, dmalen);
376
377 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
378 skb->data, skb_headlen(skb), false);
379
380
381 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d);
352 382
353 /* use radiotap header only if required */ 383 /* use radiotap header only if required */
354 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 384 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
355 wil_rx_add_radiotap_header(wil, skb); 385 wil_rx_add_radiotap_header(wil, skb);
356 386
357 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
358 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
359 (const void *)d, sizeof(*d), false);
360
361 wil_vring_advance_head(vring, 1);
362
363 /* no extra checks if in sniffer mode */ 387 /* no extra checks if in sniffer mode */
364 if (ndev->type != ARPHRD_ETHER) 388 if (ndev->type != ARPHRD_ETHER)
365 return skb; 389 return skb;
@@ -368,7 +392,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
368 * Driver should recognize it by frame type, that is found 392 * Driver should recognize it by frame type, that is found
369 * in Rx descriptor. If type is not data, it is 802.11 frame as is 393 * in Rx descriptor. If type is not data, it is 802.11 frame as is
370 */ 394 */
371 ftype = wil_rxdesc_ftype(d1) << 2; 395 ftype = wil_rxdesc_ftype(d) << 2;
372 if (ftype != IEEE80211_FTYPE_DATA) { 396 if (ftype != IEEE80211_FTYPE_DATA) {
373 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); 397 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
374 /* TODO: process it */ 398 /* TODO: process it */
@@ -383,7 +407,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
383 return NULL; 407 return NULL;
384 } 408 }
385 409
386 ds_bits = wil_rxdesc_ds_bits(d1); 410 ds_bits = wil_rxdesc_ds_bits(d);
387 if (ds_bits == 1) { 411 if (ds_bits == 1) {
388 /* 412 /*
389 * HW bug - in ToDS mode, i.e. Rx on AP side, 413 * HW bug - in ToDS mode, i.e. Rx on AP side,
@@ -425,6 +449,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
425 449
426/* 450/*
427 * Pass Rx packet to the netif. Update statistics. 451 * Pass Rx packet to the netif. Update statistics.
452 * Called in softirq context (NAPI poll).
428 */ 453 */
429static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 454static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
430{ 455{
@@ -433,10 +458,7 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
433 458
434 skb_orphan(skb); 459 skb_orphan(skb);
435 460
436 if (in_interrupt()) 461 rc = netif_receive_skb(skb);
437 rc = netif_rx(skb);
438 else
439 rc = netif_rx_ni(skb);
440 462
441 if (likely(rc == NET_RX_SUCCESS)) { 463 if (likely(rc == NET_RX_SUCCESS)) {
442 ndev->stats.rx_packets++; 464 ndev->stats.rx_packets++;
@@ -450,9 +472,9 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
450/** 472/**
451 * Proceed all completed skb's from Rx VRING 473 * Proceed all completed skb's from Rx VRING
452 * 474 *
453 * Safe to call from IRQ 475 * Safe to call from NAPI poll, i.e. softirq with interrupts enabled
454 */ 476 */
455void wil_rx_handle(struct wil6210_priv *wil) 477void wil_rx_handle(struct wil6210_priv *wil, int *quota)
456{ 478{
457 struct net_device *ndev = wil_to_ndev(wil); 479 struct net_device *ndev = wil_to_ndev(wil);
458 struct vring *v = &wil->vring_rx; 480 struct vring *v = &wil->vring_rx;
@@ -463,9 +485,8 @@ void wil_rx_handle(struct wil6210_priv *wil)
463 return; 485 return;
464 } 486 }
465 wil_dbg_txrx(wil, "%s()\n", __func__); 487 wil_dbg_txrx(wil, "%s()\n", __func__);
466 while (NULL != (skb = wil_vring_reap_rx(wil, v))) { 488 while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
467 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, 489 (*quota)--;
468 skb->data, skb_headlen(skb), false);
469 490
470 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 491 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
471 skb->dev = ndev; 492 skb->dev = ndev;
@@ -600,17 +621,15 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
600 return NULL; 621 return NULL;
601} 622}
602 623
603static int wil_tx_desc_map(volatile struct vring_tx_desc *d, 624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len)
604 dma_addr_t pa, u32 len)
605{ 625{
606 d->dma.addr_low = lower_32_bits(pa); 626 wil_desc_addr_set(&d->dma.addr, pa);
607 d->dma.addr_high = (u16)upper_32_bits(pa);
608 d->dma.ip_length = 0; 627 d->dma.ip_length = 0;
609 /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/ 628 /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/
610 d->dma.b11 = 0/*14 | BIT(7)*/; 629 d->dma.b11 = 0/*14 | BIT(7)*/;
611 d->dma.error = 0; 630 d->dma.error = 0;
612 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 631 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
613 d->dma.length = len; 632 d->dma.length = cpu_to_le16((u16)len);
614 d->dma.d0 = 0; 633 d->dma.d0 = 0;
615 d->mac.d[0] = 0; 634 d->mac.d[0] = 0;
616 d->mac.d[1] = 0; 635 d->mac.d[1] = 0;
@@ -630,7 +649,8 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
630 struct sk_buff *skb) 649 struct sk_buff *skb)
631{ 650{
632 struct device *dev = wil_to_dev(wil); 651 struct device *dev = wil_to_dev(wil);
633 volatile struct vring_tx_desc *d; 652 struct vring_tx_desc dd, *d = &dd;
653 volatile struct vring_tx_desc *_d;
634 u32 swhead = vring->swhead; 654 u32 swhead = vring->swhead;
635 int avail = wil_vring_avail_tx(vring); 655 int avail = wil_vring_avail_tx(vring);
636 int nr_frags = skb_shinfo(skb)->nr_frags; 656 int nr_frags = skb_shinfo(skb)->nr_frags;
@@ -648,7 +668,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
648 1 + nr_frags); 668 1 + nr_frags);
649 return -ENOMEM; 669 return -ENOMEM;
650 } 670 }
651 d = &(vring->va[i].tx); 671 _d = &(vring->va[i].tx);
652 672
653 /* FIXME FW can accept only unicast frames for the peer */ 673 /* FIXME FW can accept only unicast frames for the peer */
654 memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN); 674 memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
@@ -667,25 +687,30 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
667 wil_tx_desc_map(d, pa, skb_headlen(skb)); 687 wil_tx_desc_map(d, pa, skb_headlen(skb));
668 d->mac.d[2] |= ((nr_frags + 1) << 688 d->mac.d[2] |= ((nr_frags + 1) <<
669 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); 689 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
690 if (nr_frags)
691 *_d = *d;
692
670 /* middle segments */ 693 /* middle segments */
671 for (f = 0; f < nr_frags; f++) { 694 for (f = 0; f < nr_frags; f++) {
672 const struct skb_frag_struct *frag = 695 const struct skb_frag_struct *frag =
673 &skb_shinfo(skb)->frags[f]; 696 &skb_shinfo(skb)->frags[f];
674 int len = skb_frag_size(frag); 697 int len = skb_frag_size(frag);
675 i = (swhead + f + 1) % vring->size; 698 i = (swhead + f + 1) % vring->size;
676 d = &(vring->va[i].tx); 699 _d = &(vring->va[i].tx);
677 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), 700 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
678 DMA_TO_DEVICE); 701 DMA_TO_DEVICE);
679 if (unlikely(dma_mapping_error(dev, pa))) 702 if (unlikely(dma_mapping_error(dev, pa)))
680 goto dma_error; 703 goto dma_error;
681 wil_tx_desc_map(d, pa, len); 704 wil_tx_desc_map(d, pa, len);
682 vring->ctx[i] = NULL; 705 vring->ctx[i] = NULL;
706 *_d = *d;
683 } 707 }
684 /* for the last seg only */ 708 /* for the last seg only */
685 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 709 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
686 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ 710 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */
687 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
688 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS); 712 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
713 *_d = *d;
689 714
690 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
691 (const void *)d, sizeof(*d), false); 716 (const void *)d, sizeof(*d), false);
@@ -693,6 +718,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
693 /* advance swhead */ 718 /* advance swhead */
694 wil_vring_advance_head(vring, nr_frags + 1); 719 wil_vring_advance_head(vring, nr_frags + 1);
695 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 720 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
721 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
696 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 722 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
697 /* hold reference to skb 723 /* hold reference to skb
698 * to prevent skb release before accounting 724 * to prevent skb release before accounting
@@ -705,14 +731,18 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
705 /* unmap what we have mapped */ 731 /* unmap what we have mapped */
706 /* Note: increment @f to operate with positive index */ 732 /* Note: increment @f to operate with positive index */
707 for (f++; f > 0; f--) { 733 for (f++; f > 0; f--) {
734 u16 dmalen;
735
708 i = (swhead + f) % vring->size; 736 i = (swhead + f) % vring->size;
709 d = &(vring->va[i].tx); 737 _d = &(vring->va[i].tx);
710 d->dma.status = TX_DMA_STATUS_DU; 738 *d = *_d;
711 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); 739 _d->dma.status = TX_DMA_STATUS_DU;
740 pa = wil_desc_addr(&d->dma.addr);
741 dmalen = le16_to_cpu(d->dma.length);
712 if (vring->ctx[i]) 742 if (vring->ctx[i])
713 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); 743 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
714 else 744 else
715 dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); 745 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
716 } 746 }
717 747
718 return -EINVAL; 748 return -EINVAL;
@@ -761,7 +791,6 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
761 break; /* goto drop; */ 791 break; /* goto drop; */
762 } 792 }
763 drop: 793 drop:
764 netif_tx_stop_all_queues(ndev);
765 ndev->stats.tx_dropped++; 794 ndev->stats.tx_dropped++;
766 dev_kfree_skb_any(skb); 795 dev_kfree_skb_any(skb);
767 796
@@ -771,41 +800,48 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
771/** 800/**
772 * Clean up transmitted skb's from the Tx VRING 801 * Clean up transmitted skb's from the Tx VRING
773 * 802 *
803 * Return number of descriptors cleared
804 *
774 * Safe to call from IRQ 805 * Safe to call from IRQ
775 */ 806 */
776void wil_tx_complete(struct wil6210_priv *wil, int ringid) 807int wil_tx_complete(struct wil6210_priv *wil, int ringid)
777{ 808{
778 struct net_device *ndev = wil_to_ndev(wil); 809 struct net_device *ndev = wil_to_ndev(wil);
779 struct device *dev = wil_to_dev(wil); 810 struct device *dev = wil_to_dev(wil);
780 struct vring *vring = &wil->vring_tx[ringid]; 811 struct vring *vring = &wil->vring_tx[ringid];
812 int done = 0;
781 813
782 if (!vring->va) { 814 if (!vring->va) {
783 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 815 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
784 return; 816 return 0;
785 } 817 }
786 818
787 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); 819 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
788 820
789 while (!wil_vring_is_empty(vring)) { 821 while (!wil_vring_is_empty(vring)) {
790 volatile struct vring_tx_desc *d1 = 822 volatile struct vring_tx_desc *_d =
791 &vring->va[vring->swtail].tx; 823 &vring->va[vring->swtail].tx;
792 struct vring_tx_desc dd, *d = &dd; 824 struct vring_tx_desc dd, *d = &dd;
793 dma_addr_t pa; 825 dma_addr_t pa;
794 struct sk_buff *skb; 826 struct sk_buff *skb;
827 u16 dmalen;
795 828
796 dd = *d1; 829 *d = *_d;
797 830
798 if (!(d->dma.status & TX_DMA_STATUS_DU)) 831 if (!(d->dma.status & TX_DMA_STATUS_DU))
799 break; 832 break;
800 833
834 dmalen = le16_to_cpu(d->dma.length);
835 trace_wil6210_tx_done(ringid, vring->swtail, dmalen,
836 d->dma.error);
801 wil_dbg_txrx(wil, 837 wil_dbg_txrx(wil,
802 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", 838 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
803 vring->swtail, d->dma.length, d->dma.status, 839 vring->swtail, dmalen, d->dma.status,
804 d->dma.error); 840 d->dma.error);
805 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, 841 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
806 (const void *)d, sizeof(*d), false); 842 (const void *)d, sizeof(*d), false);
807 843
808 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); 844 pa = wil_desc_addr(&d->dma.addr);
809 skb = vring->ctx[vring->swtail]; 845 skb = vring->ctx[vring->swtail];
810 if (skb) { 846 if (skb) {
811 if (d->dma.error == 0) { 847 if (d->dma.error == 0) {
@@ -815,18 +851,21 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
815 ndev->stats.tx_errors++; 851 ndev->stats.tx_errors++;
816 } 852 }
817 853
818 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); 854 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
819 dev_kfree_skb_any(skb); 855 dev_kfree_skb_any(skb);
820 vring->ctx[vring->swtail] = NULL; 856 vring->ctx[vring->swtail] = NULL;
821 } else { 857 } else {
822 dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); 858 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
823 } 859 }
824 d->dma.addr_low = 0; 860 d->dma.addr.addr_low = 0;
825 d->dma.addr_high = 0; 861 d->dma.addr.addr_high = 0;
826 d->dma.length = 0; 862 d->dma.length = 0;
827 d->dma.status = TX_DMA_STATUS_DU; 863 d->dma.status = TX_DMA_STATUS_DU;
828 vring->swtail = wil_vring_next_tail(vring); 864 vring->swtail = wil_vring_next_tail(vring);
865 done++;
829 } 866 }
830 if (wil_vring_avail_tx(vring) > vring->size/4) 867 if (wil_vring_avail_tx(vring) > vring->size/4)
831 netif_tx_wake_all_queues(wil_to_ndev(wil)); 868 netif_tx_wake_all_queues(wil_to_ndev(wil));
869
870 return done;
832} 871}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index adef12fb2aee..23c0781cdb93 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -27,6 +27,28 @@
27#define WIL6210_RTAP_SIZE (128) 27#define WIL6210_RTAP_SIZE (128)
28 28
29/* Tx/Rx path */ 29/* Tx/Rx path */
30
31/*
32 * Common representation of physical address in Vring
33 */
34struct vring_dma_addr {
35 __le32 addr_low;
36 __le16 addr_high;
37} __packed;
38
39static inline dma_addr_t wil_desc_addr(struct vring_dma_addr *addr)
40{
41 return le32_to_cpu(addr->addr_low) |
42 ((u64)le16_to_cpu(addr->addr_high) << 32);
43}
44
45static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
46 dma_addr_t pa)
47{
48 addr->addr_low = cpu_to_le32(lower_32_bits(pa));
49 addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa));
50}
51
30/* 52/*
31 * Tx descriptor - MAC part 53 * Tx descriptor - MAC part
32 * [dword 0] 54 * [dword 0]
@@ -216,13 +238,12 @@ struct vring_tx_mac {
216 238
217struct vring_tx_dma { 239struct vring_tx_dma {
218 u32 d0; 240 u32 d0;
219 u32 addr_low; 241 struct vring_dma_addr addr;
220 u16 addr_high;
221 u8 ip_length; 242 u8 ip_length;
222 u8 b11; /* 0..6: mac_length; 7:ip_version */ 243 u8 b11; /* 0..6: mac_length; 7:ip_version */
223 u8 error; /* 0..2: err; 3..7: reserved; */ 244 u8 error; /* 0..2: err; 3..7: reserved; */
224 u8 status; /* 0: used; 1..7; reserved */ 245 u8 status; /* 0: used; 1..7; reserved */
225 u16 length; 246 __le16 length;
226} __packed; 247} __packed;
227 248
228/* 249/*
@@ -315,13 +336,12 @@ struct vring_rx_mac {
315 336
316struct vring_rx_dma { 337struct vring_rx_dma {
317 u32 d0; 338 u32 d0;
318 u32 addr_low; 339 struct vring_dma_addr addr;
319 u16 addr_high;
320 u8 ip_length; 340 u8 ip_length;
321 u8 b11; 341 u8 b11;
322 u8 error; 342 u8 error;
323 u8 status; 343 u8 status;
324 u16 length; 344 __le16 length;
325} __packed; 345} __packed;
326 346
327struct vring_tx_desc { 347struct vring_tx_desc {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 8f76ecd8a7e5..373cf656f5b0 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -34,9 +34,11 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
34 34
35#define WIL6210_MEM_SIZE (2*1024*1024UL) 35#define WIL6210_MEM_SIZE (2*1024*1024UL)
36 36
37#define WIL6210_RX_RING_SIZE (128) 37#define WIL6210_RX_RING_SIZE (128)
38#define WIL6210_TX_RING_SIZE (128) 38#define WIL6210_TX_RING_SIZE (128)
39#define WIL6210_MAX_TX_RINGS (24) 39#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
40#define WIL6210_MAX_CID (8) /* HW limit */
41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
40 42
41/* Hardware definitions begin */ 43/* Hardware definitions begin */
42 44
@@ -184,6 +186,7 @@ struct vring {
184 186
185enum { /* for wil6210_priv.status */ 187enum { /* for wil6210_priv.status */
186 wil_status_fwready = 0, 188 wil_status_fwready = 0,
189 wil_status_fwconnecting,
187 wil_status_fwconnected, 190 wil_status_fwconnected,
188 wil_status_dontscan, 191 wil_status_dontscan,
189 wil_status_reset_done, 192 wil_status_reset_done,
@@ -239,6 +242,8 @@ struct wil6210_priv {
239 * - consumed in thread by wmi_event_worker 242 * - consumed in thread by wmi_event_worker
240 */ 243 */
241 spinlock_t wmi_ev_lock; 244 spinlock_t wmi_ev_lock;
245 struct napi_struct napi_rx;
246 struct napi_struct napi_tx;
242 /* DMA related */ 247 /* DMA related */
243 struct vring vring_rx; 248 struct vring vring_rx;
244 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 249 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -267,9 +272,13 @@ struct wil6210_priv {
267#define wil_to_ndev(i) (wil_to_wdev(i)->netdev) 272#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
268#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) 273#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
269 274
270#define wil_dbg(wil, fmt, arg...) netdev_dbg(wil_to_ndev(wil), fmt, ##arg) 275int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...);
271#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg) 276int wil_err(struct wil6210_priv *wil, const char *fmt, ...);
272#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg) 277int wil_info(struct wil6210_priv *wil, const char *fmt, ...);
278#define wil_dbg(wil, fmt, arg...) do { \
279 netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \
280 wil_dbg_trace(wil, fmt, ##arg); \
281} while (0)
273 282
274#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg) 283#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
275#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg) 284#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
@@ -356,10 +365,12 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
356void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 365void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
357 366
358netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 367netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
359void wil_tx_complete(struct wil6210_priv *wil, int ringid); 368int wil_tx_complete(struct wil6210_priv *wil, int ringid);
369void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
360 370
361/* RX API */ 371/* RX API */
362void wil_rx_handle(struct wil6210_priv *wil); 372void wil_rx_handle(struct wil6210_priv *wil, int *quota);
373void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
363 374
364int wil_iftype_nl2wmi(enum nl80211_iftype type); 375int wil_iftype_nl2wmi(enum nl80211_iftype type);
365 376
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 45b04e383f9a..527ffb543821 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -20,6 +20,7 @@
20#include "wil6210.h" 20#include "wil6210.h"
21#include "txrx.h" 21#include "txrx.h"
22#include "wmi.h" 22#include "wmi.h"
23#include "trace.h"
23 24
24/** 25/**
25 * WMI event receiving - theory of operations 26 * WMI event receiving - theory of operations
@@ -246,6 +247,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
246 iowrite32(r->head = next_head, wil->csr + HOST_MBOX + 247 iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
247 offsetof(struct wil6210_mbox_ctl, tx.head)); 248 offsetof(struct wil6210_mbox_ctl, tx.head));
248 249
250 trace_wil6210_wmi_cmd(cmdid, buf, len);
251
249 /* interrupt to FW */ 252 /* interrupt to FW */
250 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT); 253 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
251 254
@@ -406,7 +409,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
406 409
407 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 410 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
408 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 411 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
409 if (wdev->sme_state != CFG80211_SME_CONNECTING) { 412 if (!test_bit(wil_status_fwconnecting, &wil->status)) {
410 wil_err(wil, "Not in connecting state\n"); 413 wil_err(wil, "Not in connecting state\n");
411 return; 414 return;
412 } 415 }
@@ -430,6 +433,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
430 433
431 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 434 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
432 } 435 }
436 clear_bit(wil_status_fwconnecting, &wil->status);
433 set_bit(wil_status_fwconnected, &wil->status); 437 set_bit(wil_status_fwconnected, &wil->status);
434 438
435 /* FIXME FW can transmit only ucast frames to peer */ 439 /* FIXME FW can transmit only ucast frames to peer */
@@ -635,8 +639,9 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
635 hdr.flags); 639 hdr.flags);
636 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 640 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
637 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { 641 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
638 wil_dbg_wmi(wil, "WMI event 0x%04x\n", 642 u16 id = le16_to_cpu(evt->event.wmi.id);
639 evt->event.wmi.id); 643 wil_dbg_wmi(wil, "WMI event 0x%04x\n", id);
644 trace_wil6210_wmi_event(id, &evt->event.wmi, len);
640 } 645 }
641 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1, 646 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
642 &evt->event.hdr, sizeof(hdr) + len, true); 647 &evt->event.hdr, sizeof(hdr) + len, true);
@@ -724,7 +729,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
724 .bcon_interval = cpu_to_le16(bi), 729 .bcon_interval = cpu_to_le16(bi),
725 .network_type = wmi_nettype, 730 .network_type = wmi_nettype,
726 .disable_sec_offload = 1, 731 .disable_sec_offload = 1,
727 .channel = chan, 732 .channel = chan - 1,
728 }; 733 };
729 struct { 734 struct {
730 struct wil6210_mbox_hdr_wmi wmi; 735 struct wil6210_mbox_hdr_wmi wmi;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 44fa0cdbf97b..11400b39cf0b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -606,7 +606,8 @@ static int brcmf_sdio_pd_remove(struct platform_device *pdev)
606static struct platform_driver brcmf_sdio_pd = { 606static struct platform_driver brcmf_sdio_pd = {
607 .remove = brcmf_sdio_pd_remove, 607 .remove = brcmf_sdio_pd_remove,
608 .driver = { 608 .driver = {
609 .name = BRCMFMAC_SDIO_PDATA_NAME 609 .name = BRCMFMAC_SDIO_PDATA_NAME,
610 .owner = THIS_MODULE,
610 } 611 }
611}; 612};
612 613
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 1585cc5bf866..bd982856d385 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
900 if (supr_status) { 900 if (supr_status) {
901 update_rate = false; 901 update_rate = false;
902 if (supr_status == TX_STATUS_SUPR_BADCH) { 902 if (supr_status == TX_STATUS_SUPR_BADCH) {
903 brcms_err(wlc->hw->d11core, 903 brcms_dbg_ht(wlc->hw->d11core,
904 "%s: Pkt tx suppressed, illegal channel possibly %d\n", 904 "%s: Pkt tx suppressed, illegal channel possibly %d\n",
905 __func__, CHSPEC_CHANNEL( 905 __func__, CHSPEC_CHANNEL(
906 wlc->default_bss->chanspec)); 906 wlc->default_bss->chanspec));
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
new file mode 100644
index 000000000000..7a585d4e9c8e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -0,0 +1,45 @@
1config CW1200
2 tristate "CW1200 WLAN support"
3 depends on MAC80211 && CFG80211
4 help
5 This is a driver for the ST-E CW1100 & CW1200 WLAN chipsets.
6 This option just enables the driver core, see below for
7 specific bus support.
8
9if CW1200
10
11config CW1200_WLAN_SDIO
12 tristate "Support SDIO platforms"
13 depends on CW1200 && MMC
14 help
15 Enable support for the CW1200 connected via an SDIO bus.
16 By default this driver only supports the Sagrad SG901-1091/1098 EVK
17 and similar designs that utilize a hardware reset circuit. To
18 support different CW1200 SDIO designs you will need to override
19 the default platform data by calling cw1200_sdio_set_platform_data()
20 in your board setup file.
21
22config CW1200_WLAN_SPI
23 tristate "Support SPI platforms"
24 depends on CW1200 && SPI
25 help
26 Enables support for the CW1200 connected via a SPI bus. You will
27 need to add appropriate platform data glue in your board setup
28 file.
29
30menu "Driver debug features"
31 depends on CW1200 && DEBUG_FS
32
33config CW1200_ETF
34 bool "Enable CW1200 Engineering Test Framework hooks"
35 help
36 If you don't know what this is, just say N.
37
38config CW1200_ITP
39 bool "Enable ITP access"
40 help
41 If you don't know what this is, just say N.
42
43endmenu
44
45endif
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
new file mode 100644
index 000000000000..bc6cbf91f26e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -0,0 +1,22 @@
1cw1200_core-y := \
2 fwio.o \
3 txrx.o \
4 main.o \
5 queue.o \
6 hwio.o \
7 bh.o \
8 wsm.o \
9 sta.o \
10 scan.o \
11 debug.o
12cw1200_core-$(CONFIG_CW1200_ITP) += itp.o
13cw1200_core-$(CONFIG_PM) += pm.o
14
15# CFLAGS_sta.o += -DDEBUG
16
17cw1200_wlan_sdio-y := cw1200_sdio.o
18cw1200_wlan_spi-y := cw1200_spi.o
19
20obj-$(CONFIG_CW1200) += cw1200_core.o
21obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
22obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
diff --git a/drivers/net/wireless/cw1200/bh.c b/drivers/net/wireless/cw1200/bh.c
new file mode 100644
index 000000000000..324b57001da0
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.c
@@ -0,0 +1,616 @@
1/*
2 * Device handling thread implementation for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/module.h>
18#include <net/mac80211.h>
19#include <linux/kthread.h>
20#include <linux/timer.h>
21
22#include "cw1200.h"
23#include "bh.h"
24#include "hwio.h"
25#include "wsm.h"
26#include "hwbus.h"
27#include "debug.h"
28#include "fwio.h"
29
30static int cw1200_bh(void *arg);
31
32#define DOWNLOAD_BLOCK_SIZE_WR (0x1000 - 4)
33/* an SPI message cannot be bigger than (2"12-1)*2 bytes
34 * "*2" to cvt to bytes */
35#define MAX_SZ_RD_WR_BUFFERS (DOWNLOAD_BLOCK_SIZE_WR*2)
36#define PIGGYBACK_CTRL_REG (2)
37#define EFFECTIVE_BUF_SIZE (MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
38
39/* Suspend state privates */
40enum cw1200_bh_pm_state {
41 CW1200_BH_RESUMED = 0,
42 CW1200_BH_SUSPEND,
43 CW1200_BH_SUSPENDED,
44 CW1200_BH_RESUME,
45};
46
47typedef int (*cw1200_wsm_handler)(struct cw1200_common *priv,
48 u8 *data, size_t size);
49
50static void cw1200_bh_work(struct work_struct *work)
51{
52 struct cw1200_common *priv =
53 container_of(work, struct cw1200_common, bh_work);
54 cw1200_bh(priv);
55}
56
57int cw1200_register_bh(struct cw1200_common *priv)
58{
59 int err = 0;
60 /* Realtime workqueue */
61 priv->bh_workqueue = alloc_workqueue("cw1200_bh",
62 WQ_MEM_RECLAIM | WQ_HIGHPRI
63 | WQ_CPU_INTENSIVE, 1);
64
65 if (!priv->bh_workqueue)
66 return -ENOMEM;
67
68 INIT_WORK(&priv->bh_work, cw1200_bh_work);
69
70 pr_debug("[BH] register.\n");
71
72 atomic_set(&priv->bh_rx, 0);
73 atomic_set(&priv->bh_tx, 0);
74 atomic_set(&priv->bh_term, 0);
75 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
76 priv->bh_error = 0;
77 priv->hw_bufs_used = 0;
78 priv->buf_id_tx = 0;
79 priv->buf_id_rx = 0;
80 init_waitqueue_head(&priv->bh_wq);
81 init_waitqueue_head(&priv->bh_evt_wq);
82
83 err = !queue_work(priv->bh_workqueue, &priv->bh_work);
84 WARN_ON(err);
85 return err;
86}
87
88void cw1200_unregister_bh(struct cw1200_common *priv)
89{
90 atomic_add(1, &priv->bh_term);
91 wake_up(&priv->bh_wq);
92
93 flush_workqueue(priv->bh_workqueue);
94
95 destroy_workqueue(priv->bh_workqueue);
96 priv->bh_workqueue = NULL;
97
98 pr_debug("[BH] unregistered.\n");
99}
100
101void cw1200_irq_handler(struct cw1200_common *priv)
102{
103 pr_debug("[BH] irq.\n");
104
105 /* Disable Interrupts! */
106 /* NOTE: hwbus_ops->lock already held */
107 __cw1200_irq_enable(priv, 0);
108
109 if (/* WARN_ON */(priv->bh_error))
110 return;
111
112 if (atomic_add_return(1, &priv->bh_rx) == 1)
113 wake_up(&priv->bh_wq);
114}
115EXPORT_SYMBOL_GPL(cw1200_irq_handler);
116
117void cw1200_bh_wakeup(struct cw1200_common *priv)
118{
119 pr_debug("[BH] wakeup.\n");
120 if (priv->bh_error) {
121 pr_err("[BH] wakeup failed (BH error)\n");
122 return;
123 }
124
125 if (atomic_add_return(1, &priv->bh_tx) == 1)
126 wake_up(&priv->bh_wq);
127}
128
129int cw1200_bh_suspend(struct cw1200_common *priv)
130{
131 pr_debug("[BH] suspend.\n");
132 if (priv->bh_error) {
133 wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n");
134 return -EINVAL;
135 }
136
137 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND);
138 wake_up(&priv->bh_wq);
139 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
140 (CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)),
141 1 * HZ) ? 0 : -ETIMEDOUT;
142}
143
144int cw1200_bh_resume(struct cw1200_common *priv)
145{
146 pr_debug("[BH] resume.\n");
147 if (priv->bh_error) {
148 wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n");
149 return -EINVAL;
150 }
151
152 atomic_set(&priv->bh_suspend, CW1200_BH_RESUME);
153 wake_up(&priv->bh_wq);
154 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
155 (CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)),
156 1 * HZ) ? 0 : -ETIMEDOUT;
157}
158
159static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv)
160{
161 ++priv->hw_bufs_used;
162}
163
164int wsm_release_tx_buffer(struct cw1200_common *priv, int count)
165{
166 int ret = 0;
167 int hw_bufs_used = priv->hw_bufs_used;
168
169 priv->hw_bufs_used -= count;
170 if (WARN_ON(priv->hw_bufs_used < 0))
171 ret = -1;
172 else if (hw_bufs_used >= priv->wsm_caps.input_buffers)
173 ret = 1;
174 if (!priv->hw_bufs_used)
175 wake_up(&priv->bh_evt_wq);
176 return ret;
177}
178
179static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv,
180 u16 *ctrl_reg)
181{
182 int ret;
183
184 ret = cw1200_reg_read_16(priv,
185 ST90TDS_CONTROL_REG_ID, ctrl_reg);
186 if (ret) {
187 ret = cw1200_reg_read_16(priv,
188 ST90TDS_CONTROL_REG_ID, ctrl_reg);
189 if (ret)
190 pr_err("[BH] Failed to read control register.\n");
191 }
192
193 return ret;
194}
195
196static int cw1200_device_wakeup(struct cw1200_common *priv)
197{
198 u16 ctrl_reg;
199 int ret;
200
201 pr_debug("[BH] Device wakeup.\n");
202
203 /* First, set the dpll register */
204 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
205 cw1200_dpll_from_clk(priv->hw_refclk));
206 if (WARN_ON(ret))
207 return ret;
208
209 /* To force the device to be always-on, the host sets WLAN_UP to 1 */
210 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
211 ST90TDS_CONT_WUP_BIT);
212 if (WARN_ON(ret))
213 return ret;
214
215 ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg);
216 if (WARN_ON(ret))
217 return ret;
218
219 /* If the device returns WLAN_RDY as 1, the device is active and will
220 * remain active. */
221 if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
222 pr_debug("[BH] Device awake.\n");
223 return 1;
224 }
225
226 return 0;
227}
228
229/* Must be called from BH thraed. */
230void cw1200_enable_powersave(struct cw1200_common *priv,
231 bool enable)
232{
233 pr_debug("[BH] Powerave is %s.\n",
234 enable ? "enabled" : "disabled");
235 priv->powersave_enabled = enable;
236}
237
238static int cw1200_bh_rx_helper(struct cw1200_common *priv,
239 uint16_t *ctrl_reg,
240 int *tx)
241{
242 size_t read_len = 0;
243 struct sk_buff *skb_rx = NULL;
244 struct wsm_hdr *wsm;
245 size_t wsm_len;
246 u16 wsm_id;
247 u8 wsm_seq;
248 int rx_resync = 1;
249
250 size_t alloc_len;
251 u8 *data;
252
253 read_len = (*ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
254 if (!read_len)
255 return 0; /* No more work */
256
257 if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
258 (read_len > EFFECTIVE_BUF_SIZE))) {
259 pr_debug("Invalid read len: %zu (%04x)",
260 read_len, *ctrl_reg);
261 goto err;
262 }
263
264 /* Add SIZE of PIGGYBACK reg (CONTROL Reg)
265 * to the NEXT Message length + 2 Bytes for SKB */
266 read_len = read_len + 2;
267
268 alloc_len = priv->hwbus_ops->align_size(
269 priv->hwbus_priv, read_len);
270
271 /* Check if not exceeding CW1200 capabilities */
272 if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
273 pr_debug("Read aligned len: %zu\n",
274 alloc_len);
275 }
276
277 skb_rx = dev_alloc_skb(alloc_len);
278 if (WARN_ON(!skb_rx))
279 goto err;
280
281 skb_trim(skb_rx, 0);
282 skb_put(skb_rx, read_len);
283 data = skb_rx->data;
284 if (WARN_ON(!data))
285 goto err;
286
287 if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) {
288 pr_err("rx blew up, len %zu\n", alloc_len);
289 goto err;
290 }
291
292 /* Piggyback */
293 *ctrl_reg = __le16_to_cpu(
294 ((__le16 *)data)[alloc_len / 2 - 1]);
295
296 wsm = (struct wsm_hdr *)data;
297 wsm_len = __le16_to_cpu(wsm->len);
298 if (WARN_ON(wsm_len > read_len))
299 goto err;
300
301 if (priv->wsm_enable_wsm_dumps)
302 print_hex_dump_bytes("<-- ",
303 DUMP_PREFIX_NONE,
304 data, wsm_len);
305
306 wsm_id = __le16_to_cpu(wsm->id) & 0xFFF;
307 wsm_seq = (__le16_to_cpu(wsm->id) >> 13) & 7;
308
309 skb_trim(skb_rx, wsm_len);
310
311 if (wsm_id == 0x0800) {
312 wsm_handle_exception(priv,
313 &data[sizeof(*wsm)],
314 wsm_len - sizeof(*wsm));
315 goto err;
316 } else if (!rx_resync) {
317 if (WARN_ON(wsm_seq != priv->wsm_rx_seq))
318 goto err;
319 }
320 priv->wsm_rx_seq = (wsm_seq + 1) & 7;
321 rx_resync = 0;
322
323 if (wsm_id & 0x0400) {
324 int rc = wsm_release_tx_buffer(priv, 1);
325 if (WARN_ON(rc < 0))
326 return rc;
327 else if (rc > 0)
328 *tx = 1;
329 }
330
331 /* cw1200_wsm_rx takes care on SKB livetime */
332 if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx)))
333 goto err;
334
335 if (skb_rx) {
336 dev_kfree_skb(skb_rx);
337 skb_rx = NULL;
338 }
339
340 return 0;
341
342err:
343 if (skb_rx) {
344 dev_kfree_skb(skb_rx);
345 skb_rx = NULL;
346 }
347 return -1;
348}
349
350static int cw1200_bh_tx_helper(struct cw1200_common *priv,
351 int *pending_tx,
352 int *tx_burst)
353{
354 size_t tx_len;
355 u8 *data;
356 int ret;
357 struct wsm_hdr *wsm;
358
359 if (priv->device_can_sleep) {
360 ret = cw1200_device_wakeup(priv);
361 if (WARN_ON(ret < 0)) { /* Error in wakeup */
362 *pending_tx = 1;
363 return 0;
364 } else if (ret) { /* Woke up */
365 priv->device_can_sleep = false;
366 } else { /* Did not awake */
367 *pending_tx = 1;
368 return 0;
369 }
370 }
371
372 wsm_alloc_tx_buffer(priv);
373 ret = wsm_get_tx(priv, &data, &tx_len, tx_burst);
374 if (ret <= 0) {
375 wsm_release_tx_buffer(priv, 1);
376 if (WARN_ON(ret < 0))
377 return ret; /* Error */
378 return 0; /* No work */
379 }
380
381 wsm = (struct wsm_hdr *)data;
382 BUG_ON(tx_len < sizeof(*wsm));
383 BUG_ON(__le16_to_cpu(wsm->len) != tx_len);
384
385 atomic_add(1, &priv->bh_tx);
386
387 tx_len = priv->hwbus_ops->align_size(
388 priv->hwbus_priv, tx_len);
389
390 /* Check if not exceeding CW1200 capabilities */
391 if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
392 pr_debug("Write aligned len: %zu\n", tx_len);
393
394 wsm->id &= __cpu_to_le16(0xffff ^ WSM_TX_SEQ(WSM_TX_SEQ_MAX));
395 wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq));
396
397 if (WARN_ON(cw1200_data_write(priv, data, tx_len))) {
398 pr_err("tx blew up, len %zu\n", tx_len);
399 wsm_release_tx_buffer(priv, 1);
400 return -1; /* Error */
401 }
402
403 if (priv->wsm_enable_wsm_dumps)
404 print_hex_dump_bytes("--> ",
405 DUMP_PREFIX_NONE,
406 data,
407 __le16_to_cpu(wsm->len));
408
409 wsm_txed(priv, data);
410 priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX;
411
412 if (*tx_burst > 1) {
413 cw1200_debug_tx_burst(priv);
414 return 1; /* Work remains */
415 }
416
417 return 0;
418}
419
420static int cw1200_bh(void *arg)
421{
422 struct cw1200_common *priv = arg;
423 int rx, tx, term, suspend;
424 u16 ctrl_reg = 0;
425 int tx_allowed;
426 int pending_tx = 0;
427 int tx_burst;
428 long status;
429 u32 dummy;
430 int ret;
431
432 for (;;) {
433 if (!priv->hw_bufs_used &&
434 priv->powersave_enabled &&
435 !priv->device_can_sleep &&
436 !atomic_read(&priv->recent_scan)) {
437 status = 1 * HZ;
438 pr_debug("[BH] Device wakedown. No data.\n");
439 cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0);
440 priv->device_can_sleep = true;
441 } else if (priv->hw_bufs_used) {
442 /* Interrupt loss detection */
443 status = 1 * HZ;
444 } else {
445 status = MAX_SCHEDULE_TIMEOUT;
446 }
447
448 /* Dummy Read for SDIO retry mechanism*/
449 if ((priv->hw_type != -1) &&
450 (atomic_read(&priv->bh_rx) == 0) &&
451 (atomic_read(&priv->bh_tx) == 0))
452 cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID,
453 &dummy, sizeof(dummy));
454
455 pr_debug("[BH] waiting ...\n");
456 status = wait_event_interruptible_timeout(priv->bh_wq, ({
457 rx = atomic_xchg(&priv->bh_rx, 0);
458 tx = atomic_xchg(&priv->bh_tx, 0);
459 term = atomic_xchg(&priv->bh_term, 0);
460 suspend = pending_tx ?
461 0 : atomic_read(&priv->bh_suspend);
462 (rx || tx || term || suspend || priv->bh_error);
463 }), status);
464
465 pr_debug("[BH] - rx: %d, tx: %d, term: %d, suspend: %d, status: %ld\n",
466 rx, tx, term, suspend, status);
467
468 /* Did an error occur? */
469 if ((status < 0 && status != -ERESTARTSYS) ||
470 term || priv->bh_error) {
471 break;
472 }
473 if (!status) { /* wait_event timed out */
474 unsigned long timestamp = jiffies;
475 long timeout;
476 int pending = 0;
477 int i;
478
479 /* Check to see if we have any outstanding frames */
480 if (priv->hw_bufs_used && (!rx || !tx)) {
481 wiphy_warn(priv->hw->wiphy,
482 "Missed interrupt? (%d frames outstanding)\n",
483 priv->hw_bufs_used);
484 rx = 1;
485
486 /* Get a timestamp of "oldest" frame */
487 for (i = 0; i < 4; ++i)
488 pending += cw1200_queue_get_xmit_timestamp(
489 &priv->tx_queue[i],
490 &timestamp,
491 priv->pending_frame_id);
492
493 /* Check if frame transmission is timed out.
494 * Add an extra second with respect to possible
495 * interrupt loss.
496 */
497 timeout = timestamp +
498 WSM_CMD_LAST_CHANCE_TIMEOUT +
499 1 * HZ -
500 jiffies;
501
502 /* And terminate BH thread if the frame is "stuck" */
503 if (pending && timeout < 0) {
504 wiphy_warn(priv->hw->wiphy,
505 "Timeout waiting for TX confirm (%d/%d pending, %ld vs %lu).\n",
506 priv->hw_bufs_used, pending,
507 timestamp, jiffies);
508 break;
509 }
510 } else if (!priv->device_can_sleep &&
511 !atomic_read(&priv->recent_scan)) {
512 pr_debug("[BH] Device wakedown. Timeout.\n");
513 cw1200_reg_write_16(priv,
514 ST90TDS_CONTROL_REG_ID, 0);
515 priv->device_can_sleep = true;
516 }
517 goto done;
518 } else if (suspend) {
519 pr_debug("[BH] Device suspend.\n");
520 if (priv->powersave_enabled) {
521 pr_debug("[BH] Device wakedown. Suspend.\n");
522 cw1200_reg_write_16(priv,
523 ST90TDS_CONTROL_REG_ID, 0);
524 priv->device_can_sleep = true;
525 }
526
527 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED);
528 wake_up(&priv->bh_evt_wq);
529 status = wait_event_interruptible(priv->bh_wq,
530 CW1200_BH_RESUME == atomic_read(&priv->bh_suspend));
531 if (status < 0) {
532 wiphy_err(priv->hw->wiphy,
533 "Failed to wait for resume: %ld.\n",
534 status);
535 break;
536 }
537 pr_debug("[BH] Device resume.\n");
538 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
539 wake_up(&priv->bh_evt_wq);
540 atomic_add(1, &priv->bh_rx);
541 goto done;
542 }
543
544 rx:
545 tx += pending_tx;
546 pending_tx = 0;
547
548 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
549 break;
550
551 /* Don't bother trying to rx unless we have data to read */
552 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
553 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
554 if (ret < 0)
555 break;
556 /* Double up here if there's more data.. */
557 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
558 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
559 if (ret < 0)
560 break;
561 }
562 }
563
564 tx:
565 if (tx) {
566 tx = 0;
567
568 BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers);
569 tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used;
570 tx_allowed = tx_burst > 0;
571
572 if (!tx_allowed) {
573 /* Buffers full. Ensure we process tx
574 * after we handle rx..
575 */
576 pending_tx = tx;
577 goto done_rx;
578 }
579 ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst);
580 if (ret < 0)
581 break;
582 if (ret > 0) /* More to transmit */
583 tx = ret;
584
585 /* Re-read ctrl reg */
586 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
587 break;
588 }
589
590 done_rx:
591 if (priv->bh_error)
592 break;
593 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
594 goto rx;
595 if (tx)
596 goto tx;
597
598 done:
599 /* Re-enable device interrupts */
600 priv->hwbus_ops->lock(priv->hwbus_priv);
601 __cw1200_irq_enable(priv, 1);
602 priv->hwbus_ops->unlock(priv->hwbus_priv);
603 }
604
605 /* Explicitly disable device interrupts */
606 priv->hwbus_ops->lock(priv->hwbus_priv);
607 __cw1200_irq_enable(priv, 0);
608 priv->hwbus_ops->unlock(priv->hwbus_priv);
609
610 if (!term) {
611 pr_err("[BH] Fatal error, exiting.\n");
612 priv->bh_error = 1;
613 /* TODO: schedule_work(recovery) */
614 }
615 return 0;
616}
diff --git a/drivers/net/wireless/cw1200/bh.h b/drivers/net/wireless/cw1200/bh.h
new file mode 100644
index 000000000000..af6a4853728f
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.h
@@ -0,0 +1,28 @@
1/*
2 * Device handling thread interface for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_BH_H
13#define CW1200_BH_H
14
15/* extern */ struct cw1200_common;
16
17int cw1200_register_bh(struct cw1200_common *priv);
18void cw1200_unregister_bh(struct cw1200_common *priv);
19void cw1200_irq_handler(struct cw1200_common *priv);
20void cw1200_bh_wakeup(struct cw1200_common *priv);
21int cw1200_bh_suspend(struct cw1200_common *priv);
22int cw1200_bh_resume(struct cw1200_common *priv);
23/* Must be called from BH thread. */
24void cw1200_enable_powersave(struct cw1200_common *priv,
25 bool enable);
26int wsm_release_tx_buffer(struct cw1200_common *priv, int count);
27
28#endif /* CW1200_BH_H */
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
new file mode 100644
index 000000000000..95320f2b25eb
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -0,0 +1,331 @@
1/*
2 * Common private data for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on the mac80211 Prism54 code, which is
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 *
10 * Based on the islsm (softmac prism54) driver, which is:
11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#ifndef CW1200_H
19#define CW1200_H
20
21#include <linux/wait.h>
22#include <linux/mutex.h>
23#include <linux/workqueue.h>
24#include <net/mac80211.h>
25
26#include "queue.h"
27#include "wsm.h"
28#include "scan.h"
29#include "txrx.h"
30#include "pm.h"
31
32/* Forward declarations */
33struct hwbus_ops;
34struct task_struct;
35struct cw1200_debug_priv;
36struct firmware;
37
38#ifdef CONFIG_CW1200_ETF
39extern int etf_mode;
40extern char *etf_firmware;
41#endif
42
43#define CW1200_MAX_CTRL_FRAME_LEN (0x1000)
44
45#define CW1200_MAX_STA_IN_AP_MODE (5)
46#define CW1200_LINK_ID_AFTER_DTIM (CW1200_MAX_STA_IN_AP_MODE + 1)
47#define CW1200_LINK_ID_UAPSD (CW1200_MAX_STA_IN_AP_MODE + 2)
48#define CW1200_LINK_ID_MAX (CW1200_MAX_STA_IN_AP_MODE + 3)
49#define CW1200_MAX_REQUEUE_ATTEMPTS (5)
50
51#define CW1200_MAX_TID (8)
52
53#define CW1200_BLOCK_ACK_CNT (30)
54#define CW1200_BLOCK_ACK_THLD (800)
55#define CW1200_BLOCK_ACK_HIST (3)
56#define CW1200_BLOCK_ACK_INTERVAL (1 * HZ / CW1200_BLOCK_ACK_HIST)
57
58#define CW1200_JOIN_TIMEOUT (1 * HZ)
59#define CW1200_AUTH_TIMEOUT (5 * HZ)
60
61struct cw1200_ht_info {
62 struct ieee80211_sta_ht_cap ht_cap;
63 enum nl80211_channel_type channel_type;
64 u16 operation_mode;
65};
66
67/* Please keep order */
68enum cw1200_join_status {
69 CW1200_JOIN_STATUS_PASSIVE = 0,
70 CW1200_JOIN_STATUS_MONITOR,
71 CW1200_JOIN_STATUS_JOINING,
72 CW1200_JOIN_STATUS_PRE_STA,
73 CW1200_JOIN_STATUS_STA,
74 CW1200_JOIN_STATUS_IBSS,
75 CW1200_JOIN_STATUS_AP,
76};
77
78enum cw1200_link_status {
79 CW1200_LINK_OFF,
80 CW1200_LINK_RESERVE,
81 CW1200_LINK_SOFT,
82 CW1200_LINK_HARD,
83 CW1200_LINK_RESET,
84 CW1200_LINK_RESET_REMAP,
85};
86
87extern int cw1200_power_mode;
88extern const char * const cw1200_fw_types[];
89
90struct cw1200_link_entry {
91 unsigned long timestamp;
92 enum cw1200_link_status status;
93 enum cw1200_link_status prev_status;
94 u8 mac[ETH_ALEN];
95 u8 buffered[CW1200_MAX_TID];
96 struct sk_buff_head rx_queue;
97};
98
99struct cw1200_common {
100 /* interfaces to the rest of the stack */
101 struct ieee80211_hw *hw;
102 struct ieee80211_vif *vif;
103 struct device *pdev;
104
105 /* Statistics */
106 struct ieee80211_low_level_stats stats;
107
108 /* Our macaddr */
109 u8 mac_addr[ETH_ALEN];
110
111 /* Hardware interface */
112 const struct hwbus_ops *hwbus_ops;
113 struct hwbus_priv *hwbus_priv;
114
115 /* Hardware information */
116 enum {
117 HIF_9000_SILICON_VERSATILE = 0,
118 HIF_8601_VERSATILE,
119 HIF_8601_SILICON,
120 } hw_type;
121 enum {
122 CW1200_HW_REV_CUT10 = 10,
123 CW1200_HW_REV_CUT11 = 11,
124 CW1200_HW_REV_CUT20 = 20,
125 CW1200_HW_REV_CUT22 = 22,
126 CW1X60_HW_REV = 40,
127 } hw_revision;
128 int hw_refclk;
129 bool hw_have_5ghz;
130 const struct firmware *sdd;
131 char *sdd_path;
132
133 struct cw1200_debug_priv *debug;
134
135 struct workqueue_struct *workqueue;
136 struct mutex conf_mutex;
137
138 struct cw1200_queue tx_queue[4];
139 struct cw1200_queue_stats tx_queue_stats;
140 int tx_burst_idx;
141
142 /* firmware/hardware info */
143 unsigned int tx_hdr_len;
144
145 /* Radio data */
146 int output_power;
147
148 /* BBP/MAC state */
149 struct ieee80211_rate *rates;
150 struct ieee80211_rate *mcs_rates;
151 struct ieee80211_channel *channel;
152 struct wsm_edca_params edca;
153 struct wsm_tx_queue_params tx_queue_params;
154 struct wsm_mib_association_mode association_mode;
155 struct wsm_set_bss_params bss_params;
156 struct cw1200_ht_info ht_info;
157 struct wsm_set_pm powersave_mode;
158 struct wsm_set_pm firmware_ps_mode;
159 int cqm_rssi_thold;
160 unsigned cqm_rssi_hyst;
161 bool cqm_use_rssi;
162 int cqm_beacon_loss_count;
163 int channel_switch_in_progress;
164 wait_queue_head_t channel_switch_done;
165 u8 long_frame_max_tx_count;
166 u8 short_frame_max_tx_count;
167 int mode;
168 bool enable_beacon;
169 int beacon_int;
170 bool listening;
171 struct wsm_rx_filter rx_filter;
172 struct wsm_mib_multicast_filter multicast_filter;
173 bool has_multicast_subscription;
174 bool disable_beacon_filter;
175 struct work_struct update_filtering_work;
176 struct work_struct set_beacon_wakeup_period_work;
177
178 u8 ba_rx_tid_mask;
179 u8 ba_tx_tid_mask;
180
181 struct cw1200_pm_state pm_state;
182
183 struct wsm_p2p_ps_modeinfo p2p_ps_modeinfo;
184 struct wsm_uapsd_info uapsd_info;
185 bool setbssparams_done;
186 bool bt_present;
187 u8 conf_listen_interval;
188 u32 listen_interval;
189 u32 erp_info;
190 u32 rts_threshold;
191
192 /* BH */
193 atomic_t bh_rx;
194 atomic_t bh_tx;
195 atomic_t bh_term;
196 atomic_t bh_suspend;
197
198 struct workqueue_struct *bh_workqueue;
199 struct work_struct bh_work;
200
201 int bh_error;
202 wait_queue_head_t bh_wq;
203 wait_queue_head_t bh_evt_wq;
204 u8 buf_id_tx;
205 u8 buf_id_rx;
206 u8 wsm_rx_seq;
207 u8 wsm_tx_seq;
208 int hw_bufs_used;
209 bool powersave_enabled;
210 bool device_can_sleep;
211
212 /* Scan status */
213 struct cw1200_scan scan;
214 /* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
215 * FW issue with sleeping/waking up. */
216 atomic_t recent_scan;
217 struct delayed_work clear_recent_scan_work;
218
219 /* WSM */
220 struct wsm_startup_ind wsm_caps;
221 struct mutex wsm_cmd_mux;
222 struct wsm_buf wsm_cmd_buf;
223 struct wsm_cmd wsm_cmd;
224 wait_queue_head_t wsm_cmd_wq;
225 wait_queue_head_t wsm_startup_done;
226 int firmware_ready;
227 atomic_t tx_lock;
228
229 /* WSM debug */
230 int wsm_enable_wsm_dumps;
231
232 /* WSM Join */
233 enum cw1200_join_status join_status;
234 u32 pending_frame_id;
235 bool join_pending;
236 struct delayed_work join_timeout;
237 struct work_struct unjoin_work;
238 struct work_struct join_complete_work;
239 int join_complete_status;
240 int join_dtim_period;
241 bool delayed_unjoin;
242
243 /* TX/RX and security */
244 s8 wep_default_key_id;
245 struct work_struct wep_key_work;
246 u32 key_map;
247 struct wsm_add_key keys[WSM_KEY_MAX_INDEX + 1];
248
249 /* AP powersave */
250 u32 link_id_map;
251 struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE];
252 struct work_struct link_id_work;
253 struct delayed_work link_id_gc_work;
254 u32 sta_asleep_mask;
255 u32 pspoll_mask;
256 bool aid0_bit_set;
257 spinlock_t ps_state_lock; /* Protect power save state */
258 bool buffered_multicasts;
259 bool tx_multicast;
260 struct work_struct set_tim_work;
261 struct work_struct set_cts_work;
262 struct work_struct multicast_start_work;
263 struct work_struct multicast_stop_work;
264 struct timer_list mcast_timeout;
265
266 /* WSM events and CQM implementation */
267 spinlock_t event_queue_lock; /* Protect event queue */
268 struct list_head event_queue;
269 struct work_struct event_handler;
270
271 struct delayed_work bss_loss_work;
272 spinlock_t bss_loss_lock; /* Protect BSS loss state */
273 int bss_loss_state;
274 int bss_loss_confirm_id;
275 int delayed_link_loss;
276 struct work_struct bss_params_work;
277
278 /* TX rate policy cache */
279 struct tx_policy_cache tx_policy_cache;
280 struct work_struct tx_policy_upload_work;
281
282 /* legacy PS mode switch in suspend */
283 int ps_mode_switch_in_progress;
284 wait_queue_head_t ps_mode_switch_done;
285
286 /* Workaround for WFD testcase 6.1.10*/
287 struct work_struct linkid_reset_work;
288 u8 action_frame_sa[ETH_ALEN];
289 u8 action_linkid;
290
291#ifdef CONFIG_CW1200_ETF
292 struct sk_buff_head etf_q;
293#endif
294};
295
296struct cw1200_sta_priv {
297 int link_id;
298};
299
300/* interfaces for the drivers */
301int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
302 struct hwbus_priv *hwbus,
303 struct device *pdev,
304 struct cw1200_common **pself,
305 int ref_clk, const u8 *macaddr,
306 const char *sdd_path, bool have_5ghz);
307void cw1200_core_release(struct cw1200_common *self);
308
309#define FWLOAD_BLOCK_SIZE (1024)
310
311static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info)
312{
313 return ht_info->channel_type != NL80211_CHAN_NO_HT;
314}
315
316static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info)
317{
318 return cw1200_is_ht(ht_info) &&
319 (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
320 !(ht_info->operation_mode &
321 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
322}
323
324static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info)
325{
326 if (!cw1200_is_ht(ht_info))
327 return 0;
328 return ht_info->ht_cap.ampdu_density;
329}
330
331#endif /* CW1200_H */
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
new file mode 100644
index 000000000000..bb1f405315e4
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -0,0 +1,424 @@
1/*
2 * Mac80211 SDIO driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/gpio.h>
14#include <linux/delay.h>
15#include <linux/mmc/host.h>
16#include <linux/mmc/sdio_func.h>
17#include <linux/mmc/card.h>
18#include <linux/mmc/sdio.h>
19#include <net/mac80211.h>
20
21#include "cw1200.h"
22#include "hwbus.h"
23#include <linux/platform_data/net-cw1200.h>
24#include "hwio.h"
25
26MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
27MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver");
28MODULE_LICENSE("GPL");
29
30#define SDIO_BLOCK_SIZE (512)
31
32/* Default platform data for Sagrad modules */
33static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
34 .ref_clk = 38400,
35 .have_5ghz = false,
36 .sdd_file = "sdd_sagrad_1091_1098.bin",
37};
38
39/* Allow platform data to be overridden */
40static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
41
42void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
43{
44 global_plat_data = pdata;
45}
46
47struct hwbus_priv {
48 struct sdio_func *func;
49 struct cw1200_common *core;
50 const struct cw1200_platform_data_sdio *pdata;
51};
52
53#ifndef SDIO_VENDOR_ID_STE
54#define SDIO_VENDOR_ID_STE 0x0020
55#endif
56
57#ifndef SDIO_DEVICE_ID_STE_CW1200
58#define SDIO_DEVICE_ID_STE_CW1200 0x2280
59#endif
60
61static const struct sdio_device_id cw1200_sdio_ids[] = {
62 { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
63 { /* end: all zeroes */ },
64};
65
66/* hwbus_ops implemetation */
67
68static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
69 unsigned int addr,
70 void *dst, int count)
71{
72 return sdio_memcpy_fromio(self->func, dst, addr, count);
73}
74
75static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
76 unsigned int addr,
77 const void *src, int count)
78{
79 return sdio_memcpy_toio(self->func, addr, (void *)src, count);
80}
81
82static void cw1200_sdio_lock(struct hwbus_priv *self)
83{
84 sdio_claim_host(self->func);
85}
86
87static void cw1200_sdio_unlock(struct hwbus_priv *self)
88{
89 sdio_release_host(self->func);
90}
91
92static void cw1200_sdio_irq_handler(struct sdio_func *func)
93{
94 struct hwbus_priv *self = sdio_get_drvdata(func);
95
96 /* note: sdio_host already claimed here. */
97 if (self->core)
98 cw1200_irq_handler(self->core);
99}
100
101static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
102{
103 return IRQ_WAKE_THREAD;
104}
105
106static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
107{
108 struct hwbus_priv *self = dev_id;
109
110 if (self->core) {
111 sdio_claim_host(self->func);
112 cw1200_irq_handler(self->core);
113 sdio_release_host(self->func);
114 return IRQ_HANDLED;
115 } else {
116 return IRQ_NONE;
117 }
118}
119
120static int cw1200_request_irq(struct hwbus_priv *self)
121{
122 int ret;
123 u8 cccr;
124
125 cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
126 if (WARN_ON(ret))
127 goto err;
128
129 /* Master interrupt enable ... */
130 cccr |= BIT(0);
131
132 /* ... for our function */
133 cccr |= BIT(self->func->num);
134
135 sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
136 if (WARN_ON(ret))
137 goto err;
138
139 ret = enable_irq_wake(self->pdata->irq);
140 if (WARN_ON(ret))
141 goto err;
142
143 /* Request the IRQ */
144 ret = request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
145 cw1200_gpio_irq,
146 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
147 "cw1200_wlan_irq", self);
148 if (WARN_ON(ret))
149 goto err;
150
151 return 0;
152
153err:
154 return ret;
155}
156
157static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
158{
159 int ret = 0;
160
161 pr_debug("SW IRQ subscribe\n");
162 sdio_claim_host(self->func);
163 if (self->pdata->irq)
164 ret = cw1200_request_irq(self);
165 else
166 ret = sdio_claim_irq(self->func, cw1200_sdio_irq_handler);
167
168 sdio_release_host(self->func);
169 return ret;
170}
171
172static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
173{
174 int ret = 0;
175
176 pr_debug("SW IRQ unsubscribe\n");
177
178 if (self->pdata->irq) {
179 disable_irq_wake(self->pdata->irq);
180 free_irq(self->pdata->irq, self);
181 } else {
182 sdio_claim_host(self->func);
183 ret = sdio_release_irq(self->func);
184 sdio_release_host(self->func);
185 }
186 return ret;
187}
188
189static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
190{
191 if (pdata->reset) {
192 gpio_set_value(pdata->reset, 0);
193 msleep(30); /* Min is 2 * CLK32K cycles */
194 gpio_free(pdata->reset);
195 }
196
197 if (pdata->power_ctrl)
198 pdata->power_ctrl(pdata, false);
199 if (pdata->clk_ctrl)
200 pdata->clk_ctrl(pdata, false);
201
202 return 0;
203}
204
205static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
206{
207 /* Ensure I/Os are pulled low */
208 if (pdata->reset) {
209 gpio_request(pdata->reset, "cw1200_wlan_reset");
210 gpio_direction_output(pdata->reset, 0);
211 }
212 if (pdata->powerup) {
213 gpio_request(pdata->powerup, "cw1200_wlan_powerup");
214 gpio_direction_output(pdata->powerup, 0);
215 }
216 if (pdata->reset || pdata->powerup)
217 msleep(10); /* Settle time? */
218
219 /* Enable 3v3 and 1v8 to hardware */
220 if (pdata->power_ctrl) {
221 if (pdata->power_ctrl(pdata, true)) {
222 pr_err("power_ctrl() failed!\n");
223 return -1;
224 }
225 }
226
227 /* Enable CLK32K */
228 if (pdata->clk_ctrl) {
229 if (pdata->clk_ctrl(pdata, true)) {
230 pr_err("clk_ctrl() failed!\n");
231 return -1;
232 }
233 msleep(10); /* Delay until clock is stable for 2 cycles */
234 }
235
236 /* Enable POWERUP signal */
237 if (pdata->powerup) {
238 gpio_set_value(pdata->powerup, 1);
239 msleep(250); /* or more..? */
240 }
241 /* Enable RSTn signal */
242 if (pdata->reset) {
243 gpio_set_value(pdata->reset, 1);
244 msleep(50); /* Or more..? */
245 }
246 return 0;
247}
248
249static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
250{
251 if (self->pdata->no_nptb)
252 size = round_up(size, SDIO_BLOCK_SIZE);
253 else
254 size = sdio_align_size(self->func, size);
255
256 return size;
257}
258
259static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
260{
261 int ret = 0;
262
263 if (self->pdata->irq)
264 ret = irq_set_irq_wake(self->pdata->irq, suspend);
265 return ret;
266}
267
268static struct hwbus_ops cw1200_sdio_hwbus_ops = {
269 .hwbus_memcpy_fromio = cw1200_sdio_memcpy_fromio,
270 .hwbus_memcpy_toio = cw1200_sdio_memcpy_toio,
271 .lock = cw1200_sdio_lock,
272 .unlock = cw1200_sdio_unlock,
273 .align_size = cw1200_sdio_align_size,
274 .power_mgmt = cw1200_sdio_pm,
275};
276
277/* Probe Function to be called by SDIO stack when device is discovered */
278static int cw1200_sdio_probe(struct sdio_func *func,
279 const struct sdio_device_id *id)
280{
281 struct hwbus_priv *self;
282 int status;
283
284 pr_info("cw1200_wlan_sdio: Probe called\n");
285
286 /* We are only able to handle the wlan function */
287 if (func->num != 0x01)
288 return -ENODEV;
289
290 self = kzalloc(sizeof(*self), GFP_KERNEL);
291 if (!self) {
292 pr_err("Can't allocate SDIO hwbus_priv.\n");
293 return -ENOMEM;
294 }
295
296 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
297
298 self->pdata = global_plat_data; /* FIXME */
299 self->func = func;
300 sdio_set_drvdata(func, self);
301 sdio_claim_host(func);
302 sdio_enable_func(func);
303 sdio_release_host(func);
304
305 status = cw1200_sdio_irq_subscribe(self);
306
307 status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
308 self, &func->dev, &self->core,
309 self->pdata->ref_clk,
310 self->pdata->macaddr,
311 self->pdata->sdd_file,
312 self->pdata->have_5ghz);
313 if (status) {
314 cw1200_sdio_irq_unsubscribe(self);
315 sdio_claim_host(func);
316 sdio_disable_func(func);
317 sdio_release_host(func);
318 sdio_set_drvdata(func, NULL);
319 kfree(self);
320 }
321
322 return status;
323}
324
325/* Disconnect Function to be called by SDIO stack when
326 * device is disconnected */
327static void cw1200_sdio_disconnect(struct sdio_func *func)
328{
329 struct hwbus_priv *self = sdio_get_drvdata(func);
330
331 if (self) {
332 cw1200_sdio_irq_unsubscribe(self);
333 if (self->core) {
334 cw1200_core_release(self->core);
335 self->core = NULL;
336 }
337 sdio_claim_host(func);
338 sdio_disable_func(func);
339 sdio_release_host(func);
340 sdio_set_drvdata(func, NULL);
341 kfree(self);
342 }
343}
344
345#ifdef CONFIG_PM
346static int cw1200_sdio_suspend(struct device *dev)
347{
348 int ret;
349 struct sdio_func *func = dev_to_sdio_func(dev);
350 struct hwbus_priv *self = sdio_get_drvdata(func);
351
352 if (!cw1200_can_suspend(self->core))
353 return -EAGAIN;
354
355 /* Notify SDIO that CW1200 will remain powered during suspend */
356 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
357 if (ret)
358 pr_err("Error setting SDIO pm flags: %i\n", ret);
359
360 return ret;
361}
362
363static int cw1200_sdio_resume(struct device *dev)
364{
365 return 0;
366}
367
368static const struct dev_pm_ops cw1200_pm_ops = {
369 .suspend = cw1200_sdio_suspend,
370 .resume = cw1200_sdio_resume,
371};
372#endif
373
374static struct sdio_driver sdio_driver = {
375 .name = "cw1200_wlan_sdio",
376 .id_table = cw1200_sdio_ids,
377 .probe = cw1200_sdio_probe,
378 .remove = cw1200_sdio_disconnect,
379#ifdef CONFIG_PM
380 .drv = {
381 .pm = &cw1200_pm_ops,
382 }
383#endif
384};
385
386/* Init Module function -> Called by insmod */
387static int __init cw1200_sdio_init(void)
388{
389 const struct cw1200_platform_data_sdio *pdata;
390 int ret;
391
392 /* FIXME -- this won't support multiple devices */
393 pdata = global_plat_data;
394
395 if (cw1200_sdio_on(pdata)) {
396 ret = -1;
397 goto err;
398 }
399
400 ret = sdio_register_driver(&sdio_driver);
401 if (ret)
402 goto err;
403
404 return 0;
405
406err:
407 cw1200_sdio_off(pdata);
408 return ret;
409}
410
411/* Called at Driver Unloading */
412static void __exit cw1200_sdio_exit(void)
413{
414 const struct cw1200_platform_data_sdio *pdata;
415
416 /* FIXME -- this won't support multiple devices */
417 pdata = global_plat_data;
418 sdio_unregister_driver(&sdio_driver);
419 cw1200_sdio_off(pdata);
420}
421
422
423module_init(cw1200_sdio_init);
424module_exit(cw1200_sdio_exit);
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
new file mode 100644
index 000000000000..e58f0a5bafa9
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -0,0 +1,465 @@
1/*
2 * Mac80211 SPI driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2011, Sagrad Inc.
5 * Author: Solomon Peachy <speachy@sagrad.com>
6 *
7 * Based on cw1200_sdio.c
8 * Copyright (c) 2010, ST-Ericsson
9 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/delay.h>
19#include <linux/spinlock.h>
20#include <linux/interrupt.h>
21#include <net/mac80211.h>
22
23#include <linux/spi/spi.h>
24#include <linux/device.h>
25
26#include "cw1200.h"
27#include "hwbus.h"
28#include <linux/platform_data/net-cw1200.h>
29#include "hwio.h"
30
31MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
32MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
33MODULE_LICENSE("GPL");
34MODULE_ALIAS("spi:cw1200_wlan_spi");
35
36/* #define SPI_DEBUG */
37
38struct hwbus_priv {
39 struct spi_device *func;
40 struct cw1200_common *core;
41 const struct cw1200_platform_data_spi *pdata;
42 spinlock_t lock; /* Serialize all bus operations */
43 int claimed;
44};
45
46#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
47#define SET_WRITE 0x7FFF /* usage: and operation */
48#define SET_READ 0x8000 /* usage: or operation */
49
50/*
51 Notes on byte ordering:
52 LE: B0 B1 B2 B3
53 BE: B3 B2 B1 B0
54
55 Hardware expects 32-bit data to be written as 16-bit BE words:
56
57 B1 B0 B3 B2
58
59*/
60
61static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
62 unsigned int addr,
63 void *dst, int count)
64{
65 int ret, i;
66 uint16_t regaddr;
67 struct spi_message m;
68
69 struct spi_transfer t_addr = {
70 .tx_buf = &regaddr,
71 .len = sizeof(regaddr),
72 };
73 struct spi_transfer t_msg = {
74 .rx_buf = dst,
75 .len = count,
76 };
77
78 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
79 regaddr |= SET_READ;
80 regaddr |= (count>>1);
81 regaddr = cpu_to_le16(regaddr);
82
83#ifdef SPI_DEBUG
84 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr,
85 le16_to_cpu(regaddr));
86#endif
87
88#if defined(__LITTLE_ENDIAN)
89 /* We have to byteswap if the SPI bus is limited to 8b operation */
90 if (self->func->bits_per_word == 8)
91#endif
92 regaddr = swab16(regaddr);
93
94 spi_message_init(&m);
95 spi_message_add_tail(&t_addr, &m);
96 spi_message_add_tail(&t_msg, &m);
97 ret = spi_sync(self->func, &m);
98
99#ifdef SPI_DEBUG
100 pr_info("READ : ");
101 for (i = 0; i < t_addr.len; i++)
102 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
103 printk(" : ");
104 for (i = 0; i < t_msg.len; i++)
105 printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
106 printk("\n");
107#endif
108
109#if defined(__LITTLE_ENDIAN)
110 /* We have to byteswap if the SPI bus is limited to 8b operation */
111 if (self->func->bits_per_word == 8)
112#endif
113 {
114 uint16_t *buf = (uint16_t *)dst;
115 for (i = 0; i < ((count + 1) >> 1); i++)
116 buf[i] = swab16(buf[i]);
117 }
118
119 return ret;
120}
121
122static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
123 unsigned int addr,
124 const void *src, int count)
125{
126 int rval, i;
127 uint16_t regaddr;
128 struct spi_transfer t_addr = {
129 .tx_buf = &regaddr,
130 .len = sizeof(regaddr),
131 };
132 struct spi_transfer t_msg = {
133 .tx_buf = src,
134 .len = count,
135 };
136 struct spi_message m;
137
138 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
139 regaddr &= SET_WRITE;
140 regaddr |= (count>>1);
141 regaddr = cpu_to_le16(regaddr);
142
143#ifdef SPI_DEBUG
144 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr,
145 le16_to_cpu(regaddr));
146#endif
147
148#if defined(__LITTLE_ENDIAN)
149 /* We have to byteswap if the SPI bus is limited to 8b operation */
150 if (self->func->bits_per_word == 8)
151#endif
152 {
153 uint16_t *buf = (uint16_t *)src;
154 regaddr = swab16(regaddr);
155 for (i = 0; i < ((count + 1) >> 1); i++)
156 buf[i] = swab16(buf[i]);
157 }
158
159#ifdef SPI_DEBUG
160 pr_info("WRITE: ");
161 for (i = 0; i < t_addr.len; i++)
162 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
163 printk(" : ");
164 for (i = 0; i < t_msg.len; i++)
165 printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
166 printk("\n");
167#endif
168
169 spi_message_init(&m);
170 spi_message_add_tail(&t_addr, &m);
171 spi_message_add_tail(&t_msg, &m);
172 rval = spi_sync(self->func, &m);
173
174#ifdef SPI_DEBUG
175 pr_info("WROTE: %d\n", m.actual_length);
176#endif
177
178#if defined(__LITTLE_ENDIAN)
179 /* We have to byteswap if the SPI bus is limited to 8b operation */
180 if (self->func->bits_per_word == 8)
181#endif
182 {
183 uint16_t *buf = (uint16_t *)src;
184 for (i = 0; i < ((count + 1) >> 1); i++)
185 buf[i] = swab16(buf[i]);
186 }
187 return rval;
188}
189
190static void cw1200_spi_lock(struct hwbus_priv *self)
191{
192 unsigned long flags;
193
194 might_sleep();
195
196 spin_lock_irqsave(&self->lock, flags);
197 while (1) {
198 set_current_state(TASK_UNINTERRUPTIBLE);
199 if (!self->claimed)
200 break;
201 spin_unlock_irqrestore(&self->lock, flags);
202 schedule();
203 spin_lock_irqsave(&self->lock, flags);
204 }
205 set_current_state(TASK_RUNNING);
206 self->claimed = 1;
207 spin_unlock_irqrestore(&self->lock, flags);
208
209 return;
210}
211
212static void cw1200_spi_unlock(struct hwbus_priv *self)
213{
214 unsigned long flags;
215
216 spin_lock_irqsave(&self->lock, flags);
217 self->claimed = 0;
218 spin_unlock_irqrestore(&self->lock, flags);
219 return;
220}
221
222static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
223{
224 struct hwbus_priv *self = dev_id;
225
226 if (self->core) {
227 cw1200_irq_handler(self->core);
228 return IRQ_HANDLED;
229 } else {
230 return IRQ_NONE;
231 }
232}
233
234static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
235{
236 int ret;
237
238 pr_debug("SW IRQ subscribe\n");
239
240 ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
241 IRQF_TRIGGER_HIGH,
242 "cw1200_wlan_irq", self);
243 if (WARN_ON(ret < 0))
244 goto exit;
245
246 ret = enable_irq_wake(self->func->irq);
247 if (WARN_ON(ret))
248 goto free_irq;
249
250 return 0;
251
252free_irq:
253 free_irq(self->func->irq, self);
254exit:
255 return ret;
256}
257
258static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
259{
260 int ret = 0;
261
262 pr_debug("SW IRQ unsubscribe\n");
263 disable_irq_wake(self->func->irq);
264 free_irq(self->func->irq, self);
265
266 return ret;
267}
268
269static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
270{
271 if (pdata->reset) {
272 gpio_set_value(pdata->reset, 0);
273 msleep(30); /* Min is 2 * CLK32K cycles */
274 gpio_free(pdata->reset);
275 }
276
277 if (pdata->power_ctrl)
278 pdata->power_ctrl(pdata, false);
279 if (pdata->clk_ctrl)
280 pdata->clk_ctrl(pdata, false);
281
282 return 0;
283}
284
285static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
286{
287 /* Ensure I/Os are pulled low */
288 if (pdata->reset) {
289 gpio_request(pdata->reset, "cw1200_wlan_reset");
290 gpio_direction_output(pdata->reset, 0);
291 }
292 if (pdata->powerup) {
293 gpio_request(pdata->powerup, "cw1200_wlan_powerup");
294 gpio_direction_output(pdata->powerup, 0);
295 }
296 if (pdata->reset || pdata->powerup)
297 msleep(10); /* Settle time? */
298
299 /* Enable 3v3 and 1v8 to hardware */
300 if (pdata->power_ctrl) {
301 if (pdata->power_ctrl(pdata, true)) {
302 pr_err("power_ctrl() failed!\n");
303 return -1;
304 }
305 }
306
307 /* Enable CLK32K */
308 if (pdata->clk_ctrl) {
309 if (pdata->clk_ctrl(pdata, true)) {
310 pr_err("clk_ctrl() failed!\n");
311 return -1;
312 }
313 msleep(10); /* Delay until clock is stable for 2 cycles */
314 }
315
316 /* Enable POWERUP signal */
317 if (pdata->powerup) {
318 gpio_set_value(pdata->powerup, 1);
319 msleep(250); /* or more..? */
320 }
321 /* Enable RSTn signal */
322 if (pdata->reset) {
323 gpio_set_value(pdata->reset, 1);
324 msleep(50); /* Or more..? */
325 }
326 return 0;
327}
328
329static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
330{
331 return size & 1 ? size + 1 : size;
332}
333
334static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
335{
336 return irq_set_irq_wake(self->func->irq, suspend);
337}
338
339static struct hwbus_ops cw1200_spi_hwbus_ops = {
340 .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
341 .hwbus_memcpy_toio = cw1200_spi_memcpy_toio,
342 .lock = cw1200_spi_lock,
343 .unlock = cw1200_spi_unlock,
344 .align_size = cw1200_spi_align_size,
345 .power_mgmt = cw1200_spi_pm,
346};
347
348/* Probe Function to be called by SPI stack when device is discovered */
349static int cw1200_spi_probe(struct spi_device *func)
350{
351 const struct cw1200_platform_data_spi *plat_data =
352 func->dev.platform_data;
353 struct hwbus_priv *self;
354 int status;
355
356 /* Sanity check speed */
357 if (func->max_speed_hz > 52000000)
358 func->max_speed_hz = 52000000;
359 if (func->max_speed_hz < 1000000)
360 func->max_speed_hz = 1000000;
361
362 /* Fix up transfer size */
363 if (plat_data->spi_bits_per_word)
364 func->bits_per_word = plat_data->spi_bits_per_word;
365 if (!func->bits_per_word)
366 func->bits_per_word = 16;
367
368 /* And finally.. */
369 func->mode = SPI_MODE_0;
370
371 pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
372 func->chip_select, func->mode, func->bits_per_word,
373 func->max_speed_hz);
374
375 if (cw1200_spi_on(plat_data)) {
376 pr_err("spi_on() failed!\n");
377 return -1;
378 }
379
380 if (spi_setup(func)) {
381 pr_err("spi_setup() failed!\n");
382 return -1;
383 }
384
385 self = kzalloc(sizeof(*self), GFP_KERNEL);
386 if (!self) {
387 pr_err("Can't allocate SPI hwbus_priv.");
388 return -ENOMEM;
389 }
390
391 self->pdata = plat_data;
392 self->func = func;
393 spin_lock_init(&self->lock);
394
395 spi_set_drvdata(func, self);
396
397 status = cw1200_spi_irq_subscribe(self);
398
399 status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
400 self, &func->dev, &self->core,
401 self->pdata->ref_clk,
402 self->pdata->macaddr,
403 self->pdata->sdd_file,
404 self->pdata->have_5ghz);
405
406 if (status) {
407 cw1200_spi_irq_unsubscribe(self);
408 cw1200_spi_off(plat_data);
409 kfree(self);
410 }
411
412 return status;
413}
414
415/* Disconnect Function to be called by SPI stack when device is disconnected */
416static int cw1200_spi_disconnect(struct spi_device *func)
417{
418 struct hwbus_priv *self = spi_get_drvdata(func);
419
420 if (self) {
421 cw1200_spi_irq_unsubscribe(self);
422 if (self->core) {
423 cw1200_core_release(self->core);
424 self->core = NULL;
425 }
426 kfree(self);
427 }
428 cw1200_spi_off(func->dev.platform_data);
429
430 return 0;
431}
432
433#ifdef CONFIG_PM
434static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
435{
436 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
437
438 if (!cw1200_can_suspend(self->core))
439 return -EAGAIN;
440
441 /* XXX notify host that we have to keep CW1200 powered on? */
442 return 0;
443}
444
445static int cw1200_spi_resume(struct device *dev)
446{
447 return 0;
448}
449#endif
450
451static struct spi_driver spi_driver = {
452 .probe = cw1200_spi_probe,
453 .remove = cw1200_spi_disconnect,
454 .driver = {
455 .name = "cw1200_wlan_spi",
456 .bus = &spi_bus_type,
457 .owner = THIS_MODULE,
458#ifdef CONFIG_PM
459 .suspend = cw1200_spi_suspend,
460 .resume = cw1200_spi_resume,
461#endif
462 },
463};
464
465module_spi_driver(spi_driver);
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
new file mode 100644
index 000000000000..eb40c9c61a51
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -0,0 +1,658 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 * DebugFS code
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/seq_file.h>
16#include "cw1200.h"
17#include "debug.h"
18#include "fwio.h"
19
20/* join_status */
21static const char * const cw1200_debug_join_status[] = {
22 "passive",
23 "monitor",
24 "station (joining)",
25 "station (not authenticated yet)",
26 "station",
27 "adhoc",
28 "access point",
29};
30
31/* WSM_JOIN_PREAMBLE_... */
32static const char * const cw1200_debug_preamble[] = {
33 "long",
34 "short",
35 "long on 1 and 2 Mbps",
36};
37
38
39static const char * const cw1200_debug_link_id[] = {
40 "OFF",
41 "REQ",
42 "SOFT",
43 "HARD",
44};
45
46static const char *cw1200_debug_mode(int mode)
47{
48 switch (mode) {
49 case NL80211_IFTYPE_UNSPECIFIED:
50 return "unspecified";
51 case NL80211_IFTYPE_MONITOR:
52 return "monitor";
53 case NL80211_IFTYPE_STATION:
54 return "station";
55 case NL80211_IFTYPE_ADHOC:
56 return "adhoc";
57 case NL80211_IFTYPE_MESH_POINT:
58 return "mesh point";
59 case NL80211_IFTYPE_AP:
60 return "access point";
61 case NL80211_IFTYPE_P2P_CLIENT:
62 return "p2p client";
63 case NL80211_IFTYPE_P2P_GO:
64 return "p2p go";
65 default:
66 return "unsupported";
67 }
68}
69
70static void cw1200_queue_status_show(struct seq_file *seq,
71 struct cw1200_queue *q)
72{
73 int i;
74 seq_printf(seq, "Queue %d:\n", q->queue_id);
75 seq_printf(seq, " capacity: %zu\n", q->capacity);
76 seq_printf(seq, " queued: %zu\n", q->num_queued);
77 seq_printf(seq, " pending: %zu\n", q->num_pending);
78 seq_printf(seq, " sent: %zu\n", q->num_sent);
79 seq_printf(seq, " locked: %s\n", q->tx_locked_cnt ? "yes" : "no");
80 seq_printf(seq, " overfull: %s\n", q->overfull ? "yes" : "no");
81 seq_puts(seq, " link map: 0-> ");
82 for (i = 0; i < q->stats->map_capacity; ++i)
83 seq_printf(seq, "%.2d ", q->link_map_cache[i]);
84 seq_printf(seq, "<-%zu\n", q->stats->map_capacity);
85}
86
87static void cw1200_debug_print_map(struct seq_file *seq,
88 struct cw1200_common *priv,
89 const char *label,
90 u32 map)
91{
92 int i;
93 seq_printf(seq, "%s0-> ", label);
94 for (i = 0; i < priv->tx_queue_stats.map_capacity; ++i)
95 seq_printf(seq, "%s ", (map & BIT(i)) ? "**" : "..");
96 seq_printf(seq, "<-%zu\n", priv->tx_queue_stats.map_capacity - 1);
97}
98
99static int cw1200_status_show(struct seq_file *seq, void *v)
100{
101 int i;
102 struct list_head *item;
103 struct cw1200_common *priv = seq->private;
104 struct cw1200_debug_priv *d = priv->debug;
105
106 seq_puts(seq, "CW1200 Wireless LAN driver status\n");
107 seq_printf(seq, "Hardware: %d.%d\n",
108 priv->wsm_caps.hw_id,
109 priv->wsm_caps.hw_subid);
110 seq_printf(seq, "Firmware: %s %d.%d\n",
111 cw1200_fw_types[priv->wsm_caps.fw_type],
112 priv->wsm_caps.fw_ver,
113 priv->wsm_caps.fw_build);
114 seq_printf(seq, "FW API: %d\n",
115 priv->wsm_caps.fw_api);
116 seq_printf(seq, "FW caps: 0x%.4X\n",
117 priv->wsm_caps.fw_cap);
118 seq_printf(seq, "FW label: '%s'\n",
119 priv->wsm_caps.fw_label);
120 seq_printf(seq, "Mode: %s%s\n",
121 cw1200_debug_mode(priv->mode),
122 priv->listening ? " (listening)" : "");
123 seq_printf(seq, "Join state: %s\n",
124 cw1200_debug_join_status[priv->join_status]);
125 if (priv->channel)
126 seq_printf(seq, "Channel: %d%s\n",
127 priv->channel->hw_value,
128 priv->channel_switch_in_progress ?
129 " (switching)" : "");
130 if (priv->rx_filter.promiscuous)
131 seq_puts(seq, "Filter: promisc\n");
132 else if (priv->rx_filter.fcs)
133 seq_puts(seq, "Filter: fcs\n");
134 if (priv->rx_filter.bssid)
135 seq_puts(seq, "Filter: bssid\n");
136 if (!priv->disable_beacon_filter)
137 seq_puts(seq, "Filter: beacons\n");
138
139 if (priv->enable_beacon ||
140 priv->mode == NL80211_IFTYPE_AP ||
141 priv->mode == NL80211_IFTYPE_ADHOC ||
142 priv->mode == NL80211_IFTYPE_MESH_POINT ||
143 priv->mode == NL80211_IFTYPE_P2P_GO)
144 seq_printf(seq, "Beaconing: %s\n",
145 priv->enable_beacon ?
146 "enabled" : "disabled");
147
148 for (i = 0; i < 4; ++i)
149 seq_printf(seq, "EDCA(%d): %d, %d, %d, %d, %d\n", i,
150 priv->edca.params[i].cwmin,
151 priv->edca.params[i].cwmax,
152 priv->edca.params[i].aifns,
153 priv->edca.params[i].txop_limit,
154 priv->edca.params[i].max_rx_lifetime);
155
156 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
157 static const char *pm_mode = "unknown";
158 switch (priv->powersave_mode.mode) {
159 case WSM_PSM_ACTIVE:
160 pm_mode = "off";
161 break;
162 case WSM_PSM_PS:
163 pm_mode = "on";
164 break;
165 case WSM_PSM_FAST_PS:
166 pm_mode = "dynamic";
167 break;
168 }
169 seq_printf(seq, "Preamble: %s\n",
170 cw1200_debug_preamble[priv->association_mode.preamble]);
171 seq_printf(seq, "AMPDU spcn: %d\n",
172 priv->association_mode.mpdu_start_spacing);
173 seq_printf(seq, "Basic rate: 0x%.8X\n",
174 le32_to_cpu(priv->association_mode.basic_rate_set));
175 seq_printf(seq, "Bss lost: %d beacons\n",
176 priv->bss_params.beacon_lost_count);
177 seq_printf(seq, "AID: %d\n",
178 priv->bss_params.aid);
179 seq_printf(seq, "Rates: 0x%.8X\n",
180 priv->bss_params.operational_rate_set);
181 seq_printf(seq, "Powersave: %s\n", pm_mode);
182 }
183 seq_printf(seq, "HT: %s\n",
184 cw1200_is_ht(&priv->ht_info) ? "on" : "off");
185 if (cw1200_is_ht(&priv->ht_info)) {
186 seq_printf(seq, "Greenfield: %s\n",
187 cw1200_ht_greenfield(&priv->ht_info) ? "yes" : "no");
188 seq_printf(seq, "AMPDU dens: %d\n",
189 cw1200_ht_ampdu_density(&priv->ht_info));
190 }
191 seq_printf(seq, "RSSI thold: %d\n",
192 priv->cqm_rssi_thold);
193 seq_printf(seq, "RSSI hyst: %d\n",
194 priv->cqm_rssi_hyst);
195 seq_printf(seq, "Long retr: %d\n",
196 priv->long_frame_max_tx_count);
197 seq_printf(seq, "Short retr: %d\n",
198 priv->short_frame_max_tx_count);
199 spin_lock_bh(&priv->tx_policy_cache.lock);
200 i = 0;
201 list_for_each(item, &priv->tx_policy_cache.used)
202 ++i;
203 spin_unlock_bh(&priv->tx_policy_cache.lock);
204 seq_printf(seq, "RC in use: %d\n", i);
205
206 seq_puts(seq, "\n");
207 for (i = 0; i < 4; ++i) {
208 cw1200_queue_status_show(seq, &priv->tx_queue[i]);
209 seq_puts(seq, "\n");
210 }
211
212 cw1200_debug_print_map(seq, priv, "Link map: ",
213 priv->link_id_map);
214 cw1200_debug_print_map(seq, priv, "Asleep map: ",
215 priv->sta_asleep_mask);
216 cw1200_debug_print_map(seq, priv, "PSPOLL map: ",
217 priv->pspoll_mask);
218
219 seq_puts(seq, "\n");
220
221 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
222 if (priv->link_id_db[i].status) {
223 seq_printf(seq, "Link %d: %s, %pM\n",
224 i + 1,
225 cw1200_debug_link_id[priv->link_id_db[i].status],
226 priv->link_id_db[i].mac);
227 }
228 }
229
230 seq_puts(seq, "\n");
231
232 seq_printf(seq, "BH status: %s\n",
233 atomic_read(&priv->bh_term) ? "terminated" : "alive");
234 seq_printf(seq, "Pending RX: %d\n",
235 atomic_read(&priv->bh_rx));
236 seq_printf(seq, "Pending TX: %d\n",
237 atomic_read(&priv->bh_tx));
238 if (priv->bh_error)
239 seq_printf(seq, "BH errcode: %d\n",
240 priv->bh_error);
241 seq_printf(seq, "TX bufs: %d x %d bytes\n",
242 priv->wsm_caps.input_buffers,
243 priv->wsm_caps.input_buffer_size);
244 seq_printf(seq, "Used bufs: %d\n",
245 priv->hw_bufs_used);
246 seq_printf(seq, "Powermgmt: %s\n",
247 priv->powersave_enabled ? "on" : "off");
248 seq_printf(seq, "Device: %s\n",
249 priv->device_can_sleep ? "asleep" : "awake");
250
251 spin_lock(&priv->wsm_cmd.lock);
252 seq_printf(seq, "WSM status: %s\n",
253 priv->wsm_cmd.done ? "idle" : "active");
254 seq_printf(seq, "WSM cmd: 0x%.4X (%td bytes)\n",
255 priv->wsm_cmd.cmd, priv->wsm_cmd.len);
256 seq_printf(seq, "WSM retval: %d\n",
257 priv->wsm_cmd.ret);
258 spin_unlock(&priv->wsm_cmd.lock);
259
260 seq_printf(seq, "Datapath: %s\n",
261 atomic_read(&priv->tx_lock) ? "locked" : "unlocked");
262 if (atomic_read(&priv->tx_lock))
263 seq_printf(seq, "TXlock cnt: %d\n",
264 atomic_read(&priv->tx_lock));
265
266 seq_printf(seq, "TXed: %d\n",
267 d->tx);
268 seq_printf(seq, "AGG TXed: %d\n",
269 d->tx_agg);
270 seq_printf(seq, "MULTI TXed: %d (%d)\n",
271 d->tx_multi, d->tx_multi_frames);
272 seq_printf(seq, "RXed: %d\n",
273 d->rx);
274 seq_printf(seq, "AGG RXed: %d\n",
275 d->rx_agg);
276 seq_printf(seq, "TX miss: %d\n",
277 d->tx_cache_miss);
278 seq_printf(seq, "TX align: %d\n",
279 d->tx_align);
280 seq_printf(seq, "TX burst: %d\n",
281 d->tx_burst);
282 seq_printf(seq, "TX TTL: %d\n",
283 d->tx_ttl);
284 seq_printf(seq, "Scan: %s\n",
285 atomic_read(&priv->scan.in_progress) ? "active" : "idle");
286
287 return 0;
288}
289
290static int cw1200_status_open(struct inode *inode, struct file *file)
291{
292 return single_open(file, &cw1200_status_show,
293 inode->i_private);
294}
295
296static const struct file_operations fops_status = {
297 .open = cw1200_status_open,
298 .read = seq_read,
299 .llseek = seq_lseek,
300 .release = single_release,
301 .owner = THIS_MODULE,
302};
303
304static int cw1200_counters_show(struct seq_file *seq, void *v)
305{
306 int ret;
307 struct cw1200_common *priv = seq->private;
308 struct wsm_mib_counters_table counters;
309
310 ret = wsm_get_counters_table(priv, &counters);
311 if (ret)
312 return ret;
313
314#define PUT_COUNTER(tab, name) \
315 seq_printf(seq, "%s:" tab "%d\n", #name, \
316 __le32_to_cpu(counters.name))
317
318 PUT_COUNTER("\t\t", plcp_errors);
319 PUT_COUNTER("\t\t", fcs_errors);
320 PUT_COUNTER("\t\t", tx_packets);
321 PUT_COUNTER("\t\t", rx_packets);
322 PUT_COUNTER("\t\t", rx_packet_errors);
323 PUT_COUNTER("\t", rx_decryption_failures);
324 PUT_COUNTER("\t\t", rx_mic_failures);
325 PUT_COUNTER("\t", rx_no_key_failures);
326 PUT_COUNTER("\t", tx_multicast_frames);
327 PUT_COUNTER("\t", tx_frames_success);
328 PUT_COUNTER("\t", tx_frame_failures);
329 PUT_COUNTER("\t", tx_frames_retried);
330 PUT_COUNTER("\t", tx_frames_multi_retried);
331 PUT_COUNTER("\t", rx_frame_duplicates);
332 PUT_COUNTER("\t\t", rts_success);
333 PUT_COUNTER("\t\t", rts_failures);
334 PUT_COUNTER("\t\t", ack_failures);
335 PUT_COUNTER("\t", rx_multicast_frames);
336 PUT_COUNTER("\t", rx_frames_success);
337 PUT_COUNTER("\t", rx_cmac_icv_errors);
338 PUT_COUNTER("\t\t", rx_cmac_replays);
339 PUT_COUNTER("\t", rx_mgmt_ccmp_replays);
340
341#undef PUT_COUNTER
342
343 return 0;
344}
345
346static int cw1200_counters_open(struct inode *inode, struct file *file)
347{
348 return single_open(file, &cw1200_counters_show,
349 inode->i_private);
350}
351
352static const struct file_operations fops_counters = {
353 .open = cw1200_counters_open,
354 .read = seq_read,
355 .llseek = seq_lseek,
356 .release = single_release,
357 .owner = THIS_MODULE,
358};
359
360#ifdef CONFIG_CW1200_ETF
361static int cw1200_etf_out_show(struct seq_file *seq, void *v)
362{
363 struct cw1200_common *priv = seq->private;
364 struct sk_buff *skb;
365 u32 len = 0;
366
367 skb = skb_dequeue(&priv->etf_q);
368
369 if (skb)
370 len = skb->len;
371
372 seq_write(seq, &len, sizeof(len));
373
374 if (skb) {
375 seq_write(seq, skb->data, len);
376 kfree_skb(skb);
377 }
378
379 return 0;
380}
381
382static int cw1200_etf_out_open(struct inode *inode, struct file *file)
383{
384 return single_open(file, &cw1200_etf_out_show,
385 inode->i_private);
386}
387
388static const struct file_operations fops_etf_out = {
389 .open = cw1200_etf_out_open,
390 .read = seq_read,
391 .llseek = seq_lseek,
392 .release = single_release,
393 .owner = THIS_MODULE,
394};
395
396struct etf_req_msg;
397static int etf_request(struct cw1200_common *priv,
398 struct etf_req_msg *msg, u32 len);
399
400#define MAX_RX_SZE 2600
401
402struct etf_in_state {
403 struct cw1200_common *priv;
404 u32 total_len;
405 u8 buf[MAX_RX_SZE];
406 u32 written;
407};
408
409static int cw1200_etf_in_open(struct inode *inode, struct file *file)
410{
411 struct etf_in_state *etf = kmalloc(sizeof(struct etf_in_state),
412 GFP_KERNEL);
413
414 if (!etf)
415 return -ENOMEM;
416
417 etf->written = 0;
418 etf->total_len = 0;
419 etf->priv = inode->i_private;
420
421 file->private_data = etf;
422
423 return 0;
424}
425
426static int cw1200_etf_in_release(struct inode *inode, struct file *file)
427{
428 kfree(file->private_data);
429 return 0;
430}
431
432static ssize_t cw1200_etf_in_write(struct file *file,
433 const char __user *user_buf, size_t count, loff_t *ppos)
434{
435 struct etf_in_state *etf = file->private_data;
436
437 ssize_t written = 0;
438
439 if (!etf->total_len) {
440 if (count < sizeof(etf->total_len)) {
441 pr_err("count < sizeof(total_len)\n");
442 return -EINVAL;
443 }
444
445 if (copy_from_user(&etf->total_len, user_buf,
446 sizeof(etf->total_len))) {
447 pr_err("copy_from_user (len) failed\n");
448 return -EFAULT;
449 }
450
451 written += sizeof(etf->total_len);
452 count -= sizeof(etf->total_len);
453 }
454
455 if (!count)
456 goto done;
457
458 if (copy_from_user(etf->buf + etf->written, user_buf + written,
459 count)) {
460 pr_err("copy_from_user (payload %zu) failed\n", count);
461 return -EFAULT;
462 }
463
464 written += count;
465 etf->written += count;
466
467 if (etf->written >= etf->total_len) {
468 if (etf_request(etf->priv, (struct etf_req_msg *)etf->buf,
469 etf->total_len)) {
470 pr_err("etf_request failed\n");
471 return -EIO;
472 }
473 }
474
475done:
476 return written;
477}
478
479static const struct file_operations fops_etf_in = {
480 .open = cw1200_etf_in_open,
481 .release = cw1200_etf_in_release,
482 .write = cw1200_etf_in_write,
483 .llseek = default_llseek,
484 .owner = THIS_MODULE,
485};
486#endif /* CONFIG_CW1200_ETF */
487
488static ssize_t cw1200_wsm_dumps(struct file *file,
489 const char __user *user_buf, size_t count, loff_t *ppos)
490{
491 struct cw1200_common *priv = file->private_data;
492 char buf[1];
493
494 if (!count)
495 return -EINVAL;
496 if (copy_from_user(buf, user_buf, 1))
497 return -EFAULT;
498
499 if (buf[0] == '1')
500 priv->wsm_enable_wsm_dumps = 1;
501 else
502 priv->wsm_enable_wsm_dumps = 0;
503
504 return count;
505}
506
507static const struct file_operations fops_wsm_dumps = {
508 .open = simple_open,
509 .write = cw1200_wsm_dumps,
510 .llseek = default_llseek,
511};
512
513int cw1200_debug_init(struct cw1200_common *priv)
514{
515 int ret = -ENOMEM;
516 struct cw1200_debug_priv *d = kzalloc(sizeof(struct cw1200_debug_priv),
517 GFP_KERNEL);
518 priv->debug = d;
519 if (!d)
520 return ret;
521
522 d->debugfs_phy = debugfs_create_dir("cw1200",
523 priv->hw->wiphy->debugfsdir);
524 if (!d->debugfs_phy)
525 goto err;
526
527 if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
528 priv, &fops_status))
529 goto err;
530
531 if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy,
532 priv, &fops_counters))
533 goto err;
534
535#ifdef CONFIG_CW1200_ETF
536 if (etf_mode) {
537 skb_queue_head_init(&priv->etf_q);
538
539 if (!debugfs_create_file("etf_out", S_IRUSR, d->debugfs_phy,
540 priv, &fops_etf_out))
541 goto err;
542 if (!debugfs_create_file("etf_in", S_IWUSR, d->debugfs_phy,
543 priv, &fops_etf_in))
544 goto err;
545 }
546#endif /* CONFIG_CW1200_ETF */
547
548 if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
549 priv, &fops_wsm_dumps))
550 goto err;
551
552 ret = cw1200_itp_init(priv);
553 if (ret)
554 goto err;
555
556 return 0;
557
558err:
559 priv->debug = NULL;
560 debugfs_remove_recursive(d->debugfs_phy);
561 kfree(d);
562 return ret;
563}
564
565void cw1200_debug_release(struct cw1200_common *priv)
566{
567 struct cw1200_debug_priv *d = priv->debug;
568 if (d) {
569 cw1200_itp_release(priv);
570 priv->debug = NULL;
571 kfree(d);
572 }
573}
574
575#ifdef CONFIG_CW1200_ETF
576struct cw1200_sdd {
577 u8 id;
578 u8 len;
579 u8 data[];
580};
581
582struct etf_req_msg {
583 u32 id;
584 u32 len;
585 u8 data[];
586};
587
588static int parse_sdd_file(struct cw1200_common *priv, u8 *data, u32 length)
589{
590 struct cw1200_sdd *ie;
591
592 while (length > 0) {
593 ie = (struct cw1200_sdd *)data;
594 if (ie->id == SDD_REFERENCE_FREQUENCY_ELT_ID) {
595 priv->hw_refclk = cpu_to_le16(*((u16 *)ie->data));
596 pr_info("Using Reference clock frequency %d KHz\n",
597 priv->hw_refclk);
598 break;
599 }
600
601 length -= ie->len + sizeof(*ie);
602 data += ie->len + sizeof(*ie);
603 }
604 return 0;
605}
606
607char *etf_firmware;
608
609#define ST90TDS_START_ADAPTER 0x09 /* Loads firmware too */
610#define ST90TDS_STOP_ADAPTER 0x0A
611#define ST90TDS_CONFIG_ADAPTER 0x0E /* Send configuration params */
612#define ST90TDS_SBUS_READ 0x13
613#define ST90TDS_SBUS_WRITE 0x14
614#define ST90TDS_GET_DEVICE_OPTION 0x19
615#define ST90TDS_SET_DEVICE_OPTION 0x1A
616#define ST90TDS_SEND_SDD 0x1D /* SDD File used to find DPLL */
617
618#include "fwio.h"
619
620static int etf_request(struct cw1200_common *priv,
621 struct etf_req_msg *msg,
622 u32 len)
623{
624 int rval = -1;
625 switch (msg->id) {
626 case ST90TDS_START_ADAPTER:
627 etf_firmware = "cw1200_etf.bin";
628 pr_info("ETF_START (len %d, '%s')\n", len, etf_firmware);
629 rval = cw1200_load_firmware(priv);
630 break;
631 case ST90TDS_STOP_ADAPTER:
632 pr_info("ETF_STOP (unhandled)\n");
633 break;
634 case ST90TDS_SEND_SDD:
635 pr_info("ETF_SDD\n");
636 rval = parse_sdd_file(priv, msg->data, msg->len);
637 break;
638 case ST90TDS_CONFIG_ADAPTER:
639 pr_info("ETF_CONFIG_ADAP (unhandled)\n");
640 break;
641 case ST90TDS_SBUS_READ:
642 pr_info("ETF_SBUS_READ (unhandled)\n");
643 break;
644 case ST90TDS_SBUS_WRITE:
645 pr_info("ETF_SBUS_WRITE (unhandled)\n");
646 break;
647 case ST90TDS_SET_DEVICE_OPTION:
648 pr_info("ETF_SET_DEV_OPT (unhandled)\n");
649 break;
650 default:
651 pr_info("ETF_PASSTHRU (0x%08x)\n", msg->id);
652 rval = wsm_raw_cmd(priv, (u8 *)msg, len);
653 break;
654 }
655
656 return rval;
657}
658#endif /* CONFIG_CW1200_ETF */
diff --git a/drivers/net/wireless/cw1200/debug.h b/drivers/net/wireless/cw1200/debug.h
new file mode 100644
index 000000000000..1fea5b29a819
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.h
@@ -0,0 +1,98 @@
1/*
2 * DebugFS code for ST-Ericsson CW1200 mac80211 driver
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_DEBUG_H_INCLUDED
13#define CW1200_DEBUG_H_INCLUDED
14
15#include "itp.h"
16
17struct cw1200_debug_priv {
18 struct dentry *debugfs_phy;
19 int tx;
20 int tx_agg;
21 int rx;
22 int rx_agg;
23 int tx_multi;
24 int tx_multi_frames;
25 int tx_cache_miss;
26 int tx_align;
27 int tx_ttl;
28 int tx_burst;
29 int ba_cnt;
30 int ba_acc;
31 int ba_cnt_rx;
32 int ba_acc_rx;
33#ifdef CONFIG_CW1200_ITP
34 struct cw1200_itp itp;
35#endif /* CONFIG_CW1200_ITP */
36};
37
38int cw1200_debug_init(struct cw1200_common *priv);
39void cw1200_debug_release(struct cw1200_common *priv);
40
41static inline void cw1200_debug_txed(struct cw1200_common *priv)
42{
43 ++priv->debug->tx;
44}
45
46static inline void cw1200_debug_txed_agg(struct cw1200_common *priv)
47{
48 ++priv->debug->tx_agg;
49}
50
51static inline void cw1200_debug_txed_multi(struct cw1200_common *priv,
52 int count)
53{
54 ++priv->debug->tx_multi;
55 priv->debug->tx_multi_frames += count;
56}
57
58static inline void cw1200_debug_rxed(struct cw1200_common *priv)
59{
60 ++priv->debug->rx;
61}
62
63static inline void cw1200_debug_rxed_agg(struct cw1200_common *priv)
64{
65 ++priv->debug->rx_agg;
66}
67
68static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv)
69{
70 ++priv->debug->tx_cache_miss;
71}
72
73static inline void cw1200_debug_tx_align(struct cw1200_common *priv)
74{
75 ++priv->debug->tx_align;
76}
77
78static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv)
79{
80 ++priv->debug->tx_ttl;
81}
82
83static inline void cw1200_debug_tx_burst(struct cw1200_common *priv)
84{
85 ++priv->debug->tx_burst;
86}
87
88static inline void cw1200_debug_ba(struct cw1200_common *priv,
89 int ba_cnt, int ba_acc,
90 int ba_cnt_rx, int ba_acc_rx)
91{
92 priv->debug->ba_cnt = ba_cnt;
93 priv->debug->ba_acc = ba_acc;
94 priv->debug->ba_cnt_rx = ba_cnt_rx;
95 priv->debug->ba_acc_rx = ba_acc_rx;
96}
97
98#endif /* CW1200_DEBUG_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
new file mode 100644
index 000000000000..427c9f24b94e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -0,0 +1,525 @@
1/*
2 * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/init.h>
18#include <linux/vmalloc.h>
19#include <linux/sched.h>
20#include <linux/firmware.h>
21
22#include "cw1200.h"
23#include "fwio.h"
24#include "hwio.h"
25#include "hwbus.h"
26#include "bh.h"
27
28static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
29{
30 int hw_type = -1;
31 u32 silicon_type = (config_reg_val >> 24) & 0x7;
32 u32 silicon_vers = (config_reg_val >> 31) & 0x1;
33
34 switch (silicon_type) {
35 case 0x00:
36 *major_revision = 1;
37 hw_type = HIF_9000_SILICON_VERSATILE;
38 break;
39 case 0x01:
40 case 0x02: /* CW1x00 */
41 case 0x04: /* CW1x60 */
42 *major_revision = silicon_type;
43 if (silicon_vers)
44 hw_type = HIF_8601_VERSATILE;
45 else
46 hw_type = HIF_8601_SILICON;
47 break;
48 default:
49 break;
50 }
51
52 return hw_type;
53}
54
55static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
56{
57 int ret, block, num_blocks;
58 unsigned i;
59 u32 val32;
60 u32 put = 0, get = 0;
61 u8 *buf = NULL;
62 const char *fw_path;
63 const struct firmware *firmware = NULL;
64
65 /* Macroses are local. */
66#define APB_WRITE(reg, val) \
67 do { \
68 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
69 if (ret < 0) \
70 goto error; \
71 } while (0)
72#define APB_READ(reg, val) \
73 do { \
74 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
75 if (ret < 0) \
76 goto error; \
77 } while (0)
78#define REG_WRITE(reg, val) \
79 do { \
80 ret = cw1200_reg_write_32(priv, (reg), (val)); \
81 if (ret < 0) \
82 goto error; \
83 } while (0)
84#define REG_READ(reg, val) \
85 do { \
86 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
87 if (ret < 0) \
88 goto error; \
89 } while (0)
90
91 switch (priv->hw_revision) {
92 case CW1200_HW_REV_CUT10:
93 fw_path = FIRMWARE_CUT10;
94 if (!priv->sdd_path)
95 priv->sdd_path = SDD_FILE_10;
96 break;
97 case CW1200_HW_REV_CUT11:
98 fw_path = FIRMWARE_CUT11;
99 if (!priv->sdd_path)
100 priv->sdd_path = SDD_FILE_11;
101 break;
102 case CW1200_HW_REV_CUT20:
103 fw_path = FIRMWARE_CUT20;
104 if (!priv->sdd_path)
105 priv->sdd_path = SDD_FILE_20;
106 break;
107 case CW1200_HW_REV_CUT22:
108 fw_path = FIRMWARE_CUT22;
109 if (!priv->sdd_path)
110 priv->sdd_path = SDD_FILE_22;
111 break;
112 case CW1X60_HW_REV:
113 fw_path = FIRMWARE_CW1X60;
114 if (!priv->sdd_path)
115 priv->sdd_path = SDD_FILE_CW1X60;
116 break;
117 default:
118 pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
119 return -EINVAL;
120 }
121
122 /* Initialize common registers */
123 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
124 APB_WRITE(DOWNLOAD_PUT_REG, 0);
125 APB_WRITE(DOWNLOAD_GET_REG, 0);
126 APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
127 APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
128
129 /* Write the NOP Instruction */
130 REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
131 REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
132
133 /* Release CPU from RESET */
134 REG_READ(ST90TDS_CONFIG_REG_ID, val32);
135 val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
136 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
137
138 /* Enable Clock */
139 val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
140 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
141
142#ifdef CONFIG_CW1200_ETF
143 if (etf_mode)
144 fw_path = etf_firmware;
145#endif
146
147 /* Load a firmware file */
148 ret = request_firmware(&firmware, fw_path, priv->pdev);
149 if (ret) {
150 pr_err("Can't load firmware file %s.\n", fw_path);
151 goto error;
152 }
153
154 buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
155 if (!buf) {
156 pr_err("Can't allocate firmware load buffer.\n");
157 ret = -ENOMEM;
158 goto error;
159 }
160
161 /* Check if the bootloader is ready */
162 for (i = 0; i < 100; i += 1 + i / 2) {
163 APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
164 if (val32 == DOWNLOAD_I_AM_HERE)
165 break;
166 mdelay(i);
167 } /* End of for loop */
168
169 if (val32 != DOWNLOAD_I_AM_HERE) {
170 pr_err("Bootloader is not ready.\n");
171 ret = -ETIMEDOUT;
172 goto error;
173 }
174
175 /* Calculcate number of download blocks */
176 num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
177
178 /* Updating the length in Download Ctrl Area */
179 val32 = firmware->size; /* Explicit cast from size_t to u32 */
180 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32);
181
182 /* Firmware downloading loop */
183 for (block = 0; block < num_blocks; block++) {
184 size_t tx_size;
185 size_t block_size;
186
187 /* check the download status */
188 APB_READ(DOWNLOAD_STATUS_REG, val32);
189 if (val32 != DOWNLOAD_PENDING) {
190 pr_err("Bootloader reported error %d.\n", val32);
191 ret = -EIO;
192 goto error;
193 }
194
195 /* loop until put - get <= 24K */
196 for (i = 0; i < 100; i++) {
197 APB_READ(DOWNLOAD_GET_REG, get);
198 if ((put - get) <=
199 (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
200 break;
201 mdelay(i);
202 }
203
204 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
205 pr_err("Timeout waiting for FIFO.\n");
206 ret = -ETIMEDOUT;
207 goto error;
208 }
209
210 /* calculate the block size */
211 tx_size = block_size = min((size_t)(firmware->size - put),
212 (size_t)DOWNLOAD_BLOCK_SIZE);
213
214 memcpy(buf, &firmware->data[put], block_size);
215 if (block_size < DOWNLOAD_BLOCK_SIZE) {
216 memset(&buf[block_size], 0,
217 DOWNLOAD_BLOCK_SIZE - block_size);
218 tx_size = DOWNLOAD_BLOCK_SIZE;
219 }
220
221 /* send the block to sram */
222 ret = cw1200_apb_write(priv,
223 CW1200_APB(DOWNLOAD_FIFO_OFFSET +
224 (put & (DOWNLOAD_FIFO_SIZE - 1))),
225 buf, tx_size);
226 if (ret < 0) {
227 pr_err("Can't write firmware block @ %d!\n",
228 put & (DOWNLOAD_FIFO_SIZE - 1));
229 goto error;
230 }
231
232 /* update the put register */
233 put += block_size;
234 APB_WRITE(DOWNLOAD_PUT_REG, put);
235 } /* End of firmware download loop */
236
237 /* Wait for the download completion */
238 for (i = 0; i < 300; i += 1 + i / 2) {
239 APB_READ(DOWNLOAD_STATUS_REG, val32);
240 if (val32 != DOWNLOAD_PENDING)
241 break;
242 mdelay(i);
243 }
244 if (val32 != DOWNLOAD_SUCCESS) {
245 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
246 ret = -ETIMEDOUT;
247 goto error;
248 } else {
249 pr_info("Firmware download completed.\n");
250 ret = 0;
251 }
252
253error:
254 kfree(buf);
255 if (firmware)
256 release_firmware(firmware);
257 return ret;
258
259#undef APB_WRITE
260#undef APB_READ
261#undef REG_WRITE
262#undef REG_READ
263}
264
265
266static int config_reg_read(struct cw1200_common *priv, u32 *val)
267{
268 switch (priv->hw_type) {
269 case HIF_9000_SILICON_VERSATILE: {
270 u16 val16;
271 int ret = cw1200_reg_read_16(priv,
272 ST90TDS_CONFIG_REG_ID,
273 &val16);
274 if (ret < 0)
275 return ret;
276 *val = val16;
277 return 0;
278 }
279 case HIF_8601_VERSATILE:
280 case HIF_8601_SILICON:
281 default:
282 cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
283 break;
284 }
285 return 0;
286}
287
288static int config_reg_write(struct cw1200_common *priv, u32 val)
289{
290 switch (priv->hw_type) {
291 case HIF_9000_SILICON_VERSATILE:
292 return cw1200_reg_write_16(priv,
293 ST90TDS_CONFIG_REG_ID,
294 (u16)val);
295 case HIF_8601_VERSATILE:
296 case HIF_8601_SILICON:
297 default:
298 return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
299 break;
300 }
301 return 0;
302}
303
304int cw1200_load_firmware(struct cw1200_common *priv)
305{
306 int ret;
307 int i;
308 u32 val32;
309 u16 val16;
310 int major_revision = -1;
311
312 /* Read CONFIG Register */
313 ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
314 if (ret < 0) {
315 pr_err("Can't read config register.\n");
316 goto out;
317 }
318
319 if (val32 == 0 || val32 == 0xffffffff) {
320 pr_err("Bad config register value (0x%08x)\n", val32);
321 ret = -EIO;
322 goto out;
323 }
324
325 priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
326 if (priv->hw_type < 0) {
327 pr_err("Can't deduce hardware type.\n");
328 ret = -ENOTSUPP;
329 goto out;
330 }
331
332 /* Set DPLL Reg value, and read back to confirm writes work */
333 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
334 cw1200_dpll_from_clk(priv->hw_refclk));
335 if (ret < 0) {
336 pr_err("Can't write DPLL register.\n");
337 goto out;
338 }
339
340 msleep(20);
341
342 ret = cw1200_reg_read_32(priv,
343 ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
344 if (ret < 0) {
345 pr_err("Can't read DPLL register.\n");
346 goto out;
347 }
348
349 if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
350 pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
351 cw1200_dpll_from_clk(priv->hw_refclk), val32);
352 ret = -EIO;
353 goto out;
354 }
355
356 /* Set wakeup bit in device */
357 ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
358 if (ret < 0) {
359 pr_err("set_wakeup: can't read control register.\n");
360 goto out;
361 }
362
363 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
364 val16 | ST90TDS_CONT_WUP_BIT);
365 if (ret < 0) {
366 pr_err("set_wakeup: can't write control register.\n");
367 goto out;
368 }
369
370 /* Wait for wakeup */
371 for (i = 0; i < 300; i += (1 + i / 2)) {
372 ret = cw1200_reg_read_16(priv,
373 ST90TDS_CONTROL_REG_ID, &val16);
374 if (ret < 0) {
375 pr_err("wait_for_wakeup: can't read control register.\n");
376 goto out;
377 }
378
379 if (val16 & ST90TDS_CONT_RDY_BIT)
380 break;
381
382 msleep(i);
383 }
384
385 if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
386 pr_err("wait_for_wakeup: device is not responding.\n");
387 ret = -ETIMEDOUT;
388 goto out;
389 }
390
391 switch (major_revision) {
392 case 1:
393 /* CW1200 Hardware detection logic : Check for CUT1.1 */
394 ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
395 if (ret) {
396 pr_err("HW detection: can't read CUT ID.\n");
397 goto out;
398 }
399
400 switch (val32) {
401 case CW1200_CUT_11_ID_STR:
402 pr_info("CW1x00 Cut 1.1 silicon detected.\n");
403 priv->hw_revision = CW1200_HW_REV_CUT11;
404 break;
405 default:
406 pr_info("CW1x00 Cut 1.0 silicon detected.\n");
407 priv->hw_revision = CW1200_HW_REV_CUT10;
408 break;
409 }
410
411 /* According to ST-E, CUT<2.0 has busted BA TID0-3.
412 Just disable it entirely...
413 */
414 priv->ba_rx_tid_mask = 0;
415 priv->ba_tx_tid_mask = 0;
416 break;
417 case 2: {
418 u32 ar1, ar2, ar3;
419 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
420 if (ret) {
421 pr_err("(1) HW detection: can't read CUT ID\n");
422 goto out;
423 }
424 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
425 if (ret) {
426 pr_err("(2) HW detection: can't read CUT ID.\n");
427 goto out;
428 }
429
430 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
431 if (ret) {
432 pr_err("(3) HW detection: can't read CUT ID.\n");
433 goto out;
434 }
435
436 if (ar1 == CW1200_CUT_22_ID_STR1 &&
437 ar2 == CW1200_CUT_22_ID_STR2 &&
438 ar3 == CW1200_CUT_22_ID_STR3) {
439 pr_info("CW1x00 Cut 2.2 silicon detected.\n");
440 priv->hw_revision = CW1200_HW_REV_CUT22;
441 } else {
442 pr_info("CW1x00 Cut 2.0 silicon detected.\n");
443 priv->hw_revision = CW1200_HW_REV_CUT20;
444 }
445 break;
446 }
447 case 4:
448 pr_info("CW1x60 silicon detected.\n");
449 priv->hw_revision = CW1X60_HW_REV;
450 break;
451 default:
452 pr_err("Unsupported silicon major revision %d.\n",
453 major_revision);
454 ret = -ENOTSUPP;
455 goto out;
456 }
457
458 /* Checking for access mode */
459 ret = config_reg_read(priv, &val32);
460 if (ret < 0) {
461 pr_err("Can't read config register.\n");
462 goto out;
463 }
464
465 if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
466 pr_err("Device is already in QUEUE mode!\n");
467 ret = -EINVAL;
468 goto out;
469 }
470
471 switch (priv->hw_type) {
472 case HIF_8601_SILICON:
473 if (priv->hw_revision == CW1X60_HW_REV) {
474 pr_err("Can't handle CW1160/1260 firmware load yet.\n");
475 ret = -ENOTSUPP;
476 goto out;
477 }
478 ret = cw1200_load_firmware_cw1200(priv);
479 break;
480 default:
481 pr_err("Can't perform firmware load for hw type %d.\n",
482 priv->hw_type);
483 ret = -ENOTSUPP;
484 goto out;
485 }
486 if (ret < 0) {
487 pr_err("Firmware load error.\n");
488 goto out;
489 }
490
491 /* Enable interrupt signalling */
492 priv->hwbus_ops->lock(priv->hwbus_priv);
493 ret = __cw1200_irq_enable(priv, 1);
494 priv->hwbus_ops->unlock(priv->hwbus_priv);
495 if (ret < 0)
496 goto unsubscribe;
497
498 /* Configure device for MESSSAGE MODE */
499 ret = config_reg_read(priv, &val32);
500 if (ret < 0) {
501 pr_err("Can't read config register.\n");
502 goto unsubscribe;
503 }
504 ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
505 if (ret < 0) {
506 pr_err("Can't write config register.\n");
507 goto unsubscribe;
508 }
509
510 /* Unless we read the CONFIG Register we are
511 * not able to get an interrupt
512 */
513 mdelay(10);
514 config_reg_read(priv, &val32);
515
516out:
517 return ret;
518
519unsubscribe:
520 /* Disable interrupt signalling */
521 priv->hwbus_ops->lock(priv->hwbus_priv);
522 ret = __cw1200_irq_enable(priv, 0);
523 priv->hwbus_ops->unlock(priv->hwbus_priv);
524 return ret;
525}
diff --git a/drivers/net/wireless/cw1200/fwio.h b/drivers/net/wireless/cw1200/fwio.h
new file mode 100644
index 000000000000..ea3099362cdf
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.h
@@ -0,0 +1,39 @@
1/*
2 * Firmware API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef FWIO_H_INCLUDED
18#define FWIO_H_INCLUDED
19
20#define BOOTLOADER_CW1X60 "boot_cw1x60.bin"
21#define FIRMWARE_CW1X60 "wsm_cw1x60.bin"
22#define FIRMWARE_CUT22 "wsm_22.bin"
23#define FIRMWARE_CUT20 "wsm_20.bin"
24#define FIRMWARE_CUT11 "wsm_11.bin"
25#define FIRMWARE_CUT10 "wsm_10.bin"
26#define SDD_FILE_CW1X60 "sdd_cw1x60.bin"
27#define SDD_FILE_22 "sdd_22.bin"
28#define SDD_FILE_20 "sdd_20.bin"
29#define SDD_FILE_11 "sdd_11.bin"
30#define SDD_FILE_10 "sdd_10.bin"
31
32int cw1200_load_firmware(struct cw1200_common *priv);
33
34/* SDD definitions */
35#define SDD_PTA_CFG_ELT_ID 0xEB
36#define SDD_REFERENCE_FREQUENCY_ELT_ID 0xc5
37u32 cw1200_dpll_from_clk(u16 clk);
38
39#endif
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h
new file mode 100644
index 000000000000..8b2fc831c3de
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwbus.h
@@ -0,0 +1,33 @@
1/*
2 * Common hwbus abstraction layer interface for cw1200 wireless driver
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_HWBUS_H
13#define CW1200_HWBUS_H
14
15struct hwbus_priv;
16
17void cw1200_irq_handler(struct cw1200_common *priv);
18
19/* This MUST be wrapped with hwbus_ops->lock/unlock! */
20int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
21
22struct hwbus_ops {
23 int (*hwbus_memcpy_fromio)(struct hwbus_priv *self, unsigned int addr,
24 void *dst, int count);
25 int (*hwbus_memcpy_toio)(struct hwbus_priv *self, unsigned int addr,
26 const void *src, int count);
27 void (*lock)(struct hwbus_priv *self);
28 void (*unlock)(struct hwbus_priv *self);
29 size_t (*align_size)(struct hwbus_priv *self, size_t size);
30 int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
31};
32
33#endif /* CW1200_HWBUS_H */
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
new file mode 100644
index 000000000000..142f45efa204
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -0,0 +1,311 @@
1/*
2 * Low-level device IO routines for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/types.h>
18
19#include "cw1200.h"
20#include "hwio.h"
21#include "hwbus.h"
22
23 /* Sdio addr is 4*spi_addr */
24#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
25#define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
26 ((((buf_id) & 0x1F) << 7) \
27 | (((mpf) & 1) << 6) \
28 | (((rfu) & 1) << 5) \
29 | (((reg_id_ofs) & 0x1F) << 0))
30#define MAX_RETRY 3
31
32
33static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
34 void *buf, size_t buf_len, int buf_id)
35{
36 u16 addr_sdio;
37 u32 sdio_reg_addr_17bit;
38
39 /* Check if buffer is aligned to 4 byte boundary */
40 if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
41 pr_err("buffer is not aligned.\n");
42 return -EINVAL;
43 }
44
45 /* Convert to SDIO Register Address */
46 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
47 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
48
49 return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
50 sdio_reg_addr_17bit,
51 buf, buf_len);
52}
53
54static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
55 const void *buf, size_t buf_len, int buf_id)
56{
57 u16 addr_sdio;
58 u32 sdio_reg_addr_17bit;
59
60 /* Convert to SDIO Register Address */
61 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
62 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
63
64 return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
65 sdio_reg_addr_17bit,
66 buf, buf_len);
67}
68
69static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 u16 addr, u32 *val)
71{
72 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
73 *val = le32_to_cpu(*val);
74 return i;
75}
76
77static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
78 u16 addr, u32 val)
79{
80 val = cpu_to_le32(val);
81 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
82}
83
84static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
85 u16 addr, u16 *val)
86{
87 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
88 *val = le16_to_cpu(*val);
89 return i;
90}
91
92static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
93 u16 addr, u16 val)
94{
95 val = cpu_to_le16(val);
96 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
97}
98
99int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
100 size_t buf_len)
101{
102 int ret;
103 priv->hwbus_ops->lock(priv->hwbus_priv);
104 ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
105 priv->hwbus_ops->unlock(priv->hwbus_priv);
106 return ret;
107}
108
109int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
110 size_t buf_len)
111{
112 int ret;
113 priv->hwbus_ops->lock(priv->hwbus_priv);
114 ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
115 priv->hwbus_ops->unlock(priv->hwbus_priv);
116 return ret;
117}
118
119int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
120{
121 int ret, retry = 1;
122 int buf_id_rx = priv->buf_id_rx;
123
124 priv->hwbus_ops->lock(priv->hwbus_priv);
125
126 while (retry <= MAX_RETRY) {
127 ret = __cw1200_reg_read(priv,
128 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
129 buf_len, buf_id_rx + 1);
130 if (!ret) {
131 buf_id_rx = (buf_id_rx + 1) & 3;
132 priv->buf_id_rx = buf_id_rx;
133 break;
134 } else {
135 retry++;
136 mdelay(1);
137 pr_err("error :[%d]\n", ret);
138 }
139 }
140
141 priv->hwbus_ops->unlock(priv->hwbus_priv);
142 return ret;
143}
144
145int cw1200_data_write(struct cw1200_common *priv, const void *buf,
146 size_t buf_len)
147{
148 int ret, retry = 1;
149 int buf_id_tx = priv->buf_id_tx;
150
151 priv->hwbus_ops->lock(priv->hwbus_priv);
152
153 while (retry <= MAX_RETRY) {
154 ret = __cw1200_reg_write(priv,
155 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
156 buf_len, buf_id_tx);
157 if (!ret) {
158 buf_id_tx = (buf_id_tx + 1) & 31;
159 priv->buf_id_tx = buf_id_tx;
160 break;
161 } else {
162 retry++;
163 mdelay(1);
164 pr_err("error :[%d]\n", ret);
165 }
166 }
167
168 priv->hwbus_ops->unlock(priv->hwbus_priv);
169 return ret;
170}
171
172int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
173 size_t buf_len, u32 prefetch, u16 port_addr)
174{
175 u32 val32 = 0;
176 int i, ret;
177
178 if ((buf_len / 2) >= 0x1000) {
179 pr_err("Can't read more than 0xfff words.\n");
180 return -EINVAL;
181 goto out;
182 }
183
184 priv->hwbus_ops->lock(priv->hwbus_priv);
185 /* Write address */
186 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
187 if (ret < 0) {
188 pr_err("Can't write address register.\n");
189 goto out;
190 }
191
192 /* Read CONFIG Register Value - We will read 32 bits */
193 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
194 if (ret < 0) {
195 pr_err("Can't read config register.\n");
196 goto out;
197 }
198
199 /* Set PREFETCH bit */
200 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
201 val32 | prefetch);
202 if (ret < 0) {
203 pr_err("Can't write prefetch bit.\n");
204 goto out;
205 }
206
207 /* Check for PRE-FETCH bit to be cleared */
208 for (i = 0; i < 20; i++) {
209 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
210 if (ret < 0) {
211 pr_err("Can't check prefetch bit.\n");
212 goto out;
213 }
214 if (!(val32 & prefetch))
215 break;
216
217 mdelay(i);
218 }
219
220 if (val32 & prefetch) {
221 pr_err("Prefetch bit is not cleared.\n");
222 goto out;
223 }
224
225 /* Read data port */
226 ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
227 if (ret < 0) {
228 pr_err("Can't read data port.\n");
229 goto out;
230 }
231
232out:
233 priv->hwbus_ops->unlock(priv->hwbus_priv);
234 return ret;
235}
236
237int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
238 size_t buf_len)
239{
240 int ret;
241
242 if ((buf_len / 2) >= 0x1000) {
243 pr_err("Can't write more than 0xfff words.\n");
244 return -EINVAL;
245 }
246
247 priv->hwbus_ops->lock(priv->hwbus_priv);
248
249 /* Write address */
250 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
251 if (ret < 0) {
252 pr_err("Can't write address register.\n");
253 goto out;
254 }
255
256 /* Write data port */
257 ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
258 buf, buf_len, 0);
259 if (ret < 0) {
260 pr_err("Can't write data port.\n");
261 goto out;
262 }
263
264out:
265 priv->hwbus_ops->unlock(priv->hwbus_priv);
266 return ret;
267}
268
269int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
270{
271 u32 val32;
272 u16 val16;
273 int ret;
274
275 if (HIF_8601_SILICON == priv->hw_type) {
276 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
277 if (ret < 0) {
278 pr_err("Can't read config register.\n");
279 return ret;
280 }
281
282 if (enable)
283 val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
284 else
285 val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
286
287 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
288 if (ret < 0) {
289 pr_err("Can't write config register.\n");
290 return ret;
291 }
292 } else {
293 ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
294 if (ret < 0) {
295 pr_err("Can't read control register.\n");
296 return ret;
297 }
298
299 if (enable)
300 val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
301 else
302 val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
303
304 ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
305 if (ret < 0) {
306 pr_err("Can't write control register.\n");
307 return ret;
308 }
309 }
310 return 0;
311}
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
new file mode 100644
index 000000000000..7ee73fe32ccf
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -0,0 +1,247 @@
1/*
2 * Low-level API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef CW1200_HWIO_H_INCLUDED
18#define CW1200_HWIO_H_INCLUDED
19
20/* extern */ struct cw1200_common;
21
22#define CW1200_CUT_11_ID_STR (0x302E3830)
23#define CW1200_CUT_22_ID_STR1 (0x302e3132)
24#define CW1200_CUT_22_ID_STR2 (0x32302e30)
25#define CW1200_CUT_22_ID_STR3 (0x3335)
26#define CW1200_CUT_ID_ADDR (0xFFF17F90)
27#define CW1200_CUT2_ID_ADDR (0xFFF1FF90)
28
29/* Download control area */
30/* boot loader start address in SRAM */
31#define DOWNLOAD_BOOT_LOADER_OFFSET (0x00000000)
32/* 32K, 0x4000 to 0xDFFF */
33#define DOWNLOAD_FIFO_OFFSET (0x00004000)
34/* 32K */
35#define DOWNLOAD_FIFO_SIZE (0x00008000)
36/* 128 bytes, 0xFF80 to 0xFFFF */
37#define DOWNLOAD_CTRL_OFFSET (0x0000FF80)
38#define DOWNLOAD_CTRL_DATA_DWORDS (32-6)
39
40struct download_cntl_t {
41 /* size of whole firmware file (including Cheksum), host init */
42 u32 image_size;
43 /* downloading flags */
44 u32 flags;
45 /* No. of bytes put into the download, init & updated by host */
46 u32 put;
47 /* last traced program counter, last ARM reg_pc */
48 u32 trace_pc;
49 /* No. of bytes read from the download, host init, device updates */
50 u32 get;
51 /* r0, boot losader status, host init to pending, device updates */
52 u32 status;
53 /* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */
54 u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS];
55};
56
57#define DOWNLOAD_IMAGE_SIZE_REG \
58 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size))
59#define DOWNLOAD_FLAGS_REG \
60 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags))
61#define DOWNLOAD_PUT_REG \
62 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put))
63#define DOWNLOAD_TRACE_PC_REG \
64 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc))
65#define DOWNLOAD_GET_REG \
66 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get))
67#define DOWNLOAD_STATUS_REG \
68 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status))
69#define DOWNLOAD_DEBUG_DATA_REG \
70 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data))
71#define DOWNLOAD_DEBUG_DATA_LEN (108)
72
73#define DOWNLOAD_BLOCK_SIZE (1024)
74
75/* For boot loader detection */
76#define DOWNLOAD_ARE_YOU_HERE (0x87654321)
77#define DOWNLOAD_I_AM_HERE (0x12345678)
78
79/* Download error code */
80#define DOWNLOAD_PENDING (0xFFFFFFFF)
81#define DOWNLOAD_SUCCESS (0)
82#define DOWNLOAD_EXCEPTION (1)
83#define DOWNLOAD_ERR_MEM_1 (2)
84#define DOWNLOAD_ERR_MEM_2 (3)
85#define DOWNLOAD_ERR_SOFTWARE (4)
86#define DOWNLOAD_ERR_FILE_SIZE (5)
87#define DOWNLOAD_ERR_CHECKSUM (6)
88#define DOWNLOAD_ERR_OVERFLOW (7)
89#define DOWNLOAD_ERR_IMAGE (8)
90#define DOWNLOAD_ERR_HOST (9)
91#define DOWNLOAD_ERR_ABORT (10)
92
93
94#define SYS_BASE_ADDR_SILICON (0)
95#define PAC_BASE_ADDRESS_SILICON (SYS_BASE_ADDR_SILICON + 0x09000000)
96#define PAC_SHARED_MEMORY_SILICON (PAC_BASE_ADDRESS_SILICON)
97
98#define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr))
99
100/* ***************************************************************
101*Device register definitions
102*************************************************************** */
103/* WBF - SPI Register Addresses */
104#define ST90TDS_ADDR_ID_BASE (0x0000)
105/* 16/32 bits */
106#define ST90TDS_CONFIG_REG_ID (0x0000)
107/* 16/32 bits */
108#define ST90TDS_CONTROL_REG_ID (0x0001)
109/* 16 bits, Q mode W/R */
110#define ST90TDS_IN_OUT_QUEUE_REG_ID (0x0002)
111/* 32 bits, AHB bus R/W */
112#define ST90TDS_AHB_DPORT_REG_ID (0x0003)
113/* 16/32 bits */
114#define ST90TDS_SRAM_BASE_ADDR_REG_ID (0x0004)
115/* 32 bits, APB bus R/W */
116#define ST90TDS_SRAM_DPORT_REG_ID (0x0005)
117/* 32 bits, t_settle/general */
118#define ST90TDS_TSET_GEN_R_W_REG_ID (0x0006)
119/* 16 bits, Q mode read, no length */
120#define ST90TDS_FRAME_OUT_REG_ID (0x0007)
121#define ST90TDS_ADDR_ID_MAX (ST90TDS_FRAME_OUT_REG_ID)
122
123/* WBF - Control register bit set */
124/* next o/p length, bit 11 to 0 */
125#define ST90TDS_CONT_NEXT_LEN_MASK (0x0FFF)
126#define ST90TDS_CONT_WUP_BIT (BIT(12))
127#define ST90TDS_CONT_RDY_BIT (BIT(13))
128#define ST90TDS_CONT_IRQ_ENABLE (BIT(14))
129#define ST90TDS_CONT_RDY_ENABLE (BIT(15))
130#define ST90TDS_CONT_IRQ_RDY_ENABLE (BIT(14)|BIT(15))
131
132/* SPI Config register bit set */
133#define ST90TDS_CONFIG_FRAME_BIT (BIT(2))
134#define ST90TDS_CONFIG_WORD_MODE_BITS (BIT(3)|BIT(4))
135#define ST90TDS_CONFIG_WORD_MODE_1 (BIT(3))
136#define ST90TDS_CONFIG_WORD_MODE_2 (BIT(4))
137#define ST90TDS_CONFIG_ERROR_0_BIT (BIT(5))
138#define ST90TDS_CONFIG_ERROR_1_BIT (BIT(6))
139#define ST90TDS_CONFIG_ERROR_2_BIT (BIT(7))
140/* TBD: Sure??? */
141#define ST90TDS_CONFIG_CSN_FRAME_BIT (BIT(7))
142#define ST90TDS_CONFIG_ERROR_3_BIT (BIT(8))
143#define ST90TDS_CONFIG_ERROR_4_BIT (BIT(9))
144/* QueueM */
145#define ST90TDS_CONFIG_ACCESS_MODE_BIT (BIT(10))
146/* AHB bus */
147#define ST90TDS_CONFIG_AHB_PRFETCH_BIT (BIT(11))
148#define ST90TDS_CONFIG_CPU_CLK_DIS_BIT (BIT(12))
149/* APB bus */
150#define ST90TDS_CONFIG_PRFETCH_BIT (BIT(13))
151/* cpu reset */
152#define ST90TDS_CONFIG_CPU_RESET_BIT (BIT(14))
153#define ST90TDS_CONFIG_CLEAR_INT_BIT (BIT(15))
154
155/* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */
156#define ST90TDS_CONF_IRQ_ENABLE (BIT(16))
157#define ST90TDS_CONF_RDY_ENABLE (BIT(17))
158#define ST90TDS_CONF_IRQ_RDY_ENABLE (BIT(16)|BIT(17))
159
160int cw1200_data_read(struct cw1200_common *priv,
161 void *buf, size_t buf_len);
162int cw1200_data_write(struct cw1200_common *priv,
163 const void *buf, size_t buf_len);
164
165int cw1200_reg_read(struct cw1200_common *priv, u16 addr,
166 void *buf, size_t buf_len);
167int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
168 const void *buf, size_t buf_len);
169
170static inline int cw1200_reg_read_16(struct cw1200_common *priv,
171 u16 addr, u16 *val)
172{
173 u32 tmp;
174 int i;
175 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
176 tmp = le32_to_cpu(tmp);
177 *val = tmp & 0xffff;
178 return i;
179}
180
181static inline int cw1200_reg_write_16(struct cw1200_common *priv,
182 u16 addr, u16 val)
183{
184 u32 tmp = val;
185 tmp = cpu_to_le32(tmp);
186 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
187}
188
189static inline int cw1200_reg_read_32(struct cw1200_common *priv,
190 u16 addr, u32 *val)
191{
192 int i = cw1200_reg_read(priv, addr, val, sizeof(*val));
193 *val = le32_to_cpu(*val);
194 return i;
195}
196
197static inline int cw1200_reg_write_32(struct cw1200_common *priv,
198 u16 addr, u32 val)
199{
200 val = cpu_to_le32(val);
201 return cw1200_reg_write(priv, addr, &val, sizeof(val));
202}
203
204int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
205 size_t buf_len, u32 prefetch, u16 port_addr);
206int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
207 size_t buf_len);
208
209static inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr,
210 void *buf, size_t buf_len)
211{
212 return cw1200_indirect_read(priv, addr, buf, buf_len,
213 ST90TDS_CONFIG_PRFETCH_BIT,
214 ST90TDS_SRAM_DPORT_REG_ID);
215}
216
217static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
218 void *buf, size_t buf_len)
219{
220 return cw1200_indirect_read(priv, addr, buf, buf_len,
221 ST90TDS_CONFIG_AHB_PRFETCH_BIT,
222 ST90TDS_AHB_DPORT_REG_ID);
223}
224
225static inline int cw1200_apb_read_32(struct cw1200_common *priv,
226 u32 addr, u32 *val)
227{
228 int i = cw1200_apb_read(priv, addr, val, sizeof(*val));
229 *val = le32_to_cpu(*val);
230 return i;
231}
232
233static inline int cw1200_apb_write_32(struct cw1200_common *priv,
234 u32 addr, u32 val)
235{
236 val = cpu_to_le32(val);
237 return cw1200_apb_write(priv, addr, &val, sizeof(val));
238}
239static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
240 u32 addr, u32 *val)
241{
242 int i = cw1200_ahb_read(priv, addr, val, sizeof(*val));
243 *val = le32_to_cpu(*val);
244 return i;
245}
246
247#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/itp.c b/drivers/net/wireless/cw1200/itp.c
new file mode 100644
index 000000000000..c0730bb49b75
--- /dev/null
+++ b/drivers/net/wireless/cw1200/itp.c
@@ -0,0 +1,730 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 * ITP code
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/poll.h>
16#include <linux/time.h>
17#include <linux/random.h>
18#include <linux/kallsyms.h>
19#include <net/mac80211.h>
20#include "cw1200.h"
21#include "debug.h"
22#include "itp.h"
23#include "sta.h"
24
25static int __cw1200_itp_open(struct cw1200_common *priv);
26static int __cw1200_itp_close(struct cw1200_common *priv);
27static void cw1200_itp_rx_start(struct cw1200_common *priv);
28static void cw1200_itp_rx_stop(struct cw1200_common *priv);
29static void cw1200_itp_rx_stats(struct cw1200_common *priv);
30static void cw1200_itp_rx_reset(struct cw1200_common *priv);
31static void cw1200_itp_tx_stop(struct cw1200_common *priv);
32static void cw1200_itp_handle(struct cw1200_common *priv,
33 struct sk_buff *skb);
34static void cw1200_itp_err(struct cw1200_common *priv,
35 int err,
36 int arg);
37static void __cw1200_itp_tx_stop(struct cw1200_common *priv);
38
39static ssize_t cw1200_itp_read(struct file *file,
40 char __user *user_buf, size_t count, loff_t *ppos)
41{
42 struct cw1200_common *priv = file->private_data;
43 struct cw1200_itp *itp = &priv->debug->itp;
44 struct sk_buff *skb;
45 int ret;
46
47 if (skb_queue_empty(&itp->log_queue))
48 return 0;
49
50 skb = skb_dequeue(&itp->log_queue);
51 ret = copy_to_user(user_buf, skb->data, skb->len);
52 *ppos += skb->len;
53 skb->data[skb->len] = 0;
54 pr_debug("[ITP] >>> %s", skb->data);
55 consume_skb(skb);
56
57 return skb->len - ret;
58}
59
60static ssize_t cw1200_itp_write(struct file *file,
61 const char __user *user_buf, size_t count, loff_t *ppos)
62{
63 struct cw1200_common *priv = file->private_data;
64 struct sk_buff *skb;
65
66 if (!count || count > 1024)
67 return -EINVAL;
68 skb = dev_alloc_skb(count + 1);
69 if (!skb)
70 return -ENOMEM;
71 skb_trim(skb, 0);
72 skb_put(skb, count + 1);
73 if (copy_from_user(skb->data, user_buf, count)) {
74 kfree_skb(skb);
75 return -EFAULT;
76 }
77 skb->data[count] = 0;
78
79 cw1200_itp_handle(priv, skb);
80 consume_skb(skb);
81 return count;
82}
83
84static unsigned int cw1200_itp_poll(struct file *file, poll_table *wait)
85{
86 struct cw1200_common *priv = file->private_data;
87 struct cw1200_itp *itp = &priv->debug->itp;
88 unsigned int mask = 0;
89
90 poll_wait(file, &itp->read_wait, wait);
91
92 if (!skb_queue_empty(&itp->log_queue))
93 mask |= POLLIN | POLLRDNORM;
94
95 mask |= POLLOUT | POLLWRNORM;
96
97 return mask;
98}
99
100static int cw1200_itp_open(struct inode *inode, struct file *file)
101{
102 struct cw1200_common *priv = inode->i_private;
103 struct cw1200_itp *itp = &priv->debug->itp;
104 int ret = 0;
105
106 file->private_data = priv;
107 if (atomic_inc_return(&itp->open_count) == 1) {
108 ret = __cw1200_itp_open(priv);
109 if (ret && !atomic_dec_return(&itp->open_count))
110 __cw1200_itp_close(priv);
111 } else {
112 atomic_dec(&itp->open_count);
113 ret = -EBUSY;
114 }
115
116 return ret;
117}
118
119static int cw1200_itp_close(struct inode *inode, struct file *file)
120{
121 struct cw1200_common *priv = file->private_data;
122 struct cw1200_itp *itp = &priv->debug->itp;
123 if (!atomic_dec_return(&itp->open_count)) {
124 __cw1200_itp_close(priv);
125 wake_up(&itp->close_wait);
126 }
127 return 0;
128}
129
130static const struct file_operations fops_itp = {
131 .open = cw1200_itp_open,
132 .read = cw1200_itp_read,
133 .write = cw1200_itp_write,
134 .poll = cw1200_itp_poll,
135 .release = cw1200_itp_close,
136 .llseek = default_llseek,
137 .owner = THIS_MODULE,
138};
139
140static void cw1200_itp_fill_pattern(u8 *data, int size,
141 enum cw1200_itp_data_modes mode)
142{
143 if (size <= 0)
144 return;
145
146 switch (mode) {
147 default:
148 case ITP_DATA_ZEROS:
149 memset(data, 0x0, size);
150 break;
151 case ITP_DATA_ONES:
152 memset(data, 0xff, size);
153 break;
154 case ITP_DATA_ZERONES:
155 memset(data, 0x55, size);
156 break;
157 case ITP_DATA_RANDOM:
158 get_random_bytes(data, size);
159 break;
160 }
161 return;
162}
163
164static void cw1200_itp_tx_work(struct work_struct *work)
165{
166 struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
167 tx_work.work);
168 struct cw1200_common *priv = itp->priv;
169 atomic_set(&priv->bh_tx, 1);
170 wake_up(&priv->bh_wq);
171}
172
173static void cw1200_itp_tx_finish(struct work_struct *work)
174{
175 struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
176 tx_finish.work);
177 __cw1200_itp_tx_stop(itp->priv);
178}
179
180int cw1200_itp_init(struct cw1200_common *priv)
181{
182 struct cw1200_itp *itp = &priv->debug->itp;
183
184 itp->priv = priv;
185 atomic_set(&itp->open_count, 0);
186 atomic_set(&itp->stop_tx, 0);
187 atomic_set(&itp->awaiting_confirm, 0);
188 skb_queue_head_init(&itp->log_queue);
189 spin_lock_init(&itp->tx_lock);
190 init_waitqueue_head(&itp->read_wait);
191 init_waitqueue_head(&itp->write_wait);
192 init_waitqueue_head(&itp->close_wait);
193 INIT_DELAYED_WORK(&itp->tx_work, cw1200_itp_tx_work);
194 INIT_DELAYED_WORK(&itp->tx_finish, cw1200_itp_tx_finish);
195 itp->data = NULL;
196 itp->hdr_len = WSM_TX_EXTRA_HEADROOM +
197 sizeof(struct ieee80211_hdr_3addr);
198
199 if (!debugfs_create_file("itp", S_IRUSR | S_IWUSR,
200 priv->debug->debugfs_phy, priv, &fops_itp))
201 return -ENOMEM;
202
203 return 0;
204}
205
206void cw1200_itp_release(struct cw1200_common *priv)
207{
208 struct cw1200_itp *itp = &priv->debug->itp;
209
210 wait_event_interruptible(itp->close_wait,
211 !atomic_read(&itp->open_count));
212
213 WARN_ON(atomic_read(&itp->open_count));
214
215 skb_queue_purge(&itp->log_queue);
216 cw1200_itp_tx_stop(priv);
217}
218
219static int __cw1200_itp_open(struct cw1200_common *priv)
220{
221 struct cw1200_itp *itp = &priv->debug->itp;
222
223 if (!priv->vif)
224 return -EINVAL;
225 if (priv->join_status)
226 return -EINVAL;
227 itp->saved_channel = priv->channel;
228 if (!priv->channel)
229 priv->channel = &priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
230 wsm_set_bssid_filtering(priv, false);
231 cw1200_itp_rx_reset(priv);
232 return 0;
233}
234
235static int __cw1200_itp_close(struct cw1200_common *priv)
236{
237 struct cw1200_itp *itp = &priv->debug->itp;
238 if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST)
239 cw1200_itp_rx_stop(priv);
240 cw1200_itp_tx_stop(priv);
241 cw1200_disable_listening(priv);
242 cw1200_update_filtering(priv);
243 priv->channel = itp->saved_channel;
244 return 0;
245}
246
247bool cw1200_is_itp(struct cw1200_common *priv)
248{
249 struct cw1200_itp *itp = &priv->debug->itp;
250 return atomic_read(&itp->open_count) != 0;
251}
252
253static void cw1200_itp_rx_reset(struct cw1200_common *priv)
254{
255 struct cw1200_itp *itp = &priv->debug->itp;
256 itp->rx_cnt = 0;
257 itp->rx_rssi = 0;
258 itp->rx_rssi_max = -1000;
259 itp->rx_rssi_min = 1000;
260}
261
262static void cw1200_itp_rx_start(struct cw1200_common *priv)
263{
264 struct cw1200_itp *itp = &priv->debug->itp;
265
266 pr_debug("[ITP] RX start, band = %d, ch = %d\n",
267 itp->band, itp->ch);
268 atomic_set(&itp->test_mode, TEST_MODE_RX_TEST);
269 cw1200_update_listening(priv, false);
270 priv->channel = &priv->hw->
271 wiphy->bands[itp->band]->channels[itp->ch];
272 cw1200_update_listening(priv, true);
273 wsm_set_bssid_filtering(priv, false);
274}
275
276static void cw1200_itp_rx_stop(struct cw1200_common *priv)
277{
278 struct cw1200_itp *itp = &priv->debug->itp;
279 pr_debug("[ITP] RX stop\n");
280 atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
281 cw1200_itp_rx_reset(priv);
282}
283
284static void cw1200_itp_rx_stats(struct cw1200_common *priv)
285{
286 struct cw1200_itp *itp = &priv->debug->itp;
287 struct sk_buff *skb;
288 char buf[128];
289 int len, ret;
290 struct wsm_mib_counters_table counters;
291
292 ret = wsm_get_counters_table(priv, &counters);
293
294 if (ret)
295 cw1200_itp_err(priv, -EBUSY, 20);
296
297 if (!itp->rx_cnt)
298 len = snprintf(buf, sizeof(buf), "1,0,0,0,0,%d\n",
299 counters.rx_packet_errors);
300 else
301 len = snprintf(buf, sizeof(buf), "1,%d,%ld,%d,%d,%d\n",
302 itp->rx_cnt,
303 itp->rx_cnt ? itp->rx_rssi / itp->rx_cnt : 0,
304 itp->rx_rssi_min, itp->rx_rssi_max,
305 counters.rx_packet_errors);
306
307 if (len <= 0) {
308 cw1200_itp_err(priv, -EBUSY, 21);
309 return;
310 }
311
312 skb = dev_alloc_skb(len);
313 if (!skb) {
314 cw1200_itp_err(priv, -ENOMEM, 22);
315 return;
316 }
317
318 itp->rx_cnt = 0;
319 itp->rx_rssi = 0;
320 itp->rx_rssi_max = -1000;
321 itp->rx_rssi_min = 1000;
322
323 skb_trim(skb, 0);
324 skb_put(skb, len);
325
326 memcpy(skb->data, buf, len);
327 skb_queue_tail(&itp->log_queue, skb);
328 wake_up(&itp->read_wait);
329}
330
331static void cw1200_itp_tx_start(struct cw1200_common *priv)
332{
333 struct wsm_tx *tx;
334 struct ieee80211_hdr_3addr *hdr;
335 struct cw1200_itp *itp = &priv->debug->itp;
336 struct wsm_mib_association_mode assoc_mode = {
337 .flags = WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE,
338 .preamble = itp->preamble,
339 };
340 int len;
341 u8 da_addr[6] = ITP_DEFAULT_DA_ADDR;
342
343 /* Rates index 4 and 5 are not supported */
344 if (itp->rate > 3)
345 itp->rate += 2;
346
347 pr_debug("[ITP] TX start: band = %d, ch = %d, rate = %d, preamble = %d, number = %d, data_mode = %d, interval = %d, power = %d, data_len = %d\n",
348 itp->band, itp->ch, itp->rate, itp->preamble,
349 itp->number, itp->data_mode, itp->interval_us,
350 itp->power, itp->data_len);
351
352 len = itp->hdr_len + itp->data_len;
353
354 itp->data = kmalloc(len, GFP_KERNEL);
355 tx = (struct wsm_tx *)itp->data;
356 tx->hdr.len = itp->data_len + itp->hdr_len;
357 tx->hdr.id = __cpu_to_le16(0x0004 | 1 << 6);
358 tx->max_tx_rate = itp->rate;
359 tx->queue_id = 3;
360 tx->more = 0;
361 tx->flags = 0xc;
362 tx->packet_id = 0x55ff55;
363 tx->reserved = 0;
364 tx->expire_time = 1;
365
366 if (itp->preamble == ITP_PREAMBLE_GREENFIELD)
367 tx->ht_tx_parameters = WSM_HT_TX_GREENFIELD;
368 else if (itp->preamble == ITP_PREAMBLE_MIXED)
369 tx->ht_tx_parameters = WSM_HT_TX_MIXED;
370
371 hdr = (struct ieee80211_hdr_3addr *)&itp->data[sizeof(struct wsm_tx)];
372 memset(hdr, 0, sizeof(*hdr));
373 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
374 memcpy(hdr->addr1, da_addr, ETH_ALEN);
375 memcpy(hdr->addr2, priv->vif->addr, ETH_ALEN);
376 memcpy(hdr->addr3, da_addr, ETH_ALEN);
377
378 cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
379 itp->data_len, itp->data_mode);
380
381 cw1200_update_listening(priv, false);
382 priv->channel = &priv->hw->wiphy->bands[itp->band]->channels[itp->ch];
383 WARN_ON(wsm_set_output_power(priv, itp->power));
384 if (itp->preamble == ITP_PREAMBLE_SHORT ||
385 itp->preamble == ITP_PREAMBLE_LONG)
386 WARN_ON(wsm_set_association_mode(priv,
387 &assoc_mode));
388 wsm_set_bssid_filtering(priv, false);
389 cw1200_update_listening(priv, true);
390
391 spin_lock_bh(&itp->tx_lock);
392 atomic_set(&itp->test_mode, TEST_MODE_TX_TEST);
393 atomic_set(&itp->awaiting_confirm, 0);
394 atomic_set(&itp->stop_tx, 0);
395 atomic_set(&priv->bh_tx, 1);
396 ktime_get_ts(&itp->last_sent);
397 wake_up(&priv->bh_wq);
398 spin_unlock_bh(&itp->tx_lock);
399}
400
401void __cw1200_itp_tx_stop(struct cw1200_common *priv)
402{
403 struct cw1200_itp *itp = &priv->debug->itp;
404 spin_lock_bh(&itp->tx_lock);
405 kfree(itp->data);
406 itp->data = NULL;
407 atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
408 spin_unlock_bh(&itp->tx_lock);
409}
410
411static void cw1200_itp_tx_stop(struct cw1200_common *priv)
412{
413 struct cw1200_itp *itp = &priv->debug->itp;
414 pr_debug("[ITP] TX stop\n");
415 atomic_set(&itp->stop_tx, 1);
416 flush_workqueue(priv->workqueue);
417
418 /* time for FW to confirm all tx requests */
419 msleep(500);
420
421 __cw1200_itp_tx_stop(priv);
422}
423
424static int cw1200_print_fw_version(struct cw1200_common *priv,
425 u8 *buf, size_t len)
426{
427 return snprintf(buf, len, "%s %d.%d",
428 cw1200_fw_types[priv->wsm_caps.fw_type],
429 priv->wsm_caps.fw_ver,
430 priv->wsm_caps.fw_build);
431}
432
433static void cw1200_itp_get_version(struct cw1200_common *priv,
434 enum cw1200_itp_version_type type)
435{
436 struct cw1200_itp *itp = &priv->debug->itp;
437 struct sk_buff *skb;
438 char buf[ITP_BUF_SIZE];
439 size_t size = 0;
440 int len;
441 pr_debug("[ITP] print %s version\n",
442 type == ITP_CHIP_ID ? "chip" : "firmware");
443
444 len = snprintf(buf, ITP_BUF_SIZE, "2,");
445 if (len <= 0) {
446 cw1200_itp_err(priv, -EINVAL, 40);
447 return;
448 }
449 size += len;
450
451 switch (type) {
452 case ITP_CHIP_ID:
453 len = cw1200_print_fw_version(priv, buf+size,
454 ITP_BUF_SIZE - size);
455
456 if (len <= 0) {
457 cw1200_itp_err(priv, -EINVAL, 41);
458 return;
459 }
460 size += len;
461 break;
462 case ITP_FW_VER:
463 len = snprintf(buf+size, ITP_BUF_SIZE - size,
464 "%d.%d", priv->wsm_caps.hw_id,
465 priv->wsm_caps.hw_subid);
466 if (len <= 0) {
467 cw1200_itp_err(priv, -EINVAL, 42);
468 return;
469 }
470 size += len;
471 break;
472 default:
473 cw1200_itp_err(priv, -EINVAL, 43);
474 break;
475 }
476
477 len = snprintf(buf+size, ITP_BUF_SIZE-size, "\n");
478 if (len <= 0) {
479 cw1200_itp_err(priv, -EINVAL, 44);
480 return;
481 }
482 size += len;
483
484 skb = dev_alloc_skb(size);
485 if (!skb) {
486 cw1200_itp_err(priv, -ENOMEM, 45);
487 return;
488 }
489
490 skb_trim(skb, 0);
491 skb_put(skb, size);
492
493 memcpy(skb->data, buf, size);
494 skb_queue_tail(&itp->log_queue, skb);
495 wake_up(&itp->read_wait);
496}
497
498int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
499 size_t *tx_len, int *burst)
500{
501 struct cw1200_itp *itp;
502 struct timespec now;
503 int time_left_us;
504
505 if (!priv->debug)
506 return 0;
507
508 itp = &priv->debug->itp;
509
510 if (!itp)
511 return 0;
512
513 spin_lock_bh(&itp->tx_lock);
514 if (atomic_read(&itp->test_mode) != TEST_MODE_TX_TEST)
515 goto out;
516
517 if (atomic_read(&itp->stop_tx))
518 goto out;
519
520 if (itp->number == 0) {
521 atomic_set(&itp->stop_tx, 1);
522 queue_delayed_work(priv->workqueue, &itp->tx_finish, HZ/10);
523 goto out;
524 }
525
526 if (!itp->data)
527 goto out;
528
529 if (priv->hw_bufs_used >= 2) {
530 if (!atomic_read(&priv->bh_rx))
531 atomic_set(&priv->bh_rx, 1);
532 atomic_set(&priv->bh_tx, 1);
533 goto out;
534 }
535
536 ktime_get_ts(&now);
537 time_left_us = (itp->last_sent.tv_sec - now.tv_sec)*1000000 +
538 (itp->last_sent.tv_nsec - now.tv_nsec)/1000 +
539 itp->interval_us;
540
541 if (time_left_us > ITP_TIME_THRES_US) {
542 queue_delayed_work(priv->workqueue, &itp->tx_work,
543 ITP_US_TO_MS(time_left_us)*HZ/1000);
544 goto out;
545 }
546
547 if (time_left_us > 50)
548 udelay(time_left_us);
549
550 if (itp->number > 0)
551 itp->number--;
552
553 *data = itp->data;
554 *tx_len = itp->data_len + itp->hdr_len;
555
556 if (itp->data_mode == ITP_DATA_RANDOM)
557 cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
558 itp->data_len, itp->data_mode);
559 *burst = 2;
560 atomic_set(&priv->bh_tx, 1);
561 ktime_get_ts(&itp->last_sent);
562 atomic_add(1, &itp->awaiting_confirm);
563 spin_unlock_bh(&itp->tx_lock);
564 return 1;
565
566out:
567 spin_unlock_bh(&itp->tx_lock);
568 return 0;
569}
570
571bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb)
572{
573 struct cw1200_itp *itp = &priv->debug->itp;
574 struct ieee80211_rx_status *rx = IEEE80211_SKB_RXCB(skb);
575 int signal;
576
577 if (atomic_read(&itp->test_mode) != TEST_MODE_RX_TEST)
578 return cw1200_is_itp(priv);
579 if (rx->freq != priv->channel->center_freq)
580 return true;
581
582 signal = rx->signal;
583 itp->rx_cnt++;
584 itp->rx_rssi += signal;
585 if (itp->rx_rssi_min > rx->signal)
586 itp->rx_rssi_min = rx->signal;
587 if (itp->rx_rssi_max < rx->signal)
588 itp->rx_rssi_max = rx->signal;
589
590 return true;
591}
592
593void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
594{
595 wake_up(&priv->debug->itp.write_wait);
596}
597
598bool cw1200_itp_tx_running(struct cw1200_common *priv)
599{
600 if (atomic_read(&priv->debug->itp.awaiting_confirm) ||
601 atomic_read(&priv->debug->itp.test_mode) ==
602 TEST_MODE_TX_TEST) {
603 atomic_sub(1, &priv->debug->itp.awaiting_confirm);
604 return true;
605 }
606 return false;
607}
608
609static void cw1200_itp_handle(struct cw1200_common *priv,
610 struct sk_buff *skb)
611{
612 struct cw1200_itp *itp = &priv->debug->itp;
613 const struct wiphy *wiphy = priv->hw->wiphy;
614 int cmd;
615 int ret;
616
617 pr_debug("[ITP] <<< %s", skb->data);
618 if (sscanf(skb->data, "%d", &cmd) != 1) {
619 cw1200_itp_err(priv, -EINVAL, 1);
620 return;
621 }
622
623 switch (cmd) {
624 case 1: /* RX test */
625 if (atomic_read(&itp->test_mode)) {
626 cw1200_itp_err(priv, -EBUSY, 0);
627 return;
628 }
629 ret = sscanf(skb->data, "%d,%d,%d",
630 &cmd, &itp->band, &itp->ch);
631 if (ret != 3) {
632 cw1200_itp_err(priv, -EINVAL, ret + 1);
633 return;
634 }
635 if (itp->band >= 2) {
636 cw1200_itp_err(priv, -EINVAL, 2);
637 } else if (!wiphy->bands[itp->band]) {
638 cw1200_itp_err(priv, -EINVAL, 2);
639 } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
640 cw1200_itp_err(priv, -EINVAL, 3);
641 } else {
642 cw1200_itp_rx_stats(priv);
643 cw1200_itp_rx_start(priv);
644 }
645 break;
646 case 2: /* RX stat */
647 cw1200_itp_rx_stats(priv);
648 break;
649 case 3: /* RX/TX stop */
650 if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST) {
651 cw1200_itp_rx_stats(priv);
652 cw1200_itp_rx_stop(priv);
653 } else if (atomic_read(&itp->test_mode) == TEST_MODE_TX_TEST) {
654 cw1200_itp_tx_stop(priv);
655 } else {
656 cw1200_itp_err(priv, -EBUSY, 0);
657 }
658 break;
659 case 4: /* TX start */
660 if (atomic_read(&itp->test_mode) != TEST_MODE_NO_TEST) {
661 cw1200_itp_err(priv, -EBUSY, 0);
662 return;
663 }
664 ret = sscanf(skb->data, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
665 &cmd, &itp->band, &itp->ch, &itp->rate,
666 &itp->preamble, &itp->number, &itp->data_mode,
667 &itp->interval_us, &itp->power, &itp->data_len);
668 if (ret != 10) {
669 cw1200_itp_err(priv, -EINVAL, ret + 1);
670 return;
671 }
672 if (itp->band >= 2) {
673 cw1200_itp_err(priv, -EINVAL, 2);
674 } else if (!wiphy->bands[itp->band]) {
675 cw1200_itp_err(priv, -EINVAL, 2);
676 } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
677 cw1200_itp_err(priv, -EINVAL, 3);
678 } else if (itp->rate >= 20) {
679 cw1200_itp_err(priv, -EINVAL, 4);
680 } else if (itp->preamble >= ITP_PREAMBLE_MAX) {
681 cw1200_itp_err(priv, -EINVAL, 5);
682 } else if (itp->data_mode >= ITP_DATA_MAX_MODE) {
683 cw1200_itp_err(priv, -EINVAL, 7);
684 } else if (itp->data_len < ITP_MIN_DATA_SIZE ||
685 itp->data_len > (priv->wsm_caps.input_buffer_size - itp->hdr_len)) {
686 cw1200_itp_err(priv, -EINVAL, 8);
687 } else {
688 cw1200_itp_tx_start(priv);
689 }
690 break;
691 case 5:
692 cw1200_itp_get_version(priv, ITP_CHIP_ID);
693 break;
694 case 6:
695 cw1200_itp_get_version(priv, ITP_FW_VER);
696 break;
697 }
698}
699
700static void cw1200_itp_err(struct cw1200_common *priv,
701 int err, int arg)
702{
703 struct cw1200_itp *itp = &priv->debug->itp;
704 struct sk_buff *skb;
705 static char buf[255];
706 int len;
707
708 len = snprintf(buf, sizeof(buf), "%d,%d\n",
709 err, arg);
710 if (len <= 0)
711 return;
712
713 skb = dev_alloc_skb(len);
714 if (!skb)
715 return;
716
717 skb_trim(skb, 0);
718 skb_put(skb, len);
719
720 memcpy(skb->data, buf, len);
721 skb_queue_tail(&itp->log_queue, skb);
722 wake_up(&itp->read_wait);
723
724 len = sprint_symbol(buf,
725 (unsigned long)__builtin_return_address(0));
726 if (len <= 0)
727 return;
728 pr_debug("[ITP] error %d,%d from %s\n",
729 err, arg, buf);
730}
diff --git a/drivers/net/wireless/cw1200/itp.h b/drivers/net/wireless/cw1200/itp.h
new file mode 100644
index 000000000000..1e9dfb7fcadc
--- /dev/null
+++ b/drivers/net/wireless/cw1200/itp.h
@@ -0,0 +1,144 @@
1/*
2 * ITP code for ST-Ericsson CW1200 mac80211 driver
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_ITP_H_INCLUDED
13#define CW1200_ITP_H_INCLUDED
14
15struct cw200_common;
16struct wsm_tx_confirm;
17struct dentry;
18
19#ifdef CONFIG_CW1200_ITP
20
21/*extern*/ struct ieee80211_channel;
22
23#define TEST_MODE_NO_TEST (0)
24#define TEST_MODE_RX_TEST (1)
25#define TEST_MODE_TX_TEST (2)
26#define ITP_DEFAULT_DA_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
27#define ITP_MIN_DATA_SIZE 6
28#define ITP_MAX_DATA_SIZE 1600
29#define ITP_TIME_THRES_US 10000
30#define ITP_US_TO_MS(x) ((x)/1000)
31#define ITP_MS_TO_US(x) ((x)*1000)
32#define ITP_BUF_SIZE 255
33
34
35enum cw1200_itp_data_modes {
36 ITP_DATA_ZEROS,
37 ITP_DATA_ONES,
38 ITP_DATA_ZERONES,
39 ITP_DATA_RANDOM,
40 ITP_DATA_MAX_MODE,
41};
42
43enum cw1200_itp_version_type {
44 ITP_CHIP_ID,
45 ITP_FW_VER,
46};
47
48enum cw1200_itp_preamble_type {
49 ITP_PREAMBLE_LONG,
50 ITP_PREAMBLE_SHORT,
51 ITP_PREAMBLE_OFDM,
52 ITP_PREAMBLE_MIXED,
53 ITP_PREAMBLE_GREENFIELD,
54 ITP_PREAMBLE_MAX,
55};
56
57
58struct cw1200_itp {
59 struct cw1200_common *priv;
60 atomic_t open_count;
61 atomic_t awaiting_confirm;
62 struct sk_buff_head log_queue;
63 wait_queue_head_t read_wait;
64 wait_queue_head_t write_wait;
65 wait_queue_head_t close_wait;
66 struct ieee80211_channel *saved_channel;
67 atomic_t stop_tx;
68 struct delayed_work tx_work;
69 struct delayed_work tx_finish;
70 spinlock_t tx_lock;
71 struct timespec last_sent;
72 atomic_t test_mode;
73 int rx_cnt;
74 long rx_rssi;
75 int rx_rssi_max;
76 int rx_rssi_min;
77 unsigned band;
78 unsigned ch;
79 unsigned rate;
80 unsigned preamble;
81 unsigned int number;
82 unsigned data_mode;
83 int interval_us;
84 int power;
85 u8 *data;
86 int hdr_len;
87 int data_len;
88};
89
90int cw1200_itp_init(struct cw1200_common *priv);
91void cw1200_itp_release(struct cw1200_common *priv);
92
93bool cw1200_is_itp(struct cw1200_common *priv);
94bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb);
95void cw1200_itp_wake_up_tx(struct cw1200_common *priv);
96int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
97 size_t *tx_len, int *burst);
98bool cw1200_itp_tx_running(struct cw1200_common *priv);
99
100#else /* CONFIG_CW1200_ITP */
101
102static inline int cw1200_itp_init(struct cw1200_common *priv)
103{
104 return 0;
105}
106
107static inline void cw1200_itp_release(struct cw1200_common *priv)
108{
109}
110
111static inline bool cw1200_is_itp(struct cw1200_common *priv)
112{
113 return false;
114}
115
116static inline bool cw1200_itp_rxed(struct cw1200_common *priv,
117 struct sk_buff *skb)
118{
119 return false;
120}
121
122
123static inline void cw1200_itp_consume_txed(struct cw1200_common *priv)
124{
125}
126
127static inline void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
128{
129}
130
131static inline int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
132 size_t *tx_len, int *burst)
133{
134 return 0;
135}
136
137static inline bool cw1200_itp_tx_running(struct cw1200_common *priv)
138{
139 return false;
140}
141
142#endif /* CONFIG_CW1200_ITP */
143
144#endif /* CW1200_ITP_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
new file mode 100644
index 000000000000..c934ec52d129
--- /dev/null
+++ b/drivers/net/wireless/cw1200/main.c
@@ -0,0 +1,633 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11 *
12 * Based on:
13 * - the islsm (softmac prism54) driver, which is:
14 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
15 * - stlc45xx driver
16 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/firmware.h>
26#include <linux/etherdevice.h>
27#include <linux/vmalloc.h>
28#include <linux/random.h>
29#include <linux/sched.h>
30#include <net/mac80211.h>
31
32#include "cw1200.h"
33#include "txrx.h"
34#include "hwbus.h"
35#include "fwio.h"
36#include "hwio.h"
37#include "bh.h"
38#include "sta.h"
39#include "scan.h"
40#include "debug.h"
41#include "pm.h"
42
43MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
44MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
45MODULE_LICENSE("GPL");
46MODULE_ALIAS("cw1200_core");
47
48/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
49static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
50module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO);
51MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
52
53static char *cw1200_sdd_path;
54module_param(cw1200_sdd_path, charp, 0644);
55MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
56static int cw1200_refclk;
57module_param(cw1200_refclk, int, 0644);
58MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
59
60int cw1200_power_mode = wsm_power_mode_quiescent;
61module_param(cw1200_power_mode, int, 0644);
62MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode. 0 == active, 1 == doze, 2 == quiescent (default)");
63
64#ifdef CONFIG_CW1200_ETF
65int etf_mode;
66module_param(etf_mode, int, 0644);
67MODULE_PARM_DESC(etf_mode, "Enable EngineeringTestingFramework operation");
68#endif
69
70#define RATETAB_ENT(_rate, _rateid, _flags) \
71 { \
72 .bitrate = (_rate), \
73 .hw_value = (_rateid), \
74 .flags = (_flags), \
75 }
76
77static struct ieee80211_rate cw1200_rates[] = {
78 RATETAB_ENT(10, 0, 0),
79 RATETAB_ENT(20, 1, 0),
80 RATETAB_ENT(55, 2, 0),
81 RATETAB_ENT(110, 3, 0),
82 RATETAB_ENT(60, 6, 0),
83 RATETAB_ENT(90, 7, 0),
84 RATETAB_ENT(120, 8, 0),
85 RATETAB_ENT(180, 9, 0),
86 RATETAB_ENT(240, 10, 0),
87 RATETAB_ENT(360, 11, 0),
88 RATETAB_ENT(480, 12, 0),
89 RATETAB_ENT(540, 13, 0),
90};
91
92static struct ieee80211_rate cw1200_mcs_rates[] = {
93 RATETAB_ENT(65, 14, IEEE80211_TX_RC_MCS),
94 RATETAB_ENT(130, 15, IEEE80211_TX_RC_MCS),
95 RATETAB_ENT(195, 16, IEEE80211_TX_RC_MCS),
96 RATETAB_ENT(260, 17, IEEE80211_TX_RC_MCS),
97 RATETAB_ENT(390, 18, IEEE80211_TX_RC_MCS),
98 RATETAB_ENT(520, 19, IEEE80211_TX_RC_MCS),
99 RATETAB_ENT(585, 20, IEEE80211_TX_RC_MCS),
100 RATETAB_ENT(650, 21, IEEE80211_TX_RC_MCS),
101};
102
103#define cw1200_a_rates (cw1200_rates + 4)
104#define cw1200_a_rates_size (ARRAY_SIZE(cw1200_rates) - 4)
105#define cw1200_g_rates (cw1200_rates + 0)
106#define cw1200_g_rates_size (ARRAY_SIZE(cw1200_rates))
107#define cw1200_n_rates (cw1200_mcs_rates)
108#define cw1200_n_rates_size (ARRAY_SIZE(cw1200_mcs_rates))
109
110
111#define CHAN2G(_channel, _freq, _flags) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (_freq), \
114 .hw_value = (_channel), \
115 .flags = (_flags), \
116 .max_antenna_gain = 0, \
117 .max_power = 30, \
118}
119
120#define CHAN5G(_channel, _flags) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = 5000 + (5 * (_channel)), \
123 .hw_value = (_channel), \
124 .flags = (_flags), \
125 .max_antenna_gain = 0, \
126 .max_power = 30, \
127}
128
129static struct ieee80211_channel cw1200_2ghz_chantable[] = {
130 CHAN2G(1, 2412, 0),
131 CHAN2G(2, 2417, 0),
132 CHAN2G(3, 2422, 0),
133 CHAN2G(4, 2427, 0),
134 CHAN2G(5, 2432, 0),
135 CHAN2G(6, 2437, 0),
136 CHAN2G(7, 2442, 0),
137 CHAN2G(8, 2447, 0),
138 CHAN2G(9, 2452, 0),
139 CHAN2G(10, 2457, 0),
140 CHAN2G(11, 2462, 0),
141 CHAN2G(12, 2467, 0),
142 CHAN2G(13, 2472, 0),
143 CHAN2G(14, 2484, 0),
144};
145
146static struct ieee80211_channel cw1200_5ghz_chantable[] = {
147 CHAN5G(34, 0), CHAN5G(36, 0),
148 CHAN5G(38, 0), CHAN5G(40, 0),
149 CHAN5G(42, 0), CHAN5G(44, 0),
150 CHAN5G(46, 0), CHAN5G(48, 0),
151 CHAN5G(52, 0), CHAN5G(56, 0),
152 CHAN5G(60, 0), CHAN5G(64, 0),
153 CHAN5G(100, 0), CHAN5G(104, 0),
154 CHAN5G(108, 0), CHAN5G(112, 0),
155 CHAN5G(116, 0), CHAN5G(120, 0),
156 CHAN5G(124, 0), CHAN5G(128, 0),
157 CHAN5G(132, 0), CHAN5G(136, 0),
158 CHAN5G(140, 0), CHAN5G(149, 0),
159 CHAN5G(153, 0), CHAN5G(157, 0),
160 CHAN5G(161, 0), CHAN5G(165, 0),
161 CHAN5G(184, 0), CHAN5G(188, 0),
162 CHAN5G(192, 0), CHAN5G(196, 0),
163 CHAN5G(200, 0), CHAN5G(204, 0),
164 CHAN5G(208, 0), CHAN5G(212, 0),
165 CHAN5G(216, 0),
166};
167
168static struct ieee80211_supported_band cw1200_band_2ghz = {
169 .channels = cw1200_2ghz_chantable,
170 .n_channels = ARRAY_SIZE(cw1200_2ghz_chantable),
171 .bitrates = cw1200_g_rates,
172 .n_bitrates = cw1200_g_rates_size,
173 .ht_cap = {
174 .cap = IEEE80211_HT_CAP_GRN_FLD |
175 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
176 IEEE80211_HT_CAP_MAX_AMSDU,
177 .ht_supported = 1,
178 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
179 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
180 .mcs = {
181 .rx_mask[0] = 0xFF,
182 .rx_highest = __cpu_to_le16(0x41),
183 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
184 },
185 },
186};
187
188static struct ieee80211_supported_band cw1200_band_5ghz = {
189 .channels = cw1200_5ghz_chantable,
190 .n_channels = ARRAY_SIZE(cw1200_5ghz_chantable),
191 .bitrates = cw1200_a_rates,
192 .n_bitrates = cw1200_a_rates_size,
193 .ht_cap = {
194 .cap = IEEE80211_HT_CAP_GRN_FLD |
195 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
196 IEEE80211_HT_CAP_MAX_AMSDU,
197 .ht_supported = 1,
198 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
199 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
200 .mcs = {
201 .rx_mask[0] = 0xFF,
202 .rx_highest = __cpu_to_le16(0x41),
203 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
204 },
205 },
206};
207
208static const unsigned long cw1200_ttl[] = {
209 1 * HZ, /* VO */
210 2 * HZ, /* VI */
211 5 * HZ, /* BE */
212 10 * HZ /* BK */
213};
214
215static const struct ieee80211_ops cw1200_ops = {
216 .start = cw1200_start,
217 .stop = cw1200_stop,
218 .add_interface = cw1200_add_interface,
219 .remove_interface = cw1200_remove_interface,
220 .change_interface = cw1200_change_interface,
221 .tx = cw1200_tx,
222 .hw_scan = cw1200_hw_scan,
223 .set_tim = cw1200_set_tim,
224 .sta_notify = cw1200_sta_notify,
225 .sta_add = cw1200_sta_add,
226 .sta_remove = cw1200_sta_remove,
227 .set_key = cw1200_set_key,
228 .set_rts_threshold = cw1200_set_rts_threshold,
229 .config = cw1200_config,
230 .bss_info_changed = cw1200_bss_info_changed,
231 .prepare_multicast = cw1200_prepare_multicast,
232 .configure_filter = cw1200_configure_filter,
233 .conf_tx = cw1200_conf_tx,
234 .get_stats = cw1200_get_stats,
235 .ampdu_action = cw1200_ampdu_action,
236 .flush = cw1200_flush,
237#ifdef CONFIG_PM
238 .suspend = cw1200_wow_suspend,
239 .resume = cw1200_wow_resume,
240#endif
241 /* Intentionally not offloaded: */
242 /*.channel_switch = cw1200_channel_switch, */
243 /*.remain_on_channel = cw1200_remain_on_channel, */
244 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
245};
246
247int cw1200_ba_rx_tids = -1;
248int cw1200_ba_tx_tids = -1;
249module_param(cw1200_ba_rx_tids, int, 0644);
250module_param(cw1200_ba_tx_tids, int, 0644);
251MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
252MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
253
254#ifdef CONFIG_PM
255static const struct wiphy_wowlan_support cw1200_wowlan_support = {
256 /* Support only for limited wowlan functionalities */
257 .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
258};
259#endif
260
261
262static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
263 const bool have_5ghz)
264{
265 int i, band;
266 struct ieee80211_hw *hw;
267 struct cw1200_common *priv;
268
269 hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
270 if (!hw)
271 return NULL;
272
273 priv = hw->priv;
274 priv->hw = hw;
275 priv->hw_type = -1;
276 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
277 priv->rates = cw1200_rates; /* TODO: fetch from FW */
278 priv->mcs_rates = cw1200_n_rates;
279 if (cw1200_ba_rx_tids != -1)
280 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
281 else
282 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
283 if (cw1200_ba_tx_tids != -1)
284 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
285 else
286 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
287
288 hw->flags = IEEE80211_HW_SIGNAL_DBM |
289 IEEE80211_HW_SUPPORTS_PS |
290 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
291 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
292 IEEE80211_HW_SUPPORTS_UAPSD |
293 IEEE80211_HW_CONNECTION_MONITOR |
294 IEEE80211_HW_AMPDU_AGGREGATION |
295 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
296 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC;
297
298 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
299 BIT(NL80211_IFTYPE_ADHOC) |
300 BIT(NL80211_IFTYPE_AP) |
301 BIT(NL80211_IFTYPE_MESH_POINT) |
302 BIT(NL80211_IFTYPE_P2P_CLIENT) |
303 BIT(NL80211_IFTYPE_P2P_GO);
304
305#ifdef CONFIG_PM
306 hw->wiphy->wowlan = &cw1200_wowlan_support;
307#endif
308
309 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
310
311 hw->channel_change_time = 1000; /* TODO: find actual value */
312 hw->queues = 4;
313
314 priv->rts_threshold = -1;
315
316 hw->max_rates = 8;
317 hw->max_rate_tries = 15;
318 hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
319 8; /* TKIP IV */
320
321 hw->sta_data_size = sizeof(struct cw1200_sta_priv);
322
323 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &cw1200_band_2ghz;
324 if (have_5ghz)
325 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &cw1200_band_5ghz;
326
327 /* Channel params have to be cleared before registering wiphy again */
328 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
329 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
330 if (!sband)
331 continue;
332 for (i = 0; i < sband->n_channels; i++) {
333 sband->channels[i].flags = 0;
334 sband->channels[i].max_antenna_gain = 0;
335 sband->channels[i].max_power = 30;
336 }
337 }
338
339 hw->wiphy->max_scan_ssids = 2;
340 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
341
342 if (macaddr)
343 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
344 else
345 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
346
347 /* Fix up mac address if necessary */
348 if (hw->wiphy->perm_addr[3] == 0 &&
349 hw->wiphy->perm_addr[4] == 0 &&
350 hw->wiphy->perm_addr[5] == 0) {
351 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
352 }
353
354 mutex_init(&priv->wsm_cmd_mux);
355 mutex_init(&priv->conf_mutex);
356 priv->workqueue = create_singlethread_workqueue("cw1200_wq");
357 sema_init(&priv->scan.lock, 1);
358 INIT_WORK(&priv->scan.work, cw1200_scan_work);
359 INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
360 INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
361 INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
362 cw1200_clear_recent_scan_work);
363 INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
364 INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
365 INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
366 INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
367 INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
368 spin_lock_init(&priv->event_queue_lock);
369 INIT_LIST_HEAD(&priv->event_queue);
370 INIT_WORK(&priv->event_handler, cw1200_event_handler);
371 INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
372 INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
373 spin_lock_init(&priv->bss_loss_lock);
374 spin_lock_init(&priv->ps_state_lock);
375 INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
376 INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
377 INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
378 INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
379 INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
380 INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
381 INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
382 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
383 INIT_WORK(&priv->set_beacon_wakeup_period_work,
384 cw1200_set_beacon_wakeup_period_work);
385 init_timer(&priv->mcast_timeout);
386 priv->mcast_timeout.data = (unsigned long)priv;
387 priv->mcast_timeout.function = cw1200_mcast_timeout;
388
389 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
390 CW1200_LINK_ID_MAX,
391 cw1200_skb_dtor,
392 priv)) {
393 ieee80211_free_hw(hw);
394 return NULL;
395 }
396
397 for (i = 0; i < 4; ++i) {
398 if (cw1200_queue_init(&priv->tx_queue[i],
399 &priv->tx_queue_stats, i, 16,
400 cw1200_ttl[i])) {
401 for (; i > 0; i--)
402 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
403 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
404 ieee80211_free_hw(hw);
405 return NULL;
406 }
407 }
408
409 init_waitqueue_head(&priv->channel_switch_done);
410 init_waitqueue_head(&priv->wsm_cmd_wq);
411 init_waitqueue_head(&priv->wsm_startup_done);
412 init_waitqueue_head(&priv->ps_mode_switch_done);
413 wsm_buf_init(&priv->wsm_cmd_buf);
414 spin_lock_init(&priv->wsm_cmd.lock);
415 priv->wsm_cmd.done = 1;
416 tx_policy_init(priv);
417
418 return hw;
419}
420
421static int cw1200_register_common(struct ieee80211_hw *dev)
422{
423 struct cw1200_common *priv = dev->priv;
424 int err;
425
426#ifdef CONFIG_CW1200_ETF
427 if (etf_mode)
428 goto done;
429#endif
430
431#ifdef CONFIG_PM
432 err = cw1200_pm_init(&priv->pm_state, priv);
433 if (err) {
434 pr_err("Cannot init PM. (%d).\n",
435 err);
436 return err;
437 }
438#endif
439
440 err = ieee80211_register_hw(dev);
441 if (err) {
442 pr_err("Cannot register device (%d).\n",
443 err);
444#ifdef CONFIG_PM
445 cw1200_pm_deinit(&priv->pm_state);
446#endif
447 return err;
448 }
449
450#ifdef CONFIG_CW1200_ETF
451done:
452#endif
453 cw1200_debug_init(priv);
454
455 pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
456 return 0;
457}
458
459static void cw1200_free_common(struct ieee80211_hw *dev)
460{
461 ieee80211_free_hw(dev);
462}
463
464static void cw1200_unregister_common(struct ieee80211_hw *dev)
465{
466 struct cw1200_common *priv = dev->priv;
467 int i;
468
469#ifdef CONFIG_CW1200_ETF
470 if (!etf_mode) {
471#endif
472 ieee80211_unregister_hw(dev);
473#ifdef CONFIG_CW1200_ETF
474 }
475#endif
476
477 del_timer_sync(&priv->mcast_timeout);
478 cw1200_unregister_bh(priv);
479
480 cw1200_debug_release(priv);
481
482 mutex_destroy(&priv->conf_mutex);
483
484 wsm_buf_deinit(&priv->wsm_cmd_buf);
485
486 destroy_workqueue(priv->workqueue);
487 priv->workqueue = NULL;
488
489 if (priv->sdd) {
490 release_firmware(priv->sdd);
491 priv->sdd = NULL;
492 }
493
494 for (i = 0; i < 4; ++i)
495 cw1200_queue_deinit(&priv->tx_queue[i]);
496
497 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
498#ifdef CONFIG_PM
499 cw1200_pm_deinit(&priv->pm_state);
500#endif
501}
502
503/* Clock is in KHz */
504u32 cw1200_dpll_from_clk(u16 clk_khz)
505{
506 switch (clk_khz) {
507 case 0x32C8: /* 13000 KHz */
508 return 0x1D89D241;
509 case 0x3E80: /* 16000 KHz */
510 return 0x000001E1;
511 case 0x41A0: /* 16800 KHz */
512 return 0x124931C1;
513 case 0x4B00: /* 19200 KHz */
514 return 0x00000191;
515 case 0x5DC0: /* 24000 KHz */
516 return 0x00000141;
517 case 0x6590: /* 26000 KHz */
518 return 0x0EC4F121;
519 case 0x8340: /* 33600 KHz */
520 return 0x092490E1;
521 case 0x9600: /* 38400 KHz */
522 return 0x100010C1;
523 case 0x9C40: /* 40000 KHz */
524 return 0x000000C1;
525 case 0xBB80: /* 48000 KHz */
526 return 0x000000A1;
527 case 0xCB20: /* 52000 KHz */
528 return 0x07627091;
529 default:
530 pr_err("Unknown Refclk freq (0x%04x), using 2600KHz\n",
531 clk_khz);
532 return 0x0EC4F121;
533 }
534}
535
536int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
537 struct hwbus_priv *hwbus,
538 struct device *pdev,
539 struct cw1200_common **core,
540 int ref_clk, const u8 *macaddr,
541 const char *sdd_path, bool have_5ghz)
542{
543 int err = -EINVAL;
544 struct ieee80211_hw *dev;
545 struct cw1200_common *priv;
546 struct wsm_operational_mode mode = {
547 .power_mode = cw1200_power_mode,
548 .disable_more_flag_usage = true,
549 };
550
551 dev = cw1200_init_common(macaddr, have_5ghz);
552 if (!dev)
553 goto err;
554
555 priv = dev->priv;
556 priv->hw_refclk = ref_clk;
557 if (cw1200_refclk)
558 priv->hw_refclk = cw1200_refclk;
559
560 priv->sdd_path = (char *)sdd_path;
561 if (cw1200_sdd_path)
562 priv->sdd_path = cw1200_sdd_path;
563
564 priv->hwbus_ops = hwbus_ops;
565 priv->hwbus_priv = hwbus;
566 priv->pdev = pdev;
567 SET_IEEE80211_DEV(priv->hw, pdev);
568
569 /* Pass struct cw1200_common back up */
570 *core = priv;
571
572 err = cw1200_register_bh(priv);
573 if (err)
574 goto err1;
575
576#ifdef CONFIG_CW1200_ETF
577 if (etf_mode)
578 goto skip_fw;
579#endif
580
581 err = cw1200_load_firmware(priv);
582 if (err)
583 goto err2;
584
585 if (wait_event_interruptible_timeout(priv->wsm_startup_done,
586 priv->firmware_ready,
587 3*HZ) <= 0) {
588 /* TODO: Need to find how to reset device
589 in QUEUE mode properly.
590 */
591 pr_err("Timeout waiting on device startup\n");
592 err = -ETIMEDOUT;
593 goto err2;
594 }
595
596 /* Set low-power mode. */
597 wsm_set_operational_mode(priv, &mode);
598
599 /* Enable multi-TX confirmation */
600 wsm_use_multi_tx_conf(priv, true);
601
602#ifdef CONFIG_CW1200_ETF
603skip_fw:
604#endif
605 err = cw1200_register_common(dev);
606 if (err)
607 goto err2;
608
609 return err;
610
611err2:
612 cw1200_unregister_bh(priv);
613err1:
614 cw1200_free_common(dev);
615err:
616 *core = NULL;
617 return err;
618}
619EXPORT_SYMBOL_GPL(cw1200_core_probe);
620
621void cw1200_core_release(struct cw1200_common *self)
622{
623 /* Disable device interrupts */
624 self->hwbus_ops->lock(self->hwbus_priv);
625 __cw1200_irq_enable(self, 0);
626 self->hwbus_ops->unlock(self->hwbus_priv);
627
628 /* And then clean up */
629 cw1200_unregister_common(self->hw);
630 cw1200_free_common(self->hw);
631 return;
632}
633EXPORT_SYMBOL_GPL(cw1200_core_release);
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
new file mode 100644
index 000000000000..b37abb9f0453
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -0,0 +1,367 @@
1/*
2 * Mac80211 power management API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/if_ether.h>
14#include "cw1200.h"
15#include "pm.h"
16#include "sta.h"
17#include "bh.h"
18#include "hwbus.h"
19
20#define CW1200_BEACON_SKIPPING_MULTIPLIER 3
21
22struct cw1200_udp_port_filter {
23 struct wsm_udp_port_filter_hdr hdr;
24 /* Up to 4 filters are allowed. */
25 struct wsm_udp_port_filter filters[WSM_MAX_FILTER_ELEMENTS];
26} __packed;
27
28struct cw1200_ether_type_filter {
29 struct wsm_ether_type_filter_hdr hdr;
30 /* Up to 4 filters are allowed. */
31 struct wsm_ether_type_filter filters[WSM_MAX_FILTER_ELEMENTS];
32} __packed;
33
34static struct cw1200_udp_port_filter cw1200_udp_port_filter_on = {
35 .hdr.num = 2,
36 .filters = {
37 [0] = {
38 .action = WSM_FILTER_ACTION_FILTER_OUT,
39 .type = WSM_FILTER_PORT_TYPE_DST,
40 .port = __cpu_to_le16(67), /* DHCP Bootps */
41 },
42 [1] = {
43 .action = WSM_FILTER_ACTION_FILTER_OUT,
44 .type = WSM_FILTER_PORT_TYPE_DST,
45 .port = __cpu_to_le16(68), /* DHCP Bootpc */
46 },
47 }
48};
49
50static struct wsm_udp_port_filter_hdr cw1200_udp_port_filter_off = {
51 .num = 0,
52};
53
54#ifndef ETH_P_WAPI
55#define ETH_P_WAPI 0x88B4
56#endif
57
58static struct cw1200_ether_type_filter cw1200_ether_type_filter_on = {
59 .hdr.num = 4,
60 .filters = {
61 [0] = {
62 .action = WSM_FILTER_ACTION_FILTER_IN,
63 .type = __cpu_to_le16(ETH_P_IP),
64 },
65 [1] = {
66 .action = WSM_FILTER_ACTION_FILTER_IN,
67 .type = __cpu_to_le16(ETH_P_PAE),
68 },
69 [2] = {
70 .action = WSM_FILTER_ACTION_FILTER_IN,
71 .type = __cpu_to_le16(ETH_P_WAPI),
72 },
73 [3] = {
74 .action = WSM_FILTER_ACTION_FILTER_IN,
75 .type = __cpu_to_le16(ETH_P_ARP),
76 },
77 },
78};
79
80static struct wsm_ether_type_filter_hdr cw1200_ether_type_filter_off = {
81 .num = 0,
82};
83
84/* private */
85struct cw1200_suspend_state {
86 unsigned long bss_loss_tmo;
87 unsigned long join_tmo;
88 unsigned long direct_probe;
89 unsigned long link_id_gc;
90 bool beacon_skipping;
91 u8 prev_ps_mode;
92};
93
94static void cw1200_pm_stay_awake_tmo(unsigned long arg)
95{
96 /* XXX what's the point of this ? */
97}
98
99int cw1200_pm_init(struct cw1200_pm_state *pm,
100 struct cw1200_common *priv)
101{
102 spin_lock_init(&pm->lock);
103
104 init_timer(&pm->stay_awake);
105 pm->stay_awake.data = (unsigned long)pm;
106 pm->stay_awake.function = cw1200_pm_stay_awake_tmo;
107
108 return 0;
109}
110
111void cw1200_pm_deinit(struct cw1200_pm_state *pm)
112{
113 del_timer_sync(&pm->stay_awake);
114}
115
116void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
117 unsigned long tmo)
118{
119 long cur_tmo;
120 spin_lock_bh(&pm->lock);
121 cur_tmo = pm->stay_awake.expires - jiffies;
122 if (!timer_pending(&pm->stay_awake) || cur_tmo < (long)tmo)
123 mod_timer(&pm->stay_awake, jiffies + tmo);
124 spin_unlock_bh(&pm->lock);
125}
126
127static long cw1200_suspend_work(struct delayed_work *work)
128{
129 int ret = cancel_delayed_work(work);
130 long tmo;
131 if (ret > 0) {
132 /* Timer is pending */
133 tmo = work->timer.expires - jiffies;
134 if (tmo < 0)
135 tmo = 0;
136 } else {
137 tmo = -1;
138 }
139 return tmo;
140}
141
142static int cw1200_resume_work(struct cw1200_common *priv,
143 struct delayed_work *work,
144 unsigned long tmo)
145{
146 if ((long)tmo < 0)
147 return 1;
148
149 return queue_delayed_work(priv->workqueue, work, tmo);
150}
151
152int cw1200_can_suspend(struct cw1200_common *priv)
153{
154 if (atomic_read(&priv->bh_rx)) {
155 wiphy_dbg(priv->hw->wiphy, "Suspend interrupted.\n");
156 return 0;
157 }
158 return 1;
159}
160EXPORT_SYMBOL_GPL(cw1200_can_suspend);
161
162int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
163{
164 struct cw1200_common *priv = hw->priv;
165 struct cw1200_pm_state *pm_state = &priv->pm_state;
166 struct cw1200_suspend_state *state;
167 int ret;
168
169 spin_lock_bh(&pm_state->lock);
170 ret = timer_pending(&pm_state->stay_awake);
171 spin_unlock_bh(&pm_state->lock);
172 if (ret)
173 return -EAGAIN;
174
175 /* Do not suspend when datapath is not idle */
176 if (priv->tx_queue_stats.num_queued)
177 return -EBUSY;
178
179 /* Make sure there is no configuration requests in progress. */
180 if (!mutex_trylock(&priv->conf_mutex))
181 return -EBUSY;
182
183 /* Ensure pending operations are done.
184 * Note also that wow_suspend must return in ~2.5sec, before
185 * watchdog is triggered.
186 */
187 if (priv->channel_switch_in_progress)
188 goto revert1;
189
190 /* Do not suspend when join is pending */
191 if (priv->join_pending)
192 goto revert1;
193
194 /* Do not suspend when scanning */
195 if (down_trylock(&priv->scan.lock))
196 goto revert1;
197
198 /* Lock TX. */
199 wsm_lock_tx_async(priv);
200
201 /* Wait to avoid possible race with bh code.
202 * But do not wait too long...
203 */
204 if (wait_event_timeout(priv->bh_evt_wq,
205 !priv->hw_bufs_used, HZ / 10) <= 0)
206 goto revert2;
207
208 /* Set UDP filter */
209 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_on.hdr);
210
211 /* Set ethernet frame type filter */
212 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_on.hdr);
213
214 /* Allocate state */
215 state = kzalloc(sizeof(struct cw1200_suspend_state), GFP_KERNEL);
216 if (!state)
217 goto revert3;
218
219 /* Change to legacy PS while going to suspend */
220 if (!priv->vif->p2p &&
221 priv->join_status == CW1200_JOIN_STATUS_STA &&
222 priv->powersave_mode.mode != WSM_PSM_PS) {
223 state->prev_ps_mode = priv->powersave_mode.mode;
224 priv->powersave_mode.mode = WSM_PSM_PS;
225 cw1200_set_pm(priv, &priv->powersave_mode);
226 if (wait_event_interruptible_timeout(priv->ps_mode_switch_done,
227 !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) {
228 goto revert3;
229 }
230 }
231
232 /* Store delayed work states. */
233 state->bss_loss_tmo =
234 cw1200_suspend_work(&priv->bss_loss_work);
235 state->join_tmo =
236 cw1200_suspend_work(&priv->join_timeout);
237 state->direct_probe =
238 cw1200_suspend_work(&priv->scan.probe_work);
239 state->link_id_gc =
240 cw1200_suspend_work(&priv->link_id_gc_work);
241
242 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
243 atomic_set(&priv->recent_scan, 0);
244
245 /* Enable beacon skipping */
246 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
247 priv->join_dtim_period &&
248 !priv->has_multicast_subscription) {
249 state->beacon_skipping = true;
250 wsm_set_beacon_wakeup_period(priv,
251 priv->join_dtim_period,
252 CW1200_BEACON_SKIPPING_MULTIPLIER * priv->join_dtim_period);
253 }
254
255 /* Stop serving thread */
256 if (cw1200_bh_suspend(priv))
257 goto revert4;
258
259 ret = timer_pending(&priv->mcast_timeout);
260 if (ret)
261 goto revert5;
262
263 /* Store suspend state */
264 pm_state->suspend_state = state;
265
266 /* Enable IRQ wake */
267 ret = priv->hwbus_ops->power_mgmt(priv->hwbus_priv, true);
268 if (ret) {
269 wiphy_err(priv->hw->wiphy,
270 "PM request failed: %d. WoW is disabled.\n", ret);
271 cw1200_wow_resume(hw);
272 return -EBUSY;
273 }
274
275 /* Force resume if event is coming from the device. */
276 if (atomic_read(&priv->bh_rx)) {
277 cw1200_wow_resume(hw);
278 return -EAGAIN;
279 }
280
281 return 0;
282
283revert5:
284 WARN_ON(cw1200_bh_resume(priv));
285revert4:
286 cw1200_resume_work(priv, &priv->bss_loss_work,
287 state->bss_loss_tmo);
288 cw1200_resume_work(priv, &priv->join_timeout,
289 state->join_tmo);
290 cw1200_resume_work(priv, &priv->scan.probe_work,
291 state->direct_probe);
292 cw1200_resume_work(priv, &priv->link_id_gc_work,
293 state->link_id_gc);
294 kfree(state);
295revert3:
296 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
297 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
298revert2:
299 wsm_unlock_tx(priv);
300 up(&priv->scan.lock);
301revert1:
302 mutex_unlock(&priv->conf_mutex);
303 return -EBUSY;
304}
305
306int cw1200_wow_resume(struct ieee80211_hw *hw)
307{
308 struct cw1200_common *priv = hw->priv;
309 struct cw1200_pm_state *pm_state = &priv->pm_state;
310 struct cw1200_suspend_state *state;
311
312 state = pm_state->suspend_state;
313 pm_state->suspend_state = NULL;
314
315 /* Disable IRQ wake */
316 priv->hwbus_ops->power_mgmt(priv->hwbus_priv, false);
317
318 /* Scan.lock must be released before BH is resumed other way
319 * in case when BSS_LOST command arrived the processing of the
320 * command will be delayed.
321 */
322 up(&priv->scan.lock);
323
324 /* Resume BH thread */
325 WARN_ON(cw1200_bh_resume(priv));
326
327 /* Restores previous PS mode */
328 if (!priv->vif->p2p && priv->join_status == CW1200_JOIN_STATUS_STA) {
329 priv->powersave_mode.mode = state->prev_ps_mode;
330 cw1200_set_pm(priv, &priv->powersave_mode);
331 }
332
333 if (state->beacon_skipping) {
334 wsm_set_beacon_wakeup_period(priv, priv->beacon_int *
335 priv->join_dtim_period >
336 MAX_BEACON_SKIP_TIME_MS ? 1 :
337 priv->join_dtim_period, 0);
338 state->beacon_skipping = false;
339 }
340
341 /* Resume delayed work */
342 cw1200_resume_work(priv, &priv->bss_loss_work,
343 state->bss_loss_tmo);
344 cw1200_resume_work(priv, &priv->join_timeout,
345 state->join_tmo);
346 cw1200_resume_work(priv, &priv->scan.probe_work,
347 state->direct_probe);
348 cw1200_resume_work(priv, &priv->link_id_gc_work,
349 state->link_id_gc);
350
351 /* Remove UDP port filter */
352 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
353
354 /* Remove ethernet frame type filter */
355 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
356
357 /* Unlock datapath */
358 wsm_unlock_tx(priv);
359
360 /* Unlock configuration mutex */
361 mutex_unlock(&priv->conf_mutex);
362
363 /* Free memory */
364 kfree(state);
365
366 return 0;
367}
diff --git a/drivers/net/wireless/cw1200/pm.h b/drivers/net/wireless/cw1200/pm.h
new file mode 100644
index 000000000000..3ed90ff22bb8
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.h
@@ -0,0 +1,43 @@
1/*
2 * Mac80211 power management interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef PM_H_INCLUDED
13#define PM_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18/* extern */ struct cw1200_common;
19/* private */ struct cw1200_suspend_state;
20
21struct cw1200_pm_state {
22 struct cw1200_suspend_state *suspend_state;
23 struct timer_list stay_awake;
24 struct platform_device *pm_dev;
25 spinlock_t lock; /* Protect access */
26};
27
28#ifdef CONFIG_PM
29int cw1200_pm_init(struct cw1200_pm_state *pm,
30 struct cw1200_common *priv);
31void cw1200_pm_deinit(struct cw1200_pm_state *pm);
32int cw1200_wow_suspend(struct ieee80211_hw *hw,
33 struct cfg80211_wowlan *wowlan);
34int cw1200_wow_resume(struct ieee80211_hw *hw);
35int cw1200_can_suspend(struct cw1200_common *priv);
36void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
37 unsigned long tmo);
38#else
39static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
40 unsigned long tmo) {
41}
42#endif
43#endif
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
new file mode 100644
index 000000000000..8510454d5db1
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -0,0 +1,583 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/sched.h>
14#include "queue.h"
15#include "cw1200.h"
16#include "debug.h"
17
18/* private */ struct cw1200_queue_item
19{
20 struct list_head head;
21 struct sk_buff *skb;
22 u32 packet_id;
23 unsigned long queue_timestamp;
24 unsigned long xmit_timestamp;
25 struct cw1200_txpriv txpriv;
26 u8 generation;
27};
28
29static inline void __cw1200_queue_lock(struct cw1200_queue *queue)
30{
31 struct cw1200_queue_stats *stats = queue->stats;
32 if (queue->tx_locked_cnt++ == 0) {
33 pr_debug("[TX] Queue %d is locked.\n",
34 queue->queue_id);
35 ieee80211_stop_queue(stats->priv->hw, queue->queue_id);
36 }
37}
38
39static inline void __cw1200_queue_unlock(struct cw1200_queue *queue)
40{
41 struct cw1200_queue_stats *stats = queue->stats;
42 BUG_ON(!queue->tx_locked_cnt);
43 if (--queue->tx_locked_cnt == 0) {
44 pr_debug("[TX] Queue %d is unlocked.\n",
45 queue->queue_id);
46 ieee80211_wake_queue(stats->priv->hw, queue->queue_id);
47 }
48}
49
50static inline void cw1200_queue_parse_id(u32 packet_id, u8 *queue_generation,
51 u8 *queue_id, u8 *item_generation,
52 u8 *item_id)
53{
54 *item_id = (packet_id >> 0) & 0xFF;
55 *item_generation = (packet_id >> 8) & 0xFF;
56 *queue_id = (packet_id >> 16) & 0xFF;
57 *queue_generation = (packet_id >> 24) & 0xFF;
58}
59
60static inline u32 cw1200_queue_mk_packet_id(u8 queue_generation, u8 queue_id,
61 u8 item_generation, u8 item_id)
62{
63 return ((u32)item_id << 0) |
64 ((u32)item_generation << 8) |
65 ((u32)queue_id << 16) |
66 ((u32)queue_generation << 24);
67}
68
69static void cw1200_queue_post_gc(struct cw1200_queue_stats *stats,
70 struct list_head *gc_list)
71{
72 struct cw1200_queue_item *item, *tmp;
73
74 list_for_each_entry_safe(item, tmp, gc_list, head) {
75 list_del(&item->head);
76 stats->skb_dtor(stats->priv, item->skb, &item->txpriv);
77 kfree(item);
78 }
79}
80
81static void cw1200_queue_register_post_gc(struct list_head *gc_list,
82 struct cw1200_queue_item *item)
83{
84 struct cw1200_queue_item *gc_item;
85 gc_item = kmalloc(sizeof(struct cw1200_queue_item),
86 GFP_ATOMIC);
87 BUG_ON(!gc_item);
88 memcpy(gc_item, item, sizeof(struct cw1200_queue_item));
89 list_add_tail(&gc_item->head, gc_list);
90}
91
92static void __cw1200_queue_gc(struct cw1200_queue *queue,
93 struct list_head *head,
94 bool unlock)
95{
96 struct cw1200_queue_stats *stats = queue->stats;
97 struct cw1200_queue_item *item = NULL, *tmp;
98 bool wakeup_stats = false;
99
100 list_for_each_entry_safe(item, tmp, &queue->queue, head) {
101 if (jiffies - item->queue_timestamp < queue->ttl)
102 break;
103 --queue->num_queued;
104 --queue->link_map_cache[item->txpriv.link_id];
105 spin_lock_bh(&stats->lock);
106 --stats->num_queued;
107 if (!--stats->link_map_cache[item->txpriv.link_id])
108 wakeup_stats = true;
109 spin_unlock_bh(&stats->lock);
110 cw1200_debug_tx_ttl(stats->priv);
111 cw1200_queue_register_post_gc(head, item);
112 item->skb = NULL;
113 list_move_tail(&item->head, &queue->free_pool);
114 }
115
116 if (wakeup_stats)
117 wake_up(&stats->wait_link_id_empty);
118
119 if (queue->overfull) {
120 if (queue->num_queued <= (queue->capacity >> 1)) {
121 queue->overfull = false;
122 if (unlock)
123 __cw1200_queue_unlock(queue);
124 } else if (item) {
125 unsigned long tmo = item->queue_timestamp + queue->ttl;
126 mod_timer(&queue->gc, tmo);
127 cw1200_pm_stay_awake(&stats->priv->pm_state,
128 tmo - jiffies);
129 }
130 }
131}
132
133static void cw1200_queue_gc(unsigned long arg)
134{
135 LIST_HEAD(list);
136 struct cw1200_queue *queue =
137 (struct cw1200_queue *)arg;
138
139 spin_lock_bh(&queue->lock);
140 __cw1200_queue_gc(queue, &list, true);
141 spin_unlock_bh(&queue->lock);
142 cw1200_queue_post_gc(queue->stats, &list);
143}
144
145int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
146 size_t map_capacity,
147 cw1200_queue_skb_dtor_t skb_dtor,
148 struct cw1200_common *priv)
149{
150 memset(stats, 0, sizeof(*stats));
151 stats->map_capacity = map_capacity;
152 stats->skb_dtor = skb_dtor;
153 stats->priv = priv;
154 spin_lock_init(&stats->lock);
155 init_waitqueue_head(&stats->wait_link_id_empty);
156
157 stats->link_map_cache = kzalloc(sizeof(int) * map_capacity,
158 GFP_KERNEL);
159 if (!stats->link_map_cache)
160 return -ENOMEM;
161
162 return 0;
163}
164
165int cw1200_queue_init(struct cw1200_queue *queue,
166 struct cw1200_queue_stats *stats,
167 u8 queue_id,
168 size_t capacity,
169 unsigned long ttl)
170{
171 size_t i;
172
173 memset(queue, 0, sizeof(*queue));
174 queue->stats = stats;
175 queue->capacity = capacity;
176 queue->queue_id = queue_id;
177 queue->ttl = ttl;
178 INIT_LIST_HEAD(&queue->queue);
179 INIT_LIST_HEAD(&queue->pending);
180 INIT_LIST_HEAD(&queue->free_pool);
181 spin_lock_init(&queue->lock);
182 init_timer(&queue->gc);
183 queue->gc.data = (unsigned long)queue;
184 queue->gc.function = cw1200_queue_gc;
185
186 queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
187 GFP_KERNEL);
188 if (!queue->pool)
189 return -ENOMEM;
190
191 queue->link_map_cache = kzalloc(sizeof(int) * stats->map_capacity,
192 GFP_KERNEL);
193 if (!queue->link_map_cache) {
194 kfree(queue->pool);
195 queue->pool = NULL;
196 return -ENOMEM;
197 }
198
199 for (i = 0; i < capacity; ++i)
200 list_add_tail(&queue->pool[i].head, &queue->free_pool);
201
202 return 0;
203}
204
205int cw1200_queue_clear(struct cw1200_queue *queue)
206{
207 int i;
208 LIST_HEAD(gc_list);
209 struct cw1200_queue_stats *stats = queue->stats;
210 struct cw1200_queue_item *item, *tmp;
211
212 spin_lock_bh(&queue->lock);
213 queue->generation++;
214 list_splice_tail_init(&queue->queue, &queue->pending);
215 list_for_each_entry_safe(item, tmp, &queue->pending, head) {
216 WARN_ON(!item->skb);
217 cw1200_queue_register_post_gc(&gc_list, item);
218 item->skb = NULL;
219 list_move_tail(&item->head, &queue->free_pool);
220 }
221 queue->num_queued = 0;
222 queue->num_pending = 0;
223
224 spin_lock_bh(&stats->lock);
225 for (i = 0; i < stats->map_capacity; ++i) {
226 stats->num_queued -= queue->link_map_cache[i];
227 stats->link_map_cache[i] -= queue->link_map_cache[i];
228 queue->link_map_cache[i] = 0;
229 }
230 spin_unlock_bh(&stats->lock);
231 if (queue->overfull) {
232 queue->overfull = false;
233 __cw1200_queue_unlock(queue);
234 }
235 spin_unlock_bh(&queue->lock);
236 wake_up(&stats->wait_link_id_empty);
237 cw1200_queue_post_gc(stats, &gc_list);
238 return 0;
239}
240
241void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats)
242{
243 kfree(stats->link_map_cache);
244 stats->link_map_cache = NULL;
245}
246
247void cw1200_queue_deinit(struct cw1200_queue *queue)
248{
249 cw1200_queue_clear(queue);
250 del_timer_sync(&queue->gc);
251 INIT_LIST_HEAD(&queue->free_pool);
252 kfree(queue->pool);
253 kfree(queue->link_map_cache);
254 queue->pool = NULL;
255 queue->link_map_cache = NULL;
256 queue->capacity = 0;
257}
258
259size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
260 u32 link_id_map)
261{
262 size_t ret;
263 int i, bit;
264 size_t map_capacity = queue->stats->map_capacity;
265
266 if (!link_id_map)
267 return 0;
268
269 spin_lock_bh(&queue->lock);
270 if (link_id_map == (u32)-1) {
271 ret = queue->num_queued - queue->num_pending;
272 } else {
273 ret = 0;
274 for (i = 0, bit = 1; i < map_capacity; ++i, bit <<= 1) {
275 if (link_id_map & bit)
276 ret += queue->link_map_cache[i];
277 }
278 }
279 spin_unlock_bh(&queue->lock);
280 return ret;
281}
282
283int cw1200_queue_put(struct cw1200_queue *queue,
284 struct sk_buff *skb,
285 struct cw1200_txpriv *txpriv)
286{
287 int ret = 0;
288 LIST_HEAD(gc_list);
289 struct cw1200_queue_stats *stats = queue->stats;
290
291 if (txpriv->link_id >= queue->stats->map_capacity)
292 return -EINVAL;
293
294 spin_lock_bh(&queue->lock);
295 if (!WARN_ON(list_empty(&queue->free_pool))) {
296 struct cw1200_queue_item *item = list_first_entry(
297 &queue->free_pool, struct cw1200_queue_item, head);
298 BUG_ON(item->skb);
299
300 list_move_tail(&item->head, &queue->queue);
301 item->skb = skb;
302 item->txpriv = *txpriv;
303 item->generation = 0;
304 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
305 queue->queue_id,
306 item->generation,
307 item - queue->pool);
308 item->queue_timestamp = jiffies;
309
310 ++queue->num_queued;
311 ++queue->link_map_cache[txpriv->link_id];
312
313 spin_lock_bh(&stats->lock);
314 ++stats->num_queued;
315 ++stats->link_map_cache[txpriv->link_id];
316 spin_unlock_bh(&stats->lock);
317
318 /* TX may happen in parallel sometimes.
319 * Leave extra queue slots so we don't overflow.
320 */
321 if (queue->overfull == false &&
322 queue->num_queued >=
323 (queue->capacity - (num_present_cpus() - 1))) {
324 queue->overfull = true;
325 __cw1200_queue_lock(queue);
326 mod_timer(&queue->gc, jiffies);
327 }
328 } else {
329 ret = -ENOENT;
330 }
331 spin_unlock_bh(&queue->lock);
332 return ret;
333}
334
335int cw1200_queue_get(struct cw1200_queue *queue,
336 u32 link_id_map,
337 struct wsm_tx **tx,
338 struct ieee80211_tx_info **tx_info,
339 const struct cw1200_txpriv **txpriv)
340{
341 int ret = -ENOENT;
342 struct cw1200_queue_item *item;
343 struct cw1200_queue_stats *stats = queue->stats;
344 bool wakeup_stats = false;
345
346 spin_lock_bh(&queue->lock);
347 list_for_each_entry(item, &queue->queue, head) {
348 if (link_id_map & BIT(item->txpriv.link_id)) {
349 ret = 0;
350 break;
351 }
352 }
353
354 if (!WARN_ON(ret)) {
355 *tx = (struct wsm_tx *)item->skb->data;
356 *tx_info = IEEE80211_SKB_CB(item->skb);
357 *txpriv = &item->txpriv;
358 (*tx)->packet_id = __cpu_to_le32(item->packet_id);
359 list_move_tail(&item->head, &queue->pending);
360 ++queue->num_pending;
361 --queue->link_map_cache[item->txpriv.link_id];
362 item->xmit_timestamp = jiffies;
363
364 spin_lock_bh(&stats->lock);
365 --stats->num_queued;
366 if (!--stats->link_map_cache[item->txpriv.link_id])
367 wakeup_stats = true;
368 spin_unlock_bh(&stats->lock);
369 }
370 spin_unlock_bh(&queue->lock);
371 if (wakeup_stats)
372 wake_up(&stats->wait_link_id_empty);
373 return ret;
374}
375
376int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id)
377{
378 int ret = 0;
379 u8 queue_generation, queue_id, item_generation, item_id;
380 struct cw1200_queue_item *item;
381 struct cw1200_queue_stats *stats = queue->stats;
382
383 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
384 &item_generation, &item_id);
385
386 item = &queue->pool[item_id];
387
388 spin_lock_bh(&queue->lock);
389 BUG_ON(queue_id != queue->queue_id);
390 if (queue_generation != queue->generation) {
391 ret = -ENOENT;
392 } else if (item_id >= (unsigned) queue->capacity) {
393 WARN_ON(1);
394 ret = -EINVAL;
395 } else if (item->generation != item_generation) {
396 WARN_ON(1);
397 ret = -ENOENT;
398 } else {
399 --queue->num_pending;
400 ++queue->link_map_cache[item->txpriv.link_id];
401
402 spin_lock_bh(&stats->lock);
403 ++stats->num_queued;
404 ++stats->link_map_cache[item->txpriv.link_id];
405 spin_unlock_bh(&stats->lock);
406
407 item->generation = ++item_generation;
408 item->packet_id = cw1200_queue_mk_packet_id(queue_generation,
409 queue_id,
410 item_generation,
411 item_id);
412 list_move(&item->head, &queue->queue);
413 }
414 spin_unlock_bh(&queue->lock);
415 return ret;
416}
417
418int cw1200_queue_requeue_all(struct cw1200_queue *queue)
419{
420 struct cw1200_queue_item *item, *tmp;
421 struct cw1200_queue_stats *stats = queue->stats;
422 spin_lock_bh(&queue->lock);
423
424 list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) {
425 --queue->num_pending;
426 ++queue->link_map_cache[item->txpriv.link_id];
427
428 spin_lock_bh(&stats->lock);
429 ++stats->num_queued;
430 ++stats->link_map_cache[item->txpriv.link_id];
431 spin_unlock_bh(&stats->lock);
432
433 ++item->generation;
434 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
435 queue->queue_id,
436 item->generation,
437 item - queue->pool);
438 list_move(&item->head, &queue->queue);
439 }
440 spin_unlock_bh(&queue->lock);
441
442 return 0;
443}
444
445int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id)
446{
447 int ret = 0;
448 u8 queue_generation, queue_id, item_generation, item_id;
449 struct cw1200_queue_item *item;
450 struct cw1200_queue_stats *stats = queue->stats;
451 struct sk_buff *gc_skb = NULL;
452 struct cw1200_txpriv gc_txpriv;
453
454 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
455 &item_generation, &item_id);
456
457 item = &queue->pool[item_id];
458
459 spin_lock_bh(&queue->lock);
460 BUG_ON(queue_id != queue->queue_id);
461 if (queue_generation != queue->generation) {
462 ret = -ENOENT;
463 } else if (item_id >= (unsigned) queue->capacity) {
464 WARN_ON(1);
465 ret = -EINVAL;
466 } else if (item->generation != item_generation) {
467 WARN_ON(1);
468 ret = -ENOENT;
469 } else {
470 gc_txpriv = item->txpriv;
471 gc_skb = item->skb;
472 item->skb = NULL;
473 --queue->num_pending;
474 --queue->num_queued;
475 ++queue->num_sent;
476 ++item->generation;
477 /* Do not use list_move_tail here, but list_move:
478 * try to utilize cache row.
479 */
480 list_move(&item->head, &queue->free_pool);
481
482 if (queue->overfull &&
483 (queue->num_queued <= (queue->capacity >> 1))) {
484 queue->overfull = false;
485 __cw1200_queue_unlock(queue);
486 }
487 }
488 spin_unlock_bh(&queue->lock);
489
490 if (gc_skb)
491 stats->skb_dtor(stats->priv, gc_skb, &gc_txpriv);
492
493 return ret;
494}
495
496int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
497 struct sk_buff **skb,
498 const struct cw1200_txpriv **txpriv)
499{
500 int ret = 0;
501 u8 queue_generation, queue_id, item_generation, item_id;
502 struct cw1200_queue_item *item;
503 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
504 &item_generation, &item_id);
505
506 item = &queue->pool[item_id];
507
508 spin_lock_bh(&queue->lock);
509 BUG_ON(queue_id != queue->queue_id);
510 if (queue_generation != queue->generation) {
511 ret = -ENOENT;
512 } else if (item_id >= (unsigned) queue->capacity) {
513 WARN_ON(1);
514 ret = -EINVAL;
515 } else if (item->generation != item_generation) {
516 WARN_ON(1);
517 ret = -ENOENT;
518 } else {
519 *skb = item->skb;
520 *txpriv = &item->txpriv;
521 }
522 spin_unlock_bh(&queue->lock);
523 return ret;
524}
525
526void cw1200_queue_lock(struct cw1200_queue *queue)
527{
528 spin_lock_bh(&queue->lock);
529 __cw1200_queue_lock(queue);
530 spin_unlock_bh(&queue->lock);
531}
532
533void cw1200_queue_unlock(struct cw1200_queue *queue)
534{
535 spin_lock_bh(&queue->lock);
536 __cw1200_queue_unlock(queue);
537 spin_unlock_bh(&queue->lock);
538}
539
540bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
541 unsigned long *timestamp,
542 u32 pending_frame_id)
543{
544 struct cw1200_queue_item *item;
545 bool ret;
546
547 spin_lock_bh(&queue->lock);
548 ret = !list_empty(&queue->pending);
549 if (ret) {
550 list_for_each_entry(item, &queue->pending, head) {
551 if (item->packet_id != pending_frame_id)
552 if (time_before(item->xmit_timestamp,
553 *timestamp))
554 *timestamp = item->xmit_timestamp;
555 }
556 }
557 spin_unlock_bh(&queue->lock);
558 return ret;
559}
560
561bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
562 u32 link_id_map)
563{
564 bool empty = true;
565
566 spin_lock_bh(&stats->lock);
567 if (link_id_map == (u32)-1) {
568 empty = stats->num_queued == 0;
569 } else {
570 int i;
571 for (i = 0; i < stats->map_capacity; ++i) {
572 if (link_id_map & BIT(i)) {
573 if (stats->link_map_cache[i]) {
574 empty = false;
575 break;
576 }
577 }
578 }
579 }
580 spin_unlock_bh(&stats->lock);
581
582 return empty;
583}
diff --git a/drivers/net/wireless/cw1200/queue.h b/drivers/net/wireless/cw1200/queue.h
new file mode 100644
index 000000000000..119f9c79c14e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.h
@@ -0,0 +1,116 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_QUEUE_H_INCLUDED
13#define CW1200_QUEUE_H_INCLUDED
14
15/* private */ struct cw1200_queue_item;
16
17/* extern */ struct sk_buff;
18/* extern */ struct wsm_tx;
19/* extern */ struct cw1200_common;
20/* extern */ struct ieee80211_tx_queue_stats;
21/* extern */ struct cw1200_txpriv;
22
23/* forward */ struct cw1200_queue_stats;
24
25typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
26 struct sk_buff *skb,
27 const struct cw1200_txpriv *txpriv);
28
29struct cw1200_queue {
30 struct cw1200_queue_stats *stats;
31 size_t capacity;
32 size_t num_queued;
33 size_t num_pending;
34 size_t num_sent;
35 struct cw1200_queue_item *pool;
36 struct list_head queue;
37 struct list_head free_pool;
38 struct list_head pending;
39 int tx_locked_cnt;
40 int *link_map_cache;
41 bool overfull;
42 spinlock_t lock; /* Protect queue entry */
43 u8 queue_id;
44 u8 generation;
45 struct timer_list gc;
46 unsigned long ttl;
47};
48
49struct cw1200_queue_stats {
50 spinlock_t lock; /* Protect stats entry */
51 int *link_map_cache;
52 int num_queued;
53 size_t map_capacity;
54 wait_queue_head_t wait_link_id_empty;
55 cw1200_queue_skb_dtor_t skb_dtor;
56 struct cw1200_common *priv;
57};
58
59struct cw1200_txpriv {
60 u8 link_id;
61 u8 raw_link_id;
62 u8 tid;
63 u8 rate_id;
64 u8 offset;
65};
66
67int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
68 size_t map_capacity,
69 cw1200_queue_skb_dtor_t skb_dtor,
70 struct cw1200_common *priv);
71int cw1200_queue_init(struct cw1200_queue *queue,
72 struct cw1200_queue_stats *stats,
73 u8 queue_id,
74 size_t capacity,
75 unsigned long ttl);
76int cw1200_queue_clear(struct cw1200_queue *queue);
77void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
78void cw1200_queue_deinit(struct cw1200_queue *queue);
79
80size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
81 u32 link_id_map);
82int cw1200_queue_put(struct cw1200_queue *queue,
83 struct sk_buff *skb,
84 struct cw1200_txpriv *txpriv);
85int cw1200_queue_get(struct cw1200_queue *queue,
86 u32 link_id_map,
87 struct wsm_tx **tx,
88 struct ieee80211_tx_info **tx_info,
89 const struct cw1200_txpriv **txpriv);
90int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
91int cw1200_queue_requeue_all(struct cw1200_queue *queue);
92int cw1200_queue_remove(struct cw1200_queue *queue,
93 u32 packet_id);
94int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
95 struct sk_buff **skb,
96 const struct cw1200_txpriv **txpriv);
97void cw1200_queue_lock(struct cw1200_queue *queue);
98void cw1200_queue_unlock(struct cw1200_queue *queue);
99bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
100 unsigned long *timestamp,
101 u32 pending_frame_id);
102
103bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
104 u32 link_id_map);
105
106static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
107{
108 return (packet_id >> 16) & 0xFF;
109}
110
111static inline u8 cw1200_queue_get_generation(u32 packet_id)
112{
113 return (packet_id >> 8) & 0xFF;
114}
115
116#endif /* CW1200_QUEUE_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
new file mode 100644
index 000000000000..ee3c19037aac
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -0,0 +1,461 @@
1/*
2 * Scan implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/sched.h>
13#include "cw1200.h"
14#include "scan.h"
15#include "sta.h"
16#include "pm.h"
17
18static void cw1200_scan_restart_delayed(struct cw1200_common *priv);
19
20static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
21{
22 int ret, i;
23 int tmo = 2000;
24
25 switch (priv->join_status) {
26 case CW1200_JOIN_STATUS_PRE_STA:
27 case CW1200_JOIN_STATUS_JOINING:
28 return -EBUSY;
29 default:
30 break;
31 }
32
33 wiphy_dbg(priv->hw->wiphy, "[SCAN] hw req, type %d, %d channels, flags: 0x%x.\n",
34 scan->type, scan->num_channels, scan->flags);
35
36 for (i = 0; i < scan->num_channels; ++i)
37 tmo += scan->ch[i].max_chan_time + 10;
38
39 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
40 atomic_set(&priv->scan.in_progress, 1);
41 atomic_set(&priv->recent_scan, 1);
42 cw1200_pm_stay_awake(&priv->pm_state, tmo * HZ / 1000);
43 queue_delayed_work(priv->workqueue, &priv->scan.timeout,
44 tmo * HZ / 1000);
45 ret = wsm_scan(priv, scan);
46 if (ret) {
47 atomic_set(&priv->scan.in_progress, 0);
48 cancel_delayed_work_sync(&priv->scan.timeout);
49 cw1200_scan_restart_delayed(priv);
50 }
51 return ret;
52}
53
54int cw1200_hw_scan(struct ieee80211_hw *hw,
55 struct ieee80211_vif *vif,
56 struct cfg80211_scan_request *req)
57{
58 struct cw1200_common *priv = hw->priv;
59 struct wsm_template_frame frame = {
60 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
61 };
62 int i, ret;
63
64 if (!priv->vif)
65 return -EINVAL;
66
67 /* Scan when P2P_GO corrupt firmware MiniAP mode */
68 if (priv->join_status == CW1200_JOIN_STATUS_AP)
69 return -EOPNOTSUPP;
70
71 if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
72 req->n_ssids = 0;
73
74 wiphy_dbg(hw->wiphy, "[SCAN] Scan request for %d SSIDs.\n",
75 req->n_ssids);
76
77 if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
78 return -EINVAL;
79
80 frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0,
81 req->ie_len);
82 if (!frame.skb)
83 return -ENOMEM;
84
85 if (req->ie_len)
86 memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
87
88 /* will be unlocked in cw1200_scan_work() */
89 down(&priv->scan.lock);
90 mutex_lock(&priv->conf_mutex);
91
92 ret = wsm_set_template_frame(priv, &frame);
93 if (!ret) {
94 /* Host want to be the probe responder. */
95 ret = wsm_set_probe_responder(priv, true);
96 }
97 if (ret) {
98 mutex_unlock(&priv->conf_mutex);
99 up(&priv->scan.lock);
100 dev_kfree_skb(frame.skb);
101 return ret;
102 }
103
104 wsm_lock_tx(priv);
105
106 BUG_ON(priv->scan.req);
107 priv->scan.req = req;
108 priv->scan.n_ssids = 0;
109 priv->scan.status = 0;
110 priv->scan.begin = &req->channels[0];
111 priv->scan.curr = priv->scan.begin;
112 priv->scan.end = &req->channels[req->n_channels];
113 priv->scan.output_power = priv->output_power;
114
115 for (i = 0; i < req->n_ssids; ++i) {
116 struct wsm_ssid *dst = &priv->scan.ssids[priv->scan.n_ssids];
117 memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
118 dst->length = req->ssids[i].ssid_len;
119 ++priv->scan.n_ssids;
120 }
121
122 mutex_unlock(&priv->conf_mutex);
123
124 if (frame.skb)
125 dev_kfree_skb(frame.skb);
126 queue_work(priv->workqueue, &priv->scan.work);
127 return 0;
128}
129
130void cw1200_scan_work(struct work_struct *work)
131{
132 struct cw1200_common *priv = container_of(work, struct cw1200_common,
133 scan.work);
134 struct ieee80211_channel **it;
135 struct wsm_scan scan = {
136 .type = WSM_SCAN_TYPE_FOREGROUND,
137 .flags = WSM_SCAN_FLAG_SPLIT_METHOD,
138 };
139 bool first_run = (priv->scan.begin == priv->scan.curr &&
140 priv->scan.begin != priv->scan.end);
141 int i;
142
143 if (first_run) {
144 /* Firmware gets crazy if scan request is sent
145 * when STA is joined but not yet associated.
146 * Force unjoin in this case.
147 */
148 if (cancel_delayed_work_sync(&priv->join_timeout) > 0)
149 cw1200_join_timeout(&priv->join_timeout.work);
150 }
151
152 mutex_lock(&priv->conf_mutex);
153
154 if (first_run) {
155 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
156 !(priv->powersave_mode.mode & WSM_PSM_PS)) {
157 struct wsm_set_pm pm = priv->powersave_mode;
158 pm.mode = WSM_PSM_PS;
159 cw1200_set_pm(priv, &pm);
160 } else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
161 /* FW bug: driver has to restart p2p-dev mode
162 * after scan
163 */
164 cw1200_disable_listening(priv);
165 }
166 }
167
168 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) {
169 if (priv->scan.output_power != priv->output_power)
170 wsm_set_output_power(priv, priv->output_power * 10);
171 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
172 !(priv->powersave_mode.mode & WSM_PSM_PS))
173 cw1200_set_pm(priv, &priv->powersave_mode);
174
175 if (priv->scan.status < 0)
176 wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
177 priv->scan.status);
178 else if (priv->scan.req)
179 wiphy_dbg(priv->hw->wiphy,
180 "[SCAN] Scan completed.\n");
181 else
182 wiphy_dbg(priv->hw->wiphy,
183 "[SCAN] Scan canceled.\n");
184
185 priv->scan.req = NULL;
186 cw1200_scan_restart_delayed(priv);
187 wsm_unlock_tx(priv);
188 mutex_unlock(&priv->conf_mutex);
189 ieee80211_scan_completed(priv->hw, priv->scan.status ? 1 : 0);
190 up(&priv->scan.lock);
191 return;
192 } else {
193 struct ieee80211_channel *first = *priv->scan.curr;
194 for (it = priv->scan.curr + 1, i = 1;
195 it != priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS;
196 ++it, ++i) {
197 if ((*it)->band != first->band)
198 break;
199 if (((*it)->flags ^ first->flags) &
200 IEEE80211_CHAN_PASSIVE_SCAN)
201 break;
202 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
203 (*it)->max_power != first->max_power)
204 break;
205 }
206 scan.band = first->band;
207
208 if (priv->scan.req->no_cck)
209 scan.max_tx_rate = WSM_TRANSMIT_RATE_6;
210 else
211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
212 scan.num_probes =
213 (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
214 scan.num_ssids = priv->scan.n_ssids;
215 scan.ssids = &priv->scan.ssids[0];
216 scan.num_channels = it - priv->scan.curr;
217 /* TODO: Is it optimal? */
218 scan.probe_delay = 100;
219 /* It is not stated in WSM specification, however
220 * FW team says that driver may not use FG scan
221 * when joined.
222 */
223 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
224 scan.type = WSM_SCAN_TYPE_BACKGROUND;
225 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
226 }
227 scan.ch = kzalloc(
228 sizeof(struct wsm_scan_ch) * (it - priv->scan.curr),
229 GFP_KERNEL);
230 if (!scan.ch) {
231 priv->scan.status = -ENOMEM;
232 goto fail;
233 }
234 for (i = 0; i < scan.num_channels; ++i) {
235 scan.ch[i].number = priv->scan.curr[i]->hw_value;
236 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
237 scan.ch[i].min_chan_time = 50;
238 scan.ch[i].max_chan_time = 100;
239 } else {
240 scan.ch[i].min_chan_time = 10;
241 scan.ch[i].max_chan_time = 25;
242 }
243 }
244 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
245 priv->scan.output_power != first->max_power) {
246 priv->scan.output_power = first->max_power;
247 wsm_set_output_power(priv,
248 priv->scan.output_power * 10);
249 }
250 priv->scan.status = cw1200_scan_start(priv, &scan);
251 kfree(scan.ch);
252 if (priv->scan.status)
253 goto fail;
254 priv->scan.curr = it;
255 }
256 mutex_unlock(&priv->conf_mutex);
257 return;
258
259fail:
260 priv->scan.curr = priv->scan.end;
261 mutex_unlock(&priv->conf_mutex);
262 queue_work(priv->workqueue, &priv->scan.work);
263 return;
264}
265
266static void cw1200_scan_restart_delayed(struct cw1200_common *priv)
267{
268 /* FW bug: driver has to restart p2p-dev mode after scan. */
269 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
270 cw1200_enable_listening(priv);
271 cw1200_update_filtering(priv);
272 }
273
274 if (priv->delayed_unjoin) {
275 priv->delayed_unjoin = false;
276 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
277 wsm_unlock_tx(priv);
278 } else if (priv->delayed_link_loss) {
279 wiphy_dbg(priv->hw->wiphy, "[CQM] Requeue BSS loss.\n");
280 priv->delayed_link_loss = 0;
281 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
282 }
283}
284
285static void cw1200_scan_complete(struct cw1200_common *priv)
286{
287 queue_delayed_work(priv->workqueue, &priv->clear_recent_scan_work, HZ);
288 if (priv->scan.direct_probe) {
289 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe complete.\n");
290 cw1200_scan_restart_delayed(priv);
291 priv->scan.direct_probe = 0;
292 up(&priv->scan.lock);
293 wsm_unlock_tx(priv);
294 } else {
295 cw1200_scan_work(&priv->scan.work);
296 }
297}
298
299void cw1200_scan_failed_cb(struct cw1200_common *priv)
300{
301 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
302 /* STA is stopped. */
303 return;
304
305 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
306 priv->scan.status = -EIO;
307 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
308 }
309}
310
311
312void cw1200_scan_complete_cb(struct cw1200_common *priv,
313 struct wsm_scan_complete *arg)
314{
315 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
316 /* STA is stopped. */
317 return;
318
319 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
320 priv->scan.status = 1;
321 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
322 }
323}
324
325void cw1200_clear_recent_scan_work(struct work_struct *work)
326{
327 struct cw1200_common *priv =
328 container_of(work, struct cw1200_common,
329 clear_recent_scan_work.work);
330 atomic_xchg(&priv->recent_scan, 0);
331}
332
333void cw1200_scan_timeout(struct work_struct *work)
334{
335 struct cw1200_common *priv =
336 container_of(work, struct cw1200_common, scan.timeout.work);
337 if (atomic_xchg(&priv->scan.in_progress, 0)) {
338 if (priv->scan.status > 0) {
339 priv->scan.status = 0;
340 } else if (!priv->scan.status) {
341 wiphy_warn(priv->hw->wiphy,
342 "Timeout waiting for scan complete notification.\n");
343 priv->scan.status = -ETIMEDOUT;
344 priv->scan.curr = priv->scan.end;
345 wsm_stop_scan(priv);
346 }
347 cw1200_scan_complete(priv);
348 }
349}
350
351void cw1200_probe_work(struct work_struct *work)
352{
353 struct cw1200_common *priv =
354 container_of(work, struct cw1200_common, scan.probe_work.work);
355 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
356 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
357 const struct cw1200_txpriv *txpriv;
358 struct wsm_tx *wsm;
359 struct wsm_template_frame frame = {
360 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
361 };
362 struct wsm_ssid ssids[1] = {{
363 .length = 0,
364 } };
365 struct wsm_scan_ch ch[1] = {{
366 .min_chan_time = 0,
367 .max_chan_time = 10,
368 } };
369 struct wsm_scan scan = {
370 .type = WSM_SCAN_TYPE_FOREGROUND,
371 .num_probes = 1,
372 .probe_delay = 0,
373 .num_channels = 1,
374 .ssids = ssids,
375 .ch = ch,
376 };
377 u8 *ies;
378 size_t ies_len;
379 int ret;
380
381 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe work.\n");
382
383 mutex_lock(&priv->conf_mutex);
384 if (down_trylock(&priv->scan.lock)) {
385 /* Scan is already in progress. Requeue self. */
386 schedule();
387 queue_delayed_work(priv->workqueue,
388 &priv->scan.probe_work, HZ / 10);
389 mutex_unlock(&priv->conf_mutex);
390 return;
391 }
392
393 /* Make sure we still have a pending probe req */
394 if (cw1200_queue_get_skb(queue, priv->pending_frame_id,
395 &frame.skb, &txpriv)) {
396 up(&priv->scan.lock);
397 mutex_unlock(&priv->conf_mutex);
398 wsm_unlock_tx(priv);
399 return;
400 }
401 wsm = (struct wsm_tx *)frame.skb->data;
402 scan.max_tx_rate = wsm->max_tx_rate;
403 scan.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
404 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
405 if (priv->join_status == CW1200_JOIN_STATUS_STA ||
406 priv->join_status == CW1200_JOIN_STATUS_IBSS) {
407 scan.type = WSM_SCAN_TYPE_BACKGROUND;
408 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
409 }
410 ch[0].number = priv->channel->hw_value;
411
412 skb_pull(frame.skb, txpriv->offset);
413
414 ies = &frame.skb->data[sizeof(struct ieee80211_hdr_3addr)];
415 ies_len = frame.skb->len - sizeof(struct ieee80211_hdr_3addr);
416
417 if (ies_len) {
418 u8 *ssidie =
419 (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
420 if (ssidie && ssidie[1] && ssidie[1] <= sizeof(ssids[0].ssid)) {
421 u8 *nextie = &ssidie[2 + ssidie[1]];
422 /* Remove SSID from the IE list. It has to be provided
423 * as a separate argument in cw1200_scan_start call
424 */
425
426 /* Store SSID localy */
427 ssids[0].length = ssidie[1];
428 memcpy(ssids[0].ssid, &ssidie[2], ssids[0].length);
429 scan.num_ssids = 1;
430
431 /* Remove SSID from IE list */
432 ssidie[1] = 0;
433 memmove(&ssidie[2], nextie, &ies[ies_len] - nextie);
434 skb_trim(frame.skb, frame.skb->len - ssids[0].length);
435 }
436 }
437
438 /* FW bug: driver has to restart p2p-dev mode after scan */
439 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
440 cw1200_disable_listening(priv);
441 ret = wsm_set_template_frame(priv, &frame);
442 priv->scan.direct_probe = 1;
443 if (!ret) {
444 wsm_flush_tx(priv);
445 ret = cw1200_scan_start(priv, &scan);
446 }
447 mutex_unlock(&priv->conf_mutex);
448
449 skb_push(frame.skb, txpriv->offset);
450 if (!ret)
451 IEEE80211_SKB_CB(frame.skb)->flags |= IEEE80211_TX_STAT_ACK;
452 BUG_ON(cw1200_queue_remove(queue, priv->pending_frame_id));
453
454 if (ret) {
455 priv->scan.direct_probe = 0;
456 up(&priv->scan.lock);
457 wsm_unlock_tx(priv);
458 }
459
460 return;
461}
diff --git a/drivers/net/wireless/cw1200/scan.h b/drivers/net/wireless/cw1200/scan.h
new file mode 100644
index 000000000000..5a8296ccfa82
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.h
@@ -0,0 +1,56 @@
1/*
2 * Scan interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef SCAN_H_INCLUDED
13#define SCAN_H_INCLUDED
14
15#include <linux/semaphore.h>
16#include "wsm.h"
17
18/* external */ struct sk_buff;
19/* external */ struct cfg80211_scan_request;
20/* external */ struct ieee80211_channel;
21/* external */ struct ieee80211_hw;
22/* external */ struct work_struct;
23
24struct cw1200_scan {
25 struct semaphore lock;
26 struct work_struct work;
27 struct delayed_work timeout;
28 struct cfg80211_scan_request *req;
29 struct ieee80211_channel **begin;
30 struct ieee80211_channel **curr;
31 struct ieee80211_channel **end;
32 struct wsm_ssid ssids[WSM_SCAN_MAX_NUM_OF_SSIDS];
33 int output_power;
34 int n_ssids;
35 int status;
36 atomic_t in_progress;
37 /* Direct probe requests workaround */
38 struct delayed_work probe_work;
39 int direct_probe;
40};
41
42int cw1200_hw_scan(struct ieee80211_hw *hw,
43 struct ieee80211_vif *vif,
44 struct cfg80211_scan_request *req);
45void cw1200_scan_work(struct work_struct *work);
46void cw1200_scan_timeout(struct work_struct *work);
47void cw1200_clear_recent_scan_work(struct work_struct *work);
48void cw1200_scan_complete_cb(struct cw1200_common *priv,
49 struct wsm_scan_complete *arg);
50void cw1200_scan_failed_cb(struct cw1200_common *priv);
51
52/* ******************************************************************** */
53/* Raw probe requests TX workaround */
54void cw1200_probe_work(struct work_struct *work);
55
56#endif
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
new file mode 100644
index 000000000000..679c55f15c67
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -0,0 +1,2406 @@
1/*
2 * Mac80211 STA API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/vmalloc.h>
13#include <linux/sched.h>
14#include <linux/firmware.h>
15#include <linux/module.h>
16
17#include "cw1200.h"
18#include "sta.h"
19#include "fwio.h"
20#include "bh.h"
21#include "debug.h"
22
23#ifndef ERP_INFO_BYTE_OFFSET
24#define ERP_INFO_BYTE_OFFSET 2
25#endif
26
27static void cw1200_do_join(struct cw1200_common *priv);
28static void cw1200_do_unjoin(struct cw1200_common *priv);
29
30static int cw1200_upload_beacon(struct cw1200_common *priv);
31static int cw1200_upload_pspoll(struct cw1200_common *priv);
32static int cw1200_upload_null(struct cw1200_common *priv);
33static int cw1200_upload_qosnull(struct cw1200_common *priv);
34static int cw1200_start_ap(struct cw1200_common *priv);
35static int cw1200_update_beaconing(struct cw1200_common *priv);
36static int cw1200_enable_beaconing(struct cw1200_common *priv,
37 bool enable);
38static void __cw1200_sta_notify(struct ieee80211_hw *dev,
39 struct ieee80211_vif *vif,
40 enum sta_notify_cmd notify_cmd,
41 int link_id);
42static int __cw1200_flush(struct cw1200_common *priv, bool drop);
43
44static inline void __cw1200_free_event_queue(struct list_head *list)
45{
46 struct cw1200_wsm_event *event, *tmp;
47 list_for_each_entry_safe(event, tmp, list, link) {
48 list_del(&event->link);
49 kfree(event);
50 }
51}
52
53/* ******************************************************************** */
54/* STA API */
55
56int cw1200_start(struct ieee80211_hw *dev)
57{
58 struct cw1200_common *priv = dev->priv;
59 int ret = 0;
60
61 cw1200_pm_stay_awake(&priv->pm_state, HZ);
62
63 mutex_lock(&priv->conf_mutex);
64
65 /* default EDCA */
66 WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007, 47, 0xc8, false);
67 WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f, 94, 0xc8, false);
68 WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff, 0, 0xc8, false);
69 WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff, 0, 0xc8, false);
70 ret = wsm_set_edca_params(priv, &priv->edca);
71 if (ret)
72 goto out;
73
74 ret = cw1200_set_uapsd_param(priv, &priv->edca);
75 if (ret)
76 goto out;
77
78 priv->setbssparams_done = false;
79
80 memcpy(priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
81 priv->mode = NL80211_IFTYPE_MONITOR;
82 priv->wep_default_key_id = -1;
83
84 priv->cqm_beacon_loss_count = 10;
85
86 ret = cw1200_setup_mac(priv);
87 if (ret)
88 goto out;
89
90out:
91 mutex_unlock(&priv->conf_mutex);
92 return ret;
93}
94
95void cw1200_stop(struct ieee80211_hw *dev)
96{
97 struct cw1200_common *priv = dev->priv;
98 LIST_HEAD(list);
99 int i;
100
101 wsm_lock_tx(priv);
102
103 while (down_trylock(&priv->scan.lock)) {
104 /* Scan is in progress. Force it to stop. */
105 priv->scan.req = NULL;
106 schedule();
107 }
108 up(&priv->scan.lock);
109
110 cancel_delayed_work_sync(&priv->scan.probe_work);
111 cancel_delayed_work_sync(&priv->scan.timeout);
112 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
113 cancel_delayed_work_sync(&priv->join_timeout);
114 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
115 cancel_work_sync(&priv->unjoin_work);
116 cancel_delayed_work_sync(&priv->link_id_gc_work);
117 flush_workqueue(priv->workqueue);
118 del_timer_sync(&priv->mcast_timeout);
119 mutex_lock(&priv->conf_mutex);
120 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
121 priv->listening = false;
122
123 spin_lock(&priv->event_queue_lock);
124 list_splice_init(&priv->event_queue, &list);
125 spin_unlock(&priv->event_queue_lock);
126 __cw1200_free_event_queue(&list);
127
128
129 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
130 priv->join_pending = false;
131
132 for (i = 0; i < 4; i++)
133 cw1200_queue_clear(&priv->tx_queue[i]);
134 mutex_unlock(&priv->conf_mutex);
135 tx_policy_clean(priv);
136
137 /* HACK! */
138 if (atomic_xchg(&priv->tx_lock, 1) != 1)
139 pr_debug("[STA] TX is force-unlocked due to stop request.\n");
140
141 wsm_unlock_tx(priv);
142 atomic_xchg(&priv->tx_lock, 0); /* for recovery to work */
143}
144
145static int cw1200_bssloss_mitigation = 1;
146module_param(cw1200_bssloss_mitigation, int, 0644);
147MODULE_PARM_DESC(cw1200_bssloss_mitigation, "BSS Loss mitigation. 0 == disabled, 1 == enabled (default)");
148
149
150void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
151 int init, int good, int bad)
152{
153 int tx = 0;
154
155 priv->delayed_link_loss = 0;
156 cancel_work_sync(&priv->bss_params_work);
157
158 pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n",
159 priv->bss_loss_state,
160 init, good, bad,
161 atomic_read(&priv->tx_lock),
162 priv->delayed_unjoin);
163
164 /* If we have a pending unjoin */
165 if (priv->delayed_unjoin)
166 return;
167
168 if (init) {
169 queue_delayed_work(priv->workqueue,
170 &priv->bss_loss_work,
171 HZ);
172 priv->bss_loss_state = 0;
173
174 /* Skip the confimration procedure in P2P case */
175 if (!priv->vif->p2p && !atomic_read(&priv->tx_lock))
176 tx = 1;
177 } else if (good) {
178 cancel_delayed_work_sync(&priv->bss_loss_work);
179 priv->bss_loss_state = 0;
180 queue_work(priv->workqueue, &priv->bss_params_work);
181 } else if (bad) {
182 /* XXX Should we just keep going until we time out? */
183 if (priv->bss_loss_state < 3)
184 tx = 1;
185 } else {
186 cancel_delayed_work_sync(&priv->bss_loss_work);
187 priv->bss_loss_state = 0;
188 }
189
190 /* Bypass mitigation if it's disabled */
191 if (!cw1200_bssloss_mitigation)
192 tx = 0;
193
194 /* Spit out a NULL packet to our AP if necessary */
195 if (tx) {
196 struct sk_buff *skb;
197
198 priv->bss_loss_state++;
199
200 skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
201 WARN_ON(!skb);
202 if (skb)
203 cw1200_tx(priv->hw, NULL, skb);
204 }
205}
206
207int cw1200_add_interface(struct ieee80211_hw *dev,
208 struct ieee80211_vif *vif)
209{
210 int ret;
211 struct cw1200_common *priv = dev->priv;
212 /* __le32 auto_calibration_mode = __cpu_to_le32(1); */
213
214 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
215 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
216
217 mutex_lock(&priv->conf_mutex);
218
219 if (priv->mode != NL80211_IFTYPE_MONITOR) {
220 mutex_unlock(&priv->conf_mutex);
221 return -EOPNOTSUPP;
222 }
223
224 switch (vif->type) {
225 case NL80211_IFTYPE_STATION:
226 case NL80211_IFTYPE_ADHOC:
227 case NL80211_IFTYPE_MESH_POINT:
228 case NL80211_IFTYPE_AP:
229 priv->mode = vif->type;
230 break;
231 default:
232 mutex_unlock(&priv->conf_mutex);
233 return -EOPNOTSUPP;
234 }
235
236 priv->vif = vif;
237 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
238 ret = cw1200_setup_mac(priv);
239 /* Enable auto-calibration */
240 /* Exception in subsequent channel switch; disabled.
241 * wsm_write_mib(priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
242 * &auto_calibration_mode, sizeof(auto_calibration_mode));
243 */
244
245 mutex_unlock(&priv->conf_mutex);
246 return ret;
247}
248
249void cw1200_remove_interface(struct ieee80211_hw *dev,
250 struct ieee80211_vif *vif)
251{
252 struct cw1200_common *priv = dev->priv;
253 struct wsm_reset reset = {
254 .reset_statistics = true,
255 };
256 int i;
257
258 mutex_lock(&priv->conf_mutex);
259 switch (priv->join_status) {
260 case CW1200_JOIN_STATUS_JOINING:
261 case CW1200_JOIN_STATUS_PRE_STA:
262 case CW1200_JOIN_STATUS_STA:
263 case CW1200_JOIN_STATUS_IBSS:
264 wsm_lock_tx(priv);
265 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
266 wsm_unlock_tx(priv);
267 break;
268 case CW1200_JOIN_STATUS_AP:
269 for (i = 0; priv->link_id_map; ++i) {
270 if (priv->link_id_map & BIT(i)) {
271 reset.link_id = i;
272 wsm_reset(priv, &reset);
273 priv->link_id_map &= ~BIT(i);
274 }
275 }
276 memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
277 priv->sta_asleep_mask = 0;
278 priv->enable_beacon = false;
279 priv->tx_multicast = false;
280 priv->aid0_bit_set = false;
281 priv->buffered_multicasts = false;
282 priv->pspoll_mask = 0;
283 reset.link_id = 0;
284 wsm_reset(priv, &reset);
285 break;
286 case CW1200_JOIN_STATUS_MONITOR:
287 cw1200_update_listening(priv, false);
288 break;
289 default:
290 break;
291 }
292 priv->vif = NULL;
293 priv->mode = NL80211_IFTYPE_MONITOR;
294 memset(priv->mac_addr, 0, ETH_ALEN);
295 memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
296 cw1200_free_keys(priv);
297 cw1200_setup_mac(priv);
298 priv->listening = false;
299 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
300 if (!__cw1200_flush(priv, true))
301 wsm_unlock_tx(priv);
302
303 mutex_unlock(&priv->conf_mutex);
304}
305
306int cw1200_change_interface(struct ieee80211_hw *dev,
307 struct ieee80211_vif *vif,
308 enum nl80211_iftype new_type,
309 bool p2p)
310{
311 int ret = 0;
312 pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
313 p2p, vif->type, vif->p2p);
314
315 if (new_type != vif->type || vif->p2p != p2p) {
316 cw1200_remove_interface(dev, vif);
317 vif->type = new_type;
318 vif->p2p = p2p;
319 ret = cw1200_add_interface(dev, vif);
320 }
321
322 return ret;
323}
324
325int cw1200_config(struct ieee80211_hw *dev, u32 changed)
326{
327 int ret = 0;
328 struct cw1200_common *priv = dev->priv;
329 struct ieee80211_conf *conf = &dev->conf;
330
331 pr_debug("CONFIG CHANGED: %08x\n", changed);
332
333 down(&priv->scan.lock);
334 mutex_lock(&priv->conf_mutex);
335 /* TODO: IEEE80211_CONF_CHANGE_QOS */
336 /* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */
337
338 if (changed & IEEE80211_CONF_CHANGE_POWER) {
339 priv->output_power = conf->power_level;
340 pr_debug("[STA] TX power: %d\n", priv->output_power);
341 wsm_set_output_power(priv, priv->output_power * 10);
342 }
343
344 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
345 (priv->channel != conf->chandef.chan)) {
346 struct ieee80211_channel *ch = conf->chandef.chan;
347 struct wsm_switch_channel channel = {
348 .channel_number = ch->hw_value,
349 };
350 pr_debug("[STA] Freq %d (wsm ch: %d).\n",
351 ch->center_freq, ch->hw_value);
352
353 /* __cw1200_flush() implicitly locks tx, if successful */
354 if (!__cw1200_flush(priv, false)) {
355 if (!wsm_switch_channel(priv, &channel)) {
356 ret = wait_event_timeout(priv->channel_switch_done,
357 !priv->channel_switch_in_progress,
358 3 * HZ);
359 if (ret) {
360 /* Already unlocks if successful */
361 priv->channel = ch;
362 ret = 0;
363 } else {
364 ret = -ETIMEDOUT;
365 }
366 } else {
367 /* Unlock if switch channel fails */
368 wsm_unlock_tx(priv);
369 }
370 }
371 }
372
373 if (changed & IEEE80211_CONF_CHANGE_PS) {
374 if (!(conf->flags & IEEE80211_CONF_PS))
375 priv->powersave_mode.mode = WSM_PSM_ACTIVE;
376 else if (conf->dynamic_ps_timeout <= 0)
377 priv->powersave_mode.mode = WSM_PSM_PS;
378 else
379 priv->powersave_mode.mode = WSM_PSM_FAST_PS;
380
381 /* Firmware requires that value for this 1-byte field must
382 * be specified in units of 500us. Values above the 128ms
383 * threshold are not supported.
384 */
385 if (conf->dynamic_ps_timeout >= 0x80)
386 priv->powersave_mode.fast_psm_idle_period = 0xFF;
387 else
388 priv->powersave_mode.fast_psm_idle_period =
389 conf->dynamic_ps_timeout << 1;
390
391 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
392 priv->bss_params.aid)
393 cw1200_set_pm(priv, &priv->powersave_mode);
394 }
395
396 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
397 /* TBD: It looks like it's transparent
398 * there's a monitor interface present -- use this
399 * to determine for example whether to calculate
400 * timestamps for packets or not, do not use instead
401 * of filter flags!
402 */
403 }
404
405 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
406 struct wsm_operational_mode mode = {
407 .power_mode = cw1200_power_mode,
408 .disable_more_flag_usage = true,
409 };
410
411 wsm_lock_tx(priv);
412 /* Disable p2p-dev mode forced by TX request */
413 if ((priv->join_status == CW1200_JOIN_STATUS_MONITOR) &&
414 (conf->flags & IEEE80211_CONF_IDLE) &&
415 !priv->listening) {
416 cw1200_disable_listening(priv);
417 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
418 }
419 wsm_set_operational_mode(priv, &mode);
420 wsm_unlock_tx(priv);
421 }
422
423 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
424 pr_debug("[STA] Retry limits: %d (long), %d (short).\n",
425 conf->long_frame_max_tx_count,
426 conf->short_frame_max_tx_count);
427 spin_lock_bh(&priv->tx_policy_cache.lock);
428 priv->long_frame_max_tx_count = conf->long_frame_max_tx_count;
429 priv->short_frame_max_tx_count =
430 (conf->short_frame_max_tx_count < 0x0F) ?
431 conf->short_frame_max_tx_count : 0x0F;
432 priv->hw->max_rate_tries = priv->short_frame_max_tx_count;
433 spin_unlock_bh(&priv->tx_policy_cache.lock);
434 }
435 mutex_unlock(&priv->conf_mutex);
436 up(&priv->scan.lock);
437 return ret;
438}
439
440void cw1200_update_filtering(struct cw1200_common *priv)
441{
442 int ret;
443 bool bssid_filtering = !priv->rx_filter.bssid;
444 bool is_p2p = priv->vif && priv->vif->p2p;
445 bool is_sta = priv->vif && NL80211_IFTYPE_STATION == priv->vif->type;
446
447 static struct wsm_beacon_filter_control bf_ctrl;
448 static struct wsm_mib_beacon_filter_table bf_tbl = {
449 .entry[0].ie_id = WLAN_EID_VENDOR_SPECIFIC,
450 .entry[0].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
451 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
452 WSM_BEACON_FILTER_IE_HAS_APPEARED,
453 .entry[0].oui[0] = 0x50,
454 .entry[0].oui[1] = 0x6F,
455 .entry[0].oui[2] = 0x9A,
456 .entry[1].ie_id = WLAN_EID_HT_OPERATION,
457 .entry[1].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
458 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
459 WSM_BEACON_FILTER_IE_HAS_APPEARED,
460 .entry[2].ie_id = WLAN_EID_ERP_INFO,
461 .entry[2].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
462 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
463 WSM_BEACON_FILTER_IE_HAS_APPEARED,
464 };
465
466 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE)
467 return;
468 else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
469 bssid_filtering = false;
470
471 if (priv->disable_beacon_filter) {
472 bf_ctrl.enabled = 0;
473 bf_ctrl.bcn_count = 1;
474 bf_tbl.num = __cpu_to_le32(0);
475 } else if (is_p2p || !is_sta) {
476 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE |
477 WSM_BEACON_FILTER_AUTO_ERP;
478 bf_ctrl.bcn_count = 0;
479 bf_tbl.num = __cpu_to_le32(2);
480 } else {
481 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE;
482 bf_ctrl.bcn_count = 0;
483 bf_tbl.num = __cpu_to_le32(3);
484 }
485
486 /*
487 * When acting as p2p client being connected to p2p GO, in order to
488 * receive frames from a different p2p device, turn off bssid filter.
489 *
490 * WARNING: FW dependency!
491 * This can only be used with FW WSM371 and its successors.
492 * In that FW version even with bssid filter turned off,
493 * device will block most of the unwanted frames.
494 */
495 if (is_p2p)
496 bssid_filtering = false;
497
498 ret = wsm_set_rx_filter(priv, &priv->rx_filter);
499 if (!ret)
500 ret = wsm_set_beacon_filter_table(priv, &bf_tbl);
501 if (!ret)
502 ret = wsm_beacon_filter_control(priv, &bf_ctrl);
503 if (!ret)
504 ret = wsm_set_bssid_filtering(priv, bssid_filtering);
505 if (!ret)
506 ret = wsm_set_multicast_filter(priv, &priv->multicast_filter);
507 if (ret)
508 wiphy_err(priv->hw->wiphy,
509 "Update filtering failed: %d.\n", ret);
510 return;
511}
512
513void cw1200_update_filtering_work(struct work_struct *work)
514{
515 struct cw1200_common *priv =
516 container_of(work, struct cw1200_common,
517 update_filtering_work);
518
519 cw1200_update_filtering(priv);
520}
521
522void cw1200_set_beacon_wakeup_period_work(struct work_struct *work)
523{
524 struct cw1200_common *priv =
525 container_of(work, struct cw1200_common,
526 set_beacon_wakeup_period_work);
527
528 wsm_set_beacon_wakeup_period(priv,
529 priv->beacon_int * priv->join_dtim_period >
530 MAX_BEACON_SKIP_TIME_MS ? 1 :
531 priv->join_dtim_period, 0);
532}
533
534u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
535 struct netdev_hw_addr_list *mc_list)
536{
537 static u8 broadcast_ipv6[ETH_ALEN] = {
538 0x33, 0x33, 0x00, 0x00, 0x00, 0x01
539 };
540 static u8 broadcast_ipv4[ETH_ALEN] = {
541 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
542 };
543 struct cw1200_common *priv = hw->priv;
544 struct netdev_hw_addr *ha;
545 int count = 0;
546
547 /* Disable multicast filtering */
548 priv->has_multicast_subscription = false;
549 memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
550
551 if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
552 return 0;
553
554 /* Enable if requested */
555 netdev_hw_addr_list_for_each(ha, mc_list) {
556 pr_debug("[STA] multicast: %pM\n", ha->addr);
557 memcpy(&priv->multicast_filter.macaddrs[count],
558 ha->addr, ETH_ALEN);
559 if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) &&
560 memcmp(ha->addr, broadcast_ipv6, ETH_ALEN))
561 priv->has_multicast_subscription = true;
562 count++;
563 }
564
565 if (count) {
566 priv->multicast_filter.enable = __cpu_to_le32(1);
567 priv->multicast_filter.num_addrs = __cpu_to_le32(count);
568 }
569
570 return netdev_hw_addr_list_count(mc_list);
571}
572
573void cw1200_configure_filter(struct ieee80211_hw *dev,
574 unsigned int changed_flags,
575 unsigned int *total_flags,
576 u64 multicast)
577{
578 struct cw1200_common *priv = dev->priv;
579 bool listening = !!(*total_flags &
580 (FIF_PROMISC_IN_BSS |
581 FIF_OTHER_BSS |
582 FIF_BCN_PRBRESP_PROMISC |
583 FIF_PROBE_REQ));
584
585 *total_flags &= FIF_PROMISC_IN_BSS |
586 FIF_OTHER_BSS |
587 FIF_FCSFAIL |
588 FIF_BCN_PRBRESP_PROMISC |
589 FIF_PROBE_REQ;
590
591 down(&priv->scan.lock);
592 mutex_lock(&priv->conf_mutex);
593
594 priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS)
595 ? 1 : 0;
596 priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
597 FIF_PROBE_REQ)) ? 1 : 0;
598 priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
599 priv->disable_beacon_filter = !(*total_flags &
600 (FIF_BCN_PRBRESP_PROMISC |
601 FIF_PROMISC_IN_BSS |
602 FIF_PROBE_REQ));
603 if (priv->listening != listening) {
604 priv->listening = listening;
605 wsm_lock_tx(priv);
606 cw1200_update_listening(priv, listening);
607 wsm_unlock_tx(priv);
608 }
609 cw1200_update_filtering(priv);
610 mutex_unlock(&priv->conf_mutex);
611 up(&priv->scan.lock);
612}
613
614int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
615 u16 queue, const struct ieee80211_tx_queue_params *params)
616{
617 struct cw1200_common *priv = dev->priv;
618 int ret = 0;
619 /* To prevent re-applying PM request OID again and again*/
620 bool old_uapsd_flags;
621
622 mutex_lock(&priv->conf_mutex);
623
624 if (queue < dev->queues) {
625 old_uapsd_flags = priv->uapsd_info.uapsd_flags;
626
627 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
628 ret = wsm_set_tx_queue_params(priv,
629 &priv->tx_queue_params.params[queue], queue);
630 if (ret) {
631 ret = -EINVAL;
632 goto out;
633 }
634
635 WSM_EDCA_SET(&priv->edca, queue, params->aifs,
636 params->cw_min, params->cw_max,
637 params->txop, 0xc8,
638 params->uapsd);
639 ret = wsm_set_edca_params(priv, &priv->edca);
640 if (ret) {
641 ret = -EINVAL;
642 goto out;
643 }
644
645 if (priv->mode == NL80211_IFTYPE_STATION) {
646 ret = cw1200_set_uapsd_param(priv, &priv->edca);
647 if (!ret && priv->setbssparams_done &&
648 (priv->join_status == CW1200_JOIN_STATUS_STA) &&
649 (old_uapsd_flags != priv->uapsd_info.uapsd_flags))
650 ret = cw1200_set_pm(priv, &priv->powersave_mode);
651 }
652 } else {
653 ret = -EINVAL;
654 }
655
656out:
657 mutex_unlock(&priv->conf_mutex);
658 return ret;
659}
660
661int cw1200_get_stats(struct ieee80211_hw *dev,
662 struct ieee80211_low_level_stats *stats)
663{
664 struct cw1200_common *priv = dev->priv;
665
666 memcpy(stats, &priv->stats, sizeof(*stats));
667 return 0;
668}
669
670int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
671{
672 struct wsm_set_pm pm = *arg;
673
674 if (priv->uapsd_info.uapsd_flags != 0)
675 pm.mode &= ~WSM_PSM_FAST_PS_FLAG;
676
677 if (memcmp(&pm, &priv->firmware_ps_mode,
678 sizeof(struct wsm_set_pm))) {
679 priv->firmware_ps_mode = pm;
680 return wsm_set_pm(priv, &pm);
681 } else {
682 return 0;
683 }
684}
685
686int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
687 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
688 struct ieee80211_key_conf *key)
689{
690 int ret = -EOPNOTSUPP;
691 struct cw1200_common *priv = dev->priv;
692 struct ieee80211_key_seq seq;
693
694 mutex_lock(&priv->conf_mutex);
695
696 if (cmd == SET_KEY) {
697 u8 *peer_addr = NULL;
698 int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
699 1 : 0;
700 int idx = cw1200_alloc_key(priv);
701 struct wsm_add_key *wsm_key = &priv->keys[idx];
702
703 if (idx < 0) {
704 ret = -EINVAL;
705 goto finally;
706 }
707
708 if (sta)
709 peer_addr = sta->addr;
710
711 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
712
713 switch (key->cipher) {
714 case WLAN_CIPHER_SUITE_WEP40:
715 case WLAN_CIPHER_SUITE_WEP104:
716 if (key->keylen > 16) {
717 cw1200_free_key(priv, idx);
718 ret = -EINVAL;
719 goto finally;
720 }
721
722 if (pairwise) {
723 wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
724 memcpy(wsm_key->wep_pairwise.peer,
725 peer_addr, ETH_ALEN);
726 memcpy(wsm_key->wep_pairwise.keydata,
727 &key->key[0], key->keylen);
728 wsm_key->wep_pairwise.keylen = key->keylen;
729 } else {
730 wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
731 memcpy(wsm_key->wep_group.keydata,
732 &key->key[0], key->keylen);
733 wsm_key->wep_group.keylen = key->keylen;
734 wsm_key->wep_group.keyid = key->keyidx;
735 }
736 break;
737 case WLAN_CIPHER_SUITE_TKIP:
738 ieee80211_get_key_rx_seq(key, 0, &seq);
739 if (pairwise) {
740 wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
741 memcpy(wsm_key->tkip_pairwise.peer,
742 peer_addr, ETH_ALEN);
743 memcpy(wsm_key->tkip_pairwise.keydata,
744 &key->key[0], 16);
745 memcpy(wsm_key->tkip_pairwise.tx_mic_key,
746 &key->key[16], 8);
747 memcpy(wsm_key->tkip_pairwise.rx_mic_key,
748 &key->key[24], 8);
749 } else {
750 size_t mic_offset =
751 (priv->mode == NL80211_IFTYPE_AP) ?
752 16 : 24;
753 wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
754 memcpy(wsm_key->tkip_group.keydata,
755 &key->key[0], 16);
756 memcpy(wsm_key->tkip_group.rx_mic_key,
757 &key->key[mic_offset], 8);
758
759 wsm_key->tkip_group.rx_seqnum[0] = seq.tkip.iv16 & 0xff;
760 wsm_key->tkip_group.rx_seqnum[1] = (seq.tkip.iv16 >> 8) & 0xff;
761 wsm_key->tkip_group.rx_seqnum[2] = seq.tkip.iv32 & 0xff;
762 wsm_key->tkip_group.rx_seqnum[3] = (seq.tkip.iv32 >> 8) & 0xff;
763 wsm_key->tkip_group.rx_seqnum[4] = (seq.tkip.iv32 >> 16) & 0xff;
764 wsm_key->tkip_group.rx_seqnum[5] = (seq.tkip.iv32 >> 24) & 0xff;
765 wsm_key->tkip_group.rx_seqnum[6] = 0;
766 wsm_key->tkip_group.rx_seqnum[7] = 0;
767
768 wsm_key->tkip_group.keyid = key->keyidx;
769 }
770 break;
771 case WLAN_CIPHER_SUITE_CCMP:
772 ieee80211_get_key_rx_seq(key, 0, &seq);
773 if (pairwise) {
774 wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
775 memcpy(wsm_key->aes_pairwise.peer,
776 peer_addr, ETH_ALEN);
777 memcpy(wsm_key->aes_pairwise.keydata,
778 &key->key[0], 16);
779 } else {
780 wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
781 memcpy(wsm_key->aes_group.keydata,
782 &key->key[0], 16);
783
784 wsm_key->aes_group.rx_seqnum[0] = seq.ccmp.pn[5];
785 wsm_key->aes_group.rx_seqnum[1] = seq.ccmp.pn[4];
786 wsm_key->aes_group.rx_seqnum[2] = seq.ccmp.pn[3];
787 wsm_key->aes_group.rx_seqnum[3] = seq.ccmp.pn[2];
788 wsm_key->aes_group.rx_seqnum[4] = seq.ccmp.pn[1];
789 wsm_key->aes_group.rx_seqnum[5] = seq.ccmp.pn[0];
790 wsm_key->aes_group.rx_seqnum[6] = 0;
791 wsm_key->aes_group.rx_seqnum[7] = 0;
792 wsm_key->aes_group.keyid = key->keyidx;
793 }
794 break;
795 case WLAN_CIPHER_SUITE_SMS4:
796 if (pairwise) {
797 wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
798 memcpy(wsm_key->wapi_pairwise.peer,
799 peer_addr, ETH_ALEN);
800 memcpy(wsm_key->wapi_pairwise.keydata,
801 &key->key[0], 16);
802 memcpy(wsm_key->wapi_pairwise.mic_key,
803 &key->key[16], 16);
804 wsm_key->wapi_pairwise.keyid = key->keyidx;
805 } else {
806 wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
807 memcpy(wsm_key->wapi_group.keydata,
808 &key->key[0], 16);
809 memcpy(wsm_key->wapi_group.mic_key,
810 &key->key[16], 16);
811 wsm_key->wapi_group.keyid = key->keyidx;
812 }
813 break;
814 default:
815 pr_warn("Unhandled key type %d\n", key->cipher);
816 cw1200_free_key(priv, idx);
817 ret = -EOPNOTSUPP;
818 goto finally;
819 }
820 ret = wsm_add_key(priv, wsm_key);
821 if (!ret)
822 key->hw_key_idx = idx;
823 else
824 cw1200_free_key(priv, idx);
825 } else if (cmd == DISABLE_KEY) {
826 struct wsm_remove_key wsm_key = {
827 .index = key->hw_key_idx,
828 };
829
830 if (wsm_key.index > WSM_KEY_MAX_INDEX) {
831 ret = -EINVAL;
832 goto finally;
833 }
834
835 cw1200_free_key(priv, wsm_key.index);
836 ret = wsm_remove_key(priv, &wsm_key);
837 } else {
838 pr_warn("Unhandled key command %d\n", cmd);
839 }
840
841finally:
842 mutex_unlock(&priv->conf_mutex);
843 return ret;
844}
845
846void cw1200_wep_key_work(struct work_struct *work)
847{
848 struct cw1200_common *priv =
849 container_of(work, struct cw1200_common, wep_key_work);
850 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
851 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
852 __le32 wep_default_key_id = __cpu_to_le32(
853 priv->wep_default_key_id);
854
855 pr_debug("[STA] Setting default WEP key: %d\n",
856 priv->wep_default_key_id);
857 wsm_flush_tx(priv);
858 wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
859 &wep_default_key_id, sizeof(wep_default_key_id));
860 cw1200_queue_requeue(queue, priv->pending_frame_id);
861 wsm_unlock_tx(priv);
862}
863
864int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
865{
866 int ret = 0;
867 __le32 val32;
868 struct cw1200_common *priv = hw->priv;
869
870 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
871 return 0;
872
873 if (value != (u32) -1)
874 val32 = __cpu_to_le32(value);
875 else
876 val32 = 0; /* disabled */
877
878 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
879 /* device is down, can _not_ set threshold */
880 ret = -ENODEV;
881 goto out;
882 }
883
884 if (priv->rts_threshold == value)
885 goto out;
886
887 pr_debug("[STA] Setting RTS threshold: %d\n",
888 priv->rts_threshold);
889
890 /* mutex_lock(&priv->conf_mutex); */
891 ret = wsm_write_mib(priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
892 &val32, sizeof(val32));
893 if (!ret)
894 priv->rts_threshold = value;
895 /* mutex_unlock(&priv->conf_mutex); */
896
897out:
898 return ret;
899}
900
901/* If successful, LOCKS the TX queue! */
902static int __cw1200_flush(struct cw1200_common *priv, bool drop)
903{
904 int i, ret;
905
906 for (;;) {
907 /* TODO: correct flush handling is required when dev_stop.
908 * Temporary workaround: 2s
909 */
910 if (drop) {
911 for (i = 0; i < 4; ++i)
912 cw1200_queue_clear(&priv->tx_queue[i]);
913 } else {
914 ret = wait_event_timeout(
915 priv->tx_queue_stats.wait_link_id_empty,
916 cw1200_queue_stats_is_empty(
917 &priv->tx_queue_stats, -1),
918 2 * HZ);
919 }
920
921 if (!drop && ret <= 0) {
922 ret = -ETIMEDOUT;
923 break;
924 } else {
925 ret = 0;
926 }
927
928 wsm_lock_tx(priv);
929 if (!cw1200_queue_stats_is_empty(&priv->tx_queue_stats, -1)) {
930 /* Highly unlikely: WSM requeued frames. */
931 wsm_unlock_tx(priv);
932 continue;
933 }
934 break;
935 }
936 return ret;
937}
938
939void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
940{
941 struct cw1200_common *priv = hw->priv;
942
943 switch (priv->mode) {
944 case NL80211_IFTYPE_MONITOR:
945 drop = true;
946 break;
947 case NL80211_IFTYPE_AP:
948 if (!priv->enable_beacon)
949 drop = true;
950 break;
951 }
952
953 if (!__cw1200_flush(priv, drop))
954 wsm_unlock_tx(priv);
955
956 return;
957}
958
959/* ******************************************************************** */
960/* WSM callbacks */
961
962void cw1200_free_event_queue(struct cw1200_common *priv)
963{
964 LIST_HEAD(list);
965
966 spin_lock(&priv->event_queue_lock);
967 list_splice_init(&priv->event_queue, &list);
968 spin_unlock(&priv->event_queue_lock);
969
970 __cw1200_free_event_queue(&list);
971}
972
973void cw1200_event_handler(struct work_struct *work)
974{
975 struct cw1200_common *priv =
976 container_of(work, struct cw1200_common, event_handler);
977 struct cw1200_wsm_event *event;
978 LIST_HEAD(list);
979
980 spin_lock(&priv->event_queue_lock);
981 list_splice_init(&priv->event_queue, &list);
982 spin_unlock(&priv->event_queue_lock);
983
984 list_for_each_entry(event, &list, link) {
985 switch (event->evt.id) {
986 case WSM_EVENT_ERROR:
987 pr_err("Unhandled WSM Error from LMAC\n");
988 break;
989 case WSM_EVENT_BSS_LOST:
990 pr_debug("[CQM] BSS lost.\n");
991 cancel_work_sync(&priv->unjoin_work);
992 if (!down_trylock(&priv->scan.lock)) {
993 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
994 up(&priv->scan.lock);
995 } else {
996 /* Scan is in progress. Delay reporting.
997 * Scan complete will trigger bss_loss_work
998 */
999 priv->delayed_link_loss = 1;
1000 /* Also start a watchdog. */
1001 queue_delayed_work(priv->workqueue,
1002 &priv->bss_loss_work, 5*HZ);
1003 }
1004 break;
1005 case WSM_EVENT_BSS_REGAINED:
1006 pr_debug("[CQM] BSS regained.\n");
1007 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1008 cancel_work_sync(&priv->unjoin_work);
1009 break;
1010 case WSM_EVENT_RADAR_DETECTED:
1011 wiphy_info(priv->hw->wiphy, "radar pulse detected\n");
1012 break;
1013 case WSM_EVENT_RCPI_RSSI:
1014 {
1015 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1016 * RSSI = RCPI / 2 - 110
1017 */
1018 int rcpiRssi = (int)(event->evt.data & 0xFF);
1019 int cqm_evt;
1020 if (priv->cqm_use_rssi)
1021 rcpiRssi = (s8)rcpiRssi;
1022 else
1023 rcpiRssi = rcpiRssi / 2 - 110;
1024
1025 cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ?
1026 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
1027 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
1028 pr_debug("[CQM] RSSI event: %d.\n", rcpiRssi);
1029 ieee80211_cqm_rssi_notify(priv->vif, cqm_evt,
1030 GFP_KERNEL);
1031 break;
1032 }
1033 case WSM_EVENT_BT_INACTIVE:
1034 pr_warn("Unhandled BT INACTIVE from LMAC\n");
1035 break;
1036 case WSM_EVENT_BT_ACTIVE:
1037 pr_warn("Unhandled BT ACTIVE from LMAC\n");
1038 break;
1039 }
1040 }
1041 __cw1200_free_event_queue(&list);
1042}
1043
1044void cw1200_bss_loss_work(struct work_struct *work)
1045{
1046 struct cw1200_common *priv =
1047 container_of(work, struct cw1200_common, bss_loss_work.work);
1048
1049 pr_debug("[CQM] Reporting connection loss.\n");
1050 wsm_lock_tx(priv);
1051 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1052 wsm_unlock_tx(priv);
1053}
1054
1055void cw1200_bss_params_work(struct work_struct *work)
1056{
1057 struct cw1200_common *priv =
1058 container_of(work, struct cw1200_common, bss_params_work);
1059 mutex_lock(&priv->conf_mutex);
1060
1061 priv->bss_params.reset_beacon_loss = 1;
1062 wsm_set_bss_params(priv, &priv->bss_params);
1063 priv->bss_params.reset_beacon_loss = 0;
1064
1065 mutex_unlock(&priv->conf_mutex);
1066}
1067
1068/* ******************************************************************** */
1069/* Internal API */
1070
1071/*
1072 * This function is called to Parse the SDD file
1073 * to extract listen_interval and PTA related information
1074 * sdd is a TLV: u8 id, u8 len, u8 data[]
1075 */
1076static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1077{
1078 const u8 *p = priv->sdd->data;
1079 int ret = 0;
1080
1081 while (p + 2 <= priv->sdd->data + priv->sdd->size) {
1082 if (p + p[1] + 2 > priv->sdd->data + priv->sdd->size) {
1083 pr_warn("Malformed sdd structure\n");
1084 return -1;
1085 }
1086 switch (p[0]) {
1087 case SDD_PTA_CFG_ELT_ID: {
1088 u16 v;
1089 if (p[1] < 4) {
1090 pr_warn("SDD_PTA_CFG_ELT_ID malformed\n");
1091 ret = -1;
1092 break;
1093 }
1094 v = le16_to_cpu(*((u16 *)(p + 2)));
1095 if (!v) /* non-zero means this is enabled */
1096 break;
1097
1098 v = le16_to_cpu(*((u16 *)(p + 4)));
1099 priv->conf_listen_interval = (v >> 7) & 0x1F;
1100 pr_debug("PTA found; Listen Interval %d\n",
1101 priv->conf_listen_interval);
1102 break;
1103 }
1104 case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1105 u16 clk = le16_to_cpu(*((u16 *)(p + 2)));
1106 if (clk != priv->hw_refclk)
1107 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1108 clk, priv->hw_refclk);
1109 break;
1110 }
1111 default:
1112 break;
1113 }
1114 p += p[1] + 2;
1115 }
1116
1117 if (!priv->bt_present) {
1118 pr_debug("PTA element NOT found.\n");
1119 priv->conf_listen_interval = 0;
1120 }
1121 return ret;
1122}
1123
1124int cw1200_setup_mac(struct cw1200_common *priv)
1125{
1126 int ret = 0;
1127
1128 /* NOTE: There is a bug in FW: it reports signal
1129 * as RSSI if RSSI subscription is enabled.
1130 * It's not enough to set WSM_RCPI_RSSI_USE_RSSI.
1131 *
1132 * NOTE2: RSSI based reports have been switched to RCPI, since
1133 * FW has a bug and RSSI reported values are not stable,
1134 * what can leads to signal level oscilations in user-end applications
1135 */
1136 struct wsm_rcpi_rssi_threshold threshold = {
1137 .rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
1138 WSM_RCPI_RSSI_DONT_USE_UPPER |
1139 WSM_RCPI_RSSI_DONT_USE_LOWER,
1140 .rollingAverageCount = 16,
1141 };
1142
1143 struct wsm_configuration cfg = {
1144 .dot11StationId = &priv->mac_addr[0],
1145 };
1146
1147 /* Remember the decission here to make sure, we will handle
1148 * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS
1149 */
1150 if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
1151 priv->cqm_use_rssi = true;
1152
1153 if (!priv->sdd) {
1154 ret = request_firmware(&priv->sdd, priv->sdd_path, priv->pdev);
1155 if (ret) {
1156 pr_err("Can't load sdd file %s.\n", priv->sdd_path);
1157 return ret;
1158 }
1159 cw1200_parse_sdd_file(priv);
1160 }
1161
1162 cfg.dpdData = priv->sdd->data;
1163 cfg.dpdData_size = priv->sdd->size;
1164 ret = wsm_configuration(priv, &cfg);
1165 if (ret)
1166 return ret;
1167
1168 /* Configure RSSI/SCPI reporting as RSSI. */
1169 wsm_set_rcpi_rssi_threshold(priv, &threshold);
1170
1171 return 0;
1172}
1173
1174static void cw1200_join_complete(struct cw1200_common *priv)
1175{
1176 pr_debug("[STA] Join complete (%d)\n", priv->join_complete_status);
1177
1178 priv->join_pending = false;
1179 if (priv->join_complete_status) {
1180 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1181 cw1200_update_listening(priv, priv->listening);
1182 cw1200_do_unjoin(priv);
1183 ieee80211_connection_loss(priv->vif);
1184 } else {
1185 if (priv->mode == NL80211_IFTYPE_ADHOC)
1186 priv->join_status = CW1200_JOIN_STATUS_IBSS;
1187 else
1188 priv->join_status = CW1200_JOIN_STATUS_PRE_STA;
1189 }
1190 wsm_unlock_tx(priv); /* Clearing the lock held before do_join() */
1191}
1192
1193void cw1200_join_complete_work(struct work_struct *work)
1194{
1195 struct cw1200_common *priv =
1196 container_of(work, struct cw1200_common, join_complete_work);
1197 mutex_lock(&priv->conf_mutex);
1198 cw1200_join_complete(priv);
1199 mutex_unlock(&priv->conf_mutex);
1200}
1201
1202void cw1200_join_complete_cb(struct cw1200_common *priv,
1203 struct wsm_join_complete *arg)
1204{
1205 pr_debug("[STA] cw1200_join_complete_cb called, status=%d.\n",
1206 arg->status);
1207
1208 if (cancel_delayed_work(&priv->join_timeout)) {
1209 priv->join_complete_status = arg->status;
1210 queue_work(priv->workqueue, &priv->join_complete_work);
1211 }
1212}
1213
1214/* MUST be called with tx_lock held! It will be unlocked for us. */
1215static void cw1200_do_join(struct cw1200_common *priv)
1216{
1217 const u8 *bssid;
1218 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
1219 struct cfg80211_bss *bss = NULL;
1220 struct wsm_protected_mgmt_policy mgmt_policy;
1221 struct wsm_join join = {
1222 .mode = conf->ibss_joined ?
1223 WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
1224 .preamble_type = WSM_JOIN_PREAMBLE_LONG,
1225 .probe_for_join = 1,
1226 .atim_window = 0,
1227 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
1228 conf->basic_rates),
1229 };
1230 if (delayed_work_pending(&priv->join_timeout)) {
1231 pr_warn("[STA] - Join request already pending, skipping..\n");
1232 wsm_unlock_tx(priv);
1233 return;
1234 }
1235
1236 if (priv->join_status)
1237 cw1200_do_unjoin(priv);
1238
1239 bssid = priv->vif->bss_conf.bssid;
1240
1241 bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
1242 bssid, NULL, 0, 0, 0);
1243
1244 if (!bss && !conf->ibss_joined) {
1245 wsm_unlock_tx(priv);
1246 return;
1247 }
1248
1249 mutex_lock(&priv->conf_mutex);
1250
1251 /* Under the conf lock: check scan status and
1252 * bail out if it is in progress.
1253 */
1254 if (atomic_read(&priv->scan.in_progress)) {
1255 wsm_unlock_tx(priv);
1256 goto done_put;
1257 }
1258
1259 priv->join_pending = true;
1260
1261 /* Sanity check basic rates */
1262 if (!join.basic_rate_set)
1263 join.basic_rate_set = 7;
1264
1265 /* Sanity check beacon interval */
1266 if (!priv->beacon_int)
1267 priv->beacon_int = 1;
1268
1269 join.beacon_interval = priv->beacon_int;
1270
1271 /* BT Coex related changes */
1272 if (priv->bt_present) {
1273 if (((priv->conf_listen_interval * 100) %
1274 priv->beacon_int) == 0)
1275 priv->listen_interval =
1276 ((priv->conf_listen_interval * 100) /
1277 priv->beacon_int);
1278 else
1279 priv->listen_interval =
1280 ((priv->conf_listen_interval * 100) /
1281 priv->beacon_int + 1);
1282 }
1283
1284 if (priv->hw->conf.ps_dtim_period)
1285 priv->join_dtim_period = priv->hw->conf.ps_dtim_period;
1286 join.dtim_period = priv->join_dtim_period;
1287
1288 join.channel_number = priv->channel->hw_value;
1289 join.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
1290 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1291
1292 memcpy(join.bssid, bssid, sizeof(join.bssid));
1293
1294 pr_debug("[STA] Join BSSID: %pM DTIM: %d, interval: %d\n",
1295 join.bssid,
1296 join.dtim_period, priv->beacon_int);
1297
1298 if (!conf->ibss_joined) {
1299 const u8 *ssidie;
1300 rcu_read_lock();
1301 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1302 if (ssidie) {
1303 join.ssid_len = ssidie[1];
1304 memcpy(join.ssid, &ssidie[2], join.ssid_len);
1305 }
1306 rcu_read_unlock();
1307 }
1308
1309 if (priv->vif->p2p) {
1310 join.flags |= WSM_JOIN_FLAGS_P2P_GO;
1311 join.basic_rate_set =
1312 cw1200_rate_mask_to_wsm(priv, 0xFF0);
1313 }
1314
1315 /* Enable asynchronous join calls */
1316 if (!conf->ibss_joined) {
1317 join.flags |= WSM_JOIN_FLAGS_FORCE;
1318 join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
1319 }
1320
1321 wsm_flush_tx(priv);
1322
1323 /* Stay Awake for Join and Auth Timeouts and a bit more */
1324 cw1200_pm_stay_awake(&priv->pm_state,
1325 CW1200_JOIN_TIMEOUT + CW1200_AUTH_TIMEOUT);
1326
1327 cw1200_update_listening(priv, false);
1328
1329 /* Turn on Block ACKs */
1330 wsm_set_block_ack_policy(priv, priv->ba_tx_tid_mask,
1331 priv->ba_rx_tid_mask);
1332
1333 /* Set up timeout */
1334 if (join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND) {
1335 priv->join_status = CW1200_JOIN_STATUS_JOINING;
1336 queue_delayed_work(priv->workqueue,
1337 &priv->join_timeout,
1338 CW1200_JOIN_TIMEOUT);
1339 }
1340
1341 /* 802.11w protected mgmt frames */
1342 mgmt_policy.protectedMgmtEnable = 0;
1343 mgmt_policy.unprotectedMgmtFramesAllowed = 1;
1344 mgmt_policy.encryptionForAuthFrame = 1;
1345 wsm_set_protected_mgmt_policy(priv, &mgmt_policy);
1346
1347 /* Perform actual join */
1348 if (wsm_join(priv, &join)) {
1349 pr_err("[STA] cw1200_join_work: wsm_join failed!\n");
1350 cancel_delayed_work_sync(&priv->join_timeout);
1351 cw1200_update_listening(priv, priv->listening);
1352 /* Tx lock still held, unjoin will clear it. */
1353 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1354 wsm_unlock_tx(priv);
1355 } else {
1356 if (!(join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND))
1357 cw1200_join_complete(priv); /* Will clear tx_lock */
1358
1359 /* Upload keys */
1360 cw1200_upload_keys(priv);
1361
1362 /* Due to beacon filtering it is possible that the
1363 * AP's beacon is not known for the mac80211 stack.
1364 * Disable filtering temporary to make sure the stack
1365 * receives at least one
1366 */
1367 priv->disable_beacon_filter = true;
1368 }
1369 cw1200_update_filtering(priv);
1370
1371done_put:
1372 mutex_unlock(&priv->conf_mutex);
1373 if (bss)
1374 cfg80211_put_bss(priv->hw->wiphy, bss);
1375}
1376
1377void cw1200_join_timeout(struct work_struct *work)
1378{
1379 struct cw1200_common *priv =
1380 container_of(work, struct cw1200_common, join_timeout.work);
1381 pr_debug("[WSM] Join timed out.\n");
1382 wsm_lock_tx(priv);
1383 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1384 wsm_unlock_tx(priv);
1385}
1386
1387static void cw1200_do_unjoin(struct cw1200_common *priv)
1388{
1389 struct wsm_reset reset = {
1390 .reset_statistics = true,
1391 };
1392
1393 cancel_delayed_work_sync(&priv->join_timeout);
1394
1395 mutex_lock(&priv->conf_mutex);
1396 priv->join_pending = false;
1397
1398 if (atomic_read(&priv->scan.in_progress)) {
1399 if (priv->delayed_unjoin)
1400 wiphy_dbg(priv->hw->wiphy, "Delayed unjoin is already scheduled.\n");
1401 else
1402 priv->delayed_unjoin = true;
1403 goto done;
1404 }
1405
1406 priv->delayed_link_loss = false;
1407
1408 if (!priv->join_status)
1409 goto done;
1410
1411 if (priv->join_status > CW1200_JOIN_STATUS_IBSS) {
1412 wiphy_err(priv->hw->wiphy, "Unexpected: join status: %d\n",
1413 priv->join_status);
1414 BUG_ON(1);
1415 }
1416
1417 cancel_work_sync(&priv->update_filtering_work);
1418 cancel_work_sync(&priv->set_beacon_wakeup_period_work);
1419 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1420
1421 /* Unjoin is a reset. */
1422 wsm_flush_tx(priv);
1423 wsm_keep_alive_period(priv, 0);
1424 wsm_reset(priv, &reset);
1425 wsm_set_output_power(priv, priv->output_power * 10);
1426 priv->join_dtim_period = 0;
1427 cw1200_setup_mac(priv);
1428 cw1200_free_event_queue(priv);
1429 cancel_work_sync(&priv->event_handler);
1430 cw1200_update_listening(priv, priv->listening);
1431 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1432
1433 /* Disable Block ACKs */
1434 wsm_set_block_ack_policy(priv, 0, 0);
1435
1436 priv->disable_beacon_filter = false;
1437 cw1200_update_filtering(priv);
1438 memset(&priv->association_mode, 0,
1439 sizeof(priv->association_mode));
1440 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
1441 priv->setbssparams_done = false;
1442 memset(&priv->firmware_ps_mode, 0,
1443 sizeof(priv->firmware_ps_mode));
1444
1445 pr_debug("[STA] Unjoin completed.\n");
1446
1447done:
1448 mutex_unlock(&priv->conf_mutex);
1449}
1450
1451void cw1200_unjoin_work(struct work_struct *work)
1452{
1453 struct cw1200_common *priv =
1454 container_of(work, struct cw1200_common, unjoin_work);
1455
1456 cw1200_do_unjoin(priv);
1457
1458 /* Tell the stack we're dead */
1459 ieee80211_connection_loss(priv->vif);
1460
1461 wsm_unlock_tx(priv);
1462}
1463
1464int cw1200_enable_listening(struct cw1200_common *priv)
1465{
1466 struct wsm_start start = {
1467 .mode = WSM_START_MODE_P2P_DEV,
1468 .band = WSM_PHY_BAND_2_4G,
1469 .beacon_interval = 100,
1470 .dtim_period = 1,
1471 .probe_delay = 0,
1472 .basic_rate_set = 0x0F,
1473 };
1474
1475 if (priv->channel) {
1476 start.band = priv->channel->band == IEEE80211_BAND_5GHZ ?
1477 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1478 start.channel_number = priv->channel->hw_value;
1479 } else {
1480 start.band = WSM_PHY_BAND_2_4G;
1481 start.channel_number = 1;
1482 }
1483
1484 return wsm_start(priv, &start);
1485}
1486
1487int cw1200_disable_listening(struct cw1200_common *priv)
1488{
1489 int ret;
1490 struct wsm_reset reset = {
1491 .reset_statistics = true,
1492 };
1493 ret = wsm_reset(priv, &reset);
1494 return ret;
1495}
1496
1497void cw1200_update_listening(struct cw1200_common *priv, bool enabled)
1498{
1499 if (enabled) {
1500 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE) {
1501 if (!cw1200_enable_listening(priv))
1502 priv->join_status = CW1200_JOIN_STATUS_MONITOR;
1503 wsm_set_probe_responder(priv, true);
1504 }
1505 } else {
1506 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
1507 if (!cw1200_disable_listening(priv))
1508 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1509 wsm_set_probe_responder(priv, false);
1510 }
1511 }
1512}
1513
1514int cw1200_set_uapsd_param(struct cw1200_common *priv,
1515 const struct wsm_edca_params *arg)
1516{
1517 int ret;
1518 u16 uapsd_flags = 0;
1519
1520 /* Here's the mapping AC [queue, bit]
1521 * VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
1522 */
1523
1524 if (arg->uapsd_enable[0])
1525 uapsd_flags |= 1 << 3;
1526
1527 if (arg->uapsd_enable[1])
1528 uapsd_flags |= 1 << 2;
1529
1530 if (arg->uapsd_enable[2])
1531 uapsd_flags |= 1 << 1;
1532
1533 if (arg->uapsd_enable[3])
1534 uapsd_flags |= 1;
1535
1536 /* Currently pseudo U-APSD operation is not supported, so setting
1537 * MinAutoTriggerInterval, MaxAutoTriggerInterval and
1538 * AutoTriggerStep to 0
1539 */
1540
1541 priv->uapsd_info.uapsd_flags = cpu_to_le16(uapsd_flags);
1542 priv->uapsd_info.min_auto_trigger_interval = 0;
1543 priv->uapsd_info.max_auto_trigger_interval = 0;
1544 priv->uapsd_info.auto_trigger_step = 0;
1545
1546 ret = wsm_set_uapsd_info(priv, &priv->uapsd_info);
1547 return ret;
1548}
1549
1550/* ******************************************************************** */
1551/* AP API */
1552
1553int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1554 struct ieee80211_sta *sta)
1555{
1556 struct cw1200_common *priv = hw->priv;
1557 struct cw1200_sta_priv *sta_priv =
1558 (struct cw1200_sta_priv *)&sta->drv_priv;
1559 struct cw1200_link_entry *entry;
1560 struct sk_buff *skb;
1561
1562 if (priv->mode != NL80211_IFTYPE_AP)
1563 return 0;
1564
1565 sta_priv->link_id = cw1200_find_link_id(priv, sta->addr);
1566 if (WARN_ON(!sta_priv->link_id)) {
1567 wiphy_info(priv->hw->wiphy,
1568 "[AP] No more link IDs available.\n");
1569 return -ENOENT;
1570 }
1571
1572 entry = &priv->link_id_db[sta_priv->link_id - 1];
1573 spin_lock_bh(&priv->ps_state_lock);
1574 if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
1575 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
1576 priv->sta_asleep_mask |= BIT(sta_priv->link_id);
1577 entry->status = CW1200_LINK_HARD;
1578 while ((skb = skb_dequeue(&entry->rx_queue)))
1579 ieee80211_rx_irqsafe(priv->hw, skb);
1580 spin_unlock_bh(&priv->ps_state_lock);
1581 return 0;
1582}
1583
1584int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1585 struct ieee80211_sta *sta)
1586{
1587 struct cw1200_common *priv = hw->priv;
1588 struct cw1200_sta_priv *sta_priv =
1589 (struct cw1200_sta_priv *)&sta->drv_priv;
1590 struct cw1200_link_entry *entry;
1591
1592 if (priv->mode != NL80211_IFTYPE_AP || !sta_priv->link_id)
1593 return 0;
1594
1595 entry = &priv->link_id_db[sta_priv->link_id - 1];
1596 spin_lock_bh(&priv->ps_state_lock);
1597 entry->status = CW1200_LINK_RESERVE;
1598 entry->timestamp = jiffies;
1599 wsm_lock_tx_async(priv);
1600 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1601 wsm_unlock_tx(priv);
1602 spin_unlock_bh(&priv->ps_state_lock);
1603 flush_workqueue(priv->workqueue);
1604 return 0;
1605}
1606
1607static void __cw1200_sta_notify(struct ieee80211_hw *dev,
1608 struct ieee80211_vif *vif,
1609 enum sta_notify_cmd notify_cmd,
1610 int link_id)
1611{
1612 struct cw1200_common *priv = dev->priv;
1613 u32 bit, prev;
1614
1615 /* Zero link id means "for all link IDs" */
1616 if (link_id)
1617 bit = BIT(link_id);
1618 else if (WARN_ON_ONCE(notify_cmd != STA_NOTIFY_AWAKE))
1619 bit = 0;
1620 else
1621 bit = priv->link_id_map;
1622 prev = priv->sta_asleep_mask & bit;
1623
1624 switch (notify_cmd) {
1625 case STA_NOTIFY_SLEEP:
1626 if (!prev) {
1627 if (priv->buffered_multicasts &&
1628 !priv->sta_asleep_mask)
1629 queue_work(priv->workqueue,
1630 &priv->multicast_start_work);
1631 priv->sta_asleep_mask |= bit;
1632 }
1633 break;
1634 case STA_NOTIFY_AWAKE:
1635 if (prev) {
1636 priv->sta_asleep_mask &= ~bit;
1637 priv->pspoll_mask &= ~bit;
1638 if (priv->tx_multicast && link_id &&
1639 !priv->sta_asleep_mask)
1640 queue_work(priv->workqueue,
1641 &priv->multicast_stop_work);
1642 cw1200_bh_wakeup(priv);
1643 }
1644 break;
1645 }
1646}
1647
1648void cw1200_sta_notify(struct ieee80211_hw *dev,
1649 struct ieee80211_vif *vif,
1650 enum sta_notify_cmd notify_cmd,
1651 struct ieee80211_sta *sta)
1652{
1653 struct cw1200_common *priv = dev->priv;
1654 struct cw1200_sta_priv *sta_priv =
1655 (struct cw1200_sta_priv *)&sta->drv_priv;
1656
1657 spin_lock_bh(&priv->ps_state_lock);
1658 __cw1200_sta_notify(dev, vif, notify_cmd, sta_priv->link_id);
1659 spin_unlock_bh(&priv->ps_state_lock);
1660}
1661
1662static void cw1200_ps_notify(struct cw1200_common *priv,
1663 int link_id, bool ps)
1664{
1665 if (link_id > CW1200_MAX_STA_IN_AP_MODE)
1666 return;
1667
1668 pr_debug("%s for LinkId: %d. STAs asleep: %.8X\n",
1669 ps ? "Stop" : "Start",
1670 link_id, priv->sta_asleep_mask);
1671
1672 __cw1200_sta_notify(priv->hw, priv->vif,
1673 ps ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE, link_id);
1674}
1675
1676static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
1677{
1678 struct sk_buff *skb;
1679 struct wsm_update_ie update_ie = {
1680 .what = WSM_UPDATE_IE_BEACON,
1681 .count = 1,
1682 };
1683 u16 tim_offset, tim_length;
1684
1685 pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
1686
1687 skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
1688 &tim_offset, &tim_length);
1689 if (!skb) {
1690 if (!__cw1200_flush(priv, true))
1691 wsm_unlock_tx(priv);
1692 return -ENOENT;
1693 }
1694
1695 if (tim_offset && tim_length >= 6) {
1696 /* Ignore DTIM count from mac80211:
1697 * firmware handles DTIM internally.
1698 */
1699 skb->data[tim_offset + 2] = 0;
1700
1701 /* Set/reset aid0 bit */
1702 if (aid0_bit_set)
1703 skb->data[tim_offset + 4] |= 1;
1704 else
1705 skb->data[tim_offset + 4] &= ~1;
1706 }
1707
1708 update_ie.ies = &skb->data[tim_offset];
1709 update_ie.length = tim_length;
1710 wsm_update_ie(priv, &update_ie);
1711
1712 dev_kfree_skb(skb);
1713
1714 return 0;
1715}
1716
1717void cw1200_set_tim_work(struct work_struct *work)
1718{
1719 struct cw1200_common *priv =
1720 container_of(work, struct cw1200_common, set_tim_work);
1721 (void)cw1200_set_tim_impl(priv, priv->aid0_bit_set);
1722}
1723
1724int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
1725 bool set)
1726{
1727 struct cw1200_common *priv = dev->priv;
1728 queue_work(priv->workqueue, &priv->set_tim_work);
1729 return 0;
1730}
1731
1732void cw1200_set_cts_work(struct work_struct *work)
1733{
1734 struct cw1200_common *priv =
1735 container_of(work, struct cw1200_common, set_cts_work);
1736
1737 u8 erp_ie[3] = {WLAN_EID_ERP_INFO, 0x1, 0};
1738 struct wsm_update_ie update_ie = {
1739 .what = WSM_UPDATE_IE_BEACON,
1740 .count = 1,
1741 .ies = erp_ie,
1742 .length = 3,
1743 };
1744 u32 erp_info;
1745 __le32 use_cts_prot;
1746 mutex_lock(&priv->conf_mutex);
1747 erp_info = priv->erp_info;
1748 mutex_unlock(&priv->conf_mutex);
1749 use_cts_prot =
1750 erp_info & WLAN_ERP_USE_PROTECTION ?
1751 __cpu_to_le32(1) : 0;
1752
1753 erp_ie[ERP_INFO_BYTE_OFFSET] = erp_info;
1754
1755 pr_debug("[STA] ERP information 0x%x\n", erp_info);
1756
1757 wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
1758 &use_cts_prot, sizeof(use_cts_prot));
1759 wsm_update_ie(priv, &update_ie);
1760
1761 return;
1762}
1763
1764static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1765{
1766 struct wsm_override_internal_txrate arg;
1767 int ret = 0;
1768
1769 if (priv->mode == NL80211_IFTYPE_STATION) {
1770 /* Plumb PSPOLL and NULL template */
1771 cw1200_upload_pspoll(priv);
1772 cw1200_upload_null(priv);
1773 cw1200_upload_qosnull(priv);
1774 } else {
1775 return 0;
1776 }
1777
1778 memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
1779
1780 if (!priv->vif->p2p) {
1781 /* STATION mode */
1782 if (priv->bss_params.operational_rate_set & ~0xF) {
1783 pr_debug("[STA] STA has ERP rates\n");
1784 /* G or BG mode */
1785 arg.internalTxRate = (__ffs(
1786 priv->bss_params.operational_rate_set & ~0xF));
1787 } else {
1788 pr_debug("[STA] STA has non ERP rates\n");
1789 /* B only mode */
1790 arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1791 }
1792 arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1793 } else {
1794 /* P2P mode */
1795 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1796 arg.nonErpInternalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1797 }
1798
1799 pr_debug("[STA] BTCOEX_INFO MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
1800 priv->mode,
1801 arg.internalTxRate,
1802 arg.nonErpInternalTxRate);
1803
1804 ret = wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1805 &arg, sizeof(arg));
1806
1807 return ret;
1808}
1809
1810void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1811 struct ieee80211_vif *vif,
1812 struct ieee80211_bss_conf *info,
1813 u32 changed)
1814{
1815 struct cw1200_common *priv = dev->priv;
1816 bool do_join = false;
1817
1818 mutex_lock(&priv->conf_mutex);
1819
1820 pr_debug("BSS CHANGED: %08x\n", changed);
1821
1822 /* TODO: BSS_CHANGED_QOS */
1823 /* TODO: BSS_CHANGED_TXPOWER */
1824
1825 if (changed & BSS_CHANGED_ARP_FILTER) {
1826 struct wsm_mib_arp_ipv4_filter filter = {0};
1827 int i;
1828
1829 pr_debug("[STA] BSS_CHANGED_ARP_FILTER cnt: %d\n",
1830 info->arp_addr_cnt);
1831
1832 /* Currently only one IP address is supported by firmware.
1833 * In case of more IPs arp filtering will be disabled.
1834 */
1835 if (info->arp_addr_cnt > 0 &&
1836 info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
1837 for (i = 0; i < info->arp_addr_cnt; i++) {
1838 filter.ipv4addrs[i] = info->arp_addr_list[i];
1839 pr_debug("[STA] addr[%d]: 0x%X\n",
1840 i, filter.ipv4addrs[i]);
1841 }
1842 filter.enable = __cpu_to_le32(1);
1843 }
1844
1845 pr_debug("[STA] arp ip filter enable: %d\n",
1846 __le32_to_cpu(filter.enable));
1847
1848 wsm_set_arp_ipv4_filter(priv, &filter);
1849 }
1850
1851 if (changed &
1852 (BSS_CHANGED_BEACON |
1853 BSS_CHANGED_AP_PROBE_RESP |
1854 BSS_CHANGED_BSSID |
1855 BSS_CHANGED_SSID |
1856 BSS_CHANGED_IBSS)) {
1857 pr_debug("BSS_CHANGED_BEACON\n");
1858 priv->beacon_int = info->beacon_int;
1859 cw1200_update_beaconing(priv);
1860 cw1200_upload_beacon(priv);
1861 }
1862
1863 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1864 pr_debug("BSS_CHANGED_BEACON_ENABLED (%d)\n", info->enable_beacon);
1865
1866 if (priv->enable_beacon != info->enable_beacon) {
1867 cw1200_enable_beaconing(priv, info->enable_beacon);
1868 priv->enable_beacon = info->enable_beacon;
1869 }
1870 }
1871
1872 if (changed & BSS_CHANGED_BEACON_INT) {
1873 pr_debug("CHANGED_BEACON_INT\n");
1874 if (info->ibss_joined)
1875 do_join = true;
1876 else if (priv->join_status == CW1200_JOIN_STATUS_AP)
1877 cw1200_update_beaconing(priv);
1878 }
1879
1880 /* assoc/disassoc, or maybe AID changed */
1881 if (changed & BSS_CHANGED_ASSOC) {
1882 wsm_lock_tx(priv);
1883 priv->wep_default_key_id = -1;
1884 wsm_unlock_tx(priv);
1885 }
1886
1887 if (changed & BSS_CHANGED_BSSID) {
1888 pr_debug("BSS_CHANGED_BSSID\n");
1889 do_join = true;
1890 }
1891
1892 if (changed &
1893 (BSS_CHANGED_ASSOC |
1894 BSS_CHANGED_BSSID |
1895 BSS_CHANGED_IBSS |
1896 BSS_CHANGED_BASIC_RATES |
1897 BSS_CHANGED_HT)) {
1898 pr_debug("BSS_CHANGED_ASSOC\n");
1899 if (info->assoc) {
1900 if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) {
1901 ieee80211_connection_loss(vif);
1902 mutex_unlock(&priv->conf_mutex);
1903 return;
1904 } else if (priv->join_status == CW1200_JOIN_STATUS_PRE_STA) {
1905 priv->join_status = CW1200_JOIN_STATUS_STA;
1906 }
1907 } else {
1908 do_join = true;
1909 }
1910
1911 if (info->assoc || info->ibss_joined) {
1912 struct ieee80211_sta *sta = NULL;
1913 u32 val = 0;
1914
1915 if (info->dtim_period)
1916 priv->join_dtim_period = info->dtim_period;
1917 priv->beacon_int = info->beacon_int;
1918
1919 rcu_read_lock();
1920
1921 if (info->bssid && !info->ibss_joined)
1922 sta = ieee80211_find_sta(vif, info->bssid);
1923 if (sta) {
1924 priv->ht_info.ht_cap = sta->ht_cap;
1925 priv->bss_params.operational_rate_set =
1926 cw1200_rate_mask_to_wsm(priv,
1927 sta->supp_rates[priv->channel->band]);
1928 priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef);
1929 priv->ht_info.operation_mode = info->ht_operation_mode;
1930 } else {
1931 memset(&priv->ht_info, 0,
1932 sizeof(priv->ht_info));
1933 priv->bss_params.operational_rate_set = -1;
1934 }
1935 rcu_read_unlock();
1936
1937 /* Non Greenfield stations present */
1938 if (priv->ht_info.operation_mode &
1939 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1940 val |= WSM_NON_GREENFIELD_STA_PRESENT;
1941
1942 /* Set HT protection method */
1943 val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2;
1944
1945 /* TODO:
1946 * STBC_param.dual_cts
1947 * STBC_param.LSIG_TXOP_FILL
1948 */
1949
1950 val = cpu_to_le32(val);
1951 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1952 &val, sizeof(val));
1953
1954 priv->association_mode.greenfield =
1955 cw1200_ht_greenfield(&priv->ht_info);
1956 priv->association_mode.flags =
1957 WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES |
1958 WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE |
1959 WSM_ASSOCIATION_MODE_USE_HT_MODE |
1960 WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET |
1961 WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING;
1962 priv->association_mode.preamble =
1963 info->use_short_preamble ?
1964 WSM_JOIN_PREAMBLE_SHORT :
1965 WSM_JOIN_PREAMBLE_LONG;
1966 priv->association_mode.basic_rate_set = __cpu_to_le32(
1967 cw1200_rate_mask_to_wsm(priv,
1968 info->basic_rates));
1969 priv->association_mode.mpdu_start_spacing =
1970 cw1200_ht_ampdu_density(&priv->ht_info);
1971
1972 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1973 cancel_work_sync(&priv->unjoin_work);
1974
1975 priv->bss_params.beacon_lost_count = priv->cqm_beacon_loss_count;
1976 priv->bss_params.aid = info->aid;
1977
1978 if (priv->join_dtim_period < 1)
1979 priv->join_dtim_period = 1;
1980
1981 pr_debug("[STA] DTIM %d, interval: %d\n",
1982 priv->join_dtim_period, priv->beacon_int);
1983 pr_debug("[STA] Preamble: %d, Greenfield: %d, Aid: %d, Rates: 0x%.8X, Basic: 0x%.8X\n",
1984 priv->association_mode.preamble,
1985 priv->association_mode.greenfield,
1986 priv->bss_params.aid,
1987 priv->bss_params.operational_rate_set,
1988 priv->association_mode.basic_rate_set);
1989 wsm_set_association_mode(priv, &priv->association_mode);
1990
1991 if (!info->ibss_joined) {
1992 wsm_keep_alive_period(priv, 30 /* sec */);
1993 wsm_set_bss_params(priv, &priv->bss_params);
1994 priv->setbssparams_done = true;
1995 cw1200_set_beacon_wakeup_period_work(&priv->set_beacon_wakeup_period_work);
1996 cw1200_set_pm(priv, &priv->powersave_mode);
1997 }
1998 if (priv->vif->p2p) {
1999 pr_debug("[STA] Setting p2p powersave configuration.\n");
2000 wsm_set_p2p_ps_modeinfo(priv,
2001 &priv->p2p_ps_modeinfo);
2002 }
2003 if (priv->bt_present)
2004 cw1200_set_btcoexinfo(priv);
2005 } else {
2006 memset(&priv->association_mode, 0,
2007 sizeof(priv->association_mode));
2008 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
2009 }
2010 }
2011
2012 /* ERP Protection */
2013 if (changed & (BSS_CHANGED_ASSOC |
2014 BSS_CHANGED_ERP_CTS_PROT |
2015 BSS_CHANGED_ERP_PREAMBLE)) {
2016 u32 prev_erp_info = priv->erp_info;
2017 if (info->use_cts_prot)
2018 priv->erp_info |= WLAN_ERP_USE_PROTECTION;
2019 else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
2020 priv->erp_info &= ~WLAN_ERP_USE_PROTECTION;
2021
2022 if (info->use_short_preamble)
2023 priv->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
2024 else
2025 priv->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
2026
2027 pr_debug("[STA] ERP Protection: %x\n", priv->erp_info);
2028
2029 if (prev_erp_info != priv->erp_info)
2030 queue_work(priv->workqueue, &priv->set_cts_work);
2031 }
2032
2033 /* ERP Slottime */
2034 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) {
2035 __le32 slot_time = info->use_short_slot ?
2036 __cpu_to_le32(9) : __cpu_to_le32(20);
2037 pr_debug("[STA] Slot time: %d us.\n",
2038 __le32_to_cpu(slot_time));
2039 wsm_write_mib(priv, WSM_MIB_ID_DOT11_SLOT_TIME,
2040 &slot_time, sizeof(slot_time));
2041 }
2042
2043 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
2044 struct wsm_rcpi_rssi_threshold threshold = {
2045 .rollingAverageCount = 8,
2046 };
2047 pr_debug("[CQM] RSSI threshold subscribe: %d +- %d\n",
2048 info->cqm_rssi_thold, info->cqm_rssi_hyst);
2049 priv->cqm_rssi_thold = info->cqm_rssi_thold;
2050 priv->cqm_rssi_hyst = info->cqm_rssi_hyst;
2051
2052 if (info->cqm_rssi_thold || info->cqm_rssi_hyst) {
2053 /* RSSI subscription enabled */
2054 /* TODO: It's not a correct way of setting threshold.
2055 * Upper and lower must be set equal here and adjusted
2056 * in callback. However current implementation is much
2057 * more relaible and stable.
2058 */
2059
2060 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
2061 * RSSI = RCPI / 2 - 110
2062 */
2063 if (priv->cqm_use_rssi) {
2064 threshold.upperThreshold =
2065 info->cqm_rssi_thold + info->cqm_rssi_hyst;
2066 threshold.lowerThreshold =
2067 info->cqm_rssi_thold;
2068 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2069 } else {
2070 threshold.upperThreshold = (info->cqm_rssi_thold + info->cqm_rssi_hyst + 110) * 2;
2071 threshold.lowerThreshold = (info->cqm_rssi_thold + 110) * 2;
2072 }
2073 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_THRESHOLD_ENABLE;
2074 } else {
2075 /* There is a bug in FW, see sta.c. We have to enable
2076 * dummy subscription to get correct RSSI values.
2077 */
2078 threshold.rssiRcpiMode |=
2079 WSM_RCPI_RSSI_THRESHOLD_ENABLE |
2080 WSM_RCPI_RSSI_DONT_USE_UPPER |
2081 WSM_RCPI_RSSI_DONT_USE_LOWER;
2082 if (priv->cqm_use_rssi)
2083 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2084 }
2085 wsm_set_rcpi_rssi_threshold(priv, &threshold);
2086 }
2087 mutex_unlock(&priv->conf_mutex);
2088
2089 if (do_join) {
2090 wsm_lock_tx(priv);
2091 cw1200_do_join(priv); /* Will unlock it for us */
2092 }
2093}
2094
2095void cw1200_multicast_start_work(struct work_struct *work)
2096{
2097 struct cw1200_common *priv =
2098 container_of(work, struct cw1200_common, multicast_start_work);
2099 long tmo = priv->join_dtim_period *
2100 (priv->beacon_int + 20) * HZ / 1024;
2101
2102 cancel_work_sync(&priv->multicast_stop_work);
2103
2104 if (!priv->aid0_bit_set) {
2105 wsm_lock_tx(priv);
2106 cw1200_set_tim_impl(priv, true);
2107 priv->aid0_bit_set = true;
2108 mod_timer(&priv->mcast_timeout, jiffies + tmo);
2109 wsm_unlock_tx(priv);
2110 }
2111}
2112
2113void cw1200_multicast_stop_work(struct work_struct *work)
2114{
2115 struct cw1200_common *priv =
2116 container_of(work, struct cw1200_common, multicast_stop_work);
2117
2118 if (priv->aid0_bit_set) {
2119 del_timer_sync(&priv->mcast_timeout);
2120 wsm_lock_tx(priv);
2121 priv->aid0_bit_set = false;
2122 cw1200_set_tim_impl(priv, false);
2123 wsm_unlock_tx(priv);
2124 }
2125}
2126
2127void cw1200_mcast_timeout(unsigned long arg)
2128{
2129 struct cw1200_common *priv =
2130 (struct cw1200_common *)arg;
2131
2132 wiphy_warn(priv->hw->wiphy,
2133 "Multicast delivery timeout.\n");
2134 spin_lock_bh(&priv->ps_state_lock);
2135 priv->tx_multicast = priv->aid0_bit_set &&
2136 priv->buffered_multicasts;
2137 if (priv->tx_multicast)
2138 cw1200_bh_wakeup(priv);
2139 spin_unlock_bh(&priv->ps_state_lock);
2140}
2141
2142int cw1200_ampdu_action(struct ieee80211_hw *hw,
2143 struct ieee80211_vif *vif,
2144 enum ieee80211_ampdu_mlme_action action,
2145 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
2146 u8 buf_size)
2147{
2148 /* Aggregation is implemented fully in firmware,
2149 * including block ack negotiation. Do not allow
2150 * mac80211 stack to do anything: it interferes with
2151 * the firmware.
2152 */
2153
2154 /* Note that we still need this function stubbed. */
2155 return -ENOTSUPP;
2156}
2157
2158/* ******************************************************************** */
2159/* WSM callback */
2160void cw1200_suspend_resume(struct cw1200_common *priv,
2161 struct wsm_suspend_resume *arg)
2162{
2163 pr_debug("[AP] %s: %s\n",
2164 arg->stop ? "stop" : "start",
2165 arg->multicast ? "broadcast" : "unicast");
2166
2167 if (arg->multicast) {
2168 bool cancel_tmo = false;
2169 spin_lock_bh(&priv->ps_state_lock);
2170 if (arg->stop) {
2171 priv->tx_multicast = false;
2172 } else {
2173 /* Firmware sends this indication every DTIM if there
2174 * is a STA in powersave connected. There is no reason
2175 * to suspend, following wakeup will consume much more
2176 * power than it could be saved.
2177 */
2178 cw1200_pm_stay_awake(&priv->pm_state,
2179 priv->join_dtim_period *
2180 (priv->beacon_int + 20) * HZ / 1024);
2181 priv->tx_multicast = (priv->aid0_bit_set &&
2182 priv->buffered_multicasts);
2183 if (priv->tx_multicast) {
2184 cancel_tmo = true;
2185 cw1200_bh_wakeup(priv);
2186 }
2187 }
2188 spin_unlock_bh(&priv->ps_state_lock);
2189 if (cancel_tmo)
2190 del_timer_sync(&priv->mcast_timeout);
2191 } else {
2192 spin_lock_bh(&priv->ps_state_lock);
2193 cw1200_ps_notify(priv, arg->link_id, arg->stop);
2194 spin_unlock_bh(&priv->ps_state_lock);
2195 if (!arg->stop)
2196 cw1200_bh_wakeup(priv);
2197 }
2198 return;
2199}
2200
2201/* ******************************************************************** */
2202/* AP privates */
2203
2204static int cw1200_upload_beacon(struct cw1200_common *priv)
2205{
2206 int ret = 0;
2207 struct ieee80211_mgmt *mgmt;
2208 struct wsm_template_frame frame = {
2209 .frame_type = WSM_FRAME_TYPE_BEACON,
2210 };
2211
2212 u16 tim_offset;
2213 u16 tim_len;
2214
2215 if (priv->mode == NL80211_IFTYPE_STATION ||
2216 priv->mode == NL80211_IFTYPE_MONITOR ||
2217 priv->mode == NL80211_IFTYPE_UNSPECIFIED)
2218 goto done;
2219
2220 if (priv->vif->p2p)
2221 frame.rate = WSM_TRANSMIT_RATE_6;
2222
2223 frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
2224 &tim_offset, &tim_len);
2225 if (!frame.skb)
2226 return -ENOMEM;
2227
2228 ret = wsm_set_template_frame(priv, &frame);
2229
2230 if (ret)
2231 goto done;
2232
2233 /* TODO: Distill probe resp; remove TIM
2234 * and any other beacon-specific IEs
2235 */
2236 mgmt = (void *)frame.skb->data;
2237 mgmt->frame_control =
2238 __cpu_to_le16(IEEE80211_FTYPE_MGMT |
2239 IEEE80211_STYPE_PROBE_RESP);
2240
2241 frame.frame_type = WSM_FRAME_TYPE_PROBE_RESPONSE;
2242 if (priv->vif->p2p) {
2243 ret = wsm_set_probe_responder(priv, true);
2244 } else {
2245 ret = wsm_set_template_frame(priv, &frame);
2246 wsm_set_probe_responder(priv, false);
2247 }
2248
2249done:
2250 dev_kfree_skb(frame.skb);
2251
2252 return ret;
2253}
2254
2255static int cw1200_upload_pspoll(struct cw1200_common *priv)
2256{
2257 int ret = 0;
2258 struct wsm_template_frame frame = {
2259 .frame_type = WSM_FRAME_TYPE_PS_POLL,
2260 .rate = 0xFF,
2261 };
2262
2263
2264 frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
2265 if (!frame.skb)
2266 return -ENOMEM;
2267
2268 ret = wsm_set_template_frame(priv, &frame);
2269
2270 dev_kfree_skb(frame.skb);
2271
2272 return ret;
2273}
2274
2275static int cw1200_upload_null(struct cw1200_common *priv)
2276{
2277 int ret = 0;
2278 struct wsm_template_frame frame = {
2279 .frame_type = WSM_FRAME_TYPE_NULL,
2280 .rate = 0xFF,
2281 };
2282
2283 frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
2284 if (!frame.skb)
2285 return -ENOMEM;
2286
2287 ret = wsm_set_template_frame(priv, &frame);
2288
2289 dev_kfree_skb(frame.skb);
2290
2291 return ret;
2292}
2293
2294static int cw1200_upload_qosnull(struct cw1200_common *priv)
2295{
2296 int ret = 0;
2297 /* TODO: This needs to be implemented
2298
2299 struct wsm_template_frame frame = {
2300 .frame_type = WSM_FRAME_TYPE_QOS_NULL,
2301 .rate = 0xFF,
2302 };
2303
2304 frame.skb = ieee80211_qosnullfunc_get(priv->hw, priv->vif);
2305 if (!frame.skb)
2306 return -ENOMEM;
2307
2308 ret = wsm_set_template_frame(priv, &frame);
2309
2310 dev_kfree_skb(frame.skb);
2311
2312 */
2313 return ret;
2314}
2315
2316static int cw1200_enable_beaconing(struct cw1200_common *priv,
2317 bool enable)
2318{
2319 struct wsm_beacon_transmit transmit = {
2320 .enable_beaconing = enable,
2321 };
2322
2323 return wsm_beacon_transmit(priv, &transmit);
2324}
2325
2326static int cw1200_start_ap(struct cw1200_common *priv)
2327{
2328 int ret;
2329 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2330 struct wsm_start start = {
2331 .mode = priv->vif->p2p ?
2332 WSM_START_MODE_P2P_GO : WSM_START_MODE_AP,
2333 .band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
2334 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2335 .channel_number = priv->channel->hw_value,
2336 .beacon_interval = conf->beacon_int,
2337 .dtim_period = conf->dtim_period,
2338 .preamble = conf->use_short_preamble ?
2339 WSM_JOIN_PREAMBLE_SHORT :
2340 WSM_JOIN_PREAMBLE_LONG,
2341 .probe_delay = 100,
2342 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
2343 conf->basic_rates),
2344 };
2345 struct wsm_operational_mode mode = {
2346 .power_mode = cw1200_power_mode,
2347 .disable_more_flag_usage = true,
2348 };
2349
2350 memset(start.ssid, 0, sizeof(start.ssid));
2351 if (!conf->hidden_ssid) {
2352 start.ssid_len = conf->ssid_len;
2353 memcpy(start.ssid, conf->ssid, start.ssid_len);
2354 }
2355
2356 priv->beacon_int = conf->beacon_int;
2357 priv->join_dtim_period = conf->dtim_period;
2358
2359 memset(&priv->link_id_db, 0, sizeof(priv->link_id_db));
2360
2361 pr_debug("[AP] ch: %d(%d), bcn: %d(%d), brt: 0x%.8X, ssid: %.*s.\n",
2362 start.channel_number, start.band,
2363 start.beacon_interval, start.dtim_period,
2364 start.basic_rate_set,
2365 start.ssid_len, start.ssid);
2366 ret = wsm_start(priv, &start);
2367 if (!ret)
2368 ret = cw1200_upload_keys(priv);
2369 if (!ret && priv->vif->p2p) {
2370 pr_debug("[AP] Setting p2p powersave configuration.\n");
2371 wsm_set_p2p_ps_modeinfo(priv, &priv->p2p_ps_modeinfo);
2372 }
2373 if (!ret) {
2374 wsm_set_block_ack_policy(priv, 0, 0);
2375 priv->join_status = CW1200_JOIN_STATUS_AP;
2376 cw1200_update_filtering(priv);
2377 }
2378 wsm_set_operational_mode(priv, &mode);
2379 return ret;
2380}
2381
2382static int cw1200_update_beaconing(struct cw1200_common *priv)
2383{
2384 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2385 struct wsm_reset reset = {
2386 .link_id = 0,
2387 .reset_statistics = true,
2388 };
2389
2390 if (priv->mode == NL80211_IFTYPE_AP) {
2391 /* TODO: check if changed channel, band */
2392 if (priv->join_status != CW1200_JOIN_STATUS_AP ||
2393 priv->beacon_int != conf->beacon_int) {
2394 pr_debug("ap restarting\n");
2395 wsm_lock_tx(priv);
2396 if (priv->join_status != CW1200_JOIN_STATUS_PASSIVE)
2397 wsm_reset(priv, &reset);
2398 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
2399 cw1200_start_ap(priv);
2400 wsm_unlock_tx(priv);
2401 } else
2402 pr_debug("ap started join_status: %d\n",
2403 priv->join_status);
2404 }
2405 return 0;
2406}
diff --git a/drivers/net/wireless/cw1200/sta.h b/drivers/net/wireless/cw1200/sta.h
new file mode 100644
index 000000000000..35babb62cc6a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.h
@@ -0,0 +1,123 @@
1/*
2 * Mac80211 STA interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef STA_H_INCLUDED
13#define STA_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18int cw1200_start(struct ieee80211_hw *dev);
19void cw1200_stop(struct ieee80211_hw *dev);
20int cw1200_add_interface(struct ieee80211_hw *dev,
21 struct ieee80211_vif *vif);
22void cw1200_remove_interface(struct ieee80211_hw *dev,
23 struct ieee80211_vif *vif);
24int cw1200_change_interface(struct ieee80211_hw *dev,
25 struct ieee80211_vif *vif,
26 enum nl80211_iftype new_type,
27 bool p2p);
28int cw1200_config(struct ieee80211_hw *dev, u32 changed);
29void cw1200_configure_filter(struct ieee80211_hw *dev,
30 unsigned int changed_flags,
31 unsigned int *total_flags,
32 u64 multicast);
33int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
34 u16 queue, const struct ieee80211_tx_queue_params *params);
35int cw1200_get_stats(struct ieee80211_hw *dev,
36 struct ieee80211_low_level_stats *stats);
37int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
38 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
39 struct ieee80211_key_conf *key);
40
41int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
42
43void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
44
45u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
46 struct netdev_hw_addr_list *mc_list);
47
48int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
49
50/* ******************************************************************** */
51/* WSM callbacks */
52
53void cw1200_join_complete_cb(struct cw1200_common *priv,
54 struct wsm_join_complete *arg);
55
56/* ******************************************************************** */
57/* WSM events */
58
59void cw1200_free_event_queue(struct cw1200_common *priv);
60void cw1200_event_handler(struct work_struct *work);
61void cw1200_bss_loss_work(struct work_struct *work);
62void cw1200_bss_params_work(struct work_struct *work);
63void cw1200_keep_alive_work(struct work_struct *work);
64void cw1200_tx_failure_work(struct work_struct *work);
65
66void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, int init, int good,
67 int bad);
68static inline void cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
69 int init, int good, int bad)
70{
71 spin_lock(&priv->bss_loss_lock);
72 __cw1200_cqm_bssloss_sm(priv, init, good, bad);
73 spin_unlock(&priv->bss_loss_lock);
74}
75
76/* ******************************************************************** */
77/* Internal API */
78
79int cw1200_setup_mac(struct cw1200_common *priv);
80void cw1200_join_timeout(struct work_struct *work);
81void cw1200_unjoin_work(struct work_struct *work);
82void cw1200_join_complete_work(struct work_struct *work);
83void cw1200_wep_key_work(struct work_struct *work);
84void cw1200_update_listening(struct cw1200_common *priv, bool enabled);
85void cw1200_update_filtering(struct cw1200_common *priv);
86void cw1200_update_filtering_work(struct work_struct *work);
87void cw1200_set_beacon_wakeup_period_work(struct work_struct *work);
88int cw1200_enable_listening(struct cw1200_common *priv);
89int cw1200_disable_listening(struct cw1200_common *priv);
90int cw1200_set_uapsd_param(struct cw1200_common *priv,
91 const struct wsm_edca_params *arg);
92void cw1200_ba_work(struct work_struct *work);
93void cw1200_ba_timer(unsigned long arg);
94
95/* AP stuffs */
96int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
97 bool set);
98int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
99 struct ieee80211_sta *sta);
100int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
101 struct ieee80211_sta *sta);
102void cw1200_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
103 enum sta_notify_cmd notify_cmd,
104 struct ieee80211_sta *sta);
105void cw1200_bss_info_changed(struct ieee80211_hw *dev,
106 struct ieee80211_vif *vif,
107 struct ieee80211_bss_conf *info,
108 u32 changed);
109int cw1200_ampdu_action(struct ieee80211_hw *hw,
110 struct ieee80211_vif *vif,
111 enum ieee80211_ampdu_mlme_action action,
112 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
113 u8 buf_size);
114
115void cw1200_suspend_resume(struct cw1200_common *priv,
116 struct wsm_suspend_resume *arg);
117void cw1200_set_tim_work(struct work_struct *work);
118void cw1200_set_cts_work(struct work_struct *work);
119void cw1200_multicast_start_work(struct work_struct *work);
120void cw1200_multicast_stop_work(struct work_struct *work);
121void cw1200_mcast_timeout(unsigned long arg);
122
123#endif
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
new file mode 100644
index 000000000000..0e40890e1993
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -0,0 +1,1474 @@
1/*
2 * Datapath implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/etherdevice.h>
14#include <linux/skbuff.h>
15
16#include "cw1200.h"
17#include "wsm.h"
18#include "bh.h"
19#include "sta.h"
20#include "debug.h"
21
22#define CW1200_INVALID_RATE_ID (0xFF)
23
24static int cw1200_handle_action_rx(struct cw1200_common *priv,
25 struct sk_buff *skb);
26static const struct ieee80211_rate *
27cw1200_get_tx_rate(const struct cw1200_common *priv,
28 const struct ieee80211_tx_rate *rate);
29
30/* ******************************************************************** */
31/* TX queue lock / unlock */
32
33static inline void cw1200_tx_queues_lock(struct cw1200_common *priv)
34{
35 int i;
36 for (i = 0; i < 4; ++i)
37 cw1200_queue_lock(&priv->tx_queue[i]);
38}
39
40static inline void cw1200_tx_queues_unlock(struct cw1200_common *priv)
41{
42 int i;
43 for (i = 0; i < 4; ++i)
44 cw1200_queue_unlock(&priv->tx_queue[i]);
45}
46
47/* ******************************************************************** */
48/* TX policy cache implementation */
49
50static void tx_policy_dump(struct tx_policy *policy)
51{
52 pr_debug("[TX policy] %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X: %d\n",
53 policy->raw[0] & 0x0F, policy->raw[0] >> 4,
54 policy->raw[1] & 0x0F, policy->raw[1] >> 4,
55 policy->raw[2] & 0x0F, policy->raw[2] >> 4,
56 policy->raw[3] & 0x0F, policy->raw[3] >> 4,
57 policy->raw[4] & 0x0F, policy->raw[4] >> 4,
58 policy->raw[5] & 0x0F, policy->raw[5] >> 4,
59 policy->raw[6] & 0x0F, policy->raw[6] >> 4,
60 policy->raw[7] & 0x0F, policy->raw[7] >> 4,
61 policy->raw[8] & 0x0F, policy->raw[8] >> 4,
62 policy->raw[9] & 0x0F, policy->raw[9] >> 4,
63 policy->raw[10] & 0x0F, policy->raw[10] >> 4,
64 policy->raw[11] & 0x0F, policy->raw[11] >> 4,
65 policy->defined);
66}
67
68static void tx_policy_build(const struct cw1200_common *priv,
69 /* [out] */ struct tx_policy *policy,
70 struct ieee80211_tx_rate *rates, size_t count)
71{
72 int i, j;
73 unsigned limit = priv->short_frame_max_tx_count;
74 unsigned total = 0;
75 BUG_ON(rates[0].idx < 0);
76 memset(policy, 0, sizeof(*policy));
77
78 /* minstrel is buggy a little bit, so distille
79 * incoming rates first. */
80
81 /* Sort rates in descending order. */
82 for (i = 1; i < count; ++i) {
83 if (rates[i].idx < 0) {
84 count = i;
85 break;
86 }
87 if (rates[i].idx > rates[i - 1].idx) {
88 struct ieee80211_tx_rate tmp = rates[i - 1];
89 rates[i - 1] = rates[i];
90 rates[i] = tmp;
91 }
92 }
93
94 /* Eliminate duplicates. */
95 total = rates[0].count;
96 for (i = 0, j = 1; j < count; ++j) {
97 if (rates[j].idx == rates[i].idx) {
98 rates[i].count += rates[j].count;
99 } else if (rates[j].idx > rates[i].idx) {
100 break;
101 } else {
102 ++i;
103 if (i != j)
104 rates[i] = rates[j];
105 }
106 total += rates[j].count;
107 }
108 count = i + 1;
109
110 /* Re-fill policy trying to keep every requested rate and with
111 * respect to the global max tx retransmission count. */
112 if (limit < count)
113 limit = count;
114 if (total > limit) {
115 for (i = 0; i < count; ++i) {
116 int left = count - i - 1;
117 if (rates[i].count > limit - left)
118 rates[i].count = limit - left;
119 limit -= rates[i].count;
120 }
121 }
122
123 /* HACK!!! Device has problems (at least) switching from
124 * 54Mbps CTS to 1Mbps. This switch takes enormous amount
125 * of time (100-200 ms), leading to valuable throughput drop.
126 * As a workaround, additional g-rates are injected to the
127 * policy.
128 */
129 if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
130 rates[0].idx > 4 && rates[0].count > 2 &&
131 rates[1].idx < 2) {
132 /* ">> 1" is an equivalent of "/ 2", but faster */
133 int mid_rate = (rates[0].idx + 4) >> 1;
134
135 /* Decrease number of retries for the initial rate */
136 rates[0].count -= 2;
137
138 if (mid_rate != 4) {
139 /* Keep fallback rate at 1Mbps. */
140 rates[3] = rates[1];
141
142 /* Inject 1 transmission on lowest g-rate */
143 rates[2].idx = 4;
144 rates[2].count = 1;
145 rates[2].flags = rates[1].flags;
146
147 /* Inject 1 transmission on mid-rate */
148 rates[1].idx = mid_rate;
149 rates[1].count = 1;
150
151 /* Fallback to 1 Mbps is a really bad thing,
152 * so let's try to increase probability of
153 * successful transmission on the lowest g rate
154 * even more */
155 if (rates[0].count >= 3) {
156 --rates[0].count;
157 ++rates[2].count;
158 }
159
160 /* Adjust amount of rates defined */
161 count += 2;
162 } else {
163 /* Keep fallback rate at 1Mbps. */
164 rates[2] = rates[1];
165
166 /* Inject 2 transmissions on lowest g-rate */
167 rates[1].idx = 4;
168 rates[1].count = 2;
169
170 /* Adjust amount of rates defined */
171 count += 1;
172 }
173 }
174
175 policy->defined = cw1200_get_tx_rate(priv, &rates[0])->hw_value + 1;
176
177 for (i = 0; i < count; ++i) {
178 register unsigned rateid, off, shift, retries;
179
180 rateid = cw1200_get_tx_rate(priv, &rates[i])->hw_value;
181 off = rateid >> 3; /* eq. rateid / 8 */
182 shift = (rateid & 0x07) << 2; /* eq. (rateid % 8) * 4 */
183
184 retries = rates[i].count;
185 if (retries > 0x0F) {
186 rates[i].count = 0x0f;
187 retries = 0x0F;
188 }
189 policy->tbl[off] |= __cpu_to_le32(retries << shift);
190 policy->retry_count += retries;
191 }
192
193 pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
194 count,
195 rates[0].idx, rates[0].count,
196 rates[1].idx, rates[1].count,
197 rates[2].idx, rates[2].count,
198 rates[3].idx, rates[3].count,
199 rates[4].idx, rates[4].count);
200}
201
202static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
203 const struct tx_policy *cached)
204{
205 size_t count = wanted->defined >> 1;
206 if (wanted->defined > cached->defined)
207 return false;
208 if (count) {
209 if (memcmp(wanted->raw, cached->raw, count))
210 return false;
211 }
212 if (wanted->defined & 1) {
213 if ((wanted->raw[count] & 0x0F) != (cached->raw[count] & 0x0F))
214 return false;
215 }
216 return true;
217}
218
219static int tx_policy_find(struct tx_policy_cache *cache,
220 const struct tx_policy *wanted)
221{
222 /* O(n) complexity. Not so good, but there's only 8 entries in
223 * the cache.
224 * Also lru helps to reduce search time. */
225 struct tx_policy_cache_entry *it;
226 /* First search for policy in "used" list */
227 list_for_each_entry(it, &cache->used, link) {
228 if (tx_policy_is_equal(wanted, &it->policy))
229 return it - cache->cache;
230 }
231 /* Then - in "free list" */
232 list_for_each_entry(it, &cache->free, link) {
233 if (tx_policy_is_equal(wanted, &it->policy))
234 return it - cache->cache;
235 }
236 return -1;
237}
238
239static inline void tx_policy_use(struct tx_policy_cache *cache,
240 struct tx_policy_cache_entry *entry)
241{
242 ++entry->policy.usage_count;
243 list_move(&entry->link, &cache->used);
244}
245
246static inline int tx_policy_release(struct tx_policy_cache *cache,
247 struct tx_policy_cache_entry *entry)
248{
249 int ret = --entry->policy.usage_count;
250 if (!ret)
251 list_move(&entry->link, &cache->free);
252 return ret;
253}
254
255void tx_policy_clean(struct cw1200_common *priv)
256{
257 int idx, locked;
258 struct tx_policy_cache *cache = &priv->tx_policy_cache;
259 struct tx_policy_cache_entry *entry;
260
261 cw1200_tx_queues_lock(priv);
262 spin_lock_bh(&cache->lock);
263 locked = list_empty(&cache->free);
264
265 for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) {
266 entry = &cache->cache[idx];
267 /* Policy usage count should be 0 at this time as all queues
268 should be empty */
269 if (WARN_ON(entry->policy.usage_count)) {
270 entry->policy.usage_count = 0;
271 list_move(&entry->link, &cache->free);
272 }
273 memset(&entry->policy, 0, sizeof(entry->policy));
274 }
275 if (locked)
276 cw1200_tx_queues_unlock(priv);
277
278 cw1200_tx_queues_unlock(priv);
279 spin_unlock_bh(&cache->lock);
280}
281
282/* ******************************************************************** */
283/* External TX policy cache API */
284
285void tx_policy_init(struct cw1200_common *priv)
286{
287 struct tx_policy_cache *cache = &priv->tx_policy_cache;
288 int i;
289
290 memset(cache, 0, sizeof(*cache));
291
292 spin_lock_init(&cache->lock);
293 INIT_LIST_HEAD(&cache->used);
294 INIT_LIST_HEAD(&cache->free);
295
296 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i)
297 list_add(&cache->cache[i].link, &cache->free);
298}
299
300static int tx_policy_get(struct cw1200_common *priv,
301 struct ieee80211_tx_rate *rates,
302 size_t count, bool *renew)
303{
304 int idx;
305 struct tx_policy_cache *cache = &priv->tx_policy_cache;
306 struct tx_policy wanted;
307
308 tx_policy_build(priv, &wanted, rates, count);
309
310 spin_lock_bh(&cache->lock);
311 if (WARN_ON_ONCE(list_empty(&cache->free))) {
312 spin_unlock_bh(&cache->lock);
313 return CW1200_INVALID_RATE_ID;
314 }
315 idx = tx_policy_find(cache, &wanted);
316 if (idx >= 0) {
317 pr_debug("[TX policy] Used TX policy: %d\n", idx);
318 *renew = false;
319 } else {
320 struct tx_policy_cache_entry *entry;
321 *renew = true;
322 /* If policy is not found create a new one
323 * using the oldest entry in "free" list */
324 entry = list_entry(cache->free.prev,
325 struct tx_policy_cache_entry, link);
326 entry->policy = wanted;
327 idx = entry - cache->cache;
328 pr_debug("[TX policy] New TX policy: %d\n", idx);
329 tx_policy_dump(&entry->policy);
330 }
331 tx_policy_use(cache, &cache->cache[idx]);
332 if (list_empty(&cache->free)) {
333 /* Lock TX queues. */
334 cw1200_tx_queues_lock(priv);
335 }
336 spin_unlock_bh(&cache->lock);
337 return idx;
338}
339
340static void tx_policy_put(struct cw1200_common *priv, int idx)
341{
342 int usage, locked;
343 struct tx_policy_cache *cache = &priv->tx_policy_cache;
344
345 spin_lock_bh(&cache->lock);
346 locked = list_empty(&cache->free);
347 usage = tx_policy_release(cache, &cache->cache[idx]);
348 if (locked && !usage) {
349 /* Unlock TX queues. */
350 cw1200_tx_queues_unlock(priv);
351 }
352 spin_unlock_bh(&cache->lock);
353}
354
355static int tx_policy_upload(struct cw1200_common *priv)
356{
357 struct tx_policy_cache *cache = &priv->tx_policy_cache;
358 int i;
359 struct wsm_set_tx_rate_retry_policy arg = {
360 .num = 0,
361 };
362 spin_lock_bh(&cache->lock);
363
364 /* Upload only modified entries. */
365 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i) {
366 struct tx_policy *src = &cache->cache[i].policy;
367 if (src->retry_count && !src->uploaded) {
368 struct wsm_tx_rate_retry_policy *dst =
369 &arg.tbl[arg.num];
370 dst->index = i;
371 dst->short_retries = priv->short_frame_max_tx_count;
372 dst->long_retries = priv->long_frame_max_tx_count;
373
374 dst->flags = WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED |
375 WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT;
376 memcpy(dst->rate_count_indices, src->tbl,
377 sizeof(dst->rate_count_indices));
378 src->uploaded = 1;
379 ++arg.num;
380 }
381 }
382 spin_unlock_bh(&cache->lock);
383 cw1200_debug_tx_cache_miss(priv);
384 pr_debug("[TX policy] Upload %d policies\n", arg.num);
385 return wsm_set_tx_rate_retry_policy(priv, &arg);
386}
387
388void tx_policy_upload_work(struct work_struct *work)
389{
390 struct cw1200_common *priv =
391 container_of(work, struct cw1200_common, tx_policy_upload_work);
392
393 pr_debug("[TX] TX policy upload.\n");
394 tx_policy_upload(priv);
395
396 wsm_unlock_tx(priv);
397 cw1200_tx_queues_unlock(priv);
398}
399
400/* ******************************************************************** */
401/* cw1200 TX implementation */
402
403struct cw1200_txinfo {
404 struct sk_buff *skb;
405 unsigned queue;
406 struct ieee80211_tx_info *tx_info;
407 const struct ieee80211_rate *rate;
408 struct ieee80211_hdr *hdr;
409 size_t hdrlen;
410 const u8 *da;
411 struct cw1200_sta_priv *sta_priv;
412 struct ieee80211_sta *sta;
413 struct cw1200_txpriv txpriv;
414};
415
416u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv, u32 rates)
417{
418 u32 ret = 0;
419 int i;
420 for (i = 0; i < 32; ++i) {
421 if (rates & BIT(i))
422 ret |= BIT(priv->rates[i].hw_value);
423 }
424 return ret;
425}
426
427static const struct ieee80211_rate *
428cw1200_get_tx_rate(const struct cw1200_common *priv,
429 const struct ieee80211_tx_rate *rate)
430{
431 if (rate->idx < 0)
432 return NULL;
433 if (rate->flags & IEEE80211_TX_RC_MCS)
434 return &priv->mcs_rates[rate->idx];
435 return &priv->hw->wiphy->bands[priv->channel->band]->
436 bitrates[rate->idx];
437}
438
439static int
440cw1200_tx_h_calc_link_ids(struct cw1200_common *priv,
441 struct cw1200_txinfo *t)
442{
443 if (t->sta && t->sta_priv->link_id)
444 t->txpriv.raw_link_id =
445 t->txpriv.link_id =
446 t->sta_priv->link_id;
447 else if (priv->mode != NL80211_IFTYPE_AP)
448 t->txpriv.raw_link_id =
449 t->txpriv.link_id = 0;
450 else if (is_multicast_ether_addr(t->da)) {
451 if (priv->enable_beacon) {
452 t->txpriv.raw_link_id = 0;
453 t->txpriv.link_id = CW1200_LINK_ID_AFTER_DTIM;
454 } else {
455 t->txpriv.raw_link_id = 0;
456 t->txpriv.link_id = 0;
457 }
458 } else {
459 t->txpriv.link_id = cw1200_find_link_id(priv, t->da);
460 if (!t->txpriv.link_id)
461 t->txpriv.link_id = cw1200_alloc_link_id(priv, t->da);
462 if (!t->txpriv.link_id) {
463 wiphy_err(priv->hw->wiphy,
464 "No more link IDs available.\n");
465 return -ENOENT;
466 }
467 t->txpriv.raw_link_id = t->txpriv.link_id;
468 }
469 if (t->txpriv.raw_link_id)
470 priv->link_id_db[t->txpriv.raw_link_id - 1].timestamp =
471 jiffies;
472 if (t->sta && (t->sta->uapsd_queues & BIT(t->queue)))
473 t->txpriv.link_id = CW1200_LINK_ID_UAPSD;
474 return 0;
475}
476
477static void
478cw1200_tx_h_pm(struct cw1200_common *priv,
479 struct cw1200_txinfo *t)
480{
481 if (ieee80211_is_auth(t->hdr->frame_control)) {
482 u32 mask = ~BIT(t->txpriv.raw_link_id);
483 spin_lock_bh(&priv->ps_state_lock);
484 priv->sta_asleep_mask &= mask;
485 priv->pspoll_mask &= mask;
486 spin_unlock_bh(&priv->ps_state_lock);
487 }
488}
489
490static void
491cw1200_tx_h_calc_tid(struct cw1200_common *priv,
492 struct cw1200_txinfo *t)
493{
494 if (ieee80211_is_data_qos(t->hdr->frame_control)) {
495 u8 *qos = ieee80211_get_qos_ctl(t->hdr);
496 t->txpriv.tid = qos[0] & IEEE80211_QOS_CTL_TID_MASK;
497 } else if (ieee80211_is_data(t->hdr->frame_control)) {
498 t->txpriv.tid = 0;
499 }
500}
501
502static int
503cw1200_tx_h_crypt(struct cw1200_common *priv,
504 struct cw1200_txinfo *t)
505{
506 if (!t->tx_info->control.hw_key ||
507 !ieee80211_has_protected(t->hdr->frame_control))
508 return 0;
509
510 t->hdrlen += t->tx_info->control.hw_key->iv_len;
511 skb_put(t->skb, t->tx_info->control.hw_key->icv_len);
512
513 if (t->tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
514 skb_put(t->skb, 8); /* MIC space */
515
516 return 0;
517}
518
519static int
520cw1200_tx_h_align(struct cw1200_common *priv,
521 struct cw1200_txinfo *t,
522 u8 *flags)
523{
524 size_t offset = (size_t)t->skb->data & 3;
525
526 if (!offset)
527 return 0;
528
529 if (offset & 1) {
530 wiphy_err(priv->hw->wiphy,
531 "Bug: attempt to transmit a frame with wrong alignment: %zu\n",
532 offset);
533 return -EINVAL;
534 }
535
536 if (skb_headroom(t->skb) < offset) {
537 wiphy_err(priv->hw->wiphy,
538 "Bug: no space allocated for DMA alignment. headroom: %d\n",
539 skb_headroom(t->skb));
540 return -ENOMEM;
541 }
542 skb_push(t->skb, offset);
543 t->hdrlen += offset;
544 t->txpriv.offset += offset;
545 *flags |= WSM_TX_2BYTES_SHIFT;
546 cw1200_debug_tx_align(priv);
547 return 0;
548}
549
550static int
551cw1200_tx_h_action(struct cw1200_common *priv,
552 struct cw1200_txinfo *t)
553{
554 struct ieee80211_mgmt *mgmt =
555 (struct ieee80211_mgmt *)t->hdr;
556 if (ieee80211_is_action(t->hdr->frame_control) &&
557 mgmt->u.action.category == WLAN_CATEGORY_BACK)
558 return 1;
559 else
560 return 0;
561}
562
563/* Add WSM header */
564static struct wsm_tx *
565cw1200_tx_h_wsm(struct cw1200_common *priv,
566 struct cw1200_txinfo *t)
567{
568 struct wsm_tx *wsm;
569
570 if (skb_headroom(t->skb) < sizeof(struct wsm_tx)) {
571 wiphy_err(priv->hw->wiphy,
572 "Bug: no space allocated for WSM header. headroom: %d\n",
573 skb_headroom(t->skb));
574 return NULL;
575 }
576
577 wsm = (struct wsm_tx *)skb_push(t->skb, sizeof(struct wsm_tx));
578 t->txpriv.offset += sizeof(struct wsm_tx);
579 memset(wsm, 0, sizeof(*wsm));
580 wsm->hdr.len = __cpu_to_le16(t->skb->len);
581 wsm->hdr.id = __cpu_to_le16(0x0004);
582 wsm->queue_id = wsm_queue_id_to_wsm(t->queue);
583 return wsm;
584}
585
586/* BT Coex specific handling */
587static void
588cw1200_tx_h_bt(struct cw1200_common *priv,
589 struct cw1200_txinfo *t,
590 struct wsm_tx *wsm)
591{
592 u8 priority = 0;
593
594 if (!priv->bt_present)
595 return;
596
597 if (ieee80211_is_nullfunc(t->hdr->frame_control)) {
598 priority = WSM_EPTA_PRIORITY_MGT;
599 } else if (ieee80211_is_data(t->hdr->frame_control)) {
600 /* Skip LLC SNAP header (+6) */
601 u8 *payload = &t->skb->data[t->hdrlen];
602 u16 *ethertype = (u16 *)&payload[6];
603 if (*ethertype == __be16_to_cpu(ETH_P_PAE))
604 priority = WSM_EPTA_PRIORITY_EAPOL;
605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
606 ieee80211_is_reassoc_req(t->hdr->frame_control)) {
607 struct ieee80211_mgmt *mgt_frame =
608 (struct ieee80211_mgmt *)t->hdr;
609
610 if (mgt_frame->u.assoc_req.listen_interval <
611 priv->listen_interval) {
612 pr_debug("Modified Listen Interval to %d from %d\n",
613 priv->listen_interval,
614 mgt_frame->u.assoc_req.listen_interval);
615 /* Replace listen interval derieved from
616 * the one read from SDD */
617 mgt_frame->u.assoc_req.listen_interval =
618 priv->listen_interval;
619 }
620 }
621
622 if (!priority) {
623 if (ieee80211_is_action(t->hdr->frame_control))
624 priority = WSM_EPTA_PRIORITY_ACTION;
625 else if (ieee80211_is_mgmt(t->hdr->frame_control))
626 priority = WSM_EPTA_PRIORITY_MGT;
627 else if ((wsm->queue_id == WSM_QUEUE_VOICE))
628 priority = WSM_EPTA_PRIORITY_VOICE;
629 else if ((wsm->queue_id == WSM_QUEUE_VIDEO))
630 priority = WSM_EPTA_PRIORITY_VIDEO;
631 else
632 priority = WSM_EPTA_PRIORITY_DATA;
633 }
634
635 pr_debug("[TX] EPTA priority %d.\n", priority);
636
637 wsm->flags |= priority << 1;
638}
639
640static int
641cw1200_tx_h_rate_policy(struct cw1200_common *priv,
642 struct cw1200_txinfo *t,
643 struct wsm_tx *wsm)
644{
645 bool tx_policy_renew = false;
646
647 t->txpriv.rate_id = tx_policy_get(priv,
648 t->tx_info->control.rates, IEEE80211_TX_MAX_RATES,
649 &tx_policy_renew);
650 if (t->txpriv.rate_id == CW1200_INVALID_RATE_ID)
651 return -EFAULT;
652
653 wsm->flags |= t->txpriv.rate_id << 4;
654
655 t->rate = cw1200_get_tx_rate(priv,
656 &t->tx_info->control.rates[0]),
657 wsm->max_tx_rate = t->rate->hw_value;
658 if (t->rate->flags & IEEE80211_TX_RC_MCS) {
659 if (cw1200_ht_greenfield(&priv->ht_info))
660 wsm->ht_tx_parameters |=
661 __cpu_to_le32(WSM_HT_TX_GREENFIELD);
662 else
663 wsm->ht_tx_parameters |=
664 __cpu_to_le32(WSM_HT_TX_MIXED);
665 }
666
667 if (tx_policy_renew) {
668 pr_debug("[TX] TX policy renew.\n");
669 /* It's not so optimal to stop TX queues every now and then.
670 * Better to reimplement task scheduling with
671 * a counter. TODO. */
672 wsm_lock_tx_async(priv);
673 cw1200_tx_queues_lock(priv);
674 if (queue_work(priv->workqueue,
675 &priv->tx_policy_upload_work) <= 0) {
676 cw1200_tx_queues_unlock(priv);
677 wsm_unlock_tx(priv);
678 }
679 }
680 return 0;
681}
682
683static bool
684cw1200_tx_h_pm_state(struct cw1200_common *priv,
685 struct cw1200_txinfo *t)
686{
687 int was_buffered = 1;
688
689 if (t->txpriv.link_id == CW1200_LINK_ID_AFTER_DTIM &&
690 !priv->buffered_multicasts) {
691 priv->buffered_multicasts = true;
692 if (priv->sta_asleep_mask)
693 queue_work(priv->workqueue,
694 &priv->multicast_start_work);
695 }
696
697 if (t->txpriv.raw_link_id && t->txpriv.tid < CW1200_MAX_TID)
698 was_buffered = priv->link_id_db[t->txpriv.raw_link_id - 1].buffered[t->txpriv.tid]++;
699
700 return !was_buffered;
701}
702
703/* ******************************************************************** */
704
705void cw1200_tx(struct ieee80211_hw *dev,
706 struct ieee80211_tx_control *control,
707 struct sk_buff *skb)
708{
709 struct cw1200_common *priv = dev->priv;
710 struct cw1200_txinfo t = {
711 .skb = skb,
712 .queue = skb_get_queue_mapping(skb),
713 .tx_info = IEEE80211_SKB_CB(skb),
714 .hdr = (struct ieee80211_hdr *)skb->data,
715 .txpriv.tid = CW1200_MAX_TID,
716 .txpriv.rate_id = CW1200_INVALID_RATE_ID,
717 };
718 struct ieee80211_sta *sta;
719 struct wsm_tx *wsm;
720 bool tid_update = 0;
721 u8 flags = 0;
722 int ret;
723
724 if (priv->bh_error)
725 goto drop;
726
727 t.hdrlen = ieee80211_hdrlen(t.hdr->frame_control);
728 t.da = ieee80211_get_DA(t.hdr);
729 if (control) {
730 t.sta = control->sta;
731 t.sta_priv = (struct cw1200_sta_priv *)&t.sta->drv_priv;
732 }
733
734 if (WARN_ON(t.queue >= 4))
735 goto drop;
736
737 ret = cw1200_tx_h_calc_link_ids(priv, &t);
738 if (ret)
739 goto drop;
740
741 pr_debug("[TX] TX %d bytes (queue: %d, link_id: %d (%d)).\n",
742 skb->len, t.queue, t.txpriv.link_id,
743 t.txpriv.raw_link_id);
744
745 cw1200_tx_h_pm(priv, &t);
746 cw1200_tx_h_calc_tid(priv, &t);
747 ret = cw1200_tx_h_crypt(priv, &t);
748 if (ret)
749 goto drop;
750 ret = cw1200_tx_h_align(priv, &t, &flags);
751 if (ret)
752 goto drop;
753 ret = cw1200_tx_h_action(priv, &t);
754 if (ret)
755 goto drop;
756 wsm = cw1200_tx_h_wsm(priv, &t);
757 if (!wsm) {
758 ret = -ENOMEM;
759 goto drop;
760 }
761 wsm->flags |= flags;
762 cw1200_tx_h_bt(priv, &t, wsm);
763 ret = cw1200_tx_h_rate_policy(priv, &t, wsm);
764 if (ret)
765 goto drop;
766
767 rcu_read_lock();
768 sta = rcu_dereference(t.sta);
769
770 spin_lock_bh(&priv->ps_state_lock);
771 {
772 tid_update = cw1200_tx_h_pm_state(priv, &t);
773 BUG_ON(cw1200_queue_put(&priv->tx_queue[t.queue],
774 t.skb, &t.txpriv));
775 }
776 spin_unlock_bh(&priv->ps_state_lock);
777
778 if (tid_update && sta)
779 ieee80211_sta_set_buffered(sta, t.txpriv.tid, true);
780
781 rcu_read_unlock();
782
783 cw1200_bh_wakeup(priv);
784
785 return;
786
787drop:
788 cw1200_skb_dtor(priv, skb, &t.txpriv);
789 return;
790}
791
792/* ******************************************************************** */
793
794static int cw1200_handle_action_rx(struct cw1200_common *priv,
795 struct sk_buff *skb)
796{
797 struct ieee80211_mgmt *mgmt = (void *)skb->data;
798
799 /* Filter block ACK negotiation: fully controlled by firmware */
800 if (mgmt->u.action.category == WLAN_CATEGORY_BACK)
801 return 1;
802
803 return 0;
804}
805
806static int cw1200_handle_pspoll(struct cw1200_common *priv,
807 struct sk_buff *skb)
808{
809 struct ieee80211_sta *sta;
810 struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
811 int link_id = 0;
812 u32 pspoll_mask = 0;
813 int drop = 1;
814 int i;
815
816 if (priv->join_status != CW1200_JOIN_STATUS_AP)
817 goto done;
818 if (memcmp(priv->vif->addr, pspoll->bssid, ETH_ALEN))
819 goto done;
820
821 rcu_read_lock();
822 sta = ieee80211_find_sta(priv->vif, pspoll->ta);
823 if (sta) {
824 struct cw1200_sta_priv *sta_priv;
825 sta_priv = (struct cw1200_sta_priv *)&sta->drv_priv;
826 link_id = sta_priv->link_id;
827 pspoll_mask = BIT(sta_priv->link_id);
828 }
829 rcu_read_unlock();
830 if (!link_id)
831 goto done;
832
833 priv->pspoll_mask |= pspoll_mask;
834 drop = 0;
835
836 /* Do not report pspols if data for given link id is
837 * queued already. */
838 for (i = 0; i < 4; ++i) {
839 if (cw1200_queue_get_num_queued(&priv->tx_queue[i],
840 pspoll_mask)) {
841 cw1200_bh_wakeup(priv);
842 drop = 1;
843 break;
844 }
845 }
846 pr_debug("[RX] PSPOLL: %s\n", drop ? "local" : "fwd");
847done:
848 return drop;
849}
850
851/* ******************************************************************** */
852
853void cw1200_tx_confirm_cb(struct cw1200_common *priv,
854 int link_id,
855 struct wsm_tx_confirm *arg)
856{
857 u8 queue_id = cw1200_queue_get_queue_id(arg->packet_id);
858 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
859 struct sk_buff *skb;
860 const struct cw1200_txpriv *txpriv;
861
862 pr_debug("[TX] TX confirm: %d, %d.\n",
863 arg->status, arg->ack_failures);
864
865 if (cw1200_itp_tx_running(priv))
866 return;
867
868 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
869 /* STA is stopped. */
870 return;
871 }
872
873 if (WARN_ON(queue_id >= 4))
874 return;
875
876 if (arg->status)
877 pr_debug("TX failed: %d.\n", arg->status);
878
879 if ((arg->status == WSM_REQUEUE) &&
880 (arg->flags & WSM_TX_STATUS_REQUEUE)) {
881 /* "Requeue" means "implicit suspend" */
882 struct wsm_suspend_resume suspend = {
883 .link_id = link_id,
884 .stop = 1,
885 .multicast = !link_id,
886 };
887 cw1200_suspend_resume(priv, &suspend);
888 wiphy_warn(priv->hw->wiphy, "Requeue for link_id %d (try %d). STAs asleep: 0x%.8X\n",
889 link_id,
890 cw1200_queue_get_generation(arg->packet_id) + 1,
891 priv->sta_asleep_mask);
892 cw1200_queue_requeue(queue, arg->packet_id);
893 spin_lock_bh(&priv->ps_state_lock);
894 if (!link_id) {
895 priv->buffered_multicasts = true;
896 if (priv->sta_asleep_mask) {
897 queue_work(priv->workqueue,
898 &priv->multicast_start_work);
899 }
900 }
901 spin_unlock_bh(&priv->ps_state_lock);
902 } else if (!cw1200_queue_get_skb(queue, arg->packet_id,
903 &skb, &txpriv)) {
904 struct ieee80211_tx_info *tx = IEEE80211_SKB_CB(skb);
905 int tx_count = arg->ack_failures;
906 u8 ht_flags = 0;
907 int i;
908
909 if (cw1200_ht_greenfield(&priv->ht_info))
910 ht_flags |= IEEE80211_TX_RC_GREEN_FIELD;
911
912 spin_lock(&priv->bss_loss_lock);
913 if (priv->bss_loss_state &&
914 arg->packet_id == priv->bss_loss_confirm_id) {
915 if (arg->status) {
916 /* Recovery failed */
917 __cw1200_cqm_bssloss_sm(priv, 0, 0, 1);
918 } else {
919 /* Recovery succeeded */
920 __cw1200_cqm_bssloss_sm(priv, 0, 1, 0);
921 }
922 }
923 spin_unlock(&priv->bss_loss_lock);
924
925 if (!arg->status) {
926 tx->flags |= IEEE80211_TX_STAT_ACK;
927 ++tx_count;
928 cw1200_debug_txed(priv);
929 if (arg->flags & WSM_TX_STATUS_AGGREGATION) {
930 /* Do not report aggregation to mac80211:
931 * it confuses minstrel a lot. */
932 /* tx->flags |= IEEE80211_TX_STAT_AMPDU; */
933 cw1200_debug_txed_agg(priv);
934 }
935 } else {
936 if (tx_count)
937 ++tx_count;
938 }
939
940 for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
941 if (tx->status.rates[i].count >= tx_count) {
942 tx->status.rates[i].count = tx_count;
943 break;
944 }
945 tx_count -= tx->status.rates[i].count;
946 if (tx->status.rates[i].flags & IEEE80211_TX_RC_MCS)
947 tx->status.rates[i].flags |= ht_flags;
948 }
949
950 for (++i; i < IEEE80211_TX_MAX_RATES; ++i) {
951 tx->status.rates[i].count = 0;
952 tx->status.rates[i].idx = -1;
953 }
954
955 /* Pull off any crypto trailers that we added on */
956 if (tx->control.hw_key) {
957 skb_trim(skb, skb->len - tx->control.hw_key->icv_len);
958 if (tx->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
959 skb_trim(skb, skb->len - 8); /* MIC space */
960 }
961 cw1200_queue_remove(queue, arg->packet_id);
962 }
963 /* XXX TODO: Only wake if there are pending transmits.. */
964 cw1200_bh_wakeup(priv);
965}
966
967static void cw1200_notify_buffered_tx(struct cw1200_common *priv,
968 struct sk_buff *skb, int link_id, int tid)
969{
970 struct ieee80211_sta *sta;
971 struct ieee80211_hdr *hdr;
972 u8 *buffered;
973 u8 still_buffered = 0;
974
975 if (link_id && tid < CW1200_MAX_TID) {
976 buffered = priv->link_id_db
977 [link_id - 1].buffered;
978
979 spin_lock_bh(&priv->ps_state_lock);
980 if (!WARN_ON(!buffered[tid]))
981 still_buffered = --buffered[tid];
982 spin_unlock_bh(&priv->ps_state_lock);
983
984 if (!still_buffered && tid < CW1200_MAX_TID) {
985 hdr = (struct ieee80211_hdr *)skb->data;
986 rcu_read_lock();
987 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
988 if (sta)
989 ieee80211_sta_set_buffered(sta, tid, false);
990 rcu_read_unlock();
991 }
992 }
993}
994
995void cw1200_skb_dtor(struct cw1200_common *priv,
996 struct sk_buff *skb,
997 const struct cw1200_txpriv *txpriv)
998{
999 skb_pull(skb, txpriv->offset);
1000 if (txpriv->rate_id != CW1200_INVALID_RATE_ID) {
1001 cw1200_notify_buffered_tx(priv, skb,
1002 txpriv->raw_link_id, txpriv->tid);
1003 tx_policy_put(priv, txpriv->rate_id);
1004 }
1005 if (!cw1200_is_itp(priv))
1006 ieee80211_tx_status(priv->hw, skb);
1007}
1008
1009void cw1200_rx_cb(struct cw1200_common *priv,
1010 struct wsm_rx *arg,
1011 int link_id,
1012 struct sk_buff **skb_p)
1013{
1014 struct sk_buff *skb = *skb_p;
1015 struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
1016 struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
1017 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1018 struct cw1200_link_entry *entry = NULL;
1019 unsigned long grace_period;
1020
1021 bool early_data = false;
1022 bool p2p = priv->vif && priv->vif->p2p;
1023 size_t hdrlen;
1024 hdr->flag = 0;
1025
1026 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
1027 /* STA is stopped. */
1028 goto drop;
1029 }
1030
1031 if (link_id && link_id <= CW1200_MAX_STA_IN_AP_MODE) {
1032 entry = &priv->link_id_db[link_id - 1];
1033 if (entry->status == CW1200_LINK_SOFT &&
1034 ieee80211_is_data(frame->frame_control))
1035 early_data = true;
1036 entry->timestamp = jiffies;
1037 } else if (p2p &&
1038 ieee80211_is_action(frame->frame_control) &&
1039 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1040 pr_debug("[RX] Going to MAP&RESET link ID\n");
1041 WARN_ON(work_pending(&priv->linkid_reset_work));
1042 memcpy(&priv->action_frame_sa[0],
1043 ieee80211_get_SA(frame), ETH_ALEN);
1044 priv->action_linkid = 0;
1045 schedule_work(&priv->linkid_reset_work);
1046 }
1047
1048 if (link_id && p2p &&
1049 ieee80211_is_action(frame->frame_control) &&
1050 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1051 /* Link ID already exists for the ACTION frame.
1052 * Reset and Remap */
1053 WARN_ON(work_pending(&priv->linkid_reset_work));
1054 memcpy(&priv->action_frame_sa[0],
1055 ieee80211_get_SA(frame), ETH_ALEN);
1056 priv->action_linkid = link_id;
1057 schedule_work(&priv->linkid_reset_work);
1058 }
1059 if (arg->status) {
1060 if (arg->status == WSM_STATUS_MICFAILURE) {
1061 pr_debug("[RX] MIC failure.\n");
1062 hdr->flag |= RX_FLAG_MMIC_ERROR;
1063 } else if (arg->status == WSM_STATUS_NO_KEY_FOUND) {
1064 pr_debug("[RX] No key found.\n");
1065 goto drop;
1066 } else {
1067 pr_debug("[RX] Receive failure: %d.\n",
1068 arg->status);
1069 goto drop;
1070 }
1071 }
1072
1073 if (skb->len < sizeof(struct ieee80211_pspoll)) {
1074 wiphy_warn(priv->hw->wiphy, "Mailformed SDU rx'ed. Size is lesser than IEEE header.\n");
1075 goto drop;
1076 }
1077
1078 if (ieee80211_is_pspoll(frame->frame_control))
1079 if (cw1200_handle_pspoll(priv, skb))
1080 goto drop;
1081
1082 hdr->mactime = 0; /* Not supported by WSM */
1083 hdr->band = ((arg->channel_number & 0xff00) ||
1084 (arg->channel_number > 14)) ?
1085 IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
1086 hdr->freq = ieee80211_channel_to_frequency(
1087 arg->channel_number,
1088 hdr->band);
1089
1090 if (arg->rx_rate >= 14) {
1091 hdr->flag |= RX_FLAG_HT;
1092 hdr->rate_idx = arg->rx_rate - 14;
1093 } else if (arg->rx_rate >= 4) {
1094 hdr->rate_idx = arg->rx_rate - 2;
1095 } else {
1096 hdr->rate_idx = arg->rx_rate;
1097 }
1098
1099 hdr->signal = (s8)arg->rcpi_rssi;
1100 hdr->antenna = 0;
1101
1102 hdrlen = ieee80211_hdrlen(frame->frame_control);
1103
1104 if (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1105 size_t iv_len = 0, icv_len = 0;
1106
1107 hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED;
1108
1109 /* Oops... There is no fast way to ask mac80211 about
1110 * IV/ICV lengths. Even defineas are not exposed.*/
1111 switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1112 case WSM_RX_STATUS_WEP:
1113 iv_len = 4 /* WEP_IV_LEN */;
1114 icv_len = 4 /* WEP_ICV_LEN */;
1115 break;
1116 case WSM_RX_STATUS_TKIP:
1117 iv_len = 8 /* TKIP_IV_LEN */;
1118 icv_len = 4 /* TKIP_ICV_LEN */
1119 + 8 /*MICHAEL_MIC_LEN*/;
1120 hdr->flag |= RX_FLAG_MMIC_STRIPPED;
1121 break;
1122 case WSM_RX_STATUS_AES:
1123 iv_len = 8 /* CCMP_HDR_LEN */;
1124 icv_len = 8 /* CCMP_MIC_LEN */;
1125 break;
1126 case WSM_RX_STATUS_WAPI:
1127 iv_len = 18 /* WAPI_HDR_LEN */;
1128 icv_len = 16 /* WAPI_MIC_LEN */;
1129 break;
1130 default:
1131 pr_warn("Unknown encryption type %d\n",
1132 WSM_RX_STATUS_ENCRYPTION(arg->flags));
1133 goto drop;
1134 }
1135
1136 /* Firmware strips ICV in case of MIC failure. */
1137 if (arg->status == WSM_STATUS_MICFAILURE)
1138 icv_len = 0;
1139
1140 if (skb->len < hdrlen + iv_len + icv_len) {
1141 wiphy_warn(priv->hw->wiphy, "Malformed SDU rx'ed. Size is lesser than crypto headers.\n");
1142 goto drop;
1143 }
1144
1145 /* Remove IV, ICV and MIC */
1146 skb_trim(skb, skb->len - icv_len);
1147 memmove(skb->data + iv_len, skb->data, hdrlen);
1148 skb_pull(skb, iv_len);
1149 }
1150
1151 /* Remove TSF from the end of frame */
1152 if (arg->flags & WSM_RX_STATUS_TSF_INCLUDED) {
1153 memcpy(&hdr->mactime, skb->data + skb->len - 8, 8);
1154 hdr->mactime = le64_to_cpu(hdr->mactime);
1155 if (skb->len >= 8)
1156 skb_trim(skb, skb->len - 8);
1157 }
1158
1159 cw1200_debug_rxed(priv);
1160 if (arg->flags & WSM_RX_STATUS_AGGREGATE)
1161 cw1200_debug_rxed_agg(priv);
1162
1163 if (ieee80211_is_action(frame->frame_control) &&
1164 (arg->flags & WSM_RX_STATUS_ADDRESS1)) {
1165 if (cw1200_handle_action_rx(priv, skb))
1166 return;
1167 } else if (ieee80211_is_beacon(frame->frame_control) &&
1168 !arg->status &&
1169 !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid,
1170 ETH_ALEN)) {
1171 const u8 *tim_ie;
1172 u8 *ies = ((struct ieee80211_mgmt *)
1173 (skb->data))->u.beacon.variable;
1174 size_t ies_len = skb->len - (ies - (u8 *)(skb->data));
1175
1176 tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
1177 if (tim_ie) {
1178 struct ieee80211_tim_ie *tim =
1179 (struct ieee80211_tim_ie *)&tim_ie[2];
1180
1181 if (priv->join_dtim_period != tim->dtim_period) {
1182 priv->join_dtim_period = tim->dtim_period;
1183 queue_work(priv->workqueue,
1184 &priv->set_beacon_wakeup_period_work);
1185 }
1186 }
1187
1188 /* Disable beacon filter once we're associated... */
1189 if (priv->disable_beacon_filter &&
1190 (priv->vif->bss_conf.assoc ||
1191 priv->vif->bss_conf.ibss_joined)) {
1192 priv->disable_beacon_filter = false;
1193 queue_work(priv->workqueue,
1194 &priv->update_filtering_work);
1195 }
1196 }
1197
1198 /* Stay awake after frame is received to give
1199 * userspace chance to react and acquire appropriate
1200 * wakelock. */
1201 if (ieee80211_is_auth(frame->frame_control))
1202 grace_period = 5 * HZ;
1203 else if (ieee80211_is_deauth(frame->frame_control))
1204 grace_period = 5 * HZ;
1205 else
1206 grace_period = 1 * HZ;
1207 cw1200_pm_stay_awake(&priv->pm_state, grace_period);
1208
1209 if (cw1200_itp_rxed(priv, skb)) {
1210 consume_skb(skb);
1211 } else if (early_data) {
1212 spin_lock_bh(&priv->ps_state_lock);
1213 /* Double-check status with lock held */
1214 if (entry->status == CW1200_LINK_SOFT)
1215 skb_queue_tail(&entry->rx_queue, skb);
1216 else
1217 ieee80211_rx_irqsafe(priv->hw, skb);
1218 spin_unlock_bh(&priv->ps_state_lock);
1219 } else {
1220 ieee80211_rx_irqsafe(priv->hw, skb);
1221 }
1222 *skb_p = NULL;
1223
1224 return;
1225
1226drop:
1227 /* TODO: update failure counters */
1228 return;
1229}
1230
1231/* ******************************************************************** */
1232/* Security */
1233
1234int cw1200_alloc_key(struct cw1200_common *priv)
1235{
1236 int idx;
1237
1238 idx = ffs(~priv->key_map) - 1;
1239 if (idx < 0 || idx > WSM_KEY_MAX_INDEX)
1240 return -1;
1241
1242 priv->key_map |= BIT(idx);
1243 priv->keys[idx].index = idx;
1244 return idx;
1245}
1246
1247void cw1200_free_key(struct cw1200_common *priv, int idx)
1248{
1249 BUG_ON(!(priv->key_map & BIT(idx)));
1250 memset(&priv->keys[idx], 0, sizeof(priv->keys[idx]));
1251 priv->key_map &= ~BIT(idx);
1252}
1253
1254void cw1200_free_keys(struct cw1200_common *priv)
1255{
1256 memset(&priv->keys, 0, sizeof(priv->keys));
1257 priv->key_map = 0;
1258}
1259
1260int cw1200_upload_keys(struct cw1200_common *priv)
1261{
1262 int idx, ret = 0;
1263 for (idx = 0; idx <= WSM_KEY_MAX_INDEX; ++idx)
1264 if (priv->key_map & BIT(idx)) {
1265 ret = wsm_add_key(priv, &priv->keys[idx]);
1266 if (ret < 0)
1267 break;
1268 }
1269 return ret;
1270}
1271
1272/* Workaround for WFD test case 6.1.10 */
1273void cw1200_link_id_reset(struct work_struct *work)
1274{
1275 struct cw1200_common *priv =
1276 container_of(work, struct cw1200_common, linkid_reset_work);
1277 int temp_linkid;
1278
1279 if (!priv->action_linkid) {
1280 /* In GO mode we can receive ACTION frames without a linkID */
1281 temp_linkid = cw1200_alloc_link_id(priv,
1282 &priv->action_frame_sa[0]);
1283 WARN_ON(!temp_linkid);
1284 if (temp_linkid) {
1285 /* Make sure we execute the WQ */
1286 flush_workqueue(priv->workqueue);
1287 /* Release the link ID */
1288 spin_lock_bh(&priv->ps_state_lock);
1289 priv->link_id_db[temp_linkid - 1].prev_status =
1290 priv->link_id_db[temp_linkid - 1].status;
1291 priv->link_id_db[temp_linkid - 1].status =
1292 CW1200_LINK_RESET;
1293 spin_unlock_bh(&priv->ps_state_lock);
1294 wsm_lock_tx_async(priv);
1295 if (queue_work(priv->workqueue,
1296 &priv->link_id_work) <= 0)
1297 wsm_unlock_tx(priv);
1298 }
1299 } else {
1300 spin_lock_bh(&priv->ps_state_lock);
1301 priv->link_id_db[priv->action_linkid - 1].prev_status =
1302 priv->link_id_db[priv->action_linkid - 1].status;
1303 priv->link_id_db[priv->action_linkid - 1].status =
1304 CW1200_LINK_RESET_REMAP;
1305 spin_unlock_bh(&priv->ps_state_lock);
1306 wsm_lock_tx_async(priv);
1307 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1308 wsm_unlock_tx(priv);
1309 flush_workqueue(priv->workqueue);
1310 }
1311}
1312
1313int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac)
1314{
1315 int i, ret = 0;
1316 spin_lock_bh(&priv->ps_state_lock);
1317 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1318 if (!memcmp(mac, priv->link_id_db[i].mac, ETH_ALEN) &&
1319 priv->link_id_db[i].status) {
1320 priv->link_id_db[i].timestamp = jiffies;
1321 ret = i + 1;
1322 break;
1323 }
1324 }
1325 spin_unlock_bh(&priv->ps_state_lock);
1326 return ret;
1327}
1328
1329int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac)
1330{
1331 int i, ret = 0;
1332 unsigned long max_inactivity = 0;
1333 unsigned long now = jiffies;
1334
1335 spin_lock_bh(&priv->ps_state_lock);
1336 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1337 if (!priv->link_id_db[i].status) {
1338 ret = i + 1;
1339 break;
1340 } else if (priv->link_id_db[i].status != CW1200_LINK_HARD &&
1341 !priv->tx_queue_stats.link_map_cache[i + 1]) {
1342 unsigned long inactivity =
1343 now - priv->link_id_db[i].timestamp;
1344 if (inactivity < max_inactivity)
1345 continue;
1346 max_inactivity = inactivity;
1347 ret = i + 1;
1348 }
1349 }
1350 if (ret) {
1351 struct cw1200_link_entry *entry = &priv->link_id_db[ret - 1];
1352 pr_debug("[AP] STA added, link_id: %d\n", ret);
1353 entry->status = CW1200_LINK_RESERVE;
1354 memcpy(&entry->mac, mac, ETH_ALEN);
1355 memset(&entry->buffered, 0, CW1200_MAX_TID);
1356 skb_queue_head_init(&entry->rx_queue);
1357 wsm_lock_tx_async(priv);
1358 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1359 wsm_unlock_tx(priv);
1360 } else {
1361 wiphy_info(priv->hw->wiphy,
1362 "[AP] Early: no more link IDs available.\n");
1363 }
1364
1365 spin_unlock_bh(&priv->ps_state_lock);
1366 return ret;
1367}
1368
1369void cw1200_link_id_work(struct work_struct *work)
1370{
1371 struct cw1200_common *priv =
1372 container_of(work, struct cw1200_common, link_id_work);
1373 wsm_flush_tx(priv);
1374 cw1200_link_id_gc_work(&priv->link_id_gc_work.work);
1375 wsm_unlock_tx(priv);
1376}
1377
1378void cw1200_link_id_gc_work(struct work_struct *work)
1379{
1380 struct cw1200_common *priv =
1381 container_of(work, struct cw1200_common, link_id_gc_work.work);
1382 struct wsm_reset reset = {
1383 .reset_statistics = false,
1384 };
1385 struct wsm_map_link map_link = {
1386 .link_id = 0,
1387 };
1388 unsigned long now = jiffies;
1389 unsigned long next_gc = -1;
1390 long ttl;
1391 bool need_reset;
1392 u32 mask;
1393 int i;
1394
1395 if (priv->join_status != CW1200_JOIN_STATUS_AP)
1396 return;
1397
1398 wsm_lock_tx(priv);
1399 spin_lock_bh(&priv->ps_state_lock);
1400 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1401 need_reset = false;
1402 mask = BIT(i + 1);
1403 if (priv->link_id_db[i].status == CW1200_LINK_RESERVE ||
1404 (priv->link_id_db[i].status == CW1200_LINK_HARD &&
1405 !(priv->link_id_map & mask))) {
1406 if (priv->link_id_map & mask) {
1407 priv->sta_asleep_mask &= ~mask;
1408 priv->pspoll_mask &= ~mask;
1409 need_reset = true;
1410 }
1411 priv->link_id_map |= mask;
1412 if (priv->link_id_db[i].status != CW1200_LINK_HARD)
1413 priv->link_id_db[i].status = CW1200_LINK_SOFT;
1414 memcpy(map_link.mac_addr, priv->link_id_db[i].mac,
1415 ETH_ALEN);
1416 spin_unlock_bh(&priv->ps_state_lock);
1417 if (need_reset) {
1418 reset.link_id = i + 1;
1419 wsm_reset(priv, &reset);
1420 }
1421 map_link.link_id = i + 1;
1422 wsm_map_link(priv, &map_link);
1423 next_gc = min(next_gc, CW1200_LINK_ID_GC_TIMEOUT);
1424 spin_lock_bh(&priv->ps_state_lock);
1425 } else if (priv->link_id_db[i].status == CW1200_LINK_SOFT) {
1426 ttl = priv->link_id_db[i].timestamp - now +
1427 CW1200_LINK_ID_GC_TIMEOUT;
1428 if (ttl <= 0) {
1429 need_reset = true;
1430 priv->link_id_db[i].status = CW1200_LINK_OFF;
1431 priv->link_id_map &= ~mask;
1432 priv->sta_asleep_mask &= ~mask;
1433 priv->pspoll_mask &= ~mask;
1434 memset(map_link.mac_addr, 0, ETH_ALEN);
1435 spin_unlock_bh(&priv->ps_state_lock);
1436 reset.link_id = i + 1;
1437 wsm_reset(priv, &reset);
1438 spin_lock_bh(&priv->ps_state_lock);
1439 } else {
1440 next_gc = min_t(unsigned long, next_gc, ttl);
1441 }
1442 } else if (priv->link_id_db[i].status == CW1200_LINK_RESET ||
1443 priv->link_id_db[i].status ==
1444 CW1200_LINK_RESET_REMAP) {
1445 int status = priv->link_id_db[i].status;
1446 priv->link_id_db[i].status =
1447 priv->link_id_db[i].prev_status;
1448 priv->link_id_db[i].timestamp = now;
1449 reset.link_id = i + 1;
1450 spin_unlock_bh(&priv->ps_state_lock);
1451 wsm_reset(priv, &reset);
1452 if (status == CW1200_LINK_RESET_REMAP) {
1453 memcpy(map_link.mac_addr,
1454 priv->link_id_db[i].mac,
1455 ETH_ALEN);
1456 map_link.link_id = i + 1;
1457 wsm_map_link(priv, &map_link);
1458 next_gc = min(next_gc,
1459 CW1200_LINK_ID_GC_TIMEOUT);
1460 }
1461 spin_lock_bh(&priv->ps_state_lock);
1462 }
1463 if (need_reset) {
1464 skb_queue_purge(&priv->link_id_db[i].rx_queue);
1465 pr_debug("[AP] STA removed, link_id: %d\n",
1466 reset.link_id);
1467 }
1468 }
1469 spin_unlock_bh(&priv->ps_state_lock);
1470 if (next_gc != -1)
1471 queue_delayed_work(priv->workqueue,
1472 &priv->link_id_gc_work, next_gc);
1473 wsm_unlock_tx(priv);
1474}
diff --git a/drivers/net/wireless/cw1200/txrx.h b/drivers/net/wireless/cw1200/txrx.h
new file mode 100644
index 000000000000..492a4e14213b
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.h
@@ -0,0 +1,106 @@
1/*
2 * Datapath interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_TXRX_H
13#define CW1200_TXRX_H
14
15#include <linux/list.h>
16
17/* extern */ struct ieee80211_hw;
18/* extern */ struct sk_buff;
19/* extern */ struct wsm_tx;
20/* extern */ struct wsm_rx;
21/* extern */ struct wsm_tx_confirm;
22/* extern */ struct cw1200_txpriv;
23
24struct tx_policy {
25 union {
26 __le32 tbl[3];
27 u8 raw[12];
28 };
29 u8 defined;
30 u8 usage_count;
31 u8 retry_count;
32 u8 uploaded;
33};
34
35struct tx_policy_cache_entry {
36 struct tx_policy policy;
37 struct list_head link;
38};
39
40#define TX_POLICY_CACHE_SIZE (8)
41struct tx_policy_cache {
42 struct tx_policy_cache_entry cache[TX_POLICY_CACHE_SIZE];
43 struct list_head used;
44 struct list_head free;
45 spinlock_t lock; /* Protect policy cache */
46};
47
48/* ******************************************************************** */
49/* TX policy cache */
50/* Intention of TX policy cache is an overcomplicated WSM API.
51 * Device does not accept per-PDU tx retry sequence.
52 * It uses "tx retry policy id" instead, so driver code has to sync
53 * linux tx retry sequences with a retry policy table in the device.
54 */
55void tx_policy_init(struct cw1200_common *priv);
56void tx_policy_upload_work(struct work_struct *work);
57void tx_policy_clean(struct cw1200_common *priv);
58
59/* ******************************************************************** */
60/* TX implementation */
61
62u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv,
63 u32 rates);
64void cw1200_tx(struct ieee80211_hw *dev,
65 struct ieee80211_tx_control *control,
66 struct sk_buff *skb);
67void cw1200_skb_dtor(struct cw1200_common *priv,
68 struct sk_buff *skb,
69 const struct cw1200_txpriv *txpriv);
70
71/* ******************************************************************** */
72/* WSM callbacks */
73
74void cw1200_tx_confirm_cb(struct cw1200_common *priv,
75 int link_id,
76 struct wsm_tx_confirm *arg);
77void cw1200_rx_cb(struct cw1200_common *priv,
78 struct wsm_rx *arg,
79 int link_id,
80 struct sk_buff **skb_p);
81
82/* ******************************************************************** */
83/* Timeout */
84
85void cw1200_tx_timeout(struct work_struct *work);
86
87/* ******************************************************************** */
88/* Security */
89int cw1200_alloc_key(struct cw1200_common *priv);
90void cw1200_free_key(struct cw1200_common *priv, int idx);
91void cw1200_free_keys(struct cw1200_common *priv);
92int cw1200_upload_keys(struct cw1200_common *priv);
93
94/* ******************************************************************** */
95/* Workaround for WFD test case 6.1.10 */
96void cw1200_link_id_reset(struct work_struct *work);
97
98#define CW1200_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
99
100int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac);
101int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac);
102void cw1200_link_id_work(struct work_struct *work);
103void cw1200_link_id_gc_work(struct work_struct *work);
104
105
106#endif /* CW1200_TXRX_H */
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
new file mode 100644
index 000000000000..f3fd9b218724
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -0,0 +1,1883 @@
1/*
2 * WSM host interface (HI) implementation for
3 * ST-Ericsson CW1200 mac80211 drivers.
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/skbuff.h>
14#include <linux/wait.h>
15#include <linux/delay.h>
16#include <linux/sched.h>
17#include <linux/random.h>
18
19#include "cw1200.h"
20#include "wsm.h"
21#include "bh.h"
22#include "sta.h"
23#include "debug.h"
24#include "itp.h"
25
26#define WSM_CMD_TIMEOUT (2 * HZ) /* With respect to interrupt loss */
27#define WSM_CMD_START_TIMEOUT (7 * HZ)
28#define WSM_CMD_RESET_TIMEOUT (3 * HZ) /* 2 sec. timeout was observed. */
29#define WSM_CMD_MAX_TIMEOUT (3 * HZ)
30
31#define WSM_SKIP(buf, size) \
32 do { \
33 if ((buf)->data + size > (buf)->end) \
34 goto underflow; \
35 (buf)->data += size; \
36 } while (0)
37
38#define WSM_GET(buf, ptr, size) \
39 do { \
40 if ((buf)->data + size > (buf)->end) \
41 goto underflow; \
42 memcpy(ptr, (buf)->data, size); \
43 (buf)->data += size; \
44 } while (0)
45
46#define __WSM_GET(buf, type, cvt) \
47 ({ \
48 type val; \
49 if ((buf)->data + sizeof(type) > (buf)->end) \
50 goto underflow; \
51 val = cvt(*(type *)(buf)->data); \
52 (buf)->data += sizeof(type); \
53 val; \
54 })
55
56#define WSM_GET8(buf) __WSM_GET(buf, u8, (u8))
57#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu)
58#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu)
59
60#define WSM_PUT(buf, ptr, size) \
61 do { \
62 if ((buf)->data + size > (buf)->end) \
63 if (wsm_buf_reserve((buf), size)) \
64 goto nomem; \
65 memcpy((buf)->data, ptr, size); \
66 (buf)->data += size; \
67 } while (0)
68
69#define __WSM_PUT(buf, val, type, cvt) \
70 do { \
71 if ((buf)->data + sizeof(type) > (buf)->end) \
72 if (wsm_buf_reserve((buf), sizeof(type))) \
73 goto nomem; \
74 *(type *)(buf)->data = cvt(val); \
75 (buf)->data += sizeof(type); \
76 } while (0)
77
78#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8))
79#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16)
80#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32)
81
82static void wsm_buf_reset(struct wsm_buf *buf);
83static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
84
85static int wsm_cmd_send(struct cw1200_common *priv,
86 struct wsm_buf *buf,
87 void *arg, u16 cmd, long tmo);
88
89#define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
90#define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
91
92/* ******************************************************************** */
93/* WSM API implementation */
94
95static int wsm_generic_confirm(struct cw1200_common *priv,
96 void *arg,
97 struct wsm_buf *buf)
98{
99 u32 status = WSM_GET32(buf);
100 if (status != WSM_STATUS_SUCCESS)
101 return -EINVAL;
102 return 0;
103
104underflow:
105 WARN_ON(1);
106 return -EINVAL;
107}
108
109int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
110{
111 int ret;
112 struct wsm_buf *buf = &priv->wsm_cmd_buf;
113
114 wsm_cmd_lock(priv);
115
116 WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
117 WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
118 WSM_PUT32(buf, arg->dot11RtsThreshold);
119
120 /* DPD block. */
121 WSM_PUT16(buf, arg->dpdData_size + 12);
122 WSM_PUT16(buf, 1); /* DPD version */
123 WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
124 WSM_PUT16(buf, 5); /* DPD flags */
125 WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
126
127 ret = wsm_cmd_send(priv, buf, arg,
128 WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
129
130 wsm_cmd_unlock(priv);
131 return ret;
132
133nomem:
134 wsm_cmd_unlock(priv);
135 return -ENOMEM;
136}
137
138static int wsm_configuration_confirm(struct cw1200_common *priv,
139 struct wsm_configuration *arg,
140 struct wsm_buf *buf)
141{
142 int i;
143 int status;
144
145 status = WSM_GET32(buf);
146 if (WARN_ON(status != WSM_STATUS_SUCCESS))
147 return -EINVAL;
148
149 WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
150 arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
151 WSM_SKIP(buf, 1);
152 arg->supportedRateMask = WSM_GET32(buf);
153 for (i = 0; i < 2; ++i) {
154 arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
155 arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
156 arg->txPowerRange[i].stepping = WSM_GET32(buf);
157 }
158 return 0;
159
160underflow:
161 WARN_ON(1);
162 return -EINVAL;
163}
164
165/* ******************************************************************** */
166
167int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
168{
169 int ret;
170 struct wsm_buf *buf = &priv->wsm_cmd_buf;
171 u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
172
173 wsm_cmd_lock(priv);
174
175 WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
176 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
177 wsm_cmd_unlock(priv);
178 return ret;
179
180nomem:
181 wsm_cmd_unlock(priv);
182 return -ENOMEM;
183}
184
185/* ******************************************************************** */
186
187struct wsm_mib {
188 u16 mib_id;
189 void *buf;
190 size_t buf_size;
191};
192
193int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
194 size_t buf_size)
195{
196 int ret;
197 struct wsm_buf *buf = &priv->wsm_cmd_buf;
198 struct wsm_mib mib_buf = {
199 .mib_id = mib_id,
200 .buf = _buf,
201 .buf_size = buf_size,
202 };
203 wsm_cmd_lock(priv);
204
205 WSM_PUT16(buf, mib_id);
206 WSM_PUT16(buf, 0);
207
208 ret = wsm_cmd_send(priv, buf, &mib_buf,
209 WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
210 wsm_cmd_unlock(priv);
211 return ret;
212
213nomem:
214 wsm_cmd_unlock(priv);
215 return -ENOMEM;
216}
217
218static int wsm_read_mib_confirm(struct cw1200_common *priv,
219 struct wsm_mib *arg,
220 struct wsm_buf *buf)
221{
222 u16 size;
223 if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
224 return -EINVAL;
225
226 if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
227 return -EINVAL;
228
229 size = WSM_GET16(buf);
230 if (size > arg->buf_size)
231 size = arg->buf_size;
232
233 WSM_GET(buf, arg->buf, size);
234 arg->buf_size = size;
235 return 0;
236
237underflow:
238 WARN_ON(1);
239 return -EINVAL;
240}
241
242/* ******************************************************************** */
243
244int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
245 size_t buf_size)
246{
247 int ret;
248 struct wsm_buf *buf = &priv->wsm_cmd_buf;
249 struct wsm_mib mib_buf = {
250 .mib_id = mib_id,
251 .buf = _buf,
252 .buf_size = buf_size,
253 };
254
255 wsm_cmd_lock(priv);
256
257 WSM_PUT16(buf, mib_id);
258 WSM_PUT16(buf, buf_size);
259 WSM_PUT(buf, _buf, buf_size);
260
261 ret = wsm_cmd_send(priv, buf, &mib_buf,
262 WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
263 wsm_cmd_unlock(priv);
264 return ret;
265
266nomem:
267 wsm_cmd_unlock(priv);
268 return -ENOMEM;
269}
270
271static int wsm_write_mib_confirm(struct cw1200_common *priv,
272 struct wsm_mib *arg,
273 struct wsm_buf *buf)
274{
275 int ret;
276
277 ret = wsm_generic_confirm(priv, arg, buf);
278 if (ret)
279 return ret;
280
281 if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
282 /* OperationalMode: update PM status. */
283 const char *p = arg->buf;
284 cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
285 }
286 return 0;
287}
288
289/* ******************************************************************** */
290
291int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
292{
293 int i;
294 int ret;
295 struct wsm_buf *buf = &priv->wsm_cmd_buf;
296
297 if (arg->num_channels > 48)
298 return -EINVAL;
299
300 if (arg->num_ssids > 2)
301 return -EINVAL;
302
303 if (arg->band > 1)
304 return -EINVAL;
305
306 wsm_cmd_lock(priv);
307
308 WSM_PUT8(buf, arg->band);
309 WSM_PUT8(buf, arg->type);
310 WSM_PUT8(buf, arg->flags);
311 WSM_PUT8(buf, arg->max_tx_rate);
312 WSM_PUT32(buf, arg->auto_scan_interval);
313 WSM_PUT8(buf, arg->num_probes);
314 WSM_PUT8(buf, arg->num_channels);
315 WSM_PUT8(buf, arg->num_ssids);
316 WSM_PUT8(buf, arg->probe_delay);
317
318 for (i = 0; i < arg->num_channels; ++i) {
319 WSM_PUT16(buf, arg->ch[i].number);
320 WSM_PUT16(buf, 0);
321 WSM_PUT32(buf, arg->ch[i].min_chan_time);
322 WSM_PUT32(buf, arg->ch[i].max_chan_time);
323 WSM_PUT32(buf, 0);
324 }
325
326 for (i = 0; i < arg->num_ssids; ++i) {
327 WSM_PUT32(buf, arg->ssids[i].length);
328 WSM_PUT(buf, &arg->ssids[i].ssid[0],
329 sizeof(arg->ssids[i].ssid));
330 }
331
332 ret = wsm_cmd_send(priv, buf, NULL,
333 WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
334 wsm_cmd_unlock(priv);
335 return ret;
336
337nomem:
338 wsm_cmd_unlock(priv);
339 return -ENOMEM;
340}
341
342/* ******************************************************************** */
343
344int wsm_stop_scan(struct cw1200_common *priv)
345{
346 int ret;
347 struct wsm_buf *buf = &priv->wsm_cmd_buf;
348 wsm_cmd_lock(priv);
349 ret = wsm_cmd_send(priv, buf, NULL,
350 WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
351 wsm_cmd_unlock(priv);
352 return ret;
353}
354
355
356static int wsm_tx_confirm(struct cw1200_common *priv,
357 struct wsm_buf *buf,
358 int link_id)
359{
360 struct wsm_tx_confirm tx_confirm;
361
362 tx_confirm.packet_id = WSM_GET32(buf);
363 tx_confirm.status = WSM_GET32(buf);
364 tx_confirm.tx_rate = WSM_GET8(buf);
365 tx_confirm.ack_failures = WSM_GET8(buf);
366 tx_confirm.flags = WSM_GET16(buf);
367 tx_confirm.media_delay = WSM_GET32(buf);
368 tx_confirm.tx_queue_delay = WSM_GET32(buf);
369
370 cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
371 return 0;
372
373underflow:
374 WARN_ON(1);
375 return -EINVAL;
376}
377
378static int wsm_multi_tx_confirm(struct cw1200_common *priv,
379 struct wsm_buf *buf, int link_id)
380{
381 int ret;
382 int count;
383 int i;
384
385 count = WSM_GET32(buf);
386 if (WARN_ON(count <= 0))
387 return -EINVAL;
388
389 if (count > 1) {
390 /* We already released one buffer, now for the rest */
391 ret = wsm_release_tx_buffer(priv, count - 1);
392 if (ret < 0)
393 return ret;
394 else if (ret > 0)
395 cw1200_bh_wakeup(priv);
396 }
397
398 cw1200_debug_txed_multi(priv, count);
399 for (i = 0; i < count; ++i) {
400 ret = wsm_tx_confirm(priv, buf, link_id);
401 if (ret)
402 return ret;
403 }
404 return ret;
405
406underflow:
407 WARN_ON(1);
408 return -EINVAL;
409}
410
411/* ******************************************************************** */
412
413static int wsm_join_confirm(struct cw1200_common *priv,
414 struct wsm_join_cnf *arg,
415 struct wsm_buf *buf)
416{
417 arg->status = WSM_GET32(buf);
418 if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
419 return -EINVAL;
420
421 arg->min_power_level = WSM_GET32(buf);
422 arg->max_power_level = WSM_GET32(buf);
423
424 return 0;
425
426underflow:
427 WARN_ON(1);
428 return -EINVAL;
429}
430
431int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
432{
433 int ret;
434 struct wsm_buf *buf = &priv->wsm_cmd_buf;
435 struct wsm_join_cnf resp;
436 wsm_cmd_lock(priv);
437
438 WSM_PUT8(buf, arg->mode);
439 WSM_PUT8(buf, arg->band);
440 WSM_PUT16(buf, arg->channel_number);
441 WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
442 WSM_PUT16(buf, arg->atim_window);
443 WSM_PUT8(buf, arg->preamble_type);
444 WSM_PUT8(buf, arg->probe_for_join);
445 WSM_PUT8(buf, arg->dtim_period);
446 WSM_PUT8(buf, arg->flags);
447 WSM_PUT32(buf, arg->ssid_len);
448 WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
449 WSM_PUT32(buf, arg->beacon_interval);
450 WSM_PUT32(buf, arg->basic_rate_set);
451
452 priv->tx_burst_idx = -1;
453 ret = wsm_cmd_send(priv, buf, &resp,
454 WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
455 /* TODO: Update state based on resp.min|max_power_level */
456
457 priv->join_complete_status = resp.status;
458
459 wsm_cmd_unlock(priv);
460 return ret;
461
462nomem:
463 wsm_cmd_unlock(priv);
464 return -ENOMEM;
465}
466
467/* ******************************************************************** */
468
469int wsm_set_bss_params(struct cw1200_common *priv,
470 const struct wsm_set_bss_params *arg)
471{
472 int ret;
473 struct wsm_buf *buf = &priv->wsm_cmd_buf;
474
475 wsm_cmd_lock(priv);
476
477 WSM_PUT8(buf, (arg->reset_beacon_loss ? 0x1 : 0));
478 WSM_PUT8(buf, arg->beacon_lost_count);
479 WSM_PUT16(buf, arg->aid);
480 WSM_PUT32(buf, arg->operational_rate_set);
481
482 ret = wsm_cmd_send(priv, buf, NULL,
483 WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
484
485 wsm_cmd_unlock(priv);
486 return ret;
487
488nomem:
489 wsm_cmd_unlock(priv);
490 return -ENOMEM;
491}
492
493/* ******************************************************************** */
494
495int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
496{
497 int ret;
498 struct wsm_buf *buf = &priv->wsm_cmd_buf;
499
500 wsm_cmd_lock(priv);
501
502 WSM_PUT(buf, arg, sizeof(*arg));
503
504 ret = wsm_cmd_send(priv, buf, NULL,
505 WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
506
507 wsm_cmd_unlock(priv);
508 return ret;
509
510nomem:
511 wsm_cmd_unlock(priv);
512 return -ENOMEM;
513}
514
515/* ******************************************************************** */
516
517int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
518{
519 int ret;
520 struct wsm_buf *buf = &priv->wsm_cmd_buf;
521
522 wsm_cmd_lock(priv);
523
524 WSM_PUT8(buf, arg->index);
525 WSM_PUT8(buf, 0);
526 WSM_PUT16(buf, 0);
527
528 ret = wsm_cmd_send(priv, buf, NULL,
529 WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
530
531 wsm_cmd_unlock(priv);
532 return ret;
533
534nomem:
535 wsm_cmd_unlock(priv);
536 return -ENOMEM;
537}
538
539/* ******************************************************************** */
540
541int wsm_set_tx_queue_params(struct cw1200_common *priv,
542 const struct wsm_set_tx_queue_params *arg, u8 id)
543{
544 int ret;
545 struct wsm_buf *buf = &priv->wsm_cmd_buf;
546 u8 queue_id_to_wmm_aci[] = {3, 2, 0, 1};
547
548 wsm_cmd_lock(priv);
549
550 WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
551 WSM_PUT8(buf, 0);
552 WSM_PUT8(buf, arg->ackPolicy);
553 WSM_PUT8(buf, 0);
554 WSM_PUT32(buf, arg->maxTransmitLifetime);
555 WSM_PUT16(buf, arg->allowedMediumTime);
556 WSM_PUT16(buf, 0);
557
558 ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
559
560 wsm_cmd_unlock(priv);
561 return ret;
562
563nomem:
564 wsm_cmd_unlock(priv);
565 return -ENOMEM;
566}
567
568/* ******************************************************************** */
569
570int wsm_set_edca_params(struct cw1200_common *priv,
571 const struct wsm_edca_params *arg)
572{
573 int ret;
574 struct wsm_buf *buf = &priv->wsm_cmd_buf;
575
576 wsm_cmd_lock(priv);
577
578 /* Implemented according to specification. */
579
580 WSM_PUT16(buf, arg->params[3].cwmin);
581 WSM_PUT16(buf, arg->params[2].cwmin);
582 WSM_PUT16(buf, arg->params[1].cwmin);
583 WSM_PUT16(buf, arg->params[0].cwmin);
584
585 WSM_PUT16(buf, arg->params[3].cwmax);
586 WSM_PUT16(buf, arg->params[2].cwmax);
587 WSM_PUT16(buf, arg->params[1].cwmax);
588 WSM_PUT16(buf, arg->params[0].cwmax);
589
590 WSM_PUT8(buf, arg->params[3].aifns);
591 WSM_PUT8(buf, arg->params[2].aifns);
592 WSM_PUT8(buf, arg->params[1].aifns);
593 WSM_PUT8(buf, arg->params[0].aifns);
594
595 WSM_PUT16(buf, arg->params[3].txop_limit);
596 WSM_PUT16(buf, arg->params[2].txop_limit);
597 WSM_PUT16(buf, arg->params[1].txop_limit);
598 WSM_PUT16(buf, arg->params[0].txop_limit);
599
600 WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
601 WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
602 WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
603 WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
604
605 ret = wsm_cmd_send(priv, buf, NULL,
606 WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
607 wsm_cmd_unlock(priv);
608 return ret;
609
610nomem:
611 wsm_cmd_unlock(priv);
612 return -ENOMEM;
613}
614
615/* ******************************************************************** */
616
617int wsm_switch_channel(struct cw1200_common *priv,
618 const struct wsm_switch_channel *arg)
619{
620 int ret;
621 struct wsm_buf *buf = &priv->wsm_cmd_buf;
622
623 wsm_cmd_lock(priv);
624
625 WSM_PUT8(buf, arg->mode);
626 WSM_PUT8(buf, arg->switch_count);
627 WSM_PUT16(buf, arg->channel_number);
628
629 priv->channel_switch_in_progress = 1;
630
631 ret = wsm_cmd_send(priv, buf, NULL,
632 WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
633 if (ret)
634 priv->channel_switch_in_progress = 0;
635
636 wsm_cmd_unlock(priv);
637 return ret;
638
639nomem:
640 wsm_cmd_unlock(priv);
641 return -ENOMEM;
642}
643
644/* ******************************************************************** */
645
646int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
647{
648 int ret;
649 struct wsm_buf *buf = &priv->wsm_cmd_buf;
650 priv->ps_mode_switch_in_progress = 1;
651
652 wsm_cmd_lock(priv);
653
654 WSM_PUT8(buf, arg->mode);
655 WSM_PUT8(buf, arg->fast_psm_idle_period);
656 WSM_PUT8(buf, arg->ap_psm_change_period);
657 WSM_PUT8(buf, arg->min_auto_pspoll_period);
658
659 ret = wsm_cmd_send(priv, buf, NULL,
660 WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
661
662 wsm_cmd_unlock(priv);
663 return ret;
664
665nomem:
666 wsm_cmd_unlock(priv);
667 return -ENOMEM;
668}
669
670/* ******************************************************************** */
671
672int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
673{
674 int ret;
675 struct wsm_buf *buf = &priv->wsm_cmd_buf;
676
677 wsm_cmd_lock(priv);
678
679 WSM_PUT8(buf, arg->mode);
680 WSM_PUT8(buf, arg->band);
681 WSM_PUT16(buf, arg->channel_number);
682 WSM_PUT32(buf, arg->ct_window);
683 WSM_PUT32(buf, arg->beacon_interval);
684 WSM_PUT8(buf, arg->dtim_period);
685 WSM_PUT8(buf, arg->preamble);
686 WSM_PUT8(buf, arg->probe_delay);
687 WSM_PUT8(buf, arg->ssid_len);
688 WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
689 WSM_PUT32(buf, arg->basic_rate_set);
690
691 priv->tx_burst_idx = -1;
692 ret = wsm_cmd_send(priv, buf, NULL,
693 WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
694
695 wsm_cmd_unlock(priv);
696 return ret;
697
698nomem:
699 wsm_cmd_unlock(priv);
700 return -ENOMEM;
701}
702
703/* ******************************************************************** */
704
705int wsm_beacon_transmit(struct cw1200_common *priv,
706 const struct wsm_beacon_transmit *arg)
707{
708 int ret;
709 struct wsm_buf *buf = &priv->wsm_cmd_buf;
710
711 wsm_cmd_lock(priv);
712
713 WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
714
715 ret = wsm_cmd_send(priv, buf, NULL,
716 WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
717
718 wsm_cmd_unlock(priv);
719 return ret;
720
721nomem:
722 wsm_cmd_unlock(priv);
723 return -ENOMEM;
724}
725
726/* ******************************************************************** */
727
728int wsm_start_find(struct cw1200_common *priv)
729{
730 int ret;
731 struct wsm_buf *buf = &priv->wsm_cmd_buf;
732
733 wsm_cmd_lock(priv);
734 ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
735 wsm_cmd_unlock(priv);
736 return ret;
737}
738
739/* ******************************************************************** */
740
741int wsm_stop_find(struct cw1200_common *priv)
742{
743 int ret;
744 struct wsm_buf *buf = &priv->wsm_cmd_buf;
745
746 wsm_cmd_lock(priv);
747 ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
748 wsm_cmd_unlock(priv);
749 return ret;
750}
751
752/* ******************************************************************** */
753
754int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
755{
756 int ret;
757 struct wsm_buf *buf = &priv->wsm_cmd_buf;
758 u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
759
760 wsm_cmd_lock(priv);
761
762 WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
763 WSM_PUT16(buf, 0);
764
765 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
766
767 wsm_cmd_unlock(priv);
768 return ret;
769
770nomem:
771 wsm_cmd_unlock(priv);
772 return -ENOMEM;
773}
774
775/* ******************************************************************** */
776
777int wsm_update_ie(struct cw1200_common *priv,
778 const struct wsm_update_ie *arg)
779{
780 int ret;
781 struct wsm_buf *buf = &priv->wsm_cmd_buf;
782
783 wsm_cmd_lock(priv);
784
785 WSM_PUT16(buf, arg->what);
786 WSM_PUT16(buf, arg->count);
787 WSM_PUT(buf, arg->ies, arg->length);
788
789 ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
790
791 wsm_cmd_unlock(priv);
792 return ret;
793
794nomem:
795 wsm_cmd_unlock(priv);
796 return -ENOMEM;
797}
798
799/* ******************************************************************** */
800int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
801{
802 priv->rx_filter.probeResponder = enable;
803 return wsm_set_rx_filter(priv, &priv->rx_filter);
804}
805
806/* ******************************************************************** */
807/* WSM indication events implementation */
808const char * const cw1200_fw_types[] = {
809 "ETF",
810 "WFM",
811 "WSM",
812 "HI test",
813 "Platform test"
814};
815
816static int wsm_startup_indication(struct cw1200_common *priv,
817 struct wsm_buf *buf)
818{
819 priv->wsm_caps.input_buffers = WSM_GET16(buf);
820 priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
821 priv->wsm_caps.hw_id = WSM_GET16(buf);
822 priv->wsm_caps.hw_subid = WSM_GET16(buf);
823 priv->wsm_caps.status = WSM_GET16(buf);
824 priv->wsm_caps.fw_cap = WSM_GET16(buf);
825 priv->wsm_caps.fw_type = WSM_GET16(buf);
826 priv->wsm_caps.fw_api = WSM_GET16(buf);
827 priv->wsm_caps.fw_build = WSM_GET16(buf);
828 priv->wsm_caps.fw_ver = WSM_GET16(buf);
829 WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
830 priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
831
832 if (WARN_ON(priv->wsm_caps.status))
833 return -EINVAL;
834
835 if (WARN_ON(priv->wsm_caps.fw_type > 4))
836 return -EINVAL;
837
838 pr_info("CW1200 WSM init done.\n"
839 " Input buffers: %d x %d bytes\n"
840 " Hardware: %d.%d\n"
841 " %s firmware [%s], ver: %d, build: %d,"
842 " api: %d, cap: 0x%.4X\n",
843 priv->wsm_caps.input_buffers,
844 priv->wsm_caps.input_buffer_size,
845 priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
846 cw1200_fw_types[priv->wsm_caps.fw_type],
847 priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
848 priv->wsm_caps.fw_build,
849 priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
850
851 /* Disable unsupported frequency bands */
852 if (!(priv->wsm_caps.fw_cap & 0x1))
853 priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
854 if (!(priv->wsm_caps.fw_cap & 0x2))
855 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
856
857 priv->firmware_ready = 1;
858 wake_up(&priv->wsm_startup_done);
859 return 0;
860
861underflow:
862 WARN_ON(1);
863 return -EINVAL;
864}
865
866static int wsm_receive_indication(struct cw1200_common *priv,
867 int link_id,
868 struct wsm_buf *buf,
869 struct sk_buff **skb_p)
870{
871 struct wsm_rx rx;
872 struct ieee80211_hdr *hdr;
873 size_t hdr_len;
874 __le16 fctl;
875
876 rx.status = WSM_GET32(buf);
877 rx.channel_number = WSM_GET16(buf);
878 rx.rx_rate = WSM_GET8(buf);
879 rx.rcpi_rssi = WSM_GET8(buf);
880 rx.flags = WSM_GET32(buf);
881
882 /* FW Workaround: Drop probe resp or
883 beacon when RSSI is 0
884 */
885 hdr = (struct ieee80211_hdr *)(*skb_p)->data;
886
887 if (!rx.rcpi_rssi &&
888 (ieee80211_is_probe_resp(hdr->frame_control) ||
889 ieee80211_is_beacon(hdr->frame_control)))
890 return 0;
891
892 /* If no RSSI subscription has been made,
893 * convert RCPI to RSSI here
894 */
895 if (!priv->cqm_use_rssi)
896 rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
897
898 fctl = *(__le16 *)buf->data;
899 hdr_len = buf->data - buf->begin;
900 skb_pull(*skb_p, hdr_len);
901 if (!rx.status && ieee80211_is_deauth(fctl)) {
902 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
903 /* Shedule unjoin work */
904 pr_debug("[WSM] Issue unjoin command (RX).\n");
905 wsm_lock_tx_async(priv);
906 if (queue_work(priv->workqueue,
907 &priv->unjoin_work) <= 0)
908 wsm_unlock_tx(priv);
909 }
910 }
911 cw1200_rx_cb(priv, &rx, link_id, skb_p);
912 if (*skb_p)
913 skb_push(*skb_p, hdr_len);
914
915 return 0;
916
917underflow:
918 return -EINVAL;
919}
920
921static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
922{
923 int first;
924 struct cw1200_wsm_event *event;
925
926 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
927 /* STA is stopped. */
928 return 0;
929 }
930
931 event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
932
933 event->evt.id = __le32_to_cpu(WSM_GET32(buf));
934 event->evt.data = __le32_to_cpu(WSM_GET32(buf));
935
936 pr_debug("[WSM] Event: %d(%d)\n",
937 event->evt.id, event->evt.data);
938
939 spin_lock(&priv->event_queue_lock);
940 first = list_empty(&priv->event_queue);
941 list_add_tail(&event->link, &priv->event_queue);
942 spin_unlock(&priv->event_queue_lock);
943
944 if (first)
945 queue_work(priv->workqueue, &priv->event_handler);
946
947 return 0;
948
949underflow:
950 kfree(event);
951 return -EINVAL;
952}
953
954static int wsm_channel_switch_indication(struct cw1200_common *priv,
955 struct wsm_buf *buf)
956{
957 WARN_ON(WSM_GET32(buf));
958
959 priv->channel_switch_in_progress = 0;
960 wake_up(&priv->channel_switch_done);
961
962 wsm_unlock_tx(priv);
963
964 return 0;
965
966underflow:
967 return -EINVAL;
968}
969
970static int wsm_set_pm_indication(struct cw1200_common *priv,
971 struct wsm_buf *buf)
972{
973 /* TODO: Check buf (struct wsm_set_pm_complete) for validity */
974 if (priv->ps_mode_switch_in_progress) {
975 priv->ps_mode_switch_in_progress = 0;
976 wake_up(&priv->ps_mode_switch_done);
977 }
978 return 0;
979}
980
981static int wsm_scan_started(struct cw1200_common *priv, void *arg,
982 struct wsm_buf *buf)
983{
984 u32 status = WSM_GET32(buf);
985 if (status != WSM_STATUS_SUCCESS) {
986 cw1200_scan_failed_cb(priv);
987 return -EINVAL;
988 }
989 return 0;
990
991underflow:
992 WARN_ON(1);
993 return -EINVAL;
994}
995
996static int wsm_scan_complete_indication(struct cw1200_common *priv,
997 struct wsm_buf *buf)
998{
999 struct wsm_scan_complete arg;
1000 arg.status = WSM_GET32(buf);
1001 arg.psm = WSM_GET8(buf);
1002 arg.num_channels = WSM_GET8(buf);
1003 cw1200_scan_complete_cb(priv, &arg);
1004
1005 return 0;
1006
1007underflow:
1008 return -EINVAL;
1009}
1010
1011static int wsm_join_complete_indication(struct cw1200_common *priv,
1012 struct wsm_buf *buf)
1013{
1014 struct wsm_join_complete arg;
1015 arg.status = WSM_GET32(buf);
1016 pr_debug("[WSM] Join complete indication, status: %d\n", arg.status);
1017 cw1200_join_complete_cb(priv, &arg);
1018
1019 return 0;
1020
1021underflow:
1022 return -EINVAL;
1023}
1024
1025static int wsm_find_complete_indication(struct cw1200_common *priv,
1026 struct wsm_buf *buf)
1027{
1028 pr_warn("Implement find_complete_indication\n");
1029 return 0;
1030}
1031
1032static int wsm_ba_timeout_indication(struct cw1200_common *priv,
1033 struct wsm_buf *buf)
1034{
1035 u32 dummy;
1036 u8 tid;
1037 u8 dummy2;
1038 u8 addr[ETH_ALEN];
1039
1040 dummy = WSM_GET32(buf);
1041 tid = WSM_GET8(buf);
1042 dummy2 = WSM_GET8(buf);
1043 WSM_GET(buf, addr, ETH_ALEN);
1044
1045 pr_info("BlockACK timeout, tid %d, addr %pM\n",
1046 tid, addr);
1047
1048 return 0;
1049
1050underflow:
1051 return -EINVAL;
1052}
1053
1054static int wsm_suspend_resume_indication(struct cw1200_common *priv,
1055 int link_id, struct wsm_buf *buf)
1056{
1057 u32 flags;
1058 struct wsm_suspend_resume arg;
1059
1060 flags = WSM_GET32(buf);
1061 arg.link_id = link_id;
1062 arg.stop = !(flags & 1);
1063 arg.multicast = !!(flags & 8);
1064 arg.queue = (flags >> 1) & 3;
1065
1066 cw1200_suspend_resume(priv, &arg);
1067
1068 return 0;
1069
1070underflow:
1071 return -EINVAL;
1072}
1073
1074
1075/* ******************************************************************** */
1076/* WSM TX */
1077
1078static int wsm_cmd_send(struct cw1200_common *priv,
1079 struct wsm_buf *buf,
1080 void *arg, u16 cmd, long tmo)
1081{
1082 size_t buf_len = buf->data - buf->begin;
1083 int ret;
1084
1085 /* Don't bother if we're dead. */
1086 if (priv->bh_error) {
1087 ret = 0;
1088 goto done;
1089 }
1090
1091 /* Block until the cmd buffer is completed. Tortuous. */
1092 spin_lock(&priv->wsm_cmd.lock);
1093 while (!priv->wsm_cmd.done) {
1094 spin_unlock(&priv->wsm_cmd.lock);
1095 spin_lock(&priv->wsm_cmd.lock);
1096 }
1097 priv->wsm_cmd.done = 0;
1098 spin_unlock(&priv->wsm_cmd.lock);
1099
1100 if (cmd == WSM_WRITE_MIB_REQ_ID ||
1101 cmd == WSM_READ_MIB_REQ_ID)
1102 pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n",
1103 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]),
1104 buf_len);
1105 else
1106 pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
1107
1108 /*
1109 * Due to buggy SPI on CW1200, we need to
1110 * pad the message by a few bytes to ensure
1111 * that it's completely received.
1112 */
1113#ifdef CONFIG_CW1200_ETF
1114 if (!etf_mode)
1115#endif
1116 buf_len += 4;
1117
1118 /* Fill HI message header */
1119 /* BH will add sequence number */
1120 ((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len);
1121 ((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd);
1122
1123 spin_lock(&priv->wsm_cmd.lock);
1124 BUG_ON(priv->wsm_cmd.ptr);
1125 priv->wsm_cmd.ptr = buf->begin;
1126 priv->wsm_cmd.len = buf_len;
1127 priv->wsm_cmd.arg = arg;
1128 priv->wsm_cmd.cmd = cmd;
1129 spin_unlock(&priv->wsm_cmd.lock);
1130
1131 cw1200_bh_wakeup(priv);
1132
1133 /* Wait for command completion */
1134 ret = wait_event_timeout(priv->wsm_cmd_wq,
1135 priv->wsm_cmd.done, tmo);
1136
1137 if (!ret && !priv->wsm_cmd.done) {
1138 spin_lock(&priv->wsm_cmd.lock);
1139 priv->wsm_cmd.done = 1;
1140 priv->wsm_cmd.ptr = NULL;
1141 spin_unlock(&priv->wsm_cmd.lock);
1142 if (priv->bh_error) {
1143 /* Return ok to help system cleanup */
1144 ret = 0;
1145 } else {
1146 pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd);
1147 print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE,
1148 buf->begin, buf_len);
1149 pr_err("Outstanding outgoing frames: %d\n", priv->hw_bufs_used);
1150
1151 /* Kill BH thread to report the error to the top layer. */
1152 atomic_add(1, &priv->bh_term);
1153 wake_up(&priv->bh_wq);
1154 ret = -ETIMEDOUT;
1155 }
1156 } else {
1157 spin_lock(&priv->wsm_cmd.lock);
1158 BUG_ON(!priv->wsm_cmd.done);
1159 ret = priv->wsm_cmd.ret;
1160 spin_unlock(&priv->wsm_cmd.lock);
1161 }
1162done:
1163 wsm_buf_reset(buf);
1164 return ret;
1165}
1166
1167#ifdef CONFIG_CW1200_ETF
1168int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len)
1169{
1170 struct wsm_buf *buf = &priv->wsm_cmd_buf;
1171 int ret;
1172
1173 u16 *cmd = (u16 *)(data + 2);
1174
1175 wsm_cmd_lock(priv);
1176
1177 WSM_PUT(buf, data + 4, len - 4); /* Skip over header (u16+u16) */
1178
1179 ret = wsm_cmd_send(priv, buf, NULL, __le16_to_cpu(*cmd), WSM_CMD_TIMEOUT);
1180
1181 wsm_cmd_unlock(priv);
1182 return ret;
1183
1184nomem:
1185 wsm_cmd_unlock(priv);
1186 return -ENOMEM;
1187}
1188#endif /* CONFIG_CW1200_ETF */
1189
1190/* ******************************************************************** */
1191/* WSM TX port control */
1192
1193void wsm_lock_tx(struct cw1200_common *priv)
1194{
1195 wsm_cmd_lock(priv);
1196 if (atomic_add_return(1, &priv->tx_lock) == 1) {
1197 if (wsm_flush_tx(priv))
1198 pr_debug("[WSM] TX is locked.\n");
1199 }
1200 wsm_cmd_unlock(priv);
1201}
1202
1203void wsm_lock_tx_async(struct cw1200_common *priv)
1204{
1205 if (atomic_add_return(1, &priv->tx_lock) == 1)
1206 pr_debug("[WSM] TX is locked (async).\n");
1207}
1208
1209bool wsm_flush_tx(struct cw1200_common *priv)
1210{
1211 unsigned long timestamp = jiffies;
1212 bool pending = false;
1213 long timeout;
1214 int i;
1215
1216 /* Flush must be called with TX lock held. */
1217 BUG_ON(!atomic_read(&priv->tx_lock));
1218
1219 /* First check if we really need to do something.
1220 * It is safe to use unprotected access, as hw_bufs_used
1221 * can only decrements.
1222 */
1223 if (!priv->hw_bufs_used)
1224 return true;
1225
1226 if (priv->bh_error) {
1227 /* In case of failure do not wait for magic. */
1228 pr_err("[WSM] Fatal error occured, will not flush TX.\n");
1229 return false;
1230 } else {
1231 /* Get a timestamp of "oldest" frame */
1232 for (i = 0; i < 4; ++i)
1233 pending |= cw1200_queue_get_xmit_timestamp(
1234 &priv->tx_queue[i],
1235 &timestamp, 0xffffffff);
1236 /* If there's nothing pending, we're good */
1237 if (!pending)
1238 return true;
1239
1240 timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
1241 if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq,
1242 !priv->hw_bufs_used,
1243 timeout) <= 0) {
1244 /* Hmmm... Not good. Frame had stuck in firmware. */
1245 priv->bh_error = 1;
1246 wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used);
1247 wake_up(&priv->bh_wq);
1248 return false;
1249 }
1250
1251 /* Ok, everything is flushed. */
1252 return true;
1253 }
1254}
1255
1256void wsm_unlock_tx(struct cw1200_common *priv)
1257{
1258 int tx_lock;
1259 tx_lock = atomic_sub_return(1, &priv->tx_lock);
1260 BUG_ON(tx_lock < 0);
1261
1262 if (tx_lock == 0) {
1263 if (!priv->bh_error)
1264 cw1200_bh_wakeup(priv);
1265 pr_debug("[WSM] TX is unlocked.\n");
1266 }
1267}
1268
1269/* ******************************************************************** */
1270/* WSM RX */
1271
1272int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len)
1273{
1274 struct wsm_buf buf;
1275 u32 reason;
1276 u32 reg[18];
1277 char fname[48];
1278 unsigned int i;
1279
1280 static const char * const reason_str[] = {
1281 "undefined instruction",
1282 "prefetch abort",
1283 "data abort",
1284 "unknown error",
1285 };
1286
1287 buf.begin = buf.data = data;
1288 buf.end = &buf.begin[len];
1289
1290 reason = WSM_GET32(&buf);
1291 for (i = 0; i < ARRAY_SIZE(reg); ++i)
1292 reg[i] = WSM_GET32(&buf);
1293 WSM_GET(&buf, fname, sizeof(fname));
1294
1295 if (reason < 4)
1296 wiphy_err(priv->hw->wiphy,
1297 "Firmware exception: %s.\n",
1298 reason_str[reason]);
1299 else
1300 wiphy_err(priv->hw->wiphy,
1301 "Firmware assert at %.*s, line %d\n",
1302 (int) sizeof(fname), fname, reg[1]);
1303
1304 for (i = 0; i < 12; i += 4)
1305 wiphy_err(priv->hw->wiphy,
1306 "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n",
1307 i + 0, reg[i + 0], i + 1, reg[i + 1],
1308 i + 2, reg[i + 2], i + 3, reg[i + 3]);
1309 wiphy_err(priv->hw->wiphy,
1310 "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n",
1311 reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]);
1312 i += 4;
1313 wiphy_err(priv->hw->wiphy,
1314 "CPSR: 0x%.8X, SPSR: 0x%.8X\n",
1315 reg[i + 0], reg[i + 1]);
1316
1317 print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE,
1318 fname, sizeof(fname));
1319 return 0;
1320
1321underflow:
1322 wiphy_err(priv->hw->wiphy, "Firmware exception.\n");
1323 print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE,
1324 data, len);
1325 return -EINVAL;
1326}
1327
1328int wsm_handle_rx(struct cw1200_common *priv, u16 id,
1329 struct wsm_hdr *wsm, struct sk_buff **skb_p)
1330{
1331 int ret = 0;
1332 struct wsm_buf wsm_buf;
1333 int link_id = (id >> 6) & 0x0F;
1334
1335 /* Strip link id. */
1336 id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1337
1338 wsm_buf.begin = (u8 *)&wsm[0];
1339 wsm_buf.data = (u8 *)&wsm[1];
1340 wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)];
1341
1342 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
1343 wsm_buf.end - wsm_buf.begin);
1344
1345#ifdef CONFIG_CW1200_ETF
1346 if (etf_mode) {
1347 struct sk_buff *skb = alloc_skb(wsm_buf.end - wsm_buf.begin, GFP_KERNEL);
1348
1349 /* Strip out Sequence num before passing up */
1350 wsm->id = __le16_to_cpu(wsm->id);
1351 wsm->id &= 0x0FFF;
1352 wsm->id = __cpu_to_le16(wsm->id);
1353
1354 memcpy(skb_put(skb, wsm_buf.end - wsm_buf.begin),
1355 wsm_buf.begin,
1356 wsm_buf.end - wsm_buf.begin);
1357 skb_queue_tail(&priv->etf_q, skb);
1358
1359 /* Special case for startup */
1360 if (id == WSM_STARTUP_IND_ID) {
1361 wsm_startup_indication(priv, &wsm_buf);
1362 } else if (id & 0x0400) {
1363 spin_lock(&priv->wsm_cmd.lock);
1364 priv->wsm_cmd.done = 1;
1365 spin_unlock(&priv->wsm_cmd.lock);
1366 wake_up(&priv->wsm_cmd_wq);
1367 }
1368
1369 goto out;
1370 }
1371#endif
1372
1373 if (id == WSM_TX_CONFIRM_IND_ID) {
1374 ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
1375 } else if (id == WSM_MULTI_TX_CONFIRM_ID) {
1376 ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id);
1377 } else if (id & 0x0400) {
1378 void *wsm_arg;
1379 u16 wsm_cmd;
1380
1381 /* Do not trust FW too much. Protection against repeated
1382 * response and race condition removal (see above).
1383 */
1384 spin_lock(&priv->wsm_cmd.lock);
1385 wsm_arg = priv->wsm_cmd.arg;
1386 wsm_cmd = priv->wsm_cmd.cmd &
1387 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1388 priv->wsm_cmd.cmd = 0xFFFF;
1389 spin_unlock(&priv->wsm_cmd.lock);
1390
1391 if (WARN_ON((id & ~0x0400) != wsm_cmd)) {
1392 /* Note that any non-zero is a fatal retcode. */
1393 ret = -EINVAL;
1394 goto out;
1395 }
1396
1397 /* Note that wsm_arg can be NULL in case of timeout in
1398 * wsm_cmd_send().
1399 */
1400
1401 switch (id) {
1402 case WSM_READ_MIB_RESP_ID:
1403 if (wsm_arg)
1404 ret = wsm_read_mib_confirm(priv, wsm_arg,
1405 &wsm_buf);
1406 break;
1407 case WSM_WRITE_MIB_RESP_ID:
1408 if (wsm_arg)
1409 ret = wsm_write_mib_confirm(priv, wsm_arg,
1410 &wsm_buf);
1411 break;
1412 case WSM_START_SCAN_RESP_ID:
1413 if (wsm_arg)
1414 ret = wsm_scan_started(priv, wsm_arg, &wsm_buf);
1415 break;
1416 case WSM_CONFIGURATION_RESP_ID:
1417 if (wsm_arg)
1418 ret = wsm_configuration_confirm(priv, wsm_arg,
1419 &wsm_buf);
1420 break;
1421 case WSM_JOIN_RESP_ID:
1422 if (wsm_arg)
1423 ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf);
1424 break;
1425 case WSM_STOP_SCAN_RESP_ID:
1426 case WSM_RESET_RESP_ID:
1427 case WSM_ADD_KEY_RESP_ID:
1428 case WSM_REMOVE_KEY_RESP_ID:
1429 case WSM_SET_PM_RESP_ID:
1430 case WSM_SET_BSS_PARAMS_RESP_ID:
1431 case 0x0412: /* set_tx_queue_params */
1432 case WSM_EDCA_PARAMS_RESP_ID:
1433 case WSM_SWITCH_CHANNEL_RESP_ID:
1434 case WSM_START_RESP_ID:
1435 case WSM_BEACON_TRANSMIT_RESP_ID:
1436 case 0x0419: /* start_find */
1437 case 0x041A: /* stop_find */
1438 case 0x041B: /* update_ie */
1439 case 0x041C: /* map_link */
1440 WARN_ON(wsm_arg != NULL);
1441 ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf);
1442 if (ret) {
1443 wiphy_warn(priv->hw->wiphy,
1444 "wsm_generic_confirm failed for request 0x%04x.\n",
1445 id & ~0x0400);
1446
1447 /* often 0x407 and 0x410 occur, this means we're dead.. */
1448 if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) {
1449 wsm_lock_tx(priv);
1450 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1451 wsm_unlock_tx(priv);
1452 }
1453 }
1454 break;
1455 default:
1456 wiphy_warn(priv->hw->wiphy,
1457 "Unrecognized confirmation 0x%04x\n",
1458 id & ~0x0400);
1459 }
1460
1461 spin_lock(&priv->wsm_cmd.lock);
1462 priv->wsm_cmd.ret = ret;
1463 priv->wsm_cmd.done = 1;
1464 spin_unlock(&priv->wsm_cmd.lock);
1465
1466 ret = 0; /* Error response from device should ne stop BH. */
1467
1468 wake_up(&priv->wsm_cmd_wq);
1469 } else if (id & 0x0800) {
1470 switch (id) {
1471 case WSM_STARTUP_IND_ID:
1472 ret = wsm_startup_indication(priv, &wsm_buf);
1473 break;
1474 case WSM_RECEIVE_IND_ID:
1475 ret = wsm_receive_indication(priv, link_id,
1476 &wsm_buf, skb_p);
1477 break;
1478 case 0x0805:
1479 ret = wsm_event_indication(priv, &wsm_buf);
1480 break;
1481 case WSM_SCAN_COMPLETE_IND_ID:
1482 ret = wsm_scan_complete_indication(priv, &wsm_buf);
1483 break;
1484 case 0x0808:
1485 ret = wsm_ba_timeout_indication(priv, &wsm_buf);
1486 break;
1487 case 0x0809:
1488 ret = wsm_set_pm_indication(priv, &wsm_buf);
1489 break;
1490 case 0x080A:
1491 ret = wsm_channel_switch_indication(priv, &wsm_buf);
1492 break;
1493 case 0x080B:
1494 ret = wsm_find_complete_indication(priv, &wsm_buf);
1495 break;
1496 case 0x080C:
1497 ret = wsm_suspend_resume_indication(priv,
1498 link_id, &wsm_buf);
1499 break;
1500 case 0x080F:
1501 ret = wsm_join_complete_indication(priv, &wsm_buf);
1502 break;
1503 default:
1504 pr_warn("Unrecognised WSM ID %04x\n", id);
1505 }
1506 } else {
1507 WARN_ON(1);
1508 ret = -EINVAL;
1509 }
1510out:
1511 return ret;
1512}
1513
1514static bool wsm_handle_tx_data(struct cw1200_common *priv,
1515 struct wsm_tx *wsm,
1516 const struct ieee80211_tx_info *tx_info,
1517 const struct cw1200_txpriv *txpriv,
1518 struct cw1200_queue *queue)
1519{
1520 bool handled = false;
1521 const struct ieee80211_hdr *frame =
1522 (struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset];
1523 __le16 fctl = frame->frame_control;
1524 enum {
1525 do_probe,
1526 do_drop,
1527 do_wep,
1528 do_tx,
1529 } action = do_tx;
1530
1531 switch (priv->mode) {
1532 case NL80211_IFTYPE_STATION:
1533 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
1534 action = do_tx;
1535 else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA)
1536 action = do_drop;
1537 break;
1538 case NL80211_IFTYPE_AP:
1539 if (!priv->join_status) {
1540 action = do_drop;
1541 } else if (!(BIT(txpriv->raw_link_id) &
1542 (BIT(0) | priv->link_id_map))) {
1543 wiphy_warn(priv->hw->wiphy,
1544 "A frame with expired link id is dropped.\n");
1545 action = do_drop;
1546 }
1547 if (cw1200_queue_get_generation(wsm->packet_id) >
1548 CW1200_MAX_REQUEUE_ATTEMPTS) {
1549 /* HACK!!! WSM324 firmware has tendency to requeue
1550 * multicast frames in a loop, causing performance
1551 * drop and high power consumption of the driver.
1552 * In this situation it is better just to drop
1553 * the problematic frame.
1554 */
1555 wiphy_warn(priv->hw->wiphy,
1556 "Too many attempts to requeue a frame; dropped.\n");
1557 action = do_drop;
1558 }
1559 break;
1560 case NL80211_IFTYPE_ADHOC:
1561 if (priv->join_status != CW1200_JOIN_STATUS_IBSS)
1562 action = do_drop;
1563 break;
1564 case NL80211_IFTYPE_MESH_POINT:
1565 action = do_tx; /* TODO: Test me! */
1566 break;
1567 case NL80211_IFTYPE_MONITOR:
1568 default:
1569 action = do_drop;
1570 break;
1571 }
1572
1573 if (action == do_tx) {
1574 if (ieee80211_is_nullfunc(fctl)) {
1575 spin_lock(&priv->bss_loss_lock);
1576 if (priv->bss_loss_state) {
1577 priv->bss_loss_confirm_id = wsm->packet_id;
1578 wsm->queue_id = WSM_QUEUE_VOICE;
1579 }
1580 spin_unlock(&priv->bss_loss_lock);
1581 } else if (ieee80211_is_probe_req(fctl)) {
1582 action = do_probe;
1583 } else if (ieee80211_is_deauth(fctl) &&
1584 priv->mode != NL80211_IFTYPE_AP) {
1585 pr_debug("[WSM] Issue unjoin command due to tx deauth.\n");
1586 wsm_lock_tx_async(priv);
1587 if (queue_work(priv->workqueue,
1588 &priv->unjoin_work) <= 0)
1589 wsm_unlock_tx(priv);
1590 } else if (ieee80211_has_protected(fctl) &&
1591 tx_info->control.hw_key &&
1592 tx_info->control.hw_key->keyidx != priv->wep_default_key_id &&
1593 (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
1594 tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
1595 action = do_wep;
1596 }
1597 }
1598
1599 switch (action) {
1600 case do_probe:
1601 /* An interesting FW "feature". Device filters probe responses.
1602 * The easiest way to get it back is to convert
1603 * probe request into WSM start_scan command.
1604 */
1605 pr_debug("[WSM] Convert probe request to scan.\n");
1606 wsm_lock_tx_async(priv);
1607 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1608 if (queue_delayed_work(priv->workqueue,
1609 &priv->scan.probe_work, 0) <= 0)
1610 wsm_unlock_tx(priv);
1611 handled = true;
1612 break;
1613 case do_drop:
1614 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
1615 BUG_ON(cw1200_queue_remove(queue,
1616 __le32_to_cpu(wsm->packet_id)));
1617 handled = true;
1618 break;
1619 case do_wep:
1620 pr_debug("[WSM] Issue set_default_wep_key.\n");
1621 wsm_lock_tx_async(priv);
1622 priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
1623 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1624 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
1625 wsm_unlock_tx(priv);
1626 handled = true;
1627 break;
1628 case do_tx:
1629 pr_debug("[WSM] Transmit frame.\n");
1630 break;
1631 default:
1632 /* Do nothing */
1633 break;
1634 }
1635 return handled;
1636}
1637
1638static int cw1200_get_prio_queue(struct cw1200_common *priv,
1639 u32 link_id_map, int *total)
1640{
1641 static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) |
1642 BIT(CW1200_LINK_ID_UAPSD);
1643 struct wsm_edca_queue_params *edca;
1644 unsigned score, best = -1;
1645 int winner = -1;
1646 int queued;
1647 int i;
1648
1649 /* search for a winner using edca params */
1650 for (i = 0; i < 4; ++i) {
1651 queued = cw1200_queue_get_num_queued(&priv->tx_queue[i],
1652 link_id_map);
1653 if (!queued)
1654 continue;
1655 *total += queued;
1656 edca = &priv->edca.params[i];
1657 score = ((edca->aifns + edca->cwmin) << 16) +
1658 ((edca->cwmax - edca->cwmin) *
1659 (get_random_int() & 0xFFFF));
1660 if (score < best && (winner < 0 || i != 3)) {
1661 best = score;
1662 winner = i;
1663 }
1664 }
1665
1666 /* override winner if bursting */
1667 if (winner >= 0 && priv->tx_burst_idx >= 0 &&
1668 winner != priv->tx_burst_idx &&
1669 !cw1200_queue_get_num_queued(
1670 &priv->tx_queue[winner],
1671 link_id_map & urgent) &&
1672 cw1200_queue_get_num_queued(
1673 &priv->tx_queue[priv->tx_burst_idx],
1674 link_id_map))
1675 winner = priv->tx_burst_idx;
1676
1677 return winner;
1678}
1679
1680static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv,
1681 struct cw1200_queue **queue_p,
1682 u32 *tx_allowed_mask_p,
1683 bool *more)
1684{
1685 int idx;
1686 u32 tx_allowed_mask;
1687 int total = 0;
1688
1689 /* Search for a queue with multicast frames buffered */
1690 if (priv->tx_multicast) {
1691 tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM);
1692 idx = cw1200_get_prio_queue(priv,
1693 tx_allowed_mask, &total);
1694 if (idx >= 0) {
1695 *more = total > 1;
1696 goto found;
1697 }
1698 }
1699
1700 /* Search for unicast traffic */
1701 tx_allowed_mask = ~priv->sta_asleep_mask;
1702 tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD);
1703 if (priv->sta_asleep_mask) {
1704 tx_allowed_mask |= priv->pspoll_mask;
1705 tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM);
1706 } else {
1707 tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM);
1708 }
1709 idx = cw1200_get_prio_queue(priv,
1710 tx_allowed_mask, &total);
1711 if (idx < 0)
1712 return -ENOENT;
1713
1714found:
1715 *queue_p = &priv->tx_queue[idx];
1716 *tx_allowed_mask_p = tx_allowed_mask;
1717 return 0;
1718}
1719
1720int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1721 size_t *tx_len, int *burst)
1722{
1723 struct wsm_tx *wsm = NULL;
1724 struct ieee80211_tx_info *tx_info;
1725 struct cw1200_queue *queue = NULL;
1726 int queue_num;
1727 u32 tx_allowed_mask = 0;
1728 const struct cw1200_txpriv *txpriv = NULL;
1729 int count = 0;
1730
1731 /* More is used only for broadcasts. */
1732 bool more = false;
1733
1734#ifdef CONFIG_CW1200_ITP
1735 count = cw1200_itp_get_tx(priv, data, tx_len, burst);
1736 if (count)
1737 return count;
1738#endif
1739
1740 if (priv->wsm_cmd.ptr) { /* CMD request */
1741 ++count;
1742 spin_lock(&priv->wsm_cmd.lock);
1743 BUG_ON(!priv->wsm_cmd.ptr);
1744 *data = priv->wsm_cmd.ptr;
1745 *tx_len = priv->wsm_cmd.len;
1746 *burst = 1;
1747 spin_unlock(&priv->wsm_cmd.lock);
1748 } else {
1749 for (;;) {
1750 int ret;
1751
1752 if (atomic_add_return(0, &priv->tx_lock))
1753 break;
1754
1755 spin_lock_bh(&priv->ps_state_lock);
1756
1757 ret = wsm_get_tx_queue_and_mask(priv, &queue,
1758 &tx_allowed_mask, &more);
1759 queue_num = queue - priv->tx_queue;
1760
1761 if (priv->buffered_multicasts &&
1762 (ret || !more) &&
1763 (priv->tx_multicast || !priv->sta_asleep_mask)) {
1764 priv->buffered_multicasts = false;
1765 if (priv->tx_multicast) {
1766 priv->tx_multicast = false;
1767 queue_work(priv->workqueue,
1768 &priv->multicast_stop_work);
1769 }
1770 }
1771
1772 spin_unlock_bh(&priv->ps_state_lock);
1773
1774 if (ret)
1775 break;
1776
1777 if (cw1200_queue_get(queue,
1778 tx_allowed_mask,
1779 &wsm, &tx_info, &txpriv))
1780 continue;
1781
1782 if (wsm_handle_tx_data(priv, wsm,
1783 tx_info, txpriv, queue))
1784 continue; /* Handled by WSM */
1785
1786 wsm->hdr.id &= __cpu_to_le16(
1787 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX));
1788 wsm->hdr.id |= cpu_to_le16(
1789 WSM_TX_LINK_ID(txpriv->raw_link_id));
1790 priv->pspoll_mask &= ~BIT(txpriv->raw_link_id);
1791
1792 *data = (u8 *)wsm;
1793 *tx_len = __le16_to_cpu(wsm->hdr.len);
1794
1795 /* allow bursting if txop is set */
1796 if (priv->edca.params[queue_num].txop_limit)
1797 *burst = min(*burst,
1798 (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1);
1799 else
1800 *burst = 1;
1801
1802 /* store index of bursting queue */
1803 if (*burst > 1)
1804 priv->tx_burst_idx = queue_num;
1805 else
1806 priv->tx_burst_idx = -1;
1807
1808 if (more) {
1809 struct ieee80211_hdr *hdr =
1810 (struct ieee80211_hdr *)
1811 &((u8 *)wsm)[txpriv->offset];
1812 /* more buffered multicast/broadcast frames
1813 * ==> set MoreData flag in IEEE 802.11 header
1814 * to inform PS STAs
1815 */
1816 hdr->frame_control |=
1817 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1818 }
1819
1820 pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n",
1821 0x0004, *tx_len, *data,
1822 wsm->more ? 'M' : ' ');
1823 ++count;
1824 break;
1825 }
1826 }
1827
1828 return count;
1829}
1830
1831void wsm_txed(struct cw1200_common *priv, u8 *data)
1832{
1833 if (data == priv->wsm_cmd.ptr) {
1834 spin_lock(&priv->wsm_cmd.lock);
1835 priv->wsm_cmd.ptr = NULL;
1836 spin_unlock(&priv->wsm_cmd.lock);
1837 }
1838}
1839
1840/* ******************************************************************** */
1841/* WSM buffer */
1842
1843void wsm_buf_init(struct wsm_buf *buf)
1844{
1845 BUG_ON(buf->begin);
1846 buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
1847 buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin;
1848 wsm_buf_reset(buf);
1849}
1850
1851void wsm_buf_deinit(struct wsm_buf *buf)
1852{
1853 kfree(buf->begin);
1854 buf->begin = buf->data = buf->end = NULL;
1855}
1856
1857static void wsm_buf_reset(struct wsm_buf *buf)
1858{
1859 if (buf->begin) {
1860 buf->data = &buf->begin[4];
1861 *(u32 *)buf->begin = 0;
1862 } else {
1863 buf->data = buf->begin;
1864 }
1865}
1866
1867static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
1868{
1869 size_t pos = buf->data - buf->begin;
1870 size_t size = pos + extra_size;
1871
1872 size = round_up(size, FWLOAD_BLOCK_SIZE);
1873
1874 buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
1875 if (buf->begin) {
1876 buf->data = &buf->begin[pos];
1877 buf->end = &buf->begin[size];
1878 return 0;
1879 } else {
1880 buf->end = buf->data = buf->begin;
1881 return -ENOMEM;
1882 }
1883}
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
new file mode 100644
index 000000000000..8d902d6a7dc4
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -0,0 +1,1879 @@
1/*
2 * WSM host interface (HI) interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on CW1200 UMAC WSM API, which is
8 * Copyright (C) ST-Ericsson SA 2010
9 * Author: Stewart Mathers <stewart.mathers@stericsson.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef CW1200_WSM_H_INCLUDED
17#define CW1200_WSM_H_INCLUDED
18
19#include <linux/spinlock.h>
20
21struct cw1200_common;
22
23/* Bands */
24/* Radio band 2.412 -2.484 GHz. */
25#define WSM_PHY_BAND_2_4G (0)
26
27/* Radio band 4.9375-5.8250 GHz. */
28#define WSM_PHY_BAND_5G (1)
29
30/* Transmit rates */
31/* 1 Mbps ERP-DSSS */
32#define WSM_TRANSMIT_RATE_1 (0)
33
34/* 2 Mbps ERP-DSSS */
35#define WSM_TRANSMIT_RATE_2 (1)
36
37/* 5.5 Mbps ERP-CCK */
38#define WSM_TRANSMIT_RATE_5 (2)
39
40/* 11 Mbps ERP-CCK */
41#define WSM_TRANSMIT_RATE_11 (3)
42
43/* 22 Mbps ERP-PBCC (Not supported) */
44/* #define WSM_TRANSMIT_RATE_22 (4) */
45
46/* 33 Mbps ERP-PBCC (Not supported) */
47/* #define WSM_TRANSMIT_RATE_33 (5) */
48
49/* 6 Mbps (3 Mbps) ERP-OFDM, BPSK coding rate 1/2 */
50#define WSM_TRANSMIT_RATE_6 (6)
51
52/* 9 Mbps (4.5 Mbps) ERP-OFDM, BPSK coding rate 3/4 */
53#define WSM_TRANSMIT_RATE_9 (7)
54
55/* 12 Mbps (6 Mbps) ERP-OFDM, QPSK coding rate 1/2 */
56#define WSM_TRANSMIT_RATE_12 (8)
57
58/* 18 Mbps (9 Mbps) ERP-OFDM, QPSK coding rate 3/4 */
59#define WSM_TRANSMIT_RATE_18 (9)
60
61/* 24 Mbps (12 Mbps) ERP-OFDM, 16QAM coding rate 1/2 */
62#define WSM_TRANSMIT_RATE_24 (10)
63
64/* 36 Mbps (18 Mbps) ERP-OFDM, 16QAM coding rate 3/4 */
65#define WSM_TRANSMIT_RATE_36 (11)
66
67/* 48 Mbps (24 Mbps) ERP-OFDM, 64QAM coding rate 1/2 */
68#define WSM_TRANSMIT_RATE_48 (12)
69
70/* 54 Mbps (27 Mbps) ERP-OFDM, 64QAM coding rate 3/4 */
71#define WSM_TRANSMIT_RATE_54 (13)
72
73/* 6.5 Mbps HT-OFDM, BPSK coding rate 1/2 */
74#define WSM_TRANSMIT_RATE_HT_6 (14)
75
76/* 13 Mbps HT-OFDM, QPSK coding rate 1/2 */
77#define WSM_TRANSMIT_RATE_HT_13 (15)
78
79/* 19.5 Mbps HT-OFDM, QPSK coding rate 3/4 */
80#define WSM_TRANSMIT_RATE_HT_19 (16)
81
82/* 26 Mbps HT-OFDM, 16QAM coding rate 1/2 */
83#define WSM_TRANSMIT_RATE_HT_26 (17)
84
85/* 39 Mbps HT-OFDM, 16QAM coding rate 3/4 */
86#define WSM_TRANSMIT_RATE_HT_39 (18)
87
88/* 52 Mbps HT-OFDM, 64QAM coding rate 2/3 */
89#define WSM_TRANSMIT_RATE_HT_52 (19)
90
91/* 58.5 Mbps HT-OFDM, 64QAM coding rate 3/4 */
92#define WSM_TRANSMIT_RATE_HT_58 (20)
93
94/* 65 Mbps HT-OFDM, 64QAM coding rate 5/6 */
95#define WSM_TRANSMIT_RATE_HT_65 (21)
96
97/* Scan types */
98/* Foreground scan */
99#define WSM_SCAN_TYPE_FOREGROUND (0)
100
101/* Background scan */
102#define WSM_SCAN_TYPE_BACKGROUND (1)
103
104/* Auto scan */
105#define WSM_SCAN_TYPE_AUTO (2)
106
107/* Scan flags */
108/* Forced background scan means if the station cannot */
109/* enter the power-save mode, it shall force to perform a */
110/* background scan. Only valid when ScanType is */
111/* background scan. */
112#define WSM_SCAN_FLAG_FORCE_BACKGROUND (BIT(0))
113
114/* The WLAN device scans one channel at a time so */
115/* that disturbance to the data traffic is minimized. */
116#define WSM_SCAN_FLAG_SPLIT_METHOD (BIT(1))
117
118/* Preamble Type. Long if not set. */
119#define WSM_SCAN_FLAG_SHORT_PREAMBLE (BIT(2))
120
121/* 11n Tx Mode. Mixed if not set. */
122#define WSM_SCAN_FLAG_11N_GREENFIELD (BIT(3))
123
124/* Scan constraints */
125/* Maximum number of channels to be scanned. */
126#define WSM_SCAN_MAX_NUM_OF_CHANNELS (48)
127
128/* The maximum number of SSIDs that the device can scan for. */
129#define WSM_SCAN_MAX_NUM_OF_SSIDS (2)
130
131/* Power management modes */
132/* 802.11 Active mode */
133#define WSM_PSM_ACTIVE (0)
134
135/* 802.11 PS mode */
136#define WSM_PSM_PS BIT(0)
137
138/* Fast Power Save bit */
139#define WSM_PSM_FAST_PS_FLAG BIT(7)
140
141/* Dynamic aka Fast power save */
142#define WSM_PSM_FAST_PS (BIT(0) | BIT(7))
143
144/* Undetermined */
145/* Note : Undetermined status is reported when the */
146/* NULL data frame used to advertise the PM mode to */
147/* the AP at Pre or Post Background Scan is not Acknowledged */
148#define WSM_PSM_UNKNOWN BIT(1)
149
150/* Queue IDs */
151/* best effort/legacy */
152#define WSM_QUEUE_BEST_EFFORT (0)
153
154/* background */
155#define WSM_QUEUE_BACKGROUND (1)
156
157/* video */
158#define WSM_QUEUE_VIDEO (2)
159
160/* voice */
161#define WSM_QUEUE_VOICE (3)
162
163/* HT TX parameters */
164/* Non-HT */
165#define WSM_HT_TX_NON_HT (0)
166
167/* Mixed format */
168#define WSM_HT_TX_MIXED (1)
169
170/* Greenfield format */
171#define WSM_HT_TX_GREENFIELD (2)
172
173/* STBC allowed */
174#define WSM_HT_TX_STBC (BIT(7))
175
176/* EPTA prioirty flags for BT Coex */
177/* default epta priority */
178#define WSM_EPTA_PRIORITY_DEFAULT 4
179/* use for normal data */
180#define WSM_EPTA_PRIORITY_DATA 4
181/* use for connect/disconnect/roaming*/
182#define WSM_EPTA_PRIORITY_MGT 5
183/* use for action frames */
184#define WSM_EPTA_PRIORITY_ACTION 5
185/* use for AC_VI data */
186#define WSM_EPTA_PRIORITY_VIDEO 5
187/* use for AC_VO data */
188#define WSM_EPTA_PRIORITY_VOICE 6
189/* use for EAPOL exchange */
190#define WSM_EPTA_PRIORITY_EAPOL 7
191
192/* TX status */
193/* Frame was sent aggregated */
194/* Only valid for WSM_SUCCESS status. */
195#define WSM_TX_STATUS_AGGREGATION (BIT(0))
196
197/* Host should requeue this frame later. */
198/* Valid only when status is WSM_REQUEUE. */
199#define WSM_TX_STATUS_REQUEUE (BIT(1))
200
201/* Normal Ack */
202#define WSM_TX_STATUS_NORMAL_ACK (0<<2)
203
204/* No Ack */
205#define WSM_TX_STATUS_NO_ACK (1<<2)
206
207/* No explicit acknowledgement */
208#define WSM_TX_STATUS_NO_EXPLICIT_ACK (2<<2)
209
210/* Block Ack */
211/* Only valid for WSM_SUCCESS status. */
212#define WSM_TX_STATUS_BLOCK_ACK (3<<2)
213
214/* RX status */
215/* Unencrypted */
216#define WSM_RX_STATUS_UNENCRYPTED (0<<0)
217
218/* WEP */
219#define WSM_RX_STATUS_WEP (1<<0)
220
221/* TKIP */
222#define WSM_RX_STATUS_TKIP (2<<0)
223
224/* AES */
225#define WSM_RX_STATUS_AES (3<<0)
226
227/* WAPI */
228#define WSM_RX_STATUS_WAPI (4<<0)
229
230/* Macro to fetch encryption subfield. */
231#define WSM_RX_STATUS_ENCRYPTION(status) ((status) & 0x07)
232
233/* Frame was part of an aggregation */
234#define WSM_RX_STATUS_AGGREGATE (BIT(3))
235
236/* Frame was first in the aggregation */
237#define WSM_RX_STATUS_AGGREGATE_FIRST (BIT(4))
238
239/* Frame was last in the aggregation */
240#define WSM_RX_STATUS_AGGREGATE_LAST (BIT(5))
241
242/* Indicates a defragmented frame */
243#define WSM_RX_STATUS_DEFRAGMENTED (BIT(6))
244
245/* Indicates a Beacon frame */
246#define WSM_RX_STATUS_BEACON (BIT(7))
247
248/* Indicates STA bit beacon TIM field */
249#define WSM_RX_STATUS_TIM (BIT(8))
250
251/* Indicates Beacon frame's virtual bitmap contains multicast bit */
252#define WSM_RX_STATUS_MULTICAST (BIT(9))
253
254/* Indicates frame contains a matching SSID */
255#define WSM_RX_STATUS_MATCHING_SSID (BIT(10))
256
257/* Indicates frame contains a matching BSSI */
258#define WSM_RX_STATUS_MATCHING_BSSI (BIT(11))
259
260/* Indicates More bit set in Framectl field */
261#define WSM_RX_STATUS_MORE_DATA (BIT(12))
262
263/* Indicates frame received during a measurement process */
264#define WSM_RX_STATUS_MEASUREMENT (BIT(13))
265
266/* Indicates frame received as an HT packet */
267#define WSM_RX_STATUS_HT (BIT(14))
268
269/* Indicates frame received with STBC */
270#define WSM_RX_STATUS_STBC (BIT(15))
271
272/* Indicates Address 1 field matches dot11StationId */
273#define WSM_RX_STATUS_ADDRESS1 (BIT(16))
274
275/* Indicates Group address present in the Address 1 field */
276#define WSM_RX_STATUS_GROUP (BIT(17))
277
278/* Indicates Broadcast address present in the Address 1 field */
279#define WSM_RX_STATUS_BROADCAST (BIT(18))
280
281/* Indicates group key used with encrypted frames */
282#define WSM_RX_STATUS_GROUP_KEY (BIT(19))
283
284/* Macro to fetch encryption key index. */
285#define WSM_RX_STATUS_KEY_IDX(status) (((status >> 20)) & 0x0F)
286
287/* Indicates TSF inclusion after 802.11 frame body */
288#define WSM_RX_STATUS_TSF_INCLUDED (BIT(24))
289
290/* Frame Control field starts at Frame offset + 2 */
291#define WSM_TX_2BYTES_SHIFT (BIT(7))
292
293/* Join mode */
294/* IBSS */
295#define WSM_JOIN_MODE_IBSS (0)
296
297/* BSS */
298#define WSM_JOIN_MODE_BSS (1)
299
300/* PLCP preamble type */
301/* For long preamble */
302#define WSM_JOIN_PREAMBLE_LONG (0)
303
304/* For short preamble (Long for 1Mbps) */
305#define WSM_JOIN_PREAMBLE_SHORT (1)
306
307/* For short preamble (Long for 1 and 2Mbps) */
308#define WSM_JOIN_PREAMBLE_SHORT_2 (2)
309
310/* Join flags */
311/* Unsynchronized */
312#define WSM_JOIN_FLAGS_UNSYNCRONIZED BIT(0)
313/* The BSS owner is a P2P GO */
314#define WSM_JOIN_FLAGS_P2P_GO BIT(1)
315/* Force to join BSS with the BSSID and the
316 * SSID specified without waiting for beacons. The
317 * ProbeForJoin parameter is ignored. */
318#define WSM_JOIN_FLAGS_FORCE BIT(2)
319/* Give probe request/response higher
320 * priority over the BT traffic */
321#define WSM_JOIN_FLAGS_PRIO BIT(3)
322/* Issue immediate join confirmation and use
323 * join complete to notify about completion */
324#define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5)
325
326/* Key types */
327#define WSM_KEY_TYPE_WEP_DEFAULT (0)
328#define WSM_KEY_TYPE_WEP_PAIRWISE (1)
329#define WSM_KEY_TYPE_TKIP_GROUP (2)
330#define WSM_KEY_TYPE_TKIP_PAIRWISE (3)
331#define WSM_KEY_TYPE_AES_GROUP (4)
332#define WSM_KEY_TYPE_AES_PAIRWISE (5)
333#define WSM_KEY_TYPE_WAPI_GROUP (6)
334#define WSM_KEY_TYPE_WAPI_PAIRWISE (7)
335
336/* Key indexes */
337#define WSM_KEY_MAX_INDEX (10)
338
339/* ACK policy */
340#define WSM_ACK_POLICY_NORMAL (0)
341#define WSM_ACK_POLICY_NO_ACK (1)
342
343/* Start modes */
344#define WSM_START_MODE_AP (0) /* Mini AP */
345#define WSM_START_MODE_P2P_GO (1) /* P2P GO */
346#define WSM_START_MODE_P2P_DEV (2) /* P2P device */
347
348/* SetAssociationMode MIB flags */
349#define WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE (BIT(0))
350#define WSM_ASSOCIATION_MODE_USE_HT_MODE (BIT(1))
351#define WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET (BIT(2))
352#define WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING (BIT(3))
353#define WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES (BIT(4))
354
355/* RcpiRssiThreshold MIB flags */
356#define WSM_RCPI_RSSI_THRESHOLD_ENABLE (BIT(0))
357#define WSM_RCPI_RSSI_USE_RSSI (BIT(1))
358#define WSM_RCPI_RSSI_DONT_USE_UPPER (BIT(2))
359#define WSM_RCPI_RSSI_DONT_USE_LOWER (BIT(3))
360
361/* Update-ie constants */
362#define WSM_UPDATE_IE_BEACON (BIT(0))
363#define WSM_UPDATE_IE_PROBE_RESP (BIT(1))
364#define WSM_UPDATE_IE_PROBE_REQ (BIT(2))
365
366/* WSM events */
367/* Error */
368#define WSM_EVENT_ERROR (0)
369
370/* BSS lost */
371#define WSM_EVENT_BSS_LOST (1)
372
373/* BSS regained */
374#define WSM_EVENT_BSS_REGAINED (2)
375
376/* Radar detected */
377#define WSM_EVENT_RADAR_DETECTED (3)
378
379/* RCPI or RSSI threshold triggered */
380#define WSM_EVENT_RCPI_RSSI (4)
381
382/* BT inactive */
383#define WSM_EVENT_BT_INACTIVE (5)
384
385/* BT active */
386#define WSM_EVENT_BT_ACTIVE (6)
387
388/* MIB IDs */
389/* 4.1 dot11StationId */
390#define WSM_MIB_ID_DOT11_STATION_ID 0x0000
391
392/* 4.2 dot11MaxtransmitMsduLifeTime */
393#define WSM_MIB_ID_DOT11_MAX_TRANSMIT_LIFTIME 0x0001
394
395/* 4.3 dot11MaxReceiveLifeTime */
396#define WSM_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME 0x0002
397
398/* 4.4 dot11SlotTime */
399#define WSM_MIB_ID_DOT11_SLOT_TIME 0x0003
400
401/* 4.5 dot11GroupAddressesTable */
402#define WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE 0x0004
403#define WSM_MAX_GRP_ADDRTABLE_ENTRIES 8
404
405/* 4.6 dot11WepDefaultKeyId */
406#define WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID 0x0005
407
408/* 4.7 dot11CurrentTxPowerLevel */
409#define WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL 0x0006
410
411/* 4.8 dot11RTSThreshold */
412#define WSM_MIB_ID_DOT11_RTS_THRESHOLD 0x0007
413
414/* 4.9 NonErpProtection */
415#define WSM_MIB_ID_NON_ERP_PROTECTION 0x1000
416
417/* 4.10 ArpIpAddressesTable */
418#define WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE 0x1001
419#define WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES 1
420
421/* 4.11 TemplateFrame */
422#define WSM_MIB_ID_TEMPLATE_FRAME 0x1002
423
424/* 4.12 RxFilter */
425#define WSM_MIB_ID_RX_FILTER 0x1003
426
427/* 4.13 BeaconFilterTable */
428#define WSM_MIB_ID_BEACON_FILTER_TABLE 0x1004
429
430/* 4.14 BeaconFilterEnable */
431#define WSM_MIB_ID_BEACON_FILTER_ENABLE 0x1005
432
433/* 4.15 OperationalPowerMode */
434#define WSM_MIB_ID_OPERATIONAL_POWER_MODE 0x1006
435
436/* 4.16 BeaconWakeUpPeriod */
437#define WSM_MIB_ID_BEACON_WAKEUP_PERIOD 0x1007
438
439/* 4.17 RcpiRssiThreshold */
440#define WSM_MIB_ID_RCPI_RSSI_THRESHOLD 0x1009
441
442/* 4.18 StatisticsTable */
443#define WSM_MIB_ID_STATISTICS_TABLE 0x100A
444
445/* 4.19 IbssPsConfig */
446#define WSM_MIB_ID_IBSS_PS_CONFIG 0x100B
447
448/* 4.20 CountersTable */
449#define WSM_MIB_ID_COUNTERS_TABLE 0x100C
450
451/* 4.21 BlockAckPolicy */
452#define WSM_MIB_ID_BLOCK_ACK_POLICY 0x100E
453
454/* 4.22 OverrideInternalTxRate */
455#define WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE 0x100F
456
457/* 4.23 SetAssociationMode */
458#define WSM_MIB_ID_SET_ASSOCIATION_MODE 0x1010
459
460/* 4.24 UpdateEptaConfigData */
461#define WSM_MIB_ID_UPDATE_EPTA_CONFIG_DATA 0x1011
462
463/* 4.25 SelectCcaMethod */
464#define WSM_MIB_ID_SELECT_CCA_METHOD 0x1012
465
466/* 4.26 SetUpasdInformation */
467#define WSM_MIB_ID_SET_UAPSD_INFORMATION 0x1013
468
469/* 4.27 SetAutoCalibrationMode WBF00004073 */
470#define WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE 0x1015
471
472/* 4.28 SetTxRateRetryPolicy */
473#define WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY 0x1016
474
475/* 4.29 SetHostMessageTypeFilter */
476#define WSM_MIB_ID_SET_HOST_MSG_TYPE_FILTER 0x1017
477
478/* 4.30 P2PFindInfo */
479#define WSM_MIB_ID_P2P_FIND_INFO 0x1018
480
481/* 4.31 P2PPsModeInfo */
482#define WSM_MIB_ID_P2P_PS_MODE_INFO 0x1019
483
484/* 4.32 SetEtherTypeDataFrameFilter */
485#define WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER 0x101A
486
487/* 4.33 SetUDPPortDataFrameFilter */
488#define WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER 0x101B
489
490/* 4.34 SetMagicDataFrameFilter */
491#define WSM_MIB_ID_SET_MAGIC_DATAFRAME_FILTER 0x101C
492
493/* 4.35 P2PDeviceInfo */
494#define WSM_MIB_ID_P2P_DEVICE_INFO 0x101D
495
496/* 4.36 SetWCDMABand */
497#define WSM_MIB_ID_SET_WCDMA_BAND 0x101E
498
499/* 4.37 GroupTxSequenceCounter */
500#define WSM_MIB_ID_GRP_SEQ_COUNTER 0x101F
501
502/* 4.38 ProtectedMgmtPolicy */
503#define WSM_MIB_ID_PROTECTED_MGMT_POLICY 0x1020
504
505/* 4.39 SetHtProtection */
506#define WSM_MIB_ID_SET_HT_PROTECTION 0x1021
507
508/* 4.40 GPIO Command */
509#define WSM_MIB_ID_GPIO_COMMAND 0x1022
510
511/* 4.41 TSF Counter Value */
512#define WSM_MIB_ID_TSF_COUNTER 0x1023
513
514/* Test Purposes Only */
515#define WSM_MIB_ID_BLOCK_ACK_INFO 0x100D
516
517/* 4.42 UseMultiTxConfMessage */
518#define WSM_MIB_USE_MULTI_TX_CONF 0x1024
519
520/* 4.43 Keep-alive period */
521#define WSM_MIB_ID_KEEP_ALIVE_PERIOD 0x1025
522
523/* 4.44 Disable BSSID filter */
524#define WSM_MIB_ID_DISABLE_BSSID_FILTER 0x1026
525
526/* Frame template types */
527#define WSM_FRAME_TYPE_PROBE_REQUEST (0)
528#define WSM_FRAME_TYPE_BEACON (1)
529#define WSM_FRAME_TYPE_NULL (2)
530#define WSM_FRAME_TYPE_QOS_NULL (3)
531#define WSM_FRAME_TYPE_PS_POLL (4)
532#define WSM_FRAME_TYPE_PROBE_RESPONSE (5)
533
534#define WSM_FRAME_GREENFIELD (0x80) /* See 4.11 */
535
536/* Status */
537/* The WSM firmware has completed a request */
538/* successfully. */
539#define WSM_STATUS_SUCCESS (0)
540
541/* This is a generic failure code if other error codes do */
542/* not apply. */
543#define WSM_STATUS_FAILURE (1)
544
545/* A request contains one or more invalid parameters. */
546#define WSM_INVALID_PARAMETER (2)
547
548/* The request cannot perform because the device is in */
549/* an inappropriate mode. */
550#define WSM_ACCESS_DENIED (3)
551
552/* The frame received includes a decryption error. */
553#define WSM_STATUS_DECRYPTFAILURE (4)
554
555/* A MIC failure is detected in the received packets. */
556#define WSM_STATUS_MICFAILURE (5)
557
558/* The transmit request failed due to retry limit being */
559/* exceeded. */
560#define WSM_STATUS_RETRY_EXCEEDED (6)
561
562/* The transmit request failed due to MSDU life time */
563/* being exceeded. */
564#define WSM_STATUS_TX_LIFETIME_EXCEEDED (7)
565
566/* The link to the AP is lost. */
567#define WSM_STATUS_LINK_LOST (8)
568
569/* No key was found for the encrypted frame */
570#define WSM_STATUS_NO_KEY_FOUND (9)
571
572/* Jammer was detected when transmitting this frame */
573#define WSM_STATUS_JAMMER_DETECTED (10)
574
575/* The message should be requeued later. */
576/* This is applicable only to Transmit */
577#define WSM_REQUEUE (11)
578
579/* Advanced filtering options */
580#define WSM_MAX_FILTER_ELEMENTS (4)
581
582#define WSM_FILTER_ACTION_IGNORE (0)
583#define WSM_FILTER_ACTION_FILTER_IN (1)
584#define WSM_FILTER_ACTION_FILTER_OUT (2)
585
586#define WSM_FILTER_PORT_TYPE_DST (0)
587#define WSM_FILTER_PORT_TYPE_SRC (1)
588
589/* Actual header of WSM messages */
590struct wsm_hdr {
591 __le16 len;
592 __le16 id;
593};
594
595#define WSM_TX_SEQ_MAX (7)
596#define WSM_TX_SEQ(seq) \
597 ((seq & WSM_TX_SEQ_MAX) << 13)
598#define WSM_TX_LINK_ID_MAX (0x0F)
599#define WSM_TX_LINK_ID(link_id) \
600 ((link_id & WSM_TX_LINK_ID_MAX) << 6)
601
602#define MAX_BEACON_SKIP_TIME_MS 1000
603
604#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
605
606/* ******************************************************************** */
607/* WSM capability */
608
609#define WSM_STARTUP_IND_ID 0x0801
610
611struct wsm_startup_ind {
612 u16 input_buffers;
613 u16 input_buffer_size;
614 u16 status;
615 u16 hw_id;
616 u16 hw_subid;
617 u16 fw_cap;
618 u16 fw_type;
619 u16 fw_api;
620 u16 fw_build;
621 u16 fw_ver;
622 char fw_label[128];
623 u32 config[4];
624};
625
626/* ******************************************************************** */
627/* WSM commands */
628
629/* 3.1 */
630#define WSM_CONFIGURATION_REQ_ID 0x0009
631#define WSM_CONFIGURATION_RESP_ID 0x0409
632
633struct wsm_tx_power_range {
634 int min_power_level;
635 int max_power_level;
636 u32 stepping;
637};
638
639struct wsm_configuration {
640 /* [in] */ u32 dot11MaxTransmitMsduLifeTime;
641 /* [in] */ u32 dot11MaxReceiveLifeTime;
642 /* [in] */ u32 dot11RtsThreshold;
643 /* [in, out] */ u8 *dot11StationId;
644 /* [in] */ const void *dpdData;
645 /* [in] */ size_t dpdData_size;
646 /* [out] */ u8 dot11FrequencyBandsSupported;
647 /* [out] */ u32 supportedRateMask;
648 /* [out] */ struct wsm_tx_power_range txPowerRange[2];
649};
650
651int wsm_configuration(struct cw1200_common *priv,
652 struct wsm_configuration *arg);
653
654/* 3.3 */
655#define WSM_RESET_REQ_ID 0x000A
656#define WSM_RESET_RESP_ID 0x040A
657struct wsm_reset {
658 /* [in] */ int link_id;
659 /* [in] */ bool reset_statistics;
660};
661
662int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg);
663
664/* 3.5 */
665#define WSM_READ_MIB_REQ_ID 0x0005
666#define WSM_READ_MIB_RESP_ID 0x0405
667int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
668 size_t buf_size);
669
670/* 3.7 */
671#define WSM_WRITE_MIB_REQ_ID 0x0006
672#define WSM_WRITE_MIB_RESP_ID 0x0406
673int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
674 size_t buf_size);
675
676/* 3.9 */
677#define WSM_START_SCAN_REQ_ID 0x0007
678#define WSM_START_SCAN_RESP_ID 0x0407
679
680struct wsm_ssid {
681 u8 ssid[32];
682 u32 length;
683};
684
685struct wsm_scan_ch {
686 u16 number;
687 u32 min_chan_time;
688 u32 max_chan_time;
689 u32 tx_power_level;
690};
691
692struct wsm_scan {
693 /* WSM_PHY_BAND_... */
694 u8 band;
695
696 /* WSM_SCAN_TYPE_... */
697 u8 type;
698
699 /* WSM_SCAN_FLAG_... */
700 u8 flags;
701
702 /* WSM_TRANSMIT_RATE_... */
703 u8 max_tx_rate;
704
705 /* Interval period in TUs that the device shall the re- */
706 /* execute the requested scan. Max value supported by the device */
707 /* is 256s. */
708 u32 auto_scan_interval;
709
710 /* Number of probe requests (per SSID) sent to one (1) */
711 /* channel. Zero (0) means that none is send, which */
712 /* means that a passive scan is to be done. Value */
713 /* greater than zero (0) means that an active scan is to */
714 /* be done. */
715 u32 num_probes;
716
717 /* Number of channels to be scanned. */
718 /* Maximum value is WSM_SCAN_MAX_NUM_OF_CHANNELS. */
719 u8 num_channels;
720
721 /* Number of SSID provided in the scan command (this */
722 /* is zero (0) in broadcast scan) */
723 /* The maximum number of SSIDs is WSM_SCAN_MAX_NUM_OF_SSIDS. */
724 u8 num_ssids;
725
726 /* The delay time (in microseconds) period */
727 /* before sending a probe-request. */
728 u8 probe_delay;
729
730 /* SSIDs to be scanned [numOfSSIDs]; */
731 struct wsm_ssid *ssids;
732
733 /* Channels to be scanned [numOfChannels]; */
734 struct wsm_scan_ch *ch;
735};
736
737int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg);
738
739/* 3.11 */
740#define WSM_STOP_SCAN_REQ_ID 0x0008
741#define WSM_STOP_SCAN_RESP_ID 0x0408
742int wsm_stop_scan(struct cw1200_common *priv);
743
744/* 3.13 */
745#define WSM_SCAN_COMPLETE_IND_ID 0x0806
746struct wsm_scan_complete {
747 /* WSM_STATUS_... */
748 u32 status;
749
750 /* WSM_PSM_... */
751 u8 psm;
752
753 /* Number of channels that the scan operation completed. */
754 u8 num_channels;
755};
756
757/* 3.14 */
758#define WSM_TX_CONFIRM_IND_ID 0x0404
759#define WSM_MULTI_TX_CONFIRM_ID 0x041E
760
761struct wsm_tx_confirm {
762 /* Packet identifier used in wsm_tx. */
763 u32 packet_id;
764
765 /* WSM_STATUS_... */
766 u32 status;
767
768 /* WSM_TRANSMIT_RATE_... */
769 u8 tx_rate;
770
771 /* The number of times the frame was transmitted */
772 /* without receiving an acknowledgement. */
773 u8 ack_failures;
774
775 /* WSM_TX_STATUS_... */
776 u16 flags;
777
778 /* The total time in microseconds that the frame spent in */
779 /* the WLAN device before transmission as completed. */
780 u32 media_delay;
781
782 /* The total time in microseconds that the frame spent in */
783 /* the WLAN device before transmission was started. */
784 u32 tx_queue_delay;
785};
786
787/* 3.15 */
788typedef void (*wsm_tx_confirm_cb) (struct cw1200_common *priv,
789 struct wsm_tx_confirm *arg);
790
791/* Note that ideology of wsm_tx struct is different against the rest of
792 * WSM API. wsm_hdr is /not/ a caller-adapted struct to be used as an input
793 * argument for WSM call, but a prepared bytestream to be sent to firmware.
794 * It is filled partly in cw1200_tx, partly in low-level WSM code.
795 * Please pay attention once again: ideology is different.
796 *
797 * Legend:
798 * - [in]: cw1200_tx must fill this field.
799 * - [wsm]: the field is filled by low-level WSM.
800 */
801struct wsm_tx {
802 /* common WSM header */
803 struct wsm_hdr hdr;
804
805 /* Packet identifier that meant to be used in completion. */
806 __le32 packet_id;
807
808 /* WSM_TRANSMIT_RATE_... */
809 u8 max_tx_rate;
810
811 /* WSM_QUEUE_... */
812 u8 queue_id;
813
814 /* True: another packet is pending on the host for transmission. */
815 u8 more;
816
817 /* Bit 0 = 0 - Start expiry time from first Tx attempt (default) */
818 /* Bit 0 = 1 - Start expiry time from receipt of Tx Request */
819 /* Bits 3:1 - PTA Priority */
820 /* Bits 6:4 - Tx Rate Retry Policy */
821 /* Bit 7 - Reserved */
822 u8 flags;
823
824 /* Should be 0. */
825 __le32 reserved;
826
827 /* The elapsed time in TUs, after the initial transmission */
828 /* of an MSDU, after which further attempts to transmit */
829 /* the MSDU shall be terminated. Overrides the global */
830 /* dot11MaxTransmitMsduLifeTime setting [optional] */
831 /* Device will set the default value if this is 0. */
832 __le32 expire_time;
833
834 /* WSM_HT_TX_... */
835 __le32 ht_tx_parameters;
836};
837
838/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
839#define WSM_TX_EXTRA_HEADROOM (28)
840
841/* 3.16 */
842#define WSM_RECEIVE_IND_ID 0x0804
843
844struct wsm_rx {
845 /* WSM_STATUS_... */
846 __le32 status;
847
848 /* Specifies the channel of the received packet. */
849 __le16 channel_number;
850
851 /* WSM_TRANSMIT_RATE_... */
852 u8 rx_rate;
853
854 /* This value is expressed in signed Q8.0 format for */
855 /* RSSI and unsigned Q7.1 format for RCPI. */
856 u8 rcpi_rssi;
857
858 /* WSM_RX_STATUS_... */
859 __le32 flags;
860
861 /* Payload */
862 u8 data[0];
863} __packed;
864
865/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
866#define WSM_RX_EXTRA_HEADROOM (16)
867
868typedef void (*wsm_rx_cb) (struct cw1200_common *priv, struct wsm_rx *arg,
869 struct sk_buff **skb_p);
870
871/* 3.17 */
872struct wsm_event {
873 /* WSM_STATUS_... */
874 /* [out] */ u32 id;
875
876 /* Indication parameters. */
877 /* For error indication, this shall be a 32-bit WSM status. */
878 /* For RCPI or RSSI indication, this should be an 8-bit */
879 /* RCPI or RSSI value. */
880 /* [out] */ u32 data;
881};
882
883struct cw1200_wsm_event {
884 struct list_head link;
885 struct wsm_event evt;
886};
887
888/* 3.18 - 3.22 */
889/* Measurement. Skipped for now. Irrelevent. */
890
891typedef void (*wsm_event_cb) (struct cw1200_common *priv,
892 struct wsm_event *arg);
893
894/* 3.23 */
895#define WSM_JOIN_REQ_ID 0x000B
896#define WSM_JOIN_RESP_ID 0x040B
897
898struct wsm_join {
899 /* WSM_JOIN_MODE_... */
900 u8 mode;
901
902 /* WSM_PHY_BAND_... */
903 u8 band;
904
905 /* Specifies the channel number to join. The channel */
906 /* number will be mapped to an actual frequency */
907 /* according to the band */
908 u16 channel_number;
909
910 /* Specifies the BSSID of the BSS or IBSS to be joined */
911 /* or the IBSS to be started. */
912 u8 bssid[6];
913
914 /* ATIM window of IBSS */
915 /* When ATIM window is zero the initiated IBSS does */
916 /* not support power saving. */
917 u16 atim_window;
918
919 /* WSM_JOIN_PREAMBLE_... */
920 u8 preamble_type;
921
922 /* Specifies if a probe request should be send with the */
923 /* specified SSID when joining to the network. */
924 u8 probe_for_join;
925
926 /* DTIM Period (In multiples of beacon interval) */
927 u8 dtim_period;
928
929 /* WSM_JOIN_FLAGS_... */
930 u8 flags;
931
932 /* Length of the SSID */
933 u32 ssid_len;
934
935 /* Specifies the SSID of the IBSS to join or start */
936 u8 ssid[32];
937
938 /* Specifies the time between TBTTs in TUs */
939 u32 beacon_interval;
940
941 /* A bit mask that defines the BSS basic rate set. */
942 u32 basic_rate_set;
943};
944
945struct wsm_join_cnf {
946 u32 status;
947
948 /* Minimum transmission power level in units of 0.1dBm */
949 u32 min_power_level;
950
951 /* Maximum transmission power level in units of 0.1dBm */
952 u32 max_power_level;
953};
954
955int wsm_join(struct cw1200_common *priv, struct wsm_join *arg);
956
957/* 3.24 */
958struct wsm_join_complete {
959 /* WSM_STATUS_... */
960 u32 status;
961};
962
963/* 3.25 */
964#define WSM_SET_PM_REQ_ID 0x0010
965#define WSM_SET_PM_RESP_ID 0x0410
966struct wsm_set_pm {
967 /* WSM_PSM_... */
968 u8 mode;
969
970 /* in unit of 500us; 0 to use default */
971 u8 fast_psm_idle_period;
972
973 /* in unit of 500us; 0 to use default */
974 u8 ap_psm_change_period;
975
976 /* in unit of 500us; 0 to disable auto-pspoll */
977 u8 min_auto_pspoll_period;
978};
979
980int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
981
982/* 3.27 */
983struct wsm_set_pm_complete {
984 u8 psm; /* WSM_PSM_... */
985};
986
987/* 3.28 */
988#define WSM_SET_BSS_PARAMS_REQ_ID 0x0011
989#define WSM_SET_BSS_PARAMS_RESP_ID 0x0411
990struct wsm_set_bss_params {
991 /* This resets the beacon loss counters only */
992 u8 reset_beacon_loss;
993
994 /* The number of lost consecutive beacons after which */
995 /* the WLAN device should indicate the BSS-Lost event */
996 /* to the WLAN host driver. */
997 u8 beacon_lost_count;
998
999 /* The AID received during the association process. */
1000 u16 aid;
1001
1002 /* The operational rate set mask */
1003 u32 operational_rate_set;
1004};
1005
1006int wsm_set_bss_params(struct cw1200_common *priv,
1007 const struct wsm_set_bss_params *arg);
1008
1009/* 3.30 */
1010#define WSM_ADD_KEY_REQ_ID 0x000C
1011#define WSM_ADD_KEY_RESP_ID 0x040C
1012struct wsm_add_key {
1013 u8 type; /* WSM_KEY_TYPE_... */
1014 u8 index; /* Key entry index: 0 -- WSM_KEY_MAX_INDEX */
1015 u16 reserved;
1016 union {
1017 struct {
1018 u8 peer[6]; /* MAC address of the
1019 * peer station */
1020 u8 reserved;
1021 u8 keylen; /* Key length in bytes */
1022 u8 keydata[16]; /* Key data */
1023 } __packed wep_pairwise;
1024 struct {
1025 u8 keyid; /* Unique per key identifier
1026 * (0..3) */
1027 u8 keylen; /* Key length in bytes */
1028 u16 reserved;
1029 u8 keydata[16]; /* Key data */
1030 } __packed wep_group;
1031 struct {
1032 u8 peer[6]; /* MAC address of the
1033 * peer station */
1034 u16 reserved;
1035 u8 keydata[16]; /* TKIP key data */
1036 u8 rx_mic_key[8]; /* Rx MIC key */
1037 u8 tx_mic_key[8]; /* Tx MIC key */
1038 } __packed tkip_pairwise;
1039 struct {
1040 u8 keydata[16]; /* TKIP key data */
1041 u8 rx_mic_key[8]; /* Rx MIC key */
1042 u8 keyid; /* Key ID */
1043 u8 reserved[3];
1044 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1045 } __packed tkip_group;
1046 struct {
1047 u8 peer[6]; /* MAC address of the
1048 * peer station */
1049 u16 reserved;
1050 u8 keydata[16]; /* AES key data */
1051 } __packed aes_pairwise;
1052 struct {
1053 u8 keydata[16]; /* AES key data */
1054 u8 keyid; /* Key ID */
1055 u8 reserved[3];
1056 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1057 } __packed aes_group;
1058 struct {
1059 u8 peer[6]; /* MAC address of the
1060 * peer station */
1061 u8 keyid; /* Key ID */
1062 u8 reserved;
1063 u8 keydata[16]; /* WAPI key data */
1064 u8 mic_key[16]; /* MIC key data */
1065 } __packed wapi_pairwise;
1066 struct {
1067 u8 keydata[16]; /* WAPI key data */
1068 u8 mic_key[16]; /* MIC key data */
1069 u8 keyid; /* Key ID */
1070 u8 reserved[3];
1071 } __packed wapi_group;
1072 } __packed;
1073} __packed;
1074
1075int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg);
1076
1077/* 3.32 */
1078#define WSM_REMOVE_KEY_REQ_ID 0x000D
1079#define WSM_REMOVE_KEY_RESP_ID 0x040D
1080struct wsm_remove_key {
1081 u8 index; /* Key entry index : 0-10 */
1082};
1083
1084int wsm_remove_key(struct cw1200_common *priv,
1085 const struct wsm_remove_key *arg);
1086
1087/* 3.34 */
1088struct wsm_set_tx_queue_params {
1089 /* WSM_ACK_POLICY_... */
1090 u8 ackPolicy;
1091
1092 /* Medium Time of TSPEC (in 32us units) allowed per */
1093 /* One Second Averaging Period for this queue. */
1094 u16 allowedMediumTime;
1095
1096 /* dot11MaxTransmitMsduLifetime to be used for the */
1097 /* specified queue. */
1098 u32 maxTransmitLifetime;
1099};
1100
1101struct wsm_tx_queue_params {
1102 /* NOTE: index is a linux queue id. */
1103 struct wsm_set_tx_queue_params params[4];
1104};
1105
1106
1107#define WSM_TX_QUEUE_SET(queue_params, queue, ack_policy, allowed_time,\
1108 max_life_time) \
1109do { \
1110 struct wsm_set_tx_queue_params *p = &(queue_params)->params[queue]; \
1111 p->ackPolicy = (ack_policy); \
1112 p->allowedMediumTime = (allowed_time); \
1113 p->maxTransmitLifetime = (max_life_time); \
1114} while (0)
1115
1116int wsm_set_tx_queue_params(struct cw1200_common *priv,
1117 const struct wsm_set_tx_queue_params *arg, u8 id);
1118
1119/* 3.36 */
1120#define WSM_EDCA_PARAMS_REQ_ID 0x0013
1121#define WSM_EDCA_PARAMS_RESP_ID 0x0413
1122struct wsm_edca_queue_params {
1123 /* CWmin (in slots) for the access class. */
1124 __le16 cwmin;
1125
1126 /* CWmax (in slots) for the access class. */
1127 __le16 cwmax;
1128
1129 /* AIFS (in slots) for the access class. */
1130 __le16 aifns;
1131
1132 /* TX OP Limit (in microseconds) for the access class. */
1133 __le16 txop_limit;
1134
1135 /* dot11MaxReceiveLifetime to be used for the specified */
1136 /* the access class. Overrides the global */
1137 /* dot11MaxReceiveLifetime value */
1138 __le32 max_rx_lifetime;
1139} __packed;
1140
1141struct wsm_edca_params {
1142 /* NOTE: index is a linux queue id. */
1143 struct wsm_edca_queue_params params[4];
1144 bool uapsd_enable[4];
1145};
1146
1147#define TXOP_UNIT 32
1148#define WSM_EDCA_SET(__edca, __queue, __aifs, __cw_min, __cw_max, __txop, __lifetime,\
1149 __uapsd) \
1150 do { \
1151 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
1152 p->cwmin = (__cw_min); \
1153 p->cwmax = (__cw_max); \
1154 p->aifns = (__aifs); \
1155 p->txop_limit = ((__txop) * TXOP_UNIT); \
1156 p->max_rx_lifetime = (__lifetime); \
1157 (__edca)->uapsd_enable[__queue] = (__uapsd); \
1158 } while (0)
1159
1160int wsm_set_edca_params(struct cw1200_common *priv,
1161 const struct wsm_edca_params *arg);
1162
1163int wsm_set_uapsd_param(struct cw1200_common *priv,
1164 const struct wsm_edca_params *arg);
1165
1166/* 3.38 */
1167/* Set-System info. Skipped for now. Irrelevent. */
1168
1169/* 3.40 */
1170#define WSM_SWITCH_CHANNEL_REQ_ID 0x0016
1171#define WSM_SWITCH_CHANNEL_RESP_ID 0x0416
1172
1173struct wsm_switch_channel {
1174 /* 1 - means the STA shall not transmit any further */
1175 /* frames until the channel switch has completed */
1176 u8 mode;
1177
1178 /* Number of TBTTs until channel switch occurs. */
1179 /* 0 - indicates switch shall occur at any time */
1180 /* 1 - occurs immediately before the next TBTT */
1181 u8 switch_count;
1182
1183 /* The new channel number to switch to. */
1184 /* Note this is defined as per section 2.7. */
1185 u16 channel_number;
1186};
1187
1188int wsm_switch_channel(struct cw1200_common *priv,
1189 const struct wsm_switch_channel *arg);
1190
1191typedef void (*wsm_channel_switch_cb) (struct cw1200_common *priv);
1192
1193#define WSM_START_REQ_ID 0x0017
1194#define WSM_START_RESP_ID 0x0417
1195
1196struct wsm_start {
1197 /* WSM_START_MODE_... */
1198 /* [in] */ u8 mode;
1199
1200 /* WSM_PHY_BAND_... */
1201 /* [in] */ u8 band;
1202
1203 /* Channel number */
1204 /* [in] */ u16 channel_number;
1205
1206 /* Client Traffic window in units of TU */
1207 /* Valid only when mode == ..._P2P */
1208 /* [in] */ u32 ct_window;
1209
1210 /* Interval between two consecutive */
1211 /* beacon transmissions in TU. */
1212 /* [in] */ u32 beacon_interval;
1213
1214 /* DTIM period in terms of beacon intervals */
1215 /* [in] */ u8 dtim_period;
1216
1217 /* WSM_JOIN_PREAMBLE_... */
1218 /* [in] */ u8 preamble;
1219
1220 /* The delay time (in microseconds) period */
1221 /* before sending a probe-request. */
1222 /* [in] */ u8 probe_delay;
1223
1224 /* Length of the SSID */
1225 /* [in] */ u8 ssid_len;
1226
1227 /* SSID of the BSS or P2P_GO to be started now. */
1228 /* [in] */ u8 ssid[32];
1229
1230 /* The basic supported rates for the MiniAP. */
1231 /* [in] */ u32 basic_rate_set;
1232};
1233
1234int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg);
1235
1236#define WSM_BEACON_TRANSMIT_REQ_ID 0x0018
1237#define WSM_BEACON_TRANSMIT_RESP_ID 0x0418
1238
1239struct wsm_beacon_transmit {
1240 /* 1: enable; 0: disable */
1241 /* [in] */ u8 enable_beaconing;
1242};
1243
1244int wsm_beacon_transmit(struct cw1200_common *priv,
1245 const struct wsm_beacon_transmit *arg);
1246
1247int wsm_start_find(struct cw1200_common *priv);
1248
1249int wsm_stop_find(struct cw1200_common *priv);
1250
1251typedef void (*wsm_find_complete_cb) (struct cw1200_common *priv, u32 status);
1252
1253struct wsm_suspend_resume {
1254 /* See 3.52 */
1255 /* Link ID */
1256 /* [out] */ int link_id;
1257 /* Stop sending further Tx requests down to device for this link */
1258 /* [out] */ bool stop;
1259 /* Transmit multicast Frames */
1260 /* [out] */ bool multicast;
1261 /* The AC on which Tx to be suspended /resumed. */
1262 /* This is applicable only for U-APSD */
1263 /* WSM_QUEUE_... */
1264 /* [out] */ int queue;
1265};
1266
1267typedef void (*wsm_suspend_resume_cb) (struct cw1200_common *priv,
1268 struct wsm_suspend_resume *arg);
1269
1270/* 3.54 Update-IE request. */
1271struct wsm_update_ie {
1272 /* WSM_UPDATE_IE_... */
1273 /* [in] */ u16 what;
1274 /* [in] */ u16 count;
1275 /* [in] */ u8 *ies;
1276 /* [in] */ size_t length;
1277};
1278
1279int wsm_update_ie(struct cw1200_common *priv,
1280 const struct wsm_update_ie *arg);
1281
1282/* 3.56 */
1283struct wsm_map_link {
1284 /* MAC address of the remote device */
1285 /* [in] */ u8 mac_addr[6];
1286 /* [in] */ u8 link_id;
1287};
1288
1289int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg);
1290
1291/* ******************************************************************** */
1292/* MIB shortcats */
1293
1294static inline int wsm_set_output_power(struct cw1200_common *priv,
1295 int power_level)
1296{
1297 __le32 val = __cpu_to_le32(power_level);
1298 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL,
1299 &val, sizeof(val));
1300}
1301
1302static inline int wsm_set_beacon_wakeup_period(struct cw1200_common *priv,
1303 unsigned dtim_interval,
1304 unsigned listen_interval)
1305{
1306 struct {
1307 u8 numBeaconPeriods;
1308 u8 reserved;
1309 __le16 listenInterval;
1310 } val = {
1311 dtim_interval, 0, __cpu_to_le16(listen_interval)
1312 };
1313
1314 if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
1315 return -EINVAL;
1316 else
1317 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_WAKEUP_PERIOD,
1318 &val, sizeof(val));
1319}
1320
1321struct wsm_rcpi_rssi_threshold {
1322 u8 rssiRcpiMode; /* WSM_RCPI_RSSI_... */
1323 u8 lowerThreshold;
1324 u8 upperThreshold;
1325 u8 rollingAverageCount;
1326};
1327
1328static inline int wsm_set_rcpi_rssi_threshold(struct cw1200_common *priv,
1329 struct wsm_rcpi_rssi_threshold *arg)
1330{
1331 return wsm_write_mib(priv, WSM_MIB_ID_RCPI_RSSI_THRESHOLD, arg,
1332 sizeof(*arg));
1333}
1334
1335struct wsm_mib_counters_table {
1336 __le32 plcp_errors;
1337 __le32 fcs_errors;
1338 __le32 tx_packets;
1339 __le32 rx_packets;
1340 __le32 rx_packet_errors;
1341 __le32 rx_decryption_failures;
1342 __le32 rx_mic_failures;
1343 __le32 rx_no_key_failures;
1344 __le32 tx_multicast_frames;
1345 __le32 tx_frames_success;
1346 __le32 tx_frame_failures;
1347 __le32 tx_frames_retried;
1348 __le32 tx_frames_multi_retried;
1349 __le32 rx_frame_duplicates;
1350 __le32 rts_success;
1351 __le32 rts_failures;
1352 __le32 ack_failures;
1353 __le32 rx_multicast_frames;
1354 __le32 rx_frames_success;
1355 __le32 rx_cmac_icv_errors;
1356 __le32 rx_cmac_replays;
1357 __le32 rx_mgmt_ccmp_replays;
1358} __packed;
1359
1360static inline int wsm_get_counters_table(struct cw1200_common *priv,
1361 struct wsm_mib_counters_table *arg)
1362{
1363 return wsm_read_mib(priv, WSM_MIB_ID_COUNTERS_TABLE,
1364 arg, sizeof(*arg));
1365}
1366
1367static inline int wsm_get_station_id(struct cw1200_common *priv, u8 *mac)
1368{
1369 return wsm_read_mib(priv, WSM_MIB_ID_DOT11_STATION_ID, mac, ETH_ALEN);
1370}
1371
1372struct wsm_rx_filter {
1373 bool promiscuous;
1374 bool bssid;
1375 bool fcs;
1376 bool probeResponder;
1377};
1378
1379static inline int wsm_set_rx_filter(struct cw1200_common *priv,
1380 const struct wsm_rx_filter *arg)
1381{
1382 __le32 val = 0;
1383 if (arg->promiscuous)
1384 val |= __cpu_to_le32(BIT(0));
1385 if (arg->bssid)
1386 val |= __cpu_to_le32(BIT(1));
1387 if (arg->fcs)
1388 val |= __cpu_to_le32(BIT(2));
1389 if (arg->probeResponder)
1390 val |= __cpu_to_le32(BIT(3));
1391 return wsm_write_mib(priv, WSM_MIB_ID_RX_FILTER, &val, sizeof(val));
1392}
1393
1394int wsm_set_probe_responder(struct cw1200_common *priv, bool enable);
1395
1396#define WSM_BEACON_FILTER_IE_HAS_CHANGED BIT(0)
1397#define WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT BIT(1)
1398#define WSM_BEACON_FILTER_IE_HAS_APPEARED BIT(2)
1399
1400struct wsm_beacon_filter_table_entry {
1401 u8 ie_id;
1402 u8 flags;
1403 u8 oui[3];
1404 u8 match_data[3];
1405} __packed;
1406
1407struct wsm_mib_beacon_filter_table {
1408 __le32 num;
1409 struct wsm_beacon_filter_table_entry entry[10];
1410} __packed;
1411
1412static inline int wsm_set_beacon_filter_table(struct cw1200_common *priv,
1413 struct wsm_mib_beacon_filter_table *ft)
1414{
1415 size_t size = __le32_to_cpu(ft->num) *
1416 sizeof(struct wsm_beacon_filter_table_entry) +
1417 sizeof(__le32);
1418
1419 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_TABLE, ft, size);
1420}
1421
1422#define WSM_BEACON_FILTER_ENABLE BIT(0) /* Enable/disable beacon filtering */
1423#define WSM_BEACON_FILTER_AUTO_ERP BIT(1) /* If 1 FW will handle ERP IE changes internally */
1424
1425struct wsm_beacon_filter_control {
1426 int enabled;
1427 int bcn_count;
1428};
1429
1430static inline int wsm_beacon_filter_control(struct cw1200_common *priv,
1431 struct wsm_beacon_filter_control *arg)
1432{
1433 struct {
1434 __le32 enabled;
1435 __le32 bcn_count;
1436 } val;
1437 val.enabled = __cpu_to_le32(arg->enabled);
1438 val.bcn_count = __cpu_to_le32(arg->bcn_count);
1439 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, &val,
1440 sizeof(val));
1441}
1442
1443enum wsm_power_mode {
1444 wsm_power_mode_active = 0,
1445 wsm_power_mode_doze = 1,
1446 wsm_power_mode_quiescent = 2,
1447};
1448
1449struct wsm_operational_mode {
1450 enum wsm_power_mode power_mode;
1451 int disable_more_flag_usage;
1452 int perform_ant_diversity;
1453};
1454
1455static inline int wsm_set_operational_mode(struct cw1200_common *priv,
1456 const struct wsm_operational_mode *arg)
1457{
1458 u8 val = arg->power_mode;
1459 if (arg->disable_more_flag_usage)
1460 val |= BIT(4);
1461 if (arg->perform_ant_diversity)
1462 val |= BIT(5);
1463 return wsm_write_mib(priv, WSM_MIB_ID_OPERATIONAL_POWER_MODE, &val,
1464 sizeof(val));
1465}
1466
1467struct wsm_template_frame {
1468 u8 frame_type;
1469 u8 rate;
1470 struct sk_buff *skb;
1471};
1472
1473static inline int wsm_set_template_frame(struct cw1200_common *priv,
1474 struct wsm_template_frame *arg)
1475{
1476 int ret;
1477 u8 *p = skb_push(arg->skb, 4);
1478 p[0] = arg->frame_type;
1479 p[1] = arg->rate;
1480 ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
1481 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
1482 skb_pull(arg->skb, 4);
1483 return ret;
1484}
1485
1486
1487struct wsm_protected_mgmt_policy {
1488 bool protectedMgmtEnable;
1489 bool unprotectedMgmtFramesAllowed;
1490 bool encryptionForAuthFrame;
1491};
1492
1493static inline int wsm_set_protected_mgmt_policy(struct cw1200_common *priv,
1494 struct wsm_protected_mgmt_policy *arg)
1495{
1496 __le32 val = 0;
1497 int ret;
1498 if (arg->protectedMgmtEnable)
1499 val |= __cpu_to_le32(BIT(0));
1500 if (arg->unprotectedMgmtFramesAllowed)
1501 val |= __cpu_to_le32(BIT(1));
1502 if (arg->encryptionForAuthFrame)
1503 val |= __cpu_to_le32(BIT(2));
1504 ret = wsm_write_mib(priv, WSM_MIB_ID_PROTECTED_MGMT_POLICY,
1505 &val, sizeof(val));
1506 return ret;
1507}
1508
1509struct wsm_mib_block_ack_policy {
1510 u8 tx_tid;
1511 u8 reserved1;
1512 u8 rx_tid;
1513 u8 reserved2;
1514} __packed;
1515
1516static inline int wsm_set_block_ack_policy(struct cw1200_common *priv,
1517 u8 tx_tid_policy,
1518 u8 rx_tid_policy)
1519{
1520 struct wsm_mib_block_ack_policy val = {
1521 .tx_tid = tx_tid_policy,
1522 .rx_tid = rx_tid_policy,
1523 };
1524 return wsm_write_mib(priv, WSM_MIB_ID_BLOCK_ACK_POLICY, &val,
1525 sizeof(val));
1526}
1527
1528struct wsm_mib_association_mode {
1529 u8 flags; /* WSM_ASSOCIATION_MODE_... */
1530 u8 preamble; /* WSM_JOIN_PREAMBLE_... */
1531 u8 greenfield; /* 1 for greenfield */
1532 u8 mpdu_start_spacing;
1533 __le32 basic_rate_set;
1534} __packed;
1535
1536static inline int wsm_set_association_mode(struct cw1200_common *priv,
1537 struct wsm_mib_association_mode *arg)
1538{
1539 return wsm_write_mib(priv, WSM_MIB_ID_SET_ASSOCIATION_MODE, arg,
1540 sizeof(*arg));
1541}
1542
1543#define WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED BIT(2)
1544#define WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT BIT(3)
1545struct wsm_tx_rate_retry_policy {
1546 u8 index;
1547 u8 short_retries;
1548 u8 long_retries;
1549 /* BIT(2) - Terminate retries when Tx rate retry policy
1550 * finishes.
1551 * BIT(3) - Count initial frame transmission as part of
1552 * rate retry counting but not as a retry
1553 * attempt */
1554 u8 flags;
1555 u8 rate_recoveries;
1556 u8 reserved[3];
1557 __le32 rate_count_indices[3];
1558} __packed;
1559
1560struct wsm_set_tx_rate_retry_policy {
1561 u8 num;
1562 u8 reserved[3];
1563 struct wsm_tx_rate_retry_policy tbl[8];
1564} __packed;
1565
1566static inline int wsm_set_tx_rate_retry_policy(struct cw1200_common *priv,
1567 struct wsm_set_tx_rate_retry_policy *arg)
1568{
1569 size_t size = 4 + arg->num * sizeof(struct wsm_tx_rate_retry_policy);
1570 return wsm_write_mib(priv, WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg,
1571 size);
1572}
1573
1574/* 4.32 SetEtherTypeDataFrameFilter */
1575struct wsm_ether_type_filter_hdr {
1576 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1577 u8 reserved[3];
1578} __packed;
1579
1580struct wsm_ether_type_filter {
1581 u8 action; /* WSM_FILTER_ACTION_XXX */
1582 u8 reserved;
1583 __le16 type; /* Type of ethernet frame */
1584} __packed;
1585
1586static inline int wsm_set_ether_type_filter(struct cw1200_common *priv,
1587 struct wsm_ether_type_filter_hdr *arg)
1588{
1589 size_t size = sizeof(struct wsm_ether_type_filter_hdr) +
1590 arg->num * sizeof(struct wsm_ether_type_filter);
1591 return wsm_write_mib(priv, WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER,
1592 arg, size);
1593}
1594
1595/* 4.33 SetUDPPortDataFrameFilter */
1596struct wsm_udp_port_filter_hdr {
1597 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1598 u8 reserved[3];
1599} __packed;
1600
1601struct wsm_udp_port_filter {
1602 u8 action; /* WSM_FILTER_ACTION_XXX */
1603 u8 type; /* WSM_FILTER_PORT_TYPE_XXX */
1604 __le16 port; /* Port number */
1605} __packed;
1606
1607static inline int wsm_set_udp_port_filter(struct cw1200_common *priv,
1608 struct wsm_udp_port_filter_hdr *arg)
1609{
1610 size_t size = sizeof(struct wsm_udp_port_filter_hdr) +
1611 arg->num * sizeof(struct wsm_udp_port_filter);
1612 return wsm_write_mib(priv, WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER,
1613 arg, size);
1614}
1615
1616/* Undocumented MIBs: */
1617/* 4.35 P2PDeviceInfo */
1618#define D11_MAX_SSID_LEN (32)
1619
1620struct wsm_p2p_device_type {
1621 __le16 categoryId;
1622 u8 oui[4];
1623 __le16 subCategoryId;
1624} __packed;
1625
1626struct wsm_p2p_device_info {
1627 struct wsm_p2p_device_type primaryDevice;
1628 u8 reserved1[3];
1629 u8 devNameSize;
1630 u8 localDevName[D11_MAX_SSID_LEN];
1631 u8 reserved2[3];
1632 u8 numSecDevSupported;
1633 struct wsm_p2p_device_type secondaryDevices[0];
1634} __packed;
1635
1636/* 4.36 SetWCDMABand - WO */
1637struct wsm_cdma_band {
1638 u8 WCDMA_Band;
1639 u8 reserved[3];
1640} __packed;
1641
1642/* 4.37 GroupTxSequenceCounter - RO */
1643struct wsm_group_tx_seq {
1644 __le32 bits_47_16;
1645 __le16 bits_15_00;
1646 __le16 reserved;
1647} __packed;
1648
1649/* 4.39 SetHtProtection - WO */
1650#define WSM_DUAL_CTS_PROT_ENB (1 << 0)
1651#define WSM_NON_GREENFIELD_STA_PRESENT (1 << 1)
1652#define WSM_HT_PROT_MODE__NO_PROT (0 << 2)
1653#define WSM_HT_PROT_MODE__NON_MEMBER (1 << 2)
1654#define WSM_HT_PROT_MODE__20_MHZ (2 << 2)
1655#define WSM_HT_PROT_MODE__NON_HT_MIXED (3 << 2)
1656#define WSM_LSIG_TXOP_PROT_FULL (1 << 4)
1657#define WSM_LARGE_L_LENGTH_PROT (1 << 5)
1658
1659struct wsm_ht_protection {
1660 __le32 flags;
1661} __packed;
1662
1663/* 4.40 GPIO Command - R/W */
1664#define WSM_GPIO_COMMAND_SETUP 0
1665#define WSM_GPIO_COMMAND_READ 1
1666#define WSM_GPIO_COMMAND_WRITE 2
1667#define WSM_GPIO_COMMAND_RESET 3
1668#define WSM_GPIO_ALL_PINS 0xFF
1669
1670struct wsm_gpio_command {
1671 u8 GPIO_Command;
1672 u8 pin;
1673 __le16 config;
1674} __packed;
1675
1676/* 4.41 TSFCounter - RO */
1677struct wsm_tsf_counter {
1678 __le64 TSF_Counter;
1679} __packed;
1680
1681/* 4.43 Keep alive period */
1682struct wsm_keep_alive_period {
1683 __le16 keepAlivePeriod;
1684 u8 reserved[2];
1685} __packed;
1686
1687static inline int wsm_keep_alive_period(struct cw1200_common *priv,
1688 int period)
1689{
1690 struct wsm_keep_alive_period arg = {
1691 .keepAlivePeriod = __cpu_to_le16(period),
1692 };
1693 return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD,
1694 &arg, sizeof(arg));
1695};
1696
1697/* BSSID filtering */
1698struct wsm_set_bssid_filtering {
1699 u8 filter;
1700 u8 reserved[3];
1701} __packed;
1702
1703static inline int wsm_set_bssid_filtering(struct cw1200_common *priv,
1704 bool enabled)
1705{
1706 struct wsm_set_bssid_filtering arg = {
1707 .filter = !enabled,
1708 };
1709 return wsm_write_mib(priv, WSM_MIB_ID_DISABLE_BSSID_FILTER,
1710 &arg, sizeof(arg));
1711}
1712
1713/* Multicast filtering - 4.5 */
1714struct wsm_mib_multicast_filter {
1715 __le32 enable;
1716 __le32 num_addrs;
1717 u8 macaddrs[WSM_MAX_GRP_ADDRTABLE_ENTRIES][ETH_ALEN];
1718} __packed;
1719
1720static inline int wsm_set_multicast_filter(struct cw1200_common *priv,
1721 struct wsm_mib_multicast_filter *fp)
1722{
1723 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE,
1724 fp, sizeof(*fp));
1725}
1726
1727/* ARP IPv4 filtering - 4.10 */
1728struct wsm_mib_arp_ipv4_filter {
1729 __le32 enable;
1730 __be32 ipv4addrs[WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES];
1731} __packed;
1732
1733static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv,
1734 struct wsm_mib_arp_ipv4_filter *fp)
1735{
1736 return wsm_write_mib(priv, WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE,
1737 fp, sizeof(*fp));
1738}
1739
1740/* P2P Power Save Mode Info - 4.31 */
1741struct wsm_p2p_ps_modeinfo {
1742 u8 oppPsCTWindow;
1743 u8 count;
1744 u8 reserved;
1745 u8 dtimCount;
1746 __le32 duration;
1747 __le32 interval;
1748 __le32 startTime;
1749} __packed;
1750
1751static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv,
1752 struct wsm_p2p_ps_modeinfo *mi)
1753{
1754 return wsm_write_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1755 mi, sizeof(*mi));
1756}
1757
1758static inline int wsm_get_p2p_ps_modeinfo(struct cw1200_common *priv,
1759 struct wsm_p2p_ps_modeinfo *mi)
1760{
1761 return wsm_read_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1762 mi, sizeof(*mi));
1763}
1764
1765/* UseMultiTxConfMessage */
1766
1767static inline int wsm_use_multi_tx_conf(struct cw1200_common *priv,
1768 bool enabled)
1769{
1770 __le32 arg = enabled ? __cpu_to_le32(1) : 0;
1771
1772 return wsm_write_mib(priv, WSM_MIB_USE_MULTI_TX_CONF,
1773 &arg, sizeof(arg));
1774}
1775
1776
1777/* 4.26 SetUpasdInformation */
1778struct wsm_uapsd_info {
1779 __le16 uapsd_flags;
1780 __le16 min_auto_trigger_interval;
1781 __le16 max_auto_trigger_interval;
1782 __le16 auto_trigger_step;
1783};
1784
1785static inline int wsm_set_uapsd_info(struct cw1200_common *priv,
1786 struct wsm_uapsd_info *arg)
1787{
1788 return wsm_write_mib(priv, WSM_MIB_ID_SET_UAPSD_INFORMATION,
1789 arg, sizeof(*arg));
1790}
1791
1792/* 4.22 OverrideInternalTxRate */
1793struct wsm_override_internal_txrate {
1794 u8 internalTxRate;
1795 u8 nonErpInternalTxRate;
1796 u8 reserved[2];
1797} __packed;
1798
1799static inline int wsm_set_override_internal_txrate(struct cw1200_common *priv,
1800 struct wsm_override_internal_txrate *arg)
1801{
1802 return wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1803 arg, sizeof(*arg));
1804}
1805
1806/* ******************************************************************** */
1807/* WSM TX port control */
1808
1809void wsm_lock_tx(struct cw1200_common *priv);
1810void wsm_lock_tx_async(struct cw1200_common *priv);
1811bool wsm_flush_tx(struct cw1200_common *priv);
1812void wsm_unlock_tx(struct cw1200_common *priv);
1813
1814/* ******************************************************************** */
1815/* WSM / BH API */
1816
1817int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len);
1818int wsm_handle_rx(struct cw1200_common *priv, u16 id, struct wsm_hdr *wsm,
1819 struct sk_buff **skb_p);
1820
1821/* ******************************************************************** */
1822/* wsm_buf API */
1823
1824struct wsm_buf {
1825 u8 *begin;
1826 u8 *data;
1827 u8 *end;
1828};
1829
1830void wsm_buf_init(struct wsm_buf *buf);
1831void wsm_buf_deinit(struct wsm_buf *buf);
1832
1833/* ******************************************************************** */
1834/* wsm_cmd API */
1835
1836struct wsm_cmd {
1837 spinlock_t lock; /* Protect structure from multiple access */
1838 int done;
1839 u8 *ptr;
1840 size_t len;
1841 void *arg;
1842 int ret;
1843 u16 cmd;
1844};
1845
1846/* ******************************************************************** */
1847/* WSM TX buffer access */
1848
1849int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1850 size_t *tx_len, int *burst);
1851void wsm_txed(struct cw1200_common *priv, u8 *data);
1852
1853/* ******************************************************************** */
1854/* Queue mapping: WSM <---> linux */
1855/* Linux: VO VI BE BK */
1856/* WSM: BE BK VI VO */
1857
1858static inline u8 wsm_queue_id_to_linux(u8 queue_id)
1859{
1860 static const u8 queue_mapping[] = {
1861 2, 3, 1, 0
1862 };
1863 return queue_mapping[queue_id];
1864}
1865
1866static inline u8 wsm_queue_id_to_wsm(u8 queue_id)
1867{
1868 static const u8 queue_mapping[] = {
1869 3, 2, 0, 1
1870 };
1871 return queue_mapping[queue_id];
1872}
1873
1874
1875#ifdef CONFIG_CW1200_ETF
1876int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len);
1877#endif
1878
1879#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 15920aaa5dd6..f8ab193009cd 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6242,8 +6242,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6242 if ((val & 0x0000ff00) != 0) 6242 if ((val & 0x0000ff00) != 0)
6243 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff); 6243 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6244 6244
6245 pci_set_power_state(pci_dev, PCI_D0);
6246
6247 if (!ipw2100_hw_is_adapter_in_system(dev)) { 6245 if (!ipw2100_hw_is_adapter_in_system(dev)) {
6248 printk(KERN_WARNING DRV_NAME 6246 printk(KERN_WARNING DRV_NAME
6249 "Device not found via register read.\n"); 6247 "Device not found via register read.\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 48545ab00311..de2c9514bef6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -76,13 +76,16 @@
76#define IWL_INVALID_STATION 255 76#define IWL_INVALID_STATION 255
77 77
78/* device operations */ 78/* device operations */
79extern struct iwl_lib_ops iwl1000_lib; 79extern const struct iwl_dvm_cfg iwl_dvm_1000_cfg;
80extern struct iwl_lib_ops iwl2000_lib; 80extern const struct iwl_dvm_cfg iwl_dvm_2000_cfg;
81extern struct iwl_lib_ops iwl2030_lib; 81extern const struct iwl_dvm_cfg iwl_dvm_105_cfg;
82extern struct iwl_lib_ops iwl5000_lib; 82extern const struct iwl_dvm_cfg iwl_dvm_2030_cfg;
83extern struct iwl_lib_ops iwl5150_lib; 83extern const struct iwl_dvm_cfg iwl_dvm_5000_cfg;
84extern struct iwl_lib_ops iwl6000_lib; 84extern const struct iwl_dvm_cfg iwl_dvm_5150_cfg;
85extern struct iwl_lib_ops iwl6030_lib; 85extern const struct iwl_dvm_cfg iwl_dvm_6000_cfg;
86extern const struct iwl_dvm_cfg iwl_dvm_6005_cfg;
87extern const struct iwl_dvm_cfg iwl_dvm_6050_cfg;
88extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
86 89
87 90
88#define TIME_UNIT 1024 91#define TIME_UNIT 1024
@@ -291,8 +294,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
291 294
292static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) 295static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
293{ 296{
294 return priv->cfg->bt_params && 297 return priv->lib->bt_params &&
295 priv->cfg->bt_params->advanced_bt_coexist; 298 priv->lib->bt_params->advanced_bt_coexist;
296} 299}
297 300
298#ifdef CONFIG_IWLWIFI_DEBUG 301#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index d6c4cf2ad7c5..1b0f0d502568 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -521,7 +521,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
521 521
522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); 522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
523 523
524 if (priv->cfg->base_params->hd_v2) { 524 if (priv->lib->hd_v2) {
525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = 525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; 526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = 527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
@@ -895,7 +895,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
895 continue; 895 continue;
896 } 896 }
897 897
898 delta_g = (priv->cfg->base_params->chain_noise_scale * 898 delta_g = (priv->lib->chain_noise_scale *
899 ((s32)average_noise[default_chain] - 899 ((s32)average_noise[default_chain] -
900 (s32)average_noise[i])) / 1500; 900 (s32)average_noise[i])) / 1500;
901 901
@@ -1051,8 +1051,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
1051 return; 1051 return;
1052 1052
1053 /* Analyze signal for disconnected antenna */ 1053 /* Analyze signal for disconnected antenna */
1054 if (priv->cfg->bt_params && 1054 if (priv->lib->bt_params &&
1055 priv->cfg->bt_params->advanced_bt_coexist) { 1055 priv->lib->bt_params->advanced_bt_coexist) {
1056 /* Disable disconnected antenna algorithm for advanced 1056 /* Disable disconnected antenna algorithm for advanced
1057 bt coex, assuming valid antennas are connected */ 1057 bt coex, assuming valid antennas are connected */
1058 data->active_chains = priv->nvm_data->valid_rx_ant; 1058 data->active_chains = priv->nvm_data->valid_rx_ant;
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 174b0f169497..ebdac909f0cd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -838,10 +838,6 @@ struct iwl_qosparam_cmd {
838#define STA_MODIFY_DELBA_TID_MSK 0x10 838#define STA_MODIFY_DELBA_TID_MSK 0x10
839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20
840 840
841/* Receiver address (actually, Rx station's index into station table),
842 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
843#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
844
845/* agn */ 841/* agn */
846struct iwl_keyinfo { 842struct iwl_keyinfo {
847 __le16 key_flags; 843 __le16 key_flags;
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index e71acfd344aa..5cd87f949266 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -568,16 +568,61 @@ struct iwl_hw_params {
568 const struct iwl_sensitivity_ranges *sens; 568 const struct iwl_sensitivity_ranges *sens;
569}; 569};
570 570
571struct iwl_lib_ops { 571/**
572 /* set hw dependent parameters */ 572 * struct iwl_dvm_bt_params - DVM specific BT (coex) parameters
573 * @advanced_bt_coexist: support advanced bt coexist
574 * @bt_init_traffic_load: specify initial bt traffic load
575 * @bt_prio_boost: default bt priority boost value
576 * @agg_time_limit: maximum number of uSec in aggregation
577 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
578 */
579struct iwl_dvm_bt_params {
580 bool advanced_bt_coexist;
581 u8 bt_init_traffic_load;
582 u32 bt_prio_boost;
583 u16 agg_time_limit;
584 bool bt_sco_disable;
585 bool bt_session_2;
586};
587
588/**
589 * struct iwl_dvm_cfg - DVM firmware specific device configuration
590 * @set_hw_params: set hardware parameters
591 * @set_channel_switch: send channel switch command
592 * @nic_config: apply device specific configuration
593 * @temperature: read temperature
594 * @adv_thermal_throttle: support advance thermal throttle
595 * @support_ct_kill_exit: support ct kill exit condition
596 * @plcp_delta_threshold: plcp error rate threshold used to trigger
597 * radio tuning when there is a high receiving plcp error rate
598 * @chain_noise_scale: default chain noise scale used for gain computation
599 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
600 * @no_idle_support: do not support idle mode
601 * @bt_params: pointer to BT parameters
602 * @need_temp_offset_calib: need to perform temperature offset calibration
603 * @no_xtal_calib: some devices do not need crystal calibration data,
604 * don't send it to those
605 * @temp_offset_v2: support v2 of temperature offset calibration
606 * @adv_pm: advanced power management
607 */
608struct iwl_dvm_cfg {
573 void (*set_hw_params)(struct iwl_priv *priv); 609 void (*set_hw_params)(struct iwl_priv *priv);
574 int (*set_channel_switch)(struct iwl_priv *priv, 610 int (*set_channel_switch)(struct iwl_priv *priv,
575 struct ieee80211_channel_switch *ch_switch); 611 struct ieee80211_channel_switch *ch_switch);
576 /* device specific configuration */
577 void (*nic_config)(struct iwl_priv *priv); 612 void (*nic_config)(struct iwl_priv *priv);
578
579 /* temperature */
580 void (*temperature)(struct iwl_priv *priv); 613 void (*temperature)(struct iwl_priv *priv);
614
615 const struct iwl_dvm_bt_params *bt_params;
616 s32 chain_noise_scale;
617 u8 plcp_delta_threshold;
618 bool adv_thermal_throttle;
619 bool support_ct_kill_exit;
620 bool hd_v2;
621 bool no_idle_support;
622 bool need_temp_offset_calib;
623 bool no_xtal_calib;
624 bool temp_offset_v2;
625 bool adv_pm;
581}; 626};
582 627
583struct iwl_wipan_noa_data { 628struct iwl_wipan_noa_data {
@@ -610,7 +655,7 @@ struct iwl_priv {
610 struct device *dev; /* for debug prints only */ 655 struct device *dev; /* for debug prints only */
611 const struct iwl_cfg *cfg; 656 const struct iwl_cfg *cfg;
612 const struct iwl_fw *fw; 657 const struct iwl_fw *fw;
613 const struct iwl_lib_ops *lib; 658 const struct iwl_dvm_cfg *lib;
614 unsigned long status; 659 unsigned long status;
615 660
616 spinlock_t sta_lock; 661 spinlock_t sta_lock;
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index c48907c8ab43..352c6cb7b4f1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -174,10 +174,13 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
174 priv->hw_params.sens = &iwl1000_sensitivity; 174 priv->hw_params.sens = &iwl1000_sensitivity;
175} 175}
176 176
177struct iwl_lib_ops iwl1000_lib = { 177const struct iwl_dvm_cfg iwl_dvm_1000_cfg = {
178 .set_hw_params = iwl1000_hw_set_hw_params, 178 .set_hw_params = iwl1000_hw_set_hw_params,
179 .nic_config = iwl1000_nic_config, 179 .nic_config = iwl1000_nic_config,
180 .temperature = iwlagn_temperature, 180 .temperature = iwlagn_temperature,
181 .support_ct_kill_exit = true,
182 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
183 .chain_noise_scale = 1000,
181}; 184};
182 185
183 186
@@ -232,16 +235,56 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
232 priv->hw_params.sens = &iwl2000_sensitivity; 235 priv->hw_params.sens = &iwl2000_sensitivity;
233} 236}
234 237
235struct iwl_lib_ops iwl2000_lib = { 238const struct iwl_dvm_cfg iwl_dvm_2000_cfg = {
236 .set_hw_params = iwl2000_hw_set_hw_params, 239 .set_hw_params = iwl2000_hw_set_hw_params,
237 .nic_config = iwl2000_nic_config, 240 .nic_config = iwl2000_nic_config,
238 .temperature = iwlagn_temperature, 241 .temperature = iwlagn_temperature,
242 .adv_thermal_throttle = true,
243 .support_ct_kill_exit = true,
244 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
245 .chain_noise_scale = 1000,
246 .hd_v2 = true,
247 .need_temp_offset_calib = true,
248 .temp_offset_v2 = true,
239}; 249};
240 250
241struct iwl_lib_ops iwl2030_lib = { 251const struct iwl_dvm_cfg iwl_dvm_105_cfg = {
242 .set_hw_params = iwl2000_hw_set_hw_params, 252 .set_hw_params = iwl2000_hw_set_hw_params,
243 .nic_config = iwl2000_nic_config, 253 .nic_config = iwl2000_nic_config,
244 .temperature = iwlagn_temperature, 254 .temperature = iwlagn_temperature,
255 .adv_thermal_throttle = true,
256 .support_ct_kill_exit = true,
257 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
258 .chain_noise_scale = 1000,
259 .hd_v2 = true,
260 .need_temp_offset_calib = true,
261 .temp_offset_v2 = true,
262 .adv_pm = true,
263};
264
265static const struct iwl_dvm_bt_params iwl2030_bt_params = {
266 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
267 .advanced_bt_coexist = true,
268 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
269 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
270 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
271 .bt_sco_disable = true,
272 .bt_session_2 = true,
273};
274
275const struct iwl_dvm_cfg iwl_dvm_2030_cfg = {
276 .set_hw_params = iwl2000_hw_set_hw_params,
277 .nic_config = iwl2000_nic_config,
278 .temperature = iwlagn_temperature,
279 .adv_thermal_throttle = true,
280 .support_ct_kill_exit = true,
281 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
282 .chain_noise_scale = 1000,
283 .hd_v2 = true,
284 .bt_params = &iwl2030_bt_params,
285 .need_temp_offset_calib = true,
286 .temp_offset_v2 = true,
287 .adv_pm = true,
245}; 288};
246 289
247/* 290/*
@@ -420,16 +463,23 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
420 return iwl_dvm_send_cmd(priv, &hcmd); 463 return iwl_dvm_send_cmd(priv, &hcmd);
421} 464}
422 465
423struct iwl_lib_ops iwl5000_lib = { 466const struct iwl_dvm_cfg iwl_dvm_5000_cfg = {
424 .set_hw_params = iwl5000_hw_set_hw_params, 467 .set_hw_params = iwl5000_hw_set_hw_params,
425 .set_channel_switch = iwl5000_hw_channel_switch, 468 .set_channel_switch = iwl5000_hw_channel_switch,
426 .temperature = iwlagn_temperature, 469 .temperature = iwlagn_temperature,
470 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
471 .chain_noise_scale = 1000,
472 .no_idle_support = true,
427}; 473};
428 474
429struct iwl_lib_ops iwl5150_lib = { 475const struct iwl_dvm_cfg iwl_dvm_5150_cfg = {
430 .set_hw_params = iwl5150_hw_set_hw_params, 476 .set_hw_params = iwl5150_hw_set_hw_params,
431 .set_channel_switch = iwl5000_hw_channel_switch, 477 .set_channel_switch = iwl5000_hw_channel_switch,
432 .temperature = iwl5150_temperature, 478 .temperature = iwl5150_temperature,
479 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
480 .chain_noise_scale = 1000,
481 .no_idle_support = true,
482 .no_xtal_calib = true,
433}; 483};
434 484
435 485
@@ -584,16 +634,59 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
584 return err; 634 return err;
585} 635}
586 636
587struct iwl_lib_ops iwl6000_lib = { 637const struct iwl_dvm_cfg iwl_dvm_6000_cfg = {
588 .set_hw_params = iwl6000_hw_set_hw_params, 638 .set_hw_params = iwl6000_hw_set_hw_params,
589 .set_channel_switch = iwl6000_hw_channel_switch, 639 .set_channel_switch = iwl6000_hw_channel_switch,
590 .nic_config = iwl6000_nic_config, 640 .nic_config = iwl6000_nic_config,
591 .temperature = iwlagn_temperature, 641 .temperature = iwlagn_temperature,
642 .adv_thermal_throttle = true,
643 .support_ct_kill_exit = true,
644 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
645 .chain_noise_scale = 1000,
646};
647
648const struct iwl_dvm_cfg iwl_dvm_6005_cfg = {
649 .set_hw_params = iwl6000_hw_set_hw_params,
650 .set_channel_switch = iwl6000_hw_channel_switch,
651 .nic_config = iwl6000_nic_config,
652 .temperature = iwlagn_temperature,
653 .adv_thermal_throttle = true,
654 .support_ct_kill_exit = true,
655 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
656 .chain_noise_scale = 1000,
657 .need_temp_offset_calib = true,
658};
659
660const struct iwl_dvm_cfg iwl_dvm_6050_cfg = {
661 .set_hw_params = iwl6000_hw_set_hw_params,
662 .set_channel_switch = iwl6000_hw_channel_switch,
663 .nic_config = iwl6000_nic_config,
664 .temperature = iwlagn_temperature,
665 .adv_thermal_throttle = true,
666 .support_ct_kill_exit = true,
667 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
668 .chain_noise_scale = 1500,
669};
670
671static const struct iwl_dvm_bt_params iwl6000_bt_params = {
672 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
673 .advanced_bt_coexist = true,
674 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
675 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
676 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
677 .bt_sco_disable = true,
592}; 678};
593 679
594struct iwl_lib_ops iwl6030_lib = { 680const struct iwl_dvm_cfg iwl_dvm_6030_cfg = {
595 .set_hw_params = iwl6000_hw_set_hw_params, 681 .set_hw_params = iwl6000_hw_set_hw_params,
596 .set_channel_switch = iwl6000_hw_channel_switch, 682 .set_channel_switch = iwl6000_hw_channel_switch,
597 .nic_config = iwl6000_nic_config, 683 .nic_config = iwl6000_nic_config,
598 .temperature = iwlagn_temperature, 684 .temperature = iwlagn_temperature,
685 .adv_thermal_throttle = true,
686 .support_ct_kill_exit = true,
687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
688 .chain_noise_scale = 1000,
689 .bt_params = &iwl6000_bt_params,
690 .need_temp_offset_calib = true,
691 .adv_pm = true,
599}; 692};
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 54f553380aa8..9879550a0fea 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -254,23 +254,23 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != 254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
255 sizeof(basic.bt3_lookup_table)); 255 sizeof(basic.bt3_lookup_table));
256 256
257 if (priv->cfg->bt_params) { 257 if (priv->lib->bt_params) {
258 /* 258 /*
259 * newer generation of devices (2000 series and newer) 259 * newer generation of devices (2000 series and newer)
260 * use the version 2 of the bt command 260 * use the version 2 of the bt command
261 * we need to make sure sending the host command 261 * we need to make sure sending the host command
262 * with correct data structure to avoid uCode assert 262 * with correct data structure to avoid uCode assert
263 */ 263 */
264 if (priv->cfg->bt_params->bt_session_2) { 264 if (priv->lib->bt_params->bt_session_2) {
265 bt_cmd_v2.prio_boost = cpu_to_le32( 265 bt_cmd_v2.prio_boost = cpu_to_le32(
266 priv->cfg->bt_params->bt_prio_boost); 266 priv->lib->bt_params->bt_prio_boost);
267 bt_cmd_v2.tx_prio_boost = 0; 267 bt_cmd_v2.tx_prio_boost = 0;
268 bt_cmd_v2.rx_prio_boost = 0; 268 bt_cmd_v2.rx_prio_boost = 0;
269 } else { 269 } else {
270 /* older version only has 8 bits */ 270 /* older version only has 8 bits */
271 WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF); 271 WARN_ON(priv->lib->bt_params->bt_prio_boost & ~0xFF);
272 bt_cmd_v1.prio_boost = 272 bt_cmd_v1.prio_boost =
273 priv->cfg->bt_params->bt_prio_boost; 273 priv->lib->bt_params->bt_prio_boost;
274 bt_cmd_v1.tx_prio_boost = 0; 274 bt_cmd_v1.tx_prio_boost = 0;
275 bt_cmd_v1.rx_prio_boost = 0; 275 bt_cmd_v1.rx_prio_boost = 0;
276 } 276 }
@@ -330,7 +330,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
330 priv->bt_full_concurrent ? 330 priv->bt_full_concurrent ?
331 "full concurrency" : "3-wire"); 331 "full concurrency" : "3-wire");
332 332
333 if (priv->cfg->bt_params->bt_session_2) { 333 if (priv->lib->bt_params->bt_session_2) {
334 memcpy(&bt_cmd_v2.basic, &basic, 334 memcpy(&bt_cmd_v2.basic, &basic,
335 sizeof(basic)); 335 sizeof(basic));
336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, 336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
@@ -758,8 +758,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv)
758 */ 758 */
759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) 759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
760{ 760{
761 if (priv->cfg->bt_params && 761 if (priv->lib->bt_params &&
762 priv->cfg->bt_params->advanced_bt_coexist && 762 priv->lib->bt_params->advanced_bt_coexist &&
763 (priv->bt_full_concurrent || 763 (priv->bt_full_concurrent ||
764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
765 /* 765 /*
@@ -830,8 +830,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
830 else 830 else
831 active_chains = priv->nvm_data->valid_rx_ant; 831 active_chains = priv->nvm_data->valid_rx_ant;
832 832
833 if (priv->cfg->bt_params && 833 if (priv->lib->bt_params &&
834 priv->cfg->bt_params->advanced_bt_coexist && 834 priv->lib->bt_params->advanced_bt_coexist &&
835 (priv->bt_full_concurrent || 835 (priv->bt_full_concurrent ||
836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
837 /* 837 /*
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 661b5e71aac8..f10c755d952c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -427,6 +427,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
427 if (ret) 427 if (ret)
428 goto error; 428 goto error;
429 429
430 /* let the ucode operate on its own */
431 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
432 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
433
430 iwl_trans_d3_suspend(priv->trans); 434 iwl_trans_d3_suspend(priv->trans);
431 435
432 goto out; 436 goto out;
@@ -510,6 +514,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
510 goto out_unlock; 514 goto out_unlock;
511 } 515 }
512 516
517 /* uCode is no longer operating by itself */
518 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
519 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
520
513 base = priv->device_pointers.error_event_table; 521 base = priv->device_pointers.error_event_table;
514 if (!iwlagn_hw_valid_rtc_data_addr(base)) { 522 if (!iwlagn_hw_valid_rtc_data_addr(base)) {
515 IWL_WARN(priv, "Invalid error table during resume!\n"); 523 IWL_WARN(priv, "Invalid error table during resume!\n");
@@ -1277,8 +1285,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1277 IWL_DEBUG_MAC80211(priv, "enter\n"); 1285 IWL_DEBUG_MAC80211(priv, "enter\n");
1278 mutex_lock(&priv->mutex); 1286 mutex_lock(&priv->mutex);
1279 1287
1280 if (priv->cfg->bt_params && 1288 if (priv->lib->bt_params &&
1281 priv->cfg->bt_params->advanced_bt_coexist) { 1289 priv->lib->bt_params->advanced_bt_coexist) {
1282 if (rssi_event == RSSI_EVENT_LOW) 1290 if (rssi_event == RSSI_EVENT_LOW)
1283 priv->bt_enable_pspoll = true; 1291 priv->bt_enable_pspoll = true;
1284 else if (rssi_event == RSSI_EVENT_HIGH) 1292 else if (rssi_event == RSSI_EVENT_HIGH)
@@ -1388,7 +1396,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
1388 return err; 1396 return err;
1389 } 1397 }
1390 1398
1391 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && 1399 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist &&
1392 vif->type == NL80211_IFTYPE_ADHOC) { 1400 vif->type == NL80211_IFTYPE_ADHOC) {
1393 /* 1401 /*
1394 * pretend to have high BT traffic as long as we 1402 * pretend to have high BT traffic as long as we
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 74d7572e7091..68f754659570 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -615,7 +615,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
615 615
616 priv->thermal_throttle.ct_kill_toggle = false; 616 priv->thermal_throttle.ct_kill_toggle = false;
617 617
618 if (priv->cfg->base_params->support_ct_kill_exit) { 618 if (priv->lib->support_ct_kill_exit) {
619 adv_cmd.critical_temperature_enter = 619 adv_cmd.critical_temperature_enter =
620 cpu_to_le32(priv->hw_params.ct_kill_threshold); 620 cpu_to_le32(priv->hw_params.ct_kill_threshold);
621 adv_cmd.critical_temperature_exit = 621 adv_cmd.critical_temperature_exit =
@@ -732,10 +732,10 @@ int iwl_alive_start(struct iwl_priv *priv)
732 } 732 }
733 733
734 /* download priority table before any calibration request */ 734 /* download priority table before any calibration request */
735 if (priv->cfg->bt_params && 735 if (priv->lib->bt_params &&
736 priv->cfg->bt_params->advanced_bt_coexist) { 736 priv->lib->bt_params->advanced_bt_coexist) {
737 /* Configure Bluetooth device coexistence support */ 737 /* Configure Bluetooth device coexistence support */
738 if (priv->cfg->bt_params->bt_sco_disable) 738 if (priv->lib->bt_params->bt_sco_disable)
739 priv->bt_enable_pspoll = false; 739 priv->bt_enable_pspoll = false;
740 else 740 else
741 priv->bt_enable_pspoll = true; 741 priv->bt_enable_pspoll = true;
@@ -873,9 +873,9 @@ void iwl_down(struct iwl_priv *priv)
873 priv->bt_status = 0; 873 priv->bt_status = 0;
874 priv->cur_rssi_ctx = NULL; 874 priv->cur_rssi_ctx = NULL;
875 priv->bt_is_sco = 0; 875 priv->bt_is_sco = 0;
876 if (priv->cfg->bt_params) 876 if (priv->lib->bt_params)
877 priv->bt_traffic_load = 877 priv->bt_traffic_load =
878 priv->cfg->bt_params->bt_init_traffic_load; 878 priv->lib->bt_params->bt_init_traffic_load;
879 else 879 else
880 priv->bt_traffic_load = 0; 880 priv->bt_traffic_load = 0;
881 priv->bt_full_concurrent = false; 881 priv->bt_full_concurrent = false;
@@ -1058,7 +1058,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1058 1058
1059 iwl_setup_scan_deferred_work(priv); 1059 iwl_setup_scan_deferred_work(priv);
1060 1060
1061 if (priv->cfg->bt_params) 1061 if (priv->lib->bt_params)
1062 iwlagn_bt_setup_deferred_work(priv); 1062 iwlagn_bt_setup_deferred_work(priv);
1063 1063
1064 init_timer(&priv->statistics_periodic); 1064 init_timer(&priv->statistics_periodic);
@@ -1072,7 +1072,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1072 1072
1073void iwl_cancel_deferred_work(struct iwl_priv *priv) 1073void iwl_cancel_deferred_work(struct iwl_priv *priv)
1074{ 1074{
1075 if (priv->cfg->bt_params) 1075 if (priv->lib->bt_params)
1076 iwlagn_bt_cancel_deferred_work(priv); 1076 iwlagn_bt_cancel_deferred_work(priv);
1077 1077
1078 cancel_work_sync(&priv->run_time_calib_work); 1078 cancel_work_sync(&priv->run_time_calib_work);
@@ -1098,8 +1098,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
1098 1098
1099 priv->band = IEEE80211_BAND_2GHZ; 1099 priv->band = IEEE80211_BAND_2GHZ;
1100 1100
1101 priv->plcp_delta_threshold = 1101 priv->plcp_delta_threshold = priv->lib->plcp_delta_threshold;
1102 priv->cfg->base_params->plcp_delta_threshold;
1103 1102
1104 priv->iw_mode = NL80211_IFTYPE_STATION; 1103 priv->iw_mode = NL80211_IFTYPE_STATION;
1105 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 1104 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
@@ -1116,8 +1115,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
1116 iwl_init_scan_params(priv); 1115 iwl_init_scan_params(priv);
1117 1116
1118 /* init bt coex */ 1117 /* init bt coex */
1119 if (priv->cfg->bt_params && 1118 if (priv->lib->bt_params &&
1120 priv->cfg->bt_params->advanced_bt_coexist) { 1119 priv->lib->bt_params->advanced_bt_coexist) {
1121 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 1120 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
1122 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 1121 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
1123 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 1122 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
@@ -1264,31 +1263,37 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1264 switch (priv->cfg->device_family) { 1263 switch (priv->cfg->device_family) {
1265 case IWL_DEVICE_FAMILY_1000: 1264 case IWL_DEVICE_FAMILY_1000:
1266 case IWL_DEVICE_FAMILY_100: 1265 case IWL_DEVICE_FAMILY_100:
1267 priv->lib = &iwl1000_lib; 1266 priv->lib = &iwl_dvm_1000_cfg;
1268 break; 1267 break;
1269 case IWL_DEVICE_FAMILY_2000: 1268 case IWL_DEVICE_FAMILY_2000:
1269 priv->lib = &iwl_dvm_2000_cfg;
1270 break;
1270 case IWL_DEVICE_FAMILY_105: 1271 case IWL_DEVICE_FAMILY_105:
1271 priv->lib = &iwl2000_lib; 1272 priv->lib = &iwl_dvm_105_cfg;
1272 break; 1273 break;
1273 case IWL_DEVICE_FAMILY_2030: 1274 case IWL_DEVICE_FAMILY_2030:
1274 case IWL_DEVICE_FAMILY_135: 1275 case IWL_DEVICE_FAMILY_135:
1275 priv->lib = &iwl2030_lib; 1276 priv->lib = &iwl_dvm_2030_cfg;
1276 break; 1277 break;
1277 case IWL_DEVICE_FAMILY_5000: 1278 case IWL_DEVICE_FAMILY_5000:
1278 priv->lib = &iwl5000_lib; 1279 priv->lib = &iwl_dvm_5000_cfg;
1279 break; 1280 break;
1280 case IWL_DEVICE_FAMILY_5150: 1281 case IWL_DEVICE_FAMILY_5150:
1281 priv->lib = &iwl5150_lib; 1282 priv->lib = &iwl_dvm_5150_cfg;
1282 break; 1283 break;
1283 case IWL_DEVICE_FAMILY_6000: 1284 case IWL_DEVICE_FAMILY_6000:
1284 case IWL_DEVICE_FAMILY_6005:
1285 case IWL_DEVICE_FAMILY_6000i: 1285 case IWL_DEVICE_FAMILY_6000i:
1286 priv->lib = &iwl_dvm_6000_cfg;
1287 break;
1288 case IWL_DEVICE_FAMILY_6005:
1289 priv->lib = &iwl_dvm_6005_cfg;
1290 break;
1286 case IWL_DEVICE_FAMILY_6050: 1291 case IWL_DEVICE_FAMILY_6050:
1287 case IWL_DEVICE_FAMILY_6150: 1292 case IWL_DEVICE_FAMILY_6150:
1288 priv->lib = &iwl6000_lib; 1293 priv->lib = &iwl_dvm_6050_cfg;
1289 break; 1294 break;
1290 case IWL_DEVICE_FAMILY_6030: 1295 case IWL_DEVICE_FAMILY_6030:
1291 priv->lib = &iwl6030_lib; 1296 priv->lib = &iwl_dvm_6030_cfg;
1292 break; 1297 break;
1293 default: 1298 default:
1294 break; 1299 break;
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index bd69018d07a9..77cb59712235 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -163,7 +163,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
163 u8 skip; 163 u8 skip;
164 u32 slp_itrvl; 164 u32 slp_itrvl;
165 165
166 if (priv->cfg->adv_pm) { 166 if (priv->lib->adv_pm) {
167 table = apm_range_2; 167 table = apm_range_2;
168 if (period <= IWL_DTIM_RANGE_1_MAX) 168 if (period <= IWL_DTIM_RANGE_1_MAX)
169 table = apm_range_1; 169 table = apm_range_1;
@@ -217,7 +217,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; 217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
218 218
219 if (iwl_advanced_bt_coexist(priv)) { 219 if (iwl_advanced_bt_coexist(priv)) {
220 if (!priv->cfg->bt_params->bt_sco_disable) 220 if (!priv->lib->bt_params->bt_sco_disable)
221 cmd->flags |= IWL_POWER_BT_SCO_ENA; 221 cmd->flags |= IWL_POWER_BT_SCO_ENA;
222 else 222 else
223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA; 223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
@@ -293,7 +293,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
293 293
294 if (priv->wowlan) 294 if (priv->wowlan)
295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); 295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
296 else if (!priv->cfg->base_params->no_idle_support && 296 else if (!priv->lib->no_idle_support &&
297 priv->hw->conf.flags & IEEE80211_CONF_IDLE) 297 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); 298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
299 else if (iwl_tt_is_low_power_state(priv)) { 299 else if (iwl_tt_is_low_power_state(priv)) {
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 907bd6e50aad..94314a8e1029 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -1088,7 +1088,7 @@ done:
1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) 1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1089 rs_program_fix_rate(priv, lq_sta); 1089 rs_program_fix_rate(priv, lq_sta);
1090#endif 1090#endif
1091 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) 1091 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
1092 rs_bt_update_lq(priv, ctx, lq_sta); 1092 rs_bt_update_lq(priv, ctx, lq_sta);
1093} 1093}
1094 1094
@@ -3064,11 +3064,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
3064 * overwrite if needed, pass aggregation time limit 3064 * overwrite if needed, pass aggregation time limit
3065 * to uCode in uSec 3065 * to uCode in uSec
3066 */ 3066 */
3067 if (priv && priv->cfg->bt_params && 3067 if (priv && priv->lib->bt_params &&
3068 priv->cfg->bt_params->agg_time_limit && 3068 priv->lib->bt_params->agg_time_limit &&
3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) 3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
3070 lq_cmd->agg_params.agg_time_limit = 3070 lq_cmd->agg_params.agg_time_limit =
3071 cpu_to_le16(priv->cfg->bt_params->agg_time_limit); 3071 cpu_to_le16(priv->lib->bt_params->agg_time_limit);
3072} 3072}
3073 3073
3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index a4eed2055fdb..2f3fd160ab44 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1102,7 +1102,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1102 iwl_notification_wait_init(&priv->notif_wait); 1102 iwl_notification_wait_init(&priv->notif_wait);
1103 1103
1104 /* Set up BT Rx handlers */ 1104 /* Set up BT Rx handlers */
1105 if (priv->cfg->bt_params) 1105 if (priv->lib->bt_params)
1106 iwlagn_bt_rx_handler_setup(priv); 1106 iwlagn_bt_rx_handler_setup(priv);
1107} 1107}
1108 1108
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index d69b55866714..8c686a5b90ac 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -801,8 +801,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
801 * Internal scans are passive, so we can indiscriminately set 801 * Internal scans are passive, so we can indiscriminately set
802 * the BT ignore flag on 2.4 GHz since it applies to TX only. 802 * the BT ignore flag on 2.4 GHz since it applies to TX only.
803 */ 803 */
804 if (priv->cfg->bt_params && 804 if (priv->lib->bt_params &&
805 priv->cfg->bt_params->advanced_bt_coexist) 805 priv->lib->bt_params->advanced_bt_coexist)
806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; 806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
807 break; 807 break;
808 case IEEE80211_BAND_5GHZ: 808 case IEEE80211_BAND_5GHZ:
@@ -844,8 +844,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
844 band = priv->scan_band; 844 band = priv->scan_band;
845 845
846 if (band == IEEE80211_BAND_2GHZ && 846 if (band == IEEE80211_BAND_2GHZ &&
847 priv->cfg->bt_params && 847 priv->lib->bt_params &&
848 priv->cfg->bt_params->advanced_bt_coexist) { 848 priv->lib->bt_params->advanced_bt_coexist) {
849 /* transmit 2.4 GHz probes only on first antenna */ 849 /* transmit 2.4 GHz probes only on first antenna */
850 scan_tx_antennas = first_antenna(scan_tx_antennas); 850 scan_tx_antennas = first_antenna(scan_tx_antennas);
851 } 851 }
@@ -873,8 +873,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
873 873
874 rx_ant = first_antenna(active_chains); 874 rx_ant = first_antenna(active_chains);
875 } 875 }
876 if (priv->cfg->bt_params && 876 if (priv->lib->bt_params &&
877 priv->cfg->bt_params->advanced_bt_coexist && 877 priv->lib->bt_params->advanced_bt_coexist &&
878 priv->bt_full_concurrent) { 878 priv->bt_full_concurrent) {
879 /* operated as 1x1 in full concurrency mode */ 879 /* operated as 1x1 in full concurrency mode */
880 rx_ant = first_antenna(rx_ant); 880 rx_ant = first_antenna(rx_ant);
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index db183b44e038..c3c13ce96eb0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -735,7 +735,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
735 memcpy(&lq, priv->stations[i].lq, 735 memcpy(&lq, priv->stations[i].lq,
736 sizeof(struct iwl_link_quality_cmd)); 736 sizeof(struct iwl_link_quality_cmd));
737 737
738 if (!memcmp(&lq, &zero_lq, sizeof(lq))) 738 if (memcmp(&lq, &zero_lq, sizeof(lq)))
739 send_lq = true; 739 send_lq = true;
740 } 740 }
741 spin_unlock_bh(&priv->sta_lock); 741 spin_unlock_bh(&priv->sta_lock);
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index 03f9bc01c0cc..fbeee081ee2f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -627,7 +627,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); 627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); 628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
629 629
630 if (priv->cfg->base_params->adv_thermal_throttle) { 630 if (priv->lib->adv_thermal_throttle) {
631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); 631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
632 tt->restriction = kcalloc(IWL_TI_STATE_MAX, 632 tt->restriction = kcalloc(IWL_TI_STATE_MAX,
633 sizeof(struct iwl_tt_restriction), 633 sizeof(struct iwl_tt_restriction),
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index a900aaf47790..353a053b4eb1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -83,8 +83,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
83 else if (ieee80211_is_back_req(fc)) 83 else if (ieee80211_is_back_req(fc))
84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
85 else if (info->band == IEEE80211_BAND_2GHZ && 85 else if (info->band == IEEE80211_BAND_2GHZ &&
86 priv->cfg->bt_params && 86 priv->lib->bt_params &&
87 priv->cfg->bt_params->advanced_bt_coexist && 87 priv->lib->bt_params->advanced_bt_coexist &&
88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || 88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
89 ieee80211_is_reassoc_req(fc) || 89 ieee80211_is_reassoc_req(fc) ||
90 skb->protocol == cpu_to_be16(ETH_P_PAE))) 90 skb->protocol == cpu_to_be16(ETH_P_PAE)))
@@ -202,8 +202,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
202 rate_flags |= RATE_MCS_CCK_MSK; 202 rate_flags |= RATE_MCS_CCK_MSK;
203 203
204 /* Set up antennas */ 204 /* Set up antennas */
205 if (priv->cfg->bt_params && 205 if (priv->lib->bt_params &&
206 priv->cfg->bt_params->advanced_bt_coexist && 206 priv->lib->bt_params->advanced_bt_coexist &&
207 priv->bt_full_concurrent) { 207 priv->bt_full_concurrent) {
208 /* operated as 1x1 in full concurrency mode */ 208 /* operated as 1x1 in full concurrency mode */
209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
@@ -986,8 +986,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
986 * notification again. 986 * notification again.
987 */ 987 */
988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && 988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
989 priv->cfg->bt_params && 989 priv->lib->bt_params &&
990 priv->cfg->bt_params->advanced_bt_coexist) { 990 priv->lib->bt_params->advanced_bt_coexist) {
991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); 991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
992 } 992 }
993 993
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 0a1cdc5e856b..86270b69cd02 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -132,8 +132,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
132{ 132{
133 int ret; 133 int ret;
134 134
135 if (priv->cfg->bt_params && 135 if (priv->lib->bt_params &&
136 priv->cfg->bt_params->advanced_bt_coexist) { 136 priv->lib->bt_params->advanced_bt_coexist) {
137 /* 137 /*
138 * Tell uCode we are ready to perform calibration 138 * Tell uCode we are ready to perform calibration
139 * need to perform this before any calibration 139 * need to perform this before any calibration
@@ -155,8 +155,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
155 * temperature offset calibration is only needed for runtime ucode, 155 * temperature offset calibration is only needed for runtime ucode,
156 * so prepare the value now. 156 * so prepare the value now.
157 */ 157 */
158 if (priv->cfg->need_temp_offset_calib) { 158 if (priv->lib->need_temp_offset_calib) {
159 if (priv->cfg->temp_offset_v2) 159 if (priv->lib->temp_offset_v2)
160 return iwl_set_temperature_offset_calib_v2(priv); 160 return iwl_set_temperature_offset_calib_v2(priv);
161 else 161 else
162 return iwl_set_temperature_offset_calib(priv); 162 return iwl_set_temperature_offset_calib(priv);
@@ -277,7 +277,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
277 if (ret) 277 if (ret)
278 return ret; 278 return ret;
279 279
280 if (!priv->cfg->no_xtal_calib) { 280 if (!priv->lib->no_xtal_calib) {
281 ret = iwl_set_Xtal_calib(priv); 281 ret = iwl_set_Xtal_calib(priv);
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index c080ae3070b2..0d2afe098afc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -60,9 +60,6 @@ static const struct iwl_base_params iwl1000_base_params = {
60 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 60 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
61 .shadow_ram_support = false, 61 .shadow_ram_support = false,
62 .led_compensation = 51, 62 .led_compensation = 51,
63 .support_ct_kill_exit = true,
64 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
65 .chain_noise_scale = 1000,
66 .wd_timeout = IWL_WATCHDOG_DISABLED, 63 .wd_timeout = IWL_WATCHDOG_DISABLED,
67 .max_event_log_size = 128, 64 .max_event_log_size = 128,
68}; 65};
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index a6ddd2f9fba0..c727ec7c90a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -72,14 +72,9 @@ static const struct iwl_base_params iwl2000_base_params = {
72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
73 .shadow_ram_support = true, 73 .shadow_ram_support = true,
74 .led_compensation = 51, 74 .led_compensation = 51,
75 .adv_thermal_throttle = true,
76 .support_ct_kill_exit = true,
77 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
78 .chain_noise_scale = 1000,
79 .wd_timeout = IWL_DEF_WD_TIMEOUT, 75 .wd_timeout = IWL_DEF_WD_TIMEOUT,
80 .max_event_log_size = 512, 76 .max_event_log_size = 512,
81 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 77 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
82 .hd_v2 = true,
83}; 78};
84 79
85 80
@@ -90,14 +85,9 @@ static const struct iwl_base_params iwl2030_base_params = {
90 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 85 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
91 .shadow_ram_support = true, 86 .shadow_ram_support = true,
92 .led_compensation = 57, 87 .led_compensation = 57,
93 .adv_thermal_throttle = true,
94 .support_ct_kill_exit = true,
95 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
96 .chain_noise_scale = 1000,
97 .wd_timeout = IWL_LONG_WD_TIMEOUT, 88 .wd_timeout = IWL_LONG_WD_TIMEOUT,
98 .max_event_log_size = 512, 89 .max_event_log_size = 512,
99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 90 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
100 .hd_v2 = true,
101}; 91};
102 92
103static const struct iwl_ht_params iwl2000_ht_params = { 93static const struct iwl_ht_params iwl2000_ht_params = {
@@ -106,16 +96,6 @@ static const struct iwl_ht_params iwl2000_ht_params = {
106 .ht40_bands = BIT(IEEE80211_BAND_2GHZ), 96 .ht40_bands = BIT(IEEE80211_BAND_2GHZ),
107}; 97};
108 98
109static const struct iwl_bt_params iwl2030_bt_params = {
110 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
111 .advanced_bt_coexist = true,
112 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
113 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
114 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
115 .bt_sco_disable = true,
116 .bt_session_2 = true,
117};
118
119static const struct iwl_eeprom_params iwl20x0_eeprom_params = { 99static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
120 .regulatory_bands = { 100 .regulatory_bands = {
121 EEPROM_REG_BAND_1_CHANNELS, 101 EEPROM_REG_BAND_1_CHANNELS,
@@ -137,12 +117,10 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
137 .device_family = IWL_DEVICE_FAMILY_2000, \ 117 .device_family = IWL_DEVICE_FAMILY_2000, \
138 .max_inst_size = IWL60_RTC_INST_SIZE, \ 118 .max_inst_size = IWL60_RTC_INST_SIZE, \
139 .max_data_size = IWL60_RTC_DATA_SIZE, \ 119 .max_data_size = IWL60_RTC_DATA_SIZE, \
140 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 120 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
141 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 121 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
142 .base_params = &iwl2000_base_params, \ 122 .base_params = &iwl2000_base_params, \
143 .eeprom_params = &iwl20x0_eeprom_params, \ 123 .eeprom_params = &iwl20x0_eeprom_params, \
144 .need_temp_offset_calib = true, \
145 .temp_offset_v2 = true, \
146 .led_mode = IWL_LED_RF_STATE 124 .led_mode = IWL_LED_RF_STATE
147 125
148const struct iwl_cfg iwl2000_2bgn_cfg = { 126const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -168,12 +146,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
168 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 146 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
169 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 147 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
170 .base_params = &iwl2030_base_params, \ 148 .base_params = &iwl2030_base_params, \
171 .bt_params = &iwl2030_bt_params, \
172 .eeprom_params = &iwl20x0_eeprom_params, \ 149 .eeprom_params = &iwl20x0_eeprom_params, \
173 .need_temp_offset_calib = true, \ 150 .led_mode = IWL_LED_RF_STATE
174 .temp_offset_v2 = true, \
175 .led_mode = IWL_LED_RF_STATE, \
176 .adv_pm = true
177 151
178const struct iwl_cfg iwl2030_2bgn_cfg = { 152const struct iwl_cfg iwl2030_2bgn_cfg = {
179 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", 153 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -193,10 +167,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
193 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 167 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
194 .base_params = &iwl2000_base_params, \ 168 .base_params = &iwl2000_base_params, \
195 .eeprom_params = &iwl20x0_eeprom_params, \ 169 .eeprom_params = &iwl20x0_eeprom_params, \
196 .need_temp_offset_calib = true, \
197 .temp_offset_v2 = true, \
198 .led_mode = IWL_LED_RF_STATE, \ 170 .led_mode = IWL_LED_RF_STATE, \
199 .adv_pm = true, \
200 .rx_with_siso_diversity = true 171 .rx_with_siso_diversity = true
201 172
202const struct iwl_cfg iwl105_bgn_cfg = { 173const struct iwl_cfg iwl105_bgn_cfg = {
@@ -222,12 +193,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
222 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 193 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
223 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 194 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
224 .base_params = &iwl2030_base_params, \ 195 .base_params = &iwl2030_base_params, \
225 .bt_params = &iwl2030_bt_params, \
226 .eeprom_params = &iwl20x0_eeprom_params, \ 196 .eeprom_params = &iwl20x0_eeprom_params, \
227 .need_temp_offset_calib = true, \
228 .temp_offset_v2 = true, \
229 .led_mode = IWL_LED_RF_STATE, \ 197 .led_mode = IWL_LED_RF_STATE, \
230 .adv_pm = true, \
231 .rx_with_siso_diversity = true 198 .rx_with_siso_diversity = true
232 199
233const struct iwl_cfg iwl135_bgn_cfg = { 200const struct iwl_cfg iwl135_bgn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 403f3f224bf6..ecc01e1a61a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -59,11 +59,8 @@ static const struct iwl_base_params iwl5000_base_params = {
59 .num_of_queues = IWLAGN_NUM_QUEUES, 59 .num_of_queues = IWLAGN_NUM_QUEUES,
60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
61 .led_compensation = 51, 61 .led_compensation = 51,
62 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
63 .chain_noise_scale = 1000,
64 .wd_timeout = IWL_WATCHDOG_DISABLED, 62 .wd_timeout = IWL_WATCHDOG_DISABLED,
65 .max_event_log_size = 512, 63 .max_event_log_size = 512,
66 .no_idle_support = true,
67}; 64};
68 65
69static const struct iwl_ht_params iwl5000_ht_params = { 66static const struct iwl_ht_params iwl5000_ht_params = {
@@ -159,7 +156,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
159 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 156 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
160 .base_params = &iwl5000_base_params, \ 157 .base_params = &iwl5000_base_params, \
161 .eeprom_params = &iwl5000_eeprom_params, \ 158 .eeprom_params = &iwl5000_eeprom_params, \
162 .no_xtal_calib = true, \
163 .led_mode = IWL_LED_BLINK, \ 159 .led_mode = IWL_LED_BLINK, \
164 .internal_wimax_coex = true 160 .internal_wimax_coex = true
165 161
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b5ab8d1bcac0..30d45e2fc193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -82,10 +82,6 @@ static const struct iwl_base_params iwl6000_base_params = {
82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
83 .shadow_ram_support = true, 83 .shadow_ram_support = true,
84 .led_compensation = 51, 84 .led_compensation = 51,
85 .adv_thermal_throttle = true,
86 .support_ct_kill_exit = true,
87 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
88 .chain_noise_scale = 1000,
89 .wd_timeout = IWL_DEF_WD_TIMEOUT, 85 .wd_timeout = IWL_DEF_WD_TIMEOUT,
90 .max_event_log_size = 512, 86 .max_event_log_size = 512,
91 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 87 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -98,10 +94,6 @@ static const struct iwl_base_params iwl6050_base_params = {
98 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 94 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
99 .shadow_ram_support = true, 95 .shadow_ram_support = true,
100 .led_compensation = 51, 96 .led_compensation = 51,
101 .adv_thermal_throttle = true,
102 .support_ct_kill_exit = true,
103 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
104 .chain_noise_scale = 1500,
105 .wd_timeout = IWL_DEF_WD_TIMEOUT, 97 .wd_timeout = IWL_DEF_WD_TIMEOUT,
106 .max_event_log_size = 1024, 98 .max_event_log_size = 1024,
107 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -114,10 +106,6 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
114 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 106 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
115 .shadow_ram_support = true, 107 .shadow_ram_support = true,
116 .led_compensation = 57, 108 .led_compensation = 57,
117 .adv_thermal_throttle = true,
118 .support_ct_kill_exit = true,
119 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
120 .chain_noise_scale = 1000,
121 .wd_timeout = IWL_LONG_WD_TIMEOUT, 109 .wd_timeout = IWL_LONG_WD_TIMEOUT,
122 .max_event_log_size = 512, 110 .max_event_log_size = 512,
123 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 111 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -129,15 +117,6 @@ static const struct iwl_ht_params iwl6000_ht_params = {
129 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 117 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
130}; 118};
131 119
132static const struct iwl_bt_params iwl6000_bt_params = {
133 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
134 .advanced_bt_coexist = true,
135 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
136 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
137 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
138 .bt_sco_disable = true,
139};
140
141static const struct iwl_eeprom_params iwl6000_eeprom_params = { 120static const struct iwl_eeprom_params iwl6000_eeprom_params = {
142 .regulatory_bands = { 121 .regulatory_bands = {
143 EEPROM_REG_BAND_1_CHANNELS, 122 EEPROM_REG_BAND_1_CHANNELS,
@@ -163,7 +142,6 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
163 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 142 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
164 .base_params = &iwl6000_g2_base_params, \ 143 .base_params = &iwl6000_g2_base_params, \
165 .eeprom_params = &iwl6000_eeprom_params, \ 144 .eeprom_params = &iwl6000_eeprom_params, \
166 .need_temp_offset_calib = true, \
167 .led_mode = IWL_LED_RF_STATE 145 .led_mode = IWL_LED_RF_STATE
168 146
169const struct iwl_cfg iwl6005_2agn_cfg = { 147const struct iwl_cfg iwl6005_2agn_cfg = {
@@ -217,11 +195,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
217 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 195 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
218 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 196 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
219 .base_params = &iwl6000_g2_base_params, \ 197 .base_params = &iwl6000_g2_base_params, \
220 .bt_params = &iwl6000_bt_params, \
221 .eeprom_params = &iwl6000_eeprom_params, \ 198 .eeprom_params = &iwl6000_eeprom_params, \
222 .need_temp_offset_calib = true, \ 199 .led_mode = IWL_LED_RF_STATE
223 .led_mode = IWL_LED_RF_STATE, \
224 .adv_pm = true \
225 200
226const struct iwl_cfg iwl6030_2agn_cfg = { 201const struct iwl_cfg iwl6030_2agn_cfg = {
227 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", 202 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -256,11 +231,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
256 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 231 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
257 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 232 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
258 .base_params = &iwl6000_g2_base_params, \ 233 .base_params = &iwl6000_g2_base_params, \
259 .bt_params = &iwl6000_bt_params, \
260 .eeprom_params = &iwl6000_eeprom_params, \ 234 .eeprom_params = &iwl6000_eeprom_params, \
261 .need_temp_offset_calib = true, \ 235 .led_mode = IWL_LED_RF_STATE
262 .led_mode = IWL_LED_RF_STATE, \
263 .adv_pm = true
264 236
265const struct iwl_cfg iwl6035_2agn_cfg = { 237const struct iwl_cfg iwl6035_2agn_cfg = {
266 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", 238 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 50263e87fe15..d4f3b4864ab1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -96,13 +96,9 @@ static const struct iwl_base_params iwl7000_base_params = {
96 .pll_cfg_val = 0, 96 .pll_cfg_val = 0,
97 .shadow_ram_support = true, 97 .shadow_ram_support = true,
98 .led_compensation = 57, 98 .led_compensation = 57,
99 .adv_thermal_throttle = true,
100 .support_ct_kill_exit = true,
101 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
102 .chain_noise_scale = 1000,
103 .wd_timeout = IWL_LONG_WD_TIMEOUT, 99 .wd_timeout = IWL_LONG_WD_TIMEOUT,
104 .max_event_log_size = 512, 100 .max_event_log_size = 512,
105 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 101 .shadow_reg_enable = true,
106}; 102};
107 103
108static const struct iwl_ht_params iwl7000_ht_params = { 104static const struct iwl_ht_params iwl7000_ht_params = {
@@ -118,14 +114,11 @@ static const struct iwl_ht_params iwl7000_ht_params = {
118 .max_inst_size = IWL60_RTC_INST_SIZE, \ 114 .max_inst_size = IWL60_RTC_INST_SIZE, \
119 .max_data_size = IWL60_RTC_DATA_SIZE, \ 115 .max_data_size = IWL60_RTC_DATA_SIZE, \
120 .base_params = &iwl7000_base_params, \ 116 .base_params = &iwl7000_base_params, \
121 /* TODO: .bt_params? */ \ 117 .led_mode = IWL_LED_RF_STATE
122 .need_temp_offset_calib = true, \
123 .led_mode = IWL_LED_RF_STATE, \
124 .adv_pm = true \
125 118
126 119
127const struct iwl_cfg iwl7260_2ac_cfg = { 120const struct iwl_cfg iwl7260_2ac_cfg = {
128 .name = "Intel(R) Dual Band Wireless AC7260", 121 .name = "Intel(R) Dual Band Wireless AC 7260",
129 .fw_name_pre = IWL7260_FW_PRE, 122 .fw_name_pre = IWL7260_FW_PRE,
130 IWL_DEVICE_7000, 123 IWL_DEVICE_7000,
131 .ht_params = &iwl7000_ht_params, 124 .ht_params = &iwl7000_ht_params,
@@ -133,8 +126,44 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
133 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 126 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
134}; 127};
135 128
136const struct iwl_cfg iwl3160_ac_cfg = { 129const struct iwl_cfg iwl7260_2n_cfg = {
137 .name = "Intel(R) Dual Band Wireless AC3160", 130 .name = "Intel(R) Dual Band Wireless N 7260",
131 .fw_name_pre = IWL7260_FW_PRE,
132 IWL_DEVICE_7000,
133 .ht_params = &iwl7000_ht_params,
134 .nvm_ver = IWL7260_NVM_VERSION,
135 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
136};
137
138const struct iwl_cfg iwl7260_n_cfg = {
139 .name = "Intel(R) Wireless N 7260",
140 .fw_name_pre = IWL7260_FW_PRE,
141 IWL_DEVICE_7000,
142 .ht_params = &iwl7000_ht_params,
143 .nvm_ver = IWL7260_NVM_VERSION,
144 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
145};
146
147const struct iwl_cfg iwl3160_2ac_cfg = {
148 .name = "Intel(R) Dual Band Wireless AC 3160",
149 .fw_name_pre = IWL3160_FW_PRE,
150 IWL_DEVICE_7000,
151 .ht_params = &iwl7000_ht_params,
152 .nvm_ver = IWL3160_NVM_VERSION,
153 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
154};
155
156const struct iwl_cfg iwl3160_2n_cfg = {
157 .name = "Intel(R) Dual Band Wireless N 3160",
158 .fw_name_pre = IWL3160_FW_PRE,
159 IWL_DEVICE_7000,
160 .ht_params = &iwl7000_ht_params,
161 .nvm_ver = IWL3160_NVM_VERSION,
162 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
163};
164
165const struct iwl_cfg iwl3160_n_cfg = {
166 .name = "Intel(R) Wireless N 3160",
138 .fw_name_pre = IWL3160_FW_PRE, 167 .fw_name_pre = IWL3160_FW_PRE,
139 IWL_DEVICE_7000, 168 IWL_DEVICE_7000,
140 .ht_params = &iwl7000_ht_params, 169 .ht_params = &iwl7000_ht_params,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index c38aa8f77554..a193832fc790 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -136,17 +136,9 @@ enum iwl_led_mode {
136 * @led_compensation: compensate on the led on/off time per HW according 136 * @led_compensation: compensate on the led on/off time per HW according
137 * to the deviation to achieve the desired led frequency. 137 * to the deviation to achieve the desired led frequency.
138 * The detail algorithm is described in iwl-led.c 138 * The detail algorithm is described in iwl-led.c
139 * @chain_noise_num_beacons: number of beacons used to compute chain noise
140 * @adv_thermal_throttle: support advance thermal throttle
141 * @support_ct_kill_exit: support ct kill exit condition
142 * @plcp_delta_threshold: plcp error rate threshold used to trigger
143 * radio tuning when there is a high receiving plcp error rate
144 * @chain_noise_scale: default chain noise scale used for gain computation
145 * @wd_timeout: TX queues watchdog timeout 139 * @wd_timeout: TX queues watchdog timeout
146 * @max_event_log_size: size of event log buffer size for ucode event logging 140 * @max_event_log_size: size of event log buffer size for ucode event logging
147 * @shadow_reg_enable: HW shadow register support 141 * @shadow_reg_enable: HW shadow register support
148 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
149 * @no_idle_support: do not support idle mode
150 */ 142 */
151struct iwl_base_params { 143struct iwl_base_params {
152 int eeprom_size; 144 int eeprom_size;
@@ -157,31 +149,9 @@ struct iwl_base_params {
157 const u16 max_ll_items; 149 const u16 max_ll_items;
158 const bool shadow_ram_support; 150 const bool shadow_ram_support;
159 u16 led_compensation; 151 u16 led_compensation;
160 bool adv_thermal_throttle;
161 bool support_ct_kill_exit;
162 u8 plcp_delta_threshold;
163 s32 chain_noise_scale;
164 unsigned int wd_timeout; 152 unsigned int wd_timeout;
165 u32 max_event_log_size; 153 u32 max_event_log_size;
166 const bool shadow_reg_enable; 154 const bool shadow_reg_enable;
167 const bool hd_v2;
168 const bool no_idle_support;
169};
170
171/*
172 * @advanced_bt_coexist: support advanced bt coexist
173 * @bt_init_traffic_load: specify initial bt traffic load
174 * @bt_prio_boost: default bt priority boost value
175 * @agg_time_limit: maximum number of uSec in aggregation
176 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
177 */
178struct iwl_bt_params {
179 bool advanced_bt_coexist;
180 u8 bt_init_traffic_load;
181 u32 bt_prio_boost;
182 u16 agg_time_limit;
183 bool bt_sco_disable;
184 bool bt_session_2;
185}; 155};
186 156
187/* 157/*
@@ -231,16 +201,10 @@ struct iwl_eeprom_params {
231 * @nvm_calib_ver: NVM calibration version 201 * @nvm_calib_ver: NVM calibration version
232 * @lib: pointer to the lib ops 202 * @lib: pointer to the lib ops
233 * @base_params: pointer to basic parameters 203 * @base_params: pointer to basic parameters
234 * @ht_params: point to ht patameters 204 * @ht_params: point to ht parameters
235 * @bt_params: pointer to bt parameters
236 * @need_temp_offset_calib: need to perform temperature offset calibration
237 * @no_xtal_calib: some devices do not need crystal calibration data,
238 * don't send it to those
239 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) 205 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
240 * @adv_pm: advance power management
241 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity 206 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
242 * @internal_wimax_coex: internal wifi/wimax combo device 207 * @internal_wimax_coex: internal wifi/wimax combo device
243 * @temp_offset_v2: support v2 of temperature offset calibration
244 * 208 *
245 * We enable the driver to be backward compatible wrt. hardware features. 209 * We enable the driver to be backward compatible wrt. hardware features.
246 * API differences in uCode shouldn't be handled here but through TLVs 210 * API differences in uCode shouldn't be handled here but through TLVs
@@ -264,15 +228,10 @@ struct iwl_cfg {
264 const struct iwl_base_params *base_params; 228 const struct iwl_base_params *base_params;
265 /* params likely to change within a device family */ 229 /* params likely to change within a device family */
266 const struct iwl_ht_params *ht_params; 230 const struct iwl_ht_params *ht_params;
267 const struct iwl_bt_params *bt_params;
268 const struct iwl_eeprom_params *eeprom_params; 231 const struct iwl_eeprom_params *eeprom_params;
269 const bool need_temp_offset_calib; /* if used set to true */
270 const bool no_xtal_calib;
271 enum iwl_led_mode led_mode; 232 enum iwl_led_mode led_mode;
272 const bool adv_pm;
273 const bool rx_with_siso_diversity; 233 const bool rx_with_siso_diversity;
274 const bool internal_wimax_coex; 234 const bool internal_wimax_coex;
275 const bool temp_offset_v2;
276}; 235};
277 236
278/* 237/*
@@ -320,6 +279,10 @@ extern const struct iwl_cfg iwl105_bgn_cfg;
320extern const struct iwl_cfg iwl105_bgn_d_cfg; 279extern const struct iwl_cfg iwl105_bgn_d_cfg;
321extern const struct iwl_cfg iwl135_bgn_cfg; 280extern const struct iwl_cfg iwl135_bgn_cfg;
322extern const struct iwl_cfg iwl7260_2ac_cfg; 281extern const struct iwl_cfg iwl7260_2ac_cfg;
323extern const struct iwl_cfg iwl3160_ac_cfg; 282extern const struct iwl_cfg iwl7260_2n_cfg;
283extern const struct iwl_cfg iwl7260_n_cfg;
284extern const struct iwl_cfg iwl3160_2ac_cfg;
285extern const struct iwl_cfg iwl3160_2n_cfg;
286extern const struct iwl_cfg iwl3160_n_cfg;
324 287
325#endif /* __IWL_CONFIG_H__ */ 288#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 20e845d4da04..a276af476e2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -472,4 +472,23 @@
472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) 472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) 473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
474 474
475/*****************************************************************************
476 * 7000/3000 series SHR DTS addresses *
477 *****************************************************************************/
478
479/* Diode Results Register Structure: */
480enum dtd_diode_reg {
481 DTS_DIODE_REG_DIG_VAL = 0x000000FF, /* bits [7:0] */
482 DTS_DIODE_REG_VREF_LOW = 0x0000FF00, /* bits [15:8] */
483 DTS_DIODE_REG_VREF_HIGH = 0x00FF0000, /* bits [23:16] */
484 DTS_DIODE_REG_VREF_ID = 0x03000000, /* bits [25:24] */
485 DTS_DIODE_REG_PASS_ONCE = 0x80000000, /* bits [31:31] */
486 DTS_DIODE_REG_FLAGS_MSK = 0xFF000000, /* bits [31:24] */
487/* Those are the masks INSIDE the flags bit-field: */
488 DTS_DIODE_REG_FLAGS_VREFS_ID_POS = 0,
489 DTS_DIODE_REG_FLAGS_VREFS_ID = 0x00000003, /* bits [1:0] */
490 DTS_DIODE_REG_FLAGS_PASS_ONCE_POS = 7,
491 DTS_DIODE_REG_FLAGS_PASS_ONCE = 0x00000080, /* bits [7:7] */
492};
493
475#endif /* !__iwl_csr_h__ */ 494#endif /* !__iwl_csr_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 39aad9893e0b..4f886133639a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1234,6 +1234,9 @@ MODULE_PARM_DESC(wd_disable,
1234 "Disable stuck queue watchdog timer 0=system default, " 1234 "Disable stuck queue watchdog timer 0=system default, "
1235 "1=disable, 2=enable (default: 0)"); 1235 "1=disable, 2=enable (default: 0)");
1236 1236
1237module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1238MODULE_PARM_DESC(nvm_file, "NVM file name");
1239
1237/* 1240/*
1238 * set bt_coex_active to true, uCode will do kill/defer 1241 * set bt_coex_active to true, uCode will do kill/defer
1239 * every time the priority line is asserted (BT is sending signals on the 1242 * every time the priority line is asserted (BT is sending signals on the
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 600c9fdd7f71..4c887f365908 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -732,17 +732,16 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
733 struct iwl_nvm_data *data, 733 struct iwl_nvm_data *data,
734 struct ieee80211_sta_ht_cap *ht_info, 734 struct ieee80211_sta_ht_cap *ht_info,
735 enum ieee80211_band band) 735 enum ieee80211_band band,
736 u8 tx_chains, u8 rx_chains)
736{ 737{
737 int max_bit_rate = 0; 738 int max_bit_rate = 0;
738 u8 rx_chains;
739 u8 tx_chains;
740 739
741 tx_chains = hweight8(data->valid_tx_ant); 740 tx_chains = hweight8(tx_chains);
742 if (cfg->rx_with_siso_diversity) 741 if (cfg->rx_with_siso_diversity)
743 rx_chains = 1; 742 rx_chains = 1;
744 else 743 else
745 rx_chains = hweight8(data->valid_rx_ant); 744 rx_chains = hweight8(rx_chains);
746 745
747 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) { 746 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) {
748 ht_info->ht_supported = false; 747 ht_info->ht_supported = false;
@@ -806,7 +805,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
806 sband->n_bitrates = N_RATES_24; 805 sband->n_bitrates = N_RATES_24;
807 n_used += iwl_init_sband_channels(data, sband, n_channels, 806 n_used += iwl_init_sband_channels(data, sband, n_channels,
808 IEEE80211_BAND_2GHZ); 807 IEEE80211_BAND_2GHZ);
809 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 808 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
809 data->valid_tx_ant, data->valid_rx_ant);
810 810
811 sband = &data->bands[IEEE80211_BAND_5GHZ]; 811 sband = &data->bands[IEEE80211_BAND_5GHZ];
812 sband->band = IEEE80211_BAND_5GHZ; 812 sband->band = IEEE80211_BAND_5GHZ;
@@ -814,7 +814,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
814 sband->n_bitrates = N_RATES_52; 814 sband->n_bitrates = N_RATES_52;
815 n_used += iwl_init_sband_channels(data, sband, n_channels, 815 n_used += iwl_init_sband_channels(data, sband, n_channels,
816 IEEE80211_BAND_5GHZ); 816 IEEE80211_BAND_5GHZ);
817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
818 data->valid_tx_ant, data->valid_rx_ant);
818 819
819 if (n_channels != n_used) 820 if (n_channels != n_used)
820 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", 821 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 37f115390b19..d73304a23ec2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -133,6 +133,7 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
134 struct iwl_nvm_data *data, 134 struct iwl_nvm_data *data,
135 struct ieee80211_sta_ht_cap *ht_info, 135 struct ieee80211_sta_ht_cap *ht_info,
136 enum ieee80211_band band); 136 enum ieee80211_band band,
137 u8 tx_chains, u8 rx_chains);
137 138
138#endif /* __iwl_eeprom_parse_h__ */ 139#endif /* __iwl_eeprom_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index c4c446d41eb0..f844d5c748c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -106,11 +106,14 @@ enum iwl_ucode_type {
106 106
107/* 107/*
108 * enumeration of ucode section. 108 * enumeration of ucode section.
109 * This enumeration is used for legacy tlv style (before 16.0 uCode). 109 * This enumeration is used directly for older firmware (before 16.0).
110 * For new firmware, there can be up to 4 sections (see below) but the
111 * first one packaged into the firmware file is the DATA section and
112 * some debugging code accesses that.
110 */ 113 */
111enum iwl_ucode_sec { 114enum iwl_ucode_sec {
112 IWL_UCODE_SECTION_INST,
113 IWL_UCODE_SECTION_DATA, 115 IWL_UCODE_SECTION_DATA,
116 IWL_UCODE_SECTION_INST,
114}; 117};
115/* 118/*
116 * For 16.0 uCode and above, there is no differentiation between sections, 119 * For 16.0 uCode and above, there is no differentiation between sections,
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d6f6c37c09fd..36dfe0919f6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -119,6 +119,7 @@ struct iwl_mod_params {
119 int ant_coupling; 119 int ant_coupling;
120 bool bt_ch_announce; 120 bool bt_ch_announce;
121 bool auto_agg; 121 bool auto_agg;
122 char *nvm_file;
122}; 123};
123 124
124#endif /* #__iwl_modparams_h__ */ 125#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 6199a0a597a6..acd2665afb8c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -89,6 +89,7 @@ enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0), 89 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
90 NVM_SKU_CAP_BAND_52GHZ = BIT(1), 90 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
91 NVM_SKU_CAP_11N_ENABLE = BIT(2), 91 NVM_SKU_CAP_11N_ENABLE = BIT(2),
92 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
92}; 93};
93 94
94/* radio config bits (actual values from NVM definition) */ 95/* radio config bits (actual values from NVM definition) */
@@ -258,8 +259,6 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 struct iwl_nvm_data *data, 259 struct iwl_nvm_data *data,
259 struct ieee80211_sta_vht_cap *vht_cap) 260 struct ieee80211_sta_vht_cap *vht_cap)
260{ 261{
261 /* For now, assume new devices with NVM are VHT capable */
262
263 vht_cap->vht_supported = true; 262 vht_cap->vht_supported = true;
264 263
265 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | 264 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
@@ -292,7 +291,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
292} 291}
293 292
294static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 293static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
295 struct iwl_nvm_data *data, const __le16 *nvm_sw) 294 struct iwl_nvm_data *data, const __le16 *nvm_sw,
295 bool enable_vht, u8 tx_chains, u8 rx_chains)
296{ 296{
297 int n_channels = iwl_init_channel_map(dev, cfg, data, 297 int n_channels = iwl_init_channel_map(dev, cfg, data,
298 &nvm_sw[NVM_CHANNELS]); 298 &nvm_sw[NVM_CHANNELS]);
@@ -305,7 +305,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
305 sband->n_bitrates = N_RATES_24; 305 sband->n_bitrates = N_RATES_24;
306 n_used += iwl_init_sband_channels(data, sband, n_channels, 306 n_used += iwl_init_sband_channels(data, sband, n_channels,
307 IEEE80211_BAND_2GHZ); 307 IEEE80211_BAND_2GHZ);
308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
309 tx_chains, rx_chains);
309 310
310 sband = &data->bands[IEEE80211_BAND_5GHZ]; 311 sband = &data->bands[IEEE80211_BAND_5GHZ];
311 sband->band = IEEE80211_BAND_5GHZ; 312 sband->band = IEEE80211_BAND_5GHZ;
@@ -313,8 +314,10 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
313 sband->n_bitrates = N_RATES_52; 314 sband->n_bitrates = N_RATES_52;
314 n_used += iwl_init_sband_channels(data, sband, n_channels, 315 n_used += iwl_init_sband_channels(data, sband, n_channels,
315 IEEE80211_BAND_5GHZ); 316 IEEE80211_BAND_5GHZ);
316 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 317 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
317 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); 318 tx_chains, rx_chains);
319 if (enable_vht)
320 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
318 321
319 if (n_channels != n_used) 322 if (n_channels != n_used)
320 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", 323 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -324,7 +327,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
324struct iwl_nvm_data * 327struct iwl_nvm_data *
325iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 328iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
326 const __le16 *nvm_hw, const __le16 *nvm_sw, 329 const __le16 *nvm_hw, const __le16 *nvm_sw,
327 const __le16 *nvm_calib) 330 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
328{ 331{
329 struct iwl_nvm_data *data; 332 struct iwl_nvm_data *data;
330 u8 hw_addr[ETH_ALEN]; 333 u8 hw_addr[ETH_ALEN];
@@ -380,7 +383,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
380 data->hw_addr[4] = hw_addr[5]; 383 data->hw_addr[4] = hw_addr[5];
381 data->hw_addr[5] = hw_addr[4]; 384 data->hw_addr[5] = hw_addr[4];
382 385
383 iwl_init_sbands(dev, cfg, data, nvm_sw); 386 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
387 tx_chains, rx_chains);
384 388
385 data->calib_version = 255; /* TODO: 389 data->calib_version = 255; /* TODO:
386 this value will prevent some checks from 390 this value will prevent some checks from
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index e57fb989661e..3325059c52d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -75,6 +75,6 @@
75struct iwl_nvm_data * 75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib); 78 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains);
79 79
80#endif /* __iwl_nvm_parse_h__ */ 80#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 386f2a7c87cb..ff8cc75c189d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -100,6 +100,18 @@
100/* Device system time */ 100/* Device system time */
101#define DEVICE_SYSTEM_TIME_REG 0xA0206C 101#define DEVICE_SYSTEM_TIME_REG 0xA0206C
102 102
103/*****************************************************************************
104 * 7000/3000 series SHR DTS addresses *
105 *****************************************************************************/
106
107#define SHR_MISC_WFM_DTS_EN (0x00a10024)
108#define DTSC_CFG_MODE (0x00a10604)
109#define DTSC_VREF_AVG (0x00a10648)
110#define DTSC_VREF5_AVG (0x00a1064c)
111#define DTSC_CFG_MODE_PERIODIC (0x2)
112#define DTSC_PTAT_AVG (0x00a10650)
113
114
103/** 115/**
104 * Tx Scheduler 116 * Tx Scheduler
105 * 117 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 7a13790b5bfe..84f1c8dc9741 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -189,7 +189,8 @@ enum CMD_MODE {
189 CMD_SYNC = 0, 189 CMD_SYNC = 0,
190 CMD_ASYNC = BIT(0), 190 CMD_ASYNC = BIT(0),
191 CMD_WANT_SKB = BIT(1), 191 CMD_WANT_SKB = BIT(1),
192 CMD_ON_DEMAND = BIT(2), 192 CMD_SEND_IN_RFKILL = BIT(2),
193 CMD_ON_DEMAND = BIT(3),
193}; 194};
194 195
195#define DEF_CMD_PAYLOAD_SIZE 320 196#define DEF_CMD_PAYLOAD_SIZE 320
@@ -455,7 +456,7 @@ struct iwl_trans_ops {
455 int (*read_mem)(struct iwl_trans *trans, u32 addr, 456 int (*read_mem)(struct iwl_trans *trans, u32 addr,
456 void *buf, int dwords); 457 void *buf, int dwords);
457 int (*write_mem)(struct iwl_trans *trans, u32 addr, 458 int (*write_mem)(struct iwl_trans *trans, u32 addr,
458 void *buf, int dwords); 459 const void *buf, int dwords);
459 void (*configure)(struct iwl_trans *trans, 460 void (*configure)(struct iwl_trans *trans,
460 const struct iwl_trans_config *trans_cfg); 461 const struct iwl_trans_config *trans_cfg);
461 void (*set_pmi)(struct iwl_trans *trans, bool state); 462 void (*set_pmi)(struct iwl_trans *trans, bool state);
@@ -761,7 +762,7 @@ static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr)
761} 762}
762 763
763static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, 764static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
764 void *buf, int dwords) 765 const void *buf, int dwords)
765{ 766{
766 return trans->ops->write_mem(trans, addr, buf, dwords); 767 return trans->ops->write_mem(trans, addr, buf, dwords);
767} 768}
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 2acc44b40986..ff856e543ae8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o bt-coex.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 810bfa5f6de0..f03655f303aa 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -351,6 +351,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
351 enum ieee80211_band band; 351 enum ieee80211_band band;
352 int ave_rssi; 352 int ave_rssi;
353 353
354 lockdep_assert_held(&mvm->mutex);
354 if (vif->type != NL80211_IFTYPE_STATION) 355 if (vif->type != NL80211_IFTYPE_STATION)
355 return; 356 return;
356 357
@@ -365,7 +366,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
365 smps_mode = IEEE80211_SMPS_AUTOMATIC; 366 smps_mode = IEEE80211_SMPS_AUTOMATIC;
366 367
367 if (band != IEEE80211_BAND_2GHZ) { 368 if (band != IEEE80211_BAND_2GHZ) {
368 ieee80211_request_smps(vif, smps_mode); 369 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
370 smps_mode);
369 return; 371 return;
370 } 372 }
371 373
@@ -380,7 +382,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
380 mvmvif->id, data->notif->bt_status, 382 mvmvif->id, data->notif->bt_status,
381 data->notif->bt_traffic_load, smps_mode); 383 data->notif->bt_traffic_load, smps_mode);
382 384
383 ieee80211_request_smps(vif, smps_mode); 385 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
384 386
385 /* don't reduce the Tx power if in loose scheme */ 387 /* don't reduce the Tx power if in loose scheme */
386 if (is_loose_coex()) 388 if (is_loose_coex())
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 16bbdcc8627a..4d3c978b5c76 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1007,6 +1007,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1007 if (ret) 1007 if (ret)
1008 goto out; 1008 goto out;
1009 1009
1010 ret = iwl_mvm_power_update_mode(mvm, vif);
1011 if (ret)
1012 goto out;
1013
1010 /* must be last -- this switches firmware state */ 1014 /* must be last -- this switches firmware state */
1011 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1015 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
1012 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1016 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
@@ -1214,6 +1218,26 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1214 iwl_free_resp(&cmd); 1218 iwl_free_resp(&cmd);
1215} 1219}
1216 1220
1221static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
1222{
1223#ifdef CONFIG_IWLWIFI_DEBUGFS
1224 const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
1225 u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
1226 u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
1227
1228 if (!mvm->store_d3_resume_sram)
1229 return;
1230
1231 if (!mvm->d3_resume_sram) {
1232 mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
1233 if (!mvm->d3_resume_sram)
1234 return;
1235 }
1236
1237 iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
1238#endif
1239}
1240
1217int iwl_mvm_resume(struct ieee80211_hw *hw) 1241int iwl_mvm_resume(struct ieee80211_hw *hw)
1218{ 1242{
1219 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1243 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@@ -1245,6 +1269,9 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1245 goto out_unlock; 1269 goto out_unlock;
1246 } 1270 }
1247 1271
1272 /* query SRAM first in case we want event logging */
1273 iwl_mvm_read_d3_sram(mvm);
1274
1248 iwl_mvm_query_wakeup_reasons(mvm, vif); 1275 iwl_mvm_query_wakeup_reasons(mvm, vif);
1249 1276
1250 out_unlock: 1277 out_unlock:
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 2053dccefcd6..69e0806075a2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -145,15 +145,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
145 char *buf; 145 char *buf;
146 u8 *ptr; 146 u8 *ptr;
147 147
148 if (!mvm->ucode_loaded)
149 return -EINVAL;
150
148 /* default is to dump the entire data segment */ 151 /* default is to dump the entire data segment */
149 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { 152 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
150 mvm->dbgfs_sram_offset = 0x800000;
151 if (!mvm->ucode_loaded)
152 return -EINVAL;
153 img = &mvm->fw->img[mvm->cur_ucode]; 153 img = &mvm->fw->img[mvm->cur_ucode];
154 mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 154 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
155 len = img->sec[IWL_UCODE_SECTION_DATA].len;
156 } else {
157 ofs = mvm->dbgfs_sram_offset;
158 len = mvm->dbgfs_sram_len;
155 } 159 }
156 len = mvm->dbgfs_sram_len;
157 160
158 bufsz = len * 4 + 256; 161 bufsz = len * 4 + 256;
159 buf = kzalloc(bufsz, GFP_KERNEL); 162 buf = kzalloc(bufsz, GFP_KERNEL);
@@ -167,12 +170,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
167 } 170 }
168 171
169 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len); 172 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
170 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 173 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
171 mvm->dbgfs_sram_offset);
172 174
173 iwl_trans_read_mem_bytes(mvm->trans, 175 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
174 mvm->dbgfs_sram_offset,
175 ptr, len);
176 for (ofs = 0; ofs < len; ofs += 16) { 176 for (ofs = 0; ofs < len; ofs += 16) {
177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs); 177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos, 178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
@@ -300,6 +300,146 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
300 return count; 300 return count;
301} 301}
302 302
303static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
304 struct ieee80211_vif *vif,
305 enum iwl_dbgfs_pm_mask param, int val)
306{
307 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
308 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
309
310 dbgfs_pm->mask |= param;
311
312 switch (param) {
313 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
314 struct ieee80211_hw *hw = mvm->hw;
315 int dtimper = hw->conf.ps_dtim_period ?: 1;
316 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
317
318 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
319 if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
320 IWL_WARN(mvm,
321 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
322 val * MSEC_PER_SEC, 3 * dtimper_msec);
323 }
324 dbgfs_pm->keep_alive_seconds = val;
325 break;
326 }
327 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
328 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
329 val ? "enabled" : "disabled");
330 dbgfs_pm->skip_over_dtim = val;
331 break;
332 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
333 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
334 dbgfs_pm->skip_dtim_periods = val;
335 break;
336 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
337 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
338 dbgfs_pm->rx_data_timeout = val;
339 break;
340 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
341 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
342 dbgfs_pm->tx_data_timeout = val;
343 break;
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val;
347 break;
348 }
349}
350
351static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
352 const char __user *user_buf,
353 size_t count, loff_t *ppos)
354{
355 struct ieee80211_vif *vif = file->private_data;
356 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
357 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
358 enum iwl_dbgfs_pm_mask param;
359 char buf[32] = {};
360 int val;
361 int ret;
362
363 if (copy_from_user(buf, user_buf, sizeof(buf)))
364 return -EFAULT;
365
366 if (!strncmp("keep_alive=", buf, 11)) {
367 if (sscanf(buf + 11, "%d", &val) != 1)
368 return -EINVAL;
369 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
370 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
371 if (sscanf(buf + 15, "%d", &val) != 1)
372 return -EINVAL;
373 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
374 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
375 if (sscanf(buf + 18, "%d", &val) != 1)
376 return -EINVAL;
377 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
378 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
379 if (sscanf(buf + 16, "%d", &val) != 1)
380 return -EINVAL;
381 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
382 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
383 if (sscanf(buf + 16, "%d", &val) != 1)
384 return -EINVAL;
385 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
386 } else if (!strncmp("disable_power_off=", buf, 18)) {
387 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
390 } else {
391 return -EINVAL;
392 }
393
394 mutex_lock(&mvm->mutex);
395 iwl_dbgfs_update_pm(mvm, vif, param, val);
396 ret = iwl_mvm_power_update_mode(mvm, vif);
397 mutex_unlock(&mvm->mutex);
398
399 return ret ?: count;
400}
401
402static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
403 char __user *user_buf,
404 size_t count, loff_t *ppos)
405{
406 struct ieee80211_vif *vif = file->private_data;
407 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
408 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
409 struct iwl_powertable_cmd cmd = {};
410 char buf[256];
411 int bufsz = sizeof(buf);
412 int pos = 0;
413
414 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
415
416 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
417 (cmd.flags &
418 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
419 0 : 1);
420 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
421 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n",
425 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds);
428
429 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
430 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
431 (cmd.flags &
432 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
433 1 : 0);
434 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
435 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout));
438 }
439
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
441}
442
303static ssize_t iwl_dbgfs_mac_params_read(struct file *file, 443static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
304 char __user *user_buf, 444 char __user *user_buf,
305 size_t count, loff_t *ppos) 445 size_t count, loff_t *ppos)
@@ -481,6 +621,255 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
481 return count; 621 return count;
482} 622}
483 623
624static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
625 enum iwl_dbgfs_bf_mask param, int value)
626{
627 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
628 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
629
630 dbgfs_bf->mask |= param;
631
632 switch (param) {
633 case MVM_DEBUGFS_BF_ENERGY_DELTA:
634 dbgfs_bf->bf_energy_delta = value;
635 break;
636 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
637 dbgfs_bf->bf_roaming_energy_delta = value;
638 break;
639 case MVM_DEBUGFS_BF_ROAMING_STATE:
640 dbgfs_bf->bf_roaming_state = value;
641 break;
642 case MVM_DEBUGFS_BF_TEMPERATURE_DELTA:
643 dbgfs_bf->bf_temperature_delta = value;
644 break;
645 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
646 dbgfs_bf->bf_enable_beacon_filter = value;
647 break;
648 case MVM_DEBUGFS_BF_DEBUG_FLAG:
649 dbgfs_bf->bf_debug_flag = value;
650 break;
651 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
652 dbgfs_bf->bf_escape_timer = value;
653 break;
654 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
655 dbgfs_bf->ba_enable_beacon_abort = value;
656 break;
657 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
658 dbgfs_bf->ba_escape_timer = value;
659 break;
660 }
661}
662
663static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
664 const char __user *user_buf,
665 size_t count, loff_t *ppos)
666{
667 struct ieee80211_vif *vif = file->private_data;
668 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
669 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
670 enum iwl_dbgfs_bf_mask param;
671 char buf[256];
672 int buf_size;
673 int value;
674 int ret = 0;
675
676 memset(buf, 0, sizeof(buf));
677 buf_size = min(count, sizeof(buf) - 1);
678 if (copy_from_user(buf, user_buf, buf_size))
679 return -EFAULT;
680
681 if (!strncmp("bf_energy_delta=", buf, 16)) {
682 if (sscanf(buf+16, "%d", &value) != 1)
683 return -EINVAL;
684 if (value < IWL_BF_ENERGY_DELTA_MIN ||
685 value > IWL_BF_ENERGY_DELTA_MAX)
686 return -EINVAL;
687 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
688 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
689 if (sscanf(buf+24, "%d", &value) != 1)
690 return -EINVAL;
691 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
692 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
693 return -EINVAL;
694 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
695 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
696 if (sscanf(buf+17, "%d", &value) != 1)
697 return -EINVAL;
698 if (value < IWL_BF_ROAMING_STATE_MIN ||
699 value > IWL_BF_ROAMING_STATE_MAX)
700 return -EINVAL;
701 param = MVM_DEBUGFS_BF_ROAMING_STATE;
702 } else if (!strncmp("bf_temperature_delta=", buf, 21)) {
703 if (sscanf(buf+21, "%d", &value) != 1)
704 return -EINVAL;
705 if (value < IWL_BF_TEMPERATURE_DELTA_MIN ||
706 value > IWL_BF_TEMPERATURE_DELTA_MAX)
707 return -EINVAL;
708 param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA;
709 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
710 if (sscanf(buf+24, "%d", &value) != 1)
711 return -EINVAL;
712 if (value < 0 || value > 1)
713 return -EINVAL;
714 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
715 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
716 if (sscanf(buf+14, "%d", &value) != 1)
717 return -EINVAL;
718 if (value < 0 || value > 1)
719 return -EINVAL;
720 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
721 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
722 if (sscanf(buf+16, "%d", &value) != 1)
723 return -EINVAL;
724 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
725 value > IWL_BF_ESCAPE_TIMER_MAX)
726 return -EINVAL;
727 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
728 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
729 if (sscanf(buf+16, "%d", &value) != 1)
730 return -EINVAL;
731 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
732 value > IWL_BA_ESCAPE_TIMER_MAX)
733 return -EINVAL;
734 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
735 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
736 if (sscanf(buf+23, "%d", &value) != 1)
737 return -EINVAL;
738 if (value < 0 || value > 1)
739 return -EINVAL;
740 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
741 } else {
742 return -EINVAL;
743 }
744
745 mutex_lock(&mvm->mutex);
746 iwl_dbgfs_update_bf(vif, param, value);
747 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
748 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
749 } else {
750 if (mvmvif->bf_enabled)
751 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
752 else
753 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
754 }
755 mutex_unlock(&mvm->mutex);
756
757 return ret ?: count;
758}
759
760static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
761 char __user *user_buf,
762 size_t count, loff_t *ppos)
763{
764 struct ieee80211_vif *vif = file->private_data;
765 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
766 char buf[256];
767 int pos = 0;
768 const size_t bufsz = sizeof(buf);
769 struct iwl_beacon_filter_cmd cmd = {
770 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
771 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
772 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
773 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
774 .bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT,
775 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
776 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
777 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
778 .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
779 };
780
781 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
782 if (mvmvif->bf_enabled)
783 cmd.bf_enable_beacon_filter = 1;
784 else
785 cmd.bf_enable_beacon_filter = 0;
786
787 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
788 cmd.bf_energy_delta);
789 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
790 cmd.bf_roaming_energy_delta);
791 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
792 cmd.bf_roaming_state);
793 pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n",
794 cmd.bf_temperature_delta);
795 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
796 cmd.bf_enable_beacon_filter);
797 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
798 cmd.bf_debug_flag);
799 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
800 cmd.bf_escape_timer);
801 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
802 cmd.ba_escape_timer);
803 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
804 cmd.ba_enable_beacon_abort);
805
806 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
807}
808
809#ifdef CONFIG_PM_SLEEP
810static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
811 const char __user *user_buf,
812 size_t count, loff_t *ppos)
813{
814 struct iwl_mvm *mvm = file->private_data;
815 char buf[8] = {};
816 int store;
817
818 if (copy_from_user(buf, user_buf, sizeof(buf)))
819 return -EFAULT;
820
821 if (sscanf(buf, "%d", &store) != 1)
822 return -EINVAL;
823
824 mvm->store_d3_resume_sram = store;
825
826 return count;
827}
828
829static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
830 size_t count, loff_t *ppos)
831{
832 struct iwl_mvm *mvm = file->private_data;
833 const struct fw_img *img;
834 int ofs, len, pos = 0;
835 size_t bufsz, ret;
836 char *buf;
837 u8 *ptr = mvm->d3_resume_sram;
838
839 img = &mvm->fw->img[IWL_UCODE_WOWLAN];
840 len = img->sec[IWL_UCODE_SECTION_DATA].len;
841
842 bufsz = len * 4 + 256;
843 buf = kzalloc(bufsz, GFP_KERNEL);
844 if (!buf)
845 return -ENOMEM;
846
847 pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
848 mvm->store_d3_resume_sram ? "en" : "dis");
849
850 if (ptr) {
851 for (ofs = 0; ofs < len; ofs += 16) {
852 pos += scnprintf(buf + pos, bufsz - pos,
853 "0x%.4x ", ofs);
854 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
855 bufsz - pos, false);
856 pos += strlen(buf + pos);
857 if (bufsz - pos > 0)
858 buf[pos++] = '\n';
859 }
860 } else {
861 pos += scnprintf(buf + pos, bufsz - pos,
862 "(no data captured)\n");
863 }
864
865 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
866
867 kfree(buf);
868
869 return ret;
870}
871#endif
872
484#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 873#define MVM_DEBUGFS_READ_FILE_OPS(name) \
485static const struct file_operations iwl_dbgfs_##name##_ops = { \ 874static const struct file_operations iwl_dbgfs_##name##_ops = { \
486 .read = iwl_dbgfs_##name##_read, \ 875 .read = iwl_dbgfs_##name##_read, \
@@ -524,9 +913,14 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
524MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 913MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 914MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 915MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
916#ifdef CONFIG_PM_SLEEP
917MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
918#endif
527 919
528/* Interface specific debugfs entries */ 920/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params); 921MVM_DEBUGFS_READ_FILE_OPS(mac_params);
922MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
923MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
530 924
531int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 925int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
532{ 926{
@@ -542,6 +936,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
542 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 936 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
543 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 937 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
544 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 938 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
939#ifdef CONFIG_PM_SLEEP
940 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
941#endif
545 942
546 /* 943 /*
547 * Create a symlink with mac80211. It will be removed when mac80211 944 * Create a symlink with mac80211. It will be removed when mac80211
@@ -577,9 +974,19 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
577 return; 974 return;
578 } 975 }
579 976
977 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
978 vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
979 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
980 S_IRUSR);
981
580 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, 982 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
581 S_IRUSR); 983 S_IRUSR);
582 984
985 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
986 mvmvif == mvm->bf_allowed_vif)
987 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
988 S_IRUSR | S_IWUSR);
989
583 /* 990 /*
584 * Create symlink for convenience pointing to interface specific 991 * Create symlink for convenience pointing to interface specific
585 * debugfs entries for the driver. For example, under 992 * debugfs entries for the driver. For example, under
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 51e015d1dfb2..6f8b2c16ae17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -75,13 +75,15 @@ enum iwl_d3_wakeup_flags {
75 * struct iwl_d3_manager_config - D3 manager configuration command 75 * struct iwl_d3_manager_config - D3 manager configuration command
76 * @min_sleep_time: minimum sleep time (in usec) 76 * @min_sleep_time: minimum sleep time (in usec)
77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags 77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
78 * @wakeup_host_timer: force wakeup after this many seconds
78 * 79 *
79 * The structure is used for the D3_CONFIG_CMD command. 80 * The structure is used for the D3_CONFIG_CMD command.
80 */ 81 */
81struct iwl_d3_manager_config { 82struct iwl_d3_manager_config {
82 __le32 min_sleep_time; 83 __le32 min_sleep_time;
83 __le32 wakeup_flags; 84 __le32 wakeup_flags;
84} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */ 85 __le32 wakeup_host_timer;
86} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_4 */
85 87
86 88
87/* TODO: OFFLOADS_QUERY_API_S_VER_1 */ 89/* TODO: OFFLOADS_QUERY_API_S_VER_1 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 81fe45f46be7..d8e19290b0f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -101,20 +101,107 @@ enum iwl_power_flags {
101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to 101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
102 * PSM transition - legacy PM 102 * PSM transition - legacy PM
103 * @sleep_interval: not in use 103 * @sleep_interval: not in use
104 * @keep_alive_beacons: not in use 104 * @skip_dtim_periods: Number of DTIM periods to skip if Skip over DTIM flag
105 * is set. For example, if it is required to skip over
106 * one DTIM, this value need to be set to 2 (DTIM periods).
105 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 107 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
106 * Default: 80dbm 108 * Default: 80dbm
107 */ 109 */
108struct iwl_powertable_cmd { 110struct iwl_powertable_cmd {
109 /* PM_POWER_TABLE_CMD_API_S_VER_5 */ 111 /* PM_POWER_TABLE_CMD_API_S_VER_6 */
110 __le16 flags; 112 __le16 flags;
111 u8 keep_alive_seconds; 113 u8 keep_alive_seconds;
112 u8 debug_flags; 114 u8 debug_flags;
113 __le32 rx_data_timeout; 115 __le32 rx_data_timeout;
114 __le32 tx_data_timeout; 116 __le32 tx_data_timeout;
115 __le32 sleep_interval[IWL_POWER_VEC_SIZE]; 117 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
116 __le32 keep_alive_beacons; 118 __le32 skip_dtim_periods;
117 __le32 lprx_rssi_threshold; 119 __le32 lprx_rssi_threshold;
118} __packed; 120} __packed;
119 121
122/**
123 * struct iwl_beacon_filter_cmd
124 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
125 * @id_and_color: MAC contex identifier
126 * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
127 * to driver if delta in Energy values calculated for this and last
128 * passed beacon is greater than this threshold. Zero value means that
129 * the Energy change is ignored for beacon filtering, and beacon will
130 * not be forced to be sent to driver regardless of this delta. Typical
131 * energy delta 5dB.
132 * @bf_roaming_energy_delta: Used for RSSI filtering, if in 'roaming' state.
133 * Send beacon to driver if delta in Energy values calculated for this
134 * and last passed beacon is greater than this threshold. Zero value
135 * means that the Energy change is ignored for beacon filtering while in
136 * Roaming state, typical energy delta 1dB.
137 * @bf_roaming_state: Used for RSSI filtering. If absolute Energy values
138 * calculated for current beacon is less than the threshold, use
139 * Roaming Energy Delta Threshold, otherwise use normal Energy Delta
140 * Threshold. Typical energy threshold is -72dBm.
141 * @bf_temperature_delta: Send Beacon to driver if delta in temperature values
142 * calculated for this and the last passed beacon is greater than this
143 * threshold. Zero value means that the temperature changeis ignored for
144 * beacon filtering; beacons will not be forced to be sent to driver
145 * regardless of whether its temerature has been changed.
146 * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.
147 * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed
148 * for a specific period of time. Units: Beacons.
149 * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed
150 * for a longer period of time then this escape-timeout. Units: Beacons.
151 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
152 */
153struct iwl_beacon_filter_cmd {
154 u8 bf_energy_delta;
155 u8 bf_roaming_energy_delta;
156 u8 bf_roaming_state;
157 u8 bf_temperature_delta;
158 u8 bf_enable_beacon_filter;
159 u8 bf_debug_flag;
160 __le16 reserved1;
161 __le32 bf_escape_timer;
162 __le32 ba_escape_timer;
163 u8 ba_enable_beacon_abort;
164 u8 reserved2[3];
165} __packed;
166
167/* Beacon filtering and beacon abort */
168#define IWL_BF_ENERGY_DELTA_DEFAULT 5
169#define IWL_BF_ENERGY_DELTA_MAX 255
170#define IWL_BF_ENERGY_DELTA_MIN 0
171
172#define IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT 1
173#define IWL_BF_ROAMING_ENERGY_DELTA_MAX 255
174#define IWL_BF_ROAMING_ENERGY_DELTA_MIN 0
175
176#define IWL_BF_ROAMING_STATE_DEFAULT 72
177#define IWL_BF_ROAMING_STATE_MAX 255
178#define IWL_BF_ROAMING_STATE_MIN 0
179
180#define IWL_BF_TEMPERATURE_DELTA_DEFAULT 5
181#define IWL_BF_TEMPERATURE_DELTA_MAX 255
182#define IWL_BF_TEMPERATURE_DELTA_MIN 0
183
184#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1
185
186#define IWL_BF_DEBUG_FLAG_DEFAULT 0
187
188#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
189#define IWL_BF_ESCAPE_TIMER_MAX 1024
190#define IWL_BF_ESCAPE_TIMER_MIN 0
191
192#define IWL_BA_ESCAPE_TIMER_DEFAULT 3
193#define IWL_BA_ESCAPE_TIMER_MAX 1024
194#define IWL_BA_ESCAPE_TIMER_MIN 0
195
196#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
197
198#define IWL_BF_CMD_CONFIG_DEFAULTS \
199 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \
200 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \
201 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \
202 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \
203 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \
204 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
205 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
206
120#endif 207#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 007a93b25bd7..6994232f5726 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -134,6 +134,7 @@ enum iwl_tx_flags {
134#define TX_CMD_SEC_WEP 0x01 134#define TX_CMD_SEC_WEP 0x01
135#define TX_CMD_SEC_CCM 0x02 135#define TX_CMD_SEC_CCM 0x02
136#define TX_CMD_SEC_TKIP 0x03 136#define TX_CMD_SEC_TKIP 0x03
137#define TX_CMD_SEC_MSK 0x07
137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6 138#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0 139#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
139#define TX_CMD_SEC_KEY128 0x08 140#define TX_CMD_SEC_KEY128 0x08
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 191dcae8ba47..cbfb3beae783 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -139,6 +139,9 @@ enum {
139 /* Power */ 139 /* Power */
140 POWER_TABLE_CMD = 0x77, 140 POWER_TABLE_CMD = 0x77,
141 141
142 /* Thermal Throttling*/
143 REPLY_THERMAL_MNG_BACKOFF = 0x7e,
144
142 /* Scanning */ 145 /* Scanning */
143 SCAN_REQUEST_CMD = 0x80, 146 SCAN_REQUEST_CMD = 0x80,
144 SCAN_ABORT_CMD = 0x81, 147 SCAN_ABORT_CMD = 0x81,
@@ -161,6 +164,8 @@ enum {
161 CARD_STATE_CMD = 0xa0, 164 CARD_STATE_CMD = 0xa0,
162 CARD_STATE_NOTIFICATION = 0xa1, 165 CARD_STATE_NOTIFICATION = 0xa1,
163 166
167 MISSED_BEACONS_NOTIFICATION = 0xa2,
168
164 REPLY_RX_PHY_CMD = 0xc0, 169 REPLY_RX_PHY_CMD = 0xc0,
165 REPLY_RX_MPDU_CMD = 0xc1, 170 REPLY_RX_MPDU_CMD = 0xc1,
166 BA_NOTIF = 0xc5, 171 BA_NOTIF = 0xc5,
@@ -170,9 +175,13 @@ enum {
170 BT_COEX_PROT_ENV = 0xcd, 175 BT_COEX_PROT_ENV = 0xcd,
171 BT_PROFILE_NOTIFICATION = 0xce, 176 BT_PROFILE_NOTIFICATION = 0xce,
172 177
178 REPLY_BEACON_FILTERING_CMD = 0xd2,
179
173 REPLY_DEBUG_CMD = 0xf0, 180 REPLY_DEBUG_CMD = 0xf0,
174 DEBUG_LOG_MSG = 0xf7, 181 DEBUG_LOG_MSG = 0xf7,
175 182
183 MCAST_FILTER_CMD = 0xd0,
184
176 /* D3 commands/notifications */ 185 /* D3 commands/notifications */
177 D3_CONFIG_CMD = 0xd3, 186 D3_CONFIG_CMD = 0xd3,
178 PROT_OFFLOAD_CONFIG_CMD = 0xd4, 187 PROT_OFFLOAD_CONFIG_CMD = 0xd4,
@@ -936,6 +945,24 @@ struct iwl_card_state_notif {
936} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ 945} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
937 946
938/** 947/**
948 * struct iwl_missed_beacons_notif - information on missed beacons
949 * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
950 * @mac_id: interface ID
951 * @consec_missed_beacons_since_last_rx: number of consecutive missed
952 * beacons since last RX.
953 * @consec_missed_beacons: number of consecutive missed beacons
954 * @num_expected_beacons:
955 * @num_recvd_beacons:
956 */
957struct iwl_missed_beacons_notif {
958 __le32 mac_id;
959 __le32 consec_missed_beacons_since_last_rx;
960 __le32 consec_missed_beacons;
961 __le32 num_expected_beacons;
962 __le32 num_recvd_beacons;
963} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
964
965/**
939 * struct iwl_set_calib_default_cmd - set default value for calibration. 966 * struct iwl_set_calib_default_cmd - set default value for calibration.
940 * ( SET_CALIB_DEFAULT_CMD = 0x8e ) 967 * ( SET_CALIB_DEFAULT_CMD = 0x8e )
941 * @calib_index: the calibration to set value for 968 * @calib_index: the calibration to set value for
@@ -948,4 +975,237 @@ struct iwl_set_calib_default_cmd {
948 u8 data[0]; 975 u8 data[0];
949} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ 976} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
950 977
978#define MAX_PORT_ID_NUM 2
979
980/**
981 * struct iwl_mcast_filter_cmd - configure multicast filter.
982 * @filter_own: Set 1 to filter out multicast packets sent by station itself
983 * @port_id: Multicast MAC addresses array specifier. This is a strange way
984 * to identify network interface adopted in host-device IF.
985 * It is used by FW as index in array of addresses. This array has
986 * MAX_PORT_ID_NUM members.
987 * @count: Number of MAC addresses in the array
988 * @pass_all: Set 1 to pass all multicast packets.
989 * @bssid: current association BSSID.
990 * @addr_list: Place holder for array of MAC addresses.
991 * IMPORTANT: add padding if necessary to ensure DWORD alignment.
992 */
993struct iwl_mcast_filter_cmd {
994 u8 filter_own;
995 u8 port_id;
996 u8 count;
997 u8 pass_all;
998 u8 bssid[6];
999 u8 reserved[2];
1000 u8 addr_list[0];
1001} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
1002
1003struct mvm_statistics_dbg {
1004 __le32 burst_check;
1005 __le32 burst_count;
1006 __le32 wait_for_silence_timeout_cnt;
1007 __le32 reserved[3];
1008} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
1009
1010struct mvm_statistics_div {
1011 __le32 tx_on_a;
1012 __le32 tx_on_b;
1013 __le32 exec_time;
1014 __le32 probe_time;
1015 __le32 rssi_ant;
1016 __le32 reserved2;
1017} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
1018
1019struct mvm_statistics_general_common {
1020 __le32 temperature; /* radio temperature */
1021 __le32 temperature_m; /* radio voltage */
1022 struct mvm_statistics_dbg dbg;
1023 __le32 sleep_time;
1024 __le32 slots_out;
1025 __le32 slots_idle;
1026 __le32 ttl_timestamp;
1027 struct mvm_statistics_div div;
1028 __le32 rx_enable_counter;
1029 /*
1030 * num_of_sos_states:
1031 * count the number of times we have to re-tune
1032 * in order to get out of bad PHY status
1033 */
1034 __le32 num_of_sos_states;
1035} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1036
1037struct mvm_statistics_rx_non_phy {
1038 __le32 bogus_cts; /* CTS received when not expecting CTS */
1039 __le32 bogus_ack; /* ACK received when not expecting ACK */
1040 __le32 non_bssid_frames; /* number of frames with BSSID that
1041 * doesn't belong to the STA BSSID */
1042 __le32 filtered_frames; /* count frames that were dumped in the
1043 * filtering process */
1044 __le32 non_channel_beacons; /* beacons with our bss id but not on
1045 * our serving channel */
1046 __le32 channel_beacons; /* beacons with our bss id and in our
1047 * serving channel */
1048 __le32 num_missed_bcon; /* number of missed beacons */
1049 __le32 adc_rx_saturation_time; /* count in 0.8us units the time the
1050 * ADC was in saturation */
1051 __le32 ina_detection_search_time;/* total time (in 0.8us) searched
1052 * for INA */
1053 __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */
1054 __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */
1055 __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */
1056 __le32 interference_data_flag; /* flag for interference data
1057 * availability. 1 when data is
1058 * available. */
1059 __le32 channel_load; /* counts RX Enable time in uSec */
1060 __le32 dsp_false_alarms; /* DSP false alarm (both OFDM
1061 * and CCK) counter */
1062 __le32 beacon_rssi_a;
1063 __le32 beacon_rssi_b;
1064 __le32 beacon_rssi_c;
1065 __le32 beacon_energy_a;
1066 __le32 beacon_energy_b;
1067 __le32 beacon_energy_c;
1068 __le32 num_bt_kills;
1069 __le32 mac_id;
1070 __le32 directed_data_mpdu;
1071} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
1072
1073struct mvm_statistics_rx_phy {
1074 __le32 ina_cnt;
1075 __le32 fina_cnt;
1076 __le32 plcp_err;
1077 __le32 crc32_err;
1078 __le32 overrun_err;
1079 __le32 early_overrun_err;
1080 __le32 crc32_good;
1081 __le32 false_alarm_cnt;
1082 __le32 fina_sync_err_cnt;
1083 __le32 sfd_timeout;
1084 __le32 fina_timeout;
1085 __le32 unresponded_rts;
1086 __le32 rxe_frame_limit_overrun;
1087 __le32 sent_ack_cnt;
1088 __le32 sent_cts_cnt;
1089 __le32 sent_ba_rsp_cnt;
1090 __le32 dsp_self_kill;
1091 __le32 mh_format_err;
1092 __le32 re_acq_main_rssi_sum;
1093 __le32 reserved;
1094} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
1095
1096struct mvm_statistics_rx_ht_phy {
1097 __le32 plcp_err;
1098 __le32 overrun_err;
1099 __le32 early_overrun_err;
1100 __le32 crc32_good;
1101 __le32 crc32_err;
1102 __le32 mh_format_err;
1103 __le32 agg_crc32_good;
1104 __le32 agg_mpdu_cnt;
1105 __le32 agg_cnt;
1106 __le32 unsupport_mcs;
1107} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
1108
1109#define MAX_CHAINS 3
1110
1111struct mvm_statistics_tx_non_phy_agg {
1112 __le32 ba_timeout;
1113 __le32 ba_reschedule_frames;
1114 __le32 scd_query_agg_frame_cnt;
1115 __le32 scd_query_no_agg;
1116 __le32 scd_query_agg;
1117 __le32 scd_query_mismatch;
1118 __le32 frame_not_ready;
1119 __le32 underrun;
1120 __le32 bt_prio_kill;
1121 __le32 rx_ba_rsp_cnt;
1122 __s8 txpower[MAX_CHAINS];
1123 __s8 reserved;
1124 __le32 reserved2;
1125} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
1126
1127struct mvm_statistics_tx_channel_width {
1128 __le32 ext_cca_narrow_ch20[1];
1129 __le32 ext_cca_narrow_ch40[2];
1130 __le32 ext_cca_narrow_ch80[3];
1131 __le32 ext_cca_narrow_ch160[4];
1132 __le32 last_tx_ch_width_indx;
1133 __le32 rx_detected_per_ch_width[4];
1134 __le32 success_per_ch_width[4];
1135 __le32 fail_per_ch_width[4];
1136}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
1137
1138struct mvm_statistics_tx {
1139 __le32 preamble_cnt;
1140 __le32 rx_detected_cnt;
1141 __le32 bt_prio_defer_cnt;
1142 __le32 bt_prio_kill_cnt;
1143 __le32 few_bytes_cnt;
1144 __le32 cts_timeout;
1145 __le32 ack_timeout;
1146 __le32 expected_ack_cnt;
1147 __le32 actual_ack_cnt;
1148 __le32 dump_msdu_cnt;
1149 __le32 burst_abort_next_frame_mismatch_cnt;
1150 __le32 burst_abort_missing_next_frame_cnt;
1151 __le32 cts_timeout_collision;
1152 __le32 ack_or_ba_timeout_collision;
1153 struct mvm_statistics_tx_non_phy_agg agg;
1154 struct mvm_statistics_tx_channel_width channel_width;
1155} __packed; /* STATISTICS_TX_API_S_VER_4 */
1156
1157
1158struct mvm_statistics_bt_activity {
1159 __le32 hi_priority_tx_req_cnt;
1160 __le32 hi_priority_tx_denied_cnt;
1161 __le32 lo_priority_tx_req_cnt;
1162 __le32 lo_priority_tx_denied_cnt;
1163 __le32 hi_priority_rx_req_cnt;
1164 __le32 hi_priority_rx_denied_cnt;
1165 __le32 lo_priority_rx_req_cnt;
1166 __le32 lo_priority_rx_denied_cnt;
1167} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
1168
1169struct mvm_statistics_general {
1170 struct mvm_statistics_general_common common;
1171 __le32 beacon_filtered;
1172 __le32 missed_beacons;
1173 __s8 beacon_filter_everage_energy;
1174 __s8 beacon_filter_reason;
1175 __s8 beacon_filter_current_energy;
1176 __s8 beacon_filter_reserved;
1177 __le32 beacon_filter_delta_time;
1178 struct mvm_statistics_bt_activity bt_activity;
1179} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1180
1181struct mvm_statistics_rx {
1182 struct mvm_statistics_rx_phy ofdm;
1183 struct mvm_statistics_rx_phy cck;
1184 struct mvm_statistics_rx_non_phy general;
1185 struct mvm_statistics_rx_ht_phy ofdm_ht;
1186} __packed; /* STATISTICS_RX_API_S_VER_3 */
1187
1188/*
1189 * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
1190 *
1191 * By default, uCode issues this notification after receiving a beacon
1192 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
1193 * REPLY_STATISTICS_CMD 0x9c, above.
1194 *
1195 * Statistics counters continue to increment beacon after beacon, but are
1196 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
1197 * 0x9c with CLEAR_STATS bit set (see above).
1198 *
1199 * uCode also issues this notification during scans. uCode clears statistics
1200 * appropriately so that each notification contains statistics for only the
1201 * one channel that has just been scanned.
1202 */
1203
1204struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1205 __le32 flag;
1206 struct mvm_statistics_rx rx;
1207 struct mvm_statistics_tx tx;
1208 struct mvm_statistics_general general;
1209} __packed;
1210
951#endif /* __fw_api_h__ */ 1211#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index e18c92dd60ec..cd7c0032cc58 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -326,6 +326,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
327 WARN_ON(ret); 327 WARN_ON(ret);
328 328
329 /*
330 * abort after reading the nvm in case RF Kill is on, we will complete
331 * the init seq later when RF kill will switch to off
332 */
333 if (iwl_mvm_is_radio_killed(mvm)) {
334 IWL_DEBUG_RF_KILL(mvm,
335 "jump over all phy activities due to RF kill\n");
336 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
337 return 1;
338 }
339
329 /* Send TX valid antennas before triggering calibrations */ 340 /* Send TX valid antennas before triggering calibrations */
330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 341 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
331 if (ret) 342 if (ret)
@@ -388,6 +399,8 @@ out:
388int iwl_mvm_up(struct iwl_mvm *mvm) 399int iwl_mvm_up(struct iwl_mvm *mvm)
389{ 400{
390 int ret, i; 401 int ret, i;
402 struct ieee80211_channel *chan;
403 struct cfg80211_chan_def chandef;
391 404
392 lockdep_assert_held(&mvm->mutex); 405 lockdep_assert_held(&mvm->mutex);
393 406
@@ -400,8 +413,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
400 ret = iwl_run_init_mvm_ucode(mvm, false); 413 ret = iwl_run_init_mvm_ucode(mvm, false);
401 if (ret && !iwlmvm_mod_params.init_dbg) { 414 if (ret && !iwlmvm_mod_params.init_dbg) {
402 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); 415 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
416 /* this can't happen */
417 if (WARN_ON(ret > 0))
418 ret = -ERFKILL;
403 goto error; 419 goto error;
404 } 420 }
421 /* should stop & start HW since that INIT image just loaded */
422 iwl_trans_stop_hw(mvm->trans, false);
423 ret = iwl_trans_start_hw(mvm->trans);
424 if (ret)
425 return ret;
405 } 426 }
406 427
407 if (iwlmvm_mod_params.init_dbg) 428 if (iwlmvm_mod_params.init_dbg)
@@ -443,8 +464,22 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
443 if (ret) 464 if (ret)
444 goto error; 465 goto error;
445 466
446 IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); 467 /* Add all the PHY contexts */
468 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
469 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
470 for (i = 0; i < NUM_PHY_CTX; i++) {
471 /*
472 * The channel used here isn't relevant as it's
473 * going to be overwritten in the other flows.
474 * For now use the first channel we have.
475 */
476 ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
477 &chandef, 1, 1);
478 if (ret)
479 goto error;
480 }
447 481
482 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
448 return 0; 483 return 0;
449 error: 484 error:
450 iwl_trans_stop_device(mvm->trans); 485 iwl_trans_stop_device(mvm->trans);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index e6eca4d66f6c..b4e8e597d2b7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -227,7 +227,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
227 .found_vif = false, 227 .found_vif = false,
228 }; 228 };
229 u32 ac; 229 u32 ac;
230 int ret; 230 int ret, i;
231 231
232 /* 232 /*
233 * Allocate a MAC ID and a TSF for this MAC, along with the queues 233 * Allocate a MAC ID and a TSF for this MAC, along with the queues
@@ -335,6 +335,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT; 335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
337 337
338 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++)
339 mvmvif->smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
340
338 return 0; 341 return 0;
339 342
340exit_fail: 343exit_fail:
@@ -586,10 +589,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
586 */ 589 */
587static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm, 590static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
588 struct ieee80211_vif *vif, 591 struct ieee80211_vif *vif,
589 struct iwl_mac_data_sta *ctxt_sta) 592 struct iwl_mac_data_sta *ctxt_sta,
593 bool force_assoc_off)
590{ 594{
591 /* We need the dtim_period to set the MAC as associated */ 595 /* We need the dtim_period to set the MAC as associated */
592 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) { 596 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
597 !force_assoc_off) {
593 u32 dtim_offs; 598 u32 dtim_offs;
594 599
595 /* 600 /*
@@ -659,7 +664,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
659 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); 664 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
660 665
661 /* Fill the data specific for station mode */ 666 /* Fill the data specific for station mode */
662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 667 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta,
668 action == FW_CTXT_ACTION_ADD);
663 669
664 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 670 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
665} 671}
@@ -677,7 +683,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
677 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 683 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
678 684
679 /* Fill the data specific for station mode */ 685 /* Fill the data specific for station mode */
680 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); 686 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta,
687 action == FW_CTXT_ACTION_ADD);
681 688
682 cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & 689 cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
683 IEEE80211_P2P_OPPPS_CTWINDOW_MASK); 690 IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
@@ -1043,3 +1050,28 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1043 rate); 1050 rate);
1044 return 0; 1051 return 0;
1045} 1052}
1053
1054static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1055 struct ieee80211_vif *vif)
1056{
1057 u16 *id = _data;
1058 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1059
1060 if (mvmvif->id == *id)
1061 ieee80211_beacon_loss(vif);
1062}
1063
1064int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1065 struct iwl_rx_cmd_buffer *rxb,
1066 struct iwl_device_cmd *cmd)
1067{
1068 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1069 struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data;
1070 u16 id = (u16)le32_to_cpu(missed_beacons->mac_id);
1071
1072 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1073 IEEE80211_IFACE_ITER_NORMAL,
1074 iwl_mvm_beacon_loss_iterator,
1075 &id);
1076 return 0;
1077}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 827fa641490f..b807ddac650c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -127,6 +127,17 @@ static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
127}; 127};
128#endif 128#endif
129 129
130static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
131{
132 int i;
133
134 memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
135 for (i = 0; i < NUM_PHY_CTX; i++) {
136 mvm->phy_ctxts[i].id = i;
137 mvm->phy_ctxts[i].ref = 0;
138 }
139}
140
130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 141int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
131{ 142{
132 struct ieee80211_hw *hw = mvm->hw; 143 struct ieee80211_hw *hw = mvm->hw;
@@ -141,7 +152,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
141 IEEE80211_HW_SUPPORTS_PS | 152 IEEE80211_HW_SUPPORTS_PS |
142 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
143 IEEE80211_HW_AMPDU_AGGREGATION | 154 IEEE80211_HW_AMPDU_AGGREGATION |
144 IEEE80211_HW_TIMING_BEACON_ONLY; 155 IEEE80211_HW_TIMING_BEACON_ONLY |
156 IEEE80211_HW_CONNECTION_MONITOR;
145 157
146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 158 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 159 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -158,7 +170,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
158 170
159 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 171 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
160 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 172 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
161 hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt); 173 hw->chanctx_data_size = sizeof(u16);
162 174
163 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 175 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
164 BIT(NL80211_IFTYPE_P2P_CLIENT) | 176 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -193,6 +205,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
193 hw->wiphy->n_addresses++; 205 hw->wiphy->n_addresses++;
194 } 206 }
195 207
208 iwl_mvm_reset_phy_ctxts(mvm);
209
196 /* we create the 802.11 header and a max-length SSID element */ 210 /* we create the 802.11 header and a max-length SSID element */
197 hw->wiphy->max_scan_ie_len = 211 hw->wiphy->max_scan_ie_len =
198 mvm->fw->ucode_capa.max_probe_length - 24 - 34; 212 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
@@ -252,8 +266,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
252{ 266{
253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 267 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
254 268
255 if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) { 269 if (iwl_mvm_is_radio_killed(mvm)) {
256 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n"); 270 IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
257 goto drop; 271 goto drop;
258 } 272 }
259 273
@@ -345,8 +359,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
345 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 359 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
346 spin_unlock_bh(&mvm->time_event_lock); 360 spin_unlock_bh(&mvm->time_event_lock);
347 361
348 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 362 mvmvif->phy_ctxt = NULL;
349 mvmvif->phy_ctxt = NULL;
350} 363}
351 364
352static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 365static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
@@ -363,6 +376,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
363 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 376 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
364 iwl_mvm_cleanup_iterator, mvm); 377 iwl_mvm_cleanup_iterator, mvm);
365 378
379 mvm->p2p_device_vif = NULL;
380
381 iwl_mvm_reset_phy_ctxts(mvm);
366 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 382 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
367 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained)); 383 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
368 384
@@ -456,6 +472,20 @@ static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
456 iwl_mvm_power_update_mode(mvm, vif); 472 iwl_mvm_power_update_mode(mvm, vif);
457} 473}
458 474
475static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
476{
477 u16 i;
478
479 lockdep_assert_held(&mvm->mutex);
480
481 for (i = 0; i < NUM_PHY_CTX; i++)
482 if (!mvm->phy_ctxts[i].ref)
483 return &mvm->phy_ctxts[i];
484
485 IWL_ERR(mvm, "No available PHY context\n");
486 return NULL;
487}
488
459static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 489static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
460 struct ieee80211_vif *vif) 490 struct ieee80211_vif *vif)
461{ 491{
@@ -530,32 +560,34 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
530 */ 560 */
531 iwl_mvm_power_update_mode(mvm, vif); 561 iwl_mvm_power_update_mode(mvm, vif);
532 562
563 /* beacon filtering */
564 if (!mvm->bf_allowed_vif &&
565 vif->type == NL80211_IFTYPE_STATION && !vif->p2p){
566 mvm->bf_allowed_vif = mvmvif;
567 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
568 }
569
570 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
571 if (ret)
572 goto out_release;
573
533 /* 574 /*
534 * P2P_DEVICE interface does not have a channel context assigned to it, 575 * P2P_DEVICE interface does not have a channel context assigned to it,
535 * so a dedicated PHY context is allocated to it and the corresponding 576 * so a dedicated PHY context is allocated to it and the corresponding
536 * MAC context is bound to it at this stage. 577 * MAC context is bound to it at this stage.
537 */ 578 */
538 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 579 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
539 struct ieee80211_channel *chan;
540 struct cfg80211_chan_def chandef;
541
542 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
543 580
544 /* 581 mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
545 * The channel used here isn't relevant as it's 582 if (!mvmvif->phy_ctxt) {
546 * going to be overwritten as part of the ROC flow. 583 ret = -ENOSPC;
547 * For now use the first channel we have.
548 */
549 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
550 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
551 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
552 &chandef, 1, 1);
553 if (ret)
554 goto out_remove_mac; 584 goto out_remove_mac;
585 }
555 586
587 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
556 ret = iwl_mvm_binding_add_vif(mvm, vif); 588 ret = iwl_mvm_binding_add_vif(mvm, vif);
557 if (ret) 589 if (ret)
558 goto out_remove_phy; 590 goto out_unref_phy;
559 591
560 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); 592 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
561 if (ret) 593 if (ret)
@@ -571,8 +603,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
571 603
572 out_unbind: 604 out_unbind:
573 iwl_mvm_binding_remove_vif(mvm, vif); 605 iwl_mvm_binding_remove_vif(mvm, vif);
574 out_remove_phy: 606 out_unref_phy:
575 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 607 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
576 out_remove_mac: 608 out_remove_mac:
577 mvmvif->phy_ctxt = NULL; 609 mvmvif->phy_ctxt = NULL;
578 iwl_mvm_mac_ctxt_remove(mvm, vif); 610 iwl_mvm_mac_ctxt_remove(mvm, vif);
@@ -646,6 +678,11 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
646 678
647 mutex_lock(&mvm->mutex); 679 mutex_lock(&mvm->mutex);
648 680
681 if (mvm->bf_allowed_vif == mvmvif) {
682 mvm->bf_allowed_vif = NULL;
683 vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
684 }
685
649 iwl_mvm_vif_dbgfs_clean(mvm, vif); 686 iwl_mvm_vif_dbgfs_clean(mvm, vif);
650 687
651 /* 688 /*
@@ -661,7 +698,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
661 mvm->p2p_device_vif = NULL; 698 mvm->p2p_device_vif = NULL;
662 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 699 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
663 iwl_mvm_binding_remove_vif(mvm, vif); 700 iwl_mvm_binding_remove_vif(mvm, vif);
664 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 701 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
665 mvmvif->phy_ctxt = NULL; 702 mvmvif->phy_ctxt = NULL;
666 } 703 }
667 704
@@ -701,6 +738,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
701 *total_flags = 0; 738 *total_flags = 0;
702} 739}
703 740
741static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
742 struct ieee80211_vif *vif)
743{
744 struct iwl_mcast_filter_cmd mcast_filter_cmd = {
745 .pass_all = 1,
746 };
747
748 memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
749
750 return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
751 sizeof(mcast_filter_cmd),
752 &mcast_filter_cmd);
753}
754
704static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 755static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
705 struct ieee80211_vif *vif, 756 struct ieee80211_vif *vif,
706 struct ieee80211_bss_conf *bss_conf, 757 struct ieee80211_bss_conf *bss_conf,
@@ -722,6 +773,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
722 return; 773 return;
723 } 774 }
724 iwl_mvm_bt_coex_vif_assoc(mvm, vif); 775 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
776 iwl_mvm_configure_mcast_filter(mvm, vif);
725 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 777 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
726 /* remove AP station now that the MAC is unassoc */ 778 /* remove AP station now that the MAC is unassoc */
727 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 779 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -931,7 +983,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
931 983
932 switch (cmd) { 984 switch (cmd) {
933 case STA_NOTIFY_SLEEP: 985 case STA_NOTIFY_SLEEP:
934 if (atomic_read(&mvmsta->pending_frames) > 0) 986 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
935 ieee80211_sta_block_awake(hw, sta, true); 987 ieee80211_sta_block_awake(hw, sta, true);
936 /* 988 /*
937 * The fw updates the STA to be asleep. Tx packets on the Tx 989 * The fw updates the STA to be asleep. Tx packets on the Tx
@@ -984,9 +1036,13 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
984 mvmvif->phy_ctxt->channel->band); 1036 mvmvif->phy_ctxt->channel->band);
985 } else if (old_state == IEEE80211_STA_ASSOC && 1037 } else if (old_state == IEEE80211_STA_ASSOC &&
986 new_state == IEEE80211_STA_AUTHORIZED) { 1038 new_state == IEEE80211_STA_AUTHORIZED) {
1039 /* enable beacon filtering */
1040 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
987 ret = 0; 1041 ret = 0;
988 } else if (old_state == IEEE80211_STA_AUTHORIZED && 1042 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
989 new_state == IEEE80211_STA_ASSOC) { 1043 new_state == IEEE80211_STA_ASSOC) {
1044 /* disable beacon filtering */
1045 WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
990 ret = 0; 1046 ret = 0;
991 } else if (old_state == IEEE80211_STA_ASSOC && 1047 } else if (old_state == IEEE80211_STA_ASSOC &&
992 new_state == IEEE80211_STA_AUTH) { 1048 new_state == IEEE80211_STA_AUTH) {
@@ -1152,29 +1208,107 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1152 enum ieee80211_roc_type type) 1208 enum ieee80211_roc_type type)
1153{ 1209{
1154 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1210 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1211 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1155 struct cfg80211_chan_def chandef; 1212 struct cfg80211_chan_def chandef;
1156 int ret; 1213 struct iwl_mvm_phy_ctxt *phy_ctxt;
1214 int ret, i;
1215
1216 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1217 duration, type);
1157 1218
1158 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { 1219 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1159 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type); 1220 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1160 return -EINVAL; 1221 return -EINVAL;
1161 } 1222 }
1162 1223
1163 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1164 duration, type);
1165
1166 mutex_lock(&mvm->mutex); 1224 mutex_lock(&mvm->mutex);
1167 1225
1226 for (i = 0; i < NUM_PHY_CTX; i++) {
1227 phy_ctxt = &mvm->phy_ctxts[i];
1228 if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
1229 continue;
1230
1231 if (phy_ctxt->ref && channel == phy_ctxt->channel) {
1232 /*
1233 * Unbind the P2P_DEVICE from the current PHY context,
1234 * and if the PHY context is not used remove it.
1235 */
1236 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1237 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1238 goto out_unlock;
1239
1240 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1241
1242 /* Bind the P2P_DEVICE to the current PHY Context */
1243 mvmvif->phy_ctxt = phy_ctxt;
1244
1245 ret = iwl_mvm_binding_add_vif(mvm, vif);
1246 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1247 goto out_unlock;
1248
1249 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1250 goto schedule_time_event;
1251 }
1252 }
1253
1254 /* Need to update the PHY context only if the ROC channel changed */
1255 if (channel == mvmvif->phy_ctxt->channel)
1256 goto schedule_time_event;
1257
1168 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); 1258 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1169 ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1170 &chandef, 1, 1);
1171 1259
1260 /*
1261 * Change the PHY context configuration as it is currently referenced
1262 * only by the P2P Device MAC
1263 */
1264 if (mvmvif->phy_ctxt->ref == 1) {
1265 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
1266 &chandef, 1, 1);
1267 if (ret)
1268 goto out_unlock;
1269 } else {
1270 /*
1271 * The PHY context is shared with other MACs. Need to remove the
1272 * P2P Device from the binding, allocate an new PHY context and
1273 * create a new binding
1274 */
1275 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1276 if (!phy_ctxt) {
1277 ret = -ENOSPC;
1278 goto out_unlock;
1279 }
1280
1281 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
1282 1, 1);
1283 if (ret) {
1284 IWL_ERR(mvm, "Failed to change PHY context\n");
1285 goto out_unlock;
1286 }
1287
1288 /* Unbind the P2P_DEVICE from the current PHY context */
1289 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1290 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1291 goto out_unlock;
1292
1293 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1294
1295 /* Bind the P2P_DEVICE to the new allocated PHY context */
1296 mvmvif->phy_ctxt = phy_ctxt;
1297
1298 ret = iwl_mvm_binding_add_vif(mvm, vif);
1299 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1300 goto out_unlock;
1301
1302 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1303 }
1304
1305schedule_time_event:
1172 /* Schedule the time events */ 1306 /* Schedule the time events */
1173 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); 1307 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1174 1308
1309out_unlock:
1175 mutex_unlock(&mvm->mutex); 1310 mutex_unlock(&mvm->mutex);
1176 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1311 IWL_DEBUG_MAC80211(mvm, "leave\n");
1177
1178 return ret; 1312 return ret;
1179} 1313}
1180 1314
@@ -1196,15 +1330,30 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1196 struct ieee80211_chanctx_conf *ctx) 1330 struct ieee80211_chanctx_conf *ctx)
1197{ 1331{
1198 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1332 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1199 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1333 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1334 struct iwl_mvm_phy_ctxt *phy_ctxt;
1200 int ret; 1335 int ret;
1201 1336
1337 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
1338
1202 mutex_lock(&mvm->mutex); 1339 mutex_lock(&mvm->mutex);
1340 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1341 if (!phy_ctxt) {
1342 ret = -ENOSPC;
1343 goto out;
1344 }
1345
1346 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1347 ctx->rx_chains_static,
1348 ctx->rx_chains_dynamic);
1349 if (ret) {
1350 IWL_ERR(mvm, "Failed to add PHY context\n");
1351 goto out;
1352 }
1203 1353
1204 IWL_DEBUG_MAC80211(mvm, "Add PHY context\n"); 1354 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
1205 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def, 1355 *phy_ctxt_id = phy_ctxt->id;
1206 ctx->rx_chains_static, 1356out:
1207 ctx->rx_chains_dynamic);
1208 mutex_unlock(&mvm->mutex); 1357 mutex_unlock(&mvm->mutex);
1209 return ret; 1358 return ret;
1210} 1359}
@@ -1213,10 +1362,11 @@ static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1213 struct ieee80211_chanctx_conf *ctx) 1362 struct ieee80211_chanctx_conf *ctx)
1214{ 1363{
1215 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1364 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1216 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1365 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1366 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1217 1367
1218 mutex_lock(&mvm->mutex); 1368 mutex_lock(&mvm->mutex);
1219 iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt); 1369 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
1220 mutex_unlock(&mvm->mutex); 1370 mutex_unlock(&mvm->mutex);
1221} 1371}
1222 1372
@@ -1225,7 +1375,16 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1225 u32 changed) 1375 u32 changed)
1226{ 1376{
1227 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1377 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1228 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1378 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1379 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1380
1381 if (WARN_ONCE((phy_ctxt->ref > 1) &&
1382 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1383 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1384 IEEE80211_CHANCTX_CHANGE_RADAR)),
1385 "Cannot change PHY. Ref=%d, changed=0x%X\n",
1386 phy_ctxt->ref, changed))
1387 return;
1229 1388
1230 mutex_lock(&mvm->mutex); 1389 mutex_lock(&mvm->mutex);
1231 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1390 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
@@ -1239,13 +1398,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1239 struct ieee80211_chanctx_conf *ctx) 1398 struct ieee80211_chanctx_conf *ctx)
1240{ 1399{
1241 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1400 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1242 struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv; 1401 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1402 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1243 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1403 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1244 int ret; 1404 int ret;
1245 1405
1246 mutex_lock(&mvm->mutex); 1406 mutex_lock(&mvm->mutex);
1247 1407
1248 mvmvif->phy_ctxt = phyctx; 1408 mvmvif->phy_ctxt = phy_ctxt;
1249 1409
1250 switch (vif->type) { 1410 switch (vif->type) {
1251 case NL80211_IFTYPE_AP: 1411 case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index b62a948658ac..109200bdf5c5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -109,6 +109,7 @@ extern struct iwl_mvm_mod_params iwlmvm_mod_params;
109struct iwl_mvm_phy_ctxt { 109struct iwl_mvm_phy_ctxt {
110 u16 id; 110 u16 id;
111 u16 color; 111 u16 color;
112 u32 ref;
112 113
113 /* 114 /*
114 * TODO: This should probably be removed. Currently here only for rate 115 * TODO: This should probably be removed. Currently here only for rate
@@ -149,6 +150,60 @@ enum iwl_power_scheme {
149 150
150#define IWL_CONN_MAX_LISTEN_INTERVAL 70 151#define IWL_CONN_MAX_LISTEN_INTERVAL 70
151 152
153#ifdef CONFIG_IWLWIFI_DEBUGFS
154enum iwl_dbgfs_pm_mask {
155 MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
156 MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1),
157 MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
161};
162
163struct iwl_dbgfs_pm {
164 u8 keep_alive_seconds;
165 u32 rx_data_timeout;
166 u32 tx_data_timeout;
167 bool skip_over_dtim;
168 u8 skip_dtim_periods;
169 bool disable_power_off;
170 int mask;
171};
172
173/* beacon filtering */
174
175enum iwl_dbgfs_bf_mask {
176 MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
177 MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
178 MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
179 MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3),
180 MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4),
181 MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5),
182 MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6),
183 MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7),
184 MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8),
185};
186
187struct iwl_dbgfs_bf {
188 u8 bf_energy_delta;
189 u8 bf_roaming_energy_delta;
190 u8 bf_roaming_state;
191 u8 bf_temperature_delta;
192 u8 bf_enable_beacon_filter;
193 u8 bf_debug_flag;
194 u32 bf_escape_timer;
195 u32 ba_escape_timer;
196 u8 ba_enable_beacon_abort;
197 int mask;
198};
199#endif
200
201enum iwl_mvm_smps_type_request {
202 IWL_MVM_SMPS_REQ_BT_COEX,
203 IWL_MVM_SMPS_REQ_TT,
204 NUM_IWL_MVM_SMPS_REQ,
205};
206
152/** 207/**
153 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context 208 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
154 * @id: between 0 and 3 209 * @id: between 0 and 3
@@ -163,6 +218,8 @@ enum iwl_power_scheme {
163 * @bcast_sta: station used for broadcast packets. Used by the following 218 * @bcast_sta: station used for broadcast packets. Used by the following
164 * vifs: P2P_DEVICE, GO and AP. 219 * vifs: P2P_DEVICE, GO and AP.
165 * @beacon_skb: the skb used to hold the AP/GO beacon template 220 * @beacon_skb: the skb used to hold the AP/GO beacon template
221 * @smps_requests: the requests of of differents parts of the driver, regard
222 the desired smps mode.
166 */ 223 */
167struct iwl_mvm_vif { 224struct iwl_mvm_vif {
168 u16 id; 225 u16 id;
@@ -172,6 +229,8 @@ struct iwl_mvm_vif {
172 bool uploaded; 229 bool uploaded;
173 bool ap_active; 230 bool ap_active;
174 bool monitor_active; 231 bool monitor_active;
232 /* indicate whether beacon filtering is enabled */
233 bool bf_enabled;
175 234
176 u32 ap_beacon_time; 235 u32 ap_beacon_time;
177 236
@@ -214,7 +273,11 @@ struct iwl_mvm_vif {
214 struct dentry *dbgfs_dir; 273 struct dentry *dbgfs_dir;
215 struct dentry *dbgfs_slink; 274 struct dentry *dbgfs_slink;
216 void *dbgfs_data; 275 void *dbgfs_data;
276 struct iwl_dbgfs_pm dbgfs_pm;
277 struct iwl_dbgfs_bf dbgfs_bf;
217#endif 278#endif
279
280 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
218}; 281};
219 282
220static inline struct iwl_mvm_vif * 283static inline struct iwl_mvm_vif *
@@ -223,12 +286,6 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
223 return (void *)vif->drv_priv; 286 return (void *)vif->drv_priv;
224} 287}
225 288
226enum iwl_mvm_status {
227 IWL_MVM_STATUS_HW_RFKILL,
228 IWL_MVM_STATUS_ROC_RUNNING,
229 IWL_MVM_STATUS_IN_HW_RESTART,
230};
231
232enum iwl_scan_status { 289enum iwl_scan_status {
233 IWL_MVM_SCAN_NONE, 290 IWL_MVM_SCAN_NONE,
234 IWL_MVM_SCAN_OS, 291 IWL_MVM_SCAN_OS,
@@ -246,6 +303,63 @@ struct iwl_nvm_section {
246 const u8 *data; 303 const u8 *data;
247}; 304};
248 305
306/*
307 * Tx-backoff threshold
308 * @temperature: The threshold in Celsius
309 * @backoff: The tx-backoff in uSec
310 */
311struct iwl_tt_tx_backoff {
312 s32 temperature;
313 u32 backoff;
314};
315
316#define TT_TX_BACKOFF_SIZE 6
317
318/**
319 * struct iwl_tt_params - thermal throttling parameters
320 * @ct_kill_entry: CT Kill entry threshold
321 * @ct_kill_exit: CT Kill exit threshold
322 * @ct_kill_duration: The time intervals (in uSec) in which the driver needs
323 * to checks whether to exit CT Kill.
324 * @dynamic_smps_entry: Dynamic SMPS entry threshold
325 * @dynamic_smps_exit: Dynamic SMPS exit threshold
326 * @tx_protection_entry: TX protection entry threshold
327 * @tx_protection_exit: TX protection exit threshold
328 * @tx_backoff: Array of thresholds for tx-backoff , in ascending order.
329 * @support_ct_kill: Support CT Kill?
330 * @support_dynamic_smps: Support dynamic SMPS?
331 * @support_tx_protection: Support tx protection?
332 * @support_tx_backoff: Support tx-backoff?
333 */
334struct iwl_tt_params {
335 s32 ct_kill_entry;
336 s32 ct_kill_exit;
337 u32 ct_kill_duration;
338 s32 dynamic_smps_entry;
339 s32 dynamic_smps_exit;
340 s32 tx_protection_entry;
341 s32 tx_protection_exit;
342 struct iwl_tt_tx_backoff tx_backoff[TT_TX_BACKOFF_SIZE];
343 bool support_ct_kill;
344 bool support_dynamic_smps;
345 bool support_tx_protection;
346 bool support_tx_backoff;
347};
348
349/**
350 * struct iwl_mvm_tt_mgnt - Thermal Throttling Management structure
351 * @ct_kill_exit: worker to exit thermal kill
352 * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
353 * @tx_backoff: The current thremal throttling tx backoff in uSec.
354 * @params: Parameters to configure the thermal throttling algorithm.
355 */
356struct iwl_mvm_tt_mgmt {
357 struct delayed_work ct_kill_exit;
358 bool dynamic_smps;
359 u32 tx_backoff;
360 const struct iwl_tt_params *params;
361};
362
249struct iwl_mvm { 363struct iwl_mvm {
250 /* for logger access */ 364 /* for logger access */
251 struct device *dev; 365 struct device *dev;
@@ -266,6 +380,12 @@ struct iwl_mvm {
266 380
267 unsigned long status; 381 unsigned long status;
268 382
383 /*
384 * for beacon filtering -
385 * currently only one interface can be supported
386 */
387 struct iwl_mvm_vif *bf_allowed_vif;
388
269 enum iwl_ucode_type cur_ucode; 389 enum iwl_ucode_type cur_ucode;
270 bool ucode_loaded; 390 bool ucode_loaded;
271 bool init_ucode_run; 391 bool init_ucode_run;
@@ -292,6 +412,7 @@ struct iwl_mvm {
292 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; 412 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
293 struct work_struct sta_drained_wk; 413 struct work_struct sta_drained_wk;
294 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; 414 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
415 atomic_t pending_frames[IWL_MVM_STATION_COUNT];
295 416
296 /* configured by mac80211 */ 417 /* configured by mac80211 */
297 u32 rts_threshold; 418 u32 rts_threshold;
@@ -312,7 +433,7 @@ struct iwl_mvm {
312 bool prevent_power_down_d3; 433 bool prevent_power_down_d3;
313#endif 434#endif
314 435
315 struct iwl_mvm_phy_ctxt phy_ctxt_roc; 436 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
316 437
317 struct list_head time_event_list; 438 struct list_head time_event_list;
318 spinlock_t time_event_lock; 439 spinlock_t time_event_lock;
@@ -338,11 +459,19 @@ struct iwl_mvm {
338#ifdef CONFIG_PM_SLEEP 459#ifdef CONFIG_PM_SLEEP
339 struct wiphy_wowlan_support wowlan; 460 struct wiphy_wowlan_support wowlan;
340 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 461 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
462#ifdef CONFIG_IWLWIFI_DEBUGFS
463 bool store_d3_resume_sram;
464 void *d3_resume_sram;
465#endif
341#endif 466#endif
342 467
343 /* BT-Coex */ 468 /* BT-Coex */
344 u8 bt_kill_msk; 469 u8 bt_kill_msk;
345 struct iwl_bt_coex_profile_notif last_bt_notif; 470 struct iwl_bt_coex_profile_notif last_bt_notif;
471
472 /* Thermal Throttling and CTkill */
473 struct iwl_mvm_tt_mgmt thermal_throttle;
474 s32 temperature; /* Celsius */
346}; 475};
347 476
348/* Extract MVM priv from op_mode and _hw */ 477/* Extract MVM priv from op_mode and _hw */
@@ -352,6 +481,19 @@ struct iwl_mvm {
352#define IWL_MAC80211_GET_MVM(_hw) \ 481#define IWL_MAC80211_GET_MVM(_hw) \
353 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv)) 482 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
354 483
484enum iwl_mvm_status {
485 IWL_MVM_STATUS_HW_RFKILL,
486 IWL_MVM_STATUS_HW_CTKILL,
487 IWL_MVM_STATUS_ROC_RUNNING,
488 IWL_MVM_STATUS_IN_HW_RESTART,
489};
490
491static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
492{
493 return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status) ||
494 test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
495}
496
355extern const u8 iwl_mvm_ac_to_tx_fifo[]; 497extern const u8 iwl_mvm_ac_to_tx_fifo[];
356 498
357struct iwl_rate_info { 499struct iwl_rate_info {
@@ -443,8 +585,10 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
443int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 585int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
444 struct cfg80211_chan_def *chandef, 586 struct cfg80211_chan_def *chandef,
445 u8 chains_static, u8 chains_dynamic); 587 u8 chains_static, u8 chains_dynamic);
446void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, 588void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
447 struct iwl_mvm_phy_ctxt *ctxt); 589 struct iwl_mvm_phy_ctxt *ctxt);
590void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
591 struct iwl_mvm_phy_ctxt *ctxt);
448 592
449/* MAC (virtual interface) programming */ 593/* MAC (virtual interface) programming */
450int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 594int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -459,6 +603,9 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
459int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 603int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
460 struct iwl_rx_cmd_buffer *rxb, 604 struct iwl_rx_cmd_buffer *rxb,
461 struct iwl_device_cmd *cmd); 605 struct iwl_device_cmd *cmd);
606int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
607 struct iwl_rx_cmd_buffer *rxb,
608 struct iwl_device_cmd *cmd);
462 609
463/* Bindings */ 610/* Bindings */
464int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 611int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -534,4 +681,36 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
534 enum ieee80211_rssi_event rssi_event); 681 enum ieee80211_rssi_event rssi_event);
535void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 682void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
536 683
684/* beacon filtering */
685#ifdef CONFIG_IWLWIFI_DEBUGFS
686void
687iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
688 struct iwl_beacon_filter_cmd *cmd);
689int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm);
690#else
691static inline void
692iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
693 struct iwl_beacon_filter_cmd *cmd)
694{}
695static inline int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm)
696{
697 return 0;
698}
699#endif
700int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
701 struct ieee80211_vif *vif);
702int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
703 struct ieee80211_vif *vif);
704
705/* SMPS */
706void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
707 enum iwl_mvm_smps_type_request req_type,
708 enum ieee80211_smps_mode smps_request);
709
710/* Thermal management and CT-kill */
711void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
712void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
713void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
714void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
715
537#endif /* __IWL_MVM_H__ */ 716#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index b8ec02f89acc..edb94ea31654 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -60,6 +60,7 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/firmware.h>
63#include "iwl-trans.h" 64#include "iwl-trans.h"
64#include "mvm.h" 65#include "mvm.h"
65#include "iwl-eeprom-parse.h" 66#include "iwl-eeprom-parse.h"
@@ -75,31 +76,56 @@ static const int nvm_to_read[] = {
75}; 76};
76 77
77/* Default NVM size to read */ 78/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 79#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
80#define IWL_MAX_NVM_SECTION_SIZE 6000
79 81
80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd, 82#define NVM_WRITE_OPCODE 1
81 u16 offset, u16 length, u16 section) 83#define NVM_READ_OPCODE 0
84
85/*
86 * prepare the NVM host command w/ the pointers to the nvm buffer
87 * and send it to fw
88 */
89static int iwl_nvm_write_chunk(struct iwl_mvm *mvm, u16 section,
90 u16 offset, u16 length, const u8 *data)
82{ 91{
83 cmd->offset = cpu_to_le16(offset); 92 struct iwl_nvm_access_cmd nvm_access_cmd = {
84 cmd->length = cpu_to_le16(length); 93 .offset = cpu_to_le16(offset),
85 cmd->type = cpu_to_le16(section); 94 .length = cpu_to_le16(length),
95 .type = cpu_to_le16(section),
96 .op_code = NVM_WRITE_OPCODE,
97 };
98 struct iwl_host_cmd cmd = {
99 .id = NVM_ACCESS_CMD,
100 .len = { sizeof(struct iwl_nvm_access_cmd), length },
101 .flags = CMD_SYNC | CMD_SEND_IN_RFKILL,
102 .data = { &nvm_access_cmd, data },
103 /* data may come from vmalloc, so use _DUP */
104 .dataflags = { 0, IWL_HCMD_DFL_DUP },
105 };
106
107 return iwl_mvm_send_cmd(mvm, &cmd);
86} 108}
87 109
88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 110static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
89 u16 offset, u16 length, u8 *data) 111 u16 offset, u16 length, u8 *data)
90{ 112{
91 struct iwl_nvm_access_cmd nvm_access_cmd = {}; 113 struct iwl_nvm_access_cmd nvm_access_cmd = {
114 .offset = cpu_to_le16(offset),
115 .length = cpu_to_le16(length),
116 .type = cpu_to_le16(section),
117 .op_code = NVM_READ_OPCODE,
118 };
92 struct iwl_nvm_access_resp *nvm_resp; 119 struct iwl_nvm_access_resp *nvm_resp;
93 struct iwl_rx_packet *pkt; 120 struct iwl_rx_packet *pkt;
94 struct iwl_host_cmd cmd = { 121 struct iwl_host_cmd cmd = {
95 .id = NVM_ACCESS_CMD, 122 .id = NVM_ACCESS_CMD,
96 .flags = CMD_SYNC | CMD_WANT_SKB, 123 .flags = CMD_SYNC | CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
97 .data = { &nvm_access_cmd, }, 124 .data = { &nvm_access_cmd, },
98 }; 125 };
99 int ret, bytes_read, offset_read; 126 int ret, bytes_read, offset_read;
100 u8 *resp_data; 127 u8 *resp_data;
101 128
102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd); 129 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
104 130
105 ret = iwl_mvm_send_cmd(mvm, &cmd); 131 ret = iwl_mvm_send_cmd(mvm, &cmd);
@@ -144,6 +170,30 @@ exit:
144 return ret; 170 return ret;
145} 171}
146 172
173static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
174 const u8 *data, u16 length)
175{
176 int offset = 0;
177
178 /* copy data in chunks of 2k (and remainder if any) */
179
180 while (offset < length) {
181 int chunk_size, ret;
182
183 chunk_size = min(IWL_NVM_DEFAULT_CHUNK_SIZE,
184 length - offset);
185
186 ret = iwl_nvm_write_chunk(mvm, section, offset,
187 chunk_size, data + offset);
188 if (ret < 0)
189 return ret;
190
191 offset += chunk_size;
192 }
193
194 return 0;
195}
196
147/* 197/*
148 * Reads an NVM section completely. 198 * Reads an NVM section completely.
149 * NICs prior to 7000 family doesn't have a real NVM, but just read 199 * NICs prior to 7000 family doesn't have a real NVM, but just read
@@ -177,7 +227,8 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
177 offset += ret; 227 offset += ret;
178 } 228 }
179 229
180 IWL_INFO(mvm, "NVM section %d read completed\n", section); 230 IWL_DEBUG_EEPROM(mvm->trans->dev,
231 "NVM section %d read completed\n", section);
181 return offset; 232 return offset;
182} 233}
183 234
@@ -200,7 +251,130 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
200 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data; 251 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
201 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 252 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
202 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 253 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
203 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib); 254 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
255 iwl_fw_valid_tx_ant(mvm->fw),
256 iwl_fw_valid_rx_ant(mvm->fw));
257}
258
259#define MAX_NVM_FILE_LEN 16384
260
261/*
262 * HOW TO CREATE THE NVM FILE FORMAT:
263 * ------------------------------
264 * 1. create hex file, format:
265 * 3800 -> header
266 * 0000 -> header
267 * 5a40 -> data
268 *
269 * rev - 6 bit (word1)
270 * len - 10 bit (word1)
271 * id - 4 bit (word2)
272 * rsv - 12 bit (word2)
273 *
274 * 2. flip 8bits with 8 bits per line to get the right NVM file format
275 *
276 * 3. create binary file from the hex file
277 *
278 * 4. save as "iNVM_xxx.bin" under /lib/firmware
279 */
280static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
281{
282 int ret, section_id, section_size;
283 const struct firmware *fw_entry;
284 const struct {
285 __le16 word1;
286 __le16 word2;
287 u8 data[];
288 } *file_sec;
289 const u8 *eof;
290
291#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
292#define NVM_WORD2_ID(x) (x >> 12)
293
294 /*
295 * Obtain NVM image via request_firmware. Since we already used
296 * request_firmware_nowait() for the firmware binary load and only
297 * get here after that we assume the NVM request can be satisfied
298 * synchronously.
299 */
300 ret = request_firmware(&fw_entry, iwlwifi_mod_params.nvm_file,
301 mvm->trans->dev);
302 if (ret) {
303 IWL_ERR(mvm, "ERROR: %s isn't available %d\n",
304 iwlwifi_mod_params.nvm_file, ret);
305 return ret;
306 }
307
308 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
309 iwlwifi_mod_params.nvm_file, fw_entry->size);
310
311 if (fw_entry->size < sizeof(*file_sec)) {
312 IWL_ERR(mvm, "NVM file too small\n");
313 ret = -EINVAL;
314 goto out;
315 }
316
317 if (fw_entry->size > MAX_NVM_FILE_LEN) {
318 IWL_ERR(mvm, "NVM file too large\n");
319 ret = -EINVAL;
320 goto out;
321 }
322
323 eof = fw_entry->data + fw_entry->size;
324
325 file_sec = (void *)fw_entry->data;
326
327 while (true) {
328 if (file_sec->data > eof) {
329 IWL_ERR(mvm,
330 "ERROR - NVM file too short for section header\n");
331 ret = -EINVAL;
332 break;
333 }
334
335 /* check for EOF marker */
336 if (!file_sec->word1 && !file_sec->word2) {
337 ret = 0;
338 break;
339 }
340
341 section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
342 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
343
344 if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
345 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
346 section_size);
347 ret = -EINVAL;
348 break;
349 }
350
351 if (!section_size) {
352 IWL_ERR(mvm, "ERROR - section empty\n");
353 ret = -EINVAL;
354 break;
355 }
356
357 if (file_sec->data + section_size > eof) {
358 IWL_ERR(mvm,
359 "ERROR - NVM file too short for section (%d bytes)\n",
360 section_size);
361 ret = -EINVAL;
362 break;
363 }
364
365 ret = iwl_nvm_write_section(mvm, section_id, file_sec->data,
366 section_size);
367 if (ret < 0) {
368 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
369 break;
370 }
371
372 /* advance to the next section */
373 file_sec = (void *)(file_sec->data + section_size);
374 }
375out:
376 release_firmware(fw_entry);
377 return ret;
204} 378}
205 379
206int iwl_nvm_init(struct iwl_mvm *mvm) 380int iwl_nvm_init(struct iwl_mvm *mvm)
@@ -208,6 +382,17 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
208 int ret, i, section; 382 int ret, i, section;
209 u8 *nvm_buffer, *temp; 383 u8 *nvm_buffer, *temp;
210 384
385 /* load external NVM if configured */
386 if (iwlwifi_mod_params.nvm_file) {
387 /* move to External NVM flow */
388 ret = iwl_mvm_load_external_nvm(mvm);
389 if (ret)
390 return ret;
391 }
392
393 /* Read From FW NVM */
394 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
395
211 /* TODO: find correct NVM max size for a section */ 396 /* TODO: find correct NVM max size for a section */
212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 397 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
213 GFP_KERNEL); 398 GFP_KERNEL);
@@ -231,8 +416,9 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
231 if (ret < 0) 416 if (ret < 0)
232 return ret; 417 return ret;
233 418
234 ret = 0;
235 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 419 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
420 if (!mvm->nvm_data)
421 return -ENODATA;
236 422
237 return ret; 423 return 0;
238} 424}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index fe031d304d1e..d7a199b1cdef 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -222,10 +222,14 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
222 222
223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), 224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
225 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
225 226
226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 227 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 228 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
228 229
230 RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
231 false),
232
229 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 233 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
230}; 234};
231#undef RX_HANDLER 235#undef RX_HANDLER
@@ -288,10 +292,14 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
288 CMD(NET_DETECT_HOTSPOTS_CMD), 292 CMD(NET_DETECT_HOTSPOTS_CMD),
289 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 293 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
290 CMD(CARD_STATE_NOTIFICATION), 294 CMD(CARD_STATE_NOTIFICATION),
295 CMD(MISSED_BEACONS_NOTIFICATION),
291 CMD(BT_COEX_PRIO_TABLE), 296 CMD(BT_COEX_PRIO_TABLE),
292 CMD(BT_COEX_PROT_ENV), 297 CMD(BT_COEX_PROT_ENV),
293 CMD(BT_PROFILE_NOTIFICATION), 298 CMD(BT_PROFILE_NOTIFICATION),
294 CMD(BT_CONFIG), 299 CMD(BT_CONFIG),
300 CMD(MCAST_FILTER_CMD),
301 CMD(REPLY_BEACON_FILTERING_CMD),
302 CMD(REPLY_THERMAL_MNG_BACKOFF),
295}; 303};
296#undef CMD 304#undef CMD
297 305
@@ -392,10 +400,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
392 if (err) 400 if (err)
393 goto out_free; 401 goto out_free;
394 402
403 iwl_mvm_tt_initialize(mvm);
404
395 mutex_lock(&mvm->mutex); 405 mutex_lock(&mvm->mutex);
396 err = iwl_run_init_mvm_ucode(mvm, true); 406 err = iwl_run_init_mvm_ucode(mvm, true);
397 mutex_unlock(&mvm->mutex); 407 mutex_unlock(&mvm->mutex);
398 if (err && !iwlmvm_mod_params.init_dbg) { 408 /* returns 0 if successful, 1 if success but in rfkill */
409 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
399 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 410 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
400 goto out_free; 411 goto out_free;
401 } 412 }
@@ -438,10 +449,16 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
438 449
439 iwl_mvm_leds_exit(mvm); 450 iwl_mvm_leds_exit(mvm);
440 451
452 iwl_mvm_tt_exit(mvm);
453
441 ieee80211_unregister_hw(mvm->hw); 454 ieee80211_unregister_hw(mvm->hw);
442 455
443 kfree(mvm->scan_cmd); 456 kfree(mvm->scan_cmd);
444 457
458#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
459 kfree(mvm->d3_resume_sram);
460#endif
461
445 iwl_trans_stop_hw(mvm->trans, true); 462 iwl_trans_stop_hw(mvm->trans, true);
446 463
447 iwl_phy_db_free(mvm->phy_db); 464 iwl_phy_db_free(mvm->phy_db);
@@ -588,6 +605,16 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
588 ieee80211_wake_queue(mvm->hw, mq); 605 ieee80211_wake_queue(mvm->hw, mq);
589} 606}
590 607
608void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
609{
610 if (state)
611 set_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
612 else
613 clear_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
614
615 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
616}
617
591static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) 618static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
592{ 619{
593 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 620 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
@@ -597,7 +624,7 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
597 else 624 else
598 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 625 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
599 626
600 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state); 627 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
601} 628}
602 629
603static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) 630static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index a28a1d1f23eb..1b4db25d53fb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -195,21 +195,6 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
195 return ret; 195 return ret;
196} 196}
197 197
198
199struct phy_ctx_used_data {
200 unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
201};
202
203static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
204 struct ieee80211_chanctx_conf *ctx,
205 void *_data)
206{
207 struct phy_ctx_used_data *data = _data;
208 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
209
210 __set_bit(phy_ctxt->id, data->used);
211}
212
213/* 198/*
214 * Send a command to add a PHY context based on the current HW configuration. 199 * Send a command to add a PHY context based on the current HW configuration.
215 */ 200 */
@@ -217,34 +202,27 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
217 struct cfg80211_chan_def *chandef, 202 struct cfg80211_chan_def *chandef,
218 u8 chains_static, u8 chains_dynamic) 203 u8 chains_static, u8 chains_dynamic)
219{ 204{
220 struct phy_ctx_used_data data = { 205 int ret;
221 .used = { },
222 };
223
224 /*
225 * If this is a regular PHY context (not the ROC one)
226 * skip the ROC PHY context's ID.
227 */
228 if (ctxt != &mvm->phy_ctxt_roc)
229 __set_bit(mvm->phy_ctxt_roc.id, data.used);
230 206
207 WARN_ON(ctxt->ref);
231 lockdep_assert_held(&mvm->mutex); 208 lockdep_assert_held(&mvm->mutex);
232 ctxt->color++;
233 209
234 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 210 ctxt->channel = chandef->chan;
235 ieee80211_iter_chan_contexts_atomic( 211 ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
236 mvm->hw, iwl_mvm_phy_ctx_used_iter, &data); 212 chains_static, chains_dynamic,
213 FW_CTXT_ACTION_ADD, 0);
237 214
238 ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX); 215 return ret;
239 if (WARN_ONCE(ctxt->id == NUM_PHY_CTX, 216}
240 "Failed to init PHY context - no free ID!\n"))
241 return -EIO;
242 }
243 217
244 ctxt->channel = chandef->chan; 218/*
245 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 219 * Update the number of references to the given PHY context. This is valid only
246 chains_static, chains_dynamic, 220 * in case the PHY context was already created, i.e., its reference count > 0.
247 FW_CTXT_ACTION_ADD, 0); 221 */
222void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
223{
224 lockdep_assert_held(&mvm->mutex);
225 ctxt->ref++;
248} 226}
249 227
250/* 228/*
@@ -264,23 +242,12 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
264 FW_CTXT_ACTION_MODIFY, 0); 242 FW_CTXT_ACTION_MODIFY, 0);
265} 243}
266 244
267/* 245void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
268 * Send a command to the FW to remove the given phy context.
269 * Once the command is sent, regardless of success or failure, the context is
270 * marked as invalid
271 */
272void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
273{ 246{
274 struct iwl_phy_context_cmd cmd;
275 int ret;
276
277 lockdep_assert_held(&mvm->mutex); 247 lockdep_assert_held(&mvm->mutex);
278 248
279 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0); 249 if (WARN_ON_ONCE(!ctxt))
280 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC, 250 return;
281 sizeof(struct iwl_phy_context_cmd), 251
282 &cmd); 252 ctxt->ref--;
283 if (ret)
284 IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
285 ctxt->id);
286} 253}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index ed77e437aac4..67cf24aa72f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -75,6 +75,54 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd)
80{
81 int ret;
82
83 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
84 sizeof(struct iwl_beacon_filter_cmd), cmd);
85
86 if (!ret) {
87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
88 cmd->ba_enable_beacon_abort);
89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
90 cmd->ba_escape_timer);
91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
92 cmd->bf_debug_flag);
93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
94 cmd->bf_enable_beacon_filter);
95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
96 cmd->bf_energy_delta);
97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
98 cmd->bf_escape_timer);
99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
100 cmd->bf_roaming_energy_delta);
101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
102 cmd->bf_roaming_state);
103 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
104 cmd->bf_temperature_delta);
105 }
106 return ret;
107}
108
109static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
110 struct ieee80211_vif *vif, bool enable)
111{
112 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
113 struct iwl_beacon_filter_cmd cmd = {
114 IWL_BF_CMD_CONFIG_DEFAULTS,
115 .bf_enable_beacon_filter = 1,
116 .ba_enable_beacon_abort = enable,
117 };
118
119 if (!mvmvif->bf_enabled)
120 return 0;
121
122 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
123 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
124}
125
78static void iwl_mvm_power_log(struct iwl_mvm *mvm, 126static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 127 struct iwl_powertable_cmd *cmd)
80{ 128{
@@ -91,6 +139,9 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
91 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
92 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", 140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
93 cmd->lprx_rssi_threshold); 141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods));
94 } 145 }
95} 146}
96 147
@@ -103,6 +154,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
103 int dtimper, dtimper_msec; 154 int dtimper, dtimper_msec;
104 int keep_alive; 155 int keep_alive;
105 bool radar_detect = false; 156 bool radar_detect = false;
157 struct iwl_mvm_vif *mvmvif __maybe_unused =
158 iwl_mvm_vif_from_mac80211(vif);
106 159
107 /* 160 /*
108 * Regardless of power management state the driver must set 161 * Regardless of power management state the driver must set
@@ -116,6 +169,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
116 169
117 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 170 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
118 171
172#ifdef CONFIG_IWLWIFI_DEBUGFS
173 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
174 mvmvif->dbgfs_pm.disable_power_off)
175 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
176#endif
119 if (!vif->bss_conf.ps) 177 if (!vif->bss_conf.ps)
120 return; 178 return;
121 179
@@ -135,8 +193,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
135 193
136 /* Check skip over DTIM conditions */ 194 /* Check skip over DTIM conditions */
137 if (!radar_detect && (dtimper <= 10) && 195 if (!radar_detect && (dtimper <= 10) &&
138 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) 196 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
197 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
139 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 198 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
199 cmd->skip_dtim_periods = cpu_to_le32(3);
200 }
140 201
141 /* Check that keep alive period is at least 3 * DTIM */ 202 /* Check that keep alive period is at least 3 * DTIM */
142 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 203 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
@@ -145,12 +206,41 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
145 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 206 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
146 cmd->keep_alive_seconds = keep_alive; 207 cmd->keep_alive_seconds = keep_alive;
147 208
148 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 209 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
149 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 210 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
211 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
212 } else {
213 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
214 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
215 }
216
217#ifdef CONFIG_IWLWIFI_DEBUGFS
218 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
219 cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
220 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
221 if (mvmvif->dbgfs_pm.skip_over_dtim)
222 cmd->flags |=
223 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
224 else
225 cmd->flags &=
226 cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
227 }
228 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
229 cmd->rx_data_timeout =
230 cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
231 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
232 cmd->tx_data_timeout =
233 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
234 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
235 cmd->skip_dtim_periods =
236 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
237#endif /* CONFIG_IWLWIFI_DEBUGFS */
150} 238}
151 239
152int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 240int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
153{ 241{
242 int ret;
243 bool ba_enable;
154 struct iwl_powertable_cmd cmd = {}; 244 struct iwl_powertable_cmd cmd = {};
155 245
156 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 246 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
@@ -159,13 +249,22 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
159 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 249 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
160 iwl_mvm_power_log(mvm, &cmd); 250 iwl_mvm_power_log(mvm, &cmd);
161 251
162 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 252 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
163 sizeof(cmd), &cmd); 253 sizeof(cmd), &cmd);
254 if (ret)
255 return ret;
256
257 ba_enable = !!(cmd.flags &
258 cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
259
260 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
164} 261}
165 262
166int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 263int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
167{ 264{
168 struct iwl_powertable_cmd cmd = {}; 265 struct iwl_powertable_cmd cmd = {};
266 struct iwl_mvm_vif *mvmvif __maybe_unused =
267 iwl_mvm_vif_from_mac80211(vif);
169 268
170 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 269 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
171 return 0; 270 return 0;
@@ -173,8 +272,82 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
173 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 272 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
174 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 273 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
175 274
275#ifdef CONFIG_IWLWIFI_DEBUGFS
276 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
277 mvmvif->dbgfs_pm.disable_power_off)
278 cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
279#endif
176 iwl_mvm_power_log(mvm, &cmd); 280 iwl_mvm_power_log(mvm, &cmd);
177 281
178 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 282 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
179 sizeof(cmd), &cmd); 283 sizeof(cmd), &cmd);
180} 284}
285
286#ifdef CONFIG_IWLWIFI_DEBUGFS
287void
288iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
289 struct iwl_beacon_filter_cmd *cmd)
290{
291 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
292 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
293
294 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
295 cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta;
296 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
297 cmd->bf_roaming_energy_delta =
298 dbgfs_bf->bf_roaming_energy_delta;
299 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
300 cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state;
301 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA)
302 cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta;
303 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
304 cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag;
305 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
306 cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
307 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
308 cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
309 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
310 cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort;
311}
312#endif
313
314int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
315 struct ieee80211_vif *vif)
316{
317 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
318 struct iwl_beacon_filter_cmd cmd = {
319 IWL_BF_CMD_CONFIG_DEFAULTS,
320 .bf_enable_beacon_filter = 1,
321 };
322 int ret;
323
324 if (mvmvif != mvm->bf_allowed_vif ||
325 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
326 return 0;
327
328 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
329 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
330
331 if (!ret)
332 mvmvif->bf_enabled = true;
333
334 return ret;
335}
336
337int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
338 struct ieee80211_vif *vif)
339{
340 struct iwl_beacon_filter_cmd cmd = {};
341 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
342 int ret;
343
344 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
345 return 0;
346
347 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
348
349 if (!ret)
350 mvmvif->bf_enabled = false;
351
352 return ret;
353}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 55334d542e26..6a050c69e7d0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -3080,3 +3080,29 @@ void iwl_mvm_rate_control_unregister(void)
3080{ 3080{
3081 ieee80211_rate_control_unregister(&rs_mvm_ops); 3081 ieee80211_rate_control_unregister(&rs_mvm_ops);
3082} 3082}
3083
3084/**
3085 * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
3086 * Tx protection, according to this rquest and previous requests,
3087 * and send the LQ command.
3088 * @lq: The LQ command
3089 * @mvmsta: The station
3090 * @enable: Enable Tx protection?
3091 */
3092int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
3093 struct iwl_mvm_sta *mvmsta, bool enable)
3094{
3095 lockdep_assert_held(&mvm->mutex);
3096
3097 if (enable) {
3098 if (mvmsta->tx_protection == 0)
3099 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
3100 mvmsta->tx_protection++;
3101 } else {
3102 mvmsta->tx_protection--;
3103 if (mvmsta->tx_protection == 0)
3104 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
3105 }
3106
3107 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false);
3108}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 219c6857cc0f..f66155a57238 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -390,4 +390,9 @@ extern int iwl_mvm_rate_control_register(void);
390 */ 390 */
391extern void iwl_mvm_rate_control_unregister(void); 391extern void iwl_mvm_rate_control_unregister(void);
392 392
393struct iwl_mvm_sta;
394
395int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
396 struct iwl_mvm_sta *mvmsta, bool enable);
397
393#endif /* __rs__ */ 398#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 4dfc21a3e83e..e4930d5027d2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -363,3 +363,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
363 rxb, &rx_status); 363 rxb, &rx_status);
364 return 0; 364 return 0;
365} 365}
366
367/*
368 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler
369 *
370 * TODO: This handler is implemented partially.
371 * It only gets the NIC's temperature.
372 */
373int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
374 struct iwl_rx_cmd_buffer *rxb,
375 struct iwl_device_cmd *cmd)
376{
377 struct iwl_rx_packet *pkt = rxb_addr(rxb);
378 struct iwl_notif_statistics *stats = (void *)&pkt->data;
379 struct mvm_statistics_general_common *common = &stats->general.common;
380
381 if (mvm->temperature != le32_to_cpu(common->temperature)) {
382 mvm->temperature = le32_to_cpu(common->temperature);
383 iwl_mvm_tt_handler(mvm);
384 }
385
386 return 0;
387}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 0fd96e4da461..2278858d5658 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -64,6 +64,7 @@
64 64
65#include "mvm.h" 65#include "mvm.h"
66#include "sta.h" 66#include "sta.h"
67#include "rs.h"
67 68
68static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) 69static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
69{ 70{
@@ -217,9 +218,11 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
217 mvmvif->color); 218 mvmvif->color);
218 mvm_sta->vif = vif; 219 mvm_sta->vif = vif;
219 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 220 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
221 mvm_sta->tx_protection = 0;
222 mvm_sta->tt_tx_protection = false;
220 223
221 /* HW restart, don't assume the memory has been zeroed */ 224 /* HW restart, don't assume the memory has been zeroed */
222 atomic_set(&mvm_sta->pending_frames, 0); 225 atomic_set(&mvm->pending_frames[sta_id], 0);
223 mvm_sta->tid_disable_agg = 0; 226 mvm_sta->tid_disable_agg = 0;
224 mvm_sta->tfd_queue_msk = 0; 227 mvm_sta->tfd_queue_msk = 0;
225 for (i = 0; i < IEEE80211_NUM_ACS; i++) 228 for (i = 0; i < IEEE80211_NUM_ACS; i++)
@@ -407,14 +410,21 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
407 } 410 }
408 411
409 /* 412 /*
413 * Make sure that the tx response code sees the station as -EBUSY and
414 * calls the drain worker.
415 */
416 spin_lock_bh(&mvm_sta->lock);
417 /*
410 * There are frames pending on the AC queues for this station. 418 * There are frames pending on the AC queues for this station.
411 * We need to wait until all the frames are drained... 419 * We need to wait until all the frames are drained...
412 */ 420 */
413 if (atomic_read(&mvm_sta->pending_frames)) { 421 if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) {
414 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
415 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 422 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
416 ERR_PTR(-EBUSY)); 423 ERR_PTR(-EBUSY));
424 spin_unlock_bh(&mvm_sta->lock);
425 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
417 } else { 426 } else {
427 spin_unlock_bh(&mvm_sta->lock);
418 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); 428 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
419 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); 429 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
420 } 430 }
@@ -791,21 +801,23 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
791 min(mvmsta->max_agg_bufsize, buf_size); 801 min(mvmsta->max_agg_bufsize, buf_size);
792 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize; 802 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
793 803
804 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
805 sta->addr, tid);
806
794 if (mvm->cfg->ht_params->use_rts_for_aggregation) { 807 if (mvm->cfg->ht_params->use_rts_for_aggregation) {
795 /* 808 /*
796 * switch to RTS/CTS if it is the prefer protection 809 * switch to RTS/CTS if it is the prefer protection
797 * method for HT traffic 810 * method for HT traffic
811 * this function also sends the LQ command
798 */ 812 */
799 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 813 return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
814 mvmsta, true);
800 /* 815 /*
801 * TODO: remove the TLC_RTS flag when we tear down the last 816 * TODO: remove the TLC_RTS flag when we tear down the last
802 * AGG session (agg_tids_count in DVM) 817 * AGG session (agg_tids_count in DVM)
803 */ 818 */
804 } 819 }
805 820
806 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
807 sta->addr, tid);
808
809 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false); 821 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
810} 822}
811 823
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 12abd2d71835..3efa0a0cc987 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -274,8 +274,9 @@ struct iwl_mvm_tid_data {
274 * @bt_reduced_txpower: is reduced tx power enabled for this station 274 * @bt_reduced_txpower: is reduced tx power enabled for this station
275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx 275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
276 * and from Tx response flow, it needs a spinlock. 276 * and from Tx response flow, it needs a spinlock.
277 * @pending_frames: number of frames for this STA on the shared Tx queues.
278 * @tid_data: per tid data. Look at %iwl_mvm_tid_data. 277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
278 * @tx_protection: reference counter for controlling the Tx protection.
279 * @tt_tx_protection: is thermal throttling enable Tx protection?
279 * 280 *
280 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 281 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
281 * in the structure for use by driver. This structure is placed in that 282 * in the structure for use by driver. This structure is placed in that
@@ -290,7 +291,6 @@ struct iwl_mvm_sta {
290 u8 max_agg_bufsize; 291 u8 max_agg_bufsize;
291 bool bt_reduced_txpower; 292 bool bt_reduced_txpower;
292 spinlock_t lock; 293 spinlock_t lock;
293 atomic_t pending_frames;
294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; 294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
295 struct iwl_lq_sta lq_sta; 295 struct iwl_lq_sta lq_sta;
296 struct ieee80211_vif *vif; 296 struct ieee80211_vif *vif;
@@ -298,6 +298,10 @@ struct iwl_mvm_sta {
298#ifdef CONFIG_PM_SLEEP 298#ifdef CONFIG_PM_SLEEP
299 u16 last_seq_ctl; 299 u16 last_seq_ctl;
300#endif 300#endif
301
302 /* Temporary, until the new TLC will control the Tx protection */
303 s8 tx_protection;
304 bool tt_tx_protection;
301}; 305};
302 306
303/** 307/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
new file mode 100644
index 000000000000..4665fc033c17
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -0,0 +1,509 @@
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) 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) 2012 - 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 "mvm.h"
65#include "iwl-config.h"
66#include "iwl-io.h"
67#include "iwl-csr.h"
68#include "iwl-prph.h"
69
70#define OTP_DTS_DIODE_DEVIATION 96 /*in words*/
71/* VBG - Voltage Band Gap error data (temperature offset) */
72#define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2)
73#define MEAS_VBG_MIN_VAL 2300
74#define MEAS_VBG_MAX_VAL 3000
75#define MEAS_VBG_DEFAULT_VAL 2700
76#define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
77#define MIN_TEMPERATURE 0
78#define MAX_TEMPERATURE 125
79#define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1)
80#define PTAT_DIGITAL_VALUE_MIN_VALUE 0
81#define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF
82#define DTS_VREFS_NUM 5
83static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags)
84{
85 return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >>
86 DTS_DIODE_REG_FLAGS_VREFS_ID_POS;
87}
88
89#define CALC_VREFS_MIN_DIFF 43
90#define CALC_VREFS_MAX_DIFF 51
91#define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
92#define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF
93#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23
94
95/*
96 * @digital_value: The diode's digital-value sampled (temperature/voltage)
97 * @vref_low: The lower voltage-reference (the vref just below the diode's
98 * sampled digital-value)
99 * @vref_high: The higher voltage-reference (the vref just above the diode's
100 * sampled digital-value)
101 * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
102 * bits[6:2]: Reserved.
103 * bits[7:7]: Indicates completion of at least 1 successful sample
104 * since last DTS reset.
105 */
106struct iwl_mvm_dts_diode_bits {
107 u8 digital_value;
108 u8 vref_low;
109 u8 vref_high;
110 u8 flags;
111} __packed;
112
113union dts_diode_results {
114 u32 reg_value;
115 struct iwl_mvm_dts_diode_bits bits;
116} __packed;
117
118static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm)
119{
120 struct iwl_nvm_section calib_sec;
121 const __le16 *calib;
122 u16 vbg;
123
124 /* TODO: move parsing to NVM code */
125 calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION];
126 calib = (__le16 *)calib_sec.data;
127
128 vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]);
129
130 if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL)
131 vbg = MEAS_VBG_DEFAULT_VAL;
132
133 return vbg;
134}
135
136static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)
137{
138 const u8 *calib;
139 u8 ptat, pa1, pa2, median;
140
141 /* TODO: move parsing to NVM code */
142 calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
143 ptat = calib[OTP_DTS_DIODE_DEVIATION];
144 pa1 = calib[OTP_DTS_DIODE_DEVIATION + 1];
145 pa2 = calib[OTP_DTS_DIODE_DEVIATION + 2];
146
147 /* get the median: */
148 if (ptat > pa1) {
149 if (ptat > pa2)
150 median = (pa1 > pa2) ? pa1 : pa2;
151 else
152 median = ptat;
153 } else {
154 if (pa1 > pa2)
155 median = (ptat > pa2) ? ptat : pa2;
156 else
157 median = pa1;
158 }
159
160 return ptat - median;
161}
162
163static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value)
164{
165 /* Calibrate the PTAT digital value, based on PTAT deviation data: */
166 s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm);
167
168 if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE)
169 new_val = PTAT_DIGITAL_VALUE_MAX_VALUE;
170 else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE)
171 new_val = PTAT_DIGITAL_VALUE_MIN_VALUE;
172
173 return new_val;
174}
175
176static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm,
177 union dts_diode_results *avg_ptat)
178{
179 u8 vrefs_results[DTS_VREFS_NUM];
180 u8 low_vref_index = 0, flags;
181 u32 reg;
182
183 reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG);
184 memcpy(vrefs_results, &reg, sizeof(reg));
185 reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG);
186 vrefs_results[4] = reg & 0xff;
187
188 if (avg_ptat->bits.digital_value < vrefs_results[0] ||
189 avg_ptat->bits.digital_value > vrefs_results[4])
190 return false;
191
192 if (avg_ptat->bits.digital_value > vrefs_results[3])
193 low_vref_index = 3;
194 else if (avg_ptat->bits.digital_value > vrefs_results[2])
195 low_vref_index = 2;
196 else if (avg_ptat->bits.digital_value > vrefs_results[1])
197 low_vref_index = 1;
198
199 avg_ptat->bits.vref_low = vrefs_results[low_vref_index];
200 avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1];
201 flags = avg_ptat->bits.flags;
202 avg_ptat->bits.flags =
203 (flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) |
204 (low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID);
205 return true;
206}
207
208/*
209 * return true it the results are valid, and false otherwise.
210 */
211static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm,
212 union dts_diode_results *avg_ptat)
213{
214 u32 reg;
215 u8 tmp;
216
217 /* fill the diode value and pass_once with avg-reg results */
218 reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG);
219 reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE;
220 avg_ptat->reg_value = reg;
221
222 /* calibrate the PTAT digital value */
223 tmp = avg_ptat->bits.digital_value;
224 tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp);
225 avg_ptat->bits.digital_value = tmp;
226
227 /*
228 * fill vrefs fields, based on the avgVrefs results
229 * and the diode value
230 */
231 return dts_get_adjacent_vrefs(mvm, avg_ptat) &&
232 DTS_DIODE_VALID(avg_ptat->bits.flags);
233}
234
235static s32 calculate_nic_temperature(union dts_diode_results avg_ptat,
236 u16 volt_band_gap)
237{
238 u32 tmp_result;
239 u8 vrefs_diff;
240 /*
241 * For temperature calculation (at the end, shift right by 23)
242 * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
243 * (D2-D1) == 43 44 45 46 47 48 49 50 51
244 */
245 static const u16 calc_lut[CALC_LUT_SIZE] = {
246 2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828,
247 };
248
249 /*
250 * The diff between the high and low voltage-references is assumed
251 * to be strictly be in range of [60,68]
252 */
253 vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low;
254
255 if (vrefs_diff < CALC_VREFS_MIN_DIFF ||
256 vrefs_diff > CALC_VREFS_MAX_DIFF)
257 return TEMPERATURE_ERROR;
258
259 /* calculate the result: */
260 tmp_result =
261 vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9);
262 tmp_result += avg_ptat.bits.digital_value;
263 tmp_result -= avg_ptat.bits.vref_high;
264
265 /* multiply by the LUT value (based on the diff) */
266 tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET];
267
268 /*
269 * Get the BandGap (the voltage refereces source) error data
270 * (temperature offset)
271 */
272 tmp_result *= volt_band_gap;
273
274 /*
275 * here, tmp_result value can be up to 32-bits. We want to right-shift
276 * it *without* sign-extend.
277 */
278 tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET;
279
280 /*
281 * at this point, tmp_result should be in the range:
282 * 200 <= tmp_result <= 365
283 */
284 return (s16)tmp_result - 240;
285}
286
287static s32 check_nic_temperature(struct iwl_mvm *mvm)
288{
289 u16 volt_band_gap;
290 union dts_diode_results avg_ptat;
291
292 volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm);
293
294 /* disable DTS */
295 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
296
297 /* SV initialization */
298 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1);
299 iwl_write_prph(mvm->trans, DTSC_CFG_MODE,
300 DTSC_CFG_MODE_PERIODIC);
301
302 /* wait for results */
303 msleep(100);
304 if (!dts_read_ptat_avg_results(mvm, &avg_ptat))
305 return TEMPERATURE_ERROR;
306
307 /* disable DTS */
308 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
309
310 return calculate_nic_temperature(avg_ptat, volt_band_gap);
311}
312
313static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
314{
315 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
316
317 IWL_ERR(mvm, "Enter CT Kill\n");
318 iwl_mvm_set_hw_ctkill_state(mvm, true);
319 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
320 round_jiffies_relative(duration * HZ));
321}
322
323static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
324{
325 IWL_ERR(mvm, "Exit CT Kill\n");
326 iwl_mvm_set_hw_ctkill_state(mvm, false);
327}
328
329static void check_exit_ctkill(struct work_struct *work)
330{
331 struct iwl_mvm_tt_mgmt *tt;
332 struct iwl_mvm *mvm;
333 u32 duration;
334 s32 temp;
335
336 tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
337 mvm = container_of(tt, struct iwl_mvm, thermal_throttle);
338
339 duration = tt->params->ct_kill_duration;
340
341 iwl_trans_start_hw(mvm->trans);
342 temp = check_nic_temperature(mvm);
343 iwl_trans_stop_hw(mvm->trans, false);
344
345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
347 goto reschedule;
348 }
349 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);
350
351 if (temp <= tt->params->ct_kill_exit) {
352 iwl_mvm_exit_ctkill(mvm);
353 return;
354 }
355
356reschedule:
357 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
358 round_jiffies(duration * HZ));
359}
360
361static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
362 struct ieee80211_vif *vif)
363{
364 struct iwl_mvm *mvm = _data;
365 enum ieee80211_smps_mode smps_mode;
366
367 lockdep_assert_held(&mvm->mutex);
368
369 if (mvm->thermal_throttle.dynamic_smps)
370 smps_mode = IEEE80211_SMPS_DYNAMIC;
371 else
372 smps_mode = IEEE80211_SMPS_AUTOMATIC;
373
374 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode);
375}
376
377static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
378{
379 struct ieee80211_sta *sta;
380 struct iwl_mvm_sta *mvmsta;
381 int i, err;
382
383 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
384 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
385 lockdep_is_held(&mvm->mutex));
386 if (IS_ERR_OR_NULL(sta))
387 continue;
388 mvmsta = (void *)sta->drv_priv;
389 if (enable == mvmsta->tt_tx_protection)
390 continue;
391 err = iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
392 mvmsta, enable);
393 if (err) {
394 IWL_ERR(mvm, "Failed to %s Tx protection\n",
395 enable ? "enable" : "disable");
396 } else {
397 IWL_DEBUG_TEMP(mvm, "%s Tx protection\n",
398 enable ? "Enable" : "Disable");
399 mvmsta->tt_tx_protection = enable;
400 }
401 }
402}
403
404static void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff)
405{
406 struct iwl_host_cmd cmd = {
407 .id = REPLY_THERMAL_MNG_BACKOFF,
408 .len = { sizeof(u32), },
409 .data = { &backoff, },
410 .flags = CMD_SYNC,
411 };
412
413 if (iwl_mvm_send_cmd(mvm, &cmd) == 0) {
414 IWL_DEBUG_TEMP(mvm, "Set Thermal Tx backoff to: %u\n",
415 backoff);
416 mvm->thermal_throttle.tx_backoff = backoff;
417 } else {
418 IWL_ERR(mvm, "Failed to change Thermal Tx backoff\n");
419 }
420}
421
422void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
423{
424 const struct iwl_tt_params *params = mvm->thermal_throttle.params;
425 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
426 s32 temperature = mvm->temperature;
427 int i;
428 u32 tx_backoff;
429
430 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", mvm->temperature);
431
432 if (params->support_ct_kill && temperature >= params->ct_kill_entry) {
433 iwl_mvm_enter_ctkill(mvm);
434 return;
435 }
436
437 if (params->support_dynamic_smps) {
438 if (!tt->dynamic_smps &&
439 temperature >= params->dynamic_smps_entry) {
440 IWL_DEBUG_TEMP(mvm, "Enable dynamic SMPS\n");
441 tt->dynamic_smps = true;
442 ieee80211_iterate_active_interfaces_atomic(
443 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
444 iwl_mvm_tt_smps_iterator, mvm);
445 } else if (tt->dynamic_smps &&
446 temperature <= params->dynamic_smps_exit) {
447 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
448 tt->dynamic_smps = false;
449 ieee80211_iterate_active_interfaces_atomic(
450 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
451 iwl_mvm_tt_smps_iterator, mvm);
452 }
453 }
454
455 if (params->support_tx_protection) {
456 if (temperature >= params->tx_protection_entry)
457 iwl_mvm_tt_tx_protection(mvm, true);
458 else if (temperature <= params->tx_protection_exit)
459 iwl_mvm_tt_tx_protection(mvm, false);
460 }
461
462 if (params->support_tx_backoff) {
463 tx_backoff = 0;
464 for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
465 if (temperature < params->tx_backoff[i].temperature)
466 break;
467 tx_backoff = params->tx_backoff[i].backoff;
468 }
469 if (tt->tx_backoff != tx_backoff)
470 iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
471 }
472}
473
474static const struct iwl_tt_params iwl7000_tt_params = {
475 .ct_kill_entry = 118,
476 .ct_kill_exit = 96,
477 .ct_kill_duration = 5,
478 .dynamic_smps_entry = 114,
479 .dynamic_smps_exit = 110,
480 .tx_protection_entry = 114,
481 .tx_protection_exit = 108,
482 .tx_backoff = {
483 {.temperature = 112, .backoff = 200},
484 {.temperature = 113, .backoff = 600},
485 {.temperature = 114, .backoff = 1200},
486 {.temperature = 115, .backoff = 2000},
487 {.temperature = 116, .backoff = 4000},
488 {.temperature = 117, .backoff = 10000},
489 },
490 .support_ct_kill = true,
491 .support_dynamic_smps = true,
492 .support_tx_protection = true,
493 .support_tx_backoff = true,
494};
495
496void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
497{
498 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
499
500 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
501 tt->params = &iwl7000_tt_params;
502 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
503}
504
505void iwl_mvm_tt_exit(struct iwl_mvm *mvm)
506{
507 cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
508 IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
509}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 479074303bd7..f212f16502ff 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
416 416
417 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
418 418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP && 419 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE)
420 txq_id < IWL_MVM_FIRST_AGG_QUEUE) 420 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
421 atomic_inc(&mvmsta->pending_frames);
422 421
423 return 0; 422 return 0;
424 423
@@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
680 /* 679 /*
681 * If the txq is not an AMPDU queue, there is no chance we freed 680 * If the txq is not an AMPDU queue, there is no chance we freed
682 * several skbs. Check that out... 681 * several skbs. Check that out...
683 * If there are no pending frames for this STA, notify mac80211 that
684 * this station can go to sleep in its STA table.
685 */ 682 */
686 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta && 683 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) &&
687 !WARN_ON(skb_freed > 1) && 684 atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
688 mvmsta->vif->type == NL80211_IFTYPE_AP && 685 if (mvmsta) {
689 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { 686 /*
690 ieee80211_sta_block_awake(mvm->hw, sta, false); 687 * If there are no pending frames for this STA, notify
691 set_bit(sta_id, mvm->sta_drained); 688 * mac80211 that this station can go to sleep in its
692 schedule_work(&mvm->sta_drained_wk); 689 * STA table.
690 */
691 if (mvmsta->vif->type == NL80211_IFTYPE_AP)
692 ieee80211_sta_block_awake(mvm->hw, sta, false);
693 /*
694 * We might very well have taken mvmsta pointer while
695 * the station was being removed. The remove flow might
696 * have seen a pending_frame (because we didn't take
697 * the lock) even if now the queues are drained. So make
698 * really sure now that this the station is not being
699 * removed. If it is, run the drain worker to remove it.
700 */
701 spin_lock_bh(&mvmsta->lock);
702 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
703 if (IS_ERR_OR_NULL(sta)) {
704 /*
705 * Station disappeared in the meantime:
706 * so we are draining.
707 */
708 set_bit(sta_id, mvm->sta_drained);
709 schedule_work(&mvm->sta_drained_wk);
710 }
711 spin_unlock_bh(&mvmsta->lock);
712 } else if (!mvmsta) {
713 /* Tx response without STA, so we are draining */
714 set_bit(sta_id, mvm->sta_drained);
715 schedule_work(&mvm->sta_drained_wk);
716 }
693 } 717 }
694 718
695 rcu_read_unlock(); 719 rcu_read_unlock();
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 687b34e387ac..c9b44ab4af07 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -471,3 +471,34 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
471 471
472 return iwl_mvm_send_cmd(mvm, &cmd); 472 return iwl_mvm_send_cmd(mvm, &cmd);
473} 473}
474
475/**
476 * iwl_mvm_update_smps - Get a requst to change the SMPS mode
477 * @req_type: The part of the driver who call for a change.
478 * @smps_requests: The request to change the SMPS mode.
479 *
480 * Get a requst to change the SMPS mode,
481 * and change it according to all other requests in the driver.
482 */
483void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
484 enum iwl_mvm_smps_type_request req_type,
485 enum ieee80211_smps_mode smps_request)
486{
487 struct iwl_mvm_vif *mvmvif;
488 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
489 int i;
490
491 lockdep_assert_held(&mvm->mutex);
492 mvmvif = iwl_mvm_vif_from_mac80211(vif);
493 mvmvif->smps_requests[req_type] = smps_request;
494 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
495 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
496 smps_mode = IEEE80211_SMPS_STATIC;
497 break;
498 }
499 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
500 smps_mode = IEEE80211_SMPS_DYNAMIC;
501 }
502
503 ieee80211_request_smps(vif, smps_mode);
504}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 8cb53ec2b77b..db7bdd35a9c5 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -256,10 +256,54 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
256 256
257/* 7000 Series */ 257/* 7000 Series */
258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, 258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
259 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_2ac_cfg)}, 259 {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
261 {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
262 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
263 {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
264 {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
265 {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
266 {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
267 {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
268 {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
269 {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
270 {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
271 {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
272 {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg)},
273 {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg)},
274 {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg)},
275 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
276 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
277 {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, 278 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
261 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)}, 279 {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
262 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)}, 280 {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
281 {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
282 {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
283 {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
284 {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
285 {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
286 {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
287 {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
288 {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
289 {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
290 {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
291 {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
292 {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
293
294/* 3160 Series */
295 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
296 {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
297 {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
298 {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
299 {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
301 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
302 {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
303 {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
304 {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
305 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
306 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
263 307
264 {0} 308 {0}
265}; 309};
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 50ba0a468f94..0b021305eedf 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -405,20 +405,27 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
405{ 405{
406 u8 *v_addr; 406 u8 *v_addr;
407 dma_addr_t p_addr; 407 dma_addr_t p_addr;
408 u32 offset; 408 u32 offset, chunk_sz = section->len;
409 int ret = 0; 409 int ret = 0;
410 410
411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", 411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
412 section_num); 412 section_num);
413 413
414 v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL); 414 v_addr = dma_alloc_coherent(trans->dev, chunk_sz, &p_addr,
415 if (!v_addr) 415 GFP_KERNEL | __GFP_NOWARN);
416 return -ENOMEM; 416 if (!v_addr) {
417 IWL_DEBUG_INFO(trans, "Falling back to small chunks of DMA\n");
418 chunk_sz = PAGE_SIZE;
419 v_addr = dma_alloc_coherent(trans->dev, chunk_sz,
420 &p_addr, GFP_KERNEL);
421 if (!v_addr)
422 return -ENOMEM;
423 }
417 424
418 for (offset = 0; offset < section->len; offset += PAGE_SIZE) { 425 for (offset = 0; offset < section->len; offset += chunk_sz) {
419 u32 copy_size; 426 u32 copy_size;
420 427
421 copy_size = min_t(u32, PAGE_SIZE, section->len - offset); 428 copy_size = min_t(u32, chunk_sz, section->len - offset);
422 429
423 memcpy(v_addr, (u8 *)section->data + offset, copy_size); 430 memcpy(v_addr, (u8 *)section->data + offset, copy_size);
424 ret = iwl_pcie_load_firmware_chunk(trans, 431 ret = iwl_pcie_load_firmware_chunk(trans,
@@ -432,7 +439,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
432 } 439 }
433 } 440 }
434 441
435 dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr); 442 dma_free_coherent(trans->dev, chunk_sz, v_addr, p_addr);
436 return ret; 443 return ret;
437} 444}
438 445
@@ -573,10 +580,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
573 580
574static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans) 581static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
575{ 582{
576 /* let the ucode operate on its own */
577 iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
578 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
579
580 iwl_disable_interrupts(trans); 583 iwl_disable_interrupts(trans);
581 iwl_pcie_disable_ict(trans); 584 iwl_pcie_disable_ict(trans);
582 585
@@ -636,9 +639,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
636 return ret; 639 return ret;
637 } 640 }
638 641
639 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
640 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
641
642 *status = IWL_D3_STATUS_ALIVE; 642 *status = IWL_D3_STATUS_ALIVE;
643 return 0; 643 return 0;
644} 644}
@@ -917,11 +917,11 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
917} 917}
918 918
919static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, 919static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
920 void *buf, int dwords) 920 const void *buf, int dwords)
921{ 921{
922 unsigned long flags; 922 unsigned long flags;
923 int offs, ret = 0; 923 int offs, ret = 0;
924 u32 *vals = buf; 924 const u32 *vals = buf;
925 925
926 if (iwl_trans_grab_nic_access(trans, false, &flags)) { 926 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
927 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 927 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 2878ee99a668..a35c6aefbc3e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1045,6 +1045,10 @@ static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); 1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1046} 1046}
1047 1047
1048/* Receiver address (actually, Rx station's index into station table),
1049 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1050#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1051
1048void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 1052void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
1049 int sta_id, int tid, int frame_limit, u16 ssn) 1053 int sta_id, int tid, int frame_limit, u16 ssn)
1050{ 1054{
@@ -1518,6 +1522,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1518 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { 1522 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
1519 IWL_ERR(trans, "FW error in SYNC CMD %s\n", 1523 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
1520 get_cmd_string(trans_pcie, cmd->id)); 1524 get_cmd_string(trans_pcie, cmd->id));
1525 dump_stack();
1521 ret = -EIO; 1526 ret = -EIO;
1522 goto cancel; 1527 goto cancel;
1523 } 1528 }
@@ -1564,7 +1569,8 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1564 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) 1569 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1565 return -EIO; 1570 return -EIO;
1566 1571
1567 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1572 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1573 test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1568 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", 1574 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1569 cmd->id); 1575 cmd->id);
1570 return -ERFKILL; 1576 return -ERFKILL;
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 4f614aad9ded..f7ff4725506a 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -3,13 +3,13 @@ config MWIFIEX
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This adds support for wireless adapters based on Marvell 5 This adds support for wireless adapters based on Marvell
6 802.11n chipsets. 6 802.11n/ac chipsets.
7 7
8 If you choose to build it as a module, it will be called 8 If you choose to build it as a module, it will be called
9 mwifiex. 9 mwifiex.
10 10
11config MWIFIEX_SDIO 11config MWIFIEX_SDIO
12 tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797" 12 tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8897"
13 depends on MWIFIEX && MMC 13 depends on MWIFIEX && MMC
14 select FW_LOADER 14 select FW_LOADER
15 ---help--- 15 ---help---
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 60077895adff..856aea25052b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1231,6 +1231,51 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1231 return 0; 1231 return 0;
1232} 1232}
1233 1233
1234/* cfg80211 operation handler for del_station.
1235 * Function deauthenticates station which value is provided in mac parameter.
1236 * If mac is NULL/broadcast, all stations in associated station list are
1237 * deauthenticated. If bss is not started or there are no stations in
1238 * associated stations list, no action is taken.
1239 */
1240static int
1241mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1242 u8 *mac)
1243{
1244 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1245 struct mwifiex_sta_node *sta_node;
1246 unsigned long flags;
1247
1248 if (list_empty(&priv->sta_list) || !priv->bss_started)
1249 return 0;
1250
1251 if (!mac || is_broadcast_ether_addr(mac)) {
1252 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1253 list_for_each_entry(sta_node, &priv->sta_list, list) {
1254 if (mwifiex_send_cmd_sync(priv,
1255 HostCmd_CMD_UAP_STA_DEAUTH,
1256 HostCmd_ACT_GEN_SET, 0,
1257 sta_node->mac_addr))
1258 return -1;
1259 mwifiex_uap_del_sta_data(priv, sta_node);
1260 }
1261 } else {
1262 wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
1263 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1264 sta_node = mwifiex_get_sta_entry(priv, mac);
1265 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1266 if (sta_node) {
1267 if (mwifiex_send_cmd_sync(priv,
1268 HostCmd_CMD_UAP_STA_DEAUTH,
1269 HostCmd_ACT_GEN_SET, 0,
1270 sta_node->mac_addr))
1271 return -1;
1272 mwifiex_uap_del_sta_data(priv, sta_node);
1273 }
1274 }
1275
1276 return 0;
1277}
1278
1234static int 1279static int
1235mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 1280mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1236{ 1281{
@@ -1859,6 +1904,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1859 int i, offset, ret; 1904 int i, offset, ret;
1860 struct ieee80211_channel *chan; 1905 struct ieee80211_channel *chan;
1861 struct ieee_types_header *ie; 1906 struct ieee_types_header *ie;
1907 struct mwifiex_user_scan_cfg *user_scan_cfg;
1862 1908
1863 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1909 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1864 1910
@@ -1869,20 +1915,22 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1869 return -EBUSY; 1915 return -EBUSY;
1870 } 1916 }
1871 1917
1872 if (priv->user_scan_cfg) { 1918 /* Block scan request if scan operation or scan cleanup when interface
1919 * is disabled is in process
1920 */
1921 if (priv->scan_request || priv->scan_aborting) {
1873 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n"); 1922 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
1874 return -EBUSY; 1923 return -EBUSY;
1875 } 1924 }
1876 1925
1877 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), 1926 user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
1878 GFP_KERNEL); 1927 if (!user_scan_cfg)
1879 if (!priv->user_scan_cfg)
1880 return -ENOMEM; 1928 return -ENOMEM;
1881 1929
1882 priv->scan_request = request; 1930 priv->scan_request = request;
1883 1931
1884 priv->user_scan_cfg->num_ssids = request->n_ssids; 1932 user_scan_cfg->num_ssids = request->n_ssids;
1885 priv->user_scan_cfg->ssid_list = request->ssids; 1933 user_scan_cfg->ssid_list = request->ssids;
1886 1934
1887 if (request->ie && request->ie_len) { 1935 if (request->ie && request->ie_len) {
1888 offset = 0; 1936 offset = 0;
@@ -1902,25 +1950,25 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1902 for (i = 0; i < min_t(u32, request->n_channels, 1950 for (i = 0; i < min_t(u32, request->n_channels,
1903 MWIFIEX_USER_SCAN_CHAN_MAX); i++) { 1951 MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
1904 chan = request->channels[i]; 1952 chan = request->channels[i];
1905 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1953 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1906 priv->user_scan_cfg->chan_list[i].radio_type = chan->band; 1954 user_scan_cfg->chan_list[i].radio_type = chan->band;
1907 1955
1908 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1956 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
1909 priv->user_scan_cfg->chan_list[i].scan_type = 1957 user_scan_cfg->chan_list[i].scan_type =
1910 MWIFIEX_SCAN_TYPE_PASSIVE; 1958 MWIFIEX_SCAN_TYPE_PASSIVE;
1911 else 1959 else
1912 priv->user_scan_cfg->chan_list[i].scan_type = 1960 user_scan_cfg->chan_list[i].scan_type =
1913 MWIFIEX_SCAN_TYPE_ACTIVE; 1961 MWIFIEX_SCAN_TYPE_ACTIVE;
1914 1962
1915 priv->user_scan_cfg->chan_list[i].scan_time = 0; 1963 user_scan_cfg->chan_list[i].scan_time = 0;
1916 } 1964 }
1917 1965
1918 ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); 1966 ret = mwifiex_scan_networks(priv, user_scan_cfg);
1967 kfree(user_scan_cfg);
1919 if (ret) { 1968 if (ret) {
1920 dev_err(priv->adapter->dev, "scan failed: %d\n", ret); 1969 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1970 priv->scan_aborting = false;
1921 priv->scan_request = NULL; 1971 priv->scan_request = NULL;
1922 kfree(priv->user_scan_cfg);
1923 priv->user_scan_cfg = NULL;
1924 return ret; 1972 return ret;
1925 } 1973 }
1926 1974
@@ -2419,6 +2467,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2419 .change_beacon = mwifiex_cfg80211_change_beacon, 2467 .change_beacon = mwifiex_cfg80211_change_beacon,
2420 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, 2468 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
2421 .set_antenna = mwifiex_cfg80211_set_antenna, 2469 .set_antenna = mwifiex_cfg80211_set_antenna,
2470 .del_station = mwifiex_cfg80211_del_station,
2422#ifdef CONFIG_PM 2471#ifdef CONFIG_PM
2423 .suspend = mwifiex_cfg80211_suspend, 2472 .suspend = mwifiex_cfg80211_suspend,
2424 .resume = mwifiex_cfg80211_resume, 2473 .resume = mwifiex_cfg80211_resume,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 26755d9acb55..2d761477d15e 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -570,6 +570,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
570 case HostCmd_CMD_UAP_SYS_CONFIG: 570 case HostCmd_CMD_UAP_SYS_CONFIG:
571 case HostCmd_CMD_UAP_BSS_START: 571 case HostCmd_CMD_UAP_BSS_START:
572 case HostCmd_CMD_UAP_BSS_STOP: 572 case HostCmd_CMD_UAP_BSS_STOP:
573 case HostCmd_CMD_UAP_STA_DEAUTH:
573 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, 574 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
574 cmd_oid, data_buf, 575 cmd_oid, data_buf,
575 cmd_ptr); 576 cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1f7578d553ec..d6ada7354c14 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -271,6 +271,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
271#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075 271#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075
272#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f 272#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
273#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 273#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
274#define HostCmd_CMD_CFG_DATA 0x008f
274#define HostCmd_CMD_VERSION_EXT 0x0097 275#define HostCmd_CMD_VERSION_EXT 0x0097
275#define HostCmd_CMD_MEF_CFG 0x009a 276#define HostCmd_CMD_MEF_CFG 0x009a
276#define HostCmd_CMD_RSSI_INFO 0x00a4 277#define HostCmd_CMD_RSSI_INFO 0x00a4
@@ -279,6 +280,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
279#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0 280#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
280#define HostCmd_CMD_UAP_BSS_START 0x00b1 281#define HostCmd_CMD_UAP_BSS_START 0x00b1
281#define HostCmd_CMD_UAP_BSS_STOP 0x00b2 282#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
283#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5
282#define HostCmd_CMD_11N_CFG 0x00cd 284#define HostCmd_CMD_11N_CFG 0x00cd
283#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce 285#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
284#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf 286#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
@@ -464,6 +466,8 @@ enum P2P_MODES {
464#define MWIFIEX_CRITERIA_UNICAST BIT(1) 466#define MWIFIEX_CRITERIA_UNICAST BIT(1)
465#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 467#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
466 468
469#define CFG_DATA_TYPE_CAL 2
470
467struct mwifiex_ie_types_header { 471struct mwifiex_ie_types_header {
468 __le16 type; 472 __le16 type;
469 __le16 len; 473 __le16 len;
@@ -1197,6 +1201,11 @@ struct host_cmd_ds_amsdu_aggr_ctrl {
1197 __le16 curr_buf_size; 1201 __le16 curr_buf_size;
1198} __packed; 1202} __packed;
1199 1203
1204struct host_cmd_ds_sta_deauth {
1205 u8 mac[ETH_ALEN];
1206 __le16 reason;
1207} __packed;
1208
1200struct mwifiex_ie_types_wmm_param_set { 1209struct mwifiex_ie_types_wmm_param_set {
1201 struct mwifiex_ie_types_header header; 1210 struct mwifiex_ie_types_header header;
1202 u8 wmm_ie[1]; 1211 u8 wmm_ie[1];
@@ -1573,6 +1582,12 @@ struct mwifiex_ie_list {
1573 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX]; 1582 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
1574} __packed; 1583} __packed;
1575 1584
1585struct host_cmd_ds_802_11_cfg_data {
1586 __le16 action;
1587 __le16 type;
1588 __le16 data_len;
1589} __packed;
1590
1576struct host_cmd_ds_command { 1591struct host_cmd_ds_command {
1577 __le16 command; 1592 __le16 command;
1578 __le16 size; 1593 __le16 size;
@@ -1630,7 +1645,9 @@ struct host_cmd_ds_command {
1630 struct host_cmd_ds_802_11_eeprom_access eeprom; 1645 struct host_cmd_ds_802_11_eeprom_access eeprom;
1631 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1646 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1632 struct host_cmd_ds_sys_config uap_sys_config; 1647 struct host_cmd_ds_sys_config uap_sys_config;
1648 struct host_cmd_ds_sta_deauth sta_deauth;
1633 struct host_cmd_11ac_vht_cfg vht_cfg; 1649 struct host_cmd_11ac_vht_cfg vht_cfg;
1650 struct host_cmd_ds_802_11_cfg_data cfg_data;
1634 } params; 1651 } params;
1635} __packed; 1652} __packed;
1636 1653
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 9f44fda19db9..c7f11c0c3bb7 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -59,6 +59,9 @@ static void scan_delay_timer_fn(unsigned long data)
59 struct cmd_ctrl_node *cmd_node, *tmp_node; 59 struct cmd_ctrl_node *cmd_node, *tmp_node;
60 unsigned long flags; 60 unsigned long flags;
61 61
62 if (adapter->surprise_removed)
63 return;
64
62 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { 65 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
63 /* 66 /*
64 * Abort scan operation by cancelling all pending scan 67 * Abort scan operation by cancelling all pending scan
@@ -78,19 +81,13 @@ static void scan_delay_timer_fn(unsigned long data)
78 adapter->empty_tx_q_cnt = 0; 81 adapter->empty_tx_q_cnt = 0;
79 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 82 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
80 83
81 if (priv->user_scan_cfg) { 84 if (priv->scan_request) {
82 if (priv->scan_request) { 85 dev_dbg(adapter->dev, "info: aborting scan\n");
83 dev_dbg(priv->adapter->dev, 86 cfg80211_scan_done(priv->scan_request, 1);
84 "info: aborting scan\n"); 87 priv->scan_request = NULL;
85 cfg80211_scan_done(priv->scan_request, 1); 88 } else {
86 priv->scan_request = NULL; 89 priv->scan_aborting = false;
87 } else { 90 dev_dbg(adapter->dev, "info: scan already aborted\n");
88 dev_dbg(priv->adapter->dev,
89 "info: scan already aborted\n");
90 }
91
92 kfree(priv->user_scan_cfg);
93 priv->user_scan_cfg = NULL;
94 } 91 }
95 goto done; 92 goto done;
96 } 93 }
@@ -447,23 +444,29 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
447} 444}
448 445
449/* 446/*
450 * This function frees the adapter structure. 447 * This function performs cleanup for adapter structure.
451 * 448 *
452 * The freeing operation is done recursively, by canceling all 449 * The cleanup is done recursively, by canceling all pending
453 * pending commands, freeing the member buffers previously 450 * commands, freeing the member buffers previously allocated
454 * allocated (command buffers, scan table buffer, sleep confirm 451 * (command buffers, scan table buffer, sleep confirm command
455 * command buffer), stopping the timers and calling the cleanup 452 * buffer), stopping the timers and calling the cleanup routines
456 * routines for every interface, before the actual adapter 453 * for every interface.
457 * structure is freed.
458 */ 454 */
459static void 455static void
460mwifiex_free_adapter(struct mwifiex_adapter *adapter) 456mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
461{ 457{
458 int i;
459
462 if (!adapter) { 460 if (!adapter) {
463 pr_err("%s: adapter is NULL\n", __func__); 461 pr_err("%s: adapter is NULL\n", __func__);
464 return; 462 return;
465 } 463 }
466 464
465 for (i = 0; i < adapter->priv_num; i++) {
466 if (adapter->priv[i])
467 del_timer_sync(&adapter->priv[i]->scan_delay_timer);
468 }
469
467 mwifiex_cancel_all_pending_cmd(adapter); 470 mwifiex_cancel_all_pending_cmd(adapter);
468 471
469 /* Free lock variables */ 472 /* Free lock variables */
@@ -684,7 +687,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
684 int ret = -EINPROGRESS; 687 int ret = -EINPROGRESS;
685 struct mwifiex_private *priv; 688 struct mwifiex_private *priv;
686 s32 i; 689 s32 i;
687 unsigned long flags;
688 struct sk_buff *skb; 690 struct sk_buff *skb;
689 691
690 /* mwifiex already shutdown */ 692 /* mwifiex already shutdown */
@@ -719,7 +721,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
719 } 721 }
720 } 722 }
721 723
722 spin_lock_irqsave(&adapter->mwifiex_lock, flags); 724 spin_lock(&adapter->mwifiex_lock);
723 725
724 if (adapter->if_ops.data_complete) { 726 if (adapter->if_ops.data_complete) {
725 while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { 727 while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) {
@@ -733,10 +735,9 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
733 } 735 }
734 } 736 }
735 737
736 /* Free adapter structure */ 738 mwifiex_adapter_cleanup(adapter);
737 mwifiex_free_adapter(adapter);
738 739
739 spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); 740 spin_unlock(&adapter->mwifiex_lock);
740 741
741 /* Notify completion */ 742 /* Notify completion */
742 ret = mwifiex_shutdown_fw_complete(adapter); 743 ret = mwifiex_shutdown_fw_complete(adapter);
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 6bcb66e6e97c..122175af18c6 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -919,9 +919,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
919 memcpy(&priv->curr_bss_params.data_rates, 919 memcpy(&priv->curr_bss_params.data_rates,
920 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); 920 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
921 921
922 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", 922 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%4ph\n",
923 adhoc_start->data_rate[0], adhoc_start->data_rate[1], 923 adhoc_start->data_rate);
924 adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
925 924
926 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); 925 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
927 926
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 2eb88ea9acf7..5bc7ef8d04d6 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -25,6 +25,8 @@
25#define VERSION "1.0" 25#define VERSION "1.0"
26 26
27const char driver_version[] = "mwifiex " VERSION " (%s) "; 27const char driver_version[] = "mwifiex " VERSION " (%s) ";
28static char *cal_data_cfg;
29module_param(cal_data_cfg, charp, 0);
28 30
29/* 31/*
30 * This function registers the device and performs all the necessary 32 * This function registers the device and performs all the necessary
@@ -336,6 +338,13 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
336 338
337 dev_notice(adapter->dev, "WLAN FW is active\n"); 339 dev_notice(adapter->dev, "WLAN FW is active\n");
338 340
341 if (cal_data_cfg) {
342 if ((request_firmware(&adapter->cal_data, cal_data_cfg,
343 adapter->dev)) < 0)
344 dev_err(adapter->dev,
345 "Cal data request_firmware() failed\n");
346 }
347
339 adapter->init_wait_q_woken = false; 348 adapter->init_wait_q_woken = false;
340 ret = mwifiex_init_fw(adapter); 349 ret = mwifiex_init_fw(adapter);
341 if (ret == -1) { 350 if (ret == -1) {
@@ -390,6 +399,10 @@ err_init_fw:
390 pr_debug("info: %s: unregister device\n", __func__); 399 pr_debug("info: %s: unregister device\n", __func__);
391 adapter->if_ops.unregister_dev(adapter); 400 adapter->if_ops.unregister_dev(adapter);
392done: 401done:
402 if (adapter->cal_data) {
403 release_firmware(adapter->cal_data);
404 adapter->cal_data = NULL;
405 }
393 release_firmware(adapter->firmware); 406 release_firmware(adapter->firmware);
394 complete(&adapter->fw_load); 407 complete(&adapter->fw_load);
395 return; 408 return;
@@ -436,6 +449,7 @@ mwifiex_close(struct net_device *dev)
436 dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n"); 449 dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n");
437 cfg80211_scan_done(priv->scan_request, 1); 450 cfg80211_scan_done(priv->scan_request, 1);
438 priv->scan_request = NULL; 451 priv->scan_request = NULL;
452 priv->scan_aborting = true;
439 } 453 }
440 454
441 return 0; 455 return 0;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 4ef67fca06d3..0832c2437daf 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -492,7 +492,6 @@ struct mwifiex_private {
492 struct semaphore async_sem; 492 struct semaphore async_sem;
493 u8 report_scan_result; 493 u8 report_scan_result;
494 struct cfg80211_scan_request *scan_request; 494 struct cfg80211_scan_request *scan_request;
495 struct mwifiex_user_scan_cfg *user_scan_cfg;
496 u8 cfg_bssid[6]; 495 u8 cfg_bssid[6];
497 struct wps wps; 496 struct wps wps;
498 u8 scan_block; 497 u8 scan_block;
@@ -510,6 +509,7 @@ struct mwifiex_private {
510 u8 ap_11ac_enabled; 509 u8 ap_11ac_enabled;
511 u32 mgmt_frame_mask; 510 u32 mgmt_frame_mask;
512 struct mwifiex_roc_cfg roc_cfg; 511 struct mwifiex_roc_cfg roc_cfg;
512 bool scan_aborting;
513}; 513};
514 514
515enum mwifiex_ba_status { 515enum mwifiex_ba_status {
@@ -730,6 +730,7 @@ struct mwifiex_adapter {
730 u16 max_mgmt_ie_index; 730 u16 max_mgmt_ie_index;
731 u8 scan_delay_cnt; 731 u8 scan_delay_cnt;
732 u8 empty_tx_q_cnt; 732 u8 empty_tx_q_cnt;
733 const struct firmware *cal_data;
733 734
734 /* 11AC */ 735 /* 11AC */
735 u32 is_hw_11ac_capable; 736 u32 is_hw_11ac_capable;
@@ -1115,6 +1116,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1115 struct cfg80211_beacon_data *data); 1116 struct cfg80211_beacon_data *data);
1116int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1117int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1117u8 *mwifiex_11d_code_2_region(u8 code); 1118u8 *mwifiex_11d_code_2_region(u8 code);
1119void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
1120 struct mwifiex_sta_node *node);
1118 1121
1119extern const struct ethtool_ops mwifiex_ethtool_ops; 1122extern const struct ethtool_ops mwifiex_ethtool_ops;
1120 1123
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 9cf5d8f07df8..801b6b728379 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1784,22 +1784,17 @@ check_next_scan:
1784 if (priv->report_scan_result) 1784 if (priv->report_scan_result)
1785 priv->report_scan_result = false; 1785 priv->report_scan_result = false;
1786 1786
1787 if (priv->user_scan_cfg) { 1787 if (priv->scan_request) {
1788 if (priv->scan_request) { 1788 dev_dbg(adapter->dev, "info: notifying scan done\n");
1789 dev_dbg(priv->adapter->dev, 1789 cfg80211_scan_done(priv->scan_request, 0);
1790 "info: notifying scan done\n"); 1790 priv->scan_request = NULL;
1791 cfg80211_scan_done(priv->scan_request, 0); 1791 } else {
1792 priv->scan_request = NULL; 1792 priv->scan_aborting = false;
1793 } else { 1793 dev_dbg(adapter->dev, "info: scan already aborted\n");
1794 dev_dbg(priv->adapter->dev,
1795 "info: scan already aborted\n");
1796 }
1797
1798 kfree(priv->user_scan_cfg);
1799 priv->user_scan_cfg = NULL;
1800 } 1794 }
1801 } else { 1795 } else {
1802 if (priv->user_scan_cfg && !priv->scan_request) { 1796 if ((priv->scan_aborting && !priv->scan_request) ||
1797 priv->scan_block) {
1803 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1798 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1804 flags); 1799 flags);
1805 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT; 1800 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 363ba31b58bf..5ee5ed02eccd 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -77,6 +77,17 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
77 77
78 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 78 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
79 79
80 if (id->driver_data) {
81 struct mwifiex_sdio_device *data = (void *)id->driver_data;
82
83 card->firmware = data->firmware;
84 card->reg = data->reg;
85 card->max_ports = data->max_ports;
86 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
87 card->supports_sdio_new_mode = data->supports_sdio_new_mode;
88 card->has_control_mask = data->has_control_mask;
89 }
90
80 sdio_claim_host(func); 91 sdio_claim_host(func);
81 ret = sdio_enable_func(func); 92 ret = sdio_enable_func(func);
82 sdio_release_host(func); 93 sdio_release_host(func);
@@ -251,12 +262,19 @@ static int mwifiex_sdio_resume(struct device *dev)
251#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) 262#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119)
252/* Device ID for SD8797 */ 263/* Device ID for SD8797 */
253#define SDIO_DEVICE_ID_MARVELL_8797 (0x9129) 264#define SDIO_DEVICE_ID_MARVELL_8797 (0x9129)
265/* Device ID for SD8897 */
266#define SDIO_DEVICE_ID_MARVELL_8897 (0x912d)
254 267
255/* WLAN IDs */ 268/* WLAN IDs */
256static const struct sdio_device_id mwifiex_ids[] = { 269static const struct sdio_device_id mwifiex_ids[] = {
257 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786)}, 270 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786),
258 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)}, 271 .driver_data = (unsigned long) &mwifiex_sdio_sd8786},
259 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)}, 272 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787),
273 .driver_data = (unsigned long) &mwifiex_sdio_sd8787},
274 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797),
275 .driver_data = (unsigned long) &mwifiex_sdio_sd8797},
276 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897),
277 .driver_data = (unsigned long) &mwifiex_sdio_sd8897},
260 {}, 278 {},
261}; 279};
262 280
@@ -282,13 +300,13 @@ static struct sdio_driver mwifiex_sdio = {
282 * This function writes data into SDIO card register. 300 * This function writes data into SDIO card register.
283 */ 301 */
284static int 302static int
285mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data) 303mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
286{ 304{
287 struct sdio_mmc_card *card = adapter->card; 305 struct sdio_mmc_card *card = adapter->card;
288 int ret = -1; 306 int ret = -1;
289 307
290 sdio_claim_host(card->func); 308 sdio_claim_host(card->func);
291 sdio_writeb(card->func, (u8) data, reg, &ret); 309 sdio_writeb(card->func, data, reg, &ret);
292 sdio_release_host(card->func); 310 sdio_release_host(card->func);
293 311
294 return ret; 312 return ret;
@@ -298,7 +316,7 @@ mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
298 * This function reads data from SDIO card register. 316 * This function reads data from SDIO card register.
299 */ 317 */
300static int 318static int
301mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) 319mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
302{ 320{
303 struct sdio_mmc_card *card = adapter->card; 321 struct sdio_mmc_card *card = adapter->card;
304 int ret = -1; 322 int ret = -1;
@@ -400,7 +418,40 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
400} 418}
401 419
402/* 420/*
403 * This function initializes the IO ports. 421 * This function is used to initialize IO ports for the
422 * chipsets supporting SDIO new mode eg SD8897.
423 */
424static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter)
425{
426 u8 reg;
427
428 adapter->ioport = MEM_PORT;
429
430 /* enable sdio new mode */
431 if (mwifiex_read_reg(adapter, CARD_CONFIG_2_1_REG, &reg))
432 return -1;
433 if (mwifiex_write_reg(adapter, CARD_CONFIG_2_1_REG,
434 reg | CMD53_NEW_MODE))
435 return -1;
436
437 /* Configure cmd port and enable reading rx length from the register */
438 if (mwifiex_read_reg(adapter, CMD_CONFIG_0, &reg))
439 return -1;
440 if (mwifiex_write_reg(adapter, CMD_CONFIG_0, reg | CMD_PORT_RD_LEN_EN))
441 return -1;
442
443 /* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is
444 * completed
445 */
446 if (mwifiex_read_reg(adapter, CMD_CONFIG_1, &reg))
447 return -1;
448 if (mwifiex_write_reg(adapter, CMD_CONFIG_1, reg | CMD_PORT_AUTO_EN))
449 return -1;
450
451 return 0;
452}
453
454/* This function initializes the IO ports.
404 * 455 *
405 * The following operations are performed - 456 * The following operations are performed -
406 * - Read the IO ports (0, 1 and 2) 457 * - Read the IO ports (0, 1 and 2)
@@ -409,10 +460,17 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
409 */ 460 */
410static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter) 461static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
411{ 462{
412 u32 reg; 463 u8 reg;
464 struct sdio_mmc_card *card = adapter->card;
413 465
414 adapter->ioport = 0; 466 adapter->ioport = 0;
415 467
468 if (card->supports_sdio_new_mode) {
469 if (mwifiex_init_sdio_new_mode(adapter))
470 return -1;
471 goto cont;
472 }
473
416 /* Read the IO port */ 474 /* Read the IO port */
417 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg)) 475 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
418 adapter->ioport |= (reg & 0xff); 476 adapter->ioport |= (reg & 0xff);
@@ -428,19 +486,19 @@ static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
428 adapter->ioport |= ((reg & 0xff) << 16); 486 adapter->ioport |= ((reg & 0xff) << 16);
429 else 487 else
430 return -1; 488 return -1;
431 489cont:
432 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport); 490 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
433 491
434 /* Set Host interrupt reset to read to clear */ 492 /* Set Host interrupt reset to read to clear */
435 if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg)) 493 if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
436 mwifiex_write_reg(adapter, HOST_INT_RSR_REG, 494 mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
437 reg | SDIO_INT_MASK); 495 reg | card->reg->sdio_int_mask);
438 else 496 else
439 return -1; 497 return -1;
440 498
441 /* Dnld/Upld ready set to auto reset */ 499 /* Dnld/Upld ready set to auto reset */
442 if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg)) 500 if (!mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, &reg))
443 mwifiex_write_reg(adapter, CARD_MISC_CFG_REG, 501 mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,
444 reg | AUTO_RE_ENABLE_INT); 502 reg | AUTO_RE_ENABLE_INT);
445 else 503 else
446 return -1; 504 return -1;
@@ -486,34 +544,42 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
486static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) 544static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
487{ 545{
488 struct sdio_mmc_card *card = adapter->card; 546 struct sdio_mmc_card *card = adapter->card;
489 u16 rd_bitmap = card->mp_rd_bitmap; 547 const struct mwifiex_sdio_card_reg *reg = card->reg;
548 u32 rd_bitmap = card->mp_rd_bitmap;
490 549
491 dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap); 550 dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);
492 551
493 if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK))) 552 if (card->supports_sdio_new_mode) {
494 return -1; 553 if (!(rd_bitmap & reg->data_port_mask))
554 return -1;
555 } else {
556 if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask)))
557 return -1;
558 }
495 559
496 if (card->mp_rd_bitmap & CTRL_PORT_MASK) { 560 if ((card->has_control_mask) &&
497 card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); 561 (card->mp_rd_bitmap & CTRL_PORT_MASK)) {
562 card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK);
498 *port = CTRL_PORT; 563 *port = CTRL_PORT;
499 dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", 564 dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
500 *port, card->mp_rd_bitmap); 565 *port, card->mp_rd_bitmap);
501 } else { 566 return 0;
502 if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { 567 }
503 card->mp_rd_bitmap &= (u16)
504 (~(1 << card->curr_rd_port));
505 *port = card->curr_rd_port;
506 568
507 if (++card->curr_rd_port == MAX_PORT) 569 if (!(card->mp_rd_bitmap & (1 << card->curr_rd_port)))
508 card->curr_rd_port = 1; 570 return -1;
509 } else { 571
510 return -1; 572 /* We are now handling the SDIO data ports */
511 } 573 card->mp_rd_bitmap &= (u32)(~(1 << card->curr_rd_port));
574 *port = card->curr_rd_port;
575
576 if (++card->curr_rd_port == card->max_ports)
577 card->curr_rd_port = reg->start_rd_port;
578
579 dev_dbg(adapter->dev,
580 "data: port=%d mp_rd_bitmap=0x%08x -> 0x%08x\n",
581 *port, rd_bitmap, card->mp_rd_bitmap);
512 582
513 dev_dbg(adapter->dev,
514 "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
515 *port, rd_bitmap, card->mp_rd_bitmap);
516 }
517 return 0; 583 return 0;
518} 584}
519 585
@@ -524,35 +590,45 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
524 * increased (provided it does not reach the maximum limit, in which 590 * increased (provided it does not reach the maximum limit, in which
525 * case it is reset to 1) 591 * case it is reset to 1)
526 */ 592 */
527static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) 593static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
528{ 594{
529 struct sdio_mmc_card *card = adapter->card; 595 struct sdio_mmc_card *card = adapter->card;
530 u16 wr_bitmap = card->mp_wr_bitmap; 596 const struct mwifiex_sdio_card_reg *reg = card->reg;
597 u32 wr_bitmap = card->mp_wr_bitmap;
531 598
532 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap); 599 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
533 600
534 if (!(wr_bitmap & card->mp_data_port_mask)) 601 if (card->supports_sdio_new_mode &&
602 !(wr_bitmap & reg->data_port_mask)) {
603 adapter->data_sent = true;
604 return -EBUSY;
605 } else if (!card->supports_sdio_new_mode &&
606 !(wr_bitmap & card->mp_data_port_mask)) {
535 return -1; 607 return -1;
608 }
536 609
537 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { 610 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
538 card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port)); 611 card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
539 *port = card->curr_wr_port; 612 *port = card->curr_wr_port;
540 if (++card->curr_wr_port == card->mp_end_port) 613 if (((card->supports_sdio_new_mode) &&
541 card->curr_wr_port = 1; 614 (++card->curr_wr_port == card->max_ports)) ||
615 ((!card->supports_sdio_new_mode) &&
616 (++card->curr_wr_port == card->mp_end_port)))
617 card->curr_wr_port = reg->start_wr_port;
542 } else { 618 } else {
543 adapter->data_sent = true; 619 adapter->data_sent = true;
544 return -EBUSY; 620 return -EBUSY;
545 } 621 }
546 622
547 if (*port == CTRL_PORT) { 623 if ((card->has_control_mask) && (*port == CTRL_PORT)) {
548 dev_err(adapter->dev, "invalid data port=%d cur port=%d" 624 dev_err(adapter->dev,
549 " mp_wr_bitmap=0x%04x -> 0x%04x\n", 625 "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
550 *port, card->curr_wr_port, wr_bitmap, 626 *port, card->curr_wr_port, wr_bitmap,
551 card->mp_wr_bitmap); 627 card->mp_wr_bitmap);
552 return -1; 628 return -1;
553 } 629 }
554 630
555 dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", 631 dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
556 *port, wr_bitmap, card->mp_wr_bitmap); 632 *port, wr_bitmap, card->mp_wr_bitmap);
557 633
558 return 0; 634 return 0;
@@ -564,11 +640,12 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
564static int 640static int
565mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) 641mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
566{ 642{
643 struct sdio_mmc_card *card = adapter->card;
567 u32 tries; 644 u32 tries;
568 u32 cs; 645 u8 cs;
569 646
570 for (tries = 0; tries < MAX_POLL_TRIES; tries++) { 647 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
571 if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs)) 648 if (mwifiex_read_reg(adapter, card->reg->poll_reg, &cs))
572 break; 649 break;
573 else if ((cs & bits) == bits) 650 else if ((cs & bits) == bits)
574 return 0; 651 return 0;
@@ -587,12 +664,14 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
587static int 664static int
588mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) 665mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
589{ 666{
590 u32 fws0, fws1; 667 struct sdio_mmc_card *card = adapter->card;
668 const struct mwifiex_sdio_card_reg *reg = card->reg;
669 u8 fws0, fws1;
591 670
592 if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0)) 671 if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
593 return -1; 672 return -1;
594 673
595 if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1)) 674 if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))
596 return -1; 675 return -1;
597 676
598 *dat = (u16) ((fws1 << 8) | fws0); 677 *dat = (u16) ((fws1 << 8) | fws0);
@@ -608,14 +687,14 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
608 */ 687 */
609static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) 688static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
610{ 689{
611 u32 host_int_mask; 690 u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
612 691
613 /* Read back the host_int_mask register */ 692 /* Read back the host_int_mask register */
614 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) 693 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
615 return -1; 694 return -1;
616 695
617 /* Update with the mask and write back to the register */ 696 /* Update with the mask and write back to the register */
618 host_int_mask &= ~HOST_INT_DISABLE; 697 host_int_mask &= ~host_int_disable;
619 698
620 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) { 699 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
621 dev_err(adapter->dev, "disable host interrupt failed\n"); 700 dev_err(adapter->dev, "disable host interrupt failed\n");
@@ -633,8 +712,11 @@ static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
633 */ 712 */
634static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) 713static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
635{ 714{
715 struct sdio_mmc_card *card = adapter->card;
716
636 /* Simply write the mask to the register */ 717 /* Simply write the mask to the register */
637 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) { 718 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG,
719 card->reg->host_int_enable)) {
638 dev_err(adapter->dev, "enable host interrupt failed\n"); 720 dev_err(adapter->dev, "enable host interrupt failed\n");
639 return -1; 721 return -1;
640 } 722 }
@@ -686,11 +768,13 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
686static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, 768static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
687 struct mwifiex_fw_image *fw) 769 struct mwifiex_fw_image *fw)
688{ 770{
771 struct sdio_mmc_card *card = adapter->card;
772 const struct mwifiex_sdio_card_reg *reg = card->reg;
689 int ret; 773 int ret;
690 u8 *firmware = fw->fw_buf; 774 u8 *firmware = fw->fw_buf;
691 u32 firmware_len = fw->fw_len; 775 u32 firmware_len = fw->fw_len;
692 u32 offset = 0; 776 u32 offset = 0;
693 u32 base0, base1; 777 u8 base0, base1;
694 u8 *fwbuf; 778 u8 *fwbuf;
695 u16 len = 0; 779 u16 len = 0;
696 u32 txlen, tx_blocks = 0, tries; 780 u32 txlen, tx_blocks = 0, tries;
@@ -727,7 +811,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
727 break; 811 break;
728 812
729 for (tries = 0; tries < MAX_POLL_TRIES; tries++) { 813 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
730 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, 814 ret = mwifiex_read_reg(adapter, reg->base_0_reg,
731 &base0); 815 &base0);
732 if (ret) { 816 if (ret) {
733 dev_err(adapter->dev, 817 dev_err(adapter->dev,
@@ -736,7 +820,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
736 base0, base0); 820 base0, base0);
737 goto done; 821 goto done;
738 } 822 }
739 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, 823 ret = mwifiex_read_reg(adapter, reg->base_1_reg,
740 &base1); 824 &base1);
741 if (ret) { 825 if (ret) {
742 dev_err(adapter->dev, 826 dev_err(adapter->dev,
@@ -828,10 +912,11 @@ done:
828static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, 912static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
829 u32 poll_num) 913 u32 poll_num)
830{ 914{
915 struct sdio_mmc_card *card = adapter->card;
831 int ret = 0; 916 int ret = 0;
832 u16 firmware_stat; 917 u16 firmware_stat;
833 u32 tries; 918 u32 tries;
834 u32 winner_status; 919 u8 winner_status;
835 920
836 /* Wait for firmware initialization event */ 921 /* Wait for firmware initialization event */
837 for (tries = 0; tries < poll_num; tries++) { 922 for (tries = 0; tries < poll_num; tries++) {
@@ -849,7 +934,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
849 934
850 if (ret) { 935 if (ret) {
851 if (mwifiex_read_reg 936 if (mwifiex_read_reg
852 (adapter, CARD_FW_STATUS0_REG, &winner_status)) 937 (adapter, card->reg->status_reg_0, &winner_status))
853 winner_status = 0; 938 winner_status = 0;
854 939
855 if (winner_status) 940 if (winner_status)
@@ -866,12 +951,12 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
866static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) 951static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
867{ 952{
868 struct sdio_mmc_card *card = adapter->card; 953 struct sdio_mmc_card *card = adapter->card;
869 u32 sdio_ireg; 954 u8 sdio_ireg;
870 unsigned long flags; 955 unsigned long flags;
871 956
872 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, 957 if (mwifiex_read_data_sync(adapter, card->mp_regs,
873 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 958 card->reg->max_mp_regs,
874 0)) { 959 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
875 dev_err(adapter->dev, "read mp_regs failed\n"); 960 dev_err(adapter->dev, "read mp_regs failed\n");
876 return; 961 return;
877 } 962 }
@@ -880,6 +965,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
880 if (sdio_ireg) { 965 if (sdio_ireg) {
881 /* 966 /*
882 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS 967 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
968 * For SDIO new mode CMD port interrupts
969 * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
970 * UP_LD_CMD_PORT_HOST_INT_STATUS
883 * Clear the interrupt status register 971 * Clear the interrupt status register
884 */ 972 */
885 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg); 973 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
@@ -1003,11 +1091,11 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1003 s32 f_aggr_cur = 0; 1091 s32 f_aggr_cur = 0;
1004 struct sk_buff *skb_deaggr; 1092 struct sk_buff *skb_deaggr;
1005 u32 pind; 1093 u32 pind;
1006 u32 pkt_len, pkt_type = 0; 1094 u32 pkt_len, pkt_type, mport;
1007 u8 *curr_ptr; 1095 u8 *curr_ptr;
1008 u32 rx_len = skb->len; 1096 u32 rx_len = skb->len;
1009 1097
1010 if (port == CTRL_PORT) { 1098 if ((card->has_control_mask) && (port == CTRL_PORT)) {
1011 /* Read the command Resp without aggr */ 1099 /* Read the command Resp without aggr */
1012 dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " 1100 dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
1013 "response\n", __func__); 1101 "response\n", __func__);
@@ -1024,7 +1112,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1024 goto rx_curr_single; 1112 goto rx_curr_single;
1025 } 1113 }
1026 1114
1027 if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) { 1115 if ((!card->has_control_mask && (card->mp_rd_bitmap &
1116 card->reg->data_port_mask)) ||
1117 (card->has_control_mask && (card->mp_rd_bitmap &
1118 (~((u32) CTRL_PORT_MASK))))) {
1028 /* Some more data RX pending */ 1119 /* Some more data RX pending */
1029 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); 1120 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1030 1121
@@ -1060,10 +1151,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1060 if (f_aggr_cur) { 1151 if (f_aggr_cur) {
1061 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1152 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1062 /* Curr pkt can be aggregated */ 1153 /* Curr pkt can be aggregated */
1063 MP_RX_AGGR_SETUP(card, skb, port); 1154 mp_rx_aggr_setup(card, skb, port);
1064 1155
1065 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || 1156 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1066 MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { 1157 mp_rx_aggr_port_limit_reached(card)) {
1067 dev_dbg(adapter->dev, "info: %s: aggregated packet " 1158 dev_dbg(adapter->dev, "info: %s: aggregated packet "
1068 "limit reached\n", __func__); 1159 "limit reached\n", __func__);
1069 /* No more pkts allowed in Aggr buf, rx it */ 1160 /* No more pkts allowed in Aggr buf, rx it */
@@ -1076,11 +1167,28 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1076 dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", 1167 dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
1077 card->mpa_rx.pkt_cnt); 1168 card->mpa_rx.pkt_cnt);
1078 1169
1170 if (card->supports_sdio_new_mode) {
1171 int i;
1172 u32 port_count;
1173
1174 for (i = 0, port_count = 0; i < card->max_ports; i++)
1175 if (card->mpa_rx.ports & BIT(i))
1176 port_count++;
1177
1178 /* Reading data from "start_port + 0" to "start_port +
1179 * port_count -1", so decrease the count by 1
1180 */
1181 port_count--;
1182 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1183 (port_count << 8)) + card->mpa_rx.start_port;
1184 } else {
1185 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1186 (card->mpa_rx.ports << 4)) +
1187 card->mpa_rx.start_port;
1188 }
1189
1079 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, 1190 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
1080 card->mpa_rx.buf_len, 1191 card->mpa_rx.buf_len, mport, 1))
1081 (adapter->ioport | 0x1000 |
1082 (card->mpa_rx.ports << 4)) +
1083 card->mpa_rx.start_port, 1))
1084 goto error; 1192 goto error;
1085 1193
1086 curr_ptr = card->mpa_rx.buf; 1194 curr_ptr = card->mpa_rx.buf;
@@ -1167,6 +1275,7 @@ error:
1167static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) 1275static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1168{ 1276{
1169 struct sdio_mmc_card *card = adapter->card; 1277 struct sdio_mmc_card *card = adapter->card;
1278 const struct mwifiex_sdio_card_reg *reg = card->reg;
1170 int ret = 0; 1279 int ret = 0;
1171 u8 sdio_ireg; 1280 u8 sdio_ireg;
1172 struct sk_buff *skb; 1281 struct sk_buff *skb;
@@ -1175,6 +1284,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1175 u32 rx_blocks; 1284 u32 rx_blocks;
1176 u16 rx_len; 1285 u16 rx_len;
1177 unsigned long flags; 1286 unsigned long flags;
1287 u32 bitmap;
1288 u8 cr;
1178 1289
1179 spin_lock_irqsave(&adapter->int_lock, flags); 1290 spin_lock_irqsave(&adapter->int_lock, flags);
1180 sdio_ireg = adapter->int_status; 1291 sdio_ireg = adapter->int_status;
@@ -1184,10 +1295,60 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1184 if (!sdio_ireg) 1295 if (!sdio_ireg)
1185 return ret; 1296 return ret;
1186 1297
1298 /* Following interrupt is only for SDIO new mode */
1299 if (sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS && adapter->cmd_sent)
1300 adapter->cmd_sent = false;
1301
1302 /* Following interrupt is only for SDIO new mode */
1303 if (sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) {
1304 u32 pkt_type;
1305
1306 /* read the len of control packet */
1307 rx_len = card->mp_regs[CMD_RD_LEN_1] << 8;
1308 rx_len |= (u16) card->mp_regs[CMD_RD_LEN_0];
1309 rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE);
1310 if (rx_len <= INTF_HEADER_LEN ||
1311 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
1312 MWIFIEX_RX_DATA_BUF_SIZE)
1313 return -1;
1314 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1315
1316 skb = dev_alloc_skb(rx_len);
1317 if (!skb)
1318 return -1;
1319
1320 skb_put(skb, rx_len);
1321
1322 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, skb->data,
1323 skb->len, adapter->ioport |
1324 CMD_PORT_SLCT)) {
1325 dev_err(adapter->dev,
1326 "%s: failed to card_to_host", __func__);
1327 dev_kfree_skb_any(skb);
1328 goto term_cmd;
1329 }
1330
1331 if ((pkt_type != MWIFIEX_TYPE_CMD) &&
1332 (pkt_type != MWIFIEX_TYPE_EVENT))
1333 dev_err(adapter->dev,
1334 "%s:Received wrong packet on cmd port",
1335 __func__);
1336
1337 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
1338 }
1339
1187 if (sdio_ireg & DN_LD_HOST_INT_STATUS) { 1340 if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
1188 card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; 1341 bitmap = (u32) card->mp_regs[reg->wr_bitmap_l];
1189 card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; 1342 bitmap |= ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8;
1190 dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", 1343 if (card->supports_sdio_new_mode) {
1344 bitmap |=
1345 ((u32) card->mp_regs[reg->wr_bitmap_1l]) << 16;
1346 bitmap |=
1347 ((u32) card->mp_regs[reg->wr_bitmap_1u]) << 24;
1348 }
1349 card->mp_wr_bitmap = bitmap;
1350
1351 dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%x\n",
1191 card->mp_wr_bitmap); 1352 card->mp_wr_bitmap);
1192 if (adapter->data_sent && 1353 if (adapter->data_sent &&
1193 (card->mp_wr_bitmap & card->mp_data_port_mask)) { 1354 (card->mp_wr_bitmap & card->mp_data_port_mask)) {
@@ -1200,11 +1361,11 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1200 /* As firmware will not generate download ready interrupt if the port 1361 /* As firmware will not generate download ready interrupt if the port
1201 updated is command port only, cmd_sent should be done for any SDIO 1362 updated is command port only, cmd_sent should be done for any SDIO
1202 interrupt. */ 1363 interrupt. */
1203 if (adapter->cmd_sent) { 1364 if (card->has_control_mask && adapter->cmd_sent) {
1204 /* Check if firmware has attach buffer at command port and 1365 /* Check if firmware has attach buffer at command port and
1205 update just that in wr_bit_map. */ 1366 update just that in wr_bit_map. */
1206 card->mp_wr_bitmap |= 1367 card->mp_wr_bitmap |=
1207 (u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK; 1368 (u32) card->mp_regs[reg->wr_bitmap_l] & CTRL_PORT_MASK;
1208 if (card->mp_wr_bitmap & CTRL_PORT_MASK) 1369 if (card->mp_wr_bitmap & CTRL_PORT_MASK)
1209 adapter->cmd_sent = false; 1370 adapter->cmd_sent = false;
1210 } 1371 }
@@ -1212,9 +1373,16 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1212 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", 1373 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
1213 adapter->cmd_sent, adapter->data_sent); 1374 adapter->cmd_sent, adapter->data_sent);
1214 if (sdio_ireg & UP_LD_HOST_INT_STATUS) { 1375 if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
1215 card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; 1376 bitmap = (u32) card->mp_regs[reg->rd_bitmap_l];
1216 card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; 1377 bitmap |= ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8;
1217 dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", 1378 if (card->supports_sdio_new_mode) {
1379 bitmap |=
1380 ((u32) card->mp_regs[reg->rd_bitmap_1l]) << 16;
1381 bitmap |=
1382 ((u32) card->mp_regs[reg->rd_bitmap_1u]) << 24;
1383 }
1384 card->mp_rd_bitmap = bitmap;
1385 dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%x\n",
1218 card->mp_rd_bitmap); 1386 card->mp_rd_bitmap);
1219 1387
1220 while (true) { 1388 while (true) {
@@ -1224,8 +1392,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1224 "info: no more rd_port available\n"); 1392 "info: no more rd_port available\n");
1225 break; 1393 break;
1226 } 1394 }
1227 len_reg_l = RD_LEN_P0_L + (port << 1); 1395 len_reg_l = reg->rd_len_p0_l + (port << 1);
1228 len_reg_u = RD_LEN_P0_U + (port << 1); 1396 len_reg_u = reg->rd_len_p0_u + (port << 1);
1229 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; 1397 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
1230 rx_len |= (u16) card->mp_regs[len_reg_l]; 1398 rx_len |= (u16) card->mp_regs[len_reg_l];
1231 dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", 1399 dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
@@ -1257,37 +1425,33 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1257 1425
1258 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, 1426 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
1259 port)) { 1427 port)) {
1260 u32 cr = 0;
1261
1262 dev_err(adapter->dev, "card_to_host_mpa failed:" 1428 dev_err(adapter->dev, "card_to_host_mpa failed:"
1263 " int status=%#x\n", sdio_ireg); 1429 " int status=%#x\n", sdio_ireg);
1264 if (mwifiex_read_reg(adapter, 1430 goto term_cmd;
1265 CONFIGURATION_REG, &cr))
1266 dev_err(adapter->dev,
1267 "read CFG reg failed\n");
1268
1269 dev_dbg(adapter->dev,
1270 "info: CFG reg val = %d\n", cr);
1271 if (mwifiex_write_reg(adapter,
1272 CONFIGURATION_REG,
1273 (cr | 0x04)))
1274 dev_err(adapter->dev,
1275 "write CFG reg failed\n");
1276
1277 dev_dbg(adapter->dev, "info: write success\n");
1278 if (mwifiex_read_reg(adapter,
1279 CONFIGURATION_REG, &cr))
1280 dev_err(adapter->dev,
1281 "read CFG reg failed\n");
1282
1283 dev_dbg(adapter->dev,
1284 "info: CFG reg val =%x\n", cr);
1285 return -1;
1286 } 1431 }
1287 } 1432 }
1288 } 1433 }
1289 1434
1290 return 0; 1435 return 0;
1436
1437term_cmd:
1438 /* terminate cmd */
1439 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
1440 dev_err(adapter->dev, "read CFG reg failed\n");
1441 else
1442 dev_dbg(adapter->dev, "info: CFG reg val = %d\n", cr);
1443
1444 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04)))
1445 dev_err(adapter->dev, "write CFG reg failed\n");
1446 else
1447 dev_dbg(adapter->dev, "info: write success\n");
1448
1449 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
1450 dev_err(adapter->dev, "read CFG reg failed\n");
1451 else
1452 dev_dbg(adapter->dev, "info: CFG reg val =%x\n", cr);
1453
1454 return -1;
1291} 1455}
1292 1456
1293/* 1457/*
@@ -1305,7 +1469,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1305 * and return. 1469 * and return.
1306 */ 1470 */
1307static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, 1471static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1308 u8 *payload, u32 pkt_len, u8 port, 1472 u8 *payload, u32 pkt_len, u32 port,
1309 u32 next_pkt_len) 1473 u32 next_pkt_len)
1310{ 1474{
1311 struct sdio_mmc_card *card = adapter->card; 1475 struct sdio_mmc_card *card = adapter->card;
@@ -1314,8 +1478,11 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1314 s32 f_send_cur_buf = 0; 1478 s32 f_send_cur_buf = 0;
1315 s32 f_precopy_cur_buf = 0; 1479 s32 f_precopy_cur_buf = 0;
1316 s32 f_postcopy_cur_buf = 0; 1480 s32 f_postcopy_cur_buf = 0;
1481 u32 mport;
1317 1482
1318 if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { 1483 if (!card->mpa_tx.enabled ||
1484 (card->has_control_mask && (port == CTRL_PORT)) ||
1485 (card->supports_sdio_new_mode && (port == CMD_PORT_SLCT))) {
1319 dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", 1486 dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
1320 __func__); 1487 __func__);
1321 1488
@@ -1329,7 +1496,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1329 __func__); 1496 __func__);
1330 1497
1331 if (MP_TX_AGGR_IN_PROGRESS(card)) { 1498 if (MP_TX_AGGR_IN_PROGRESS(card)) {
1332 if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && 1499 if (!mp_tx_aggr_port_limit_reached(card) &&
1333 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { 1500 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
1334 f_precopy_cur_buf = 1; 1501 f_precopy_cur_buf = 1;
1335 1502
@@ -1342,7 +1509,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1342 /* No room in Aggr buf, send it */ 1509 /* No room in Aggr buf, send it */
1343 f_send_aggr_buf = 1; 1510 f_send_aggr_buf = 1;
1344 1511
1345 if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) || 1512 if (mp_tx_aggr_port_limit_reached(card) ||
1346 !(card->mp_wr_bitmap & 1513 !(card->mp_wr_bitmap &
1347 (1 << card->curr_wr_port))) 1514 (1 << card->curr_wr_port)))
1348 f_send_cur_buf = 1; 1515 f_send_cur_buf = 1;
@@ -1381,7 +1548,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1381 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); 1548 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
1382 1549
1383 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || 1550 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
1384 MP_TX_AGGR_PORT_LIMIT_REACHED(card)) 1551 mp_tx_aggr_port_limit_reached(card))
1385 /* No more pkts allowed in Aggr buf, send it */ 1552 /* No more pkts allowed in Aggr buf, send it */
1386 f_send_aggr_buf = 1; 1553 f_send_aggr_buf = 1;
1387 } 1554 }
@@ -1390,11 +1557,28 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1390 dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", 1557 dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
1391 __func__, 1558 __func__,
1392 card->mpa_tx.start_port, card->mpa_tx.ports); 1559 card->mpa_tx.start_port, card->mpa_tx.ports);
1560 if (card->supports_sdio_new_mode) {
1561 u32 port_count;
1562 int i;
1563
1564 for (i = 0, port_count = 0; i < card->max_ports; i++)
1565 if (card->mpa_tx.ports & BIT(i))
1566 port_count++;
1567
1568 /* Writing data from "start_port + 0" to "start_port +
1569 * port_count -1", so decrease the count by 1
1570 */
1571 port_count--;
1572 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1573 (port_count << 8)) + card->mpa_tx.start_port;
1574 } else {
1575 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1576 (card->mpa_tx.ports << 4)) +
1577 card->mpa_tx.start_port;
1578 }
1579
1393 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, 1580 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
1394 card->mpa_tx.buf_len, 1581 card->mpa_tx.buf_len, mport);
1395 (adapter->ioport | 0x1000 |
1396 (card->mpa_tx.ports << 4)) +
1397 card->mpa_tx.start_port);
1398 1582
1399 MP_TX_AGGR_BUF_RESET(card); 1583 MP_TX_AGGR_BUF_RESET(card);
1400 } 1584 }
@@ -1434,7 +1618,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1434 int ret; 1618 int ret;
1435 u32 buf_block_len; 1619 u32 buf_block_len;
1436 u32 blk_size; 1620 u32 blk_size;
1437 u8 port = CTRL_PORT; 1621 u32 port = CTRL_PORT;
1438 u8 *payload = (u8 *)skb->data; 1622 u8 *payload = (u8 *)skb->data;
1439 u32 pkt_len = skb->len; 1623 u32 pkt_len = skb->len;
1440 1624
@@ -1465,6 +1649,9 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1465 pkt_len > MWIFIEX_UPLD_SIZE) 1649 pkt_len > MWIFIEX_UPLD_SIZE)
1466 dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", 1650 dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
1467 __func__, payload, pkt_len); 1651 __func__, payload, pkt_len);
1652
1653 if (card->supports_sdio_new_mode)
1654 port = CMD_PORT_SLCT;
1468 } 1655 }
1469 1656
1470 /* Transfer data to card */ 1657 /* Transfer data to card */
@@ -1586,18 +1773,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1586 1773
1587 adapter->dev = &func->dev; 1774 adapter->dev = &func->dev;
1588 1775
1589 switch (func->device) { 1776 strcpy(adapter->fw_name, card->firmware);
1590 case SDIO_DEVICE_ID_MARVELL_8786:
1591 strcpy(adapter->fw_name, SD8786_DEFAULT_FW_NAME);
1592 break;
1593 case SDIO_DEVICE_ID_MARVELL_8797:
1594 strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME);
1595 break;
1596 case SDIO_DEVICE_ID_MARVELL_8787:
1597 default:
1598 strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);
1599 break;
1600 }
1601 1777
1602 return 0; 1778 return 0;
1603 1779
@@ -1626,8 +1802,9 @@ disable_func:
1626static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) 1802static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1627{ 1803{
1628 struct sdio_mmc_card *card = adapter->card; 1804 struct sdio_mmc_card *card = adapter->card;
1805 const struct mwifiex_sdio_card_reg *reg = card->reg;
1629 int ret; 1806 int ret;
1630 u32 sdio_ireg; 1807 u8 sdio_ireg;
1631 1808
1632 /* 1809 /*
1633 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got 1810 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
@@ -1645,30 +1822,35 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1645 /* Initialize SDIO variables in card */ 1822 /* Initialize SDIO variables in card */
1646 card->mp_rd_bitmap = 0; 1823 card->mp_rd_bitmap = 0;
1647 card->mp_wr_bitmap = 0; 1824 card->mp_wr_bitmap = 0;
1648 card->curr_rd_port = 1; 1825 card->curr_rd_port = reg->start_rd_port;
1649 card->curr_wr_port = 1; 1826 card->curr_wr_port = reg->start_wr_port;
1650 1827
1651 card->mp_data_port_mask = DATA_PORT_MASK; 1828 card->mp_data_port_mask = reg->data_port_mask;
1652 1829
1653 card->mpa_tx.buf_len = 0; 1830 card->mpa_tx.buf_len = 0;
1654 card->mpa_tx.pkt_cnt = 0; 1831 card->mpa_tx.pkt_cnt = 0;
1655 card->mpa_tx.start_port = 0; 1832 card->mpa_tx.start_port = 0;
1656 1833
1657 card->mpa_tx.enabled = 1; 1834 card->mpa_tx.enabled = 1;
1658 card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; 1835 card->mpa_tx.pkt_aggr_limit = card->mp_agg_pkt_limit;
1659 1836
1660 card->mpa_rx.buf_len = 0; 1837 card->mpa_rx.buf_len = 0;
1661 card->mpa_rx.pkt_cnt = 0; 1838 card->mpa_rx.pkt_cnt = 0;
1662 card->mpa_rx.start_port = 0; 1839 card->mpa_rx.start_port = 0;
1663 1840
1664 card->mpa_rx.enabled = 1; 1841 card->mpa_rx.enabled = 1;
1665 card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; 1842 card->mpa_rx.pkt_aggr_limit = card->mp_agg_pkt_limit;
1666 1843
1667 /* Allocate buffers for SDIO MP-A */ 1844 /* Allocate buffers for SDIO MP-A */
1668 card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL); 1845 card->mp_regs = kzalloc(reg->max_mp_regs, GFP_KERNEL);
1669 if (!card->mp_regs) 1846 if (!card->mp_regs)
1670 return -ENOMEM; 1847 return -ENOMEM;
1671 1848
1849 /* Allocate skb pointer buffers */
1850 card->mpa_rx.skb_arr = kzalloc((sizeof(void *)) *
1851 card->mp_agg_pkt_limit, GFP_KERNEL);
1852 card->mpa_rx.len_arr = kzalloc(sizeof(*card->mpa_rx.len_arr) *
1853 card->mp_agg_pkt_limit, GFP_KERNEL);
1672 ret = mwifiex_alloc_sdio_mpa_buffers(adapter, 1854 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
1673 SDIO_MP_TX_AGGR_DEF_BUF_SIZE, 1855 SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
1674 SDIO_MP_RX_AGGR_DEF_BUF_SIZE); 1856 SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
@@ -1705,6 +1887,8 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
1705 struct sdio_mmc_card *card = adapter->card; 1887 struct sdio_mmc_card *card = adapter->card;
1706 1888
1707 kfree(card->mp_regs); 1889 kfree(card->mp_regs);
1890 kfree(card->mpa_rx.skb_arr);
1891 kfree(card->mpa_rx.len_arr);
1708 kfree(card->mpa_tx.buf); 1892 kfree(card->mpa_tx.buf);
1709 kfree(card->mpa_rx.buf); 1893 kfree(card->mpa_rx.buf);
1710} 1894}
@@ -1716,16 +1900,20 @@ static void
1716mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) 1900mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1717{ 1901{
1718 struct sdio_mmc_card *card = adapter->card; 1902 struct sdio_mmc_card *card = adapter->card;
1903 const struct mwifiex_sdio_card_reg *reg = card->reg;
1719 int i; 1904 int i;
1720 1905
1721 card->mp_end_port = port; 1906 card->mp_end_port = port;
1722 1907
1723 card->mp_data_port_mask = DATA_PORT_MASK; 1908 card->mp_data_port_mask = reg->data_port_mask;
1724 1909
1725 for (i = 1; i <= MAX_PORT - card->mp_end_port; i++) 1910 if (reg->start_wr_port) {
1726 card->mp_data_port_mask &= ~(1 << (MAX_PORT - i)); 1911 for (i = 1; i <= card->max_ports - card->mp_end_port; i++)
1912 card->mp_data_port_mask &=
1913 ~(1 << (card->max_ports - i));
1914 }
1727 1915
1728 card->curr_wr_port = 1; 1916 card->curr_wr_port = reg->start_wr_port;
1729 1917
1730 dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", 1918 dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
1731 port, card->mp_data_port_mask); 1919 port, card->mp_data_port_mask);
@@ -1831,3 +2019,4 @@ MODULE_LICENSE("GPL v2");
1831MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME); 2019MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);
1832MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); 2020MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);
1833MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); 2021MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);
2022MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 8cc5468654b4..6d51dfdd8251 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -32,30 +32,37 @@
32#define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin" 32#define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin"
33#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" 33#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin" 34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
35#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
35 36
36#define BLOCK_MODE 1 37#define BLOCK_MODE 1
37#define BYTE_MODE 0 38#define BYTE_MODE 0
38 39
39#define REG_PORT 0 40#define REG_PORT 0
40#define RD_BITMAP_L 0x04
41#define RD_BITMAP_U 0x05
42#define WR_BITMAP_L 0x06
43#define WR_BITMAP_U 0x07
44#define RD_LEN_P0_L 0x08
45#define RD_LEN_P0_U 0x09
46 41
47#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff 42#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff
48 43
49#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000 44#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
50 45
46#define SDIO_MPA_ADDR_BASE 0x1000
51#define CTRL_PORT 0 47#define CTRL_PORT 0
52#define CTRL_PORT_MASK 0x0001 48#define CTRL_PORT_MASK 0x0001
53#define DATA_PORT_MASK 0xfffe
54 49
55#define MAX_MP_REGS 64 50#define CMD_PORT_UPLD_INT_MASK (0x1U<<6)
56#define MAX_PORT 16 51#define CMD_PORT_DNLD_INT_MASK (0x1U<<7)
57 52#define HOST_TERM_CMD53 (0x1U << 2)
58#define SDIO_MP_AGGR_DEF_PKT_LIMIT 8 53#define REG_PORT 0
54#define MEM_PORT 0x10000
55#define CMD_RD_LEN_0 0xB4
56#define CMD_RD_LEN_1 0xB5
57#define CARD_CONFIG_2_1_REG 0xCD
58#define CMD53_NEW_MODE (0x1U << 0)
59#define CMD_CONFIG_0 0xB8
60#define CMD_PORT_RD_LEN_EN (0x1U << 2)
61#define CMD_CONFIG_1 0xB9
62#define CMD_PORT_AUTO_EN (0x1U << 0)
63#define CMD_PORT_SLCT 0x8000
64#define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U)
65#define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U)
59 66
60#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */ 67#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */
61 68
@@ -75,14 +82,8 @@
75 82
76/* Host Control Registers : Configuration */ 83/* Host Control Registers : Configuration */
77#define CONFIGURATION_REG 0x00 84#define CONFIGURATION_REG 0x00
78/* Host Control Registers : Host without Command 53 finish host*/
79#define HOST_TO_CARD_EVENT (0x1U << 3)
80/* Host Control Registers : Host without Command 53 finish host */
81#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
82/* Host Control Registers : Host power up */ 85/* Host Control Registers : Host power up */
83#define HOST_POWER_UP (0x1U << 1) 86#define HOST_POWER_UP (0x1U << 1)
84/* Host Control Registers : Host power down */
85#define HOST_POWER_DOWN (0x1U << 0)
86 87
87/* Host Control Registers : Host interrupt mask */ 88/* Host Control Registers : Host interrupt mask */
88#define HOST_INT_MASK_REG 0x02 89#define HOST_INT_MASK_REG 0x02
@@ -90,8 +91,7 @@
90#define UP_LD_HOST_INT_MASK (0x1U) 91#define UP_LD_HOST_INT_MASK (0x1U)
91/* Host Control Registers : Download host interrupt mask */ 92/* Host Control Registers : Download host interrupt mask */
92#define DN_LD_HOST_INT_MASK (0x2U) 93#define DN_LD_HOST_INT_MASK (0x2U)
93/* Enable Host interrupt mask */ 94
94#define HOST_INT_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
95/* Disable Host interrupt mask */ 95/* Disable Host interrupt mask */
96#define HOST_INT_DISABLE 0xff 96#define HOST_INT_DISABLE 0xff
97 97
@@ -104,74 +104,15 @@
104 104
105/* Host Control Registers : Host interrupt RSR */ 105/* Host Control Registers : Host interrupt RSR */
106#define HOST_INT_RSR_REG 0x01 106#define HOST_INT_RSR_REG 0x01
107/* Host Control Registers : Upload host interrupt RSR */
108#define UP_LD_HOST_INT_RSR (0x1U)
109#define SDIO_INT_MASK 0x3F
110 107
111/* Host Control Registers : Host interrupt status */ 108/* Host Control Registers : Host interrupt status */
112#define HOST_INT_STATUS_REG 0x28 109#define HOST_INT_STATUS_REG 0x28
113/* Host Control Registers : Upload CRC error */ 110
114#define UP_LD_CRC_ERR (0x1U << 2)
115/* Host Control Registers : Upload restart */
116#define UP_LD_RESTART (0x1U << 1)
117/* Host Control Registers : Download restart */
118#define DN_LD_RESTART (0x1U << 0)
119
120/* Card Control Registers : Card status register */
121#define CARD_STATUS_REG 0x30
122/* Card Control Registers : Card I/O ready */ 111/* Card Control Registers : Card I/O ready */
123#define CARD_IO_READY (0x1U << 3) 112#define CARD_IO_READY (0x1U << 3)
124/* Card Control Registers : CIS card ready */
125#define CIS_CARD_RDY (0x1U << 2)
126/* Card Control Registers : Upload card ready */
127#define UP_LD_CARD_RDY (0x1U << 1)
128/* Card Control Registers : Download card ready */ 113/* Card Control Registers : Download card ready */
129#define DN_LD_CARD_RDY (0x1U << 0) 114#define DN_LD_CARD_RDY (0x1U << 0)
130 115
131/* Card Control Registers : Host interrupt mask register */
132#define HOST_INTERRUPT_MASK_REG 0x34
133/* Card Control Registers : Host power interrupt mask */
134#define HOST_POWER_INT_MASK (0x1U << 3)
135/* Card Control Registers : Abort card interrupt mask */
136#define ABORT_CARD_INT_MASK (0x1U << 2)
137/* Card Control Registers : Upload card interrupt mask */
138#define UP_LD_CARD_INT_MASK (0x1U << 1)
139/* Card Control Registers : Download card interrupt mask */
140#define DN_LD_CARD_INT_MASK (0x1U << 0)
141
142/* Card Control Registers : Card interrupt status register */
143#define CARD_INTERRUPT_STATUS_REG 0x38
144/* Card Control Registers : Power up interrupt */
145#define POWER_UP_INT (0x1U << 4)
146/* Card Control Registers : Power down interrupt */
147#define POWER_DOWN_INT (0x1U << 3)
148
149/* Card Control Registers : Card interrupt RSR register */
150#define CARD_INTERRUPT_RSR_REG 0x3c
151/* Card Control Registers : Power up RSR */
152#define POWER_UP_RSR (0x1U << 4)
153/* Card Control Registers : Power down RSR */
154#define POWER_DOWN_RSR (0x1U << 3)
155
156/* Card Control Registers : Miscellaneous Configuration Register */
157#define CARD_MISC_CFG_REG 0x6C
158
159/* Host F1 read base 0 */
160#define HOST_F1_RD_BASE_0 0x0040
161/* Host F1 read base 1 */
162#define HOST_F1_RD_BASE_1 0x0041
163/* Host F1 card ready */
164#define HOST_F1_CARD_RDY 0x0020
165
166/* Firmware status 0 register */
167#define CARD_FW_STATUS0_REG 0x60
168/* Firmware status 1 register */
169#define CARD_FW_STATUS1_REG 0x61
170/* Rx length register */
171#define CARD_RX_LEN_REG 0x62
172/* Rx unit register */
173#define CARD_RX_UNIT_REG 0x63
174
175/* Max retry number of CMD53 write */ 116/* Max retry number of CMD53 write */
176#define MAX_WRITE_IOMEM_RETRY 2 117#define MAX_WRITE_IOMEM_RETRY 2
177 118
@@ -192,7 +133,8 @@
192 if (a->mpa_tx.start_port <= port) \ 133 if (a->mpa_tx.start_port <= port) \
193 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \ 134 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \
194 else \ 135 else \
195 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - \ 136 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+ \
137 (a->max_ports - \
196 a->mp_end_port))); \ 138 a->mp_end_port))); \
197 a->mpa_tx.pkt_cnt++; \ 139 a->mpa_tx.pkt_cnt++; \
198} while (0) 140} while (0)
@@ -201,12 +143,6 @@
201#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \ 143#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \
202 (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit) 144 (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
203 145
204/* SDIO Tx aggregation port limit ? */
205#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \
206 a->mpa_tx.start_port) && (((MAX_PORT - \
207 a->mpa_tx.start_port) + a->curr_wr_port) >= \
208 SDIO_MP_AGGR_DEF_PKT_LIMIT))
209
210/* Reset SDIO Tx aggregation buffer parameters */ 146/* Reset SDIO Tx aggregation buffer parameters */
211#define MP_TX_AGGR_BUF_RESET(a) do { \ 147#define MP_TX_AGGR_BUF_RESET(a) do { \
212 a->mpa_tx.pkt_cnt = 0; \ 148 a->mpa_tx.pkt_cnt = 0; \
@@ -219,12 +155,6 @@
219#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \ 155#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \
220 (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit) 156 (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
221 157
222/* SDIO Tx aggregation port limit ? */
223#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \
224 a->mpa_rx.start_port) && (((MAX_PORT - \
225 a->mpa_rx.start_port) + a->curr_rd_port) >= \
226 SDIO_MP_AGGR_DEF_PKT_LIMIT))
227
228/* SDIO Rx aggregation in progress ? */ 158/* SDIO Rx aggregation in progress ? */
229#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0) 159#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
230 160
@@ -232,20 +162,6 @@
232#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \ 162#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \
233 ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size) 163 ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
234 164
235/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
236#define MP_RX_AGGR_SETUP(a, skb, port) do { \
237 a->mpa_rx.buf_len += skb->len; \
238 if (!a->mpa_rx.pkt_cnt) \
239 a->mpa_rx.start_port = port; \
240 if (a->mpa_rx.start_port <= port) \
241 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt)); \
242 else \
243 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \
244 a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb; \
245 a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len; \
246 a->mpa_rx.pkt_cnt++; \
247} while (0)
248
249/* Reset SDIO Rx aggregation buffer parameters */ 165/* Reset SDIO Rx aggregation buffer parameters */
250#define MP_RX_AGGR_BUF_RESET(a) do { \ 166#define MP_RX_AGGR_BUF_RESET(a) do { \
251 a->mpa_rx.pkt_cnt = 0; \ 167 a->mpa_rx.pkt_cnt = 0; \
@@ -254,14 +170,13 @@
254 a->mpa_rx.start_port = 0; \ 170 a->mpa_rx.start_port = 0; \
255} while (0) 171} while (0)
256 172
257
258/* data structure for SDIO MPA TX */ 173/* data structure for SDIO MPA TX */
259struct mwifiex_sdio_mpa_tx { 174struct mwifiex_sdio_mpa_tx {
260 /* multiport tx aggregation buffer pointer */ 175 /* multiport tx aggregation buffer pointer */
261 u8 *buf; 176 u8 *buf;
262 u32 buf_len; 177 u32 buf_len;
263 u32 pkt_cnt; 178 u32 pkt_cnt;
264 u16 ports; 179 u32 ports;
265 u16 start_port; 180 u16 start_port;
266 u8 enabled; 181 u8 enabled;
267 u32 buf_size; 182 u32 buf_size;
@@ -272,11 +187,11 @@ struct mwifiex_sdio_mpa_rx {
272 u8 *buf; 187 u8 *buf;
273 u32 buf_len; 188 u32 buf_len;
274 u32 pkt_cnt; 189 u32 pkt_cnt;
275 u16 ports; 190 u32 ports;
276 u16 start_port; 191 u16 start_port;
277 192
278 struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; 193 struct sk_buff **skb_arr;
279 u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; 194 u32 *len_arr;
280 195
281 u8 enabled; 196 u8 enabled;
282 u32 buf_size; 197 u32 buf_size;
@@ -286,15 +201,47 @@ struct mwifiex_sdio_mpa_rx {
286int mwifiex_bus_register(void); 201int mwifiex_bus_register(void);
287void mwifiex_bus_unregister(void); 202void mwifiex_bus_unregister(void);
288 203
204struct mwifiex_sdio_card_reg {
205 u8 start_rd_port;
206 u8 start_wr_port;
207 u8 base_0_reg;
208 u8 base_1_reg;
209 u8 poll_reg;
210 u8 host_int_enable;
211 u8 status_reg_0;
212 u8 status_reg_1;
213 u8 sdio_int_mask;
214 u32 data_port_mask;
215 u8 max_mp_regs;
216 u8 rd_bitmap_l;
217 u8 rd_bitmap_u;
218 u8 rd_bitmap_1l;
219 u8 rd_bitmap_1u;
220 u8 wr_bitmap_l;
221 u8 wr_bitmap_u;
222 u8 wr_bitmap_1l;
223 u8 wr_bitmap_1u;
224 u8 rd_len_p0_l;
225 u8 rd_len_p0_u;
226 u8 card_misc_cfg_reg;
227};
228
289struct sdio_mmc_card { 229struct sdio_mmc_card {
290 struct sdio_func *func; 230 struct sdio_func *func;
291 struct mwifiex_adapter *adapter; 231 struct mwifiex_adapter *adapter;
292 232
293 u16 mp_rd_bitmap; 233 const char *firmware;
294 u16 mp_wr_bitmap; 234 const struct mwifiex_sdio_card_reg *reg;
235 u8 max_ports;
236 u8 mp_agg_pkt_limit;
237 bool supports_sdio_new_mode;
238 bool has_control_mask;
239
240 u32 mp_rd_bitmap;
241 u32 mp_wr_bitmap;
295 242
296 u16 mp_end_port; 243 u16 mp_end_port;
297 u16 mp_data_port_mask; 244 u32 mp_data_port_mask;
298 245
299 u8 curr_rd_port; 246 u8 curr_rd_port;
300 u8 curr_wr_port; 247 u8 curr_wr_port;
@@ -305,6 +252,98 @@ struct sdio_mmc_card {
305 struct mwifiex_sdio_mpa_rx mpa_rx; 252 struct mwifiex_sdio_mpa_rx mpa_rx;
306}; 253};
307 254
255struct mwifiex_sdio_device {
256 const char *firmware;
257 const struct mwifiex_sdio_card_reg *reg;
258 u8 max_ports;
259 u8 mp_agg_pkt_limit;
260 bool supports_sdio_new_mode;
261 bool has_control_mask;
262};
263
264static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
265 .start_rd_port = 1,
266 .start_wr_port = 1,
267 .base_0_reg = 0x0040,
268 .base_1_reg = 0x0041,
269 .poll_reg = 0x30,
270 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK,
271 .status_reg_0 = 0x60,
272 .status_reg_1 = 0x61,
273 .sdio_int_mask = 0x3f,
274 .data_port_mask = 0x0000fffe,
275 .max_mp_regs = 64,
276 .rd_bitmap_l = 0x04,
277 .rd_bitmap_u = 0x05,
278 .wr_bitmap_l = 0x06,
279 .wr_bitmap_u = 0x07,
280 .rd_len_p0_l = 0x08,
281 .rd_len_p0_u = 0x09,
282 .card_misc_cfg_reg = 0x6c,
283};
284
285static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
286 .start_rd_port = 0,
287 .start_wr_port = 0,
288 .base_0_reg = 0x60,
289 .base_1_reg = 0x61,
290 .poll_reg = 0x50,
291 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |
292 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,
293 .status_reg_0 = 0xc0,
294 .status_reg_1 = 0xc1,
295 .sdio_int_mask = 0xff,
296 .data_port_mask = 0xffffffff,
297 .max_mp_regs = 184,
298 .rd_bitmap_l = 0x04,
299 .rd_bitmap_u = 0x05,
300 .rd_bitmap_1l = 0x06,
301 .rd_bitmap_1u = 0x07,
302 .wr_bitmap_l = 0x08,
303 .wr_bitmap_u = 0x09,
304 .wr_bitmap_1l = 0x0a,
305 .wr_bitmap_1u = 0x0b,
306 .rd_len_p0_l = 0x0c,
307 .rd_len_p0_u = 0x0d,
308 .card_misc_cfg_reg = 0xcc,
309};
310
311static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
312 .firmware = SD8786_DEFAULT_FW_NAME,
313 .reg = &mwifiex_reg_sd87xx,
314 .max_ports = 16,
315 .mp_agg_pkt_limit = 8,
316 .supports_sdio_new_mode = false,
317 .has_control_mask = true,
318};
319
320static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
321 .firmware = SD8787_DEFAULT_FW_NAME,
322 .reg = &mwifiex_reg_sd87xx,
323 .max_ports = 16,
324 .mp_agg_pkt_limit = 8,
325 .supports_sdio_new_mode = false,
326 .has_control_mask = true,
327};
328
329static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
330 .firmware = SD8797_DEFAULT_FW_NAME,
331 .reg = &mwifiex_reg_sd87xx,
332 .max_ports = 16,
333 .mp_agg_pkt_limit = 8,
334 .supports_sdio_new_mode = false,
335 .has_control_mask = true,
336};
337
338static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
339 .firmware = SD8897_DEFAULT_FW_NAME,
340 .reg = &mwifiex_reg_sd8897,
341 .max_ports = 32,
342 .mp_agg_pkt_limit = 16,
343 .supports_sdio_new_mode = true,
344 .has_control_mask = false,
345};
346
308/* 347/*
309 * .cmdrsp_complete handler 348 * .cmdrsp_complete handler
310 */ 349 */
@@ -325,4 +364,77 @@ static inline int mwifiex_sdio_event_complete(struct mwifiex_adapter *adapter,
325 return 0; 364 return 0;
326} 365}
327 366
367static inline bool
368mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
369{
370 u8 tmp;
371
372 if (card->curr_rd_port < card->mpa_rx.start_port) {
373 if (card->supports_sdio_new_mode)
374 tmp = card->mp_end_port >> 1;
375 else
376 tmp = card->mp_agg_pkt_limit;
377
378 if (((card->max_ports - card->mpa_rx.start_port) +
379 card->curr_rd_port) >= tmp)
380 return true;
381 }
382
383 if (!card->supports_sdio_new_mode)
384 return false;
385
386 if ((card->curr_rd_port - card->mpa_rx.start_port) >=
387 (card->mp_end_port >> 1))
388 return true;
389
390 return false;
391}
392
393static inline bool
394mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
395{
396 u16 tmp;
397
398 if (card->curr_wr_port < card->mpa_tx.start_port) {
399 if (card->supports_sdio_new_mode)
400 tmp = card->mp_end_port >> 1;
401 else
402 tmp = card->mp_agg_pkt_limit;
403
404 if (((card->max_ports - card->mpa_tx.start_port) +
405 card->curr_wr_port) >= tmp)
406 return true;
407 }
408
409 if (!card->supports_sdio_new_mode)
410 return false;
411
412 if ((card->curr_wr_port - card->mpa_tx.start_port) >=
413 (card->mp_end_port >> 1))
414 return true;
415
416 return false;
417}
418
419/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
420static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
421 struct sk_buff *skb, u8 port)
422{
423 card->mpa_rx.buf_len += skb->len;
424
425 if (!card->mpa_rx.pkt_cnt)
426 card->mpa_rx.start_port = port;
427
428 if (card->supports_sdio_new_mode) {
429 card->mpa_rx.ports |= (1 << port);
430 } else {
431 if (card->mpa_rx.start_port <= port)
432 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt);
433 else
434 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
435 }
436 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb;
437 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len;
438 card->mpa_rx.pkt_cnt++;
439}
328#endif /* _MWIFIEX_SDIO_H */ 440#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index b193e25977d2..8ece48580642 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1134,6 +1134,55 @@ mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
1134 return 0; 1134 return 0;
1135} 1135}
1136 1136
1137/* This function parse cal data from ASCII to hex */
1138static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
1139{
1140 u8 *s = src, *d = dst;
1141
1142 while (s - src < len) {
1143 if (*s && (isspace(*s) || *s == '\t')) {
1144 s++;
1145 continue;
1146 }
1147 if (isxdigit(*s)) {
1148 *d++ = simple_strtol(s, NULL, 16);
1149 s += 2;
1150 } else {
1151 s++;
1152 }
1153 }
1154
1155 return d - dst;
1156}
1157
1158/* This function prepares command of set_cfg_data. */
1159static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
1160 struct host_cmd_ds_command *cmd,
1161 u16 cmd_action)
1162{
1163 struct host_cmd_ds_802_11_cfg_data *cfg_data = &cmd->params.cfg_data;
1164 struct mwifiex_adapter *adapter = priv->adapter;
1165 u32 len, cal_data_offset;
1166 u8 *tmp_cmd = (u8 *)cmd;
1167
1168 cal_data_offset = S_DS_GEN + sizeof(*cfg_data);
1169 if ((adapter->cal_data->data) && (adapter->cal_data->size > 0))
1170 len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
1171 adapter->cal_data->size,
1172 (u8 *)(tmp_cmd + cal_data_offset));
1173 else
1174 return -1;
1175
1176 cfg_data->action = cpu_to_le16(cmd_action);
1177 cfg_data->type = cpu_to_le16(CFG_DATA_TYPE_CAL);
1178 cfg_data->data_len = cpu_to_le16(len);
1179
1180 cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
1181 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*cfg_data) + len);
1182
1183 return 0;
1184}
1185
1137/* 1186/*
1138 * This function prepares the commands before sending them to the firmware. 1187 * This function prepares the commands before sending them to the firmware.
1139 * 1188 *
@@ -1152,6 +1201,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1152 case HostCmd_CMD_GET_HW_SPEC: 1201 case HostCmd_CMD_GET_HW_SPEC:
1153 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr); 1202 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
1154 break; 1203 break;
1204 case HostCmd_CMD_CFG_DATA:
1205 ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, cmd_action);
1206 break;
1155 case HostCmd_CMD_MAC_CONTROL: 1207 case HostCmd_CMD_MAC_CONTROL:
1156 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action, 1208 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
1157 data_buf); 1209 data_buf);
@@ -1384,6 +1436,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1384 */ 1436 */
1385int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) 1437int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1386{ 1438{
1439 struct mwifiex_adapter *adapter = priv->adapter;
1387 int ret; 1440 int ret;
1388 u16 enable = true; 1441 u16 enable = true;
1389 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; 1442 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
@@ -1404,6 +1457,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1404 HostCmd_ACT_GEN_SET, 0, NULL); 1457 HostCmd_ACT_GEN_SET, 0, NULL);
1405 if (ret) 1458 if (ret)
1406 return -1; 1459 return -1;
1460
1461 /* Download calibration data to firmware */
1462 if (adapter->cal_data) {
1463 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
1464 HostCmd_ACT_GEN_SET, 0, NULL);
1465 if (ret)
1466 return -1;
1467 }
1468
1407 /* Read MAC address from HW */ 1469 /* Read MAC address from HW */
1408 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC, 1470 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
1409 HostCmd_ACT_GEN_GET, 0, NULL); 1471 HostCmd_ACT_GEN_GET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 9f990e14966e..d85df158cc6c 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -818,6 +818,18 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
818 return 0; 818 return 0;
819} 819}
820 820
821/* This function handles the command response of set_cfg_data */
822static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
823 struct host_cmd_ds_command *resp)
824{
825 if (resp->result != HostCmd_RESULT_OK) {
826 dev_err(priv->adapter->dev, "Cal data cmd resp failed\n");
827 return -1;
828 }
829
830 return 0;
831}
832
821/* 833/*
822 * This function handles the command responses. 834 * This function handles the command responses.
823 * 835 *
@@ -841,6 +853,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
841 case HostCmd_CMD_GET_HW_SPEC: 853 case HostCmd_CMD_GET_HW_SPEC:
842 ret = mwifiex_ret_get_hw_spec(priv, resp); 854 ret = mwifiex_ret_get_hw_spec(priv, resp);
843 break; 855 break;
856 case HostCmd_CMD_CFG_DATA:
857 ret = mwifiex_ret_cfg_data(priv, resp);
858 break;
844 case HostCmd_CMD_MAC_CONTROL: 859 case HostCmd_CMD_MAC_CONTROL:
845 break; 860 break;
846 case HostCmd_CMD_802_11_MAC_ADDRESS: 861 case HostCmd_CMD_802_11_MAC_ADDRESS:
@@ -978,6 +993,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
978 case HostCmd_CMD_UAP_BSS_STOP: 993 case HostCmd_CMD_UAP_BSS_STOP:
979 priv->bss_started = 0; 994 priv->bss_started = 0;
980 break; 995 break;
996 case HostCmd_CMD_UAP_STA_DEAUTH:
997 break;
981 case HostCmd_CMD_MEF_CFG: 998 case HostCmd_CMD_MEF_CFG:
982 break; 999 break;
983 default: 1000 default:
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index b04b1db29100..2de882dead0f 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -689,6 +689,23 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
689 return 0; 689 return 0;
690} 690}
691 691
692/* This function prepares AP specific deauth command with mac supplied in
693 * function parameter.
694 */
695static int mwifiex_cmd_uap_sta_deauth(struct mwifiex_private *priv,
696 struct host_cmd_ds_command *cmd, u8 *mac)
697{
698 struct host_cmd_ds_sta_deauth *sta_deauth = &cmd->params.sta_deauth;
699
700 cmd->command = cpu_to_le16(HostCmd_CMD_UAP_STA_DEAUTH);
701 memcpy(sta_deauth->mac, mac, ETH_ALEN);
702 sta_deauth->reason = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
703
704 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_sta_deauth) +
705 S_DS_GEN);
706 return 0;
707}
708
692/* This function prepares the AP specific commands before sending them 709/* This function prepares the AP specific commands before sending them
693 * to the firmware. 710 * to the firmware.
694 * This is a generic function which calls specific command preparation 711 * This is a generic function which calls specific command preparation
@@ -710,6 +727,10 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
710 cmd->command = cpu_to_le16(cmd_no); 727 cmd->command = cpu_to_le16(cmd_no);
711 cmd->size = cpu_to_le16(S_DS_GEN); 728 cmd->size = cpu_to_le16(S_DS_GEN);
712 break; 729 break;
730 case HostCmd_CMD_UAP_STA_DEAUTH:
731 if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
732 return -1;
733 break;
713 default: 734 default:
714 dev_err(priv->adapter->dev, 735 dev_err(priv->adapter->dev,
715 "PREP_CMD: unknown cmd %#x\n", cmd_no); 736 "PREP_CMD: unknown cmd %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 21c640d3b579..718066577c6c 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -107,18 +107,15 @@ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
107 */ 107 */
108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac) 108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
109{ 109{
110 struct mwifiex_sta_node *node, *tmp; 110 struct mwifiex_sta_node *node;
111 unsigned long flags; 111 unsigned long flags;
112 112
113 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 113 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
114 114
115 node = mwifiex_get_sta_entry(priv, mac); 115 node = mwifiex_get_sta_entry(priv, mac);
116 if (node) { 116 if (node) {
117 list_for_each_entry_safe(node, tmp, &priv->sta_list, 117 list_del(&node->list);
118 list) { 118 kfree(node);
119 list_del(&node->list);
120 kfree(node);
121 }
122 } 119 }
123 120
124 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 121 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
@@ -295,3 +292,19 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
295 292
296 return 0; 293 return 0;
297} 294}
295
296/* This function deletes station entry from associated station list.
297 * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
298 * tables created for this station are deleted.
299 */
300void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
301 struct mwifiex_sta_node *node)
302{
303 if (priv->ap_11n_enabled && node->is_11n_enabled) {
304 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
305 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
306 }
307 mwifiex_del_sta_entry(priv, node->mac_addr);
308
309 return;
310}
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 6820fce4016b..a3707fd4ef62 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1548,7 +1548,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1548 if (!priv->pending_tx_pkts) 1548 if (!priv->pending_tx_pkts)
1549 return 0; 1549 return 0;
1550 1550
1551 retry = 0; 1551 retry = 1;
1552 rc = 0; 1552 rc = 0;
1553 1553
1554 spin_lock_bh(&priv->tx_lock); 1554 spin_lock_bh(&priv->tx_lock);
@@ -1572,13 +1572,19 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1572 1572
1573 spin_lock_bh(&priv->tx_lock); 1573 spin_lock_bh(&priv->tx_lock);
1574 1574
1575 if (timeout) { 1575 if (timeout || !priv->pending_tx_pkts) {
1576 WARN_ON(priv->pending_tx_pkts); 1576 WARN_ON(priv->pending_tx_pkts);
1577 if (retry) 1577 if (retry)
1578 wiphy_notice(hw->wiphy, "tx rings drained\n"); 1578 wiphy_notice(hw->wiphy, "tx rings drained\n");
1579 break; 1579 break;
1580 } 1580 }
1581 1581
1582 if (retry) {
1583 mwl8k_tx_start(priv);
1584 retry = 0;
1585 continue;
1586 }
1587
1582 if (priv->pending_tx_pkts < oldcount) { 1588 if (priv->pending_tx_pkts < oldcount) {
1583 wiphy_notice(hw->wiphy, 1589 wiphy_notice(hw->wiphy,
1584 "waiting for tx rings to drain (%d -> %d pkts)\n", 1590 "waiting for tx rings to drain (%d -> %d pkts)\n",
@@ -2055,6 +2061,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
2055 mwl8k_remove_stream(hw, stream); 2061 mwl8k_remove_stream(hw, stream);
2056 spin_unlock(&priv->stream_lock); 2062 spin_unlock(&priv->stream_lock);
2057 } 2063 }
2064 mwl8k_tx_start(priv);
2058 spin_unlock_bh(&priv->tx_lock); 2065 spin_unlock_bh(&priv->tx_lock);
2059 pci_unmap_single(priv->pdev, dma, skb->len, 2066 pci_unmap_single(priv->pdev, dma, skb->len,
2060 PCI_DMA_TODEVICE); 2067 PCI_DMA_TODEVICE);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 978e7eb26567..7fc46f26cf2b 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -42,8 +42,7 @@
42 42
43MODULE_FIRMWARE("3826.arm"); 43MODULE_FIRMWARE("3826.arm");
44 44
45/* 45/* gpios should be handled in board files and provided via platform data,
46 * gpios should be handled in board files and provided via platform data,
47 * but because it's currently impossible for p54spi to have a header file 46 * but because it's currently impossible for p54spi to have a header file
48 * in include/linux, let's use module paramaters for now 47 * in include/linux, let's use module paramaters for now
49 */ 48 */
@@ -191,8 +190,7 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
191 const struct firmware *eeprom; 190 const struct firmware *eeprom;
192 int ret; 191 int ret;
193 192
194 /* 193 /* allow users to customize their eeprom.
195 * allow users to customize their eeprom.
196 */ 194 */
197 195
198 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); 196 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
@@ -285,8 +283,7 @@ static void p54spi_power_on(struct p54s_priv *priv)
285 gpio_set_value(p54spi_gpio_power, 1); 283 gpio_set_value(p54spi_gpio_power, 1);
286 enable_irq(gpio_to_irq(p54spi_gpio_irq)); 284 enable_irq(gpio_to_irq(p54spi_gpio_irq));
287 285
288 /* 286 /* need to wait a while before device can be accessed, the length
289 * need to wait a while before device can be accessed, the length
290 * is just a guess 287 * is just a guess
291 */ 288 */
292 msleep(10); 289 msleep(10);
@@ -365,7 +362,8 @@ static int p54spi_rx(struct p54s_priv *priv)
365 /* Firmware may insert up to 4 padding bytes after the lmac header, 362 /* Firmware may insert up to 4 padding bytes after the lmac header,
366 * but it does not amend the size of SPI data transfer. 363 * but it does not amend the size of SPI data transfer.
367 * Such packets has correct data size in header, thus referencing 364 * Such packets has correct data size in header, thus referencing
368 * past the end of allocated skb. Reserve extra 4 bytes for this case */ 365 * past the end of allocated skb. Reserve extra 4 bytes for this case
366 */
369 skb = dev_alloc_skb(len + 4); 367 skb = dev_alloc_skb(len + 4);
370 if (!skb) { 368 if (!skb) {
371 p54spi_sleep(priv); 369 p54spi_sleep(priv);
@@ -383,7 +381,8 @@ static int p54spi_rx(struct p54s_priv *priv)
383 } 381 }
384 p54spi_sleep(priv); 382 p54spi_sleep(priv);
385 /* Put additional bytes to compensate for the possible 383 /* Put additional bytes to compensate for the possible
386 * alignment-caused truncation */ 384 * alignment-caused truncation
385 */
387 skb_put(skb, 4); 386 skb_put(skb, 4);
388 387
389 if (p54_rx(priv->hw, skb) == 0) 388 if (p54_rx(priv->hw, skb) == 0)
@@ -713,27 +712,7 @@ static struct spi_driver p54spi_driver = {
713 .remove = p54spi_remove, 712 .remove = p54spi_remove,
714}; 713};
715 714
716static int __init p54spi_init(void) 715module_spi_driver(p54spi_driver);
717{
718 int ret;
719
720 ret = spi_register_driver(&p54spi_driver);
721 if (ret < 0) {
722 printk(KERN_ERR "failed to register SPI driver: %d", ret);
723 goto out;
724 }
725
726out:
727 return ret;
728}
729
730static void __exit p54spi_exit(void)
731{
732 spi_unregister_driver(&p54spi_driver);
733}
734
735module_init(p54spi_init);
736module_exit(p54spi_exit);
737 716
738MODULE_LICENSE("GPL"); 717MODULE_LICENSE("GPL");
739MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); 718MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b52d70c75e1a..ead3a3e746a2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -840,7 +840,7 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
840 unsigned int beacon_base) 840 unsigned int beacon_base)
841{ 841{
842 int i; 842 int i;
843 const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size; 843 const int txwi_desc_size = rt2x00dev->bcn->winfo_size;
844 844
845 /* 845 /*
846 * For the Beacon base registers we only need to clear 846 * For the Beacon base registers we only need to clear
@@ -3953,379 +3953,577 @@ static void rt2800_init_bbp_early(struct rt2x00_dev *rt2x00dev)
3953 rt2800_bbp_write(rt2x00dev, 106, 0x35); 3953 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3954} 3954}
3955 3955
3956static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) 3956static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
3957{ 3957{
3958 int ant, div_mode;
3959 u16 eeprom; 3958 u16 eeprom;
3960 u8 value; 3959 u8 value;
3961 3960
3962 rt2800_init_bbp_early(rt2x00dev); 3961 rt2800_bbp_read(rt2x00dev, 138, &value);
3962 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
3963 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
3964 value |= 0x20;
3965 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
3966 value &= ~0x02;
3967 rt2800_bbp_write(rt2x00dev, 138, value);
3968}
3963 3969
3964 rt2800_bbp_read(rt2x00dev, 105, &value); 3970static void rt2800_init_bbp_305x_soc(struct rt2x00_dev *rt2x00dev)
3965 rt2x00_set_field8(&value, BBP105_MLD, 3971{
3966 rt2x00dev->default_ant.rx_chain_num == 2); 3972 rt2800_bbp_write(rt2x00dev, 31, 0x08);
3967 rt2800_bbp_write(rt2x00dev, 105, value); 3973
3974 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
3975 rt2800_bbp_write(rt2x00dev, 66, 0x38);
3976
3977 rt2800_bbp_write(rt2x00dev, 69, 0x12);
3978 rt2800_bbp_write(rt2x00dev, 73, 0x10);
3979
3980 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
3981
3982 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
3983 rt2800_bbp_write(rt2x00dev, 80, 0x08);
3984
3985 rt2800_bbp_write(rt2x00dev, 82, 0x62);
3986
3987 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
3988
3989 rt2800_bbp_write(rt2x00dev, 84, 0x99);
3990
3991 rt2800_bbp_write(rt2x00dev, 86, 0x00);
3992
3993 rt2800_bbp_write(rt2x00dev, 91, 0x04);
3994
3995 rt2800_bbp_write(rt2x00dev, 92, 0x00);
3996
3997 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
3998
3999 rt2800_bbp_write(rt2x00dev, 105, 0x01);
4000
4001 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4002}
4003
4004static void rt2800_init_bbp_28xx(struct rt2x00_dev *rt2x00dev)
4005{
4006 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4007 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4008
4009 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
4010 rt2800_bbp_write(rt2x00dev, 69, 0x16);
4011 rt2800_bbp_write(rt2x00dev, 73, 0x12);
4012 } else {
4013 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4014 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4015 }
4016
4017 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4018
4019 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4020
4021 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4022
4023 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4024
4025 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
4026 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4027 else
4028 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4029
4030 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4031
4032 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4033
4034 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4035
4036 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4037
4038 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4039
4040 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4041}
4042
4043static void rt2800_init_bbp_30xx(struct rt2x00_dev *rt2x00dev)
4044{
4045 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4046 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4047
4048 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4049 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4050
4051 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4052
4053 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4054 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4055 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4056
4057 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4058
4059 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4060
4061 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4062
4063 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4064
4065 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4066
4067 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4068
4069 if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
4070 rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
4071 rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E))
4072 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4073 else
4074 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4075
4076 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4077
4078 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4079
4080 if (rt2x00_rt(rt2x00dev, RT3071) ||
4081 rt2x00_rt(rt2x00dev, RT3090))
4082 rt2800_disable_unused_dac_adc(rt2x00dev);
4083}
4084
4085static void rt2800_init_bbp_3290(struct rt2x00_dev *rt2x00dev)
4086{
4087 u8 value;
3968 4088
3969 rt2800_bbp4_mac_if_ctrl(rt2x00dev); 4089 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
3970 4090
3971 rt2800_bbp_write(rt2x00dev, 20, 0x06);
3972 rt2800_bbp_write(rt2x00dev, 31, 0x08); 4091 rt2800_bbp_write(rt2x00dev, 31, 0x08);
3973 rt2800_bbp_write(rt2x00dev, 65, 0x2C); 4092
3974 rt2800_bbp_write(rt2x00dev, 68, 0xDD); 4093 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
3975 rt2800_bbp_write(rt2x00dev, 69, 0x1A); 4094 rt2800_bbp_write(rt2x00dev, 66, 0x38);
3976 rt2800_bbp_write(rt2x00dev, 70, 0x05); 4095
4096 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4097
4098 rt2800_bbp_write(rt2x00dev, 69, 0x12);
3977 rt2800_bbp_write(rt2x00dev, 73, 0x13); 4099 rt2800_bbp_write(rt2x00dev, 73, 0x13);
3978 rt2800_bbp_write(rt2x00dev, 74, 0x0F); 4100 rt2800_bbp_write(rt2x00dev, 75, 0x46);
3979 rt2800_bbp_write(rt2x00dev, 75, 0x4F);
3980 rt2800_bbp_write(rt2x00dev, 76, 0x28); 4101 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4102
4103 rt2800_bbp_write(rt2x00dev, 77, 0x58);
4104
4105 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4106
4107 rt2800_bbp_write(rt2x00dev, 74, 0x0b);
4108 rt2800_bbp_write(rt2x00dev, 79, 0x18);
4109 rt2800_bbp_write(rt2x00dev, 80, 0x09);
4110 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4111
4112 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4113
4114 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4115
4116 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4117
4118 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4119
4120 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4121
4122 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4123
4124 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4125
4126 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4127
4128 rt2800_bbp_write(rt2x00dev, 105, 0x1c);
4129
4130 rt2800_bbp_write(rt2x00dev, 106, 0x03);
4131
4132 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4133
4134 rt2800_bbp_write(rt2x00dev, 67, 0x24);
4135 rt2800_bbp_write(rt2x00dev, 143, 0x04);
4136 rt2800_bbp_write(rt2x00dev, 142, 0x99);
4137 rt2800_bbp_write(rt2x00dev, 150, 0x30);
4138 rt2800_bbp_write(rt2x00dev, 151, 0x2e);
4139 rt2800_bbp_write(rt2x00dev, 152, 0x20);
4140 rt2800_bbp_write(rt2x00dev, 153, 0x34);
4141 rt2800_bbp_write(rt2x00dev, 154, 0x40);
4142 rt2800_bbp_write(rt2x00dev, 155, 0x3b);
4143 rt2800_bbp_write(rt2x00dev, 253, 0x04);
4144
4145 rt2800_bbp_read(rt2x00dev, 47, &value);
4146 rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
4147 rt2800_bbp_write(rt2x00dev, 47, value);
4148
4149 /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
4150 rt2800_bbp_read(rt2x00dev, 3, &value);
4151 rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
4152 rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
4153 rt2800_bbp_write(rt2x00dev, 3, value);
4154}
4155
4156static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
4157{
4158 rt2800_bbp_write(rt2x00dev, 3, 0x00);
4159 rt2800_bbp_write(rt2x00dev, 4, 0x50);
4160
4161 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4162
4163 rt2800_bbp_write(rt2x00dev, 47, 0x48);
4164
4165 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4166 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4167
4168 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4169
4170 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4171 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4172 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4173 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4174
3981 rt2800_bbp_write(rt2x00dev, 77, 0x59); 4175 rt2800_bbp_write(rt2x00dev, 77, 0x59);
3982 rt2800_bbp_write(rt2x00dev, 84, 0x9A); 4176
4177 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4178
4179 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4180 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4181 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4182
4183 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4184
4185 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4186
4187 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4188
3983 rt2800_bbp_write(rt2x00dev, 86, 0x38); 4189 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4190
3984 rt2800_bbp_write(rt2x00dev, 88, 0x90); 4191 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4192
3985 rt2800_bbp_write(rt2x00dev, 91, 0x04); 4193 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4194
3986 rt2800_bbp_write(rt2x00dev, 92, 0x02); 4195 rt2800_bbp_write(rt2x00dev, 92, 0x02);
3987 rt2800_bbp_write(rt2x00dev, 95, 0x9a); 4196
3988 rt2800_bbp_write(rt2x00dev, 98, 0x12); 4197 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
3989 rt2800_bbp_write(rt2x00dev, 103, 0xC0); 4198
3990 rt2800_bbp_write(rt2x00dev, 104, 0x92); 4199 rt2800_bbp_write(rt2x00dev, 104, 0x92);
3991 /* FIXME BBP105 owerwrite */
3992 rt2800_bbp_write(rt2x00dev, 105, 0x3C);
3993 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3994 rt2800_bbp_write(rt2x00dev, 128, 0x12);
3995 rt2800_bbp_write(rt2x00dev, 134, 0xD0);
3996 rt2800_bbp_write(rt2x00dev, 135, 0xF6);
3997 rt2800_bbp_write(rt2x00dev, 137, 0x0F);
3998 4200
3999 /* Initialize GLRT (Generalized Likehood Radio Test) */ 4201 rt2800_bbp_write(rt2x00dev, 105, 0x34);
4000 rt2800_init_bbp_5592_glrt(rt2x00dev); 4202
4203 rt2800_bbp_write(rt2x00dev, 106, 0x05);
4204
4205 rt2800_bbp_write(rt2x00dev, 120, 0x50);
4206
4207 rt2800_bbp_write(rt2x00dev, 137, 0x0f);
4208
4209 rt2800_bbp_write(rt2x00dev, 163, 0xbd);
4210 /* Set ITxBF timeout to 0x9c40=1000msec */
4211 rt2800_bbp_write(rt2x00dev, 179, 0x02);
4212 rt2800_bbp_write(rt2x00dev, 180, 0x00);
4213 rt2800_bbp_write(rt2x00dev, 182, 0x40);
4214 rt2800_bbp_write(rt2x00dev, 180, 0x01);
4215 rt2800_bbp_write(rt2x00dev, 182, 0x9c);
4216 rt2800_bbp_write(rt2x00dev, 179, 0x00);
4217 /* Reprogram the inband interface to put right values in RXWI */
4218 rt2800_bbp_write(rt2x00dev, 142, 0x04);
4219 rt2800_bbp_write(rt2x00dev, 143, 0x3b);
4220 rt2800_bbp_write(rt2x00dev, 142, 0x06);
4221 rt2800_bbp_write(rt2x00dev, 143, 0xa0);
4222 rt2800_bbp_write(rt2x00dev, 142, 0x07);
4223 rt2800_bbp_write(rt2x00dev, 143, 0xa1);
4224 rt2800_bbp_write(rt2x00dev, 142, 0x08);
4225 rt2800_bbp_write(rt2x00dev, 143, 0xa2);
4226
4227 rt2800_bbp_write(rt2x00dev, 148, 0xc8);
4228}
4001 4229
4002 rt2800_bbp4_mac_if_ctrl(rt2x00dev); 4230static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
4231{
4232 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4233 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4003 4234
4004 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 4235 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4005 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); 4236 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4006 ant = (div_mode == 3) ? 1 : 0;
4007 rt2800_bbp_read(rt2x00dev, 152, &value);
4008 if (ant == 0) {
4009 /* Main antenna */
4010 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4011 } else {
4012 /* Auxiliary antenna */
4013 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4014 }
4015 rt2800_bbp_write(rt2x00dev, 152, value);
4016 4237
4017 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) { 4238 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4018 rt2800_bbp_read(rt2x00dev, 254, &value);
4019 rt2x00_set_field8(&value, BBP254_BIT7, 1);
4020 rt2800_bbp_write(rt2x00dev, 254, value);
4021 }
4022 4239
4023 rt2800_init_freq_calibration(rt2x00dev); 4240 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4241 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4242 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4024 4243
4025 rt2800_bbp_write(rt2x00dev, 84, 0x19); 4244 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4026 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) 4245
4246 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4247
4248 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4249
4250 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4251
4252 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4253
4254 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4255
4256 if (rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E))
4027 rt2800_bbp_write(rt2x00dev, 103, 0xc0); 4257 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4258 else
4259 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4260
4261 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4262
4263 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4264
4265 rt2800_disable_unused_dac_adc(rt2x00dev);
4028} 4266}
4029 4267
4030static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) 4268static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
4031{ 4269{
4032 unsigned int i; 4270 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4033 u16 eeprom;
4034 u8 reg_id;
4035 u8 value;
4036 4271
4037 if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) || 4272 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4038 rt2800_wait_bbp_ready(rt2x00dev))) 4273 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4039 return -EACCES;
4040 4274
4041 if (rt2x00_rt(rt2x00dev, RT5592)) { 4275 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4042 rt2800_init_bbp_5592(rt2x00dev); 4276 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4043 return 0;
4044 }
4045 4277
4046 if (rt2x00_rt(rt2x00dev, RT3352)) { 4278 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4047 rt2800_bbp_write(rt2x00dev, 3, 0x00);
4048 rt2800_bbp_write(rt2x00dev, 4, 0x50);
4049 }
4050 4279
4051 if (rt2x00_rt(rt2x00dev, RT3290) || 4280 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4052 rt2x00_rt(rt2x00dev, RT5390) || 4281 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4053 rt2x00_rt(rt2x00dev, RT5392)) 4282 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4054 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4055 4283
4056 if (rt2800_is_305x_soc(rt2x00dev) || 4284 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4057 rt2x00_rt(rt2x00dev, RT3290) ||
4058 rt2x00_rt(rt2x00dev, RT3352) ||
4059 rt2x00_rt(rt2x00dev, RT3572) ||
4060 rt2x00_rt(rt2x00dev, RT5390) ||
4061 rt2x00_rt(rt2x00dev, RT5392))
4062 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4063 4285
4064 if (rt2x00_rt(rt2x00dev, RT3352)) 4286 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4065 rt2800_bbp_write(rt2x00dev, 47, 0x48); 4287
4288 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4289
4290 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4291
4292 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4293
4294 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4295
4296 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4297
4298 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4299
4300 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4301
4302 rt2800_disable_unused_dac_adc(rt2x00dev);
4303}
4304
4305static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
4306{
4307 int ant, div_mode;
4308 u16 eeprom;
4309 u8 value;
4310
4311 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4312
4313 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4066 4314
4067 rt2800_bbp_write(rt2x00dev, 65, 0x2c); 4315 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4068 rt2800_bbp_write(rt2x00dev, 66, 0x38); 4316 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4069 4317
4070 if (rt2x00_rt(rt2x00dev, RT3290) || 4318 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4071 rt2x00_rt(rt2x00dev, RT3352) ||
4072 rt2x00_rt(rt2x00dev, RT5390) ||
4073 rt2x00_rt(rt2x00dev, RT5392))
4074 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4075 4319
4076 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { 4320 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4077 rt2800_bbp_write(rt2x00dev, 69, 0x16); 4321 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4078 rt2800_bbp_write(rt2x00dev, 73, 0x12); 4322 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4079 } else if (rt2x00_rt(rt2x00dev, RT3290) || 4323 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4080 rt2x00_rt(rt2x00dev, RT3352) ||
4081 rt2x00_rt(rt2x00dev, RT5390) ||
4082 rt2x00_rt(rt2x00dev, RT5392)) {
4083 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4084 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4085 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4086 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4087 4324
4088 if (rt2x00_rt(rt2x00dev, RT3290)) 4325 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4089 rt2800_bbp_write(rt2x00dev, 77, 0x58);
4090 else
4091 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4092 } else {
4093 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4094 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4095 }
4096 4326
4097 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 4327 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4098 4328
4099 if (rt2x00_rt(rt2x00dev, RT3070) || 4329 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4100 rt2x00_rt(rt2x00dev, RT3071) || 4330 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4101 rt2x00_rt(rt2x00dev, RT3090) || 4331 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4102 rt2x00_rt(rt2x00dev, RT3390) ||
4103 rt2x00_rt(rt2x00dev, RT3572) ||
4104 rt2x00_rt(rt2x00dev, RT5390) ||
4105 rt2x00_rt(rt2x00dev, RT5392)) {
4106 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4107 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4108 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4109 } else if (rt2800_is_305x_soc(rt2x00dev)) {
4110 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4111 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4112 } else if (rt2x00_rt(rt2x00dev, RT3290)) {
4113 rt2800_bbp_write(rt2x00dev, 74, 0x0b);
4114 rt2800_bbp_write(rt2x00dev, 79, 0x18);
4115 rt2800_bbp_write(rt2x00dev, 80, 0x09);
4116 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4117 } else if (rt2x00_rt(rt2x00dev, RT3352)) {
4118 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4119 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4120 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4121 } else {
4122 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4123 }
4124 4332
4125 rt2800_bbp_write(rt2x00dev, 82, 0x62); 4333 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4126 if (rt2x00_rt(rt2x00dev, RT3290) ||
4127 rt2x00_rt(rt2x00dev, RT5390) ||
4128 rt2x00_rt(rt2x00dev, RT5392))
4129 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4130 else
4131 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4132 4334
4133 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) 4335 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4134 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4135 else if (rt2x00_rt(rt2x00dev, RT3290) ||
4136 rt2x00_rt(rt2x00dev, RT5390) ||
4137 rt2x00_rt(rt2x00dev, RT5392))
4138 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4139 else
4140 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4141 4336
4142 if (rt2x00_rt(rt2x00dev, RT3290) || 4337 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4143 rt2x00_rt(rt2x00dev, RT3352) ||
4144 rt2x00_rt(rt2x00dev, RT5390) ||
4145 rt2x00_rt(rt2x00dev, RT5392))
4146 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4147 else
4148 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4149 4338
4150 if (rt2x00_rt(rt2x00dev, RT3352) || 4339 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4151 rt2x00_rt(rt2x00dev, RT5392)) 4340
4341 if (rt2x00_rt(rt2x00dev, RT5392))
4152 rt2800_bbp_write(rt2x00dev, 88, 0x90); 4342 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4153 4343
4154 rt2800_bbp_write(rt2x00dev, 91, 0x04); 4344 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4155 4345
4156 if (rt2x00_rt(rt2x00dev, RT3290) || 4346 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4157 rt2x00_rt(rt2x00dev, RT3352) ||
4158 rt2x00_rt(rt2x00dev, RT5390) ||
4159 rt2x00_rt(rt2x00dev, RT5392))
4160 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4161 else
4162 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4163 4347
4164 if (rt2x00_rt(rt2x00dev, RT5392)) { 4348 if (rt2x00_rt(rt2x00dev, RT5392)) {
4165 rt2800_bbp_write(rt2x00dev, 95, 0x9a); 4349 rt2800_bbp_write(rt2x00dev, 95, 0x9a);
4166 rt2800_bbp_write(rt2x00dev, 98, 0x12); 4350 rt2800_bbp_write(rt2x00dev, 98, 0x12);
4167 } 4351 }
4168 4352
4169 if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || 4353 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4170 rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
4171 rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
4172 rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
4173 rt2x00_rt(rt2x00dev, RT3290) ||
4174 rt2x00_rt(rt2x00dev, RT3352) ||
4175 rt2x00_rt(rt2x00dev, RT3572) ||
4176 rt2x00_rt(rt2x00dev, RT5390) ||
4177 rt2x00_rt(rt2x00dev, RT5392) ||
4178 rt2800_is_305x_soc(rt2x00dev))
4179 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4180 else
4181 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4182 4354
4183 if (rt2x00_rt(rt2x00dev, RT3290) || 4355 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4184 rt2x00_rt(rt2x00dev, RT3352) ||
4185 rt2x00_rt(rt2x00dev, RT5390) ||
4186 rt2x00_rt(rt2x00dev, RT5392))
4187 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4188 4356
4189 if (rt2800_is_305x_soc(rt2x00dev)) 4357 rt2800_bbp_write(rt2x00dev, 105, 0x3c);
4190 rt2800_bbp_write(rt2x00dev, 105, 0x01);
4191 else if (rt2x00_rt(rt2x00dev, RT3290))
4192 rt2800_bbp_write(rt2x00dev, 105, 0x1c);
4193 else if (rt2x00_rt(rt2x00dev, RT3352))
4194 rt2800_bbp_write(rt2x00dev, 105, 0x34);
4195 else if (rt2x00_rt(rt2x00dev, RT5390) ||
4196 rt2x00_rt(rt2x00dev, RT5392))
4197 rt2800_bbp_write(rt2x00dev, 105, 0x3c);
4198 else
4199 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4200 4358
4201 if (rt2x00_rt(rt2x00dev, RT3290) || 4359 if (rt2x00_rt(rt2x00dev, RT5390))
4202 rt2x00_rt(rt2x00dev, RT5390))
4203 rt2800_bbp_write(rt2x00dev, 106, 0x03); 4360 rt2800_bbp_write(rt2x00dev, 106, 0x03);
4204 else if (rt2x00_rt(rt2x00dev, RT3352))
4205 rt2800_bbp_write(rt2x00dev, 106, 0x05);
4206 else if (rt2x00_rt(rt2x00dev, RT5392)) 4361 else if (rt2x00_rt(rt2x00dev, RT5392))
4207 rt2800_bbp_write(rt2x00dev, 106, 0x12); 4362 rt2800_bbp_write(rt2x00dev, 106, 0x12);
4208 else 4363 else
4209 rt2800_bbp_write(rt2x00dev, 106, 0x35); 4364 WARN_ON(1);
4210
4211 if (rt2x00_rt(rt2x00dev, RT3352))
4212 rt2800_bbp_write(rt2x00dev, 120, 0x50);
4213 4365
4214 if (rt2x00_rt(rt2x00dev, RT3290) || 4366 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4215 rt2x00_rt(rt2x00dev, RT5390) ||
4216 rt2x00_rt(rt2x00dev, RT5392))
4217 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4218 4367
4219 if (rt2x00_rt(rt2x00dev, RT5392)) { 4368 if (rt2x00_rt(rt2x00dev, RT5392)) {
4220 rt2800_bbp_write(rt2x00dev, 134, 0xd0); 4369 rt2800_bbp_write(rt2x00dev, 134, 0xd0);
4221 rt2800_bbp_write(rt2x00dev, 135, 0xf6); 4370 rt2800_bbp_write(rt2x00dev, 135, 0xf6);
4222 } 4371 }
4223 4372
4224 if (rt2x00_rt(rt2x00dev, RT3352)) 4373 rt2800_disable_unused_dac_adc(rt2x00dev);
4225 rt2800_bbp_write(rt2x00dev, 137, 0x0f);
4226 4374
4227 if (rt2x00_rt(rt2x00dev, RT3071) || 4375 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4228 rt2x00_rt(rt2x00dev, RT3090) || 4376 div_mode = rt2x00_get_field16(eeprom,
4229 rt2x00_rt(rt2x00dev, RT3390) || 4377 EEPROM_NIC_CONF1_ANT_DIVERSITY);
4230 rt2x00_rt(rt2x00dev, RT3572) || 4378 ant = (div_mode == 3) ? 1 : 0;
4231 rt2x00_rt(rt2x00dev, RT5390) ||
4232 rt2x00_rt(rt2x00dev, RT5392)) {
4233 rt2800_bbp_read(rt2x00dev, 138, &value);
4234 4379
4235 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 4380 /* check if this is a Bluetooth combo card */
4236 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) 4381 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
4237 value |= 0x20; 4382 u32 reg;
4238 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
4239 value &= ~0x02;
4240 4383
4241 rt2800_bbp_write(rt2x00dev, 138, value); 4384 rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
4385 rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
4386 rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
4387 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
4388 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
4389 if (ant == 0)
4390 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
4391 else if (ant == 1)
4392 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
4393 rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
4242 } 4394 }
4243 4395
4244 if (rt2x00_rt(rt2x00dev, RT3290)) { 4396 /* This chip has hardware antenna diversity*/
4245 rt2800_bbp_write(rt2x00dev, 67, 0x24); 4397 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
4246 rt2800_bbp_write(rt2x00dev, 143, 0x04); 4398 rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
4247 rt2800_bbp_write(rt2x00dev, 142, 0x99); 4399 rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
4248 rt2800_bbp_write(rt2x00dev, 150, 0x30); 4400 rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
4249 rt2800_bbp_write(rt2x00dev, 151, 0x2e);
4250 rt2800_bbp_write(rt2x00dev, 152, 0x20);
4251 rt2800_bbp_write(rt2x00dev, 153, 0x34);
4252 rt2800_bbp_write(rt2x00dev, 154, 0x40);
4253 rt2800_bbp_write(rt2x00dev, 155, 0x3b);
4254 rt2800_bbp_write(rt2x00dev, 253, 0x04);
4255
4256 rt2800_bbp_read(rt2x00dev, 47, &value);
4257 rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
4258 rt2800_bbp_write(rt2x00dev, 47, value);
4259
4260 /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
4261 rt2800_bbp_read(rt2x00dev, 3, &value);
4262 rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
4263 rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
4264 rt2800_bbp_write(rt2x00dev, 3, value);
4265 } 4401 }
4266 4402
4267 if (rt2x00_rt(rt2x00dev, RT3352)) { 4403 rt2800_bbp_read(rt2x00dev, 152, &value);
4268 rt2800_bbp_write(rt2x00dev, 163, 0xbd); 4404 if (ant == 0)
4269 /* Set ITxBF timeout to 0x9c40=1000msec */ 4405 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4270 rt2800_bbp_write(rt2x00dev, 179, 0x02); 4406 else
4271 rt2800_bbp_write(rt2x00dev, 180, 0x00); 4407 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4272 rt2800_bbp_write(rt2x00dev, 182, 0x40); 4408 rt2800_bbp_write(rt2x00dev, 152, value);
4273 rt2800_bbp_write(rt2x00dev, 180, 0x01); 4409
4274 rt2800_bbp_write(rt2x00dev, 182, 0x9c); 4410 rt2800_init_freq_calibration(rt2x00dev);
4275 rt2800_bbp_write(rt2x00dev, 179, 0x00); 4411}
4276 /* Reprogram the inband interface to put right values in RXWI */ 4412
4277 rt2800_bbp_write(rt2x00dev, 142, 0x04); 4413static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
4278 rt2800_bbp_write(rt2x00dev, 143, 0x3b); 4414{
4279 rt2800_bbp_write(rt2x00dev, 142, 0x06); 4415 int ant, div_mode;
4280 rt2800_bbp_write(rt2x00dev, 143, 0xa0); 4416 u16 eeprom;
4281 rt2800_bbp_write(rt2x00dev, 142, 0x07); 4417 u8 value;
4282 rt2800_bbp_write(rt2x00dev, 143, 0xa1); 4418
4283 rt2800_bbp_write(rt2x00dev, 142, 0x08); 4419 rt2800_init_bbp_early(rt2x00dev);
4284 rt2800_bbp_write(rt2x00dev, 143, 0xa2); 4420
4285 4421 rt2800_bbp_read(rt2x00dev, 105, &value);
4286 rt2800_bbp_write(rt2x00dev, 148, 0xc8); 4422 rt2x00_set_field8(&value, BBP105_MLD,
4423 rt2x00dev->default_ant.rx_chain_num == 2);
4424 rt2800_bbp_write(rt2x00dev, 105, value);
4425
4426 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4427
4428 rt2800_bbp_write(rt2x00dev, 20, 0x06);
4429 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4430 rt2800_bbp_write(rt2x00dev, 65, 0x2C);
4431 rt2800_bbp_write(rt2x00dev, 68, 0xDD);
4432 rt2800_bbp_write(rt2x00dev, 69, 0x1A);
4433 rt2800_bbp_write(rt2x00dev, 70, 0x05);
4434 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4435 rt2800_bbp_write(rt2x00dev, 74, 0x0F);
4436 rt2800_bbp_write(rt2x00dev, 75, 0x4F);
4437 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4438 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4439 rt2800_bbp_write(rt2x00dev, 84, 0x9A);
4440 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4441 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4442 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4443 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4444 rt2800_bbp_write(rt2x00dev, 95, 0x9a);
4445 rt2800_bbp_write(rt2x00dev, 98, 0x12);
4446 rt2800_bbp_write(rt2x00dev, 103, 0xC0);
4447 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4448 /* FIXME BBP105 owerwrite */
4449 rt2800_bbp_write(rt2x00dev, 105, 0x3C);
4450 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4451 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4452 rt2800_bbp_write(rt2x00dev, 134, 0xD0);
4453 rt2800_bbp_write(rt2x00dev, 135, 0xF6);
4454 rt2800_bbp_write(rt2x00dev, 137, 0x0F);
4455
4456 /* Initialize GLRT (Generalized Likehood Radio Test) */
4457 rt2800_init_bbp_5592_glrt(rt2x00dev);
4458
4459 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4460
4461 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4462 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
4463 ant = (div_mode == 3) ? 1 : 0;
4464 rt2800_bbp_read(rt2x00dev, 152, &value);
4465 if (ant == 0) {
4466 /* Main antenna */
4467 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4468 } else {
4469 /* Auxiliary antenna */
4470 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4287 } 4471 }
4472 rt2800_bbp_write(rt2x00dev, 152, value);
4288 4473
4289 if (rt2x00_rt(rt2x00dev, RT5390) || 4474 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) {
4290 rt2x00_rt(rt2x00dev, RT5392)) { 4475 rt2800_bbp_read(rt2x00dev, 254, &value);
4291 int ant, div_mode; 4476 rt2x00_set_field8(&value, BBP254_BIT7, 1);
4477 rt2800_bbp_write(rt2x00dev, 254, value);
4478 }
4292 4479
4293 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 4480 rt2800_init_freq_calibration(rt2x00dev);
4294 div_mode = rt2x00_get_field16(eeprom,
4295 EEPROM_NIC_CONF1_ANT_DIVERSITY);
4296 ant = (div_mode == 3) ? 1 : 0;
4297 4481
4298 /* check if this is a Bluetooth combo card */ 4482 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4299 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { 4483 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
4300 u32 reg; 4484 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4301 4485}
4302 rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
4303 rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
4304 rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
4305 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
4306 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
4307 if (ant == 0)
4308 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
4309 else if (ant == 1)
4310 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
4311 rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
4312 }
4313 4486
4314 /* This chip has hardware antenna diversity*/ 4487static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4315 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) { 4488{
4316 rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */ 4489 unsigned int i;
4317 rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */ 4490 u16 eeprom;
4318 rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */ 4491 u8 reg_id;
4319 } 4492 u8 value;
4320 4493
4321 rt2800_bbp_read(rt2x00dev, 152, &value); 4494 if (rt2800_is_305x_soc(rt2x00dev))
4322 if (ant == 0) 4495 rt2800_init_bbp_305x_soc(rt2x00dev);
4323 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4324 else
4325 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4326 rt2800_bbp_write(rt2x00dev, 152, value);
4327 4496
4328 rt2800_init_freq_calibration(rt2x00dev); 4497 switch (rt2x00dev->chip.rt) {
4498 case RT2860:
4499 case RT2872:
4500 case RT2883:
4501 rt2800_init_bbp_28xx(rt2x00dev);
4502 break;
4503 case RT3070:
4504 case RT3071:
4505 case RT3090:
4506 rt2800_init_bbp_30xx(rt2x00dev);
4507 break;
4508 case RT3290:
4509 rt2800_init_bbp_3290(rt2x00dev);
4510 break;
4511 case RT3352:
4512 rt2800_init_bbp_3352(rt2x00dev);
4513 break;
4514 case RT3390:
4515 rt2800_init_bbp_3390(rt2x00dev);
4516 break;
4517 case RT3572:
4518 rt2800_init_bbp_3572(rt2x00dev);
4519 break;
4520 case RT5390:
4521 case RT5392:
4522 rt2800_init_bbp_53xx(rt2x00dev);
4523 break;
4524 case RT5592:
4525 rt2800_init_bbp_5592(rt2x00dev);
4526 return;
4329 } 4527 }
4330 4528
4331 for (i = 0; i < EEPROM_BBP_SIZE; i++) { 4529 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
@@ -4337,8 +4535,6 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4337 rt2800_bbp_write(rt2x00dev, reg_id, value); 4535 rt2800_bbp_write(rt2x00dev, reg_id, value);
4338 } 4536 }
4339 } 4537 }
4340
4341 return 0;
4342} 4538}
4343 4539
4344static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev) 4540static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev)
@@ -5189,9 +5385,11 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
5189 } 5385 }
5190 msleep(1); 5386 msleep(1);
5191 5387
5192 if (unlikely(rt2800_init_bbp(rt2x00dev))) 5388 if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
5389 rt2800_wait_bbp_ready(rt2x00dev)))
5193 return -EIO; 5390 return -EIO;
5194 5391
5392 rt2800_init_bbp(rt2x00dev);
5195 rt2800_init_rfcsr(rt2x00dev); 5393 rt2800_init_rfcsr(rt2x00dev);
5196 5394
5197 if (rt2x00_is_usb(rt2x00dev) && 5395 if (rt2x00_is_usb(rt2x00dev) &&
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 6f4a861af336..330f1d25726d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1014,7 +1014,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
1014 * Since we have only one producer and one consumer we don't 1014 * Since we have only one producer and one consumer we don't
1015 * need to lock the kfifo. 1015 * need to lock the kfifo.
1016 */ 1016 */
1017 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { 1017 for (i = 0; i < rt2x00dev->tx->limit; i++) {
1018 rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); 1018 rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
1019 1019
1020 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) 1020 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ac854d75bd6c..c71a48da9a31 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -327,7 +327,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
327 * this limit so reduce the number to prevent errors. 327 * this limit so reduce the number to prevent errors.
328 */ 328 */
329 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT, 329 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
330 ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE) 330 ((rt2x00dev->rx->limit * DATA_FRAME_SIZE)
331 / 1024) - 3); 331 / 1024) - 3);
332 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1); 332 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
333 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1); 333 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 90dc14336980..6a201725bc50 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1077,7 +1077,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
1077 */ 1077 */
1078 int kfifo_size = 1078 int kfifo_size =
1079 roundup_pow_of_two(rt2x00dev->ops->tx_queues * 1079 roundup_pow_of_two(rt2x00dev->ops->tx_queues *
1080 rt2x00dev->ops->tx->entry_num * 1080 rt2x00dev->tx->limit *
1081 sizeof(u32)); 1081 sizeof(u32));
1082 1082
1083 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, 1083 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
@@ -1301,23 +1301,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1301 (rt2x00dev->ops->max_ap_intf - 1); 1301 (rt2x00dev->ops->max_ap_intf - 1);
1302 1302
1303 /* 1303 /*
1304 * Determine which operating modes are supported, all modes
1305 * which require beaconing, depend on the availability of
1306 * beacon entries.
1307 */
1308 rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1309 if (rt2x00dev->ops->bcn->entry_num > 0)
1310 rt2x00dev->hw->wiphy->interface_modes |=
1311 BIT(NL80211_IFTYPE_ADHOC) |
1312 BIT(NL80211_IFTYPE_AP) |
1313#ifdef CONFIG_MAC80211_MESH
1314 BIT(NL80211_IFTYPE_MESH_POINT) |
1315#endif
1316 BIT(NL80211_IFTYPE_WDS);
1317
1318 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
1319
1320 /*
1321 * Initialize work. 1304 * Initialize work.
1322 */ 1305 */
1323 rt2x00dev->workqueue = 1306 rt2x00dev->workqueue =
@@ -1348,6 +1331,23 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1348 goto exit; 1331 goto exit;
1349 1332
1350 /* 1333 /*
1334 * Determine which operating modes are supported, all modes
1335 * which require beaconing, depend on the availability of
1336 * beacon entries.
1337 */
1338 rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1339 if (rt2x00dev->ops->bcn->entry_num > 0)
1340 rt2x00dev->hw->wiphy->interface_modes |=
1341 BIT(NL80211_IFTYPE_ADHOC) |
1342 BIT(NL80211_IFTYPE_AP) |
1343#ifdef CONFIG_MAC80211_MESH
1344 BIT(NL80211_IFTYPE_MESH_POINT) |
1345#endif
1346 BIT(NL80211_IFTYPE_WDS);
1347
1348 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
1349
1350 /*
1351 * Initialize ieee80211 structure. 1351 * Initialize ieee80211 structure.
1352 */ 1352 */
1353 retval = rt2x00lib_probe_hw(rt2x00dev); 1353 retval = rt2x00lib_probe_hw(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index dc49e525ae5e..76d95deb274b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -105,11 +105,13 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
105 goto exit_release_regions; 105 goto exit_release_regions;
106 } 106 }
107 107
108 pci_enable_msi(pci_dev);
109
108 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); 110 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
109 if (!hw) { 111 if (!hw) {
110 rt2x00_probe_err("Failed to allocate hardware\n"); 112 rt2x00_probe_err("Failed to allocate hardware\n");
111 retval = -ENOMEM; 113 retval = -ENOMEM;
112 goto exit_release_regions; 114 goto exit_disable_msi;
113 } 115 }
114 116
115 pci_set_drvdata(pci_dev, hw); 117 pci_set_drvdata(pci_dev, hw);
@@ -150,6 +152,9 @@ exit_free_reg:
150exit_free_device: 152exit_free_device:
151 ieee80211_free_hw(hw); 153 ieee80211_free_hw(hw);
152 154
155exit_disable_msi:
156 pci_disable_msi(pci_dev);
157
153exit_release_regions: 158exit_release_regions:
154 pci_release_regions(pci_dev); 159 pci_release_regions(pci_dev);
155 160
@@ -174,6 +179,8 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
174 rt2x00pci_free_reg(rt2x00dev); 179 rt2x00pci_free_reg(rt2x00dev);
175 ieee80211_free_hw(hw); 180 ieee80211_free_hw(hw);
176 181
182 pci_disable_msi(pci_dev);
183
177 /* 184 /*
178 * Free the PCI device data. 185 * Free the PCI device data.
179 */ 186 */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0dc8180e251b..7e1759b3e49a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2175,7 +2175,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2175 * that the TX_STA_FIFO stack has a size of 16. We stick to our 2175 * that the TX_STA_FIFO stack has a size of 16. We stick to our
2176 * tx ring size for now. 2176 * tx ring size for now.
2177 */ 2177 */
2178 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { 2178 for (i = 0; i < rt2x00dev->tx->limit; i++) {
2179 rt2x00mmio_register_read(rt2x00dev, STA_CSR4, &reg); 2179 rt2x00mmio_register_read(rt2x00dev, STA_CSR4, &reg);
2180 if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) 2180 if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
2181 break; 2181 break;
diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h
new file mode 100644
index 000000000000..c6fbc3ce4ab0
--- /dev/null
+++ b/include/linux/platform_data/net-cw1200.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2011
3 *
4 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7
8#ifndef CW1200_PLAT_H_INCLUDED
9#define CW1200_PLAT_H_INCLUDED
10
11struct cw1200_platform_data_spi {
12 u8 spi_bits_per_word; /* REQUIRED */
13 u16 ref_clk; /* REQUIRED (in KHz) */
14
15 /* All others are optional */
16 bool have_5ghz;
17 int reset; /* GPIO to RSTn signal (0 disables) */
18 int powerup; /* GPIO to POWERUP signal (0 disables) */
19 int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
20 bool enable); /* Control 3v3 / 1v8 supply */
21 int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
22 bool enable); /* Control CLK32K */
23 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
24 const char *sdd_file; /* if NULL, will use default for detected hw type */
25};
26
27struct cw1200_platform_data_sdio {
28 u16 ref_clk; /* REQUIRED (in KHz) */
29
30 /* All others are optional */
31 bool have_5ghz;
32 bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
33 int reset; /* GPIO to RSTn signal (0 disables) */
34 int powerup; /* GPIO to POWERUP signal (0 disables) */
35 int irq; /* IRQ line or 0 to use SDIO IRQ */
36 int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
37 bool enable); /* Control 3v3 / 1v8 supply */
38 int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
39 bool enable); /* Control CLK32K */
40 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
41 const char *sdd_file; /* if NULL, will use default for detected hw type */
42};
43
44
45/* An example of SPI support in your board setup file:
46
47 static struct cw1200_platform_data_spi cw1200_platform_data = {
48 .ref_clk = 38400,
49 .spi_bits_per_word = 16,
50 .reset = GPIO_RF_RESET,
51 .powerup = GPIO_RF_POWERUP,
52 .macaddr = wifi_mac_addr,
53 .sdd_file = "sdd_sagrad_1091_1098.bin",
54 };
55 static struct spi_board_info myboard_spi_devices[] __initdata = {
56 {
57 .modalias = "cw1200_wlan_spi",
58 .max_speed_hz = 52000000,
59 .bus_num = 0,
60 .irq = WIFI_IRQ,
61 .platform_data = &cw1200_platform_data,
62 .chip_select = 0,
63 },
64 };
65
66 */
67
68/* An example of SDIO support in your board setup file:
69
70 static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
71 .ref_clk = 38400,
72 .have_5ghz = false,
73 .sdd_file = "sdd_myplatform.bin",
74 };
75 cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
76
77 */
78
79void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
80
81#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 3a7256955b10..f9f931c89e3e 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -172,6 +172,7 @@
172#define SSB_SPROMSIZE_WORDS_R4 220 172#define SSB_SPROMSIZE_WORDS_R4 220
173#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) 173#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
174#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) 174#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
175#define SSB_SPROMSIZE_WORDS_R10 230
175#define SSB_SPROM_BASE1 0x1000 176#define SSB_SPROM_BASE1 0x1000
176#define SSB_SPROM_BASE31 0x0800 177#define SSB_SPROM_BASE31 0x0800
177#define SSB_SPROM_REVISION 0x007E 178#define SSB_SPROM_REVISION 0x007E