aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/b44.c10
-rw-r--r--drivers/net/wireless/Kconfig57
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c420
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h1
-rw-r--r--drivers/net/wireless/ath/regd.h6
-rw-r--r--drivers/net/wireless/ath/regd_common.h6
-rw-r--r--drivers/net/wireless/b43/Kconfig4
-rw-r--r--drivers/net/wireless/b43/b43.h30
-rw-r--r--drivers/net/wireless/b43/debugfs.c67
-rw-r--r--drivers/net/wireless/b43/debugfs.h3
-rw-r--r--drivers/net/wireless/b43/dma.c31
-rw-r--r--drivers/net/wireless/b43/dma.h3
-rw-r--r--drivers/net/wireless/b43/main.c460
-rw-r--r--drivers/net/wireless/b43/main.h4
-rw-r--r--drivers/net/wireless/b43/phy_common.c1
-rw-r--r--drivers/net/wireless/b43/phy_common.h3
-rw-r--r--drivers/net/wireless/b43/phy_g.c7
-rw-r--r--drivers/net/wireless/b43/phy_g.h3
-rw-r--r--drivers/net/wireless/b43/pio.c71
-rw-r--r--drivers/net/wireless/b43/pio.h6
-rw-r--r--drivers/net/wireless/b43/sysfs.c3
-rw-r--r--drivers/net/wireless/b43/xmit.c10
-rw-r--r--drivers/net/wireless/b43legacy/main.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
41 files changed, 838 insertions, 526 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 951735c9ec0b..0189dcd36f31 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1303,10 +1303,13 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
1303 & MDIO_CTRL_MAXF_MASK))); 1303 & MDIO_CTRL_MAXF_MASK)));
1304 break; 1304 break;
1305 case SSB_BUSTYPE_PCI: 1305 case SSB_BUSTYPE_PCI:
1306 case SSB_BUSTYPE_PCMCIA:
1307 bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE | 1306 bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
1308 (0x0d & MDIO_CTRL_MAXF_MASK))); 1307 (0x0d & MDIO_CTRL_MAXF_MASK)));
1309 break; 1308 break;
1309 case SSB_BUSTYPE_PCMCIA:
1310 case SSB_BUSTYPE_SDIO:
1311 WARN_ON(1); /* A device with this bus does not exist. */
1312 break;
1310 } 1313 }
1311 1314
1312 br32(bp, B44_MDIO_CTRL); 1315 br32(bp, B44_MDIO_CTRL);
@@ -1764,10 +1767,13 @@ static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *inf
1764 case SSB_BUSTYPE_PCI: 1767 case SSB_BUSTYPE_PCI:
1765 strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info)); 1768 strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
1766 break; 1769 break;
1767 case SSB_BUSTYPE_PCMCIA:
1768 case SSB_BUSTYPE_SSB: 1770 case SSB_BUSTYPE_SSB:
1769 strlcpy(info->bus_info, "SSB", sizeof(info->bus_info)); 1771 strlcpy(info->bus_info, "SSB", sizeof(info->bus_info));
1770 break; 1772 break;
1773 case SSB_BUSTYPE_PCMCIA:
1774 case SSB_BUSTYPE_SDIO:
1775 WARN_ON(1); /* A device with this bus does not exist. */
1776 break;
1771 } 1777 }
1772} 1778}
1773 1779
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index a8871a84d87e..ad89d23968df 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -275,51 +275,26 @@ config PCMCIA_WL3501
275 micro support for ethtool. 275 micro support for ethtool.
276 276
277config PRISM54 277config PRISM54
278 tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus' 278 tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)'
279 depends on PCI && EXPERIMENTAL && WLAN_80211 279 depends on PCI && EXPERIMENTAL && WLAN_80211
280 select WIRELESS_EXT 280 select WIRELESS_EXT
281 select FW_LOADER 281 select FW_LOADER
282 ---help--- 282 ---help---
283 Enable PCI and Cardbus support for the following chipset based cards: 283 This enables support for FullMAC PCI/Cardbus prism54 devices. This
284 284 driver is now deprecated in favor for the SoftMAC driver, p54pci.
285 ISL3880 - Prism GT 802.11 b/g 285 p54pci supports FullMAC PCI/Cardbus devices as well. For details on
286 ISL3877 - Prism Indigo 802.11 a 286 the scheduled removal of this driver on the kernel see the feature
287 ISL3890 - Prism Duette 802.11 a/b/g 287 removal schedule:
288 288
289 For a complete list of supported cards visit <http://prism54.org>. 289 Documentation/feature-removal-schedule.txt
290 Here is the latest confirmed list of supported cards: 290
291 291 For more information refer to the p54 wiki:
292 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1) 292
293 Allnet ALL0271 PCI Card 293 http://wireless.kernel.org/en/users/Drivers/p54
294 Compex WL54G Cardbus Card 294
295 Corega CG-WLCB54GT Cardbus Card 295 Note: You need a motherboard with DMA support to use any of these cards
296 D-Link Air Plus Xtreme G A1 Cardbus Card aka DWL-g650 296
297 I-O Data WN-G54/CB Cardbus Card 297 When built as module you get the module prism54
298 Kobishi XG-300 aka Z-Com Cardbus Card
299 Netgear WG511 Cardbus Card
300 Ovislink WL-5400PCI PCI Card
301 Peabird WLG-PCI PCI Card
302 Sitecom WL-100i Cardbus Card
303 Sitecom WL-110i PCI Card
304 SMC2802W - EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card
305 SMC2835W - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
306 SMC2835W-V2 - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
307 Z-Com XG-900 PCI Card
308 Zyxel G-100 Cardbus Card
309
310 If you enable this you will need a firmware file as well.
311 You will need to copy this to /usr/lib/hotplug/firmware/isl3890.
312 You can get this non-GPL'd firmware file from the Prism54 project page:
313 <http://prism54.org>
314 You will also need the /etc/hotplug/firmware.agent script from
315 a current hotplug package.
316
317 Note: You need a motherboard with DMA support to use any of these cards
318
319 If you want to compile the driver as a module ( = code which can be
320 inserted in and removed from the running kernel whenever you want),
321 say M here and read <file:Documentation/kbuild/modules.txt>.
322 The module will be called prism54.
323 298
324config USB_ZD1201 299config USB_ZD1201
325 tristate "USB ZD1201 based Wireless device support" 300 tristate "USB ZD1201 based Wireless device support"
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index df86f70cd817..b3e5cf3735b0 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -396,6 +396,136 @@ static struct ar9170_phy_init ar5416_phy_init[] = {
396 { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } 396 { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
397}; 397};
398 398
399/*
400 * look up a certain register in ar5416_phy_init[] and return the init. value
401 * for the band and bandwidth given. Return 0 if register address not found.
402 */
403static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
404{
405 unsigned int i;
406 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
407 if (ar5416_phy_init[i].reg != reg)
408 continue;
409
410 if (is_2ghz) {
411 if (is_40mhz)
412 return ar5416_phy_init[i]._2ghz_40;
413 else
414 return ar5416_phy_init[i]._2ghz_20;
415 } else {
416 if (is_40mhz)
417 return ar5416_phy_init[i]._5ghz_40;
418 else
419 return ar5416_phy_init[i]._5ghz_20;
420 }
421 }
422 return 0;
423}
424
425/*
426 * initialize some phy regs from eeprom values in modal_header[]
427 * acc. to band and bandwith
428 */
429static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
430 bool is_2ghz, bool is_40mhz)
431{
432 static const u8 xpd2pd[16] = {
433 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
434 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
435 };
436 u32 defval, newval;
437 /* pointer to the modal_header acc. to band */
438 struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
439
440 ar9170_regwrite_begin(ar);
441
442 /* ant common control (index 0) */
443 newval = le32_to_cpu(m->antCtrlCommon);
444 ar9170_regwrite(0x1c5964, newval);
445
446 /* ant control chain 0 (index 1) */
447 newval = le32_to_cpu(m->antCtrlChain[0]);
448 ar9170_regwrite(0x1c5960, newval);
449
450 /* ant control chain 2 (index 2) */
451 newval = le32_to_cpu(m->antCtrlChain[1]);
452 ar9170_regwrite(0x1c7960, newval);
453
454 /* SwSettle (index 3) */
455 if (!is_40mhz) {
456 defval = ar9170_get_default_phy_reg_val(0x1c5844,
457 is_2ghz, is_40mhz);
458 newval = (defval & ~0x3f80) |
459 ((m->switchSettling & 0x7f) << 7);
460 ar9170_regwrite(0x1c5844, newval);
461 }
462
463 /* adcDesired, pdaDesired (index 4) */
464 defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
465 newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
466 ((u8)m->adcDesiredSize);
467 ar9170_regwrite(0x1c5850, newval);
468
469 /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
470 defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
471 newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
472 (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
473 ar9170_regwrite(0x1c5834, newval);
474
475 /* TxEndToRxOn (index 6) */
476 defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
477 newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
478 ar9170_regwrite(0x1c5828, newval);
479
480 /* thresh62 (index 7) */
481 defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
482 newval = (defval & ~0x7f000) | (m->thresh62 << 12);
483 ar9170_regwrite(0x1c8864, newval);
484
485 /* tx/rx attenuation chain 0 (index 8) */
486 defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
487 newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
488 ar9170_regwrite(0x1c5848, newval);
489
490 /* tx/rx attenuation chain 2 (index 9) */
491 defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
492 newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
493 ar9170_regwrite(0x1c7848, newval);
494
495 /* tx/rx margin chain 0 (index 10) */
496 defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
497 newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
498 /* bsw margin chain 0 for 5GHz only */
499 if (!is_2ghz)
500 newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
501 ar9170_regwrite(0x1c620c, newval);
502
503 /* tx/rx margin chain 2 (index 11) */
504 defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
505 newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
506 ar9170_regwrite(0x1c820c, newval);
507
508 /* iqCall, iqCallq chain 0 (index 12) */
509 defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
510 newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
511 ((u8)m->iqCalQCh[0] & 0x1f);
512 ar9170_regwrite(0x1c5920, newval);
513
514 /* iqCall, iqCallq chain 2 (index 13) */
515 defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
516 newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
517 ((u8)m->iqCalQCh[1] & 0x1f);
518 ar9170_regwrite(0x1c7920, newval);
519
520 /* xpd gain mask (index 14) */
521 defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
522 newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
523 ar9170_regwrite(0x1c6258, newval);
524 ar9170_regwrite_finish();
525
526 return ar9170_regwrite_result();
527}
528
399int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) 529int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
400{ 530{
401 int i, err; 531 int i, err;
@@ -426,7 +556,9 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
426 if (err) 556 if (err)
427 return err; 557 return err;
428 558
429 /* XXX: use EEPROM data here! */ 559 err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
560 if (err)
561 return err;
430 562
431 err = ar9170_init_power_cal(ar); 563 err = ar9170_init_power_cal(ar);
432 if (err) 564 if (err)
@@ -987,6 +1119,282 @@ static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
987#undef SHIFT 1119#undef SHIFT
988} 1120}
989 1121
1122static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
1123{
1124 int i;
1125
1126 for (i = 0; i < 3; i++)
1127 if (x <= x_array[i + 1])
1128 break;
1129
1130 return ar9170_interpolate_u8(x,
1131 x_array[i],
1132 y_array[i],
1133 x_array[i + 1],
1134 y_array[i + 1]);
1135}
1136
1137static int ar9170_set_freq_cal_data(struct ar9170 *ar,
1138 struct ieee80211_channel *channel)
1139{
1140 u8 *cal_freq_pier;
1141 u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
1142 u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
1143 int chain, idx, i;
1144 u8 f;
1145
1146 switch (channel->band) {
1147 case IEEE80211_BAND_2GHZ:
1148 f = channel->center_freq - 2300;
1149 cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
1150 i = AR5416_NUM_2G_CAL_PIERS - 1;
1151 break;
1152
1153 case IEEE80211_BAND_5GHZ:
1154 f = (channel->center_freq - 4800) / 5;
1155 cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
1156 i = AR5416_NUM_5G_CAL_PIERS - 1;
1157 break;
1158
1159 default:
1160 return -EINVAL;
1161 break;
1162 }
1163
1164 for (; i >= 0; i--) {
1165 if (cal_freq_pier[i] != 0xff)
1166 break;
1167 }
1168 if (i < 0)
1169 return -EINVAL;
1170
1171 idx = ar9170_find_freq_idx(i, cal_freq_pier, f);
1172
1173 ar9170_regwrite_begin(ar);
1174
1175 for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
1176 for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
1177 struct ar9170_calibration_data_per_freq *cal_pier_data;
1178 int j;
1179
1180 switch (channel->band) {
1181 case IEEE80211_BAND_2GHZ:
1182 cal_pier_data = &ar->eeprom.
1183 cal_pier_data_2G[chain][idx];
1184 break;
1185
1186 case IEEE80211_BAND_5GHZ:
1187 cal_pier_data = &ar->eeprom.
1188 cal_pier_data_5G[chain][idx];
1189 break;
1190
1191 default:
1192 return -EINVAL;
1193 }
1194
1195 for (j = 0; j < 2; j++) {
1196 vpds[j][i] = ar9170_interpolate_u8(f,
1197 cal_freq_pier[idx],
1198 cal_pier_data->vpd_pdg[j][i],
1199 cal_freq_pier[idx + 1],
1200 cal_pier_data[1].vpd_pdg[j][i]);
1201
1202 pwrs[j][i] = ar9170_interpolate_u8(f,
1203 cal_freq_pier[idx],
1204 cal_pier_data->pwr_pdg[j][i],
1205 cal_freq_pier[idx + 1],
1206 cal_pier_data[1].pwr_pdg[j][i]) / 2;
1207 }
1208 }
1209
1210 for (i = 0; i < 76; i++) {
1211 u32 phy_data;
1212 u8 tmp;
1213
1214 if (i < 25) {
1215 tmp = ar9170_interpolate_val(i, &pwrs[0][0],
1216 &vpds[0][0]);
1217 } else {
1218 tmp = ar9170_interpolate_val(i - 12,
1219 &pwrs[1][0],
1220 &vpds[1][0]);
1221 }
1222
1223 phy_data |= tmp << ((i & 3) << 3);
1224 if ((i & 3) == 3) {
1225 ar9170_regwrite(0x1c6280 + chain * 0x1000 +
1226 (i & ~3), phy_data);
1227 phy_data = 0;
1228 }
1229 }
1230
1231 for (i = 19; i < 32; i++)
1232 ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
1233 0x0);
1234 }
1235
1236 ar9170_regwrite_finish();
1237 return ar9170_regwrite_result();
1238}
1239
1240static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
1241 struct ar9170_calctl_edges edges[],
1242 u32 freq)
1243{
1244/* TODO: move somewhere else */
1245#define AR5416_MAX_RATE_POWER 63
1246
1247 int i;
1248 u8 rc = AR5416_MAX_RATE_POWER;
1249 u8 f;
1250 if (freq < 3000)
1251 f = freq - 2300;
1252 else
1253 f = (freq - 4800) / 5;
1254
1255 for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
1256 if (edges[i].channel == 0xff)
1257 break;
1258 if (f == edges[i].channel) {
1259 /* exact freq match */
1260 rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
1261 break;
1262 }
1263 if (i > 0 && f < edges[i].channel) {
1264 if (f > edges[i-1].channel &&
1265 edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
1266 /* lower channel has the inband flag set */
1267 rc = edges[i-1].power_flags &
1268 ~AR9170_CALCTL_EDGE_FLAGS;
1269 }
1270 break;
1271 }
1272 }
1273
1274 if (i == AR5416_NUM_BAND_EDGES) {
1275 if (f > edges[i-1].channel &&
1276 edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
1277 /* lower channel has the inband flag set */
1278 rc = edges[i-1].power_flags &
1279 ~AR9170_CALCTL_EDGE_FLAGS;
1280 }
1281 }
1282 return rc;
1283}
1284
1285/* calculate the conformance test limits and apply them to ar->power*
1286 * (derived from otus hal/hpmain.c, line 3706 ff.)
1287 */
1288static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1289{
1290 u8 ctl_grp; /* CTL group */
1291 u8 ctl_idx; /* CTL index */
1292 int i, j;
1293 struct ctl_modes {
1294 u8 ctl_mode;
1295 u8 max_power;
1296 u8 *pwr_cal_data;
1297 int pwr_cal_len;
1298 } *modes;
1299
1300 /* order is relevant in the mode_list_*: we fall back to the
1301 * lower indices if any mode is missed in the EEPROM.
1302 */
1303 struct ctl_modes mode_list_2ghz[] = {
1304 { CTL_11B, 0, ar->power_2G_cck, 4 },
1305 { CTL_11G, 0, ar->power_2G_ofdm, 4 },
1306 { CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
1307 { CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
1308 };
1309 struct ctl_modes mode_list_5ghz[] = {
1310 { CTL_11A, 0, ar->power_5G_leg, 4 },
1311 { CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
1312 { CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
1313 };
1314 int nr_modes;
1315
1316#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
1317
1318 /* TODO: investigate the differences between OTUS'
1319 * hpreg.c::zfHpGetRegulatoryDomain() and
1320 * ath/regd.c::ath_regd_get_band_ctl() -
1321 * e.g. for FCC3_WORLD the OTUS procedure
1322 * always returns CTL_FCC, while the one in ath/ delivers
1323 * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
1324 */
1325 ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
1326 ar->hw->conf.channel->band);
1327
1328 /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
1329 if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
1330 ctl_grp = CTL_FCC;
1331
1332 if (ctl_grp != CTL_FCC)
1333 /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
1334 return;
1335
1336 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
1337 modes = mode_list_2ghz;
1338 nr_modes = ARRAY_SIZE(mode_list_2ghz);
1339 } else {
1340 modes = mode_list_5ghz;
1341 nr_modes = ARRAY_SIZE(mode_list_5ghz);
1342 }
1343
1344 for (i = 0; i < nr_modes; i++) {
1345 u8 c = ctl_grp | modes[i].ctl_mode;
1346 for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
1347 if (c == ar->eeprom.ctl_index[ctl_idx])
1348 break;
1349 if (ctl_idx < AR5416_NUM_CTLS) {
1350 int f_off = 0;
1351
1352 /* adjust freq for 40MHz */
1353 if (modes[i].ctl_mode == CTL_2GHT40 ||
1354 modes[i].ctl_mode == CTL_5GHT40) {
1355 if (bw == AR9170_BW_40_BELOW)
1356 f_off = -10;
1357 else
1358 f_off = 10;
1359 }
1360
1361 modes[i].max_power =
1362 ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
1363 freq+f_off);
1364
1365 /* TODO: check if the regulatory max. power is
1366 * controlled by cfg80211 for DFS
1367 * (hpmain applies it to max_power itself for DFS freq)
1368 */
1369
1370 } else {
1371 /* Workaround in otus driver, hpmain.c, line 3906:
1372 * if no data for 5GHT20 are found, take the
1373 * legacy 5G value.
1374 * We extend this here to fallback from any other *HT or
1375 * 11G, too.
1376 */
1377 int k = i;
1378
1379 modes[i].max_power = AR5416_MAX_RATE_POWER;
1380 while (k-- > 0) {
1381 if (modes[k].max_power !=
1382 AR5416_MAX_RATE_POWER) {
1383 modes[i].max_power = modes[k].max_power;
1384 break;
1385 }
1386 }
1387 }
1388
1389 /* apply max power to pwr_cal_data (ar->power_*) */
1390 for (j = 0; j < modes[i].pwr_cal_len; j++) {
1391 modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
1392 modes[i].max_power);
1393 }
1394 }
1395#undef EDGES
1396}
1397
990static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) 1398static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
991{ 1399{
992 struct ar9170_calibration_target_power_legacy *ctpl; 1400 struct ar9170_calibration_target_power_legacy *ctpl;
@@ -1089,6 +1497,12 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1089 ctph[idx + 1].power[n]); 1497 ctph[idx + 1].power[n]);
1090 } 1498 }
1091 1499
1500
1501 /* calc. conformance test limits and apply to ar->power*[] */
1502 ar9170_calc_ctl(ar, freq, bw);
1503
1504 /* TODO: (heavy clip) regulatory domain power level fine-tuning. */
1505
1092 /* set ACK/CTS TX power */ 1506 /* set ACK/CTS TX power */
1093 ar9170_regwrite_begin(ar); 1507 ar9170_regwrite_begin(ar);
1094 1508
@@ -1207,6 +1621,10 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1207 if (err) 1621 if (err)
1208 return err; 1622 return err;
1209 1623
1624 err = ar9170_set_freq_cal_data(ar, channel);
1625 if (err)
1626 return err;
1627
1210 err = ar9170_set_power_cal(ar, channel->center_freq, bw); 1628 err = ar9170_set_power_cal(ar, channel->center_freq, bw);
1211 if (err) 1629 if (err)
1212 return err; 1630 return err;
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 5618fc25d52f..2ad7d0280f7a 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -119,17 +119,15 @@ static int ath_ahb_probe(struct platform_device *pdev)
119 sc->bus_ops = &ath_ahb_bus_ops; 119 sc->bus_ops = &ath_ahb_bus_ops;
120 sc->irq = irq; 120 sc->irq = irq;
121 121
122 ret = ath_init_device(AR5416_AR9100_DEVID, sc); 122 ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0);
123 if (ret != 0) { 123 if (ret) {
124 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); 124 dev_err(&pdev->dev, "failed to initialize device\n");
125 ret = -ENODEV;
126 goto err_free_hw; 125 goto err_free_hw;
127 } 126 }
128 127
129 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); 128 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
130 if (ret) { 129 if (ret) {
131 dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret); 130 dev_err(&pdev->dev, "request_irq failed\n");
132 ret = -EIO;
133 goto err_detach; 131 goto err_detach;
134 } 132 }
135 133
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1c68a9da22d4..1d59f10f68da 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -658,7 +658,7 @@ extern struct ieee80211_ops ath9k_ops;
658 658
659irqreturn_t ath_isr(int irq, void *dev); 659irqreturn_t ath_isr(int irq, void *dev);
660void ath_cleanup(struct ath_softc *sc); 660void ath_cleanup(struct ath_softc *sc);
661int ath_init_device(u16 devid, struct ath_softc *sc); 661int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid);
662void ath_detach(struct ath_softc *sc); 662void ath_detach(struct ath_softc *sc);
663const char *ath_mac_bb_name(u32 mac_bb_version); 663const char *ath_mac_bb_name(u32 mac_bb_version);
664const char *ath_rf_name(u16 rf_version); 664const char *ath_rf_name(u16 rf_version);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index e8bfb01ee78a..55f607b7699e 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -19,6 +19,29 @@
19static const struct ath_btcoex_config ath_bt_config = { 0, true, true, 19static const struct ath_btcoex_config ath_bt_config = { 0, true, true,
20 ATH_BT_COEX_MODE_SLOTTED, true, true, 2, 5, true }; 20 ATH_BT_COEX_MODE_SLOTTED, true, true, 2, 5, true };
21 21
22static const u16 ath_subsysid_tbl[] = {
23 AR9280_COEX2WIRE_SUBSYSID,
24 AT9285_COEX3WIRE_SA_SUBSYSID,
25 AT9285_COEX3WIRE_DA_SUBSYSID
26};
27
28/*
29 * Checks the subsystem id of the device to see if it
30 * supports btcoex
31 */
32bool ath_btcoex_supported(u16 subsysid)
33{
34 int i;
35
36 if (!subsysid)
37 return false;
38
39 for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
40 if (subsysid == ath_subsysid_tbl[i])
41 return true;
42
43 return false;
44}
22 45
23/* 46/*
24 * Detects if there is any priority bt traffic 47 * Detects if there is any priority bt traffic
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 45568196c59a..297b027fd3c3 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -19,6 +19,7 @@
19 19
20#define ATH_WLANACTIVE_GPIO 5 20#define ATH_WLANACTIVE_GPIO 5
21#define ATH_BTACTIVE_GPIO 6 21#define ATH_BTACTIVE_GPIO 6
22#define ATH_BTPRIORITY_GPIO 7
22 23
23#define ATH_BTCOEX_DEF_BT_PERIOD 45 24#define ATH_BTCOEX_DEF_BT_PERIOD 45
24#define ATH_BTCOEX_DEF_DUTY_CYCLE 55 25#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
@@ -79,6 +80,7 @@ struct ath_btcoex_info {
79 struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/ 80 struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
80}; 81};
81 82
83bool ath_btcoex_supported(u16 subsysid);
82int ath9k_hw_btcoex_init(struct ath_hw *ah); 84int ath9k_hw_btcoex_init(struct ath_hw *ah);
83void ath9k_hw_btcoex_enable(struct ath_hw *ah); 85void ath9k_hw_btcoex_enable(struct ath_hw *ah);
84void ath9k_hw_btcoex_disable(struct ath_hw *ah); 86void ath9k_hw_btcoex_disable(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 71f27f324cea..b6c6cca07812 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -16,14 +16,11 @@
16 16
17#include <linux/io.h> 17#include <linux/io.h>
18#include <asm/unaligned.h> 18#include <asm/unaligned.h>
19#include <linux/pci.h>
19 20
20#include "ath9k.h" 21#include "ath9k.h"
21#include "initvals.h" 22#include "initvals.h"
22 23
23static int btcoex_enable;
24module_param(btcoex_enable, bool, 0);
25MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
26
27#define ATH9K_CLOCK_RATE_CCK 22 24#define ATH9K_CLOCK_RATE_CCK 22
28#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 25#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
29#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 26#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
@@ -3689,14 +3686,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3689 pCap->num_antcfg_2ghz = 3686 pCap->num_antcfg_2ghz =
3690 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); 3687 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
3691 3688
3692 if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) { 3689 if (AR_SREV_9280_10_OR_LATER(ah) &&
3690 ath_btcoex_supported(ah->hw_version.subsysid)) {
3693 btcoex_info->btactive_gpio = ATH_BTACTIVE_GPIO; 3691 btcoex_info->btactive_gpio = ATH_BTACTIVE_GPIO;
3694 btcoex_info->wlanactive_gpio = ATH_WLANACTIVE_GPIO; 3692 btcoex_info->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
3695 3693
3696 if (AR_SREV_9285(ah)) 3694 if (AR_SREV_9285(ah)) {
3697 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_3WIRE; 3695 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_3WIRE;
3698 else 3696 btcoex_info->btpriority_gpio = ATH_BTPRIORITY_GPIO;
3697 } else {
3699 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_2WIRE; 3698 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_2WIRE;
3699 }
3700 } else { 3700 } else {
3701 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_NONE; 3701 btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_NONE;
3702 } 3702 }
@@ -3967,7 +3967,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
3967{ 3967{
3968 u32 phybits; 3968 u32 phybits;
3969 3969
3970 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR); 3970 REG_WRITE(ah, AR_RX_FILTER, bits);
3971
3971 phybits = 0; 3972 phybits = 0;
3972 if (bits & ATH9K_RX_FILTER_PHYRADAR) 3973 if (bits & ATH9K_RX_FILTER_PHYRADAR)
3973 phybits |= AR_PHY_ERR_RADAR; 3974 phybits |= AR_PHY_ERR_RADAR;
@@ -4297,3 +4298,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
4297 timer->trigger(timer->arg); 4298 timer->trigger(timer->arg);
4298 } 4299 }
4299} 4300}
4301
4302/*
4303 * Primitive to disable ASPM
4304 */
4305void ath_pcie_aspm_disable(struct ath_softc *sc)
4306{
4307 struct pci_dev *pdev = to_pci_dev(sc->dev);
4308 u8 aspm;
4309
4310 pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
4311 aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
4312 pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
4313}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 5ca6ffa70912..9106a0b537dd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -45,6 +45,10 @@
45#define AR5416_DEVID_AR9287_PCI 0x002D 45#define AR5416_DEVID_AR9287_PCI 0x002D
46#define AR5416_DEVID_AR9287_PCIE 0x002E 46#define AR5416_DEVID_AR9287_PCIE 0x002E
47 47
48#define AR9280_COEX2WIRE_SUBSYSID 0x309b
49#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
50#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
51
48/* Register read/write primitives */ 52/* Register read/write primitives */
49#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) 53#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
50#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) 54#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
@@ -390,6 +394,7 @@ struct ath9k_hw_version {
390 u16 phyRev; 394 u16 phyRev;
391 u16 analog5GhzRev; 395 u16 analog5GhzRev;
392 u16 analog2GhzRev; 396 u16 analog2GhzRev;
397 u16 subsysid;
393}; 398};
394 399
395/* Generic TSF timer definitions */ 400/* Generic TSF timer definitions */
@@ -665,4 +670,9 @@ void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
665void ath_gen_timer_isr(struct ath_hw *hw); 670void ath_gen_timer_isr(struct ath_hw *hw);
666u32 ath9k_hw_gettsf32(struct ath_hw *ah); 671u32 ath9k_hw_gettsf32(struct ath_hw *ah);
667 672
673#define ATH_PCIE_CAP_LINK_CTRL 0x70
674#define ATH_PCIE_CAP_LINK_L0S 1
675#define ATH_PCIE_CAP_LINK_L1 2
676
677void ath_pcie_aspm_disable(struct ath_softc *sc);
668#endif 678#endif
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7b3982295a43..f56e77da6c3e 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -568,6 +568,7 @@ enum ath9k_rx_filter {
568 ATH9K_RX_FILTER_PROBEREQ = 0x00000080, 568 ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
569 ATH9K_RX_FILTER_PHYERR = 0x00000100, 569 ATH9K_RX_FILTER_PHYERR = 0x00000100,
570 ATH9K_RX_FILTER_MYBEACON = 0x00000200, 570 ATH9K_RX_FILTER_MYBEACON = 0x00000200,
571 ATH9K_RX_FILTER_COMP_BAR = 0x00000400,
571 ATH9K_RX_FILTER_PSPOLL = 0x00004000, 572 ATH9K_RX_FILTER_PSPOLL = 0x00004000,
572 ATH9K_RX_FILTER_PHYRADAR = 0x00002000, 573 ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
573 ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, 574 ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c2efdf2d72d3..3dc7b5a13e64 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1310,7 +1310,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
1310 * to allow the separation between hardware specific 1310 * to allow the separation between hardware specific
1311 * variables (now in ath_hw) and driver specific variables. 1311 * variables (now in ath_hw) and driver specific variables.
1312 */ 1312 */
1313static int ath_init_softc(u16 devid, struct ath_softc *sc) 1313static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
1314{ 1314{
1315 struct ath_hw *ah = NULL; 1315 struct ath_hw *ah = NULL;
1316 int r = 0, i; 1316 int r = 0, i;
@@ -1348,6 +1348,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc)
1348 1348
1349 ah->ah_sc = sc; 1349 ah->ah_sc = sc;
1350 ah->hw_version.devid = devid; 1350 ah->hw_version.devid = devid;
1351 ah->hw_version.subsysid = subsysid;
1351 sc->sc_ah = ah; 1352 sc->sc_ah = ah;
1352 1353
1353 r = ath9k_hw_init(ah); 1354 r = ath9k_hw_init(ah);
@@ -1577,7 +1578,7 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1577} 1578}
1578 1579
1579/* Device driver core initialization */ 1580/* Device driver core initialization */
1580int ath_init_device(u16 devid, struct ath_softc *sc) 1581int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid)
1581{ 1582{
1582 struct ieee80211_hw *hw = sc->hw; 1583 struct ieee80211_hw *hw = sc->hw;
1583 int error = 0, i; 1584 int error = 0, i;
@@ -1585,7 +1586,7 @@ int ath_init_device(u16 devid, struct ath_softc *sc)
1585 1586
1586 DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); 1587 DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
1587 1588
1588 error = ath_init_softc(devid, sc); 1589 error = ath_init_softc(devid, sc, subsysid);
1589 if (error != 0) 1590 if (error != 0)
1590 return error; 1591 return error;
1591 1592
@@ -1879,7 +1880,7 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
1879 1880
1880 if (chan->band == IEEE80211_BAND_2GHZ) { 1881 if (chan->band == IEEE80211_BAND_2GHZ) {
1881 ichan->chanmode = CHANNEL_G; 1882 ichan->chanmode = CHANNEL_G;
1882 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; 1883 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
1883 } else { 1884 } else {
1884 ichan->chanmode = CHANNEL_A; 1885 ichan->chanmode = CHANNEL_A;
1885 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; 1886 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
@@ -2010,6 +2011,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
2010 AR_STOMP_LOW_WLAN_WGHT); 2011 AR_STOMP_LOW_WLAN_WGHT);
2011 ath9k_hw_btcoex_enable(sc->sc_ah); 2012 ath9k_hw_btcoex_enable(sc->sc_ah);
2012 2013
2014 ath_pcie_aspm_disable(sc);
2013 if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) 2015 if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
2014 ath_btcoex_timer_resume(sc, &sc->btcoex_info); 2016 ath_btcoex_timer_resume(sc, &sc->btcoex_info);
2015 } 2017 }
@@ -2433,7 +2435,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
2433 ath9k_hw_setrxfilter(sc->sc_ah, rfilt); 2435 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
2434 ath9k_ps_restore(sc); 2436 ath9k_ps_restore(sc);
2435 2437
2436 DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter); 2438 DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", rfilt);
2437} 2439}
2438 2440
2439static void ath9k_sta_notify(struct ieee80211_hw *hw, 2441static void ath9k_sta_notify(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 685a8cebb468..903dd8ad9d43 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -35,8 +35,7 @@ static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
35{ 35{
36 u8 u8tmp; 36 u8 u8tmp;
37 37
38 pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, 38 pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, &u8tmp);
39 (u8 *)&u8tmp);
40 *csz = (int)u8tmp; 39 *csz = (int)u8tmp;
41 40
42 /* 41 /*
@@ -89,6 +88,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
89 struct ath_softc *sc; 88 struct ath_softc *sc;
90 struct ieee80211_hw *hw; 89 struct ieee80211_hw *hw;
91 u8 csz; 90 u8 csz;
91 u16 subsysid;
92 u32 val; 92 u32 val;
93 int ret = 0; 93 int ret = 0;
94 struct ath_hw *ah; 94 struct ath_hw *ah;
@@ -160,8 +160,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
160 160
161 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + 161 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
162 sizeof(struct ath_softc), &ath9k_ops); 162 sizeof(struct ath_softc), &ath9k_ops);
163 if (hw == NULL) { 163 if (!hw) {
164 printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n"); 164 dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
165 ret = -ENOMEM;
165 goto bad2; 166 goto bad2;
166 } 167 }
167 168
@@ -178,17 +179,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
178 sc->mem = mem; 179 sc->mem = mem;
179 sc->bus_ops = &ath_pci_bus_ops; 180 sc->bus_ops = &ath_pci_bus_ops;
180 181
181 if (ath_init_device(id->device, sc) != 0) { 182 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
182 ret = -ENODEV; 183 ret = ath_init_device(id->device, sc, subsysid);
184 if (ret) {
185 dev_err(&pdev->dev, "failed to initialize device\n");
183 goto bad3; 186 goto bad3;
184 } 187 }
185 188
186 /* setup interrupt service routine */ 189 /* setup interrupt service routine */
187 190
188 if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) { 191 ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
189 printk(KERN_ERR "%s: request_irq failed\n", 192 if (ret) {
190 wiphy_name(hw->wiphy)); 193 dev_err(&pdev->dev, "request_irq failed\n");
191 ret = -EIO;
192 goto bad4; 194 goto bad4;
193 } 195 }
194 196
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 52e62daad3ce..ec0abf823995 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -423,6 +423,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
423 if (sc->rx.rxfilter & FIF_PSPOLL) 423 if (sc->rx.rxfilter & FIF_PSPOLL)
424 rfilt |= ATH9K_RX_FILTER_PSPOLL; 424 rfilt |= ATH9K_RX_FILTER_PSPOLL;
425 425
426 if (conf_is_ht(&sc->hw->conf))
427 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
428
426 if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) { 429 if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
427 /* TODO: only needed if more than one BSSID is in use in 430 /* TODO: only needed if more than one BSSID is in use in
428 * station/adhoc mode */ 431 * station/adhoc mode */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 3ddb243f0000..e5c29eb86e80 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1325,7 +1325,6 @@ enum {
1325#define AR_CFP_VAL 0x0000FFFF 1325#define AR_CFP_VAL 0x0000FFFF
1326 1326
1327#define AR_RX_FILTER 0x803C 1327#define AR_RX_FILTER 0x803C
1328#define AR_RX_COMPR_BAR 0x00000400
1329 1328
1330#define AR_MCAST_FIL0 0x8040 1329#define AR_MCAST_FIL0 0x8040
1331#define AR_MCAST_FIL1 0x8044 1330#define AR_MCAST_FIL1 0x8044
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 4d3c53674e5a..c1dd857697a7 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -22,6 +22,12 @@
22 22
23#include "ath.h" 23#include "ath.h"
24 24
25enum ctl_group {
26 CTL_FCC = 0x10,
27 CTL_MKK = 0x40,
28 CTL_ETSI = 0x30,
29};
30
25#define NO_CTL 0xff 31#define NO_CTL 0xff
26#define SD_NO_CTL 0xE0 32#define SD_NO_CTL 0xE0
27#define NO_CTL 0xff 33#define NO_CTL 0xff
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index ad6d938d3cf6..9847af72208c 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -154,12 +154,6 @@ enum EnumRd {
154 DEBUG_REG_DMN = 0x01ff, 154 DEBUG_REG_DMN = 0x01ff,
155}; 155};
156 156
157enum ctl_group {
158 CTL_FCC = 0x10,
159 CTL_MKK = 0x40,
160 CTL_ETSI = 0x30,
161};
162
163/* Regpair to CTL band mapping */ 157/* Regpair to CTL band mapping */
164static struct reg_dmn_pair_mapping regDomainPairs[] = { 158static struct reg_dmn_pair_mapping regDomainPairs[] = {
165 /* regpair, 5 GHz CTL, 2 GHz CTL */ 159 /* regpair, 5 GHz CTL, 2 GHz CTL */
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 2af3b3522322..83e38134accb 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -42,8 +42,8 @@ config B43_PCICORE_AUTOSELECT
42 default y 42 default y
43 43
44config B43_PCMCIA 44config B43_PCMCIA
45 bool "Broadcom 43xx PCMCIA device support (EXPERIMENTAL)" 45 bool "Broadcom 43xx PCMCIA device support"
46 depends on B43 && SSB_PCMCIAHOST_POSSIBLE && EXPERIMENTAL 46 depends on B43 && SSB_PCMCIAHOST_POSSIBLE
47 select SSB_PCMCIAHOST 47 select SSB_PCMCIAHOST
48 ---help--- 48 ---help---
49 Broadcom 43xx PCMCIA device support. 49 Broadcom 43xx PCMCIA device support.
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index a1b3b731935b..09cfe68537b6 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -616,6 +616,12 @@ struct b43_wl {
616 /* Pointer to the ieee80211 hardware data structure */ 616 /* Pointer to the ieee80211 hardware data structure */
617 struct ieee80211_hw *hw; 617 struct ieee80211_hw *hw;
618 618
619 /* Global driver mutex. Every operation must run with this mutex locked. */
620 struct mutex mutex;
621 /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
622 * handler, only. This basically is just the IRQ mask register. */
623 spinlock_t hardirq_lock;
624
619 /* The number of queues that were registered with the mac80211 subsystem 625 /* The number of queues that were registered with the mac80211 subsystem
620 * initially. This is a backup copy of hw->queues in case hw->queues has 626 * initially. This is a backup copy of hw->queues in case hw->queues has
621 * to be dynamically lowered at runtime (Firmware does not support QoS). 627 * to be dynamically lowered at runtime (Firmware does not support QoS).
@@ -623,16 +629,12 @@ struct b43_wl {
623 * from the mac80211 subsystem. */ 629 * from the mac80211 subsystem. */
624 u16 mac80211_initially_registered_queues; 630 u16 mac80211_initially_registered_queues;
625 631
626 struct mutex mutex;
627 spinlock_t irq_lock;
628 /* R/W lock for data transmission. 632 /* R/W lock for data transmission.
629 * Transmissions on 2+ queues can run concurrently, but somebody else 633 * Transmissions on 2+ queues can run concurrently, but somebody else
630 * might sync with TX by write_lock_irqsave()'ing. */ 634 * might sync with TX by write_lock_irqsave()'ing. */
631 rwlock_t tx_lock; 635 rwlock_t tx_lock;
632 /* Lock for LEDs access. */ 636 /* Lock for LEDs access. */
633 spinlock_t leds_lock; 637 spinlock_t leds_lock;
634 /* Lock for SHM access. */
635 spinlock_t shm_lock;
636 638
637 /* We can only have one operating interface (802.11 core) 639 /* We can only have one operating interface (802.11 core)
638 * at a time. General information about this interface follows. 640 * at a time. General information about this interface follows.
@@ -665,8 +667,7 @@ struct b43_wl {
665 bool radiotap_enabled; 667 bool radiotap_enabled;
666 bool radio_enabled; 668 bool radio_enabled;
667 669
668 /* The beacon we are currently using (AP or IBSS mode). 670 /* The beacon we are currently using (AP or IBSS mode). */
669 * This beacon stuff is protected by the irq_lock. */
670 struct sk_buff *current_beacon; 671 struct sk_buff *current_beacon;
671 bool beacon0_uploaded; 672 bool beacon0_uploaded;
672 bool beacon1_uploaded; 673 bool beacon1_uploaded;
@@ -680,6 +681,11 @@ struct b43_wl {
680 * This is scheduled when we determine that the actual TX output 681 * This is scheduled when we determine that the actual TX output
681 * power doesn't match what we want. */ 682 * power doesn't match what we want. */
682 struct work_struct txpower_adjust_work; 683 struct work_struct txpower_adjust_work;
684
685 /* Packet transmit work */
686 struct work_struct tx_work;
687 /* Queue of packets to be transmitted. */
688 struct sk_buff_head tx_queue;
683}; 689};
684 690
685/* The type of the firmware file. */ 691/* The type of the firmware file. */
@@ -754,14 +760,6 @@ enum {
754 smp_wmb(); \ 760 smp_wmb(); \
755 } while (0) 761 } while (0)
756 762
757/* XXX--- HOW LOCKING WORKS IN B43 ---XXX
758 *
759 * You should always acquire both, wl->mutex and wl->irq_lock unless:
760 * - You don't need to acquire wl->irq_lock, if the interface is stopped.
761 * - You don't need to acquire wl->mutex in the IRQ handler, IRQ tasklet
762 * and packet TX path (and _ONLY_ there.)
763 */
764
765/* Data structure for one wireless device (802.11 core) */ 763/* Data structure for one wireless device (802.11 core) */
766struct b43_wldev { 764struct b43_wldev {
767 struct ssb_device *dev; 765 struct ssb_device *dev;
@@ -807,14 +805,12 @@ struct b43_wldev {
807 u32 dma_reason[6]; 805 u32 dma_reason[6];
808 /* The currently active generic-interrupt mask. */ 806 /* The currently active generic-interrupt mask. */
809 u32 irq_mask; 807 u32 irq_mask;
808
810 /* Link Quality calculation context. */ 809 /* Link Quality calculation context. */
811 struct b43_noise_calculation noisecalc; 810 struct b43_noise_calculation noisecalc;
812 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ 811 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
813 int mac_suspended; 812 int mac_suspended;
814 813
815 /* Interrupt Service Routine tasklet (bottom-half) */
816 struct tasklet_struct isr_tasklet;
817
818 /* Periodic tasks */ 814 /* Periodic tasks */
819 struct delayed_work periodic_work; 815 struct delayed_work periodic_work;
820 unsigned int periodic_state; 816 unsigned int periodic_state;
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 45e3d6af69f5..8f64943e3f60 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -46,8 +46,6 @@ struct b43_debugfs_fops {
46 struct file_operations fops; 46 struct file_operations fops;
47 /* Offset of struct b43_dfs_file in struct b43_dfsentry */ 47 /* Offset of struct b43_dfs_file in struct b43_dfsentry */
48 size_t file_struct_offset; 48 size_t file_struct_offset;
49 /* Take wl->irq_lock before calling read/write? */
50 bool take_irqlock;
51}; 49};
52 50
53static inline 51static inline
@@ -127,7 +125,6 @@ static int shm16write__write_file(struct b43_wldev *dev,
127 unsigned int routing, addr, mask, set; 125 unsigned int routing, addr, mask, set;
128 u16 val; 126 u16 val;
129 int res; 127 int res;
130 unsigned long flags;
131 128
132 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X", 129 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
133 &routing, &addr, &mask, &set); 130 &routing, &addr, &mask, &set);
@@ -144,15 +141,13 @@ static int shm16write__write_file(struct b43_wldev *dev,
144 if ((mask > 0xFFFF) || (set > 0xFFFF)) 141 if ((mask > 0xFFFF) || (set > 0xFFFF))
145 return -E2BIG; 142 return -E2BIG;
146 143
147 spin_lock_irqsave(&dev->wl->shm_lock, flags);
148 if (mask == 0) 144 if (mask == 0)
149 val = 0; 145 val = 0;
150 else 146 else
151 val = __b43_shm_read16(dev, routing, addr); 147 val = b43_shm_read16(dev, routing, addr);
152 val &= mask; 148 val &= mask;
153 val |= set; 149 val |= set;
154 __b43_shm_write16(dev, routing, addr, val); 150 b43_shm_write16(dev, routing, addr, val);
155 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
156 151
157 return 0; 152 return 0;
158} 153}
@@ -206,7 +201,6 @@ static int shm32write__write_file(struct b43_wldev *dev,
206 unsigned int routing, addr, mask, set; 201 unsigned int routing, addr, mask, set;
207 u32 val; 202 u32 val;
208 int res; 203 int res;
209 unsigned long flags;
210 204
211 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X", 205 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
212 &routing, &addr, &mask, &set); 206 &routing, &addr, &mask, &set);
@@ -223,15 +217,13 @@ static int shm32write__write_file(struct b43_wldev *dev,
223 if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF)) 217 if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
224 return -E2BIG; 218 return -E2BIG;
225 219
226 spin_lock_irqsave(&dev->wl->shm_lock, flags);
227 if (mask == 0) 220 if (mask == 0)
228 val = 0; 221 val = 0;
229 else 222 else
230 val = __b43_shm_read32(dev, routing, addr); 223 val = b43_shm_read32(dev, routing, addr);
231 val &= mask; 224 val &= mask;
232 val |= set; 225 val |= set;
233 __b43_shm_write32(dev, routing, addr, val); 226 b43_shm_write32(dev, routing, addr, val);
234 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
235 227
236 return 0; 228 return 0;
237} 229}
@@ -372,14 +364,12 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
372{ 364{
373 struct b43_txstatus_log *log = &dev->dfsentry->txstatlog; 365 struct b43_txstatus_log *log = &dev->dfsentry->txstatlog;
374 ssize_t count = 0; 366 ssize_t count = 0;
375 unsigned long flags;
376 int i, idx; 367 int i, idx;
377 struct b43_txstatus *stat; 368 struct b43_txstatus *stat;
378 369
379 spin_lock_irqsave(&log->lock, flags);
380 if (log->end < 0) { 370 if (log->end < 0) {
381 fappend("Nothing transmitted, yet\n"); 371 fappend("Nothing transmitted, yet\n");
382 goto out_unlock; 372 goto out;
383 } 373 }
384 fappend("b43 TX status reports:\n\n" 374 fappend("b43 TX status reports:\n\n"
385 "index | cookie | seq | phy_stat | frame_count | " 375 "index | cookie | seq | phy_stat | frame_count | "
@@ -409,13 +399,11 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
409 break; 399 break;
410 i++; 400 i++;
411 } 401 }
412out_unlock: 402out:
413 spin_unlock_irqrestore(&log->lock, flags);
414 403
415 return count; 404 return count;
416} 405}
417 406
418/* wl->irq_lock is locked */
419static int restart_write_file(struct b43_wldev *dev, 407static int restart_write_file(struct b43_wldev *dev,
420 const char *buf, size_t count) 408 const char *buf, size_t count)
421{ 409{
@@ -556,12 +544,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
556 goto out_unlock; 544 goto out_unlock;
557 } 545 }
558 memset(buf, 0, bufsize); 546 memset(buf, 0, bufsize);
559 if (dfops->take_irqlock) { 547 ret = dfops->read(dev, buf, bufsize);
560 spin_lock_irq(&dev->wl->irq_lock);
561 ret = dfops->read(dev, buf, bufsize);
562 spin_unlock_irq(&dev->wl->irq_lock);
563 } else
564 ret = dfops->read(dev, buf, bufsize);
565 if (ret <= 0) { 548 if (ret <= 0) {
566 free_pages((unsigned long)buf, buforder); 549 free_pages((unsigned long)buf, buforder);
567 err = ret; 550 err = ret;
@@ -623,12 +606,7 @@ static ssize_t b43_debugfs_write(struct file *file,
623 err = -EFAULT; 606 err = -EFAULT;
624 goto out_freepage; 607 goto out_freepage;
625 } 608 }
626 if (dfops->take_irqlock) { 609 err = dfops->write(dev, buf, count);
627 spin_lock_irq(&dev->wl->irq_lock);
628 err = dfops->write(dev, buf, count);
629 spin_unlock_irq(&dev->wl->irq_lock);
630 } else
631 err = dfops->write(dev, buf, count);
632 if (err) 610 if (err)
633 goto out_freepage; 611 goto out_freepage;
634 612
@@ -641,7 +619,7 @@ out_unlock:
641} 619}
642 620
643 621
644#define B43_DEBUGFS_FOPS(name, _read, _write, _take_irqlock) \ 622#define B43_DEBUGFS_FOPS(name, _read, _write) \
645 static struct b43_debugfs_fops fops_##name = { \ 623 static struct b43_debugfs_fops fops_##name = { \
646 .read = _read, \ 624 .read = _read, \
647 .write = _write, \ 625 .write = _write, \
@@ -652,20 +630,19 @@ out_unlock:
652 }, \ 630 }, \
653 .file_struct_offset = offsetof(struct b43_dfsentry, \ 631 .file_struct_offset = offsetof(struct b43_dfsentry, \
654 file_##name), \ 632 file_##name), \
655 .take_irqlock = _take_irqlock, \
656 } 633 }
657 634
658B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1); 635B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file);
659B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1); 636B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file);
660B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1); 637B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file);
661B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1); 638B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file);
662B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); 639B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file);
663B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); 640B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file);
664B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); 641B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file);
665B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); 642B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file);
666B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); 643B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL);
667B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); 644B43_DEBUGFS_FOPS(restart, NULL, restart_write_file);
668B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0); 645B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL);
669 646
670 647
671bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) 648bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
@@ -738,7 +715,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
738 return; 715 return;
739 } 716 }
740 log->end = -1; 717 log->end = -1;
741 spin_lock_init(&log->lock);
742 718
743 dev->dfsentry = e; 719 dev->dfsentry = e;
744 720
@@ -822,7 +798,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
822 kfree(e); 798 kfree(e);
823} 799}
824 800
825/* Called with IRQs disabled. */
826void b43_debugfs_log_txstat(struct b43_wldev *dev, 801void b43_debugfs_log_txstat(struct b43_wldev *dev,
827 const struct b43_txstatus *status) 802 const struct b43_txstatus *status)
828{ 803{
@@ -834,14 +809,12 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
834 if (!e) 809 if (!e)
835 return; 810 return;
836 log = &e->txstatlog; 811 log = &e->txstatlog;
837 spin_lock(&log->lock); /* IRQs are already disabled. */
838 i = log->end + 1; 812 i = log->end + 1;
839 if (i == B43_NR_LOGGED_TXSTATUS) 813 if (i == B43_NR_LOGGED_TXSTATUS)
840 i = 0; 814 i = 0;
841 log->end = i; 815 log->end = i;
842 cur = &(log->log[i]); 816 cur = &(log->log[i]);
843 memcpy(cur, status, sizeof(*cur)); 817 memcpy(cur, status, sizeof(*cur));
844 spin_unlock(&log->lock);
845} 818}
846 819
847void b43_debugfs_init(void) 820void b43_debugfs_init(void)
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index b9d4de4a979c..e47b4b488b04 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -23,9 +23,10 @@ struct dentry;
23#define B43_NR_LOGGED_TXSTATUS 100 23#define B43_NR_LOGGED_TXSTATUS 100
24 24
25struct b43_txstatus_log { 25struct b43_txstatus_log {
26 /* This structure is protected by wl->mutex */
27
26 struct b43_txstatus *log; 28 struct b43_txstatus *log;
27 int end; 29 int end;
28 spinlock_t lock;
29}; 30};
30 31
31struct b43_dfs_file { 32struct b43_dfs_file {
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 289aaf6dfe79..a467ee260a19 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -856,7 +856,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
856 } else 856 } else
857 B43_WARN_ON(1); 857 B43_WARN_ON(1);
858 } 858 }
859 spin_lock_init(&ring->lock);
860#ifdef CONFIG_B43_DEBUG 859#ifdef CONFIG_B43_DEBUG
861 ring->last_injected_overflow = jiffies; 860 ring->last_injected_overflow = jiffies;
862#endif 861#endif
@@ -1315,7 +1314,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1315 struct b43_dmaring *ring; 1314 struct b43_dmaring *ring;
1316 struct ieee80211_hdr *hdr; 1315 struct ieee80211_hdr *hdr;
1317 int err = 0; 1316 int err = 0;
1318 unsigned long flags;
1319 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1317 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1320 1318
1321 hdr = (struct ieee80211_hdr *)skb->data; 1319 hdr = (struct ieee80211_hdr *)skb->data;
@@ -1331,8 +1329,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1331 dev, skb_get_queue_mapping(skb)); 1329 dev, skb_get_queue_mapping(skb));
1332 } 1330 }
1333 1331
1334 spin_lock_irqsave(&ring->lock, flags);
1335
1336 B43_WARN_ON(!ring->tx); 1332 B43_WARN_ON(!ring->tx);
1337 1333
1338 if (unlikely(ring->stopped)) { 1334 if (unlikely(ring->stopped)) {
@@ -1343,7 +1339,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1343 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) 1339 if (b43_debug(dev, B43_DBG_DMAVERBOSE))
1344 b43err(dev->wl, "Packet after queue stopped\n"); 1340 b43err(dev->wl, "Packet after queue stopped\n");
1345 err = -ENOSPC; 1341 err = -ENOSPC;
1346 goto out_unlock; 1342 goto out;
1347 } 1343 }
1348 1344
1349 if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) { 1345 if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) {
@@ -1351,7 +1347,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1351 * full, but queues not stopped. */ 1347 * full, but queues not stopped. */
1352 b43err(dev->wl, "DMA queue overflow\n"); 1348 b43err(dev->wl, "DMA queue overflow\n");
1353 err = -ENOSPC; 1349 err = -ENOSPC;
1354 goto out_unlock; 1350 goto out;
1355 } 1351 }
1356 1352
1357 /* Assign the queue number to the ring (if not already done before) 1353 /* Assign the queue number to the ring (if not already done before)
@@ -1365,11 +1361,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1365 * anymore and must not transmit it unencrypted. */ 1361 * anymore and must not transmit it unencrypted. */
1366 dev_kfree_skb_any(skb); 1362 dev_kfree_skb_any(skb);
1367 err = 0; 1363 err = 0;
1368 goto out_unlock; 1364 goto out;
1369 } 1365 }
1370 if (unlikely(err)) { 1366 if (unlikely(err)) {
1371 b43err(dev->wl, "DMA tx mapping failure\n"); 1367 b43err(dev->wl, "DMA tx mapping failure\n");
1372 goto out_unlock; 1368 goto out;
1373 } 1369 }
1374 ring->nr_tx_packets++; 1370 ring->nr_tx_packets++;
1375 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || 1371 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
@@ -1381,13 +1377,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1381 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1377 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
1382 } 1378 }
1383 } 1379 }
1384out_unlock: 1380out:
1385 spin_unlock_irqrestore(&ring->lock, flags);
1386 1381
1387 return err; 1382 return err;
1388} 1383}
1389 1384
1390/* Called with IRQs disabled. */
1391void b43_dma_handle_txstatus(struct b43_wldev *dev, 1385void b43_dma_handle_txstatus(struct b43_wldev *dev,
1392 const struct b43_txstatus *status) 1386 const struct b43_txstatus *status)
1393{ 1387{
@@ -1402,8 +1396,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1402 if (unlikely(!ring)) 1396 if (unlikely(!ring))
1403 return; 1397 return;
1404 1398
1405 spin_lock(&ring->lock); /* IRQs are already disabled. */
1406
1407 B43_WARN_ON(!ring->tx); 1399 B43_WARN_ON(!ring->tx);
1408 ops = ring->ops; 1400 ops = ring->ops;
1409 while (1) { 1401 while (1) {
@@ -1462,8 +1454,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1462 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); 1454 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
1463 } 1455 }
1464 } 1456 }
1465
1466 spin_unlock(&ring->lock);
1467} 1457}
1468 1458
1469void b43_dma_get_tx_stats(struct b43_wldev *dev, 1459void b43_dma_get_tx_stats(struct b43_wldev *dev,
@@ -1471,17 +1461,14 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
1471{ 1461{
1472 const int nr_queues = dev->wl->hw->queues; 1462 const int nr_queues = dev->wl->hw->queues;
1473 struct b43_dmaring *ring; 1463 struct b43_dmaring *ring;
1474 unsigned long flags;
1475 int i; 1464 int i;
1476 1465
1477 for (i = 0; i < nr_queues; i++) { 1466 for (i = 0; i < nr_queues; i++) {
1478 ring = select_ring_by_priority(dev, i); 1467 ring = select_ring_by_priority(dev, i);
1479 1468
1480 spin_lock_irqsave(&ring->lock, flags);
1481 stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME; 1469 stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
1482 stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME; 1470 stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
1483 stats[i].count = ring->nr_tx_packets; 1471 stats[i].count = ring->nr_tx_packets;
1484 spin_unlock_irqrestore(&ring->lock, flags);
1485 } 1472 }
1486} 1473}
1487 1474
@@ -1592,22 +1579,14 @@ void b43_dma_rx(struct b43_dmaring *ring)
1592 1579
1593static void b43_dma_tx_suspend_ring(struct b43_dmaring *ring) 1580static void b43_dma_tx_suspend_ring(struct b43_dmaring *ring)
1594{ 1581{
1595 unsigned long flags;
1596
1597 spin_lock_irqsave(&ring->lock, flags);
1598 B43_WARN_ON(!ring->tx); 1582 B43_WARN_ON(!ring->tx);
1599 ring->ops->tx_suspend(ring); 1583 ring->ops->tx_suspend(ring);
1600 spin_unlock_irqrestore(&ring->lock, flags);
1601} 1584}
1602 1585
1603static void b43_dma_tx_resume_ring(struct b43_dmaring *ring) 1586static void b43_dma_tx_resume_ring(struct b43_dmaring *ring)
1604{ 1587{
1605 unsigned long flags;
1606
1607 spin_lock_irqsave(&ring->lock, flags);
1608 B43_WARN_ON(!ring->tx); 1588 B43_WARN_ON(!ring->tx);
1609 ring->ops->tx_resume(ring); 1589 ring->ops->tx_resume(ring);
1610 spin_unlock_irqrestore(&ring->lock, flags);
1611} 1590}
1612 1591
1613void b43_dma_tx_suspend(struct b43_wldev *dev) 1592void b43_dma_tx_suspend(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 05dde646d831..f0b0838fb5ba 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -2,7 +2,6 @@
2#define B43_DMA_H_ 2#define B43_DMA_H_
3 3
4#include <linux/ieee80211.h> 4#include <linux/ieee80211.h>
5#include <linux/spinlock.h>
6 5
7#include "b43.h" 6#include "b43.h"
8 7
@@ -244,8 +243,6 @@ struct b43_dmaring {
244 /* The QOS priority assigned to this ring. Only used for TX rings. 243 /* The QOS priority assigned to this ring. Only used for TX rings.
245 * This is the mac80211 "queue" value. */ 244 * This is the mac80211 "queue" value. */
246 u8 queue_prio; 245 u8 queue_prio;
247 /* Lock, only used for TX. */
248 spinlock_t lock;
249 struct b43_wldev *dev; 246 struct b43_wldev *dev;
250#ifdef CONFIG_B43_DEBUG 247#ifdef CONFIG_B43_DEBUG
251 /* Maximum number of used slots. */ 248 /* Maximum number of used slots. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ae05f6671149..7a9a3fa55425 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -291,7 +291,7 @@ static struct ieee80211_supported_band b43_band_2GHz = {
291 291
292static void b43_wireless_core_exit(struct b43_wldev *dev); 292static void b43_wireless_core_exit(struct b43_wldev *dev);
293static int b43_wireless_core_init(struct b43_wldev *dev); 293static int b43_wireless_core_init(struct b43_wldev *dev);
294static void b43_wireless_core_stop(struct b43_wldev *dev); 294static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
295static int b43_wireless_core_start(struct b43_wldev *dev); 295static int b43_wireless_core_start(struct b43_wldev *dev);
296 296
297static int b43_ratelimit(struct b43_wl *wl) 297static int b43_ratelimit(struct b43_wl *wl)
@@ -390,7 +390,7 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
390 b43_write32(dev, B43_MMIO_SHM_CONTROL, control); 390 b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
391} 391}
392 392
393u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 393u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
394{ 394{
395 u32 ret; 395 u32 ret;
396 396
@@ -413,20 +413,7 @@ out:
413 return ret; 413 return ret;
414} 414}
415 415
416u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 416u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
417{
418 struct b43_wl *wl = dev->wl;
419 unsigned long flags;
420 u32 ret;
421
422 spin_lock_irqsave(&wl->shm_lock, flags);
423 ret = __b43_shm_read32(dev, routing, offset);
424 spin_unlock_irqrestore(&wl->shm_lock, flags);
425
426 return ret;
427}
428
429u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
430{ 417{
431 u16 ret; 418 u16 ret;
432 419
@@ -447,20 +434,7 @@ out:
447 return ret; 434 return ret;
448} 435}
449 436
450u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) 437void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
451{
452 struct b43_wl *wl = dev->wl;
453 unsigned long flags;
454 u16 ret;
455
456 spin_lock_irqsave(&wl->shm_lock, flags);
457 ret = __b43_shm_read16(dev, routing, offset);
458 spin_unlock_irqrestore(&wl->shm_lock, flags);
459
460 return ret;
461}
462
463void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
464{ 438{
465 if (routing == B43_SHM_SHARED) { 439 if (routing == B43_SHM_SHARED) {
466 B43_WARN_ON(offset & 0x0001); 440 B43_WARN_ON(offset & 0x0001);
@@ -480,17 +454,7 @@ void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value
480 b43_write32(dev, B43_MMIO_SHM_DATA, value); 454 b43_write32(dev, B43_MMIO_SHM_DATA, value);
481} 455}
482 456
483void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) 457void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
484{
485 struct b43_wl *wl = dev->wl;
486 unsigned long flags;
487
488 spin_lock_irqsave(&wl->shm_lock, flags);
489 __b43_shm_write32(dev, routing, offset, value);
490 spin_unlock_irqrestore(&wl->shm_lock, flags);
491}
492
493void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
494{ 458{
495 if (routing == B43_SHM_SHARED) { 459 if (routing == B43_SHM_SHARED) {
496 B43_WARN_ON(offset & 0x0001); 460 B43_WARN_ON(offset & 0x0001);
@@ -506,16 +470,6 @@ void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value
506 b43_write16(dev, B43_MMIO_SHM_DATA, value); 470 b43_write16(dev, B43_MMIO_SHM_DATA, value);
507} 471}
508 472
509void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
510{
511 struct b43_wl *wl = dev->wl;
512 unsigned long flags;
513
514 spin_lock_irqsave(&wl->shm_lock, flags);
515 __b43_shm_write16(dev, routing, offset, value);
516 spin_unlock_irqrestore(&wl->shm_lock, flags);
517}
518
519/* Read HostFlags */ 473/* Read HostFlags */
520u64 b43_hf_read(struct b43_wldev *dev) 474u64 b43_hf_read(struct b43_wldev *dev)
521{ 475{
@@ -685,22 +639,11 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
685 b43_set_slot_time(dev, 20); 639 b43_set_slot_time(dev, 20);
686} 640}
687 641
688/* Synchronize IRQ top- and bottom-half.
689 * IRQs must be masked before calling this.
690 * This must not be called with the irq_lock held.
691 */
692static void b43_synchronize_irq(struct b43_wldev *dev)
693{
694 synchronize_irq(dev->dev->irq);
695 tasklet_kill(&dev->isr_tasklet);
696}
697
698/* DummyTransmission function, as documented on 642/* DummyTransmission function, as documented on
699 * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission 643 * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission
700 */ 644 */
701void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) 645void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
702{ 646{
703 struct b43_wl *wl = dev->wl;
704 struct b43_phy *phy = &dev->phy; 647 struct b43_phy *phy = &dev->phy;
705 unsigned int i, max_loop; 648 unsigned int i, max_loop;
706 u16 value; 649 u16 value;
@@ -720,9 +663,6 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
720 buffer[0] = 0x000B846E; 663 buffer[0] = 0x000B846E;
721 } 664 }
722 665
723 spin_lock_irq(&wl->irq_lock);
724 write_lock(&wl->tx_lock);
725
726 for (i = 0; i < 5; i++) 666 for (i = 0; i < 5; i++)
727 b43_ram_write(dev, i * 4, buffer[i]); 667 b43_ram_write(dev, i * 4, buffer[i]);
728 668
@@ -778,9 +718,6 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
778 } 718 }
779 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) 719 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
780 b43_radio_write16(dev, 0x0051, 0x0037); 720 b43_radio_write16(dev, 0x0051, 0x0037);
781
782 write_unlock(&wl->tx_lock);
783 spin_unlock_irq(&wl->irq_lock);
784} 721}
785 722
786static void key_write(struct b43_wldev *dev, 723static void key_write(struct b43_wldev *dev,
@@ -1620,6 +1557,27 @@ static void handle_irq_beacon(struct b43_wldev *dev)
1620 } 1557 }
1621} 1558}
1622 1559
1560static void b43_do_beacon_update_trigger_work(struct b43_wldev *dev)
1561{
1562 u32 old_irq_mask = dev->irq_mask;
1563
1564 /* update beacon right away or defer to irq */
1565 handle_irq_beacon(dev);
1566 if (old_irq_mask != dev->irq_mask) {
1567 /* The handler updated the IRQ mask. */
1568 B43_WARN_ON(!dev->irq_mask);
1569 if (b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)) {
1570 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1571 } else {
1572 /* Device interrupts are currently disabled. That means
1573 * we just ran the hardirq handler and scheduled the
1574 * IRQ thread. The thread will write the IRQ mask when
1575 * it finished, so there's nothing to do here. Writing
1576 * the mask _here_ would incorrectly re-enable IRQs. */
1577 }
1578 }
1579}
1580
1623static void b43_beacon_update_trigger_work(struct work_struct *work) 1581static void b43_beacon_update_trigger_work(struct work_struct *work)
1624{ 1582{
1625 struct b43_wl *wl = container_of(work, struct b43_wl, 1583 struct b43_wl *wl = container_of(work, struct b43_wl,
@@ -1629,19 +1587,22 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1629 mutex_lock(&wl->mutex); 1587 mutex_lock(&wl->mutex);
1630 dev = wl->current_dev; 1588 dev = wl->current_dev;
1631 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1589 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1632 spin_lock_irq(&wl->irq_lock); 1590 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
1633 /* update beacon right away or defer to irq */ 1591 /* wl->mutex is enough. */
1634 handle_irq_beacon(dev); 1592 b43_do_beacon_update_trigger_work(dev);
1635 /* The handler might have updated the IRQ mask. */ 1593 mmiowb();
1636 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); 1594 } else {
1637 mmiowb(); 1595 spin_lock_irq(&wl->hardirq_lock);
1638 spin_unlock_irq(&wl->irq_lock); 1596 b43_do_beacon_update_trigger_work(dev);
1597 mmiowb();
1598 spin_unlock_irq(&wl->hardirq_lock);
1599 }
1639 } 1600 }
1640 mutex_unlock(&wl->mutex); 1601 mutex_unlock(&wl->mutex);
1641} 1602}
1642 1603
1643/* Asynchronously update the packet templates in template RAM. 1604/* Asynchronously update the packet templates in template RAM.
1644 * Locking: Requires wl->irq_lock to be locked. */ 1605 * Locking: Requires wl->mutex to be locked. */
1645static void b43_update_templates(struct b43_wl *wl) 1606static void b43_update_templates(struct b43_wl *wl)
1646{ 1607{
1647 struct sk_buff *beacon; 1608 struct sk_buff *beacon;
@@ -1778,18 +1739,15 @@ out:
1778 B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK); 1739 B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
1779} 1740}
1780 1741
1781/* Interrupt handler bottom-half */ 1742static void b43_do_interrupt_thread(struct b43_wldev *dev)
1782static void b43_interrupt_tasklet(struct b43_wldev *dev)
1783{ 1743{
1784 u32 reason; 1744 u32 reason;
1785 u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; 1745 u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
1786 u32 merged_dma_reason = 0; 1746 u32 merged_dma_reason = 0;
1787 int i; 1747 int i;
1788 unsigned long flags;
1789
1790 spin_lock_irqsave(&dev->wl->irq_lock, flags);
1791 1748
1792 B43_WARN_ON(b43_status(dev) != B43_STAT_STARTED); 1749 if (unlikely(b43_status(dev) != B43_STAT_STARTED))
1750 return;
1793 1751
1794 reason = dev->irq_reason; 1752 reason = dev->irq_reason;
1795 for (i = 0; i < ARRAY_SIZE(dma_reason); i++) { 1753 for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
@@ -1822,8 +1780,6 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1822 dma_reason[2], dma_reason[3], 1780 dma_reason[2], dma_reason[3],
1823 dma_reason[4], dma_reason[5]); 1781 dma_reason[4], dma_reason[5]);
1824 b43_controller_restart(dev, "DMA error"); 1782 b43_controller_restart(dev, "DMA error");
1825 mmiowb();
1826 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1827 return; 1783 return;
1828 } 1784 }
1829 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { 1785 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -1867,47 +1823,36 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1867 if (reason & B43_IRQ_TX_OK) 1823 if (reason & B43_IRQ_TX_OK)
1868 handle_irq_transmit_status(dev); 1824 handle_irq_transmit_status(dev);
1869 1825
1826 /* Re-enable interrupts on the device by restoring the current interrupt mask. */
1870 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); 1827 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1871 mmiowb();
1872 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1873} 1828}
1874 1829
1875static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason) 1830/* Interrupt thread handler. Handles device interrupts in thread context. */
1831static irqreturn_t b43_interrupt_thread_handler(int irq, void *dev_id)
1876{ 1832{
1877 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason); 1833 struct b43_wldev *dev = dev_id;
1878 1834
1879 b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]); 1835 mutex_lock(&dev->wl->mutex);
1880 b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]); 1836 b43_do_interrupt_thread(dev);
1881 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]); 1837 mmiowb();
1882 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]); 1838 mutex_unlock(&dev->wl->mutex);
1883 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]); 1839
1884/* Unused ring 1840 return IRQ_HANDLED;
1885 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
1886*/
1887} 1841}
1888 1842
1889/* Interrupt handler top-half */ 1843static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
1890static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1891{ 1844{
1892 irqreturn_t ret = IRQ_NONE;
1893 struct b43_wldev *dev = dev_id;
1894 u32 reason; 1845 u32 reason;
1895 1846
1896 B43_WARN_ON(!dev); 1847 /* This code runs under wl->hardirq_lock, but _only_ on non-SDIO busses.
1848 * On SDIO, this runs under wl->mutex. */
1897 1849
1898 spin_lock(&dev->wl->irq_lock);
1899
1900 if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
1901 /* This can only happen on shared IRQ lines. */
1902 goto out;
1903 }
1904 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); 1850 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
1905 if (reason == 0xffffffff) /* shared IRQ */ 1851 if (reason == 0xffffffff) /* shared IRQ */
1906 goto out; 1852 return IRQ_NONE;
1907 ret = IRQ_HANDLED;
1908 reason &= dev->irq_mask; 1853 reason &= dev->irq_mask;
1909 if (!reason) 1854 if (!reason)
1910 goto out; 1855 return IRQ_HANDLED;
1911 1856
1912 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) 1857 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
1913 & 0x0001DC00; 1858 & 0x0001DC00;
@@ -1924,15 +1869,38 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1924 & 0x0000DC00; 1869 & 0x0000DC00;
1925*/ 1870*/
1926 1871
1927 b43_interrupt_ack(dev, reason); 1872 /* ACK the interrupt. */
1928 /* disable all IRQs. They are enabled again in the bottom half. */ 1873 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
1874 b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
1875 b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]);
1876 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
1877 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
1878 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
1879/* Unused ring
1880 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
1881*/
1882
1883 /* Disable IRQs on the device. The IRQ thread handler will re-enable them. */
1929 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 1884 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
1930 /* save the reason code and call our bottom half. */ 1885 /* Save the reason bitmasks for the IRQ thread handler. */
1931 dev->irq_reason = reason; 1886 dev->irq_reason = reason;
1932 tasklet_schedule(&dev->isr_tasklet); 1887
1933out: 1888 return IRQ_WAKE_THREAD;
1889}
1890
1891/* Interrupt handler top-half. This runs with interrupts disabled. */
1892static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1893{
1894 struct b43_wldev *dev = dev_id;
1895 irqreturn_t ret;
1896
1897 if (unlikely(b43_status(dev) < B43_STAT_STARTED))
1898 return IRQ_NONE;
1899
1900 spin_lock(&dev->wl->hardirq_lock);
1901 ret = b43_do_interrupt(dev);
1934 mmiowb(); 1902 mmiowb();
1935 spin_unlock(&dev->wl->irq_lock); 1903 spin_unlock(&dev->wl->hardirq_lock);
1936 1904
1937 return ret; 1905 return ret;
1938} 1906}
@@ -3038,15 +3006,12 @@ static void b43_security_init(struct b43_wldev *dev)
3038static int b43_rng_read(struct hwrng *rng, u32 *data) 3006static int b43_rng_read(struct hwrng *rng, u32 *data)
3039{ 3007{
3040 struct b43_wl *wl = (struct b43_wl *)rng->priv; 3008 struct b43_wl *wl = (struct b43_wl *)rng->priv;
3041 unsigned long flags;
3042 3009
3043 /* Don't take wl->mutex here, as it could deadlock with 3010 /* FIXME: We need to take wl->mutex here to make sure the device
3044 * hwrng internal locking. It's not needed to take 3011 * is not going away from under our ass. However it could deadlock
3045 * wl->mutex here, anyway. */ 3012 * with hwrng internal locking. */
3046 3013
3047 spin_lock_irqsave(&wl->irq_lock, flags);
3048 *data = b43_read16(wl->current_dev, B43_MMIO_RNG); 3014 *data = b43_read16(wl->current_dev, B43_MMIO_RNG);
3049 spin_unlock_irqrestore(&wl->irq_lock, flags);
3050 3015
3051 return (sizeof(u16)); 3016 return (sizeof(u16));
3052} 3017}
@@ -3082,46 +3047,52 @@ static int b43_rng_init(struct b43_wl *wl)
3082 return err; 3047 return err;
3083} 3048}
3084 3049
3085static int b43_op_tx(struct ieee80211_hw *hw, 3050static void b43_tx_work(struct work_struct *work)
3086 struct sk_buff *skb)
3087{ 3051{
3088 struct b43_wl *wl = hw_to_b43_wl(hw); 3052 struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
3089 struct b43_wldev *dev = wl->current_dev; 3053 struct b43_wldev *dev;
3090 unsigned long flags; 3054 struct sk_buff *skb;
3091 int err; 3055 int err = 0;
3092 3056
3093 if (unlikely(skb->len < 2 + 2 + 6)) { 3057 mutex_lock(&wl->mutex);
3094 /* Too short, this can't be a valid frame. */ 3058 dev = wl->current_dev;
3095 goto drop_packet; 3059 if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) {
3060 mutex_unlock(&wl->mutex);
3061 return;
3096 } 3062 }
3097 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
3098 if (unlikely(!dev))
3099 goto drop_packet;
3100 3063
3101 /* Transmissions on seperate queues can run concurrently. */ 3064 while (skb_queue_len(&wl->tx_queue)) {
3102 read_lock_irqsave(&wl->tx_lock, flags); 3065 skb = skb_dequeue(&wl->tx_queue);
3103 3066
3104 err = -ENODEV;
3105 if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
3106 if (b43_using_pio_transfers(dev)) 3067 if (b43_using_pio_transfers(dev))
3107 err = b43_pio_tx(dev, skb); 3068 err = b43_pio_tx(dev, skb);
3108 else 3069 else
3109 err = b43_dma_tx(dev, skb); 3070 err = b43_dma_tx(dev, skb);
3071 if (unlikely(err))
3072 dev_kfree_skb(skb); /* Drop it */
3110 } 3073 }
3111 3074
3112 read_unlock_irqrestore(&wl->tx_lock, flags); 3075 mutex_unlock(&wl->mutex);
3076}
3113 3077
3114 if (unlikely(err)) 3078static int b43_op_tx(struct ieee80211_hw *hw,
3115 goto drop_packet; 3079 struct sk_buff *skb)
3116 return NETDEV_TX_OK; 3080{
3081 struct b43_wl *wl = hw_to_b43_wl(hw);
3082
3083 if (unlikely(skb->len < 2 + 2 + 6)) {
3084 /* Too short, this can't be a valid frame. */
3085 dev_kfree_skb_any(skb);
3086 return NETDEV_TX_OK;
3087 }
3088 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
3089
3090 skb_queue_tail(&wl->tx_queue, skb);
3091 ieee80211_queue_work(wl->hw, &wl->tx_work);
3117 3092
3118drop_packet:
3119 /* We can not transmit this packet. Drop it. */
3120 dev_kfree_skb_any(skb);
3121 return NETDEV_TX_OK; 3093 return NETDEV_TX_OK;
3122} 3094}
3123 3095
3124/* Locking: wl->irq_lock */
3125static void b43_qos_params_upload(struct b43_wldev *dev, 3096static void b43_qos_params_upload(struct b43_wldev *dev,
3126 const struct ieee80211_tx_queue_params *p, 3097 const struct ieee80211_tx_queue_params *p,
3127 u16 shm_offset) 3098 u16 shm_offset)
@@ -3130,6 +3101,9 @@ static void b43_qos_params_upload(struct b43_wldev *dev,
3130 int bslots, tmp; 3101 int bslots, tmp;
3131 unsigned int i; 3102 unsigned int i;
3132 3103
3104 if (!dev->qos_enabled)
3105 return;
3106
3133 bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min; 3107 bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min;
3134 3108
3135 memset(&params, 0, sizeof(params)); 3109 memset(&params, 0, sizeof(params));
@@ -3175,6 +3149,9 @@ static void b43_qos_upload_all(struct b43_wldev *dev)
3175 struct b43_qos_params *params; 3149 struct b43_qos_params *params;
3176 unsigned int i; 3150 unsigned int i;
3177 3151
3152 if (!dev->qos_enabled)
3153 return;
3154
3178 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) != 3155 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3179 ARRAY_SIZE(wl->qos_params)); 3156 ARRAY_SIZE(wl->qos_params));
3180 3157
@@ -3234,6 +3211,16 @@ static void b43_qos_clear(struct b43_wl *wl)
3234/* Initialize the core's QOS capabilities */ 3211/* Initialize the core's QOS capabilities */
3235static void b43_qos_init(struct b43_wldev *dev) 3212static void b43_qos_init(struct b43_wldev *dev)
3236{ 3213{
3214 if (!dev->qos_enabled) {
3215 /* Disable QOS support. */
3216 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_EDCF);
3217 b43_write16(dev, B43_MMIO_IFSCTL,
3218 b43_read16(dev, B43_MMIO_IFSCTL)
3219 & ~B43_MMIO_IFSCTL_USE_EDCF);
3220 b43dbg(dev->wl, "QoS disabled\n");
3221 return;
3222 }
3223
3237 /* Upload the current QOS parameters. */ 3224 /* Upload the current QOS parameters. */
3238 b43_qos_upload_all(dev); 3225 b43_qos_upload_all(dev);
3239 3226
@@ -3242,6 +3229,7 @@ static void b43_qos_init(struct b43_wldev *dev)
3242 b43_write16(dev, B43_MMIO_IFSCTL, 3229 b43_write16(dev, B43_MMIO_IFSCTL,
3243 b43_read16(dev, B43_MMIO_IFSCTL) 3230 b43_read16(dev, B43_MMIO_IFSCTL)
3244 | B43_MMIO_IFSCTL_USE_EDCF); 3231 | B43_MMIO_IFSCTL_USE_EDCF);
3232 b43dbg(dev->wl, "QoS enabled\n");
3245} 3233}
3246 3234
3247static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue, 3235static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
@@ -3283,22 +3271,20 @@ static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
3283 struct ieee80211_tx_queue_stats *stats) 3271 struct ieee80211_tx_queue_stats *stats)
3284{ 3272{
3285 struct b43_wl *wl = hw_to_b43_wl(hw); 3273 struct b43_wl *wl = hw_to_b43_wl(hw);
3286 struct b43_wldev *dev = wl->current_dev; 3274 struct b43_wldev *dev;
3287 unsigned long flags;
3288 int err = -ENODEV; 3275 int err = -ENODEV;
3289 3276
3290 if (!dev) 3277 mutex_lock(&wl->mutex);
3291 goto out; 3278 dev = wl->current_dev;
3292 spin_lock_irqsave(&wl->irq_lock, flags); 3279 if (dev && b43_status(dev) >= B43_STAT_STARTED) {
3293 if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
3294 if (b43_using_pio_transfers(dev)) 3280 if (b43_using_pio_transfers(dev))
3295 b43_pio_get_tx_stats(dev, stats); 3281 b43_pio_get_tx_stats(dev, stats);
3296 else 3282 else
3297 b43_dma_get_tx_stats(dev, stats); 3283 b43_dma_get_tx_stats(dev, stats);
3298 err = 0; 3284 err = 0;
3299 } 3285 }
3300 spin_unlock_irqrestore(&wl->irq_lock, flags); 3286 mutex_unlock(&wl->mutex);
3301out: 3287
3302 return err; 3288 return err;
3303} 3289}
3304 3290
@@ -3306,11 +3292,10 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
3306 struct ieee80211_low_level_stats *stats) 3292 struct ieee80211_low_level_stats *stats)
3307{ 3293{
3308 struct b43_wl *wl = hw_to_b43_wl(hw); 3294 struct b43_wl *wl = hw_to_b43_wl(hw);
3309 unsigned long flags;
3310 3295
3311 spin_lock_irqsave(&wl->irq_lock, flags); 3296 mutex_lock(&wl->mutex);
3312 memcpy(stats, &wl->ieee_stats, sizeof(*stats)); 3297 memcpy(stats, &wl->ieee_stats, sizeof(*stats));
3313 spin_unlock_irqrestore(&wl->irq_lock, flags); 3298 mutex_unlock(&wl->mutex);
3314 3299
3315 return 0; 3300 return 0;
3316} 3301}
@@ -3322,7 +3307,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
3322 u64 tsf; 3307 u64 tsf;
3323 3308
3324 mutex_lock(&wl->mutex); 3309 mutex_lock(&wl->mutex);
3325 spin_lock_irq(&wl->irq_lock);
3326 dev = wl->current_dev; 3310 dev = wl->current_dev;
3327 3311
3328 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) 3312 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
@@ -3330,7 +3314,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
3330 else 3314 else
3331 tsf = 0; 3315 tsf = 0;
3332 3316
3333 spin_unlock_irq(&wl->irq_lock);
3334 mutex_unlock(&wl->mutex); 3317 mutex_unlock(&wl->mutex);
3335 3318
3336 return tsf; 3319 return tsf;
@@ -3342,13 +3325,11 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
3342 struct b43_wldev *dev; 3325 struct b43_wldev *dev;
3343 3326
3344 mutex_lock(&wl->mutex); 3327 mutex_lock(&wl->mutex);
3345 spin_lock_irq(&wl->irq_lock);
3346 dev = wl->current_dev; 3328 dev = wl->current_dev;
3347 3329
3348 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) 3330 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
3349 b43_tsf_write(dev, tsf); 3331 b43_tsf_write(dev, tsf);
3350 3332
3351 spin_unlock_irq(&wl->irq_lock);
3352 mutex_unlock(&wl->mutex); 3333 mutex_unlock(&wl->mutex);
3353} 3334}
3354 3335
@@ -3434,7 +3415,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
3434 prev_status = b43_status(down_dev); 3415 prev_status = b43_status(down_dev);
3435 /* Shutdown the currently running core. */ 3416 /* Shutdown the currently running core. */
3436 if (prev_status >= B43_STAT_STARTED) 3417 if (prev_status >= B43_STAT_STARTED)
3437 b43_wireless_core_stop(down_dev); 3418 down_dev = b43_wireless_core_stop(down_dev);
3438 if (prev_status >= B43_STAT_INITIALIZED) 3419 if (prev_status >= B43_STAT_INITIALIZED)
3439 b43_wireless_core_exit(down_dev); 3420 b43_wireless_core_exit(down_dev);
3440 3421
@@ -3498,7 +3479,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3498 struct b43_wldev *dev; 3479 struct b43_wldev *dev;
3499 struct b43_phy *phy; 3480 struct b43_phy *phy;
3500 struct ieee80211_conf *conf = &hw->conf; 3481 struct ieee80211_conf *conf = &hw->conf;
3501 unsigned long flags;
3502 int antenna; 3482 int antenna;
3503 int err = 0; 3483 int err = 0;
3504 3484
@@ -3529,13 +3509,11 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3529 3509
3530 /* Adjust the desired TX power level. */ 3510 /* Adjust the desired TX power level. */
3531 if (conf->power_level != 0) { 3511 if (conf->power_level != 0) {
3532 spin_lock_irqsave(&wl->irq_lock, flags);
3533 if (conf->power_level != phy->desired_txpower) { 3512 if (conf->power_level != phy->desired_txpower) {
3534 phy->desired_txpower = conf->power_level; 3513 phy->desired_txpower = conf->power_level;
3535 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME | 3514 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME |
3536 B43_TXPWR_IGNORE_TSSI); 3515 B43_TXPWR_IGNORE_TSSI);
3537 } 3516 }
3538 spin_unlock_irqrestore(&wl->irq_lock, flags);
3539 } 3517 }
3540 3518
3541 /* Antennas for RX and management frame TX. */ 3519 /* Antennas for RX and management frame TX. */
@@ -3620,7 +3598,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3620{ 3598{
3621 struct b43_wl *wl = hw_to_b43_wl(hw); 3599 struct b43_wl *wl = hw_to_b43_wl(hw);
3622 struct b43_wldev *dev; 3600 struct b43_wldev *dev;
3623 unsigned long flags;
3624 3601
3625 mutex_lock(&wl->mutex); 3602 mutex_lock(&wl->mutex);
3626 3603
@@ -3630,7 +3607,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3630 3607
3631 B43_WARN_ON(wl->vif != vif); 3608 B43_WARN_ON(wl->vif != vif);
3632 3609
3633 spin_lock_irqsave(&wl->irq_lock, flags);
3634 if (changed & BSS_CHANGED_BSSID) { 3610 if (changed & BSS_CHANGED_BSSID) {
3635 if (conf->bssid) 3611 if (conf->bssid)
3636 memcpy(wl->bssid, conf->bssid, ETH_ALEN); 3612 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
@@ -3648,7 +3624,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3648 if (changed & BSS_CHANGED_BSSID) 3624 if (changed & BSS_CHANGED_BSSID)
3649 b43_write_mac_bssid_templates(dev); 3625 b43_write_mac_bssid_templates(dev);
3650 } 3626 }
3651 spin_unlock_irqrestore(&wl->irq_lock, flags);
3652 3627
3653 b43_mac_suspend(dev); 3628 b43_mac_suspend(dev);
3654 3629
@@ -3689,15 +3664,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3689 return -ENOSPC; /* User disabled HW-crypto */ 3664 return -ENOSPC; /* User disabled HW-crypto */
3690 3665
3691 mutex_lock(&wl->mutex); 3666 mutex_lock(&wl->mutex);
3692 spin_lock_irq(&wl->irq_lock);
3693 write_lock(&wl->tx_lock);
3694 /* Why do we need all this locking here?
3695 * mutex -> Every config operation must take it.
3696 * irq_lock -> We modify the dev->key array, which is accessed
3697 * in the IRQ handlers.
3698 * tx_lock -> We modify the dev->key array, which is accessed
3699 * in the TX handler.
3700 */
3701 3667
3702 dev = wl->current_dev; 3668 dev = wl->current_dev;
3703 err = -ENODEV; 3669 err = -ENODEV;
@@ -3789,8 +3755,6 @@ out_unlock:
3789 sta ? sta->addr : bcast_addr); 3755 sta ? sta->addr : bcast_addr);
3790 b43_dump_keymemory(dev); 3756 b43_dump_keymemory(dev);
3791 } 3757 }
3792 write_unlock(&wl->tx_lock);
3793 spin_unlock_irq(&wl->irq_lock);
3794 mutex_unlock(&wl->mutex); 3758 mutex_unlock(&wl->mutex);
3795 3759
3796 return err; 3760 return err;
@@ -3801,15 +3765,15 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
3801 u64 multicast) 3765 u64 multicast)
3802{ 3766{
3803 struct b43_wl *wl = hw_to_b43_wl(hw); 3767 struct b43_wl *wl = hw_to_b43_wl(hw);
3804 struct b43_wldev *dev = wl->current_dev; 3768 struct b43_wldev *dev;
3805 unsigned long flags;
3806 3769
3770 mutex_lock(&wl->mutex);
3771 dev = wl->current_dev;
3807 if (!dev) { 3772 if (!dev) {
3808 *fflags = 0; 3773 *fflags = 0;
3809 return; 3774 goto out_unlock;
3810 } 3775 }
3811 3776
3812 spin_lock_irqsave(&wl->irq_lock, flags);
3813 *fflags &= FIF_PROMISC_IN_BSS | 3777 *fflags &= FIF_PROMISC_IN_BSS |
3814 FIF_ALLMULTI | 3778 FIF_ALLMULTI |
3815 FIF_FCSFAIL | 3779 FIF_FCSFAIL |
@@ -3830,41 +3794,70 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
3830 3794
3831 if (changed && b43_status(dev) >= B43_STAT_INITIALIZED) 3795 if (changed && b43_status(dev) >= B43_STAT_INITIALIZED)
3832 b43_adjust_opmode(dev); 3796 b43_adjust_opmode(dev);
3833 spin_unlock_irqrestore(&wl->irq_lock, flags); 3797
3798out_unlock:
3799 mutex_unlock(&wl->mutex);
3834} 3800}
3835 3801
3836/* Locking: wl->mutex */ 3802/* Locking: wl->mutex
3837static void b43_wireless_core_stop(struct b43_wldev *dev) 3803 * Returns the current dev. This might be different from the passed in dev,
3804 * because the core might be gone away while we unlocked the mutex. */
3805static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
3838{ 3806{
3839 struct b43_wl *wl = dev->wl; 3807 struct b43_wl *wl = dev->wl;
3840 unsigned long flags; 3808 struct b43_wldev *orig_dev;
3841 3809
3842 if (b43_status(dev) < B43_STAT_STARTED) 3810redo:
3843 return; 3811 if (!dev || b43_status(dev) < B43_STAT_STARTED)
3812 return dev;
3844 3813
3845 /* Disable and sync interrupts. We must do this before than 3814 /* Cancel work. Unlock to avoid deadlocks. */
3846 * setting the status to INITIALIZED, as the interrupt handler 3815 mutex_unlock(&wl->mutex);
3847 * won't care about IRQs then. */ 3816 cancel_delayed_work_sync(&dev->periodic_work);
3848 spin_lock_irqsave(&wl->irq_lock, flags); 3817 cancel_work_sync(&wl->tx_work);
3849 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 3818 mutex_lock(&wl->mutex);
3850 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ 3819 dev = wl->current_dev;
3851 spin_unlock_irqrestore(&wl->irq_lock, flags); 3820 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
3852 b43_synchronize_irq(dev); 3821 /* Whoops, aliens ate up the device while we were unlocked. */
3822 return dev;
3823 }
3853 3824
3854 write_lock_irqsave(&wl->tx_lock, flags); 3825 /* Disable interrupts on the device. */
3855 b43_set_status(dev, B43_STAT_INITIALIZED); 3826 b43_set_status(dev, B43_STAT_INITIALIZED);
3856 write_unlock_irqrestore(&wl->tx_lock, flags); 3827 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
3857 3828 /* wl->mutex is locked. That is enough. */
3858 b43_pio_stop(dev); 3829 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3830 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
3831 } else {
3832 spin_lock_irq(&wl->hardirq_lock);
3833 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3834 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
3835 spin_unlock_irq(&wl->hardirq_lock);
3836 }
3837 /* Synchronize the interrupt handlers. Unlock to avoid deadlocks. */
3838 orig_dev = dev;
3859 mutex_unlock(&wl->mutex); 3839 mutex_unlock(&wl->mutex);
3860 /* Must unlock as it would otherwise deadlock. No races here. 3840 synchronize_irq(dev->dev->irq);
3861 * Cancel the possibly running self-rearming periodic work. */
3862 cancel_delayed_work_sync(&dev->periodic_work);
3863 mutex_lock(&wl->mutex); 3841 mutex_lock(&wl->mutex);
3842 dev = wl->current_dev;
3843 if (!dev)
3844 return dev;
3845 if (dev != orig_dev) {
3846 if (b43_status(dev) >= B43_STAT_STARTED)
3847 goto redo;
3848 return dev;
3849 }
3850 B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK));
3851
3852 /* Drain the TX queue */
3853 while (skb_queue_len(&wl->tx_queue))
3854 dev_kfree_skb(skb_dequeue(&wl->tx_queue));
3864 3855
3865 b43_mac_suspend(dev); 3856 b43_mac_suspend(dev);
3866 free_irq(dev->dev->irq, dev); 3857 free_irq(dev->dev->irq, dev);
3867 b43dbg(wl, "Wireless interface stopped\n"); 3858 b43dbg(wl, "Wireless interface stopped\n");
3859
3860 return dev;
3868} 3861}
3869 3862
3870/* Locking: wl->mutex */ 3863/* Locking: wl->mutex */
@@ -3875,8 +3868,9 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3875 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); 3868 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
3876 3869
3877 drain_txstatus_queue(dev); 3870 drain_txstatus_queue(dev);
3878 err = request_irq(dev->dev->irq, b43_interrupt_handler, 3871 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
3879 IRQF_SHARED, KBUILD_MODNAME, dev); 3872 b43_interrupt_thread_handler,
3873 IRQF_SHARED, KBUILD_MODNAME, dev);
3880 if (err) { 3874 if (err) {
3881 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); 3875 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
3882 goto out; 3876 goto out;
@@ -4098,16 +4092,20 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
4098 bus->pcicore.dev->id.revision <= 5) { 4092 bus->pcicore.dev->id.revision <= 5) {
4099 /* IMCFGLO timeouts workaround. */ 4093 /* IMCFGLO timeouts workaround. */
4100 tmp = ssb_read32(dev->dev, SSB_IMCFGLO); 4094 tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
4101 tmp &= ~SSB_IMCFGLO_REQTO;
4102 tmp &= ~SSB_IMCFGLO_SERTO;
4103 switch (bus->bustype) { 4095 switch (bus->bustype) {
4104 case SSB_BUSTYPE_PCI: 4096 case SSB_BUSTYPE_PCI:
4105 case SSB_BUSTYPE_PCMCIA: 4097 case SSB_BUSTYPE_PCMCIA:
4098 tmp &= ~SSB_IMCFGLO_REQTO;
4099 tmp &= ~SSB_IMCFGLO_SERTO;
4106 tmp |= 0x32; 4100 tmp |= 0x32;
4107 break; 4101 break;
4108 case SSB_BUSTYPE_SSB: 4102 case SSB_BUSTYPE_SSB:
4103 tmp &= ~SSB_IMCFGLO_REQTO;
4104 tmp &= ~SSB_IMCFGLO_SERTO;
4109 tmp |= 0x53; 4105 tmp |= 0x53;
4110 break; 4106 break;
4107 default:
4108 break;
4111 } 4109 }
4112 ssb_write32(dev->dev, SSB_IMCFGLO, tmp); 4110 ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
4113 } 4111 }
@@ -4155,8 +4153,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4155{ 4153{
4156 u32 macctl; 4154 u32 macctl;
4157 4155
4158 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED); 4156 B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
4159 if (b43_status(dev) != B43_STAT_INITIALIZED) 4157 if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
4160 return; 4158 return;
4161 b43_set_status(dev, B43_STAT_UNINIT); 4159 b43_set_status(dev, B43_STAT_UNINIT);
4162 4160
@@ -4309,7 +4307,6 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4309{ 4307{
4310 struct b43_wl *wl = hw_to_b43_wl(hw); 4308 struct b43_wl *wl = hw_to_b43_wl(hw);
4311 struct b43_wldev *dev; 4309 struct b43_wldev *dev;
4312 unsigned long flags;
4313 int err = -EOPNOTSUPP; 4310 int err = -EOPNOTSUPP;
4314 4311
4315 /* TODO: allow WDS/AP devices to coexist */ 4312 /* TODO: allow WDS/AP devices to coexist */
@@ -4333,12 +4330,10 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4333 wl->if_type = conf->type; 4330 wl->if_type = conf->type;
4334 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 4331 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
4335 4332
4336 spin_lock_irqsave(&wl->irq_lock, flags);
4337 b43_adjust_opmode(dev); 4333 b43_adjust_opmode(dev);
4338 b43_set_pretbtt(dev); 4334 b43_set_pretbtt(dev);
4339 b43_set_synth_pu_delay(dev, 0); 4335 b43_set_synth_pu_delay(dev, 0);
4340 b43_upload_card_macaddress(dev); 4336 b43_upload_card_macaddress(dev);
4341 spin_unlock_irqrestore(&wl->irq_lock, flags);
4342 4337
4343 err = 0; 4338 err = 0;
4344 out_mutex_unlock: 4339 out_mutex_unlock:
@@ -4352,7 +4347,6 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
4352{ 4347{
4353 struct b43_wl *wl = hw_to_b43_wl(hw); 4348 struct b43_wl *wl = hw_to_b43_wl(hw);
4354 struct b43_wldev *dev = wl->current_dev; 4349 struct b43_wldev *dev = wl->current_dev;
4355 unsigned long flags;
4356 4350
4357 b43dbg(wl, "Removing Interface type %d\n", conf->type); 4351 b43dbg(wl, "Removing Interface type %d\n", conf->type);
4358 4352
@@ -4364,11 +4358,9 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
4364 4358
4365 wl->operating = 0; 4359 wl->operating = 0;
4366 4360
4367 spin_lock_irqsave(&wl->irq_lock, flags);
4368 b43_adjust_opmode(dev); 4361 b43_adjust_opmode(dev);
4369 memset(wl->mac_addr, 0, ETH_ALEN); 4362 memset(wl->mac_addr, 0, ETH_ALEN);
4370 b43_upload_card_macaddress(dev); 4363 b43_upload_card_macaddress(dev);
4371 spin_unlock_irqrestore(&wl->irq_lock, flags);
4372 4364
4373 mutex_unlock(&wl->mutex); 4365 mutex_unlock(&wl->mutex);
4374} 4366}
@@ -4428,10 +4420,15 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4428 cancel_work_sync(&(wl->beacon_update_trigger)); 4420 cancel_work_sync(&(wl->beacon_update_trigger));
4429 4421
4430 mutex_lock(&wl->mutex); 4422 mutex_lock(&wl->mutex);
4431 if (b43_status(dev) >= B43_STAT_STARTED) 4423 if (b43_status(dev) >= B43_STAT_STARTED) {
4432 b43_wireless_core_stop(dev); 4424 dev = b43_wireless_core_stop(dev);
4425 if (!dev)
4426 goto out_unlock;
4427 }
4433 b43_wireless_core_exit(dev); 4428 b43_wireless_core_exit(dev);
4434 wl->radio_enabled = 0; 4429 wl->radio_enabled = 0;
4430
4431out_unlock:
4435 mutex_unlock(&wl->mutex); 4432 mutex_unlock(&wl->mutex);
4436 4433
4437 cancel_work_sync(&(wl->txpower_adjust_work)); 4434 cancel_work_sync(&(wl->txpower_adjust_work));
@@ -4441,11 +4438,10 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
4441 struct ieee80211_sta *sta, bool set) 4438 struct ieee80211_sta *sta, bool set)
4442{ 4439{
4443 struct b43_wl *wl = hw_to_b43_wl(hw); 4440 struct b43_wl *wl = hw_to_b43_wl(hw);
4444 unsigned long flags;
4445 4441
4446 spin_lock_irqsave(&wl->irq_lock, flags); 4442 mutex_lock(&wl->mutex);
4447 b43_update_templates(wl); 4443 b43_update_templates(wl);
4448 spin_unlock_irqrestore(&wl->irq_lock, flags); 4444 mutex_unlock(&wl->mutex);
4449 4445
4450 return 0; 4446 return 0;
4451} 4447}
@@ -4526,8 +4522,13 @@ static void b43_chip_reset(struct work_struct *work)
4526 4522
4527 prev_status = b43_status(dev); 4523 prev_status = b43_status(dev);
4528 /* Bring the device down... */ 4524 /* Bring the device down... */
4529 if (prev_status >= B43_STAT_STARTED) 4525 if (prev_status >= B43_STAT_STARTED) {
4530 b43_wireless_core_stop(dev); 4526 dev = b43_wireless_core_stop(dev);
4527 if (!dev) {
4528 err = -ENODEV;
4529 goto out;
4530 }
4531 }
4531 if (prev_status >= B43_STAT_INITIALIZED) 4532 if (prev_status >= B43_STAT_INITIALIZED)
4532 b43_wireless_core_exit(dev); 4533 b43_wireless_core_exit(dev);
4533 4534
@@ -4742,9 +4743,6 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
4742 wldev->wl = wl; 4743 wldev->wl = wl;
4743 b43_set_status(wldev, B43_STAT_UNINIT); 4744 b43_set_status(wldev, B43_STAT_UNINIT);
4744 wldev->bad_frames_preempt = modparam_bad_frames_preempt; 4745 wldev->bad_frames_preempt = modparam_bad_frames_preempt;
4745 tasklet_init(&wldev->isr_tasklet,
4746 (void (*)(unsigned long))b43_interrupt_tasklet,
4747 (unsigned long)wldev);
4748 INIT_LIST_HEAD(&wldev->list); 4746 INIT_LIST_HEAD(&wldev->list);
4749 4747
4750 err = b43_wireless_core_attach(wldev); 4748 err = b43_wireless_core_attach(wldev);
@@ -4841,14 +4839,14 @@ static int b43_wireless_init(struct ssb_device *dev)
4841 4839
4842 /* Initialize struct b43_wl */ 4840 /* Initialize struct b43_wl */
4843 wl->hw = hw; 4841 wl->hw = hw;
4844 spin_lock_init(&wl->irq_lock);
4845 rwlock_init(&wl->tx_lock);
4846 spin_lock_init(&wl->leds_lock); 4842 spin_lock_init(&wl->leds_lock);
4847 spin_lock_init(&wl->shm_lock);
4848 mutex_init(&wl->mutex); 4843 mutex_init(&wl->mutex);
4844 spin_lock_init(&wl->hardirq_lock);
4849 INIT_LIST_HEAD(&wl->devlist); 4845 INIT_LIST_HEAD(&wl->devlist);
4850 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 4846 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
4851 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 4847 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
4848 INIT_WORK(&wl->tx_work, b43_tx_work);
4849 skb_queue_head_init(&wl->tx_queue);
4852 4850
4853 ssb_set_devtypedata(dev, wl); 4851 ssb_set_devtypedata(dev, wl);
4854 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", 4852 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
@@ -4946,8 +4944,8 @@ static int b43_suspend(struct ssb_device *dev, pm_message_t state)
4946 wldev->suspend_in_progress = true; 4944 wldev->suspend_in_progress = true;
4947 wldev->suspend_init_status = b43_status(wldev); 4945 wldev->suspend_init_status = b43_status(wldev);
4948 if (wldev->suspend_init_status >= B43_STAT_STARTED) 4946 if (wldev->suspend_init_status >= B43_STAT_STARTED)
4949 b43_wireless_core_stop(wldev); 4947 wldev = b43_wireless_core_stop(wldev);
4950 if (wldev->suspend_init_status >= B43_STAT_INITIALIZED) 4948 if (wldev && wldev->suspend_init_status >= B43_STAT_INITIALIZED)
4951 b43_wireless_core_exit(wldev); 4949 b43_wireless_core_exit(wldev);
4952 mutex_unlock(&wl->mutex); 4950 mutex_unlock(&wl->mutex);
4953 4951
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 0406e06781d4..40db03678d9f 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -112,13 +112,9 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
112void b43_tsf_write(struct b43_wldev *dev, u64 tsf); 112void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
113 113
114u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); 114u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
115u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
116u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); 115u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
117u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
118void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); 116void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
119void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
120void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); 117void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
121void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
122 118
123u64 b43_hf_read(struct b43_wldev *dev); 119u64 b43_hf_read(struct b43_wldev *dev);
124void b43_hf_write(struct b43_wldev *dev, u64 value); 120void b43_hf_write(struct b43_wldev *dev, u64 value);
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 6e704becda6f..75b26e175e8f 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -347,7 +347,6 @@ void b43_phy_txpower_adjust_work(struct work_struct *work)
347 mutex_unlock(&wl->mutex); 347 mutex_unlock(&wl->mutex);
348} 348}
349 349
350/* Called with wl->irq_lock locked */
351void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) 350void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
352{ 351{
353 struct b43_phy *phy = &dev->phy; 352 struct b43_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 28e384633c34..9edd4e8e0c85 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -131,7 +131,7 @@ enum b43_txpwr_result {
131 * If the parameter "ignore_tssi" is true, the TSSI values should 131 * If the parameter "ignore_tssi" is true, the TSSI values should
132 * be ignored and a recalculation of the power settings should be 132 * be ignored and a recalculation of the power settings should be
133 * done even if the TSSI values did not change. 133 * done even if the TSSI values did not change.
134 * This callback is called with wl->irq_lock held and must not sleep. 134 * This function may sleep, but should not.
135 * Must not be NULL. 135 * Must not be NULL.
136 * @adjust_txpower: Write the previously calculated TX power settings 136 * @adjust_txpower: Write the previously calculated TX power settings
137 * (from @recalc_txpower) to the hardware. 137 * (from @recalc_txpower) to the hardware.
@@ -379,7 +379,6 @@ void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
379 * 379 *
380 * Compare the current TX power output to the desired power emission 380 * Compare the current TX power output to the desired power emission
381 * and schedule an adjustment in case it mismatches. 381 * and schedule an adjustment in case it mismatches.
382 * Requires wl->irq_lock locked.
383 * 382 *
384 * @flags: OR'ed enum b43_phy_txpower_check_flags flags. 383 * @flags: OR'ed enum b43_phy_txpower_check_flags flags.
385 * See the docs below. 384 * See the docs below.
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 5afa4df0b02f..382826a8da82 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2823,8 +2823,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
2823 2823
2824 b43_mac_suspend(dev); 2824 b43_mac_suspend(dev);
2825 2825
2826 spin_lock_irq(&dev->wl->irq_lock);
2827
2828 /* Calculate the new attenuation values. */ 2826 /* Calculate the new attenuation values. */
2829 bbatt = gphy->bbatt.att; 2827 bbatt = gphy->bbatt.att;
2830 bbatt += gphy->bbatt_delta; 2828 bbatt += gphy->bbatt_delta;
@@ -2864,11 +2862,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
2864 gphy->rfatt.att = rfatt; 2862 gphy->rfatt.att = rfatt;
2865 gphy->bbatt.att = bbatt; 2863 gphy->bbatt.att = bbatt;
2866 2864
2867 /* We drop the lock early, so we can sleep during hardware
2868 * adjustment. Possible races with op_recalc_txpower are harmless,
2869 * as we will be called once again in case we raced. */
2870 spin_unlock_irq(&dev->wl->irq_lock);
2871
2872 if (b43_debug(dev, B43_DBG_XMITPOWER)) 2865 if (b43_debug(dev, B43_DBG_XMITPOWER))
2873 b43dbg(dev->wl, "Adjusting TX power\n"); 2866 b43dbg(dev->wl, "Adjusting TX power\n");
2874 2867
diff --git a/drivers/net/wireless/b43/phy_g.h b/drivers/net/wireless/b43/phy_g.h
index 718947fd41ae..8569fdd4c6be 100644
--- a/drivers/net/wireless/b43/phy_g.h
+++ b/drivers/net/wireless/b43/phy_g.h
@@ -141,8 +141,7 @@ struct b43_phy_g {
141 int tgt_idle_tssi; 141 int tgt_idle_tssi;
142 /* Current idle TSSI */ 142 /* Current idle TSSI */
143 int cur_idle_tssi; 143 int cur_idle_tssi;
144 /* The current average TSSI. 144 /* The current average TSSI. */
145 * Needs irq_lock, as it's updated in the IRQ path. */
146 u8 average_tssi; 145 u8 average_tssi;
147 /* Current TX power level attenuation control values */ 146 /* Current TX power level attenuation control values */
148 struct b43_bbatt bbatt; 147 struct b43_bbatt bbatt;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 3fd653c78b10..3498b68385e7 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -32,9 +32,6 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33 33
34 34
35static void b43_pio_rx_work(struct work_struct *work);
36
37
38static u16 generate_cookie(struct b43_pio_txqueue *q, 35static u16 generate_cookie(struct b43_pio_txqueue *q,
39 struct b43_pio_txpacket *pack) 36 struct b43_pio_txpacket *pack)
40{ 37{
@@ -144,7 +141,6 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
144 q = kzalloc(sizeof(*q), GFP_KERNEL); 141 q = kzalloc(sizeof(*q), GFP_KERNEL);
145 if (!q) 142 if (!q)
146 return NULL; 143 return NULL;
147 spin_lock_init(&q->lock);
148 q->dev = dev; 144 q->dev = dev;
149 q->rev = dev->dev->id.revision; 145 q->rev = dev->dev->id.revision;
150 q->mmio_base = index_to_pioqueue_base(dev, index) + 146 q->mmio_base = index_to_pioqueue_base(dev, index) +
@@ -179,12 +175,10 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
179 q = kzalloc(sizeof(*q), GFP_KERNEL); 175 q = kzalloc(sizeof(*q), GFP_KERNEL);
180 if (!q) 176 if (!q)
181 return NULL; 177 return NULL;
182 spin_lock_init(&q->lock);
183 q->dev = dev; 178 q->dev = dev;
184 q->rev = dev->dev->id.revision; 179 q->rev = dev->dev->id.revision;
185 q->mmio_base = index_to_pioqueue_base(dev, index) + 180 q->mmio_base = index_to_pioqueue_base(dev, index) +
186 pio_rxqueue_offset(dev); 181 pio_rxqueue_offset(dev);
187 INIT_WORK(&q->rx_work, b43_pio_rx_work);
188 182
189 /* Enable Direct FIFO RX (PIO) on the engine. */ 183 /* Enable Direct FIFO RX (PIO) on the engine. */
190 b43_dma_direct_fifo_rx(dev, index, 1); 184 b43_dma_direct_fifo_rx(dev, index, 1);
@@ -249,13 +243,6 @@ void b43_pio_free(struct b43_wldev *dev)
249 destroy_queue_tx(pio, tx_queue_AC_BK); 243 destroy_queue_tx(pio, tx_queue_AC_BK);
250} 244}
251 245
252void b43_pio_stop(struct b43_wldev *dev)
253{
254 if (!b43_using_pio_transfers(dev))
255 return;
256 cancel_work_sync(&dev->pio.rx_queue->rx_work);
257}
258
259int b43_pio_init(struct b43_wldev *dev) 246int b43_pio_init(struct b43_wldev *dev)
260{ 247{
261 struct b43_pio *pio = &dev->pio; 248 struct b43_pio *pio = &dev->pio;
@@ -494,7 +481,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
494{ 481{
495 struct b43_pio_txqueue *q; 482 struct b43_pio_txqueue *q;
496 struct ieee80211_hdr *hdr; 483 struct ieee80211_hdr *hdr;
497 unsigned long flags;
498 unsigned int hdrlen, total_len; 484 unsigned int hdrlen, total_len;
499 int err = 0; 485 int err = 0;
500 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 486 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -512,20 +498,18 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
512 q = select_queue_by_priority(dev, skb_get_queue_mapping(skb)); 498 q = select_queue_by_priority(dev, skb_get_queue_mapping(skb));
513 } 499 }
514 500
515 spin_lock_irqsave(&q->lock, flags);
516
517 hdrlen = b43_txhdr_size(dev); 501 hdrlen = b43_txhdr_size(dev);
518 total_len = roundup(skb->len + hdrlen, 4); 502 total_len = roundup(skb->len + hdrlen, 4);
519 503
520 if (unlikely(total_len > q->buffer_size)) { 504 if (unlikely(total_len > q->buffer_size)) {
521 err = -ENOBUFS; 505 err = -ENOBUFS;
522 b43dbg(dev->wl, "PIO: TX packet longer than queue.\n"); 506 b43dbg(dev->wl, "PIO: TX packet longer than queue.\n");
523 goto out_unlock; 507 goto out;
524 } 508 }
525 if (unlikely(q->free_packet_slots == 0)) { 509 if (unlikely(q->free_packet_slots == 0)) {
526 err = -ENOBUFS; 510 err = -ENOBUFS;
527 b43warn(dev->wl, "PIO: TX packet overflow.\n"); 511 b43warn(dev->wl, "PIO: TX packet overflow.\n");
528 goto out_unlock; 512 goto out;
529 } 513 }
530 B43_WARN_ON(q->buffer_used > q->buffer_size); 514 B43_WARN_ON(q->buffer_used > q->buffer_size);
531 515
@@ -534,7 +518,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
534 err = -EBUSY; 518 err = -EBUSY;
535 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); 519 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
536 q->stopped = 1; 520 q->stopped = 1;
537 goto out_unlock; 521 goto out;
538 } 522 }
539 523
540 /* Assign the queue number to the ring (if not already done before) 524 /* Assign the queue number to the ring (if not already done before)
@@ -548,11 +532,11 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
548 * anymore and must not transmit it unencrypted. */ 532 * anymore and must not transmit it unencrypted. */
549 dev_kfree_skb_any(skb); 533 dev_kfree_skb_any(skb);
550 err = 0; 534 err = 0;
551 goto out_unlock; 535 goto out;
552 } 536 }
553 if (unlikely(err)) { 537 if (unlikely(err)) {
554 b43err(dev->wl, "PIO transmission failure\n"); 538 b43err(dev->wl, "PIO transmission failure\n");
555 goto out_unlock; 539 goto out;
556 } 540 }
557 q->nr_tx_packets++; 541 q->nr_tx_packets++;
558 542
@@ -564,13 +548,10 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
564 q->stopped = 1; 548 q->stopped = 1;
565 } 549 }
566 550
567out_unlock: 551out:
568 spin_unlock_irqrestore(&q->lock, flags);
569
570 return err; 552 return err;
571} 553}
572 554
573/* Called with IRQs disabled. */
574void b43_pio_handle_txstatus(struct b43_wldev *dev, 555void b43_pio_handle_txstatus(struct b43_wldev *dev,
575 const struct b43_txstatus *status) 556 const struct b43_txstatus *status)
576{ 557{
@@ -584,8 +565,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
584 return; 565 return;
585 B43_WARN_ON(!pack); 566 B43_WARN_ON(!pack);
586 567
587 spin_lock(&q->lock); /* IRQs are already disabled. */
588
589 info = IEEE80211_SKB_CB(pack->skb); 568 info = IEEE80211_SKB_CB(pack->skb);
590 569
591 b43_fill_txstatus_report(dev, info, status); 570 b43_fill_txstatus_report(dev, info, status);
@@ -603,8 +582,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
603 ieee80211_wake_queue(dev->wl->hw, q->queue_prio); 582 ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
604 q->stopped = 0; 583 q->stopped = 0;
605 } 584 }
606
607 spin_unlock(&q->lock);
608} 585}
609 586
610void b43_pio_get_tx_stats(struct b43_wldev *dev, 587void b43_pio_get_tx_stats(struct b43_wldev *dev,
@@ -612,17 +589,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
612{ 589{
613 const int nr_queues = dev->wl->hw->queues; 590 const int nr_queues = dev->wl->hw->queues;
614 struct b43_pio_txqueue *q; 591 struct b43_pio_txqueue *q;
615 unsigned long flags;
616 int i; 592 int i;
617 593
618 for (i = 0; i < nr_queues; i++) { 594 for (i = 0; i < nr_queues; i++) {
619 q = select_queue_by_priority(dev, i); 595 q = select_queue_by_priority(dev, i);
620 596
621 spin_lock_irqsave(&q->lock, flags);
622 stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots; 597 stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
623 stats[i].limit = B43_PIO_MAX_NR_TXPACKETS; 598 stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
624 stats[i].count = q->nr_tx_packets; 599 stats[i].count = q->nr_tx_packets;
625 spin_unlock_irqrestore(&q->lock, flags);
626 } 600 }
627} 601}
628 602
@@ -760,37 +734,23 @@ rx_error:
760 return 1; 734 return 1;
761} 735}
762 736
763/* RX workqueue. We can sleep, yay! */ 737void b43_pio_rx(struct b43_pio_rxqueue *q)
764static void b43_pio_rx_work(struct work_struct *work)
765{ 738{
766 struct b43_pio_rxqueue *q = container_of(work, struct b43_pio_rxqueue, 739 unsigned int count = 0;
767 rx_work);
768 unsigned int budget = 50;
769 bool stop; 740 bool stop;
770 741
771 do { 742 while (1) {
772 spin_lock_irq(&q->lock);
773 stop = (pio_rx_frame(q) == 0); 743 stop = (pio_rx_frame(q) == 0);
774 spin_unlock_irq(&q->lock);
775 cond_resched();
776 if (stop) 744 if (stop)
777 break; 745 break;
778 } while (--budget); 746 cond_resched();
779} 747 if (WARN_ON_ONCE(++count > 10000))
780 748 break;
781/* Called with IRQs disabled. */ 749 }
782void b43_pio_rx(struct b43_pio_rxqueue *q)
783{
784 /* Due to latency issues we must run the RX path in
785 * a workqueue to be able to schedule between packets. */
786 ieee80211_queue_work(q->dev->wl->hw, &q->rx_work);
787} 750}
788 751
789static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q) 752static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
790{ 753{
791 unsigned long flags;
792
793 spin_lock_irqsave(&q->lock, flags);
794 if (q->rev >= 8) { 754 if (q->rev >= 8) {
795 b43_piotx_write32(q, B43_PIO8_TXCTL, 755 b43_piotx_write32(q, B43_PIO8_TXCTL,
796 b43_piotx_read32(q, B43_PIO8_TXCTL) 756 b43_piotx_read32(q, B43_PIO8_TXCTL)
@@ -800,14 +760,10 @@ static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
800 b43_piotx_read16(q, B43_PIO_TXCTL) 760 b43_piotx_read16(q, B43_PIO_TXCTL)
801 | B43_PIO_TXCTL_SUSPREQ); 761 | B43_PIO_TXCTL_SUSPREQ);
802 } 762 }
803 spin_unlock_irqrestore(&q->lock, flags);
804} 763}
805 764
806static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q) 765static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
807{ 766{
808 unsigned long flags;
809
810 spin_lock_irqsave(&q->lock, flags);
811 if (q->rev >= 8) { 767 if (q->rev >= 8) {
812 b43_piotx_write32(q, B43_PIO8_TXCTL, 768 b43_piotx_write32(q, B43_PIO8_TXCTL,
813 b43_piotx_read32(q, B43_PIO8_TXCTL) 769 b43_piotx_read32(q, B43_PIO8_TXCTL)
@@ -817,7 +773,6 @@ static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
817 b43_piotx_read16(q, B43_PIO_TXCTL) 773 b43_piotx_read16(q, B43_PIO_TXCTL)
818 & ~B43_PIO_TXCTL_SUSPREQ); 774 & ~B43_PIO_TXCTL_SUSPREQ);
819 } 775 }
820 spin_unlock_irqrestore(&q->lock, flags);
821} 776}
822 777
823void b43_pio_tx_suspend(struct b43_wldev *dev) 778void b43_pio_tx_suspend(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index 6c174c91ca20..7dd649c9ddad 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -70,7 +70,6 @@ struct b43_pio_txpacket {
70 70
71struct b43_pio_txqueue { 71struct b43_pio_txqueue {
72 struct b43_wldev *dev; 72 struct b43_wldev *dev;
73 spinlock_t lock;
74 u16 mmio_base; 73 u16 mmio_base;
75 74
76 /* The device queue buffer size in bytes. */ 75 /* The device queue buffer size in bytes. */
@@ -103,12 +102,8 @@ struct b43_pio_txqueue {
103 102
104struct b43_pio_rxqueue { 103struct b43_pio_rxqueue {
105 struct b43_wldev *dev; 104 struct b43_wldev *dev;
106 spinlock_t lock;
107 u16 mmio_base; 105 u16 mmio_base;
108 106
109 /* Work to reduce latency issues on RX. */
110 struct work_struct rx_work;
111
112 /* Shortcut to the 802.11 core revision. This is to 107 /* Shortcut to the 802.11 core revision. This is to
113 * avoid horrible pointer dereferencing in the fastpaths. */ 108 * avoid horrible pointer dereferencing in the fastpaths. */
114 u8 rev; 109 u8 rev;
@@ -162,7 +157,6 @@ static inline void b43_piorx_write32(struct b43_pio_rxqueue *q,
162 157
163 158
164int b43_pio_init(struct b43_wldev *dev); 159int b43_pio_init(struct b43_wldev *dev);
165void b43_pio_stop(struct b43_wldev *dev);
166void b43_pio_free(struct b43_wldev *dev); 160void b43_pio_free(struct b43_wldev *dev);
167 161
168int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); 162int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index 5adaa3692d75..f1ae4e05a32c 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -94,7 +94,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
94 const char *buf, size_t count) 94 const char *buf, size_t count)
95{ 95{
96 struct b43_wldev *wldev = dev_to_b43_wldev(dev); 96 struct b43_wldev *wldev = dev_to_b43_wldev(dev);
97 unsigned long flags;
98 int err; 97 int err;
99 int mode; 98 int mode;
100 99
@@ -120,7 +119,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
120 } 119 }
121 120
122 mutex_lock(&wldev->wl->mutex); 121 mutex_lock(&wldev->wl->mutex);
123 spin_lock_irqsave(&wldev->wl->irq_lock, flags);
124 122
125 if (wldev->phy.ops->interf_mitigation) { 123 if (wldev->phy.ops->interf_mitigation) {
126 err = wldev->phy.ops->interf_mitigation(wldev, mode); 124 err = wldev->phy.ops->interf_mitigation(wldev, mode);
@@ -132,7 +130,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
132 err = -ENOSYS; 130 err = -ENOSYS;
133 131
134 mmiowb(); 132 mmiowb();
135 spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
136 mutex_unlock(&wldev->wl->mutex); 133 mutex_unlock(&wldev->wl->mutex);
137 134
138 return err ? err : count; 135 return err ? err : count;
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index e7075d2c7757..14f541248b5c 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -267,11 +267,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
267 */ 267 */
268 ieee80211_get_tkip_key(info->control.hw_key, skb_frag, 268 ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
269 IEEE80211_TKIP_P1_KEY, (u8*)phase1key); 269 IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
270 /* phase1key is in host endian */ 270 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
271 for (i = 0; i < 5; i++) 271 for (i = 0; i < 5; i++) {
272 phase1key[i] = cpu_to_le16(phase1key[i]); 272 txhdr->iv[i * 2 + 0] = phase1key[i];
273 273 txhdr->iv[i * 2 + 1] = phase1key[i] >> 8;
274 memcpy(txhdr->iv, phase1key, 10); 274 }
275 /* iv16 */ 275 /* iv16 */
276 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3); 276 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
277 } else { 277 } else {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index b166a6f9f055..1d9223b3d4c4 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3106,16 +3106,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
3106 bus->pcicore.dev->id.revision <= 5) { 3106 bus->pcicore.dev->id.revision <= 5) {
3107 /* IMCFGLO timeouts workaround. */ 3107 /* IMCFGLO timeouts workaround. */
3108 tmp = ssb_read32(dev->dev, SSB_IMCFGLO); 3108 tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
3109 tmp &= ~SSB_IMCFGLO_REQTO;
3110 tmp &= ~SSB_IMCFGLO_SERTO;
3111 switch (bus->bustype) { 3109 switch (bus->bustype) {
3112 case SSB_BUSTYPE_PCI: 3110 case SSB_BUSTYPE_PCI:
3113 case SSB_BUSTYPE_PCMCIA: 3111 case SSB_BUSTYPE_PCMCIA:
3112 tmp &= ~SSB_IMCFGLO_REQTO;
3113 tmp &= ~SSB_IMCFGLO_SERTO;
3114 tmp |= 0x32; 3114 tmp |= 0x32;
3115 break; 3115 break;
3116 case SSB_BUSTYPE_SSB: 3116 case SSB_BUSTYPE_SSB:
3117 tmp &= ~SSB_IMCFGLO_REQTO;
3118 tmp &= ~SSB_IMCFGLO_SERTO;
3117 tmp |= 0x53; 3119 tmp |= 0x53;
3118 break; 3120 break;
3121 default:
3122 break;
3119 } 3123 }
3120 ssb_write32(dev->dev, SSB_IMCFGLO, tmp); 3124 ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
3121 } 3125 }
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 164df9347a2f..798f625e38f7 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -331,9 +331,8 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
331 preamble_mask = erp->short_preamble << 3; 331 preamble_mask = erp->short_preamble << 3;
332 332
333 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg); 333 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
334 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout); 334 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
335 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 335 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
336 erp->ack_consume_time);
337 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); 336 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
338 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1); 337 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
339 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); 338 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 4186582f2770..2e872ac69826 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -337,9 +337,8 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
337 preamble_mask = erp->short_preamble << 3; 337 preamble_mask = erp->short_preamble << 3;
338 338
339 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg); 339 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
340 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout); 340 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
341 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 341 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
342 erp->ack_consume_time);
343 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); 342 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
344 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1); 343 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
345 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); 344 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index b04f59bab3b0..22dd6d9e2981 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -488,10 +488,6 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
488{ 488{
489 u16 reg; 489 u16 reg;
490 490
491 rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
492 rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout);
493 rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg);
494
495 rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg); 491 rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
496 rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE, 492 rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
497 !!erp->short_preamble); 493 !!erp->short_preamble);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 639dc6cc04b9..a084077a1c61 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -580,8 +580,7 @@ static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
580 u32 reg; 580 u32 reg;
581 581
582 rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg); 582 rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
583 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 583 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
584 DIV_ROUND_UP(erp->ack_timeout, erp->slot_time));
585 rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg); 584 rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
586 585
587 rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg); 586 rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 555a777db6df..27bc6b7fbfde 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -417,9 +417,6 @@ struct rt2x00lib_erp {
417 int short_preamble; 417 int short_preamble;
418 int cts_protection; 418 int cts_protection;
419 419
420 int ack_timeout;
421 int ack_consume_time;
422
423 u32 basic_rates; 420 u32 basic_rates;
424 421
425 int slot_time; 422 int slot_time;
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 3501788ab498..40a201e2e151 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -94,17 +94,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
94 erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS; 94 erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
95 erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS; 95 erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
96 96
97 erp.ack_timeout = PLCP + erp.difs + GET_DURATION(ACK_SIZE, 10);
98 erp.ack_consume_time = SIFS + PLCP + GET_DURATION(ACK_SIZE, 10);
99
100 if (bss_conf->use_short_preamble) {
101 erp.ack_timeout += SHORT_PREAMBLE;
102 erp.ack_consume_time += SHORT_PREAMBLE;
103 } else {
104 erp.ack_timeout += PREAMBLE;
105 erp.ack_consume_time += PREAMBLE;
106 }
107
108 erp.basic_rates = bss_conf->basic_rates; 97 erp.basic_rates = bss_conf->basic_rates;
109 erp.beacon_int = bss_conf->beacon_int; 98 erp.beacon_int = bss_conf->beacon_int;
110 99
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f4b4b86da4da..b20e3eac9d67 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -598,7 +598,7 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
598 u32 reg; 598 u32 reg;
599 599
600 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg); 600 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
601 rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); 601 rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
602 rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); 602 rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
603 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); 603 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
604 604
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 90e117263051..1cbd9b4a3efc 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -561,7 +561,7 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
561 u32 reg; 561 u32 reg;
562 562
563 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg); 563 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
564 rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); 564 rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
565 rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); 565 rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
566 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); 566 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
567 567