aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig14
-rw-r--r--drivers/net/ps3_gelic_wireless.c149
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/adm8211.c25
-rw-r--r--drivers/net/wireless/airo.c35
-rw-r--r--drivers/net/wireless/at76c50x-usb.c6
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h17
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h1
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c193
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h27
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c106
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c121
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c25
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c31
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h80
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c199
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h32
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c442
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c168
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c863
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h34
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c1451
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c73
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c62
-rw-r--r--drivers/net/wireless/ath/debug.h8
-rw-r--r--drivers/net/wireless/ath/regd.c5
-rw-r--r--drivers/net/wireless/b43/Kconfig17
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/b43.h21
-rw-r--r--drivers/net/wireless/b43/dma.c19
-rw-r--r--drivers/net/wireless/b43/dma.h5
-rw-r--r--drivers/net/wireless/b43/main.c96
-rw-r--r--drivers/net/wireless/b43/phy_common.c45
-rw-r--r--drivers/net/wireless/b43/phy_common.h10
-rw-r--r--drivers/net/wireless/b43/phy_lp.c76
-rw-r--r--drivers/net/wireless/b43/phy_n.c3035
-rw-r--r--drivers/net/wireless/b43/phy_n.h98
-rw-r--r--drivers/net/wireless/b43/pio.c17
-rw-r--r--drivers/net/wireless/b43/pio.h45
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c744
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h100
-rw-r--r--drivers/net/wireless/b43legacy/dma.c20
-rw-r--r--drivers/net/wireless/b43legacy/dma.h10
-rw-r--r--drivers/net/wireless/b43legacy/leds.h2
-rw-r--r--drivers/net/wireless/b43legacy/main.c61
-rw-r--r--drivers/net/wireless/b43legacy/pio.c13
-rw-r--r--drivers/net/wireless/b43legacy/pio.h11
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c17
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c9
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c125
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c116
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c366
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h67
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c388
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1461
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c182
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c258
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c198
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c150
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c197
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c71
-rw-r--r--drivers/net/wireless/libertas/Kconfig6
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/assoc.c95
-rw-r--r--drivers/net/wireless/libertas/cmd.c22
-rw-r--r--drivers/net/wireless/libertas/cmd.h12
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c21
-rw-r--r--drivers/net/wireless/libertas/defs.h7
-rw-r--r--drivers/net/wireless/libertas/dev.h8
-rw-r--r--drivers/net/wireless/libertas/ethtool.c2
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/libertas/main.c73
-rw-r--r--drivers/net/wireless/libertas/mesh.c29
-rw-r--r--drivers/net/wireless/libertas/mesh.h32
-rw-r--r--drivers/net/wireless/libertas/scan.c2
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c26
-rw-r--r--drivers/net/wireless/libertas_tf/main.c13
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c198
-rw-r--r--drivers/net/wireless/mwl8k.c2084
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c9
-rw-r--r--drivers/net/wireless/p54/main.c51
-rw-r--r--drivers/net/wireless/p54/p54.h8
-rw-r--r--drivers/net/wireless/p54/p54pci.c74
-rw-r--r--drivers/net/wireless/p54/p54pci.h6
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/p54/txrx.c4
-rw-r--r--drivers/net/wireless/rndis_wlan.c42
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig71
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c46
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h14
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c203
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c102
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c373
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h90
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h96
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c42
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c79
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c44
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c41
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c35
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c26
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c6
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.h2
-rw-r--r--drivers/net/wireless/wl12xx/Makefile4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c69
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.h87
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.h22
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c23
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.c5
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.h47
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c375
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.h17
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c196
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h50
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c102
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c137
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h174
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c62
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c68
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c50
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.h4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.c213
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h68
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c823
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c37
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_reg.h99
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c158
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.h30
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c283
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.h31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c71
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h36
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c14
217 files changed, 13680 insertions, 7172 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 18ff622703be..6460505ab24c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2354,20 +2354,6 @@ config GELIC_WIRELESS
2354 the driver automatically distinguishes the models, you can 2354 the driver automatically distinguishes the models, you can
2355 safely enable this option even if you have a wireless-less model. 2355 safely enable this option even if you have a wireless-less model.
2356 2356
2357config GELIC_WIRELESS_OLD_PSK_INTERFACE
2358 bool "PS3 Wireless private PSK interface (OBSOLETE)"
2359 depends on GELIC_WIRELESS
2360 select WEXT_PRIV
2361 help
2362 This option retains the obsolete private interface to pass
2363 the PSK from user space programs to the driver. The PSK
2364 stands for 'Pre Shared Key' and is used for WPA[2]-PSK
2365 (WPA-Personal) environment.
2366 If WPA[2]-PSK is used and you need to use old programs that
2367 support only this old interface, say Y. Otherwise N.
2368
2369 If unsure, say N.
2370
2371config FSL_PQ_MDIO 2357config FSL_PQ_MDIO
2372 tristate "Freescale PQ MDIO" 2358 tristate "Freescale PQ MDIO"
2373 depends on FSL_SOC 2359 depends on FSL_SOC
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 227b141c4fbd..2663b2fdc0bb 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -1389,113 +1389,6 @@ static int gelic_wl_get_mode(struct net_device *netdev,
1389 return 0; 1389 return 0;
1390} 1390}
1391 1391
1392#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
1393/* SIOCIWFIRSTPRIV */
1394static int hex2bin(u8 *str, u8 *bin, unsigned int len)
1395{
1396 unsigned int i;
1397 static unsigned char *hex = "0123456789ABCDEF";
1398 unsigned char *p, *q;
1399 u8 tmp;
1400
1401 if (len != WPA_PSK_LEN * 2)
1402 return -EINVAL;
1403
1404 for (i = 0; i < WPA_PSK_LEN * 2; i += 2) {
1405 p = strchr(hex, toupper(str[i]));
1406 q = strchr(hex, toupper(str[i + 1]));
1407 if (!p || !q) {
1408 pr_info("%s: unconvertible PSK digit=%d\n",
1409 __func__, i);
1410 return -EINVAL;
1411 }
1412 tmp = ((p - hex) << 4) + (q - hex);
1413 *bin++ = tmp;
1414 }
1415 return 0;
1416};
1417
1418static int gelic_wl_priv_set_psk(struct net_device *net_dev,
1419 struct iw_request_info *info,
1420 union iwreq_data *data, char *extra)
1421{
1422 struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
1423 unsigned int len;
1424 unsigned long irqflag;
1425 int ret = 0;
1426
1427 pr_debug("%s:<- len=%d\n", __func__, data->data.length);
1428 len = data->data.length - 1;
1429 if (len <= 2)
1430 return -EINVAL;
1431
1432 spin_lock_irqsave(&wl->lock, irqflag);
1433 if (extra[0] == '"' && extra[len - 1] == '"') {
1434 pr_debug("%s: passphrase mode\n", __func__);
1435 /* pass phrase */
1436 if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) {
1437 pr_info("%s: passphrase too long\n", __func__);
1438 ret = -E2BIG;
1439 goto out;
1440 }
1441 memset(wl->psk, 0, sizeof(wl->psk));
1442 wl->psk_len = len - 2;
1443 memcpy(wl->psk, &(extra[1]), wl->psk_len);
1444 wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
1445 } else {
1446 ret = hex2bin(extra, wl->psk, len);
1447 if (ret)
1448 goto out;
1449 wl->psk_len = WPA_PSK_LEN;
1450 wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
1451 }
1452 set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
1453out:
1454 spin_unlock_irqrestore(&wl->lock, irqflag);
1455 pr_debug("%s:->\n", __func__);
1456 return ret;
1457}
1458
1459static int gelic_wl_priv_get_psk(struct net_device *net_dev,
1460 struct iw_request_info *info,
1461 union iwreq_data *data, char *extra)
1462{
1463 struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
1464 char *p;
1465 unsigned long irqflag;
1466 unsigned int i;
1467
1468 pr_debug("%s:<-\n", __func__);
1469 if (!capable(CAP_NET_ADMIN))
1470 return -EPERM;
1471
1472 spin_lock_irqsave(&wl->lock, irqflag);
1473 p = extra;
1474 if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) {
1475 if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) {
1476 for (i = 0; i < wl->psk_len; i++) {
1477 sprintf(p, "%02xu", wl->psk[i]);
1478 p += 2;
1479 }
1480 *p = '\0';
1481 data->data.length = wl->psk_len * 2;
1482 } else {
1483 *p++ = '"';
1484 memcpy(p, wl->psk, wl->psk_len);
1485 p += wl->psk_len;
1486 *p++ = '"';
1487 *p = '\0';
1488 data->data.length = wl->psk_len + 2;
1489 }
1490 } else
1491 /* no psk set */
1492 data->data.length = 0;
1493 spin_unlock_irqrestore(&wl->lock, irqflag);
1494 pr_debug("%s:-> %d\n", __func__, data->data.length);
1495 return 0;
1496}
1497#endif
1498
1499/* SIOCGIWNICKN */ 1392/* SIOCGIWNICKN */
1500static int gelic_wl_get_nick(struct net_device *net_dev, 1393static int gelic_wl_get_nick(struct net_device *net_dev,
1501 struct iw_request_info *info, 1394 struct iw_request_info *info,
@@ -1571,8 +1464,10 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
1571 init_completion(&wl->scan_done); 1464 init_completion(&wl->scan_done);
1572 /* 1465 /*
1573 * If we have already a bss list, don't try to get new 1466 * If we have already a bss list, don't try to get new
1467 * unless we are doing an ESSID scan
1574 */ 1468 */
1575 if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) { 1469 if ((!essid_len && !always_scan)
1470 && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
1576 pr_debug("%s: already has the list\n", __func__); 1471 pr_debug("%s: already has the list\n", __func__);
1577 complete(&wl->scan_done); 1472 complete(&wl->scan_done);
1578 goto out; 1473 goto out;
@@ -1673,7 +1568,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
1673 } 1568 }
1674 } 1569 }
1675 1570
1676 /* put them in the newtork_list */ 1571 /* put them in the network_list */
1677 for (i = 0, scan_info_size = 0, scan_info = buf; 1572 for (i = 0, scan_info_size = 0, scan_info = buf;
1678 scan_info_size < data_len; 1573 scan_info_size < data_len;
1679 i++, scan_info_size += be16_to_cpu(scan_info->size), 1574 i++, scan_info_size += be16_to_cpu(scan_info->size),
@@ -2009,7 +1904,7 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
2009 /* PSK type */ 1904 /* PSK type */
2010 wpa->psk_type = cpu_to_be16(wl->psk_type); 1905 wpa->psk_type = cpu_to_be16(wl->psk_type);
2011#ifdef DEBUG 1906#ifdef DEBUG
2012 pr_debug("%s: sec=%s psktype=%s\nn", __func__, 1907 pr_debug("%s: sec=%s psktype=%s\n", __func__,
2013 wpasecstr(wpa->security), 1908 wpasecstr(wpa->security),
2014 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? 1909 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
2015 "BIN" : "passphrase"); 1910 "BIN" : "passphrase");
@@ -2019,9 +1914,9 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
2019 * the debug log because this dumps your precious 1914 * the debug log because this dumps your precious
2020 * passphrase/key. 1915 * passphrase/key.
2021 */ 1916 */
2022 pr_debug("%s: psk=%s\n", 1917 pr_debug("%s: psk=%s\n", __func__,
2023 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? 1918 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
2024 (char *)"N/A" : (char *)wpa->psk); 1919 "N/A" : wpa->psk);
2025#endif 1920#endif
2026#endif 1921#endif
2027 /* issue wpa setup */ 1922 /* issue wpa setup */
@@ -2406,40 +2301,10 @@ static const iw_handler gelic_wl_wext_handler[] =
2406 IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick, 2301 IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick,
2407}; 2302};
2408 2303
2409#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
2410static struct iw_priv_args gelic_wl_private_args[] =
2411{
2412 {
2413 .cmd = GELIC_WL_PRIV_SET_PSK,
2414 .set_args = IW_PRIV_TYPE_CHAR |
2415 (GELIC_WL_EURUS_PSK_MAX_LEN + 2),
2416 .name = "set_psk"
2417 },
2418 {
2419 .cmd = GELIC_WL_PRIV_GET_PSK,
2420 .get_args = IW_PRIV_TYPE_CHAR |
2421 (GELIC_WL_EURUS_PSK_MAX_LEN + 2),
2422 .name = "get_psk"
2423 }
2424};
2425
2426static const iw_handler gelic_wl_private_handler[] =
2427{
2428 gelic_wl_priv_set_psk,
2429 gelic_wl_priv_get_psk,
2430};
2431#endif
2432
2433static const struct iw_handler_def gelic_wl_wext_handler_def = { 2304static const struct iw_handler_def gelic_wl_wext_handler_def = {
2434 .num_standard = ARRAY_SIZE(gelic_wl_wext_handler), 2305 .num_standard = ARRAY_SIZE(gelic_wl_wext_handler),
2435 .standard = gelic_wl_wext_handler, 2306 .standard = gelic_wl_wext_handler,
2436 .get_wireless_stats = gelic_wl_get_wireless_stats, 2307 .get_wireless_stats = gelic_wl_get_wireless_stats,
2437#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
2438 .num_private = ARRAY_SIZE(gelic_wl_private_handler),
2439 .num_private_args = ARRAY_SIZE(gelic_wl_private_args),
2440 .private = gelic_wl_private_handler,
2441 .private_args = gelic_wl_private_args,
2442#endif
2443}; 2308};
2444 2309
2445static struct net_device * __devinit gelic_wl_alloc(struct gelic_card *card) 2310static struct net_device * __devinit gelic_wl_alloc(struct gelic_card *card)
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 56dd6650c97a..588943660755 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -112,6 +112,7 @@ config AIRO_CS
112 depends on PCMCIA && (BROKEN || !M32R) 112 depends on PCMCIA && (BROKEN || !M32R)
113 select WIRELESS_EXT 113 select WIRELESS_EXT
114 select WEXT_SPY 114 select WEXT_SPY
115 select WEXT_PRIV
115 select CRYPTO 116 select CRYPTO
116 select CRYPTO_AES 117 select CRYPTO_AES
117 ---help--- 118 ---help---
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 39410016b4ff..6508515feed3 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -302,18 +302,6 @@ static int adm8211_get_stats(struct ieee80211_hw *dev,
302 return 0; 302 return 0;
303} 303}
304 304
305static int adm8211_get_tx_stats(struct ieee80211_hw *dev,
306 struct ieee80211_tx_queue_stats *stats)
307{
308 struct adm8211_priv *priv = dev->priv;
309
310 stats[0].len = priv->cur_tx - priv->dirty_tx;
311 stats[0].limit = priv->tx_ring_size - 2;
312 stats[0].count = priv->dirty_tx;
313
314 return 0;
315}
316
317static void adm8211_interrupt_tci(struct ieee80211_hw *dev) 305static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
318{ 306{
319 struct adm8211_priv *priv = dev->priv; 307 struct adm8211_priv *priv = dev->priv;
@@ -1400,15 +1388,15 @@ static void adm8211_configure_filter(struct ieee80211_hw *dev,
1400} 1388}
1401 1389
1402static int adm8211_add_interface(struct ieee80211_hw *dev, 1390static int adm8211_add_interface(struct ieee80211_hw *dev,
1403 struct ieee80211_if_init_conf *conf) 1391 struct ieee80211_vif *vif)
1404{ 1392{
1405 struct adm8211_priv *priv = dev->priv; 1393 struct adm8211_priv *priv = dev->priv;
1406 if (priv->mode != NL80211_IFTYPE_MONITOR) 1394 if (priv->mode != NL80211_IFTYPE_MONITOR)
1407 return -EOPNOTSUPP; 1395 return -EOPNOTSUPP;
1408 1396
1409 switch (conf->type) { 1397 switch (vif->type) {
1410 case NL80211_IFTYPE_STATION: 1398 case NL80211_IFTYPE_STATION:
1411 priv->mode = conf->type; 1399 priv->mode = vif->type;
1412 break; 1400 break;
1413 default: 1401 default:
1414 return -EOPNOTSUPP; 1402 return -EOPNOTSUPP;
@@ -1416,8 +1404,8 @@ static int adm8211_add_interface(struct ieee80211_hw *dev,
1416 1404
1417 ADM8211_IDLE(); 1405 ADM8211_IDLE();
1418 1406
1419 ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)conf->mac_addr)); 1407 ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)vif->addr));
1420 ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(conf->mac_addr + 4))); 1408 ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(vif->addr + 4)));
1421 1409
1422 adm8211_update_mode(dev); 1410 adm8211_update_mode(dev);
1423 1411
@@ -1427,7 +1415,7 @@ static int adm8211_add_interface(struct ieee80211_hw *dev,
1427} 1415}
1428 1416
1429static void adm8211_remove_interface(struct ieee80211_hw *dev, 1417static void adm8211_remove_interface(struct ieee80211_hw *dev,
1430 struct ieee80211_if_init_conf *conf) 1418 struct ieee80211_vif *vif)
1431{ 1419{
1432 struct adm8211_priv *priv = dev->priv; 1420 struct adm8211_priv *priv = dev->priv;
1433 priv->mode = NL80211_IFTYPE_MONITOR; 1421 priv->mode = NL80211_IFTYPE_MONITOR;
@@ -1773,7 +1761,6 @@ static const struct ieee80211_ops adm8211_ops = {
1773 .prepare_multicast = adm8211_prepare_multicast, 1761 .prepare_multicast = adm8211_prepare_multicast,
1774 .configure_filter = adm8211_configure_filter, 1762 .configure_filter = adm8211_configure_filter,
1775 .get_stats = adm8211_get_stats, 1763 .get_stats = adm8211_get_stats,
1776 .get_tx_stats = adm8211_get_tx_stats,
1777 .get_tsf = adm8211_get_tsft 1764 .get_tsf = adm8211_get_tsft
1778}; 1765};
1779 1766
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 4331d675fcc6..260fb9905e97 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -51,6 +51,7 @@
51#include <linux/freezer.h> 51#include <linux/freezer.h>
52 52
53#include <linux/ieee80211.h> 53#include <linux/ieee80211.h>
54#include <net/iw_handler.h>
54 55
55#include "airo.h" 56#include "airo.h"
56 57
@@ -5254,11 +5255,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5254 WepKeyRid wkr; 5255 WepKeyRid wkr;
5255 int rc; 5256 int rc;
5256 5257
5257 if (keylen == 0) { 5258 WARN_ON(keylen == 0);
5258 airo_print_err(ai->dev->name, "%s: key length to set was zero",
5259 __func__);
5260 return -1;
5261 }
5262 5259
5263 memset(&wkr, 0, sizeof(wkr)); 5260 memset(&wkr, 0, sizeof(wkr));
5264 wkr.len = cpu_to_le16(sizeof(wkr)); 5261 wkr.len = cpu_to_le16(sizeof(wkr));
@@ -6405,11 +6402,7 @@ static int airo_set_encode(struct net_device *dev,
6405 if (dwrq->length > MIN_KEY_SIZE) 6402 if (dwrq->length > MIN_KEY_SIZE)
6406 key.len = MAX_KEY_SIZE; 6403 key.len = MAX_KEY_SIZE;
6407 else 6404 else
6408 if (dwrq->length > 0) 6405 key.len = MIN_KEY_SIZE;
6409 key.len = MIN_KEY_SIZE;
6410 else
6411 /* Disable the key */
6412 key.len = 0;
6413 /* Check if the key is not marked as invalid */ 6406 /* Check if the key is not marked as invalid */
6414 if(!(dwrq->flags & IW_ENCODE_NOKEY)) { 6407 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6415 /* Cleanup */ 6408 /* Cleanup */
@@ -6590,12 +6583,22 @@ static int airo_set_encodeext(struct net_device *dev,
6590 default: 6583 default:
6591 return -EINVAL; 6584 return -EINVAL;
6592 } 6585 }
6593 /* Send the key to the card */ 6586 if (key.len == 0) {
6594 rc = set_wep_key(local, idx, key.key, key.len, perm, 1); 6587 rc = set_wep_tx_idx(local, idx, perm, 1);
6595 if (rc < 0) { 6588 if (rc < 0) {
6596 airo_print_err(local->dev->name, "failed to set WEP key" 6589 airo_print_err(local->dev->name,
6597 " at index %d: %d.", idx, rc); 6590 "failed to set WEP transmit index to %d: %d.",
6598 return rc; 6591 idx, rc);
6592 return rc;
6593 }
6594 } else {
6595 rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6596 if (rc < 0) {
6597 airo_print_err(local->dev->name,
6598 "failed to set WEP key at index %d: %d.",
6599 idx, rc);
6600 return rc;
6601 }
6599 } 6602 }
6600 } 6603 }
6601 6604
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 2517364d3ebe..0fb419936dff 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1789,7 +1789,7 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw)
1789} 1789}
1790 1790
1791static int at76_add_interface(struct ieee80211_hw *hw, 1791static int at76_add_interface(struct ieee80211_hw *hw,
1792 struct ieee80211_if_init_conf *conf) 1792 struct ieee80211_vif *vif)
1793{ 1793{
1794 struct at76_priv *priv = hw->priv; 1794 struct at76_priv *priv = hw->priv;
1795 int ret = 0; 1795 int ret = 0;
@@ -1798,7 +1798,7 @@ static int at76_add_interface(struct ieee80211_hw *hw,
1798 1798
1799 mutex_lock(&priv->mtx); 1799 mutex_lock(&priv->mtx);
1800 1800
1801 switch (conf->type) { 1801 switch (vif->type) {
1802 case NL80211_IFTYPE_STATION: 1802 case NL80211_IFTYPE_STATION:
1803 priv->iw_mode = IW_MODE_INFRA; 1803 priv->iw_mode = IW_MODE_INFRA;
1804 break; 1804 break;
@@ -1814,7 +1814,7 @@ exit:
1814} 1814}
1815 1815
1816static void at76_remove_interface(struct ieee80211_hw *hw, 1816static void at76_remove_interface(struct ieee80211_hw *hw,
1817 struct ieee80211_if_init_conf *conf) 1817 struct ieee80211_vif *vif)
1818{ 1818{
1819 at76_dbg(DBG_MAC80211, "%s()", __func__); 1819 at76_dbg(DBG_MAC80211, "%s()", __func__);
1820} 1820}
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 9f9459860d82..8c8ce67971e9 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -109,7 +109,6 @@ struct ar9170_rxstream_mpdu_merge {
109 bool has_plcp; 109 bool has_plcp;
110}; 110};
111 111
112#define AR9170_NUM_MAX_BA_RETRY 5
113#define AR9170_NUM_TID 16 112#define AR9170_NUM_TID 16
114#define WME_BA_BMP_SIZE 64 113#define WME_BA_BMP_SIZE 64
115#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) 114#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE)
@@ -143,7 +142,12 @@ struct ar9170_sta_tid {
143 u16 tid; 142 u16 tid;
144 enum ar9170_tid_state state; 143 enum ar9170_tid_state state;
145 bool active; 144 bool active;
146 u8 retry; 145};
146
147struct ar9170_tx_queue_stats {
148 unsigned int len;
149 unsigned int limit;
150 unsigned int count;
147}; 151};
148 152
149#define AR9170_QUEUE_TIMEOUT 64 153#define AR9170_QUEUE_TIMEOUT 64
@@ -154,6 +158,8 @@ struct ar9170_sta_tid {
154 158
155#define AR9170_NUM_TX_STATUS 128 159#define AR9170_NUM_TX_STATUS 128
156#define AR9170_NUM_TX_AGG_MAX 30 160#define AR9170_NUM_TX_AGG_MAX 30
161#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
162#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
157 163
158struct ar9170 { 164struct ar9170 {
159 struct ieee80211_hw *hw; 165 struct ieee80211_hw *hw;
@@ -211,7 +217,7 @@ struct ar9170 {
211 217
212 /* qos queue settings */ 218 /* qos queue settings */
213 spinlock_t tx_stats_lock; 219 spinlock_t tx_stats_lock;
214 struct ieee80211_tx_queue_stats tx_stats[5]; 220 struct ar9170_tx_queue_stats tx_stats[5];
215 struct ieee80211_tx_queue_params edcf[5]; 221 struct ieee80211_tx_queue_params edcf[5];
216 222
217 spinlock_t cmdlock; 223 spinlock_t cmdlock;
@@ -248,13 +254,8 @@ struct ar9170_sta_info {
248 unsigned int ampdu_max_len; 254 unsigned int ampdu_max_len;
249}; 255};
250 256
251#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0)
252#define AR9170_TX_FLAG_NO_ACK BIT(1)
253#define AR9170_TX_FLAG_BLOCK_ACK BIT(2)
254
255struct ar9170_tx_info { 257struct ar9170_tx_info {
256 unsigned long timeout; 258 unsigned long timeout;
257 unsigned int flags;
258}; 259};
259 260
260#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) 261#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 701ddb7d8400..0a1d4c28e68a 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -276,6 +276,7 @@ struct ar9170_tx_control {
276#define AR9170_TX_MAC_RATE_PROBE 0x8000 276#define AR9170_TX_MAC_RATE_PROBE 0x8000
277 277
278/* either-or */ 278/* either-or */
279#define AR9170_TX_PHY_MOD_MASK 0x00000003
279#define AR9170_TX_PHY_MOD_CCK 0x00000000 280#define AR9170_TX_PHY_MOD_CCK 0x00000000
280#define AR9170_TX_PHY_MOD_OFDM 0x00000001 281#define AR9170_TX_PHY_MOD_OFDM 0x00000001
281#define AR9170_TX_PHY_MOD_HT 0x00000002 282#define AR9170_TX_PHY_MOD_HT 0x00000002
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index ddc8c09dc79e..857e86104295 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -117,7 +117,7 @@ int ar9170_set_qos(struct ar9170 *ar)
117 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, 117 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
118 ar->edcf[0].txop | ar->edcf[1].txop << 16); 118 ar->edcf[0].txop | ar->edcf[1].txop << 16);
119 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, 119 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
120 ar->edcf[1].txop | ar->edcf[3].txop << 16); 120 ar->edcf[2].txop | ar->edcf[3].txop << 16);
121 121
122 ar9170_regwrite_finish(); 122 ar9170_regwrite_finish();
123 123
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index f9d6db8d013e..8a964f130367 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -194,12 +194,15 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb)
194 return ar9170_get_seq_h((void *) txc->frame_data); 194 return ar9170_get_seq_h((void *) txc->frame_data);
195} 195}
196 196
197static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr)
198{
199 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
200}
201
197static inline u16 ar9170_get_tid(struct sk_buff *skb) 202static inline u16 ar9170_get_tid(struct sk_buff *skb)
198{ 203{
199 struct ar9170_tx_control *txc = (void *) skb->data; 204 struct ar9170_tx_control *txc = (void *) skb->data;
200 struct ieee80211_hdr *hdr = (void *) txc->frame_data; 205 return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data);
201
202 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
203} 206}
204 207
205#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) 208#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
@@ -213,10 +216,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
213 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; 216 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
214 struct ieee80211_hdr *hdr = (void *) txc->frame_data; 217 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
215 218
216 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d " 219 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
217 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", 220 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
218 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), 221 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
219 ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr), 222 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
220 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), 223 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
221 jiffies_to_msecs(arinfo->timeout - jiffies)); 224 jiffies_to_msecs(arinfo->timeout - jiffies));
222} 225}
@@ -430,7 +433,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
430 spin_lock_irqsave(&ar->tx_stats_lock, flags); 433 spin_lock_irqsave(&ar->tx_stats_lock, flags);
431 ar->tx_stats[queue].len--; 434 ar->tx_stats[queue].len--;
432 435
433 if (skb_queue_empty(&ar->tx_pending[queue])) { 436 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
434#ifdef AR9170_QUEUE_STOP_DEBUG 437#ifdef AR9170_QUEUE_STOP_DEBUG
435 printk(KERN_DEBUG "%s: wake queue %d\n", 438 printk(KERN_DEBUG "%s: wake queue %d\n",
436 wiphy_name(ar->hw->wiphy), queue); 439 wiphy_name(ar->hw->wiphy), queue);
@@ -440,22 +443,17 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
440 } 443 }
441 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 444 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
442 445
443 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { 446 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
444 ar9170_tx_ampdu_callback(ar, skb);
445 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
446 arinfo->timeout = jiffies +
447 msecs_to_jiffies(AR9170_TX_TIMEOUT);
448
449 skb_queue_tail(&ar->tx_status[queue], skb);
450 } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
451 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); 447 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
452 } else { 448 } else {
453#ifdef AR9170_QUEUE_DEBUG 449 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
454 printk(KERN_DEBUG "%s: unsupported frame flags!\n", 450 ar9170_tx_ampdu_callback(ar, skb);
455 wiphy_name(ar->hw->wiphy)); 451 } else {
456 ar9170_print_txheader(ar, skb); 452 arinfo->timeout = jiffies +
457#endif /* AR9170_QUEUE_DEBUG */ 453 msecs_to_jiffies(AR9170_TX_TIMEOUT);
458 dev_kfree_skb_any(skb); 454
455 skb_queue_tail(&ar->tx_status[queue], skb);
456 }
459 } 457 }
460 458
461 if (!ar->tx_stats[queue].len && 459 if (!ar->tx_stats[queue].len &&
@@ -1407,17 +1405,6 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1407 1405
1408 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && 1406 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1409 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { 1407 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1410 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1411 if (unlikely(!info->control.sta))
1412 goto err_out;
1413
1414 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1415 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
1416
1417 goto out;
1418 }
1419
1420 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1421 /* 1408 /*
1422 * WARNING: 1409 * WARNING:
1423 * Putting the QoS queue bits into an unexplored territory is 1410 * Putting the QoS queue bits into an unexplored territory is
@@ -1431,12 +1418,17 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1431 1418
1432 txc->phy_control |= 1419 txc->phy_control |=
1433 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); 1420 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1434 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; 1421
1435 } else { 1422 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1436 arinfo->flags = AR9170_TX_FLAG_NO_ACK; 1423 if (unlikely(!info->control.sta))
1424 goto err_out;
1425
1426 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1427 } else {
1428 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1429 }
1437 } 1430 }
1438 1431
1439out:
1440 return 0; 1432 return 0;
1441 1433
1442err_out: 1434err_out:
@@ -1671,8 +1663,7 @@ static bool ar9170_tx_ampdu(struct ar9170 *ar)
1671 * tell the FW/HW that this is the last frame, 1663 * tell the FW/HW that this is the last frame,
1672 * that way it will wait for the immediate block ack. 1664 * that way it will wait for the immediate block ack.
1673 */ 1665 */
1674 if (likely(skb_peek_tail(&agg))) 1666 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1675 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1676 1667
1677#ifdef AR9170_TXAGG_DEBUG 1668#ifdef AR9170_TXAGG_DEBUG
1678 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", 1669 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
@@ -1716,6 +1707,21 @@ static void ar9170_tx(struct ar9170 *ar)
1716 1707
1717 for (i = 0; i < __AR9170_NUM_TXQ; i++) { 1708 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1718 spin_lock_irqsave(&ar->tx_stats_lock, flags); 1709 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1710 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1711 skb_queue_len(&ar->tx_pending[i]));
1712
1713 if (remaining_space < frames) {
1714#ifdef AR9170_QUEUE_DEBUG
1715 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1716 "remaining slots:%d, needed:%d\n",
1717 wiphy_name(ar->hw->wiphy), i, remaining_space,
1718 frames);
1719#endif /* AR9170_QUEUE_DEBUG */
1720 frames = remaining_space;
1721 }
1722
1723 ar->tx_stats[i].len += frames;
1724 ar->tx_stats[i].count += frames;
1719 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { 1725 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1720#ifdef AR9170_QUEUE_DEBUG 1726#ifdef AR9170_QUEUE_DEBUG
1721 printk(KERN_DEBUG "%s: queue %d full\n", 1727 printk(KERN_DEBUG "%s: queue %d full\n",
@@ -1733,25 +1739,8 @@ static void ar9170_tx(struct ar9170 *ar)
1733 __ar9170_dump_txstats(ar); 1739 __ar9170_dump_txstats(ar);
1734#endif /* AR9170_QUEUE_STOP_DEBUG */ 1740#endif /* AR9170_QUEUE_STOP_DEBUG */
1735 ieee80211_stop_queue(ar->hw, i); 1741 ieee80211_stop_queue(ar->hw, i);
1736 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1737 continue;
1738 }
1739
1740 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1741 skb_queue_len(&ar->tx_pending[i]));
1742
1743 if (remaining_space < frames) {
1744#ifdef AR9170_QUEUE_DEBUG
1745 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1746 "remaining slots:%d, needed:%d\n",
1747 wiphy_name(ar->hw->wiphy), i, remaining_space,
1748 frames);
1749#endif /* AR9170_QUEUE_DEBUG */
1750 frames = remaining_space;
1751 } 1742 }
1752 1743
1753 ar->tx_stats[i].len += frames;
1754 ar->tx_stats[i].count += frames;
1755 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 1744 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1756 1745
1757 if (!frames) 1746 if (!frames)
@@ -1773,7 +1762,7 @@ static void ar9170_tx(struct ar9170 *ar)
1773 arinfo->timeout = jiffies + 1762 arinfo->timeout = jiffies +
1774 msecs_to_jiffies(AR9170_TX_TIMEOUT); 1763 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1775 1764
1776 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) 1765 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1777 atomic_inc(&ar->tx_ampdu_pending); 1766 atomic_inc(&ar->tx_ampdu_pending);
1778 1767
1779#ifdef AR9170_QUEUE_DEBUG 1768#ifdef AR9170_QUEUE_DEBUG
@@ -1784,7 +1773,7 @@ static void ar9170_tx(struct ar9170 *ar)
1784 1773
1785 err = ar->tx(ar, skb); 1774 err = ar->tx(ar, skb);
1786 if (unlikely(err)) { 1775 if (unlikely(err)) {
1787 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) 1776 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1788 atomic_dec(&ar->tx_ampdu_pending); 1777 atomic_dec(&ar->tx_ampdu_pending);
1789 1778
1790 frames_failed++; 1779 frames_failed++;
@@ -1950,7 +1939,7 @@ err_free:
1950} 1939}
1951 1940
1952static int ar9170_op_add_interface(struct ieee80211_hw *hw, 1941static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1953 struct ieee80211_if_init_conf *conf) 1942 struct ieee80211_vif *vif)
1954{ 1943{
1955 struct ar9170 *ar = hw->priv; 1944 struct ar9170 *ar = hw->priv;
1956 struct ath_common *common = &ar->common; 1945 struct ath_common *common = &ar->common;
@@ -1963,8 +1952,8 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1963 goto unlock; 1952 goto unlock;
1964 } 1953 }
1965 1954
1966 ar->vif = conf->vif; 1955 ar->vif = vif;
1967 memcpy(common->macaddr, conf->mac_addr, ETH_ALEN); 1956 memcpy(common->macaddr, vif->addr, ETH_ALEN);
1968 1957
1969 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { 1958 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1970 ar->rx_software_decryption = true; 1959 ar->rx_software_decryption = true;
@@ -1984,7 +1973,7 @@ unlock:
1984} 1973}
1985 1974
1986static void ar9170_op_remove_interface(struct ieee80211_hw *hw, 1975static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1987 struct ieee80211_if_init_conf *conf) 1976 struct ieee80211_vif *vif)
1988{ 1977{
1989 struct ar9170 *ar = hw->priv; 1978 struct ar9170 *ar = hw->priv;
1990 1979
@@ -2340,55 +2329,55 @@ out:
2340 return err; 2329 return err;
2341} 2330}
2342 2331
2343static void ar9170_sta_notify(struct ieee80211_hw *hw, 2332static int ar9170_sta_add(struct ieee80211_hw *hw,
2344 struct ieee80211_vif *vif, 2333 struct ieee80211_vif *vif,
2345 enum sta_notify_cmd cmd, 2334 struct ieee80211_sta *sta)
2346 struct ieee80211_sta *sta)
2347{ 2335{
2348 struct ar9170 *ar = hw->priv; 2336 struct ar9170 *ar = hw->priv;
2349 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; 2337 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2350 unsigned int i; 2338 unsigned int i;
2351 2339
2352 switch (cmd) { 2340 memset(sta_info, 0, sizeof(*sta_info));
2353 case STA_NOTIFY_ADD:
2354 memset(sta_info, 0, sizeof(*sta_info));
2355 2341
2356 if (!sta->ht_cap.ht_supported) 2342 if (!sta->ht_cap.ht_supported)
2357 break; 2343 return 0;
2358 2344
2359 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) 2345 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2360 ar->global_ampdu_density = sta->ht_cap.ampdu_density; 2346 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2361 2347
2362 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) 2348 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2363 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; 2349 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2364 2350
2365 for (i = 0; i < AR9170_NUM_TID; i++) { 2351 for (i = 0; i < AR9170_NUM_TID; i++) {
2366 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; 2352 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2367 sta_info->agg[i].active = false; 2353 sta_info->agg[i].active = false;
2368 sta_info->agg[i].ssn = 0; 2354 sta_info->agg[i].ssn = 0;
2369 sta_info->agg[i].retry = 0; 2355 sta_info->agg[i].tid = i;
2370 sta_info->agg[i].tid = i; 2356 INIT_LIST_HEAD(&sta_info->agg[i].list);
2371 INIT_LIST_HEAD(&sta_info->agg[i].list); 2357 skb_queue_head_init(&sta_info->agg[i].queue);
2372 skb_queue_head_init(&sta_info->agg[i].queue); 2358 }
2373 }
2374 2359
2375 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); 2360 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2376 break;
2377 2361
2378 case STA_NOTIFY_REMOVE: 2362 return 0;
2379 if (!sta->ht_cap.ht_supported) 2363}
2380 break;
2381 2364
2382 for (i = 0; i < AR9170_NUM_TID; i++) { 2365static int ar9170_sta_remove(struct ieee80211_hw *hw,
2383 sta_info->agg[i].state = AR9170_TID_STATE_INVALID; 2366 struct ieee80211_vif *vif,
2384 skb_queue_purge(&sta_info->agg[i].queue); 2367 struct ieee80211_sta *sta)
2385 } 2368{
2369 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2370 unsigned int i;
2386 2371
2387 break; 2372 if (!sta->ht_cap.ht_supported)
2373 return 0;
2388 2374
2389 default: 2375 for (i = 0; i < AR9170_NUM_TID; i++) {
2390 break; 2376 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2377 skb_queue_purge(&sta_info->agg[i].queue);
2391 } 2378 }
2379
2380 return 0;
2392} 2381}
2393 2382
2394static int ar9170_get_stats(struct ieee80211_hw *hw, 2383static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -2408,18 +2397,6 @@ static int ar9170_get_stats(struct ieee80211_hw *hw,
2408 return 0; 2397 return 0;
2409} 2398}
2410 2399
2411static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2412 struct ieee80211_tx_queue_stats *tx_stats)
2413{
2414 struct ar9170 *ar = hw->priv;
2415
2416 spin_lock_bh(&ar->tx_stats_lock);
2417 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2418 spin_unlock_bh(&ar->tx_stats_lock);
2419
2420 return 0;
2421}
2422
2423static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, 2400static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2424 const struct ieee80211_tx_queue_params *param) 2401 const struct ieee80211_tx_queue_params *param)
2425{ 2402{
@@ -2519,9 +2496,9 @@ static const struct ieee80211_ops ar9170_ops = {
2519 .bss_info_changed = ar9170_op_bss_info_changed, 2496 .bss_info_changed = ar9170_op_bss_info_changed,
2520 .get_tsf = ar9170_op_get_tsf, 2497 .get_tsf = ar9170_op_get_tsf,
2521 .set_key = ar9170_set_key, 2498 .set_key = ar9170_set_key,
2522 .sta_notify = ar9170_sta_notify, 2499 .sta_add = ar9170_sta_add,
2500 .sta_remove = ar9170_sta_remove,
2523 .get_stats = ar9170_get_stats, 2501 .get_stats = ar9170_get_stats,
2524 .get_tx_stats = ar9170_get_tx_stats,
2525 .ampdu_action = ar9170_ampdu_action, 2502 .ampdu_action = ar9170_ampdu_action,
2526}; 2503};
2527 2504
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index e0799d924057..0f361186b78f 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -84,6 +84,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
84 { USB_DEVICE(0x0cde, 0x0023) }, 84 { USB_DEVICE(0x0cde, 0x0023) },
85 /* Z-Com UB82 ABG */ 85 /* Z-Com UB82 ABG */
86 { USB_DEVICE(0x0cde, 0x0026) }, 86 { USB_DEVICE(0x0cde, 0x0026) },
87 /* Sphairon Homelink 1202 */
88 { USB_DEVICE(0x0cde, 0x0027) },
87 /* Arcadyan WN7512 */ 89 /* Arcadyan WN7512 */
88 { USB_DEVICE(0x083a, 0xf522) }, 90 { USB_DEVICE(0x083a, 0xf522) },
89 /* Planex GWUS300 */ 91 /* Planex GWUS300 */
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 9e05648356fe..71fc960814f0 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -74,7 +74,6 @@ struct ath_common;
74 74
75struct ath_bus_ops { 75struct ath_bus_ops {
76 void (*read_cachesize)(struct ath_common *common, int *csz); 76 void (*read_cachesize)(struct ath_common *common, int *csz);
77 void (*cleanup)(struct ath_common *common);
78 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 77 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
79 void (*bt_coex_prep)(struct ath_common *common); 78 void (*bt_coex_prep)(struct ath_common *common);
80}; 79};
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6a2a96761111..ac67f02e26d8 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -535,13 +535,12 @@ struct ath5k_txq_info {
535 u32 tqi_cbr_period; /* Constant bit rate period */ 535 u32 tqi_cbr_period; /* Constant bit rate period */
536 u32 tqi_cbr_overflow_limit; 536 u32 tqi_cbr_overflow_limit;
537 u32 tqi_burst_time; 537 u32 tqi_burst_time;
538 u32 tqi_ready_time; /* Not used */ 538 u32 tqi_ready_time; /* Time queue waits after an event */
539}; 539};
540 540
541/* 541/*
542 * Transmit packet types. 542 * Transmit packet types.
543 * used on tx control descriptor 543 * used on tx control descriptor
544 * TODO: Use them inside base.c corectly
545 */ 544 */
546enum ath5k_pkt_type { 545enum ath5k_pkt_type {
547 AR5K_PKT_TYPE_NORMAL = 0, 546 AR5K_PKT_TYPE_NORMAL = 0,
@@ -1063,6 +1062,7 @@ struct ath5k_hw {
1063 u32 ah_cw_min; 1062 u32 ah_cw_min;
1064 u32 ah_cw_max; 1063 u32 ah_cw_max;
1065 u32 ah_limit_tx_retries; 1064 u32 ah_limit_tx_retries;
1065 u8 ah_coverage_class;
1066 1066
1067 /* Antenna Control */ 1067 /* Antenna Control */
1068 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1068 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1200,6 +1200,7 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1200
1201/* Protocol Control Unit Functions */ 1201/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1203/* BSSID Functions */ 1204/* BSSID Functions */
1204extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1205extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
@@ -1231,6 +1232,10 @@ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1231extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); 1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1232extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); 1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1233extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); 1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1234/* Key table (WEP) functions */ 1239/* Key table (WEP) functions */
1235extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1236extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
@@ -1310,24 +1315,6 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1310 * Functions used internaly 1315 * Functions used internaly
1311 */ 1316 */
1312 1317
1313/*
1314 * Translate usec to hw clock units
1315 * TODO: Half/quarter rate
1316 */
1317static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1318{
1319 return turbo ? (usec * 80) : (usec * 40);
1320}
1321
1322/*
1323 * Translate hw clock units to usec
1324 * TODO: Half/quarter rate
1325 */
1326static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1327{
1328 return turbo ? (clock / 80) : (clock / 40);
1329}
1330
1331static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) 1318static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
1332{ 1319{
1333 return &ah->common; 1320 return &ah->common;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index e63b7c40d0ee..2468c64d6c12 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -225,9 +225,9 @@ static int ath5k_reset_wake(struct ath5k_softc *sc);
225static int ath5k_start(struct ieee80211_hw *hw); 225static int ath5k_start(struct ieee80211_hw *hw);
226static void ath5k_stop(struct ieee80211_hw *hw); 226static void ath5k_stop(struct ieee80211_hw *hw);
227static int ath5k_add_interface(struct ieee80211_hw *hw, 227static int ath5k_add_interface(struct ieee80211_hw *hw,
228 struct ieee80211_if_init_conf *conf); 228 struct ieee80211_vif *vif);
229static void ath5k_remove_interface(struct ieee80211_hw *hw, 229static void ath5k_remove_interface(struct ieee80211_hw *hw,
230 struct ieee80211_if_init_conf *conf); 230 struct ieee80211_vif *vif);
231static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 231static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
233 int mc_count, struct dev_addr_list *mc_list); 233 int mc_count, struct dev_addr_list *mc_list);
@@ -241,8 +241,6 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
241 struct ieee80211_key_conf *key); 241 struct ieee80211_key_conf *key);
242static int ath5k_get_stats(struct ieee80211_hw *hw, 242static int ath5k_get_stats(struct ieee80211_hw *hw,
243 struct ieee80211_low_level_stats *stats); 243 struct ieee80211_low_level_stats *stats);
244static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
245 struct ieee80211_tx_queue_stats *stats);
246static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 244static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
247static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); 245static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
248static void ath5k_reset_tsf(struct ieee80211_hw *hw); 246static void ath5k_reset_tsf(struct ieee80211_hw *hw);
@@ -254,6 +252,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
254 u32 changes); 252 u32 changes);
255static void ath5k_sw_scan_start(struct ieee80211_hw *hw); 253static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
256static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); 254static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
255static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
256 u8 coverage_class);
257 257
258static const struct ieee80211_ops ath5k_hw_ops = { 258static const struct ieee80211_ops ath5k_hw_ops = {
259 .tx = ath5k_tx, 259 .tx = ath5k_tx,
@@ -267,13 +267,13 @@ static const struct ieee80211_ops ath5k_hw_ops = {
267 .set_key = ath5k_set_key, 267 .set_key = ath5k_set_key,
268 .get_stats = ath5k_get_stats, 268 .get_stats = ath5k_get_stats,
269 .conf_tx = NULL, 269 .conf_tx = NULL,
270 .get_tx_stats = ath5k_get_tx_stats,
271 .get_tsf = ath5k_get_tsf, 270 .get_tsf = ath5k_get_tsf,
272 .set_tsf = ath5k_set_tsf, 271 .set_tsf = ath5k_set_tsf,
273 .reset_tsf = ath5k_reset_tsf, 272 .reset_tsf = ath5k_reset_tsf,
274 .bss_info_changed = ath5k_bss_info_changed, 273 .bss_info_changed = ath5k_bss_info_changed,
275 .sw_scan_start = ath5k_sw_scan_start, 274 .sw_scan_start = ath5k_sw_scan_start,
276 .sw_scan_complete = ath5k_sw_scan_complete, 275 .sw_scan_complete = ath5k_sw_scan_complete,
276 .set_coverage_class = ath5k_set_coverage_class,
277}; 277};
278 278
279/* 279/*
@@ -1246,6 +1246,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1246 return 0; 1246 return 0;
1247} 1247}
1248 1248
1249static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1250{
1251 struct ieee80211_hdr *hdr;
1252 enum ath5k_pkt_type htype;
1253 __le16 fc;
1254
1255 hdr = (struct ieee80211_hdr *)skb->data;
1256 fc = hdr->frame_control;
1257
1258 if (ieee80211_is_beacon(fc))
1259 htype = AR5K_PKT_TYPE_BEACON;
1260 else if (ieee80211_is_probe_resp(fc))
1261 htype = AR5K_PKT_TYPE_PROBE_RESP;
1262 else if (ieee80211_is_atim(fc))
1263 htype = AR5K_PKT_TYPE_ATIM;
1264 else if (ieee80211_is_pspoll(fc))
1265 htype = AR5K_PKT_TYPE_PSPOLL;
1266 else
1267 htype = AR5K_PKT_TYPE_NORMAL;
1268
1269 return htype;
1270}
1271
1249static int 1272static int
1250ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1251 struct ath5k_txq *txq) 1274 struct ath5k_txq *txq)
@@ -1300,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1300 sc->vif, pktlen, info)); 1323 sc->vif, pktlen, info));
1301 } 1324 }
1302 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1303 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1326 ieee80211_get_hdrlen_from_skb(skb),
1327 get_hw_packet_type(skb),
1304 (sc->power_level * 2), 1328 (sc->power_level * 2),
1305 hw_rate, 1329 hw_rate,
1306 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, 1330 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
@@ -1329,7 +1353,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1329 1353
1330 spin_lock_bh(&txq->lock); 1354 spin_lock_bh(&txq->lock);
1331 list_add_tail(&bf->list, &txq->q); 1355 list_add_tail(&bf->list, &txq->q);
1332 sc->tx_stats[txq->qnum].len++;
1333 if (txq->link == NULL) /* is this first packet? */ 1356 if (txq->link == NULL) /* is this first packet? */
1334 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); 1357 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
1335 else /* no, so only link it */ 1358 else /* no, so only link it */
@@ -1513,7 +1536,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1513 1536
1514 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); 1537 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
1515 if (ret) 1538 if (ret)
1516 return ret; 1539 goto err;
1540
1517 if (sc->opmode == NL80211_IFTYPE_AP || 1541 if (sc->opmode == NL80211_IFTYPE_AP ||
1518 sc->opmode == NL80211_IFTYPE_MESH_POINT) { 1542 sc->opmode == NL80211_IFTYPE_MESH_POINT) {
1519 /* 1543 /*
@@ -1540,10 +1564,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1540 if (ret) { 1564 if (ret) {
1541 ATH5K_ERR(sc, "%s: unable to update parameters for beacon " 1565 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1542 "hardware queue!\n", __func__); 1566 "hardware queue!\n", __func__);
1543 return ret; 1567 goto err;
1544 } 1568 }
1569 ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
1570 if (ret)
1571 goto err;
1572
1573 /* reconfigure cabq with ready time to 80% of beacon_interval */
1574 ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1575 if (ret)
1576 goto err;
1577
1578 qi.tqi_ready_time = (sc->bintval * 80) / 100;
1579 ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1580 if (ret)
1581 goto err;
1545 1582
1546 return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; 1583 ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
1584err:
1585 return ret;
1547} 1586}
1548 1587
1549static void 1588static void
@@ -1562,7 +1601,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1562 ath5k_txbuf_free(sc, bf); 1601 ath5k_txbuf_free(sc, bf);
1563 1602
1564 spin_lock_bh(&sc->txbuflock); 1603 spin_lock_bh(&sc->txbuflock);
1565 sc->tx_stats[txq->qnum].len--;
1566 list_move_tail(&bf->list, &sc->txbuf); 1604 list_move_tail(&bf->list, &sc->txbuf);
1567 sc->txbuf_len++; 1605 sc->txbuf_len++;
1568 spin_unlock_bh(&sc->txbuflock); 1606 spin_unlock_bh(&sc->txbuflock);
@@ -1992,10 +2030,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1992 } 2030 }
1993 2031
1994 ieee80211_tx_status(sc->hw, skb); 2032 ieee80211_tx_status(sc->hw, skb);
1995 sc->tx_stats[txq->qnum].count++;
1996 2033
1997 spin_lock(&sc->txbuflock); 2034 spin_lock(&sc->txbuflock);
1998 sc->tx_stats[txq->qnum].len--;
1999 list_move_tail(&bf->list, &sc->txbuf); 2035 list_move_tail(&bf->list, &sc->txbuf);
2000 sc->txbuf_len++; 2036 sc->txbuf_len++;
2001 spin_unlock(&sc->txbuflock); 2037 spin_unlock(&sc->txbuflock);
@@ -2773,7 +2809,7 @@ static void ath5k_stop(struct ieee80211_hw *hw)
2773} 2809}
2774 2810
2775static int ath5k_add_interface(struct ieee80211_hw *hw, 2811static int ath5k_add_interface(struct ieee80211_hw *hw,
2776 struct ieee80211_if_init_conf *conf) 2812 struct ieee80211_vif *vif)
2777{ 2813{
2778 struct ath5k_softc *sc = hw->priv; 2814 struct ath5k_softc *sc = hw->priv;
2779 int ret; 2815 int ret;
@@ -2784,22 +2820,22 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2784 goto end; 2820 goto end;
2785 } 2821 }
2786 2822
2787 sc->vif = conf->vif; 2823 sc->vif = vif;
2788 2824
2789 switch (conf->type) { 2825 switch (vif->type) {
2790 case NL80211_IFTYPE_AP: 2826 case NL80211_IFTYPE_AP:
2791 case NL80211_IFTYPE_STATION: 2827 case NL80211_IFTYPE_STATION:
2792 case NL80211_IFTYPE_ADHOC: 2828 case NL80211_IFTYPE_ADHOC:
2793 case NL80211_IFTYPE_MESH_POINT: 2829 case NL80211_IFTYPE_MESH_POINT:
2794 case NL80211_IFTYPE_MONITOR: 2830 case NL80211_IFTYPE_MONITOR:
2795 sc->opmode = conf->type; 2831 sc->opmode = vif->type;
2796 break; 2832 break;
2797 default: 2833 default:
2798 ret = -EOPNOTSUPP; 2834 ret = -EOPNOTSUPP;
2799 goto end; 2835 goto end;
2800 } 2836 }
2801 2837
2802 ath5k_hw_set_lladdr(sc->ah, conf->mac_addr); 2838 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2803 ath5k_mode_setup(sc); 2839 ath5k_mode_setup(sc);
2804 2840
2805 ret = 0; 2841 ret = 0;
@@ -2810,13 +2846,13 @@ end:
2810 2846
2811static void 2847static void
2812ath5k_remove_interface(struct ieee80211_hw *hw, 2848ath5k_remove_interface(struct ieee80211_hw *hw,
2813 struct ieee80211_if_init_conf *conf) 2849 struct ieee80211_vif *vif)
2814{ 2850{
2815 struct ath5k_softc *sc = hw->priv; 2851 struct ath5k_softc *sc = hw->priv;
2816 u8 mac[ETH_ALEN] = {}; 2852 u8 mac[ETH_ALEN] = {};
2817 2853
2818 mutex_lock(&sc->lock); 2854 mutex_lock(&sc->lock);
2819 if (sc->vif != conf->vif) 2855 if (sc->vif != vif)
2820 goto end; 2856 goto end;
2821 2857
2822 ath5k_hw_set_lladdr(sc->ah, mac); 2858 ath5k_hw_set_lladdr(sc->ah, mac);
@@ -3097,17 +3133,6 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3097 return 0; 3133 return 0;
3098} 3134}
3099 3135
3100static int
3101ath5k_get_tx_stats(struct ieee80211_hw *hw,
3102 struct ieee80211_tx_queue_stats *stats)
3103{
3104 struct ath5k_softc *sc = hw->priv;
3105
3106 memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
3107
3108 return 0;
3109}
3110
3111static u64 3136static u64
3112ath5k_get_tsf(struct ieee80211_hw *hw) 3137ath5k_get_tsf(struct ieee80211_hw *hw)
3113{ 3138{
@@ -3262,3 +3287,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
3262 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3287 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3263 AR5K_LED_ASSOC : AR5K_LED_INIT); 3288 AR5K_LED_ASSOC : AR5K_LED_INIT);
3264} 3289}
3290
3291/**
3292 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
3293 *
3294 * @hw: struct ieee80211_hw pointer
3295 * @coverage_class: IEEE 802.11 coverage class number
3296 *
3297 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
3298 * coverage class. The values are persistent, they are restored after device
3299 * reset.
3300 */
3301static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
3302{
3303 struct ath5k_softc *sc = hw->priv;
3304
3305 mutex_lock(&sc->lock);
3306 ath5k_hw_set_coverage_class(sc->ah, coverage_class);
3307 mutex_unlock(&sc->lock);
3308}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index b72338c9bde7..9c2fbf230ce7 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -117,7 +117,6 @@ struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 117 struct pci_dev *pdev; /* for dma mapping */
118 void __iomem *iobase; /* address of the device */ 118 void __iomem *iobase; /* address of the device */
119 struct mutex lock; /* dev-level lock */ 119 struct mutex lock; /* dev-level lock */
120 struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
121 struct ieee80211_low_level_stats ll_stats; 120 struct ieee80211_low_level_stats ll_stats;
122 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 121 struct ieee80211_hw *hw; /* IEEE 802.11 common */
123 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 60f547503d75..67aa52e9bf94 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, 77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
78 /* HP Compaq C700 (nitrousnrg@gmail.com) */ 78 /* HP Compaq C700 (nitrousnrg@gmail.com) */
79 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, 79 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
80 /* LiteOn AR5BXB63 (magooz@salug.it) */
81 { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
80 /* IBM-specific AR5212 (all others) */ 82 /* IBM-specific AR5212 (all others) */
81 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, 83 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
82 /* Dell Vostro A860 (shahar@shahar-or.co.il) */ 84 /* Dell Vostro A860 (shahar@shahar-or.co.il) */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 64fc1eb9b6d9..aefe84f9c04b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -187,8 +187,8 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
187{ 187{
188 ATH5K_TRACE(ah->ah_sc); 188 ATH5K_TRACE(ah->ah_sc);
189 189
190 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); 191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
192} 192}
193 193
194/** 194/**
@@ -200,12 +200,12 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
201{ 201{
202 ATH5K_TRACE(ah->ah_sc); 202 ATH5K_TRACE(ah->ah_sc);
203 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), 203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
204 ah->ah_turbo) <= timeout) 204 <= timeout)
205 return -EINVAL; 205 return -EINVAL;
206 206
207 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, 207 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
208 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 208 ath5k_hw_htoclock(ah, timeout));
209 209
210 return 0; 210 return 0;
211} 211}
@@ -218,8 +218,8 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) 218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
219{ 219{
220 ATH5K_TRACE(ah->ah_sc); 220 ATH5K_TRACE(ah->ah_sc);
221 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); 222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
223} 223}
224 224
225/** 225/**
@@ -231,17 +231,97 @@ unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
232{ 232{
233 ATH5K_TRACE(ah->ah_sc); 233 ATH5K_TRACE(ah->ah_sc);
234 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), 234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
235 ah->ah_turbo) <= timeout) 235 <= timeout)
236 return -EINVAL; 236 return -EINVAL;
237 237
238 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, 238 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
239 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 239 ath5k_hw_htoclock(ah, timeout));
240 240
241 return 0; 241 return 0;
242} 242}
243 243
244/** 244/**
245 * ath5k_hw_htoclock - Translate usec to hw clock units
246 *
247 * @ah: The &struct ath5k_hw
248 * @usec: value in microseconds
249 */
250unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
251{
252 return usec * ath5k_hw_get_clockrate(ah);
253}
254
255/**
256 * ath5k_hw_clocktoh - Translate hw clock units to usec
257 * @clock: value in hw clock units
258 */
259unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
260{
261 return clock / ath5k_hw_get_clockrate(ah);
262}
263
264/**
265 * ath5k_hw_get_clockrate - Get the clock rate for current mode
266 *
267 * @ah: The &struct ath5k_hw
268 */
269unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
270{
271 struct ieee80211_channel *channel = ah->ah_current_channel;
272 int clock;
273
274 if (channel->hw_value & CHANNEL_5GHZ)
275 clock = 40; /* 802.11a */
276 else if (channel->hw_value & CHANNEL_CCK)
277 clock = 22; /* 802.11b */
278 else
279 clock = 44; /* 802.11g */
280
281 /* Clock rate in turbo modes is twice the normal rate */
282 if (channel->hw_value & CHANNEL_TURBO)
283 clock *= 2;
284
285 return clock;
286}
287
288/**
289 * ath5k_hw_get_default_slottime - Get the default slot time for current mode
290 *
291 * @ah: The &struct ath5k_hw
292 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{
295 struct ieee80211_channel *channel = ah->ah_current_channel;
296
297 if (channel->hw_value & CHANNEL_TURBO)
298 return 6; /* both turbo modes */
299
300 if (channel->hw_value & CHANNEL_CCK)
301 return 20; /* 802.11b */
302
303 return 9; /* 802.11 a/g */
304}
305
306/**
307 * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
308 *
309 * @ah: The &struct ath5k_hw
310 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
312{
313 struct ieee80211_channel *channel = ah->ah_current_channel;
314
315 if (channel->hw_value & CHANNEL_TURBO)
316 return 8; /* both turbo modes */
317
318 if (channel->hw_value & CHANNEL_5GHZ)
319 return 16; /* 802.11a */
320
321 return 10; /* 802.11 b/g */
322}
323
324/**
245 * ath5k_hw_set_lladdr - Set station id 325 * ath5k_hw_set_lladdr - Set station id
246 * 326 *
247 * @ah: The &struct ath5k_hw 327 * @ah: The &struct ath5k_hw
@@ -1050,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
1050 return 0; 1130 return 0;
1051} 1131}
1052 1132
1133/**
1134 * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
1135 *
1136 * @ah: The &struct ath5k_hw
1137 * @coverage_class: IEEE 802.11 coverage class number
1138 *
1139 * Sets slot time, ACK timeout and CTS timeout for given coverage class.
1140 */
1141void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
1142{
1143 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1144 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
1145 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
1146 int cts_timeout = ack_timeout;
1147
1148 ath5k_hw_set_slot_time(ah, slot_time);
1149 ath5k_hw_set_ack_timeout(ah, ack_timeout);
1150 ath5k_hw_set_cts_timeout(ah, cts_timeout);
1151
1152 ah->ah_coverage_class = coverage_class;
1153}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index eeebb9aef206..9122a8556f45 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
408 break; 408 break;
409 409
410 case AR5K_TX_QUEUE_CAB: 410 case AR5K_TX_QUEUE_CAB:
411 /* XXX: use BCN_SENT_GT, if we can figure out how */
411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 412 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | 413 AR5K_QCU_MISC_FRSHED_DBA_GT |
413 AR5K_QCU_MISC_CBREXP_DIS | 414 AR5K_QCU_MISC_CBREXP_DIS |
414 AR5K_QCU_MISC_CBREXP_BCN_DIS); 415 AR5K_QCU_MISC_CBREXP_BCN_DIS);
415 416
416 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - 417 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
417 (AR5K_TUNE_SW_BEACON_RESP - 418 (AR5K_TUNE_SW_BEACON_RESP -
418 AR5K_TUNE_DMA_BEACON_RESP) - 419 AR5K_TUNE_DMA_BEACON_RESP) -
419 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 420 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
@@ -520,12 +521,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
520 */ 521 */
521unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) 522unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
522{ 523{
524 unsigned int slot_time_clock;
525
523 ATH5K_TRACE(ah->ah_sc); 526 ATH5K_TRACE(ah->ah_sc);
527
524 if (ah->ah_version == AR5K_AR5210) 528 if (ah->ah_version == AR5K_AR5210)
525 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, 529 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
526 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
527 else 530 else
528 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; 531 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
532
533 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
529} 534}
530 535
531/* 536/*
@@ -533,15 +538,17 @@ unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
533 */ 538 */
534int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
535{ 540{
541 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
542
536 ATH5K_TRACE(ah->ah_sc); 543 ATH5K_TRACE(ah->ah_sc);
537 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) 544
545 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
538 return -EINVAL; 546 return -EINVAL;
539 547
540 if (ah->ah_version == AR5K_AR5210) 548 if (ah->ah_version == AR5K_AR5210)
541 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, 549 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
542 ah->ah_turbo), AR5K_SLOT_TIME);
543 else 550 else
544 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); 551 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
545 552
546 return 0; 553 return 0;
547} 554}
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 62954fc77869..a35a7db0fc4c 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -60,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
60 !(channel->hw_value & CHANNEL_OFDM)); 60 !(channel->hw_value & CHANNEL_OFDM));
61 61
62 /* Get coefficient 62 /* Get coefficient
63 * ALGO: coef = (5 * clock * carrier_freq) / 2) 63 * ALGO: coef = (5 * clock / carrier_freq) / 2
64 * we scale coef by shifting clock value by 24 for 64 * we scale coef by shifting clock value by 24 for
65 * better precision since we use integers */ 65 * better precision since we use integers */
66 /* TODO: Half/quarter rate */ 66 /* TODO: Half/quarter rate */
67 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); 67 clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
68
69 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; 68 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
70 69
71 /* Get exponent 70 /* Get exponent
@@ -1317,6 +1316,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1317 /* Restore antenna mode */ 1316 /* Restore antenna mode */
1318 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 1317 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1319 1318
1319 /* Restore slot time and ACK timeouts */
1320 if (ah->ah_coverage_class > 0)
1321 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1322
1320 /* 1323 /*
1321 * Configure QCUs/DCUs 1324 * Configure QCUs/DCUs
1322 */ 1325 */
@@ -1371,8 +1374,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1371 * Set clocks to 32KHz operation and use an 1374 * Set clocks to 32KHz operation and use an
1372 * external 32KHz crystal when sleeping if one 1375 * external 32KHz crystal when sleeping if one
1373 * exists */ 1376 * exists */
1374 if (ah->ah_version == AR5K_AR5212) 1377 if (ah->ah_version == AR5K_AR5212 &&
1375 ath5k_hw_set_sleep_clock(ah, true); 1378 ah->ah_op_mode != NL80211_IFTYPE_AP)
1379 ath5k_hw_set_sleep_clock(ah, true);
1376 1380
1377 /* 1381 /*
1378 * Disable beacons and reset the register 1382 * Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 4985b2b1b0a9..6b50d5eb9ec3 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -1,4 +1,6 @@
1ath9k-y += beacon.o \ 1ath9k-y += beacon.o \
2 gpio.o \
3 init.o \
2 main.o \ 4 main.o \
3 recv.o \ 5 recv.o \
4 xmit.o \ 6 xmit.o \
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 329e6bc137ab..ca4994f13151 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
27 *csz = L1_CACHE_BYTES >> 2; 27 *csz = L1_CACHE_BYTES >> 2;
28} 28}
29 29
30static void ath_ahb_cleanup(struct ath_common *common)
31{
32 struct ath_softc *sc = (struct ath_softc *)common->priv;
33 iounmap(sc->mem);
34}
35
36static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) 30static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
37{ 31{
38 struct ath_softc *sc = (struct ath_softc *)common->priv; 32 struct ath_softc *sc = (struct ath_softc *)common->priv;
@@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
54 48
55static struct ath_bus_ops ath_ahb_bus_ops = { 49static struct ath_bus_ops ath_ahb_bus_ops = {
56 .read_cachesize = ath_ahb_read_cachesize, 50 .read_cachesize = ath_ahb_read_cachesize,
57 .cleanup = ath_ahb_cleanup,
58
59 .eeprom_read = ath_ahb_eeprom_read, 51 .eeprom_read = ath_ahb_eeprom_read,
60}; 52};
61 53
@@ -121,16 +113,19 @@ static int ath_ahb_probe(struct platform_device *pdev)
121 sc->mem = mem; 113 sc->mem = mem;
122 sc->irq = irq; 114 sc->irq = irq;
123 115
124 ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); 116 /* Will be cleared in ath9k_start() */
117 sc->sc_flags |= SC_OP_INVALID;
118
119 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
125 if (ret) { 120 if (ret) {
126 dev_err(&pdev->dev, "failed to initialize device\n"); 121 dev_err(&pdev->dev, "request_irq failed\n");
127 goto err_free_hw; 122 goto err_free_hw;
128 } 123 }
129 124
130 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); 125 ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
131 if (ret) { 126 if (ret) {
132 dev_err(&pdev->dev, "request_irq failed\n"); 127 dev_err(&pdev->dev, "failed to initialize device\n");
133 goto err_detach; 128 goto err_irq;
134 } 129 }
135 130
136 ah = sc->sc_ah; 131 ah = sc->sc_ah;
@@ -143,8 +138,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
143 138
144 return 0; 139 return 0;
145 140
146 err_detach: 141 err_irq:
147 ath_detach(sc); 142 free_irq(irq, sc);
148 err_free_hw: 143 err_free_hw:
149 ieee80211_free_hw(hw); 144 ieee80211_free_hw(hw);
150 platform_set_drvdata(pdev, NULL); 145 platform_set_drvdata(pdev, NULL);
@@ -161,8 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
161 if (hw) { 156 if (hw) {
162 struct ath_wiphy *aphy = hw->priv; 157 struct ath_wiphy *aphy = hw->priv;
163 struct ath_softc *sc = aphy->sc; 158 struct ath_softc *sc = aphy->sc;
159 void __iomem *mem = sc->mem;
164 160
165 ath_cleanup(sc); 161 ath9k_deinit_device(sc);
162 free_irq(sc->irq, sc);
163 ieee80211_free_hw(sc->hw);
164 iounmap(mem);
166 platform_set_drvdata(pdev, NULL); 165 platform_set_drvdata(pdev, NULL);
167 } 166 }
168 167
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1597a42731ed..83c7ea4c007f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -267,6 +267,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
267 u16 tid, u16 *ssn); 267 u16 tid, u16 *ssn);
268void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 268void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
269void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 269void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
270void ath9k_enable_ps(struct ath_softc *sc);
270 271
271/********/ 272/********/
272/* VIFs */ 273/* VIFs */
@@ -341,6 +342,12 @@ int ath_beaconq_config(struct ath_softc *sc);
341#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 342#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
342#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 343#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
343 344
345void ath_ani_calibrate(unsigned long data);
346
347/**********/
348/* BTCOEX */
349/**********/
350
344/* Defines the BT AR_BT_COEX_WGHT used */ 351/* Defines the BT AR_BT_COEX_WGHT used */
345enum ath_stomp_type { 352enum ath_stomp_type {
346 ATH_BTCOEX_NO_STOMP, 353 ATH_BTCOEX_NO_STOMP,
@@ -358,9 +365,14 @@ struct ath_btcoex {
358 int bt_stomp_type; /* Types of BT stomping */ 365 int bt_stomp_type; /* Types of BT stomping */
359 u32 btcoex_no_stomp; /* in usec */ 366 u32 btcoex_no_stomp; /* in usec */
360 u32 btcoex_period; /* in usec */ 367 u32 btcoex_period; /* in usec */
368 u32 btscan_no_stomp; /* in usec */
361 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 369 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
362}; 370};
363 371
372int ath_init_btcoex_timer(struct ath_softc *sc);
373void ath9k_btcoex_timer_resume(struct ath_softc *sc);
374void ath9k_btcoex_timer_pause(struct ath_softc *sc);
375
364/********************/ 376/********************/
365/* LED Control */ 377/* LED Control */
366/********************/ 378/********************/
@@ -385,6 +397,9 @@ struct ath_led {
385 bool registered; 397 bool registered;
386}; 398};
387 399
400void ath_init_leds(struct ath_softc *sc);
401void ath_deinit_leds(struct ath_softc *sc);
402
388/********************/ 403/********************/
389/* Main driver core */ 404/* Main driver core */
390/********************/ 405/********************/
@@ -403,26 +418,29 @@ struct ath_led {
403#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ 418#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
404#define ATH_RATE_DUMMY_MARKER 0 419#define ATH_RATE_DUMMY_MARKER 0
405 420
406#define SC_OP_INVALID BIT(0) 421#define SC_OP_INVALID BIT(0)
407#define SC_OP_BEACONS BIT(1) 422#define SC_OP_BEACONS BIT(1)
408#define SC_OP_RXAGGR BIT(2) 423#define SC_OP_RXAGGR BIT(2)
409#define SC_OP_TXAGGR BIT(3) 424#define SC_OP_TXAGGR BIT(3)
410#define SC_OP_FULL_RESET BIT(4) 425#define SC_OP_FULL_RESET BIT(4)
411#define SC_OP_PREAMBLE_SHORT BIT(5) 426#define SC_OP_PREAMBLE_SHORT BIT(5)
412#define SC_OP_PROTECT_ENABLE BIT(6) 427#define SC_OP_PROTECT_ENABLE BIT(6)
413#define SC_OP_RXFLUSH BIT(7) 428#define SC_OP_RXFLUSH BIT(7)
414#define SC_OP_LED_ASSOCIATED BIT(8) 429#define SC_OP_LED_ASSOCIATED BIT(8)
415#define SC_OP_WAIT_FOR_BEACON BIT(12) 430#define SC_OP_LED_ON BIT(9)
416#define SC_OP_LED_ON BIT(13) 431#define SC_OP_SCANNING BIT(10)
417#define SC_OP_SCANNING BIT(14) 432#define SC_OP_TSF_RESET BIT(11)
418#define SC_OP_TSF_RESET BIT(15) 433#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
419#define SC_OP_WAIT_FOR_CAB BIT(16) 434#define SC_OP_BT_SCAN BIT(13)
420#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17) 435
421#define SC_OP_WAIT_FOR_TX_ACK BIT(18) 436/* Powersave flags */
422#define SC_OP_BEACON_SYNC BIT(19) 437#define PS_WAIT_FOR_BEACON BIT(0)
423#define SC_OP_BT_PRIORITY_DETECTED BIT(21) 438#define PS_WAIT_FOR_CAB BIT(1)
424#define SC_OP_NULLFUNC_COMPLETED BIT(22) 439#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
425#define SC_OP_PS_ENABLED BIT(23) 440#define PS_WAIT_FOR_TX_ACK BIT(3)
441#define PS_BEACON_SYNC BIT(4)
442#define PS_NULLFUNC_COMPLETED BIT(5)
443#define PS_ENABLED BIT(6)
426 444
427struct ath_wiphy; 445struct ath_wiphy;
428struct ath_rate_table; 446struct ath_rate_table;
@@ -453,16 +471,17 @@ struct ath_softc {
453 int irq; 471 int irq;
454 spinlock_t sc_resetlock; 472 spinlock_t sc_resetlock;
455 spinlock_t sc_serial_rw; 473 spinlock_t sc_serial_rw;
456 spinlock_t ani_lock;
457 spinlock_t sc_pm_lock; 474 spinlock_t sc_pm_lock;
458 struct mutex mutex; 475 struct mutex mutex;
459 476
460 u32 intrstatus; 477 u32 intrstatus;
461 u32 sc_flags; /* SC_OP_* */ 478 u32 sc_flags; /* SC_OP_* */
479 u16 ps_flags; /* PS_* */
462 u16 curtxpow; 480 u16 curtxpow;
463 u8 nbcnvifs; 481 u8 nbcnvifs;
464 u16 nvifs; 482 u16 nvifs;
465 bool ps_enabled; 483 bool ps_enabled;
484 bool ps_idle;
466 unsigned long ps_usecount; 485 unsigned long ps_usecount;
467 enum ath9k_int imask; 486 enum ath9k_int imask;
468 487
@@ -509,6 +528,7 @@ struct ath_wiphy {
509 int chan_is_ht; 528 int chan_is_ht;
510}; 529};
511 530
531void ath9k_tasklet(unsigned long data);
512int ath_reset(struct ath_softc *sc, bool retry_tx); 532int ath_reset(struct ath_softc *sc, bool retry_tx);
513int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); 533int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
514int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); 534int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
@@ -519,21 +539,16 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
519 common->bus_ops->read_cachesize(common, csz); 539 common->bus_ops->read_cachesize(common, csz);
520} 540}
521 541
522static inline void ath_bus_cleanup(struct ath_common *common)
523{
524 common->bus_ops->cleanup(common);
525}
526
527extern struct ieee80211_ops ath9k_ops; 542extern struct ieee80211_ops ath9k_ops;
543extern int modparam_nohwcrypt;
528 544
529irqreturn_t ath_isr(int irq, void *dev); 545irqreturn_t ath_isr(int irq, void *dev);
530void ath_cleanup(struct ath_softc *sc); 546int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
531int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
532 const struct ath_bus_ops *bus_ops); 547 const struct ath_bus_ops *bus_ops);
533void ath_detach(struct ath_softc *sc); 548void ath9k_deinit_device(struct ath_softc *sc);
534const char *ath_mac_bb_name(u32 mac_bb_version); 549const char *ath_mac_bb_name(u32 mac_bb_version);
535const char *ath_rf_name(u16 rf_version); 550const char *ath_rf_name(u16 rf_version);
536void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); 551void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
537void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, 552void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
538 struct ath9k_channel *ichan); 553 struct ath9k_channel *ichan);
539void ath_update_chainmask(struct ath_softc *sc, int is_ht); 554void ath_update_chainmask(struct ath_softc *sc, int is_ht);
@@ -542,6 +557,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
542 557
543void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); 558void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
544void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); 559void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
560bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
545 561
546#ifdef CONFIG_PCI 562#ifdef CONFIG_PCI
547int ath_pci_init(void); 563int ath_pci_init(void);
@@ -583,4 +599,8 @@ void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
583void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); 599void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
584 600
585int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); 601int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
602
603void ath_start_rfkill_poll(struct ath_softc *sc);
604extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
605
586#endif /* ATH9K_H */ 606#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 1660ef17aaf5..b4a31a43a62c 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -62,7 +62,7 @@ int ath_beaconq_config(struct ath_softc *sc)
62 * Beacons are always sent out at the lowest rate, and are not retried. 62 * Beacons are always sent out at the lowest rate, and are not retried.
63*/ 63*/
64static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, 64static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
65 struct ath_buf *bf) 65 struct ath_buf *bf, int rateidx)
66{ 66{
67 struct sk_buff *skb = bf->bf_mpdu; 67 struct sk_buff *skb = bf->bf_mpdu;
68 struct ath_hw *ah = sc->sc_ah; 68 struct ath_hw *ah = sc->sc_ah;
@@ -96,9 +96,9 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
96 ds->ds_data = bf->bf_buf_addr; 96 ds->ds_data = bf->bf_buf_addr;
97 97
98 sband = &sc->sbands[common->hw->conf.channel->band]; 98 sband = &sc->sbands[common->hw->conf.channel->band];
99 rate = sband->bitrates[0].hw_value; 99 rate = sband->bitrates[rateidx].hw_value;
100 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 100 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
101 rate |= sband->bitrates[0].hw_value_short; 101 rate |= sband->bitrates[rateidx].hw_value_short;
102 102
103 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, 103 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
104 ATH9K_PKT_TYPE_BEACON, 104 ATH9K_PKT_TYPE_BEACON,
@@ -206,7 +206,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
206 } 206 }
207 } 207 }
208 208
209 ath_beacon_setup(sc, avp, bf); 209 ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx);
210 210
211 while (skb) { 211 while (skb) {
212 ath_tx_cabq(hw, skb); 212 ath_tx_cabq(hw, skb);
@@ -237,7 +237,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc,
237 bf = avp->av_bcbuf; 237 bf = avp->av_bcbuf;
238 skb = bf->bf_mpdu; 238 skb = bf->bf_mpdu;
239 239
240 ath_beacon_setup(sc, avp, bf); 240 ath_beacon_setup(sc, avp, bf, 0);
241 241
242 /* NB: caller is known to have already stopped tx dma */ 242 /* NB: caller is known to have already stopped tx dma */
243 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); 243 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long data)
480 sc->beacon.updateslot = COMMIT; /* commit next beacon */ 480 sc->beacon.updateslot = COMMIT; /* commit next beacon */
481 sc->beacon.slotupdate = slot; 481 sc->beacon.slotupdate = slot;
482 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { 482 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
483 ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); 483 ah->slottime = sc->beacon.slottime;
484 ath9k_hw_init_global_settings(ah);
484 sc->beacon.updateslot = OK; 485 sc->beacon.updateslot = OK;
485 } 486 }
486 if (bfaddr != 0) { 487 if (bfaddr != 0) {
@@ -525,16 +526,13 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
525{ 526{
526 u32 nexttbtt, intval; 527 u32 nexttbtt, intval;
527 528
528 /* Configure the timers only when the TSF has to be reset */
529
530 if (!(sc->sc_flags & SC_OP_TSF_RESET))
531 return;
532
533 /* NB: the beacon interval is kept internally in TU's */ 529 /* NB: the beacon interval is kept internally in TU's */
534 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 530 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
535 intval /= ATH_BCBUF; /* for staggered beacons */ 531 intval /= ATH_BCBUF; /* for staggered beacons */
536 nexttbtt = intval; 532 nexttbtt = intval;
537 intval |= ATH9K_BEACON_RESET_TSF; 533
534 if (sc->sc_flags & SC_OP_TSF_RESET)
535 intval |= ATH9K_BEACON_RESET_TSF;
538 536
539 /* 537 /*
540 * In AP mode we enable the beacon timers and SWBA interrupts to 538 * In AP mode we enable the beacon timers and SWBA interrupts to
@@ -576,6 +574,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
576 u64 tsf; 574 u64 tsf;
577 int num_beacons, offset, dtim_dec_count, cfp_dec_count; 575 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
578 576
577 /* No need to configure beacon if we are not associated */
578 if (!common->curaid) {
579 ath_print(common, ATH_DBG_BEACON,
580 "STA is not yet associated..skipping beacon config\n");
581 return;
582 }
583
579 memset(&bs, 0, sizeof(bs)); 584 memset(&bs, 0, sizeof(bs));
580 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 585 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
581 586
@@ -738,7 +743,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
738 enum nl80211_iftype iftype; 743 enum nl80211_iftype iftype;
739 744
740 /* Setup the beacon configuration parameters */ 745 /* Setup the beacon configuration parameters */
741
742 if (vif) { 746 if (vif) {
743 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 747 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
744 748
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1ba31a73317c..1ee5a15ccbb1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -25,10 +25,12 @@
25 25
26#define ATH_BTCOEX_DEF_BT_PERIOD 45 26#define ATH_BTCOEX_DEF_BT_PERIOD 45
27#define ATH_BTCOEX_DEF_DUTY_CYCLE 55 27#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
28#define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90
28#define ATH_BTCOEX_BMISS_THRESH 50 29#define ATH_BTCOEX_BMISS_THRESH 50
29 30
30#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */ 31#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */
31#define ATH_BT_CNT_THRESHOLD 3 32#define ATH_BT_CNT_THRESHOLD 3
33#define ATH_BT_CNT_SCAN_THRESHOLD 15
32 34
33enum ath_btcoex_scheme { 35enum ath_btcoex_scheme {
34 ATH_BTCOEX_CFG_NONE, 36 ATH_BTCOEX_CFG_NONE,
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index b66f72dbf7b9..42d2a506845a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -75,17 +75,24 @@ static const struct file_operations fops_debug = {
75 75
76#endif 76#endif
77 77
78#define DMA_BUF_LEN 1024
79
78static ssize_t read_file_dma(struct file *file, char __user *user_buf, 80static ssize_t read_file_dma(struct file *file, char __user *user_buf,
79 size_t count, loff_t *ppos) 81 size_t count, loff_t *ppos)
80{ 82{
81 struct ath_softc *sc = file->private_data; 83 struct ath_softc *sc = file->private_data;
82 struct ath_hw *ah = sc->sc_ah; 84 struct ath_hw *ah = sc->sc_ah;
83 char buf[1024]; 85 char *buf;
86 int retval;
84 unsigned int len = 0; 87 unsigned int len = 0;
85 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 88 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
86 int i, qcuOffset = 0, dcuOffset = 0; 89 int i, qcuOffset = 0, dcuOffset = 0;
87 u32 *qcuBase = &val[0], *dcuBase = &val[4]; 90 u32 *qcuBase = &val[0], *dcuBase = &val[4];
88 91
92 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
93 if (!buf)
94 return 0;
95
89 ath9k_ps_wakeup(sc); 96 ath9k_ps_wakeup(sc);
90 97
91 REG_WRITE_D(ah, AR_MACMISC, 98 REG_WRITE_D(ah, AR_MACMISC,
@@ -93,20 +100,20 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
93 (AR_MACMISC_MISC_OBS_BUS_1 << 100 (AR_MACMISC_MISC_OBS_BUS_1 <<
94 AR_MACMISC_MISC_OBS_BUS_MSB_S))); 101 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
95 102
96 len += snprintf(buf + len, sizeof(buf) - len, 103 len += snprintf(buf + len, DMA_BUF_LEN - len,
97 "Raw DMA Debug values:\n"); 104 "Raw DMA Debug values:\n");
98 105
99 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { 106 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
100 if (i % 4 == 0) 107 if (i % 4 == 0)
101 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 108 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
102 109
103 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); 110 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
104 len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", 111 len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
105 i, val[i]); 112 i, val[i]);
106 } 113 }
107 114
108 len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); 115 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
109 len += snprintf(buf + len, sizeof(buf) - len, 116 len += snprintf(buf + len, DMA_BUF_LEN - len,
110 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); 117 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
111 118
112 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { 119 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
@@ -120,7 +127,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
120 dcuBase++; 127 dcuBase++;
121 } 128 }
122 129
123 len += snprintf(buf + len, sizeof(buf) - len, 130 len += snprintf(buf + len, DMA_BUF_LEN - len,
124 "%2d %2x %1x %2x %2x\n", 131 "%2d %2x %1x %2x %2x\n",
125 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, 132 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
126 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), 133 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
@@ -128,35 +135,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
128 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); 135 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
129 } 136 }
130 137
131 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 138 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
132 139
133 len += snprintf(buf + len, sizeof(buf) - len, 140 len += snprintf(buf + len, DMA_BUF_LEN - len,
134 "qcu_stitch state: %2x qcu_fetch state: %2x\n", 141 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
135 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); 142 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
136 len += snprintf(buf + len, sizeof(buf) - len, 143 len += snprintf(buf + len, DMA_BUF_LEN - len,
137 "qcu_complete state: %2x dcu_complete state: %2x\n", 144 "qcu_complete state: %2x dcu_complete state: %2x\n",
138 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); 145 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
139 len += snprintf(buf + len, sizeof(buf) - len, 146 len += snprintf(buf + len, DMA_BUF_LEN - len,
140 "dcu_arb state: %2x dcu_fp state: %2x\n", 147 "dcu_arb state: %2x dcu_fp state: %2x\n",
141 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); 148 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
142 len += snprintf(buf + len, sizeof(buf) - len, 149 len += snprintf(buf + len, DMA_BUF_LEN - len,
143 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", 150 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
144 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); 151 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
145 len += snprintf(buf + len, sizeof(buf) - len, 152 len += snprintf(buf + len, DMA_BUF_LEN - len,
146 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", 153 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
147 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); 154 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
148 len += snprintf(buf + len, sizeof(buf) - len, 155 len += snprintf(buf + len, DMA_BUF_LEN - len,
149 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 156 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
150 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 157 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
151 158
152 len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", 159 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n",
153 REG_READ_D(ah, AR_OBS_BUS_1)); 160 REG_READ_D(ah, AR_OBS_BUS_1));
154 len += snprintf(buf + len, sizeof(buf) - len, 161 len += snprintf(buf + len, DMA_BUF_LEN - len,
155 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); 162 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
156 163
157 ath9k_ps_restore(sc); 164 ath9k_ps_restore(sc);
158 165
159 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 166 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
167 kfree(buf);
168 return retval;
160} 169}
161 170
162static const struct file_operations fops_dma = { 171static const struct file_operations fops_dma = {
@@ -289,23 +298,49 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
289 if (sc->cur_rate_table == NULL) 298 if (sc->cur_rate_table == NULL)
290 return 0; 299 return 0;
291 300
292 max = 80 + sc->cur_rate_table->rate_cnt * 64; 301 max = 80 + sc->cur_rate_table->rate_cnt * 1024;
293 buf = kmalloc(max + 1, GFP_KERNEL); 302 buf = kmalloc(max + 1, GFP_KERNEL);
294 if (buf == NULL) 303 if (buf == NULL)
295 return 0; 304 return 0;
296 buf[max] = 0; 305 buf[max] = 0;
297 306
298 len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success", 307 len += sprintf(buf, "%6s %6s %6s "
299 "Retries", "XRetries", "PER"); 308 "%10s %10s %10s %10s\n",
309 "HT", "MCS", "Rate",
310 "Success", "Retries", "XRetries", "PER");
300 311
301 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 312 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
302 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; 313 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
303 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; 314 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
315 char mcs[5];
316 char htmode[5];
317 int used_mcs = 0, used_htmode = 0;
318
319 if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
320 used_mcs = snprintf(mcs, 5, "%d",
321 sc->cur_rate_table->info[i].ratecode);
322
323 if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
324 used_htmode = snprintf(htmode, 5, "HT40");
325 else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
326 used_htmode = snprintf(htmode, 5, "HT20");
327 else
328 used_htmode = snprintf(htmode, 5, "????");
329 }
330
331 mcs[used_mcs] = '\0';
332 htmode[used_htmode] = '\0';
304 333
305 len += snprintf(buf + len, max - len, 334 len += snprintf(buf + len, max - len,
306 "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000, 335 "%6s %6s %3u.%d: "
307 (ratekbps % 1000) / 100, stats->success, 336 "%10u %10u %10u %10u\n",
308 stats->retries, stats->xretries, 337 htmode,
338 mcs,
339 ratekbps / 1000,
340 (ratekbps % 1000) / 100,
341 stats->success,
342 stats->retries,
343 stats->xretries,
309 stats->per); 344 stats->per);
310 } 345 }
311 346
@@ -554,6 +589,116 @@ static const struct file_operations fops_xmit = {
554 .owner = THIS_MODULE 589 .owner = THIS_MODULE
555}; 590};
556 591
592static ssize_t read_file_recv(struct file *file, char __user *user_buf,
593 size_t count, loff_t *ppos)
594{
595#define PHY_ERR(s, p) \
596 len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \
597 sc->debug.stats.rxstats.phy_err_stats[p]);
598
599 struct ath_softc *sc = file->private_data;
600 char *buf;
601 unsigned int len = 0, size = 1152;
602 ssize_t retval = 0;
603
604 buf = kzalloc(size, GFP_KERNEL);
605 if (buf == NULL)
606 return 0;
607
608 len += snprintf(buf + len, size - len,
609 "%18s : %10u\n", "CRC ERR",
610 sc->debug.stats.rxstats.crc_err);
611 len += snprintf(buf + len, size - len,
612 "%18s : %10u\n", "DECRYPT CRC ERR",
613 sc->debug.stats.rxstats.decrypt_crc_err);
614 len += snprintf(buf + len, size - len,
615 "%18s : %10u\n", "PHY ERR",
616 sc->debug.stats.rxstats.phy_err);
617 len += snprintf(buf + len, size - len,
618 "%18s : %10u\n", "MIC ERR",
619 sc->debug.stats.rxstats.mic_err);
620 len += snprintf(buf + len, size - len,
621 "%18s : %10u\n", "PRE-DELIM CRC ERR",
622 sc->debug.stats.rxstats.pre_delim_crc_err);
623 len += snprintf(buf + len, size - len,
624 "%18s : %10u\n", "POST-DELIM CRC ERR",
625 sc->debug.stats.rxstats.post_delim_crc_err);
626 len += snprintf(buf + len, size - len,
627 "%18s : %10u\n", "DECRYPT BUSY ERR",
628 sc->debug.stats.rxstats.decrypt_busy_err);
629
630 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
631 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
632 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
633 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
634 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
635 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
636 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
637 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
638 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
639 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
640 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
641 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
642 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
643 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
644 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
645 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
646 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
647 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
648 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
649 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
650 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
651 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
652 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
653 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
654 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
655 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
656
657 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
658 kfree(buf);
659
660 return retval;
661
662#undef PHY_ERR
663}
664
665void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf)
666{
667#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
668#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
669
670 struct ath_desc *ds = bf->bf_desc;
671 u32 phyerr;
672
673 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
674 RX_STAT_INC(crc_err);
675 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT)
676 RX_STAT_INC(decrypt_crc_err);
677 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC)
678 RX_STAT_INC(mic_err);
679 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE)
680 RX_STAT_INC(pre_delim_crc_err);
681 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST)
682 RX_STAT_INC(post_delim_crc_err);
683 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY)
684 RX_STAT_INC(decrypt_busy_err);
685
686 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
687 RX_STAT_INC(phy_err);
688 phyerr = ds->ds_rxstat.rs_phyerr & 0x24;
689 RX_PHY_ERR_INC(phyerr);
690 }
691
692#undef RX_STAT_INC
693#undef RX_PHY_ERR_INC
694}
695
696static const struct file_operations fops_recv = {
697 .read = read_file_recv,
698 .open = ath9k_debugfs_open,
699 .owner = THIS_MODULE
700};
701
557int ath9k_init_debug(struct ath_hw *ah) 702int ath9k_init_debug(struct ath_hw *ah)
558{ 703{
559 struct ath_common *common = ath9k_hw_common(ah); 704 struct ath_common *common = ath9k_hw_common(ah);
@@ -606,6 +751,13 @@ int ath9k_init_debug(struct ath_hw *ah)
606 if (!sc->debug.debugfs_xmit) 751 if (!sc->debug.debugfs_xmit)
607 goto err; 752 goto err;
608 753
754 sc->debug.debugfs_recv = debugfs_create_file("recv",
755 S_IRUSR,
756 sc->debug.debugfs_phy,
757 sc, &fops_recv);
758 if (!sc->debug.debugfs_recv)
759 goto err;
760
609 return 0; 761 return 0;
610err: 762err:
611 ath9k_exit_debug(ah); 763 ath9k_exit_debug(ah);
@@ -617,6 +769,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
617 struct ath_common *common = ath9k_hw_common(ah); 769 struct ath_common *common = ath9k_hw_common(ah);
618 struct ath_softc *sc = (struct ath_softc *) common->priv; 770 struct ath_softc *sc = (struct ath_softc *) common->priv;
619 771
772 debugfs_remove(sc->debug.debugfs_recv);
620 debugfs_remove(sc->debug.debugfs_xmit); 773 debugfs_remove(sc->debug.debugfs_xmit);
621 debugfs_remove(sc->debug.debugfs_wiphy); 774 debugfs_remove(sc->debug.debugfs_wiphy);
622 debugfs_remove(sc->debug.debugfs_rcstat); 775 debugfs_remove(sc->debug.debugfs_rcstat);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 536663e3ee11..86780e68b31e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -116,10 +116,35 @@ struct ath_tx_stats {
116 u32 delim_underrun; 116 u32 delim_underrun;
117}; 117};
118 118
119/**
120 * struct ath_rx_stats - RX Statistics
121 * @crc_err: No. of frames with incorrect CRC value
122 * @decrypt_crc_err: No. of frames whose CRC check failed after
123 decryption process completed
124 * @phy_err: No. of frames whose reception failed because the PHY
125 encountered an error
126 * @mic_err: No. of frames with incorrect TKIP MIC verification failure
127 * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
128 * @post_delim_crc_err: Post-Frame delimiter CRC error detections
129 * @decrypt_busy_err: Decryption interruptions counter
130 * @phy_err_stats: Individual PHY error statistics
131 */
132struct ath_rx_stats {
133 u32 crc_err;
134 u32 decrypt_crc_err;
135 u32 phy_err;
136 u32 mic_err;
137 u32 pre_delim_crc_err;
138 u32 post_delim_crc_err;
139 u32 decrypt_busy_err;
140 u32 phy_err_stats[ATH9K_PHYERR_MAX];
141};
142
119struct ath_stats { 143struct ath_stats {
120 struct ath_interrupt_stats istats; 144 struct ath_interrupt_stats istats;
121 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 145 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
122 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 146 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
147 struct ath_rx_stats rxstats;
123}; 148};
124 149
125struct ath9k_debug { 150struct ath9k_debug {
@@ -130,6 +155,7 @@ struct ath9k_debug {
130 struct dentry *debugfs_rcstat; 155 struct dentry *debugfs_rcstat;
131 struct dentry *debugfs_wiphy; 156 struct dentry *debugfs_wiphy;
132 struct dentry *debugfs_xmit; 157 struct dentry *debugfs_xmit;
158 struct dentry *debugfs_recv;
133 struct ath_stats stats; 159 struct ath_stats stats;
134}; 160};
135 161
@@ -142,6 +168,7 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
142void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); 168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
143void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
144 struct ath_buf *bf); 170 struct ath_buf *bf);
171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf);
145void ath_debug_stat_retries(struct ath_softc *sc, int rix, 172void ath_debug_stat_retries(struct ath_softc *sc, int rix,
146 int xretries, int retries, u8 per); 173 int xretries, int retries, u8 per);
147 174
@@ -181,6 +208,11 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
181{ 208{
182} 209}
183 210
211static inline void ath_debug_stat_rx(struct ath_softc *sc,
212 struct ath_buf *bf)
213{
214}
215
184static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, 216static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
185 int xretries, int retries, u8 per) 217 int xretries, int retries, u8 per)
186{ 218{
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
new file mode 100644
index 000000000000..deab8beb0680
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -0,0 +1,442 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19/********************************/
20/* LED functions */
21/********************************/
22
23static void ath_led_blink_work(struct work_struct *work)
24{
25 struct ath_softc *sc = container_of(work, struct ath_softc,
26 ath_led_blink_work.work);
27
28 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
29 return;
30
31 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
32 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
33 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
34 else
35 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
36 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
37
38 ieee80211_queue_delayed_work(sc->hw,
39 &sc->ath_led_blink_work,
40 (sc->sc_flags & SC_OP_LED_ON) ?
41 msecs_to_jiffies(sc->led_off_duration) :
42 msecs_to_jiffies(sc->led_on_duration));
43
44 sc->led_on_duration = sc->led_on_cnt ?
45 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
46 ATH_LED_ON_DURATION_IDLE;
47 sc->led_off_duration = sc->led_off_cnt ?
48 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
49 ATH_LED_OFF_DURATION_IDLE;
50 sc->led_on_cnt = sc->led_off_cnt = 0;
51 if (sc->sc_flags & SC_OP_LED_ON)
52 sc->sc_flags &= ~SC_OP_LED_ON;
53 else
54 sc->sc_flags |= SC_OP_LED_ON;
55}
56
57static void ath_led_brightness(struct led_classdev *led_cdev,
58 enum led_brightness brightness)
59{
60 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
61 struct ath_softc *sc = led->sc;
62
63 switch (brightness) {
64 case LED_OFF:
65 if (led->led_type == ATH_LED_ASSOC ||
66 led->led_type == ATH_LED_RADIO) {
67 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
68 (led->led_type == ATH_LED_RADIO));
69 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
70 if (led->led_type == ATH_LED_RADIO)
71 sc->sc_flags &= ~SC_OP_LED_ON;
72 } else {
73 sc->led_off_cnt++;
74 }
75 break;
76 case LED_FULL:
77 if (led->led_type == ATH_LED_ASSOC) {
78 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
79 ieee80211_queue_delayed_work(sc->hw,
80 &sc->ath_led_blink_work, 0);
81 } else if (led->led_type == ATH_LED_RADIO) {
82 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
83 sc->sc_flags |= SC_OP_LED_ON;
84 } else {
85 sc->led_on_cnt++;
86 }
87 break;
88 default:
89 break;
90 }
91}
92
93static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
94 char *trigger)
95{
96 int ret;
97
98 led->sc = sc;
99 led->led_cdev.name = led->name;
100 led->led_cdev.default_trigger = trigger;
101 led->led_cdev.brightness_set = ath_led_brightness;
102
103 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
104 if (ret)
105 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
106 "Failed to register led:%s", led->name);
107 else
108 led->registered = 1;
109 return ret;
110}
111
112static void ath_unregister_led(struct ath_led *led)
113{
114 if (led->registered) {
115 led_classdev_unregister(&led->led_cdev);
116 led->registered = 0;
117 }
118}
119
120void ath_deinit_leds(struct ath_softc *sc)
121{
122 ath_unregister_led(&sc->assoc_led);
123 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
124 ath_unregister_led(&sc->tx_led);
125 ath_unregister_led(&sc->rx_led);
126 ath_unregister_led(&sc->radio_led);
127 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
128}
129
130void ath_init_leds(struct ath_softc *sc)
131{
132 char *trigger;
133 int ret;
134
135 if (AR_SREV_9287(sc->sc_ah))
136 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
137 else
138 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
139
140 /* Configure gpio 1 for output */
141 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
142 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
143 /* LED off, active low */
144 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
145
146 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
147
148 trigger = ieee80211_get_radio_led_name(sc->hw);
149 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
150 "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
151 ret = ath_register_led(sc, &sc->radio_led, trigger);
152 sc->radio_led.led_type = ATH_LED_RADIO;
153 if (ret)
154 goto fail;
155
156 trigger = ieee80211_get_assoc_led_name(sc->hw);
157 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
158 "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
159 ret = ath_register_led(sc, &sc->assoc_led, trigger);
160 sc->assoc_led.led_type = ATH_LED_ASSOC;
161 if (ret)
162 goto fail;
163
164 trigger = ieee80211_get_tx_led_name(sc->hw);
165 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
166 "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
167 ret = ath_register_led(sc, &sc->tx_led, trigger);
168 sc->tx_led.led_type = ATH_LED_TX;
169 if (ret)
170 goto fail;
171
172 trigger = ieee80211_get_rx_led_name(sc->hw);
173 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
174 "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
175 ret = ath_register_led(sc, &sc->rx_led, trigger);
176 sc->rx_led.led_type = ATH_LED_RX;
177 if (ret)
178 goto fail;
179
180 return;
181
182fail:
183 cancel_delayed_work_sync(&sc->ath_led_blink_work);
184 ath_deinit_leds(sc);
185}
186
187/*******************/
188/* Rfkill */
189/*******************/
190
191static bool ath_is_rfkill_set(struct ath_softc *sc)
192{
193 struct ath_hw *ah = sc->sc_ah;
194
195 return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
196 ah->rfkill_polarity;
197}
198
199void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
200{
201 struct ath_wiphy *aphy = hw->priv;
202 struct ath_softc *sc = aphy->sc;
203 bool blocked = !!ath_is_rfkill_set(sc);
204
205 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
206}
207
208void ath_start_rfkill_poll(struct ath_softc *sc)
209{
210 struct ath_hw *ah = sc->sc_ah;
211
212 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
213 wiphy_rfkill_start_polling(sc->hw->wiphy);
214}
215
216/******************/
217/* BTCOEX */
218/******************/
219
220/*
221 * Detects if there is any priority bt traffic
222 */
223static void ath_detect_bt_priority(struct ath_softc *sc)
224{
225 struct ath_btcoex *btcoex = &sc->btcoex;
226 struct ath_hw *ah = sc->sc_ah;
227
228 if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
229 btcoex->bt_priority_cnt++;
230
231 if (time_after(jiffies, btcoex->bt_priority_time +
232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
233 sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
234 /* Detect if colocated bt started scanning */
235 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
236 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
237 "BT scan detected");
238 sc->sc_flags |= (SC_OP_BT_SCAN |
239 SC_OP_BT_PRIORITY_DETECTED);
240 } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
241 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
242 "BT priority traffic detected");
243 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
244 }
245
246 btcoex->bt_priority_cnt = 0;
247 btcoex->bt_priority_time = jiffies;
248 }
249}
250
251/*
252 * Configures appropriate weight based on stomp type.
253 */
254static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
255 enum ath_stomp_type stomp_type)
256{
257 struct ath_hw *ah = sc->sc_ah;
258
259 switch (stomp_type) {
260 case ATH_BTCOEX_STOMP_ALL:
261 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
262 AR_STOMP_ALL_WLAN_WGHT);
263 break;
264 case ATH_BTCOEX_STOMP_LOW:
265 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
266 AR_STOMP_LOW_WLAN_WGHT);
267 break;
268 case ATH_BTCOEX_STOMP_NONE:
269 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
270 AR_STOMP_NONE_WLAN_WGHT);
271 break;
272 default:
273 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
274 "Invalid Stomptype\n");
275 break;
276 }
277
278 ath9k_hw_btcoex_enable(ah);
279}
280
281static void ath9k_gen_timer_start(struct ath_hw *ah,
282 struct ath_gen_timer *timer,
283 u32 timer_next,
284 u32 timer_period)
285{
286 struct ath_common *common = ath9k_hw_common(ah);
287 struct ath_softc *sc = (struct ath_softc *) common->priv;
288
289 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
290
291 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
292 ath9k_hw_set_interrupts(ah, 0);
293 sc->imask |= ATH9K_INT_GENTIMER;
294 ath9k_hw_set_interrupts(ah, sc->imask);
295 }
296}
297
298static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
299{
300 struct ath_common *common = ath9k_hw_common(ah);
301 struct ath_softc *sc = (struct ath_softc *) common->priv;
302 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
303
304 ath9k_hw_gen_timer_stop(ah, timer);
305
306 /* if no timer is enabled, turn off interrupt mask */
307 if (timer_table->timer_mask.val == 0) {
308 ath9k_hw_set_interrupts(ah, 0);
309 sc->imask &= ~ATH9K_INT_GENTIMER;
310 ath9k_hw_set_interrupts(ah, sc->imask);
311 }
312}
313
314/*
315 * This is the master bt coex timer which runs for every
316 * 45ms, bt traffic will be given priority during 55% of this
317 * period while wlan gets remaining 45%
318 */
319static void ath_btcoex_period_timer(unsigned long data)
320{
321 struct ath_softc *sc = (struct ath_softc *) data;
322 struct ath_hw *ah = sc->sc_ah;
323 struct ath_btcoex *btcoex = &sc->btcoex;
324 u32 timer_period;
325 bool is_btscan;
326
327 ath_detect_bt_priority(sc);
328
329 is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
330
331 spin_lock_bh(&btcoex->btcoex_lock);
332
333 ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
334 btcoex->bt_stomp_type);
335
336 spin_unlock_bh(&btcoex->btcoex_lock);
337
338 if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
339 if (btcoex->hw_timer_enabled)
340 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
341
342 timer_period = is_btscan ? btcoex->btscan_no_stomp :
343 btcoex->btcoex_no_stomp;
344 ath9k_gen_timer_start(ah,
345 btcoex->no_stomp_timer,
346 (ath9k_hw_gettsf32(ah) +
347 timer_period), timer_period * 10);
348 btcoex->hw_timer_enabled = true;
349 }
350
351 mod_timer(&btcoex->period_timer, jiffies +
352 msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
353}
354
355/*
356 * Generic tsf based hw timer which configures weight
357 * registers to time slice between wlan and bt traffic
358 */
359static void ath_btcoex_no_stomp_timer(void *arg)
360{
361 struct ath_softc *sc = (struct ath_softc *)arg;
362 struct ath_hw *ah = sc->sc_ah;
363 struct ath_btcoex *btcoex = &sc->btcoex;
364 bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
365
366 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
367 "no stomp timer running \n");
368
369 spin_lock_bh(&btcoex->btcoex_lock);
370
371 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
372 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
373 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
374 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
375
376 spin_unlock_bh(&btcoex->btcoex_lock);
377}
378
379int ath_init_btcoex_timer(struct ath_softc *sc)
380{
381 struct ath_btcoex *btcoex = &sc->btcoex;
382
383 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
384 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
385 btcoex->btcoex_period / 100;
386 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
387 btcoex->btcoex_period / 100;
388
389 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
390 (unsigned long) sc);
391
392 spin_lock_init(&btcoex->btcoex_lock);
393
394 btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
395 ath_btcoex_no_stomp_timer,
396 ath_btcoex_no_stomp_timer,
397 (void *) sc, AR_FIRST_NDP_TIMER);
398
399 if (!btcoex->no_stomp_timer)
400 return -ENOMEM;
401
402 return 0;
403}
404
405/*
406 * (Re)start btcoex timers
407 */
408void ath9k_btcoex_timer_resume(struct ath_softc *sc)
409{
410 struct ath_btcoex *btcoex = &sc->btcoex;
411 struct ath_hw *ah = sc->sc_ah;
412
413 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
414 "Starting btcoex timers");
415
416 /* make sure duty cycle timer is also stopped when resuming */
417 if (btcoex->hw_timer_enabled)
418 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
419
420 btcoex->bt_priority_cnt = 0;
421 btcoex->bt_priority_time = jiffies;
422 sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
423
424 mod_timer(&btcoex->period_timer, jiffies);
425}
426
427
428/*
429 * Pause btcoex timer and bt duty cycle timer
430 */
431void ath9k_btcoex_timer_pause(struct ath_softc *sc)
432{
433 struct ath_btcoex *btcoex = &sc->btcoex;
434 struct ath_hw *ah = sc->sc_ah;
435
436 del_timer_sync(&btcoex->period_timer);
437
438 if (btcoex->hw_timer_enabled)
439 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
440
441 btcoex->hw_timer_enabled = false;
442}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ae371448b5a0..f00f5c744f48 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -52,28 +52,6 @@ module_exit(ath9k_exit);
52/* Helper Functions */ 52/* Helper Functions */
53/********************/ 53/********************/
54 54
55static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
56{
57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
58
59 if (!ah->curchan) /* should really check for CCK instead */
60 return clks / ATH9K_CLOCK_RATE_CCK;
61 if (conf->channel->band == IEEE80211_BAND_2GHZ)
62 return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
63
64 return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
65}
66
67static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
68{
69 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
70
71 if (conf_is_ht40(conf))
72 return ath9k_hw_mac_usec(ah, clks) / 2;
73 else
74 return ath9k_hw_mac_usec(ah, clks);
75}
76
77static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) 55static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
78{ 56{
79 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -343,30 +321,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
343 return true; 321 return true;
344} 322}
345 323
346static const char *ath9k_hw_devname(u16 devid)
347{
348 switch (devid) {
349 case AR5416_DEVID_PCI:
350 return "Atheros 5416";
351 case AR5416_DEVID_PCIE:
352 return "Atheros 5418";
353 case AR9160_DEVID_PCI:
354 return "Atheros 9160";
355 case AR5416_AR9100_DEVID:
356 return "Atheros 9100";
357 case AR9280_DEVID_PCI:
358 case AR9280_DEVID_PCIE:
359 return "Atheros 9280";
360 case AR9285_DEVID_PCIE:
361 return "Atheros 9285";
362 case AR5416_DEVID_AR9287_PCI:
363 case AR5416_DEVID_AR9287_PCIE:
364 return "Atheros 9287";
365 }
366
367 return NULL;
368}
369
370static void ath9k_hw_init_config(struct ath_hw *ah) 324static void ath9k_hw_init_config(struct ath_hw *ah)
371{ 325{
372 int i; 326 int i;
@@ -380,7 +334,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
380 ah->config.pcie_clock_req = 0; 334 ah->config.pcie_clock_req = 0;
381 ah->config.pcie_waen = 0; 335 ah->config.pcie_waen = 0;
382 ah->config.analog_shiftreg = 1; 336 ah->config.analog_shiftreg = 1;
383 ah->config.ht_enable = 1;
384 ah->config.ofdm_trig_low = 200; 337 ah->config.ofdm_trig_low = 200;
385 ah->config.ofdm_trig_high = 500; 338 ah->config.ofdm_trig_high = 500;
386 ah->config.cck_trig_high = 200; 339 ah->config.cck_trig_high = 200;
@@ -392,7 +345,12 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
392 ah->config.spurchans[i][1] = AR_NO_SPUR; 345 ah->config.spurchans[i][1] = AR_NO_SPUR;
393 } 346 }
394 347
395 ah->config.intr_mitigation = true; 348 if (ah->hw_version.devid != AR2427_DEVID_PCIE)
349 ah->config.ht_enable = 1;
350 else
351 ah->config.ht_enable = 0;
352
353 ah->config.rx_intr_mitigation = true;
396 354
397 /* 355 /*
398 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 356 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -437,8 +395,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
437 ah->beacon_interval = 100; 395 ah->beacon_interval = 100;
438 ah->enable_32kHz_clock = DONT_USE_32KHZ; 396 ah->enable_32kHz_clock = DONT_USE_32KHZ;
439 ah->slottime = (u32) -1; 397 ah->slottime = (u32) -1;
440 ah->acktimeout = (u32) -1;
441 ah->ctstimeout = (u32) -1;
442 ah->globaltxtimeout = (u32) -1; 398 ah->globaltxtimeout = (u32) -1;
443 ah->power_mode = ATH9K_PM_UNDEFINED; 399 ah->power_mode = ATH9K_PM_UNDEFINED;
444} 400}
@@ -590,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid)
590 case AR5416_DEVID_AR9287_PCI: 546 case AR5416_DEVID_AR9287_PCI:
591 case AR5416_DEVID_AR9287_PCIE: 547 case AR5416_DEVID_AR9287_PCIE:
592 case AR9271_USB: 548 case AR9271_USB:
549 case AR2427_DEVID_PCIE:
593 return true; 550 return true;
594 default: 551 default:
595 break; 552 break;
@@ -1183,7 +1140,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1183 AR_IMR_RXORN | 1140 AR_IMR_RXORN |
1184 AR_IMR_BCNMISC; 1141 AR_IMR_BCNMISC;
1185 1142
1186 if (ah->config.intr_mitigation) 1143 if (ah->config.rx_intr_mitigation)
1187 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 1144 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1188 else 1145 else
1189 ah->mask_reg |= AR_IMR_RXOK; 1146 ah->mask_reg |= AR_IMR_RXOK;
@@ -1203,34 +1160,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1203 } 1160 }
1204} 1161}
1205 1162
1206static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) 1163static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
1207{ 1164{
1208 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 1165 u32 val = ath9k_hw_mac_to_clks(ah, us);
1209 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1166 val = min(val, (u32) 0xFFFF);
1210 "bad ack timeout %u\n", us); 1167 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
1211 ah->acktimeout = (u32) -1;
1212 return false;
1213 } else {
1214 REG_RMW_FIELD(ah, AR_TIME_OUT,
1215 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
1216 ah->acktimeout = us;
1217 return true;
1218 }
1219} 1168}
1220 1169
1221static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) 1170static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
1222{ 1171{
1223 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 1172 u32 val = ath9k_hw_mac_to_clks(ah, us);
1224 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1173 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
1225 "bad cts timeout %u\n", us); 1174 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
1226 ah->ctstimeout = (u32) -1; 1175}
1227 return false; 1176
1228 } else { 1177static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
1229 REG_RMW_FIELD(ah, AR_TIME_OUT, 1178{
1230 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); 1179 u32 val = ath9k_hw_mac_to_clks(ah, us);
1231 ah->ctstimeout = us; 1180 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
1232 return true; 1181 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
1233 }
1234} 1182}
1235 1183
1236static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) 1184static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1247,31 +1195,48 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
1247 } 1195 }
1248} 1196}
1249 1197
1250static void ath9k_hw_init_user_settings(struct ath_hw *ah) 1198void ath9k_hw_init_global_settings(struct ath_hw *ah)
1251{ 1199{
1200 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
1201 int acktimeout;
1202 int slottime;
1203 int sifstime;
1204
1252 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", 1205 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
1253 ah->misc_mode); 1206 ah->misc_mode);
1254 1207
1255 if (ah->misc_mode != 0) 1208 if (ah->misc_mode != 0)
1256 REG_WRITE(ah, AR_PCU_MISC, 1209 REG_WRITE(ah, AR_PCU_MISC,
1257 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); 1210 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
1258 if (ah->slottime != (u32) -1) 1211
1259 ath9k_hw_setslottime(ah, ah->slottime); 1212 if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
1260 if (ah->acktimeout != (u32) -1) 1213 sifstime = 16;
1261 ath9k_hw_set_ack_timeout(ah, ah->acktimeout); 1214 else
1262 if (ah->ctstimeout != (u32) -1) 1215 sifstime = 10;
1263 ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); 1216
1217 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1218 slottime = ah->slottime + 3 * ah->coverage_class;
1219 acktimeout = slottime + sifstime;
1220
1221 /*
1222 * Workaround for early ACK timeouts, add an offset to match the
1223 * initval's 64us ack timeout value.
1224 * This was initially only meant to work around an issue with delayed
1225 * BA frames in some implementations, but it has been found to fix ACK
1226 * timeout issues in other cases as well.
1227 */
1228 if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
1229 acktimeout += 64 - sifstime - ah->slottime;
1230
1231 ath9k_hw_setslottime(ah, slottime);
1232 ath9k_hw_set_ack_timeout(ah, acktimeout);
1233 ath9k_hw_set_cts_timeout(ah, acktimeout);
1264 if (ah->globaltxtimeout != (u32) -1) 1234 if (ah->globaltxtimeout != (u32) -1)
1265 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); 1235 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
1266} 1236}
1237EXPORT_SYMBOL(ath9k_hw_init_global_settings);
1267 1238
1268const char *ath9k_hw_probe(u16 vendorid, u16 devid) 1239void ath9k_hw_deinit(struct ath_hw *ah)
1269{
1270 return vendorid == ATHEROS_VENDOR_ID ?
1271 ath9k_hw_devname(devid) : NULL;
1272}
1273
1274void ath9k_hw_detach(struct ath_hw *ah)
1275{ 1240{
1276 struct ath_common *common = ath9k_hw_common(ah); 1241 struct ath_common *common = ath9k_hw_common(ah);
1277 1242
@@ -1289,7 +1254,7 @@ free_hw:
1289 kfree(ah); 1254 kfree(ah);
1290 ah = NULL; 1255 ah = NULL;
1291} 1256}
1292EXPORT_SYMBOL(ath9k_hw_detach); 1257EXPORT_SYMBOL(ath9k_hw_deinit);
1293 1258
1294/*******/ 1259/*******/
1295/* INI */ 1260/* INI */
@@ -2090,7 +2055,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2090 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2055 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2091 ath9k_enable_rfkill(ah); 2056 ath9k_enable_rfkill(ah);
2092 2057
2093 ath9k_hw_init_user_settings(ah); 2058 ath9k_hw_init_global_settings(ah);
2094 2059
2095 if (AR_SREV_9287_12_OR_LATER(ah)) { 2060 if (AR_SREV_9287_12_OR_LATER(ah)) {
2096 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 2061 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -2120,7 +2085,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2120 2085
2121 REG_WRITE(ah, AR_OBS, 8); 2086 REG_WRITE(ah, AR_OBS, 8);
2122 2087
2123 if (ah->config.intr_mitigation) { 2088 if (ah->config.rx_intr_mitigation) {
2124 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 2089 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
2125 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 2090 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
2126 } 2091 }
@@ -2780,7 +2745,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2780 2745
2781 *masked = isr & ATH9K_INT_COMMON; 2746 *masked = isr & ATH9K_INT_COMMON;
2782 2747
2783 if (ah->config.intr_mitigation) { 2748 if (ah->config.rx_intr_mitigation) {
2784 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) 2749 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2785 *masked |= ATH9K_INT_RX; 2750 *masked |= ATH9K_INT_RX;
2786 } 2751 }
@@ -2913,7 +2878,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2913 } 2878 }
2914 if (ints & ATH9K_INT_RX) { 2879 if (ints & ATH9K_INT_RX) {
2915 mask |= AR_IMR_RXERR; 2880 mask |= AR_IMR_RXERR;
2916 if (ah->config.intr_mitigation) 2881 if (ah->config.rx_intr_mitigation)
2917 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 2882 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
2918 else 2883 else
2919 mask |= AR_IMR_RXOK | AR_IMR_RXDESC; 2884 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3687,21 +3652,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
3687} 3652}
3688EXPORT_SYMBOL(ath9k_hw_extend_tsf); 3653EXPORT_SYMBOL(ath9k_hw_extend_tsf);
3689 3654
3690bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
3691{
3692 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
3693 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
3694 "bad slot time %u\n", us);
3695 ah->slottime = (u32) -1;
3696 return false;
3697 } else {
3698 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
3699 ah->slottime = us;
3700 return true;
3701 }
3702}
3703EXPORT_SYMBOL(ath9k_hw_setslottime);
3704
3705void ath9k_hw_set11nmac2040(struct ath_hw *ah) 3655void ath9k_hw_set11nmac2040(struct ath_hw *ah)
3706{ 3656{
3707 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 3657 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e2b0c73a616f..dbbf7ca5f97d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -40,6 +40,7 @@
40#define AR9280_DEVID_PCI 0x0029 40#define AR9280_DEVID_PCI 0x0029
41#define AR9280_DEVID_PCIE 0x002a 41#define AR9280_DEVID_PCIE 0x002a
42#define AR9285_DEVID_PCIE 0x002b 42#define AR9285_DEVID_PCIE 0x002b
43#define AR2427_DEVID_PCIE 0x002c
43 44
44#define AR5416_AR9100_DEVID 0x000b 45#define AR5416_AR9100_DEVID 0x000b
45 46
@@ -212,7 +213,7 @@ struct ath9k_ops_config {
212 u32 cck_trig_low; 213 u32 cck_trig_low;
213 u32 enable_ani; 214 u32 enable_ani;
214 int serialize_regmode; 215 int serialize_regmode;
215 bool intr_mitigation; 216 bool rx_intr_mitigation;
216#define SPUR_DISABLE 0 217#define SPUR_DISABLE 0
217#define SPUR_ENABLE_IOCTL 1 218#define SPUR_ENABLE_IOCTL 1
218#define SPUR_ENABLE_EEPROM 2 219#define SPUR_ENABLE_EEPROM 2
@@ -551,10 +552,9 @@ struct ath_hw {
551 u32 *bank6Temp; 552 u32 *bank6Temp;
552 553
553 int16_t txpower_indexoffset; 554 int16_t txpower_indexoffset;
555 int coverage_class;
554 u32 beacon_interval; 556 u32 beacon_interval;
555 u32 slottime; 557 u32 slottime;
556 u32 acktimeout;
557 u32 ctstimeout;
558 u32 globaltxtimeout; 558 u32 globaltxtimeout;
559 559
560 /* ANI */ 560 /* ANI */
@@ -616,7 +616,7 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
616 616
617/* Initialization, Detach, Reset */ 617/* Initialization, Detach, Reset */
618const char *ath9k_hw_probe(u16 vendorid, u16 devid); 618const char *ath9k_hw_probe(u16 vendorid, u16 devid);
619void ath9k_hw_detach(struct ath_hw *ah); 619void ath9k_hw_deinit(struct ath_hw *ah);
620int ath9k_hw_init(struct ath_hw *ah); 620int ath9k_hw_init(struct ath_hw *ah);
621int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 621int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
622 bool bChannelChange); 622 bool bChannelChange);
@@ -668,7 +668,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
668void ath9k_hw_reset_tsf(struct ath_hw *ah); 668void ath9k_hw_reset_tsf(struct ath_hw *ah);
669void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); 669void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
670u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); 670u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
671bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); 671void ath9k_hw_init_global_settings(struct ath_hw *ah);
672void ath9k_hw_set11nmac2040(struct ath_hw *ah); 672void ath9k_hw_set11nmac2040(struct ath_hw *ah);
673void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 673void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
674void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, 674void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
new file mode 100644
index 000000000000..623c2f884987
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -0,0 +1,863 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static char *dev_info = "ath9k";
20
21MODULE_AUTHOR("Atheros Communications");
22MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
23MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
24MODULE_LICENSE("Dual BSD/GPL");
25
26static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
27module_param_named(debug, ath9k_debug, uint, 0);
28MODULE_PARM_DESC(debug, "Debugging mask");
29
30int modparam_nohwcrypt;
31module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
32MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
33
34/* We use the hw_value as an index into our private channel structure */
35
36#define CHAN2G(_freq, _idx) { \
37 .center_freq = (_freq), \
38 .hw_value = (_idx), \
39 .max_power = 20, \
40}
41
42#define CHAN5G(_freq, _idx) { \
43 .band = IEEE80211_BAND_5GHZ, \
44 .center_freq = (_freq), \
45 .hw_value = (_idx), \
46 .max_power = 20, \
47}
48
49/* Some 2 GHz radios are actually tunable on 2312-2732
50 * on 5 MHz steps, we support the channels which we know
51 * we have calibration data for all cards though to make
52 * this static */
53static struct ieee80211_channel ath9k_2ghz_chantable[] = {
54 CHAN2G(2412, 0), /* Channel 1 */
55 CHAN2G(2417, 1), /* Channel 2 */
56 CHAN2G(2422, 2), /* Channel 3 */
57 CHAN2G(2427, 3), /* Channel 4 */
58 CHAN2G(2432, 4), /* Channel 5 */
59 CHAN2G(2437, 5), /* Channel 6 */
60 CHAN2G(2442, 6), /* Channel 7 */
61 CHAN2G(2447, 7), /* Channel 8 */
62 CHAN2G(2452, 8), /* Channel 9 */
63 CHAN2G(2457, 9), /* Channel 10 */
64 CHAN2G(2462, 10), /* Channel 11 */
65 CHAN2G(2467, 11), /* Channel 12 */
66 CHAN2G(2472, 12), /* Channel 13 */
67 CHAN2G(2484, 13), /* Channel 14 */
68};
69
70/* Some 5 GHz radios are actually tunable on XXXX-YYYY
71 * on 5 MHz steps, we support the channels which we know
72 * we have calibration data for all cards though to make
73 * this static */
74static struct ieee80211_channel ath9k_5ghz_chantable[] = {
75 /* _We_ call this UNII 1 */
76 CHAN5G(5180, 14), /* Channel 36 */
77 CHAN5G(5200, 15), /* Channel 40 */
78 CHAN5G(5220, 16), /* Channel 44 */
79 CHAN5G(5240, 17), /* Channel 48 */
80 /* _We_ call this UNII 2 */
81 CHAN5G(5260, 18), /* Channel 52 */
82 CHAN5G(5280, 19), /* Channel 56 */
83 CHAN5G(5300, 20), /* Channel 60 */
84 CHAN5G(5320, 21), /* Channel 64 */
85 /* _We_ call this "Middle band" */
86 CHAN5G(5500, 22), /* Channel 100 */
87 CHAN5G(5520, 23), /* Channel 104 */
88 CHAN5G(5540, 24), /* Channel 108 */
89 CHAN5G(5560, 25), /* Channel 112 */
90 CHAN5G(5580, 26), /* Channel 116 */
91 CHAN5G(5600, 27), /* Channel 120 */
92 CHAN5G(5620, 28), /* Channel 124 */
93 CHAN5G(5640, 29), /* Channel 128 */
94 CHAN5G(5660, 30), /* Channel 132 */
95 CHAN5G(5680, 31), /* Channel 136 */
96 CHAN5G(5700, 32), /* Channel 140 */
97 /* _We_ call this UNII 3 */
98 CHAN5G(5745, 33), /* Channel 149 */
99 CHAN5G(5765, 34), /* Channel 153 */
100 CHAN5G(5785, 35), /* Channel 157 */
101 CHAN5G(5805, 36), /* Channel 161 */
102 CHAN5G(5825, 37), /* Channel 165 */
103};
104
105/* Atheros hardware rate code addition for short premble */
106#define SHPCHECK(__hw_rate, __flags) \
107 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
108
109#define RATE(_bitrate, _hw_rate, _flags) { \
110 .bitrate = (_bitrate), \
111 .flags = (_flags), \
112 .hw_value = (_hw_rate), \
113 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
114}
115
116static struct ieee80211_rate ath9k_legacy_rates[] = {
117 RATE(10, 0x1b, 0),
118 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATE(60, 0x0b, 0),
122 RATE(90, 0x0f, 0),
123 RATE(120, 0x0a, 0),
124 RATE(180, 0x0e, 0),
125 RATE(240, 0x09, 0),
126 RATE(360, 0x0d, 0),
127 RATE(480, 0x08, 0),
128 RATE(540, 0x0c, 0),
129};
130
131static void ath9k_deinit_softc(struct ath_softc *sc);
132
133/*
134 * Read and write, they both share the same lock. We do this to serialize
135 * reads and writes on Atheros 802.11n PCI devices only. This is required
136 * as the FIFO on these devices can only accept sanely 2 requests.
137 */
138
139static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
140{
141 struct ath_hw *ah = (struct ath_hw *) hw_priv;
142 struct ath_common *common = ath9k_hw_common(ah);
143 struct ath_softc *sc = (struct ath_softc *) common->priv;
144
145 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
146 unsigned long flags;
147 spin_lock_irqsave(&sc->sc_serial_rw, flags);
148 iowrite32(val, sc->mem + reg_offset);
149 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
150 } else
151 iowrite32(val, sc->mem + reg_offset);
152}
153
154static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
155{
156 struct ath_hw *ah = (struct ath_hw *) hw_priv;
157 struct ath_common *common = ath9k_hw_common(ah);
158 struct ath_softc *sc = (struct ath_softc *) common->priv;
159 u32 val;
160
161 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
162 unsigned long flags;
163 spin_lock_irqsave(&sc->sc_serial_rw, flags);
164 val = ioread32(sc->mem + reg_offset);
165 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
166 } else
167 val = ioread32(sc->mem + reg_offset);
168 return val;
169}
170
171static const struct ath_ops ath9k_common_ops = {
172 .read = ath9k_ioread32,
173 .write = ath9k_iowrite32,
174};
175
176/**************************/
177/* Initialization */
178/**************************/
179
180static void setup_ht_cap(struct ath_softc *sc,
181 struct ieee80211_sta_ht_cap *ht_info)
182{
183 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
184 u8 tx_streams, rx_streams;
185
186 ht_info->ht_supported = true;
187 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
188 IEEE80211_HT_CAP_SM_PS |
189 IEEE80211_HT_CAP_SGI_40 |
190 IEEE80211_HT_CAP_DSSSCCK40;
191
192 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
193 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
194
195 /* set up supported mcs set */
196 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
197 tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
198 1 : 2;
199 rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
200 1 : 2;
201
202 if (tx_streams != rx_streams) {
203 ath_print(common, ATH_DBG_CONFIG,
204 "TX streams %d, RX streams: %d\n",
205 tx_streams, rx_streams);
206 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
207 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
208 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
209 }
210
211 ht_info->mcs.rx_mask[0] = 0xff;
212 if (rx_streams >= 2)
213 ht_info->mcs.rx_mask[1] = 0xff;
214
215 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
216}
217
218static int ath9k_reg_notifier(struct wiphy *wiphy,
219 struct regulatory_request *request)
220{
221 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
222 struct ath_wiphy *aphy = hw->priv;
223 struct ath_softc *sc = aphy->sc;
224 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
225
226 return ath_reg_notifier_apply(wiphy, request, reg);
227}
228
229/*
230 * This function will allocate both the DMA descriptor structure, and the
231 * buffers it contains. These are used to contain the descriptors used
232 * by the system.
233*/
234int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
235 struct list_head *head, const char *name,
236 int nbuf, int ndesc)
237{
238#define DS2PHYS(_dd, _ds) \
239 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
240#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
241#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
242 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
243 struct ath_desc *ds;
244 struct ath_buf *bf;
245 int i, bsize, error;
246
247 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
248 name, nbuf, ndesc);
249
250 INIT_LIST_HEAD(head);
251 /* ath_desc must be a multiple of DWORDs */
252 if ((sizeof(struct ath_desc) % 4) != 0) {
253 ath_print(common, ATH_DBG_FATAL,
254 "ath_desc not DWORD aligned\n");
255 BUG_ON((sizeof(struct ath_desc) % 4) != 0);
256 error = -ENOMEM;
257 goto fail;
258 }
259
260 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
261
262 /*
263 * Need additional DMA memory because we can't use
264 * descriptors that cross the 4K page boundary. Assume
265 * one skipped descriptor per 4K page.
266 */
267 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
268 u32 ndesc_skipped =
269 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
270 u32 dma_len;
271
272 while (ndesc_skipped) {
273 dma_len = ndesc_skipped * sizeof(struct ath_desc);
274 dd->dd_desc_len += dma_len;
275
276 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
277 };
278 }
279
280 /* allocate descriptors */
281 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
282 &dd->dd_desc_paddr, GFP_KERNEL);
283 if (dd->dd_desc == NULL) {
284 error = -ENOMEM;
285 goto fail;
286 }
287 ds = dd->dd_desc;
288 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
289 name, ds, (u32) dd->dd_desc_len,
290 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
291
292 /* allocate buffers */
293 bsize = sizeof(struct ath_buf) * nbuf;
294 bf = kzalloc(bsize, GFP_KERNEL);
295 if (bf == NULL) {
296 error = -ENOMEM;
297 goto fail2;
298 }
299 dd->dd_bufptr = bf;
300
301 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
302 bf->bf_desc = ds;
303 bf->bf_daddr = DS2PHYS(dd, ds);
304
305 if (!(sc->sc_ah->caps.hw_caps &
306 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
307 /*
308 * Skip descriptor addresses which can cause 4KB
309 * boundary crossing (addr + length) with a 32 dword
310 * descriptor fetch.
311 */
312 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
313 BUG_ON((caddr_t) bf->bf_desc >=
314 ((caddr_t) dd->dd_desc +
315 dd->dd_desc_len));
316
317 ds += ndesc;
318 bf->bf_desc = ds;
319 bf->bf_daddr = DS2PHYS(dd, ds);
320 }
321 }
322 list_add_tail(&bf->list, head);
323 }
324 return 0;
325fail2:
326 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
327 dd->dd_desc_paddr);
328fail:
329 memset(dd, 0, sizeof(*dd));
330 return error;
331#undef ATH_DESC_4KB_BOUND_CHECK
332#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
333#undef DS2PHYS
334}
335
336static void ath9k_init_crypto(struct ath_softc *sc)
337{
338 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
339 int i = 0;
340
341 /* Get the hardware key cache size. */
342 common->keymax = sc->sc_ah->caps.keycache_size;
343 if (common->keymax > ATH_KEYMAX) {
344 ath_print(common, ATH_DBG_ANY,
345 "Warning, using only %u entries in %u key cache\n",
346 ATH_KEYMAX, common->keymax);
347 common->keymax = ATH_KEYMAX;
348 }
349
350 /*
351 * Reset the key cache since some parts do not
352 * reset the contents on initial power up.
353 */
354 for (i = 0; i < common->keymax; i++)
355 ath9k_hw_keyreset(sc->sc_ah, (u16) i);
356
357 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
358 ATH9K_CIPHER_TKIP, NULL)) {
359 /*
360 * Whether we should enable h/w TKIP MIC.
361 * XXX: if we don't support WME TKIP MIC, then we wouldn't
362 * report WMM capable, so it's always safe to turn on
363 * TKIP MIC in this case.
364 */
365 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
366 }
367
368 /*
369 * Check whether the separate key cache entries
370 * are required to handle both tx+rx MIC keys.
371 * With split mic keys the number of stations is limited
372 * to 27 otherwise 59.
373 */
374 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
375 ATH9K_CIPHER_TKIP, NULL)
376 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
377 ATH9K_CIPHER_MIC, NULL)
378 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT,
379 0, NULL))
380 common->splitmic = 1;
381
382 /* turn on mcast key search if possible */
383 if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
384 (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH,
385 1, 1, NULL);
386
387}
388
389static int ath9k_init_btcoex(struct ath_softc *sc)
390{
391 int r, qnum;
392
393 switch (sc->sc_ah->btcoex_hw.scheme) {
394 case ATH_BTCOEX_CFG_NONE:
395 break;
396 case ATH_BTCOEX_CFG_2WIRE:
397 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
398 break;
399 case ATH_BTCOEX_CFG_3WIRE:
400 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
401 r = ath_init_btcoex_timer(sc);
402 if (r)
403 return -1;
404 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
405 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
406 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
407 break;
408 default:
409 WARN_ON(1);
410 break;
411 }
412
413 return 0;
414}
415
416static int ath9k_init_queues(struct ath_softc *sc)
417{
418 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
419 int i = 0;
420
421 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
422 sc->tx.hwq_map[i] = -1;
423
424 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
425 if (sc->beacon.beaconq == -1) {
426 ath_print(common, ATH_DBG_FATAL,
427 "Unable to setup a beacon xmit queue\n");
428 goto err;
429 }
430
431 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
432 if (sc->beacon.cabq == NULL) {
433 ath_print(common, ATH_DBG_FATAL,
434 "Unable to setup CAB xmit queue\n");
435 goto err;
436 }
437
438 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
439 ath_cabq_update(sc);
440
441 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
442 ath_print(common, ATH_DBG_FATAL,
443 "Unable to setup xmit queue for BK traffic\n");
444 goto err;
445 }
446
447 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
448 ath_print(common, ATH_DBG_FATAL,
449 "Unable to setup xmit queue for BE traffic\n");
450 goto err;
451 }
452 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
453 ath_print(common, ATH_DBG_FATAL,
454 "Unable to setup xmit queue for VI traffic\n");
455 goto err;
456 }
457 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
458 ath_print(common, ATH_DBG_FATAL,
459 "Unable to setup xmit queue for VO traffic\n");
460 goto err;
461 }
462
463 return 0;
464
465err:
466 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
467 if (ATH_TXQ_SETUP(sc, i))
468 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
469
470 return -EIO;
471}
472
473static void ath9k_init_channels_rates(struct ath_softc *sc)
474{
475 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
476 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
477 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
478 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
479 ARRAY_SIZE(ath9k_2ghz_chantable);
480 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
481 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
482 ARRAY_SIZE(ath9k_legacy_rates);
483 }
484
485 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
486 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
487 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
488 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
489 ARRAY_SIZE(ath9k_5ghz_chantable);
490 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
491 ath9k_legacy_rates + 4;
492 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
493 ARRAY_SIZE(ath9k_legacy_rates) - 4;
494 }
495}
496
497static void ath9k_init_misc(struct ath_softc *sc)
498{
499 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
500 int i = 0;
501
502 common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
503 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
504
505 sc->config.txpowlimit = ATH_TXPOWER_MAX;
506
507 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
508 sc->sc_flags |= SC_OP_TXAGGR;
509 sc->sc_flags |= SC_OP_RXAGGR;
510 }
511
512 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
513 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
514
515 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
516 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
517
518 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
519 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
520
521 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
522
523 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
524 sc->beacon.bslot[i] = NULL;
525 sc->beacon.bslot_aphy[i] = NULL;
526 }
527}
528
529static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
530 const struct ath_bus_ops *bus_ops)
531{
532 struct ath_hw *ah = NULL;
533 struct ath_common *common;
534 int ret = 0, i;
535 int csz = 0;
536
537 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
538 if (!ah)
539 return -ENOMEM;
540
541 ah->hw_version.devid = devid;
542 ah->hw_version.subsysid = subsysid;
543 sc->sc_ah = ah;
544
545 common = ath9k_hw_common(ah);
546 common->ops = &ath9k_common_ops;
547 common->bus_ops = bus_ops;
548 common->ah = ah;
549 common->hw = sc->hw;
550 common->priv = sc;
551 common->debug_mask = ath9k_debug;
552
553 spin_lock_init(&sc->wiphy_lock);
554 spin_lock_init(&sc->sc_resetlock);
555 spin_lock_init(&sc->sc_serial_rw);
556 spin_lock_init(&sc->sc_pm_lock);
557 mutex_init(&sc->mutex);
558 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
559 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
560 (unsigned long)sc);
561
562 /*
563 * Cache line size is used to size and align various
564 * structures used to communicate with the hardware.
565 */
566 ath_read_cachesize(common, &csz);
567 common->cachelsz = csz << 2; /* convert to bytes */
568
569 ret = ath9k_hw_init(ah);
570 if (ret) {
571 ath_print(common, ATH_DBG_FATAL,
572 "Unable to initialize hardware; "
573 "initialization status: %d\n", ret);
574 goto err_hw;
575 }
576
577 ret = ath9k_init_debug(ah);
578 if (ret) {
579 ath_print(common, ATH_DBG_FATAL,
580 "Unable to create debugfs files\n");
581 goto err_debug;
582 }
583
584 ret = ath9k_init_queues(sc);
585 if (ret)
586 goto err_queues;
587
588 ret = ath9k_init_btcoex(sc);
589 if (ret)
590 goto err_btcoex;
591
592 ath9k_init_crypto(sc);
593 ath9k_init_channels_rates(sc);
594 ath9k_init_misc(sc);
595
596 return 0;
597
598err_btcoex:
599 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
600 if (ATH_TXQ_SETUP(sc, i))
601 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
602err_queues:
603 ath9k_exit_debug(ah);
604err_debug:
605 ath9k_hw_deinit(ah);
606err_hw:
607 tasklet_kill(&sc->intr_tq);
608 tasklet_kill(&sc->bcon_tasklet);
609
610 kfree(ah);
611 sc->sc_ah = NULL;
612
613 return ret;
614}
615
616void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
617{
618 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
619
620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
622 IEEE80211_HW_SIGNAL_DBM |
623 IEEE80211_HW_SUPPORTS_PS |
624 IEEE80211_HW_PS_NULLFUNC_STACK |
625 IEEE80211_HW_SPECTRUM_MGMT |
626 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
627
628 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
629 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
630
631 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
632 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
633
634 hw->wiphy->interface_modes =
635 BIT(NL80211_IFTYPE_AP) |
636 BIT(NL80211_IFTYPE_STATION) |
637 BIT(NL80211_IFTYPE_ADHOC) |
638 BIT(NL80211_IFTYPE_MESH_POINT);
639
640 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
641
642 hw->queues = 4;
643 hw->max_rates = 4;
644 hw->channel_change_time = 5000;
645 hw->max_listen_interval = 10;
646 hw->max_rate_tries = 10;
647 hw->sta_data_size = sizeof(struct ath_node);
648 hw->vif_data_size = sizeof(struct ath_vif);
649
650 hw->rate_control_algorithm = "ath9k_rate_control";
651
652 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
653 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
654 &sc->sbands[IEEE80211_BAND_2GHZ];
655 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
656 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
657 &sc->sbands[IEEE80211_BAND_5GHZ];
658
659 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
660 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
661 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
662 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
663 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
664 }
665
666 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
667}
668
669int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
670 const struct ath_bus_ops *bus_ops)
671{
672 struct ieee80211_hw *hw = sc->hw;
673 struct ath_common *common;
674 struct ath_hw *ah;
675 int error = 0;
676 struct ath_regulatory *reg;
677
678 /* Bring up device */
679 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
680 if (error != 0)
681 goto error_init;
682
683 ah = sc->sc_ah;
684 common = ath9k_hw_common(ah);
685 ath9k_set_hw_capab(sc, hw);
686
687 /* Initialize regulatory */
688 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
689 ath9k_reg_notifier);
690 if (error)
691 goto error_regd;
692
693 reg = &common->regulatory;
694
695 /* Setup TX DMA */
696 error = ath_tx_init(sc, ATH_TXBUF);
697 if (error != 0)
698 goto error_tx;
699
700 /* Setup RX DMA */
701 error = ath_rx_init(sc, ATH_RXBUF);
702 if (error != 0)
703 goto error_rx;
704
705 /* Register with mac80211 */
706 error = ieee80211_register_hw(hw);
707 if (error)
708 goto error_register;
709
710 /* Handle world regulatory */
711 if (!ath_is_world_regd(reg)) {
712 error = regulatory_hint(hw->wiphy, reg->alpha2);
713 if (error)
714 goto error_world;
715 }
716
717 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
718 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
719 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
720
721 ath_init_leds(sc);
722 ath_start_rfkill_poll(sc);
723
724 return 0;
725
726error_world:
727 ieee80211_unregister_hw(hw);
728error_register:
729 ath_rx_cleanup(sc);
730error_rx:
731 ath_tx_cleanup(sc);
732error_tx:
733 /* Nothing */
734error_regd:
735 ath9k_deinit_softc(sc);
736error_init:
737 return error;
738}
739
740/*****************************/
741/* De-Initialization */
742/*****************************/
743
744static void ath9k_deinit_softc(struct ath_softc *sc)
745{
746 int i = 0;
747
748 if ((sc->btcoex.no_stomp_timer) &&
749 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
750 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
751
752 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
753 if (ATH_TXQ_SETUP(sc, i))
754 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
755
756 ath9k_exit_debug(sc->sc_ah);
757 ath9k_hw_deinit(sc->sc_ah);
758
759 tasklet_kill(&sc->intr_tq);
760 tasklet_kill(&sc->bcon_tasklet);
761}
762
763void ath9k_deinit_device(struct ath_softc *sc)
764{
765 struct ieee80211_hw *hw = sc->hw;
766 int i = 0;
767
768 ath9k_ps_wakeup(sc);
769
770 wiphy_rfkill_stop_polling(sc->hw->wiphy);
771 ath_deinit_leds(sc);
772
773 for (i = 0; i < sc->num_sec_wiphy; i++) {
774 struct ath_wiphy *aphy = sc->sec_wiphy[i];
775 if (aphy == NULL)
776 continue;
777 sc->sec_wiphy[i] = NULL;
778 ieee80211_unregister_hw(aphy->hw);
779 ieee80211_free_hw(aphy->hw);
780 }
781 kfree(sc->sec_wiphy);
782
783 ieee80211_unregister_hw(hw);
784 ath_rx_cleanup(sc);
785 ath_tx_cleanup(sc);
786 ath9k_deinit_softc(sc);
787}
788
789void ath_descdma_cleanup(struct ath_softc *sc,
790 struct ath_descdma *dd,
791 struct list_head *head)
792{
793 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
794 dd->dd_desc_paddr);
795
796 INIT_LIST_HEAD(head);
797 kfree(dd->dd_bufptr);
798 memset(dd, 0, sizeof(*dd));
799}
800
801/************************/
802/* Module Hooks */
803/************************/
804
805static int __init ath9k_init(void)
806{
807 int error;
808
809 /* Register rate control algorithm */
810 error = ath_rate_control_register();
811 if (error != 0) {
812 printk(KERN_ERR
813 "ath9k: Unable to register rate control "
814 "algorithm: %d\n",
815 error);
816 goto err_out;
817 }
818
819 error = ath9k_debug_create_root();
820 if (error) {
821 printk(KERN_ERR
822 "ath9k: Unable to create debugfs root: %d\n",
823 error);
824 goto err_rate_unregister;
825 }
826
827 error = ath_pci_init();
828 if (error < 0) {
829 printk(KERN_ERR
830 "ath9k: No PCI devices found, driver not installed.\n");
831 error = -ENODEV;
832 goto err_remove_root;
833 }
834
835 error = ath_ahb_init();
836 if (error < 0) {
837 error = -ENODEV;
838 goto err_pci_exit;
839 }
840
841 return 0;
842
843 err_pci_exit:
844 ath_pci_exit();
845
846 err_remove_root:
847 ath9k_debug_remove_root();
848 err_rate_unregister:
849 ath_rate_control_unregister();
850 err_out:
851 return error;
852}
853module_init(ath9k_init);
854
855static void __exit ath9k_exit(void)
856{
857 ath_ahb_exit();
858 ath_pci_exit();
859 ath9k_debug_remove_root();
860 ath_rate_control_unregister();
861 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
862}
863module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index e185479e295e..29851e6376a9 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -167,6 +167,40 @@ struct ath_rx_status {
167#define ATH9K_RXKEYIX_INVALID ((u8)-1) 167#define ATH9K_RXKEYIX_INVALID ((u8)-1)
168#define ATH9K_TXKEYIX_INVALID ((u32)-1) 168#define ATH9K_TXKEYIX_INVALID ((u32)-1)
169 169
170enum ath9k_phyerr {
171 ATH9K_PHYERR_UNDERRUN = 0, /* Transmit underrun */
172 ATH9K_PHYERR_TIMING = 1, /* Timing error */
173 ATH9K_PHYERR_PARITY = 2, /* Illegal parity */
174 ATH9K_PHYERR_RATE = 3, /* Illegal rate */
175 ATH9K_PHYERR_LENGTH = 4, /* Illegal length */
176 ATH9K_PHYERR_RADAR = 5, /* Radar detect */
177 ATH9K_PHYERR_SERVICE = 6, /* Illegal service */
178 ATH9K_PHYERR_TOR = 7, /* Transmit override receive */
179
180 ATH9K_PHYERR_OFDM_TIMING = 17,
181 ATH9K_PHYERR_OFDM_SIGNAL_PARITY = 18,
182 ATH9K_PHYERR_OFDM_RATE_ILLEGAL = 19,
183 ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL = 20,
184 ATH9K_PHYERR_OFDM_POWER_DROP = 21,
185 ATH9K_PHYERR_OFDM_SERVICE = 22,
186 ATH9K_PHYERR_OFDM_RESTART = 23,
187 ATH9K_PHYERR_FALSE_RADAR_EXT = 24,
188
189 ATH9K_PHYERR_CCK_TIMING = 25,
190 ATH9K_PHYERR_CCK_HEADER_CRC = 26,
191 ATH9K_PHYERR_CCK_RATE_ILLEGAL = 27,
192 ATH9K_PHYERR_CCK_SERVICE = 30,
193 ATH9K_PHYERR_CCK_RESTART = 31,
194 ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 32,
195 ATH9K_PHYERR_CCK_POWER_DROP = 33,
196
197 ATH9K_PHYERR_HT_CRC_ERROR = 34,
198 ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35,
199 ATH9K_PHYERR_HT_RATE_ILLEGAL = 36,
200
201 ATH9K_PHYERR_MAX = 37,
202};
203
170struct ath_desc { 204struct ath_desc {
171 u32 ds_link; 205 u32 ds_link;
172 u32 ds_data; 206 u32 ds_data;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 643bea35686f..67ca4e5a6017 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -18,118 +18,6 @@
18#include "ath9k.h" 18#include "ath9k.h"
19#include "btcoex.h" 19#include "btcoex.h"
20 20
21static char *dev_info = "ath9k";
22
23MODULE_AUTHOR("Atheros Communications");
24MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
25MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
26MODULE_LICENSE("Dual BSD/GPL");
27
28static int modparam_nohwcrypt;
29module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
30MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
31
32static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
33module_param_named(debug, ath9k_debug, uint, 0);
34MODULE_PARM_DESC(debug, "Debugging mask");
35
36/* We use the hw_value as an index into our private channel structure */
37
38#define CHAN2G(_freq, _idx) { \
39 .center_freq = (_freq), \
40 .hw_value = (_idx), \
41 .max_power = 20, \
42}
43
44#define CHAN5G(_freq, _idx) { \
45 .band = IEEE80211_BAND_5GHZ, \
46 .center_freq = (_freq), \
47 .hw_value = (_idx), \
48 .max_power = 20, \
49}
50
51/* Some 2 GHz radios are actually tunable on 2312-2732
52 * on 5 MHz steps, we support the channels which we know
53 * we have calibration data for all cards though to make
54 * this static */
55static struct ieee80211_channel ath9k_2ghz_chantable[] = {
56 CHAN2G(2412, 0), /* Channel 1 */
57 CHAN2G(2417, 1), /* Channel 2 */
58 CHAN2G(2422, 2), /* Channel 3 */
59 CHAN2G(2427, 3), /* Channel 4 */
60 CHAN2G(2432, 4), /* Channel 5 */
61 CHAN2G(2437, 5), /* Channel 6 */
62 CHAN2G(2442, 6), /* Channel 7 */
63 CHAN2G(2447, 7), /* Channel 8 */
64 CHAN2G(2452, 8), /* Channel 9 */
65 CHAN2G(2457, 9), /* Channel 10 */
66 CHAN2G(2462, 10), /* Channel 11 */
67 CHAN2G(2467, 11), /* Channel 12 */
68 CHAN2G(2472, 12), /* Channel 13 */
69 CHAN2G(2484, 13), /* Channel 14 */
70};
71
72/* Some 5 GHz radios are actually tunable on XXXX-YYYY
73 * on 5 MHz steps, we support the channels which we know
74 * we have calibration data for all cards though to make
75 * this static */
76static struct ieee80211_channel ath9k_5ghz_chantable[] = {
77 /* _We_ call this UNII 1 */
78 CHAN5G(5180, 14), /* Channel 36 */
79 CHAN5G(5200, 15), /* Channel 40 */
80 CHAN5G(5220, 16), /* Channel 44 */
81 CHAN5G(5240, 17), /* Channel 48 */
82 /* _We_ call this UNII 2 */
83 CHAN5G(5260, 18), /* Channel 52 */
84 CHAN5G(5280, 19), /* Channel 56 */
85 CHAN5G(5300, 20), /* Channel 60 */
86 CHAN5G(5320, 21), /* Channel 64 */
87 /* _We_ call this "Middle band" */
88 CHAN5G(5500, 22), /* Channel 100 */
89 CHAN5G(5520, 23), /* Channel 104 */
90 CHAN5G(5540, 24), /* Channel 108 */
91 CHAN5G(5560, 25), /* Channel 112 */
92 CHAN5G(5580, 26), /* Channel 116 */
93 CHAN5G(5600, 27), /* Channel 120 */
94 CHAN5G(5620, 28), /* Channel 124 */
95 CHAN5G(5640, 29), /* Channel 128 */
96 CHAN5G(5660, 30), /* Channel 132 */
97 CHAN5G(5680, 31), /* Channel 136 */
98 CHAN5G(5700, 32), /* Channel 140 */
99 /* _We_ call this UNII 3 */
100 CHAN5G(5745, 33), /* Channel 149 */
101 CHAN5G(5765, 34), /* Channel 153 */
102 CHAN5G(5785, 35), /* Channel 157 */
103 CHAN5G(5805, 36), /* Channel 161 */
104 CHAN5G(5825, 37), /* Channel 165 */
105};
106
107/* Atheros hardware rate code addition for short premble */
108#define SHPCHECK(__hw_rate, __flags) \
109 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
110
111#define RATE(_bitrate, _hw_rate, _flags) { \
112 .bitrate = (_bitrate), \
113 .flags = (_flags), \
114 .hw_value = (_hw_rate), \
115 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
116}
117
118static struct ieee80211_rate ath9k_legacy_rates[] = {
119 RATE(10, 0x1b, 0),
120 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
122 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
123 RATE(60, 0x0b, 0),
124 RATE(90, 0x0f, 0),
125 RATE(120, 0x0a, 0),
126 RATE(180, 0x0e, 0),
127 RATE(240, 0x09, 0),
128 RATE(360, 0x0d, 0),
129 RATE(480, 0x08, 0),
130 RATE(540, 0x0c, 0),
131};
132
133static void ath_cache_conf_rate(struct ath_softc *sc, 21static void ath_cache_conf_rate(struct ath_softc *sc,
134 struct ieee80211_conf *conf) 22 struct ieee80211_conf *conf)
135{ 23{
@@ -221,7 +109,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
221 return channel; 109 return channel;
222} 110}
223 111
224static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) 112bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
225{ 113{
226 unsigned long flags; 114 unsigned long flags;
227 bool ret; 115 bool ret;
@@ -255,11 +143,13 @@ void ath9k_ps_restore(struct ath_softc *sc)
255 if (--sc->ps_usecount != 0) 143 if (--sc->ps_usecount != 0)
256 goto unlock; 144 goto unlock;
257 145
258 if (sc->ps_enabled && 146 if (sc->ps_idle)
259 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 147 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
260 SC_OP_WAIT_FOR_CAB | 148 else if (sc->ps_enabled &&
261 SC_OP_WAIT_FOR_PSPOLL_DATA | 149 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
262 SC_OP_WAIT_FOR_TX_ACK))) 150 PS_WAIT_FOR_CAB |
151 PS_WAIT_FOR_PSPOLL_DATA |
152 PS_WAIT_FOR_TX_ACK)))
263 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); 153 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
264 154
265 unlock: 155 unlock:
@@ -316,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
316 r = ath9k_hw_reset(ah, hchan, fastcc); 206 r = ath9k_hw_reset(ah, hchan, fastcc);
317 if (r) { 207 if (r) {
318 ath_print(common, ATH_DBG_FATAL, 208 ath_print(common, ATH_DBG_FATAL,
319 "Unable to reset channel (%u Mhz) " 209 "Unable to reset channel (%u MHz), "
320 "reset status %d\n", 210 "reset status %d\n",
321 channel->center_freq, r); 211 channel->center_freq, r);
322 spin_unlock_bh(&sc->sc_resetlock); 212 spin_unlock_bh(&sc->sc_resetlock);
@@ -349,7 +239,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
349 * When the task is complete, it reschedules itself depending on the 239 * When the task is complete, it reschedules itself depending on the
350 * appropriate interval that was calculated. 240 * appropriate interval that was calculated.
351 */ 241 */
352static void ath_ani_calibrate(unsigned long data) 242void ath_ani_calibrate(unsigned long data)
353{ 243{
354 struct ath_softc *sc = (struct ath_softc *)data; 244 struct ath_softc *sc = (struct ath_softc *)data;
355 struct ath_hw *ah = sc->sc_ah; 245 struct ath_hw *ah = sc->sc_ah;
@@ -363,14 +253,6 @@ static void ath_ani_calibrate(unsigned long data)
363 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? 253 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
364 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; 254 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
365 255
366 /*
367 * don't calibrate when we're scanning.
368 * we are most likely not on our home channel.
369 */
370 spin_lock(&sc->ani_lock);
371 if (sc->sc_flags & SC_OP_SCANNING)
372 goto set_timer;
373
374 /* Only calibrate if awake */ 256 /* Only calibrate if awake */
375 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) 257 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
376 goto set_timer; 258 goto set_timer;
@@ -437,7 +319,6 @@ static void ath_ani_calibrate(unsigned long data)
437 ath9k_ps_restore(sc); 319 ath9k_ps_restore(sc);
438 320
439set_timer: 321set_timer:
440 spin_unlock(&sc->ani_lock);
441 /* 322 /*
442 * Set timer interval based on previous results. 323 * Set timer interval based on previous results.
443 * The interval must be the shortest necessary to satisfy ANI, 324 * The interval must be the shortest necessary to satisfy ANI,
@@ -513,7 +394,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
513 ath_tx_node_cleanup(sc, an); 394 ath_tx_node_cleanup(sc, an);
514} 395}
515 396
516static void ath9k_tasklet(unsigned long data) 397void ath9k_tasklet(unsigned long data)
517{ 398{
518 struct ath_softc *sc = (struct ath_softc *)data; 399 struct ath_softc *sc = (struct ath_softc *)data;
519 struct ath_hw *ah = sc->sc_ah; 400 struct ath_hw *ah = sc->sc_ah;
@@ -545,7 +426,7 @@ static void ath9k_tasklet(unsigned long data)
545 */ 426 */
546 ath_print(common, ATH_DBG_PS, 427 ath_print(common, ATH_DBG_PS,
547 "TSFOOR - Sync with next Beacon\n"); 428 "TSFOOR - Sync with next Beacon\n");
548 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; 429 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
549 } 430 }
550 431
551 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 432 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -646,7 +527,7 @@ irqreturn_t ath_isr(int irq, void *dev)
646 * receive frames */ 527 * receive frames */
647 ath9k_setpower(sc, ATH9K_PM_AWAKE); 528 ath9k_setpower(sc, ATH9K_PM_AWAKE);
648 ath9k_hw_setrxabort(sc->sc_ah, 0); 529 ath9k_hw_setrxabort(sc->sc_ah, 0);
649 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; 530 sc->ps_flags |= PS_WAIT_FOR_BEACON;
650 } 531 }
651 532
652chip_reset: 533chip_reset:
@@ -928,49 +809,12 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf
928 809
929 clear_bit(key->hw_key_idx + 64, common->keymap); 810 clear_bit(key->hw_key_idx + 64, common->keymap);
930 if (common->splitmic) { 811 if (common->splitmic) {
812 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
931 clear_bit(key->hw_key_idx + 32, common->keymap); 813 clear_bit(key->hw_key_idx + 32, common->keymap);
932 clear_bit(key->hw_key_idx + 64 + 32, common->keymap); 814 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
933 } 815 }
934} 816}
935 817
936static void setup_ht_cap(struct ath_softc *sc,
937 struct ieee80211_sta_ht_cap *ht_info)
938{
939 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
940 u8 tx_streams, rx_streams;
941
942 ht_info->ht_supported = true;
943 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
944 IEEE80211_HT_CAP_SM_PS |
945 IEEE80211_HT_CAP_SGI_40 |
946 IEEE80211_HT_CAP_DSSSCCK40;
947
948 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
949 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
950
951 /* set up supported mcs set */
952 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
953 tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
954 1 : 2;
955 rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
956 1 : 2;
957
958 if (tx_streams != rx_streams) {
959 ath_print(common, ATH_DBG_CONFIG,
960 "TX streams %d, RX streams: %d\n",
961 tx_streams, rx_streams);
962 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
963 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
964 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
965 }
966
967 ht_info->mcs.rx_mask[0] = 0xff;
968 if (rx_streams >= 2)
969 ht_info->mcs.rx_mask[1] = 0xff;
970
971 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
972}
973
974static void ath9k_bss_assoc_info(struct ath_softc *sc, 818static void ath9k_bss_assoc_info(struct ath_softc *sc,
975 struct ieee80211_vif *vif, 819 struct ieee80211_vif *vif,
976 struct ieee80211_bss_conf *bss_conf) 820 struct ieee80211_bss_conf *bss_conf)
@@ -992,7 +836,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
992 * on the receipt of the first Beacon frame (i.e., 836 * on the receipt of the first Beacon frame (i.e.,
993 * after time sync with the AP). 837 * after time sync with the AP).
994 */ 838 */
995 sc->sc_flags |= SC_OP_BEACON_SYNC; 839 sc->ps_flags |= PS_BEACON_SYNC;
996 840
997 /* Configure the beacon */ 841 /* Configure the beacon */
998 ath_beacon_config(sc, vif); 842 ath_beacon_config(sc, vif);
@@ -1009,174 +853,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
1009 } 853 }
1010} 854}
1011 855
1012/********************************/
1013/* LED functions */
1014/********************************/
1015
1016static void ath_led_blink_work(struct work_struct *work)
1017{
1018 struct ath_softc *sc = container_of(work, struct ath_softc,
1019 ath_led_blink_work.work);
1020
1021 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
1022 return;
1023
1024 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
1025 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
1026 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
1027 else
1028 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
1029 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
1030
1031 ieee80211_queue_delayed_work(sc->hw,
1032 &sc->ath_led_blink_work,
1033 (sc->sc_flags & SC_OP_LED_ON) ?
1034 msecs_to_jiffies(sc->led_off_duration) :
1035 msecs_to_jiffies(sc->led_on_duration));
1036
1037 sc->led_on_duration = sc->led_on_cnt ?
1038 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
1039 ATH_LED_ON_DURATION_IDLE;
1040 sc->led_off_duration = sc->led_off_cnt ?
1041 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
1042 ATH_LED_OFF_DURATION_IDLE;
1043 sc->led_on_cnt = sc->led_off_cnt = 0;
1044 if (sc->sc_flags & SC_OP_LED_ON)
1045 sc->sc_flags &= ~SC_OP_LED_ON;
1046 else
1047 sc->sc_flags |= SC_OP_LED_ON;
1048}
1049
1050static void ath_led_brightness(struct led_classdev *led_cdev,
1051 enum led_brightness brightness)
1052{
1053 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
1054 struct ath_softc *sc = led->sc;
1055
1056 switch (brightness) {
1057 case LED_OFF:
1058 if (led->led_type == ATH_LED_ASSOC ||
1059 led->led_type == ATH_LED_RADIO) {
1060 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
1061 (led->led_type == ATH_LED_RADIO));
1062 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1063 if (led->led_type == ATH_LED_RADIO)
1064 sc->sc_flags &= ~SC_OP_LED_ON;
1065 } else {
1066 sc->led_off_cnt++;
1067 }
1068 break;
1069 case LED_FULL:
1070 if (led->led_type == ATH_LED_ASSOC) {
1071 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
1072 ieee80211_queue_delayed_work(sc->hw,
1073 &sc->ath_led_blink_work, 0);
1074 } else if (led->led_type == ATH_LED_RADIO) {
1075 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
1076 sc->sc_flags |= SC_OP_LED_ON;
1077 } else {
1078 sc->led_on_cnt++;
1079 }
1080 break;
1081 default:
1082 break;
1083 }
1084}
1085
1086static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
1087 char *trigger)
1088{
1089 int ret;
1090
1091 led->sc = sc;
1092 led->led_cdev.name = led->name;
1093 led->led_cdev.default_trigger = trigger;
1094 led->led_cdev.brightness_set = ath_led_brightness;
1095
1096 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
1097 if (ret)
1098 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1099 "Failed to register led:%s", led->name);
1100 else
1101 led->registered = 1;
1102 return ret;
1103}
1104
1105static void ath_unregister_led(struct ath_led *led)
1106{
1107 if (led->registered) {
1108 led_classdev_unregister(&led->led_cdev);
1109 led->registered = 0;
1110 }
1111}
1112
1113static void ath_deinit_leds(struct ath_softc *sc)
1114{
1115 ath_unregister_led(&sc->assoc_led);
1116 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1117 ath_unregister_led(&sc->tx_led);
1118 ath_unregister_led(&sc->rx_led);
1119 ath_unregister_led(&sc->radio_led);
1120 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1121}
1122
1123static void ath_init_leds(struct ath_softc *sc)
1124{
1125 char *trigger;
1126 int ret;
1127
1128 if (AR_SREV_9287(sc->sc_ah))
1129 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
1130 else
1131 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
1132
1133 /* Configure gpio 1 for output */
1134 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
1135 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1136 /* LED off, active low */
1137 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1138
1139 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
1140
1141 trigger = ieee80211_get_radio_led_name(sc->hw);
1142 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
1143 "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
1144 ret = ath_register_led(sc, &sc->radio_led, trigger);
1145 sc->radio_led.led_type = ATH_LED_RADIO;
1146 if (ret)
1147 goto fail;
1148
1149 trigger = ieee80211_get_assoc_led_name(sc->hw);
1150 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
1151 "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
1152 ret = ath_register_led(sc, &sc->assoc_led, trigger);
1153 sc->assoc_led.led_type = ATH_LED_ASSOC;
1154 if (ret)
1155 goto fail;
1156
1157 trigger = ieee80211_get_tx_led_name(sc->hw);
1158 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
1159 "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
1160 ret = ath_register_led(sc, &sc->tx_led, trigger);
1161 sc->tx_led.led_type = ATH_LED_TX;
1162 if (ret)
1163 goto fail;
1164
1165 trigger = ieee80211_get_rx_led_name(sc->hw);
1166 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
1167 "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
1168 ret = ath_register_led(sc, &sc->rx_led, trigger);
1169 sc->rx_led.led_type = ATH_LED_RX;
1170 if (ret)
1171 goto fail;
1172
1173 return;
1174
1175fail:
1176 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1177 ath_deinit_leds(sc);
1178}
1179
1180void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) 856void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
1181{ 857{
1182 struct ath_hw *ah = sc->sc_ah; 858 struct ath_hw *ah = sc->sc_ah;
@@ -1194,7 +870,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
1194 r = ath9k_hw_reset(ah, ah->curchan, false); 870 r = ath9k_hw_reset(ah, ah->curchan, false);
1195 if (r) { 871 if (r) {
1196 ath_print(common, ATH_DBG_FATAL, 872 ath_print(common, ATH_DBG_FATAL,
1197 "Unable to reset channel %u (%uMhz) ", 873 "Unable to reset channel (%u MHz), "
1198 "reset status %d\n", 874 "reset status %d\n",
1199 channel->center_freq, r); 875 channel->center_freq, r);
1200 } 876 }
@@ -1249,7 +925,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
1249 r = ath9k_hw_reset(ah, ah->curchan, false); 925 r = ath9k_hw_reset(ah, ah->curchan, false);
1250 if (r) { 926 if (r) {
1251 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 927 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1252 "Unable to reset channel %u (%uMhz) " 928 "Unable to reset channel (%u MHz), "
1253 "reset status %d\n", 929 "reset status %d\n",
1254 channel->center_freq, r); 930 channel->center_freq, r);
1255 } 931 }
@@ -1261,711 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
1261 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); 937 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
1262} 938}
1263 939
1264/*******************/
1265/* Rfkill */
1266/*******************/
1267
1268static bool ath_is_rfkill_set(struct ath_softc *sc)
1269{
1270 struct ath_hw *ah = sc->sc_ah;
1271
1272 return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
1273 ah->rfkill_polarity;
1274}
1275
1276static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
1277{
1278 struct ath_wiphy *aphy = hw->priv;
1279 struct ath_softc *sc = aphy->sc;
1280 bool blocked = !!ath_is_rfkill_set(sc);
1281
1282 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1283}
1284
1285static void ath_start_rfkill_poll(struct ath_softc *sc)
1286{
1287 struct ath_hw *ah = sc->sc_ah;
1288
1289 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1290 wiphy_rfkill_start_polling(sc->hw->wiphy);
1291}
1292
1293static void ath9k_uninit_hw(struct ath_softc *sc)
1294{
1295 struct ath_hw *ah = sc->sc_ah;
1296
1297 BUG_ON(!ah);
1298
1299 ath9k_exit_debug(ah);
1300 ath9k_hw_detach(ah);
1301 sc->sc_ah = NULL;
1302}
1303
1304static void ath_clean_core(struct ath_softc *sc)
1305{
1306 struct ieee80211_hw *hw = sc->hw;
1307 struct ath_hw *ah = sc->sc_ah;
1308 int i = 0;
1309
1310 ath9k_ps_wakeup(sc);
1311
1312 dev_dbg(sc->dev, "Detach ATH hw\n");
1313
1314 ath_deinit_leds(sc);
1315 wiphy_rfkill_stop_polling(sc->hw->wiphy);
1316
1317 for (i = 0; i < sc->num_sec_wiphy; i++) {
1318 struct ath_wiphy *aphy = sc->sec_wiphy[i];
1319 if (aphy == NULL)
1320 continue;
1321 sc->sec_wiphy[i] = NULL;
1322 ieee80211_unregister_hw(aphy->hw);
1323 ieee80211_free_hw(aphy->hw);
1324 }
1325 ieee80211_unregister_hw(hw);
1326 ath_rx_cleanup(sc);
1327 ath_tx_cleanup(sc);
1328
1329 tasklet_kill(&sc->intr_tq);
1330 tasklet_kill(&sc->bcon_tasklet);
1331
1332 if (!(sc->sc_flags & SC_OP_INVALID))
1333 ath9k_setpower(sc, ATH9K_PM_AWAKE);
1334
1335 /* cleanup tx queues */
1336 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1337 if (ATH_TXQ_SETUP(sc, i))
1338 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1339
1340 if ((sc->btcoex.no_stomp_timer) &&
1341 ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1342 ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
1343}
1344
1345void ath_detach(struct ath_softc *sc)
1346{
1347 ath_clean_core(sc);
1348 ath9k_uninit_hw(sc);
1349}
1350
1351void ath_cleanup(struct ath_softc *sc)
1352{
1353 struct ath_hw *ah = sc->sc_ah;
1354 struct ath_common *common = ath9k_hw_common(ah);
1355
1356 ath_clean_core(sc);
1357 free_irq(sc->irq, sc);
1358 ath_bus_cleanup(common);
1359 kfree(sc->sec_wiphy);
1360 ieee80211_free_hw(sc->hw);
1361
1362 ath9k_uninit_hw(sc);
1363}
1364
1365static int ath9k_reg_notifier(struct wiphy *wiphy,
1366 struct regulatory_request *request)
1367{
1368 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1369 struct ath_wiphy *aphy = hw->priv;
1370 struct ath_softc *sc = aphy->sc;
1371 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
1372
1373 return ath_reg_notifier_apply(wiphy, request, reg);
1374}
1375
1376/*
1377 * Detects if there is any priority bt traffic
1378 */
1379static void ath_detect_bt_priority(struct ath_softc *sc)
1380{
1381 struct ath_btcoex *btcoex = &sc->btcoex;
1382 struct ath_hw *ah = sc->sc_ah;
1383
1384 if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
1385 btcoex->bt_priority_cnt++;
1386
1387 if (time_after(jiffies, btcoex->bt_priority_time +
1388 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
1389 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
1390 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
1391 "BT priority traffic detected");
1392 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
1393 } else {
1394 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
1395 }
1396
1397 btcoex->bt_priority_cnt = 0;
1398 btcoex->bt_priority_time = jiffies;
1399 }
1400}
1401
1402/*
1403 * Configures appropriate weight based on stomp type.
1404 */
1405static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
1406 enum ath_stomp_type stomp_type)
1407{
1408 struct ath_hw *ah = sc->sc_ah;
1409
1410 switch (stomp_type) {
1411 case ATH_BTCOEX_STOMP_ALL:
1412 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1413 AR_STOMP_ALL_WLAN_WGHT);
1414 break;
1415 case ATH_BTCOEX_STOMP_LOW:
1416 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1417 AR_STOMP_LOW_WLAN_WGHT);
1418 break;
1419 case ATH_BTCOEX_STOMP_NONE:
1420 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1421 AR_STOMP_NONE_WLAN_WGHT);
1422 break;
1423 default:
1424 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
1425 "Invalid Stomptype\n");
1426 break;
1427 }
1428
1429 ath9k_hw_btcoex_enable(ah);
1430}
1431
1432static void ath9k_gen_timer_start(struct ath_hw *ah,
1433 struct ath_gen_timer *timer,
1434 u32 timer_next,
1435 u32 timer_period)
1436{
1437 struct ath_common *common = ath9k_hw_common(ah);
1438 struct ath_softc *sc = (struct ath_softc *) common->priv;
1439
1440 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
1441
1442 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
1443 ath9k_hw_set_interrupts(ah, 0);
1444 sc->imask |= ATH9K_INT_GENTIMER;
1445 ath9k_hw_set_interrupts(ah, sc->imask);
1446 }
1447}
1448
1449static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
1450{
1451 struct ath_common *common = ath9k_hw_common(ah);
1452 struct ath_softc *sc = (struct ath_softc *) common->priv;
1453 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
1454
1455 ath9k_hw_gen_timer_stop(ah, timer);
1456
1457 /* if no timer is enabled, turn off interrupt mask */
1458 if (timer_table->timer_mask.val == 0) {
1459 ath9k_hw_set_interrupts(ah, 0);
1460 sc->imask &= ~ATH9K_INT_GENTIMER;
1461 ath9k_hw_set_interrupts(ah, sc->imask);
1462 }
1463}
1464
1465/*
1466 * This is the master bt coex timer which runs for every
1467 * 45ms, bt traffic will be given priority during 55% of this
1468 * period while wlan gets remaining 45%
1469 */
1470static void ath_btcoex_period_timer(unsigned long data)
1471{
1472 struct ath_softc *sc = (struct ath_softc *) data;
1473 struct ath_hw *ah = sc->sc_ah;
1474 struct ath_btcoex *btcoex = &sc->btcoex;
1475
1476 ath_detect_bt_priority(sc);
1477
1478 spin_lock_bh(&btcoex->btcoex_lock);
1479
1480 ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
1481
1482 spin_unlock_bh(&btcoex->btcoex_lock);
1483
1484 if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
1485 if (btcoex->hw_timer_enabled)
1486 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
1487
1488 ath9k_gen_timer_start(ah,
1489 btcoex->no_stomp_timer,
1490 (ath9k_hw_gettsf32(ah) +
1491 btcoex->btcoex_no_stomp),
1492 btcoex->btcoex_no_stomp * 10);
1493 btcoex->hw_timer_enabled = true;
1494 }
1495
1496 mod_timer(&btcoex->period_timer, jiffies +
1497 msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
1498}
1499
1500/*
1501 * Generic tsf based hw timer which configures weight
1502 * registers to time slice between wlan and bt traffic
1503 */
1504static void ath_btcoex_no_stomp_timer(void *arg)
1505{
1506 struct ath_softc *sc = (struct ath_softc *)arg;
1507 struct ath_hw *ah = sc->sc_ah;
1508 struct ath_btcoex *btcoex = &sc->btcoex;
1509
1510 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
1511 "no stomp timer running \n");
1512
1513 spin_lock_bh(&btcoex->btcoex_lock);
1514
1515 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
1516 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
1517 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
1518 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
1519
1520 spin_unlock_bh(&btcoex->btcoex_lock);
1521}
1522
1523static int ath_init_btcoex_timer(struct ath_softc *sc)
1524{
1525 struct ath_btcoex *btcoex = &sc->btcoex;
1526
1527 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
1528 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
1529 btcoex->btcoex_period / 100;
1530
1531 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
1532 (unsigned long) sc);
1533
1534 spin_lock_init(&btcoex->btcoex_lock);
1535
1536 btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
1537 ath_btcoex_no_stomp_timer,
1538 ath_btcoex_no_stomp_timer,
1539 (void *) sc, AR_FIRST_NDP_TIMER);
1540
1541 if (!btcoex->no_stomp_timer)
1542 return -ENOMEM;
1543
1544 return 0;
1545}
1546
1547/*
1548 * Read and write, they both share the same lock. We do this to serialize
1549 * reads and writes on Atheros 802.11n PCI devices only. This is required
1550 * as the FIFO on these devices can only accept sanely 2 requests. After
1551 * that the device goes bananas. Serializing the reads/writes prevents this
1552 * from happening.
1553 */
1554
1555static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
1556{
1557 struct ath_hw *ah = (struct ath_hw *) hw_priv;
1558 struct ath_common *common = ath9k_hw_common(ah);
1559 struct ath_softc *sc = (struct ath_softc *) common->priv;
1560
1561 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
1562 unsigned long flags;
1563 spin_lock_irqsave(&sc->sc_serial_rw, flags);
1564 iowrite32(val, sc->mem + reg_offset);
1565 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
1566 } else
1567 iowrite32(val, sc->mem + reg_offset);
1568}
1569
1570static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
1571{
1572 struct ath_hw *ah = (struct ath_hw *) hw_priv;
1573 struct ath_common *common = ath9k_hw_common(ah);
1574 struct ath_softc *sc = (struct ath_softc *) common->priv;
1575 u32 val;
1576
1577 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
1578 unsigned long flags;
1579 spin_lock_irqsave(&sc->sc_serial_rw, flags);
1580 val = ioread32(sc->mem + reg_offset);
1581 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
1582 } else
1583 val = ioread32(sc->mem + reg_offset);
1584 return val;
1585}
1586
1587static const struct ath_ops ath9k_common_ops = {
1588 .read = ath9k_ioread32,
1589 .write = ath9k_iowrite32,
1590};
1591
1592/*
1593 * Initialize and fill ath_softc, ath_sofct is the
1594 * "Software Carrier" struct. Historically it has existed
1595 * to allow the separation between hardware specific
1596 * variables (now in ath_hw) and driver specific variables.
1597 */
1598static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1599 const struct ath_bus_ops *bus_ops)
1600{
1601 struct ath_hw *ah = NULL;
1602 struct ath_common *common;
1603 int r = 0, i;
1604 int csz = 0;
1605 int qnum;
1606
1607 /* XXX: hardware will not be ready until ath_open() being called */
1608 sc->sc_flags |= SC_OP_INVALID;
1609
1610 spin_lock_init(&sc->wiphy_lock);
1611 spin_lock_init(&sc->sc_resetlock);
1612 spin_lock_init(&sc->sc_serial_rw);
1613 spin_lock_init(&sc->ani_lock);
1614 spin_lock_init(&sc->sc_pm_lock);
1615 mutex_init(&sc->mutex);
1616 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1617 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
1618 (unsigned long)sc);
1619
1620 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
1621 if (!ah)
1622 return -ENOMEM;
1623
1624 ah->hw_version.devid = devid;
1625 ah->hw_version.subsysid = subsysid;
1626 sc->sc_ah = ah;
1627
1628 common = ath9k_hw_common(ah);
1629 common->ops = &ath9k_common_ops;
1630 common->bus_ops = bus_ops;
1631 common->ah = ah;
1632 common->hw = sc->hw;
1633 common->priv = sc;
1634 common->debug_mask = ath9k_debug;
1635
1636 /*
1637 * Cache line size is used to size and align various
1638 * structures used to communicate with the hardware.
1639 */
1640 ath_read_cachesize(common, &csz);
1641 /* XXX assert csz is non-zero */
1642 common->cachelsz = csz << 2; /* convert to bytes */
1643
1644 r = ath9k_hw_init(ah);
1645 if (r) {
1646 ath_print(common, ATH_DBG_FATAL,
1647 "Unable to initialize hardware; "
1648 "initialization status: %d\n", r);
1649 goto bad_free_hw;
1650 }
1651
1652 if (ath9k_init_debug(ah) < 0) {
1653 ath_print(common, ATH_DBG_FATAL,
1654 "Unable to create debugfs files\n");
1655 goto bad_free_hw;
1656 }
1657
1658 /* Get the hardware key cache size. */
1659 common->keymax = ah->caps.keycache_size;
1660 if (common->keymax > ATH_KEYMAX) {
1661 ath_print(common, ATH_DBG_ANY,
1662 "Warning, using only %u entries in %u key cache\n",
1663 ATH_KEYMAX, common->keymax);
1664 common->keymax = ATH_KEYMAX;
1665 }
1666
1667 /*
1668 * Reset the key cache since some parts do not
1669 * reset the contents on initial power up.
1670 */
1671 for (i = 0; i < common->keymax; i++)
1672 ath9k_hw_keyreset(ah, (u16) i);
1673
1674 /* default to MONITOR mode */
1675 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1676
1677 /*
1678 * Allocate hardware transmit queues: one queue for
1679 * beacon frames and one data queue for each QoS
1680 * priority. Note that the hal handles reseting
1681 * these queues at the needed time.
1682 */
1683 sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah);
1684 if (sc->beacon.beaconq == -1) {
1685 ath_print(common, ATH_DBG_FATAL,
1686 "Unable to setup a beacon xmit queue\n");
1687 r = -EIO;
1688 goto bad2;
1689 }
1690 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
1691 if (sc->beacon.cabq == NULL) {
1692 ath_print(common, ATH_DBG_FATAL,
1693 "Unable to setup CAB xmit queue\n");
1694 r = -EIO;
1695 goto bad2;
1696 }
1697
1698 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
1699 ath_cabq_update(sc);
1700
1701 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
1702 sc->tx.hwq_map[i] = -1;
1703
1704 /* Setup data queues */
1705 /* NB: ensure BK queue is the lowest priority h/w queue */
1706 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1707 ath_print(common, ATH_DBG_FATAL,
1708 "Unable to setup xmit queue for BK traffic\n");
1709 r = -EIO;
1710 goto bad2;
1711 }
1712
1713 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1714 ath_print(common, ATH_DBG_FATAL,
1715 "Unable to setup xmit queue for BE traffic\n");
1716 r = -EIO;
1717 goto bad2;
1718 }
1719 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1720 ath_print(common, ATH_DBG_FATAL,
1721 "Unable to setup xmit queue for VI traffic\n");
1722 r = -EIO;
1723 goto bad2;
1724 }
1725 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1726 ath_print(common, ATH_DBG_FATAL,
1727 "Unable to setup xmit queue for VO traffic\n");
1728 r = -EIO;
1729 goto bad2;
1730 }
1731
1732 /* Initializes the noise floor to a reasonable default value.
1733 * Later on this will be updated during ANI processing. */
1734
1735 common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
1736 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
1737
1738 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1739 ATH9K_CIPHER_TKIP, NULL)) {
1740 /*
1741 * Whether we should enable h/w TKIP MIC.
1742 * XXX: if we don't support WME TKIP MIC, then we wouldn't
1743 * report WMM capable, so it's always safe to turn on
1744 * TKIP MIC in this case.
1745 */
1746 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
1747 0, 1, NULL);
1748 }
1749
1750 /*
1751 * Check whether the separate key cache entries
1752 * are required to handle both tx+rx MIC keys.
1753 * With split mic keys the number of stations is limited
1754 * to 27 otherwise 59.
1755 */
1756 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1757 ATH9K_CIPHER_TKIP, NULL)
1758 && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1759 ATH9K_CIPHER_MIC, NULL)
1760 && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
1761 0, NULL))
1762 common->splitmic = 1;
1763
1764 /* turn on mcast key search if possible */
1765 if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
1766 (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1767 1, NULL);
1768
1769 sc->config.txpowlimit = ATH_TXPOWER_MAX;
1770
1771 /* 11n Capabilities */
1772 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1773 sc->sc_flags |= SC_OP_TXAGGR;
1774 sc->sc_flags |= SC_OP_RXAGGR;
1775 }
1776
1777 common->tx_chainmask = ah->caps.tx_chainmask;
1778 common->rx_chainmask = ah->caps.rx_chainmask;
1779
1780 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
1781 sc->rx.defant = ath9k_hw_getdefantenna(ah);
1782
1783 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1784 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
1785
1786 sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
1787
1788 /* initialize beacon slots */
1789 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1790 sc->beacon.bslot[i] = NULL;
1791 sc->beacon.bslot_aphy[i] = NULL;
1792 }
1793
1794 /* setup channels and rates */
1795
1796 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
1797 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
1798 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1799 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
1800 ARRAY_SIZE(ath9k_2ghz_chantable);
1801 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
1802 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
1803 ARRAY_SIZE(ath9k_legacy_rates);
1804 }
1805
1806 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
1807 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
1808 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
1809 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
1810 ARRAY_SIZE(ath9k_5ghz_chantable);
1811 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1812 ath9k_legacy_rates + 4;
1813 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
1814 ARRAY_SIZE(ath9k_legacy_rates) - 4;
1815 }
1816
1817 switch (ah->btcoex_hw.scheme) {
1818 case ATH_BTCOEX_CFG_NONE:
1819 break;
1820 case ATH_BTCOEX_CFG_2WIRE:
1821 ath9k_hw_btcoex_init_2wire(ah);
1822 break;
1823 case ATH_BTCOEX_CFG_3WIRE:
1824 ath9k_hw_btcoex_init_3wire(ah);
1825 r = ath_init_btcoex_timer(sc);
1826 if (r)
1827 goto bad2;
1828 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
1829 ath9k_hw_init_btcoex_hw(ah, qnum);
1830 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
1831 break;
1832 default:
1833 WARN_ON(1);
1834 break;
1835 }
1836
1837 return 0;
1838bad2:
1839 /* cleanup tx queues */
1840 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1841 if (ATH_TXQ_SETUP(sc, i))
1842 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1843
1844bad_free_hw:
1845 ath9k_uninit_hw(sc);
1846 return r;
1847}
1848
1849void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1850{
1851 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1852 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1853 IEEE80211_HW_SIGNAL_DBM |
1854 IEEE80211_HW_AMPDU_AGGREGATION |
1855 IEEE80211_HW_SUPPORTS_PS |
1856 IEEE80211_HW_PS_NULLFUNC_STACK |
1857 IEEE80211_HW_SPECTRUM_MGMT;
1858
1859 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
1860 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
1861
1862 hw->wiphy->interface_modes =
1863 BIT(NL80211_IFTYPE_AP) |
1864 BIT(NL80211_IFTYPE_STATION) |
1865 BIT(NL80211_IFTYPE_ADHOC) |
1866 BIT(NL80211_IFTYPE_MESH_POINT);
1867
1868 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
1869
1870 hw->queues = 4;
1871 hw->max_rates = 4;
1872 hw->channel_change_time = 5000;
1873 hw->max_listen_interval = 10;
1874 /* Hardware supports 10 but we use 4 */
1875 hw->max_rate_tries = 4;
1876 hw->sta_data_size = sizeof(struct ath_node);
1877 hw->vif_data_size = sizeof(struct ath_vif);
1878
1879 hw->rate_control_algorithm = "ath9k_rate_control";
1880
1881 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
1882 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1883 &sc->sbands[IEEE80211_BAND_2GHZ];
1884 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
1885 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1886 &sc->sbands[IEEE80211_BAND_5GHZ];
1887}
1888
1889/* Device driver core initialization */
1890int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
1891 const struct ath_bus_ops *bus_ops)
1892{
1893 struct ieee80211_hw *hw = sc->hw;
1894 struct ath_common *common;
1895 struct ath_hw *ah;
1896 int error = 0, i;
1897 struct ath_regulatory *reg;
1898
1899 dev_dbg(sc->dev, "Attach ATH hw\n");
1900
1901 error = ath_init_softc(devid, sc, subsysid, bus_ops);
1902 if (error != 0)
1903 return error;
1904
1905 ah = sc->sc_ah;
1906 common = ath9k_hw_common(ah);
1907
1908 /* get mac address from hardware and set in mac80211 */
1909
1910 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
1911
1912 ath_set_hw_capab(sc, hw);
1913
1914 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
1915 ath9k_reg_notifier);
1916 if (error)
1917 return error;
1918
1919 reg = &common->regulatory;
1920
1921 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1922 if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes))
1923 setup_ht_cap(sc,
1924 &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
1925 if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes))
1926 setup_ht_cap(sc,
1927 &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
1928 }
1929
1930 /* initialize tx/rx engine */
1931 error = ath_tx_init(sc, ATH_TXBUF);
1932 if (error != 0)
1933 goto error_attach;
1934
1935 error = ath_rx_init(sc, ATH_RXBUF);
1936 if (error != 0)
1937 goto error_attach;
1938
1939 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
1940 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
1941 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
1942
1943 error = ieee80211_register_hw(hw);
1944
1945 if (!ath_is_world_regd(reg)) {
1946 error = regulatory_hint(hw->wiphy, reg->alpha2);
1947 if (error)
1948 goto error_attach;
1949 }
1950
1951 /* Initialize LED control */
1952 ath_init_leds(sc);
1953
1954 ath_start_rfkill_poll(sc);
1955
1956 return 0;
1957
1958error_attach:
1959 /* cleanup tx queues */
1960 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1961 if (ATH_TXQ_SETUP(sc, i))
1962 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1963
1964 ath9k_uninit_hw(sc);
1965
1966 return error;
1967}
1968
1969int ath_reset(struct ath_softc *sc, bool retry_tx) 940int ath_reset(struct ath_softc *sc, bool retry_tx)
1970{ 941{
1971 struct ath_hw *ah = sc->sc_ah; 942 struct ath_hw *ah = sc->sc_ah;
@@ -1976,6 +947,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1976 /* Stop ANI */ 947 /* Stop ANI */
1977 del_timer_sync(&common->ani.timer); 948 del_timer_sync(&common->ani.timer);
1978 949
950 ieee80211_stop_queues(hw);
951
1979 ath9k_hw_set_interrupts(ah, 0); 952 ath9k_hw_set_interrupts(ah, 0);
1980 ath_drain_all_txq(sc, retry_tx); 953 ath_drain_all_txq(sc, retry_tx);
1981 ath_stoprecv(sc); 954 ath_stoprecv(sc);
@@ -2017,131 +990,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
2017 } 990 }
2018 } 991 }
2019 992
993 ieee80211_wake_queues(hw);
994
2020 /* Start ANI */ 995 /* Start ANI */
2021 ath_start_ani(common); 996 ath_start_ani(common);
2022 997
2023 return r; 998 return r;
2024} 999}
2025 1000
2026/*
2027 * This function will allocate both the DMA descriptor structure, and the
2028 * buffers it contains. These are used to contain the descriptors used
2029 * by the system.
2030*/
2031int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
2032 struct list_head *head, const char *name,
2033 int nbuf, int ndesc)
2034{
2035#define DS2PHYS(_dd, _ds) \
2036 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
2037#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
2038#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
2039 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2040 struct ath_desc *ds;
2041 struct ath_buf *bf;
2042 int i, bsize, error;
2043
2044 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
2045 name, nbuf, ndesc);
2046
2047 INIT_LIST_HEAD(head);
2048 /* ath_desc must be a multiple of DWORDs */
2049 if ((sizeof(struct ath_desc) % 4) != 0) {
2050 ath_print(common, ATH_DBG_FATAL,
2051 "ath_desc not DWORD aligned\n");
2052 BUG_ON((sizeof(struct ath_desc) % 4) != 0);
2053 error = -ENOMEM;
2054 goto fail;
2055 }
2056
2057 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
2058
2059 /*
2060 * Need additional DMA memory because we can't use
2061 * descriptors that cross the 4K page boundary. Assume
2062 * one skipped descriptor per 4K page.
2063 */
2064 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
2065 u32 ndesc_skipped =
2066 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
2067 u32 dma_len;
2068
2069 while (ndesc_skipped) {
2070 dma_len = ndesc_skipped * sizeof(struct ath_desc);
2071 dd->dd_desc_len += dma_len;
2072
2073 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
2074 };
2075 }
2076
2077 /* allocate descriptors */
2078 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
2079 &dd->dd_desc_paddr, GFP_KERNEL);
2080 if (dd->dd_desc == NULL) {
2081 error = -ENOMEM;
2082 goto fail;
2083 }
2084 ds = dd->dd_desc;
2085 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
2086 name, ds, (u32) dd->dd_desc_len,
2087 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
2088
2089 /* allocate buffers */
2090 bsize = sizeof(struct ath_buf) * nbuf;
2091 bf = kzalloc(bsize, GFP_KERNEL);
2092 if (bf == NULL) {
2093 error = -ENOMEM;
2094 goto fail2;
2095 }
2096 dd->dd_bufptr = bf;
2097
2098 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
2099 bf->bf_desc = ds;
2100 bf->bf_daddr = DS2PHYS(dd, ds);
2101
2102 if (!(sc->sc_ah->caps.hw_caps &
2103 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
2104 /*
2105 * Skip descriptor addresses which can cause 4KB
2106 * boundary crossing (addr + length) with a 32 dword
2107 * descriptor fetch.
2108 */
2109 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
2110 BUG_ON((caddr_t) bf->bf_desc >=
2111 ((caddr_t) dd->dd_desc +
2112 dd->dd_desc_len));
2113
2114 ds += ndesc;
2115 bf->bf_desc = ds;
2116 bf->bf_daddr = DS2PHYS(dd, ds);
2117 }
2118 }
2119 list_add_tail(&bf->list, head);
2120 }
2121 return 0;
2122fail2:
2123 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2124 dd->dd_desc_paddr);
2125fail:
2126 memset(dd, 0, sizeof(*dd));
2127 return error;
2128#undef ATH_DESC_4KB_BOUND_CHECK
2129#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
2130#undef DS2PHYS
2131}
2132
2133void ath_descdma_cleanup(struct ath_softc *sc,
2134 struct ath_descdma *dd,
2135 struct list_head *head)
2136{
2137 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2138 dd->dd_desc_paddr);
2139
2140 INIT_LIST_HEAD(head);
2141 kfree(dd->dd_bufptr);
2142 memset(dd, 0, sizeof(*dd));
2143}
2144
2145int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) 1001int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
2146{ 1002{
2147 int qnum; 1003 int qnum;
@@ -2220,28 +1076,6 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
2220/* mac80211 callbacks */ 1076/* mac80211 callbacks */
2221/**********************/ 1077/**********************/
2222 1078
2223/*
2224 * (Re)start btcoex timers
2225 */
2226static void ath9k_btcoex_timer_resume(struct ath_softc *sc)
2227{
2228 struct ath_btcoex *btcoex = &sc->btcoex;
2229 struct ath_hw *ah = sc->sc_ah;
2230
2231 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
2232 "Starting btcoex timers");
2233
2234 /* make sure duty cycle timer is also stopped when resuming */
2235 if (btcoex->hw_timer_enabled)
2236 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
2237
2238 btcoex->bt_priority_cnt = 0;
2239 btcoex->bt_priority_time = jiffies;
2240 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
2241
2242 mod_timer(&btcoex->period_timer, jiffies);
2243}
2244
2245static int ath9k_start(struct ieee80211_hw *hw) 1079static int ath9k_start(struct ieee80211_hw *hw)
2246{ 1080{
2247 struct ath_wiphy *aphy = hw->priv; 1081 struct ath_wiphy *aphy = hw->priv;
@@ -2411,11 +1245,11 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2411 if (ieee80211_is_pspoll(hdr->frame_control)) { 1245 if (ieee80211_is_pspoll(hdr->frame_control)) {
2412 ath_print(common, ATH_DBG_PS, 1246 ath_print(common, ATH_DBG_PS,
2413 "Sending PS-Poll to pick a buffered frame\n"); 1247 "Sending PS-Poll to pick a buffered frame\n");
2414 sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; 1248 sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
2415 } else { 1249 } else {
2416 ath_print(common, ATH_DBG_PS, 1250 ath_print(common, ATH_DBG_PS,
2417 "Wake up to complete TX\n"); 1251 "Wake up to complete TX\n");
2418 sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; 1252 sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
2419 } 1253 }
2420 /* 1254 /*
2421 * The actual restore operation will happen only after 1255 * The actual restore operation will happen only after
@@ -2468,22 +1302,6 @@ exit:
2468 return 0; 1302 return 0;
2469} 1303}
2470 1304
2471/*
2472 * Pause btcoex timer and bt duty cycle timer
2473 */
2474static void ath9k_btcoex_timer_pause(struct ath_softc *sc)
2475{
2476 struct ath_btcoex *btcoex = &sc->btcoex;
2477 struct ath_hw *ah = sc->sc_ah;
2478
2479 del_timer_sync(&btcoex->period_timer);
2480
2481 if (btcoex->hw_timer_enabled)
2482 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
2483
2484 btcoex->hw_timer_enabled = false;
2485}
2486
2487static void ath9k_stop(struct ieee80211_hw *hw) 1305static void ath9k_stop(struct ieee80211_hw *hw)
2488{ 1306{
2489 struct ath_wiphy *aphy = hw->priv; 1307 struct ath_wiphy *aphy = hw->priv;
@@ -2550,12 +1368,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2550} 1368}
2551 1369
2552static int ath9k_add_interface(struct ieee80211_hw *hw, 1370static int ath9k_add_interface(struct ieee80211_hw *hw,
2553 struct ieee80211_if_init_conf *conf) 1371 struct ieee80211_vif *vif)
2554{ 1372{
2555 struct ath_wiphy *aphy = hw->priv; 1373 struct ath_wiphy *aphy = hw->priv;
2556 struct ath_softc *sc = aphy->sc; 1374 struct ath_softc *sc = aphy->sc;
2557 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1375 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2558 struct ath_vif *avp = (void *)conf->vif->drv_priv; 1376 struct ath_vif *avp = (void *)vif->drv_priv;
2559 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; 1377 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
2560 int ret = 0; 1378 int ret = 0;
2561 1379
@@ -2567,7 +1385,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2567 goto out; 1385 goto out;
2568 } 1386 }
2569 1387
2570 switch (conf->type) { 1388 switch (vif->type) {
2571 case NL80211_IFTYPE_STATION: 1389 case NL80211_IFTYPE_STATION:
2572 ic_opmode = NL80211_IFTYPE_STATION; 1390 ic_opmode = NL80211_IFTYPE_STATION;
2573 break; 1391 break;
@@ -2578,11 +1396,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2578 ret = -ENOBUFS; 1396 ret = -ENOBUFS;
2579 goto out; 1397 goto out;
2580 } 1398 }
2581 ic_opmode = conf->type; 1399 ic_opmode = vif->type;
2582 break; 1400 break;
2583 default: 1401 default:
2584 ath_print(common, ATH_DBG_FATAL, 1402 ath_print(common, ATH_DBG_FATAL,
2585 "Interface type %d not yet supported\n", conf->type); 1403 "Interface type %d not yet supported\n", vif->type);
2586 ret = -EOPNOTSUPP; 1404 ret = -EOPNOTSUPP;
2587 goto out; 1405 goto out;
2588 } 1406 }
@@ -2614,18 +1432,18 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2614 * Enable MIB interrupts when there are hardware phy counters. 1432 * Enable MIB interrupts when there are hardware phy counters.
2615 * Note we only do this (at the moment) for station mode. 1433 * Note we only do this (at the moment) for station mode.
2616 */ 1434 */
2617 if ((conf->type == NL80211_IFTYPE_STATION) || 1435 if ((vif->type == NL80211_IFTYPE_STATION) ||
2618 (conf->type == NL80211_IFTYPE_ADHOC) || 1436 (vif->type == NL80211_IFTYPE_ADHOC) ||
2619 (conf->type == NL80211_IFTYPE_MESH_POINT)) { 1437 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
2620 sc->imask |= ATH9K_INT_MIB; 1438 sc->imask |= ATH9K_INT_MIB;
2621 sc->imask |= ATH9K_INT_TSFOOR; 1439 sc->imask |= ATH9K_INT_TSFOOR;
2622 } 1440 }
2623 1441
2624 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 1442 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
2625 1443
2626 if (conf->type == NL80211_IFTYPE_AP || 1444 if (vif->type == NL80211_IFTYPE_AP ||
2627 conf->type == NL80211_IFTYPE_ADHOC || 1445 vif->type == NL80211_IFTYPE_ADHOC ||
2628 conf->type == NL80211_IFTYPE_MONITOR) 1446 vif->type == NL80211_IFTYPE_MONITOR)
2629 ath_start_ani(common); 1447 ath_start_ani(common);
2630 1448
2631out: 1449out:
@@ -2634,12 +1452,12 @@ out:
2634} 1452}
2635 1453
2636static void ath9k_remove_interface(struct ieee80211_hw *hw, 1454static void ath9k_remove_interface(struct ieee80211_hw *hw,
2637 struct ieee80211_if_init_conf *conf) 1455 struct ieee80211_vif *vif)
2638{ 1456{
2639 struct ath_wiphy *aphy = hw->priv; 1457 struct ath_wiphy *aphy = hw->priv;
2640 struct ath_softc *sc = aphy->sc; 1458 struct ath_softc *sc = aphy->sc;
2641 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1459 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2642 struct ath_vif *avp = (void *)conf->vif->drv_priv; 1460 struct ath_vif *avp = (void *)vif->drv_priv;
2643 int i; 1461 int i;
2644 1462
2645 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); 1463 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
@@ -2662,7 +1480,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
2662 sc->sc_flags &= ~SC_OP_BEACONS; 1480 sc->sc_flags &= ~SC_OP_BEACONS;
2663 1481
2664 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { 1482 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
2665 if (sc->beacon.bslot[i] == conf->vif) { 1483 if (sc->beacon.bslot[i] == vif) {
2666 printk(KERN_DEBUG "%s: vif had allocated beacon " 1484 printk(KERN_DEBUG "%s: vif had allocated beacon "
2667 "slot\n", __func__); 1485 "slot\n", __func__);
2668 sc->beacon.bslot[i] = NULL; 1486 sc->beacon.bslot[i] = NULL;
@@ -2675,6 +1493,19 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
2675 mutex_unlock(&sc->mutex); 1493 mutex_unlock(&sc->mutex);
2676} 1494}
2677 1495
1496void ath9k_enable_ps(struct ath_softc *sc)
1497{
1498 sc->ps_enabled = true;
1499 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1500 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
1501 sc->imask |= ATH9K_INT_TIM_TIMER;
1502 ath9k_hw_set_interrupts(sc->sc_ah,
1503 sc->imask);
1504 }
1505 }
1506 ath9k_hw_setrxabort(sc->sc_ah, 1);
1507}
1508
2678static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1509static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2679{ 1510{
2680 struct ath_wiphy *aphy = hw->priv; 1511 struct ath_wiphy *aphy = hw->priv;
@@ -2713,6 +1544,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2713 spin_unlock_bh(&sc->wiphy_lock); 1544 spin_unlock_bh(&sc->wiphy_lock);
2714 1545
2715 if (enable_radio) { 1546 if (enable_radio) {
1547 sc->ps_idle = false;
2716 ath_radio_enable(sc, hw); 1548 ath_radio_enable(sc, hw);
2717 ath_print(common, ATH_DBG_CONFIG, 1549 ath_print(common, ATH_DBG_CONFIG,
2718 "not-idle: enabling radio\n"); 1550 "not-idle: enabling radio\n");
@@ -2727,36 +1559,27 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2727 */ 1559 */
2728 if (changed & IEEE80211_CONF_CHANGE_PS) { 1560 if (changed & IEEE80211_CONF_CHANGE_PS) {
2729 if (conf->flags & IEEE80211_CONF_PS) { 1561 if (conf->flags & IEEE80211_CONF_PS) {
2730 sc->sc_flags |= SC_OP_PS_ENABLED; 1562 sc->ps_flags |= PS_ENABLED;
2731 if (!(ah->caps.hw_caps &
2732 ATH9K_HW_CAP_AUTOSLEEP)) {
2733 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
2734 sc->imask |= ATH9K_INT_TIM_TIMER;
2735 ath9k_hw_set_interrupts(sc->sc_ah,
2736 sc->imask);
2737 }
2738 }
2739 /* 1563 /*
2740 * At this point we know hardware has received an ACK 1564 * At this point we know hardware has received an ACK
2741 * of a previously sent null data frame. 1565 * of a previously sent null data frame.
2742 */ 1566 */
2743 if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { 1567 if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
2744 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; 1568 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
2745 sc->ps_enabled = true; 1569 ath9k_enable_ps(sc);
2746 ath9k_hw_setrxabort(sc->sc_ah, 1);
2747 } 1570 }
2748 } else { 1571 } else {
2749 sc->ps_enabled = false; 1572 sc->ps_enabled = false;
2750 sc->sc_flags &= ~(SC_OP_PS_ENABLED | 1573 sc->ps_flags &= ~(PS_ENABLED |
2751 SC_OP_NULLFUNC_COMPLETED); 1574 PS_NULLFUNC_COMPLETED);
2752 ath9k_setpower(sc, ATH9K_PM_AWAKE); 1575 ath9k_setpower(sc, ATH9K_PM_AWAKE);
2753 if (!(ah->caps.hw_caps & 1576 if (!(ah->caps.hw_caps &
2754 ATH9K_HW_CAP_AUTOSLEEP)) { 1577 ATH9K_HW_CAP_AUTOSLEEP)) {
2755 ath9k_hw_setrxabort(sc->sc_ah, 0); 1578 ath9k_hw_setrxabort(sc->sc_ah, 0);
2756 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | 1579 sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
2757 SC_OP_WAIT_FOR_CAB | 1580 PS_WAIT_FOR_CAB |
2758 SC_OP_WAIT_FOR_PSPOLL_DATA | 1581 PS_WAIT_FOR_PSPOLL_DATA |
2759 SC_OP_WAIT_FOR_TX_ACK); 1582 PS_WAIT_FOR_TX_ACK);
2760 if (sc->imask & ATH9K_INT_TIM_TIMER) { 1583 if (sc->imask & ATH9K_INT_TIM_TIMER) {
2761 sc->imask &= ~ATH9K_INT_TIM_TIMER; 1584 sc->imask &= ~ATH9K_INT_TIM_TIMER;
2762 ath9k_hw_set_interrupts(sc->sc_ah, 1585 ath9k_hw_set_interrupts(sc->sc_ah,
@@ -2766,6 +1589,14 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2766 } 1589 }
2767 } 1590 }
2768 1591
1592 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1593 if (conf->flags & IEEE80211_CONF_MONITOR) {
1594 ath_print(common, ATH_DBG_CONFIG,
1595 "HW opmode set to Monitor mode\n");
1596 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1597 }
1598 }
1599
2769 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1600 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
2770 struct ieee80211_channel *curchan = hw->conf.channel; 1601 struct ieee80211_channel *curchan = hw->conf.channel;
2771 int pos = curchan->hw_value; 1602 int pos = curchan->hw_value;
@@ -2801,8 +1632,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2801 } 1632 }
2802 1633
2803skip_chan_change: 1634skip_chan_change:
2804 if (changed & IEEE80211_CONF_CHANGE_POWER) 1635 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2805 sc->config.txpowlimit = 2 * conf->power_level; 1636 sc->config.txpowlimit = 2 * conf->power_level;
1637 ath_update_txpow(sc);
1638 }
2806 1639
2807 spin_lock_bh(&sc->wiphy_lock); 1640 spin_lock_bh(&sc->wiphy_lock);
2808 disable_radio = ath9k_all_wiphys_idle(sc); 1641 disable_radio = ath9k_all_wiphys_idle(sc);
@@ -2810,6 +1643,7 @@ skip_chan_change:
2810 1643
2811 if (disable_radio) { 1644 if (disable_radio) {
2812 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); 1645 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1646 sc->ps_idle = true;
2813 ath_radio_disable(sc, hw); 1647 ath_radio_disable(sc, hw);
2814 } 1648 }
2815 1649
@@ -2850,24 +1684,28 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
2850 "Set HW RX filter: 0x%x\n", rfilt); 1684 "Set HW RX filter: 0x%x\n", rfilt);
2851} 1685}
2852 1686
2853static void ath9k_sta_notify(struct ieee80211_hw *hw, 1687static int ath9k_sta_add(struct ieee80211_hw *hw,
2854 struct ieee80211_vif *vif, 1688 struct ieee80211_vif *vif,
2855 enum sta_notify_cmd cmd, 1689 struct ieee80211_sta *sta)
2856 struct ieee80211_sta *sta)
2857{ 1690{
2858 struct ath_wiphy *aphy = hw->priv; 1691 struct ath_wiphy *aphy = hw->priv;
2859 struct ath_softc *sc = aphy->sc; 1692 struct ath_softc *sc = aphy->sc;
2860 1693
2861 switch (cmd) { 1694 ath_node_attach(sc, sta);
2862 case STA_NOTIFY_ADD: 1695
2863 ath_node_attach(sc, sta); 1696 return 0;
2864 break; 1697}
2865 case STA_NOTIFY_REMOVE: 1698
2866 ath_node_detach(sc, sta); 1699static int ath9k_sta_remove(struct ieee80211_hw *hw,
2867 break; 1700 struct ieee80211_vif *vif,
2868 default: 1701 struct ieee80211_sta *sta)
2869 break; 1702{
2870 } 1703 struct ath_wiphy *aphy = hw->priv;
1704 struct ath_softc *sc = aphy->sc;
1705
1706 ath_node_detach(sc, sta);
1707
1708 return 0;
2871} 1709}
2872 1710
2873static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, 1711static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -2966,6 +1804,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2966 struct ath_hw *ah = sc->sc_ah; 1804 struct ath_hw *ah = sc->sc_ah;
2967 struct ath_common *common = ath9k_hw_common(ah); 1805 struct ath_common *common = ath9k_hw_common(ah);
2968 struct ath_vif *avp = (void *)vif->drv_priv; 1806 struct ath_vif *avp = (void *)vif->drv_priv;
1807 int slottime;
2969 int error; 1808 int error;
2970 1809
2971 mutex_lock(&sc->mutex); 1810 mutex_lock(&sc->mutex);
@@ -3001,6 +1840,25 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
3001 ath_beacon_config(sc, vif); 1840 ath_beacon_config(sc, vif);
3002 } 1841 }
3003 1842
1843 if (changed & BSS_CHANGED_ERP_SLOT) {
1844 if (bss_conf->use_short_slot)
1845 slottime = 9;
1846 else
1847 slottime = 20;
1848 if (vif->type == NL80211_IFTYPE_AP) {
1849 /*
1850 * Defer update, so that connected stations can adjust
1851 * their settings at the same time.
1852 * See beacon.c for more details
1853 */
1854 sc->beacon.slottime = slottime;
1855 sc->beacon.updateslot = UPDATE;
1856 } else {
1857 ah->slottime = slottime;
1858 ath9k_hw_init_global_settings(ah);
1859 }
1860 }
1861
3004 /* Disable transmission of beacons */ 1862 /* Disable transmission of beacons */
3005 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) 1863 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
3006 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1864 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -3133,6 +1991,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
3133{ 1991{
3134 struct ath_wiphy *aphy = hw->priv; 1992 struct ath_wiphy *aphy = hw->priv;
3135 struct ath_softc *sc = aphy->sc; 1993 struct ath_softc *sc = aphy->sc;
1994 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
3136 1995
3137 mutex_lock(&sc->mutex); 1996 mutex_lock(&sc->mutex);
3138 if (ath9k_wiphy_scanning(sc)) { 1997 if (ath9k_wiphy_scanning(sc)) {
@@ -3148,10 +2007,9 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
3148 2007
3149 aphy->state = ATH_WIPHY_SCAN; 2008 aphy->state = ATH_WIPHY_SCAN;
3150 ath9k_wiphy_pause_all_forced(sc, aphy); 2009 ath9k_wiphy_pause_all_forced(sc, aphy);
3151
3152 spin_lock_bh(&sc->ani_lock);
3153 sc->sc_flags |= SC_OP_SCANNING; 2010 sc->sc_flags |= SC_OP_SCANNING;
3154 spin_unlock_bh(&sc->ani_lock); 2011 del_timer_sync(&common->ani.timer);
2012 cancel_delayed_work_sync(&sc->tx_complete_work);
3155 mutex_unlock(&sc->mutex); 2013 mutex_unlock(&sc->mutex);
3156} 2014}
3157 2015
@@ -3159,17 +2017,30 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
3159{ 2017{
3160 struct ath_wiphy *aphy = hw->priv; 2018 struct ath_wiphy *aphy = hw->priv;
3161 struct ath_softc *sc = aphy->sc; 2019 struct ath_softc *sc = aphy->sc;
2020 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
3162 2021
3163 mutex_lock(&sc->mutex); 2022 mutex_lock(&sc->mutex);
3164 spin_lock_bh(&sc->ani_lock);
3165 aphy->state = ATH_WIPHY_ACTIVE; 2023 aphy->state = ATH_WIPHY_ACTIVE;
3166 sc->sc_flags &= ~SC_OP_SCANNING; 2024 sc->sc_flags &= ~SC_OP_SCANNING;
3167 sc->sc_flags |= SC_OP_FULL_RESET; 2025 sc->sc_flags |= SC_OP_FULL_RESET;
3168 spin_unlock_bh(&sc->ani_lock); 2026 ath_start_ani(common);
2027 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
3169 ath_beacon_config(sc, NULL); 2028 ath_beacon_config(sc, NULL);
3170 mutex_unlock(&sc->mutex); 2029 mutex_unlock(&sc->mutex);
3171} 2030}
3172 2031
2032static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
2033{
2034 struct ath_wiphy *aphy = hw->priv;
2035 struct ath_softc *sc = aphy->sc;
2036 struct ath_hw *ah = sc->sc_ah;
2037
2038 mutex_lock(&sc->mutex);
2039 ah->coverage_class = coverage_class;
2040 ath9k_hw_init_global_settings(ah);
2041 mutex_unlock(&sc->mutex);
2042}
2043
3173struct ieee80211_ops ath9k_ops = { 2044struct ieee80211_ops ath9k_ops = {
3174 .tx = ath9k_tx, 2045 .tx = ath9k_tx,
3175 .start = ath9k_start, 2046 .start = ath9k_start,
@@ -3178,7 +2049,8 @@ struct ieee80211_ops ath9k_ops = {
3178 .remove_interface = ath9k_remove_interface, 2049 .remove_interface = ath9k_remove_interface,
3179 .config = ath9k_config, 2050 .config = ath9k_config,
3180 .configure_filter = ath9k_configure_filter, 2051 .configure_filter = ath9k_configure_filter,
3181 .sta_notify = ath9k_sta_notify, 2052 .sta_add = ath9k_sta_add,
2053 .sta_remove = ath9k_sta_remove,
3182 .conf_tx = ath9k_conf_tx, 2054 .conf_tx = ath9k_conf_tx,
3183 .bss_info_changed = ath9k_bss_info_changed, 2055 .bss_info_changed = ath9k_bss_info_changed,
3184 .set_key = ath9k_set_key, 2056 .set_key = ath9k_set_key,
@@ -3189,64 +2061,5 @@ struct ieee80211_ops ath9k_ops = {
3189 .sw_scan_start = ath9k_sw_scan_start, 2061 .sw_scan_start = ath9k_sw_scan_start,
3190 .sw_scan_complete = ath9k_sw_scan_complete, 2062 .sw_scan_complete = ath9k_sw_scan_complete,
3191 .rfkill_poll = ath9k_rfkill_poll_state, 2063 .rfkill_poll = ath9k_rfkill_poll_state,
2064 .set_coverage_class = ath9k_set_coverage_class,
3192}; 2065};
3193
3194static int __init ath9k_init(void)
3195{
3196 int error;
3197
3198 /* Register rate control algorithm */
3199 error = ath_rate_control_register();
3200 if (error != 0) {
3201 printk(KERN_ERR
3202 "ath9k: Unable to register rate control "
3203 "algorithm: %d\n",
3204 error);
3205 goto err_out;
3206 }
3207
3208 error = ath9k_debug_create_root();
3209 if (error) {
3210 printk(KERN_ERR
3211 "ath9k: Unable to create debugfs root: %d\n",
3212 error);
3213 goto err_rate_unregister;
3214 }
3215
3216 error = ath_pci_init();
3217 if (error < 0) {
3218 printk(KERN_ERR
3219 "ath9k: No PCI devices found, driver not installed.\n");
3220 error = -ENODEV;
3221 goto err_remove_root;
3222 }
3223
3224 error = ath_ahb_init();
3225 if (error < 0) {
3226 error = -ENODEV;
3227 goto err_pci_exit;
3228 }
3229
3230 return 0;
3231
3232 err_pci_exit:
3233 ath_pci_exit();
3234
3235 err_remove_root:
3236 ath9k_debug_remove_root();
3237 err_rate_unregister:
3238 ath_rate_control_unregister();
3239 err_out:
3240 return error;
3241}
3242module_init(ath9k_init);
3243
3244static void __exit ath9k_exit(void)
3245{
3246 ath_ahb_exit();
3247 ath_pci_exit();
3248 ath9k_debug_remove_root();
3249 ath_rate_control_unregister();
3250 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
3251}
3252module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index f7af5ea54753..f318b3b1abe9 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -25,6 +25,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ 25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ 26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ 27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
28 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
29 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
30 { 0 } 31 { 0 }
@@ -49,16 +50,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
49 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ 50 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
50} 51}
51 52
52static void ath_pci_cleanup(struct ath_common *common)
53{
54 struct ath_softc *sc = (struct ath_softc *) common->priv;
55 struct pci_dev *pdev = to_pci_dev(sc->dev);
56
57 pci_iounmap(pdev, sc->mem);
58 pci_disable_device(pdev);
59 pci_release_region(pdev, 0);
60}
61
62static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) 53static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
63{ 54{
64 struct ath_hw *ah = (struct ath_hw *) common->ah; 55 struct ath_hw *ah = (struct ath_hw *) common->ah;
@@ -98,7 +89,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
98 89
99static const struct ath_bus_ops ath_pci_bus_ops = { 90static const struct ath_bus_ops ath_pci_bus_ops = {
100 .read_cachesize = ath_pci_read_cachesize, 91 .read_cachesize = ath_pci_read_cachesize,
101 .cleanup = ath_pci_cleanup,
102 .eeprom_read = ath_pci_eeprom_read, 92 .eeprom_read = ath_pci_eeprom_read,
103 .bt_coex_prep = ath_pci_bt_coex_prep, 93 .bt_coex_prep = ath_pci_bt_coex_prep,
104}; 94};
@@ -113,25 +103,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
113 u16 subsysid; 103 u16 subsysid;
114 u32 val; 104 u32 val;
115 int ret = 0; 105 int ret = 0;
116 struct ath_hw *ah;
117 char hw_name[64]; 106 char hw_name[64];
118 107
119 if (pci_enable_device(pdev)) 108 if (pci_enable_device(pdev))
120 return -EIO; 109 return -EIO;
121 110
122 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 111 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
123
124 if (ret) { 112 if (ret) {
125 printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); 113 printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
126 goto bad; 114 goto err_dma;
127 } 115 }
128 116
129 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 117 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
130
131 if (ret) { 118 if (ret) {
132 printk(KERN_ERR "ath9k: 32-bit DMA consistent " 119 printk(KERN_ERR "ath9k: 32-bit DMA consistent "
133 "DMA enable failed\n"); 120 "DMA enable failed\n");
134 goto bad; 121 goto err_dma;
135 } 122 }
136 123
137 /* 124 /*
@@ -171,22 +158,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
171 if (ret) { 158 if (ret) {
172 dev_err(&pdev->dev, "PCI memory region reserve error\n"); 159 dev_err(&pdev->dev, "PCI memory region reserve error\n");
173 ret = -ENODEV; 160 ret = -ENODEV;
174 goto bad; 161 goto err_region;
175 } 162 }
176 163
177 mem = pci_iomap(pdev, 0, 0); 164 mem = pci_iomap(pdev, 0, 0);
178 if (!mem) { 165 if (!mem) {
179 printk(KERN_ERR "PCI memory map error\n") ; 166 printk(KERN_ERR "PCI memory map error\n") ;
180 ret = -EIO; 167 ret = -EIO;
181 goto bad1; 168 goto err_iomap;
182 } 169 }
183 170
184 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + 171 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
185 sizeof(struct ath_softc), &ath9k_ops); 172 sizeof(struct ath_softc), &ath9k_ops);
186 if (!hw) { 173 if (!hw) {
187 dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); 174 dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
188 ret = -ENOMEM; 175 ret = -ENOMEM;
189 goto bad2; 176 goto err_alloc_hw;
190 } 177 }
191 178
192 SET_IEEE80211_DEV(hw, &pdev->dev); 179 SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -201,25 +188,25 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
201 sc->dev = &pdev->dev; 188 sc->dev = &pdev->dev;
202 sc->mem = mem; 189 sc->mem = mem;
203 190
204 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); 191 /* Will be cleared in ath9k_start() */
205 ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); 192 sc->sc_flags |= SC_OP_INVALID;
206 if (ret) {
207 dev_err(&pdev->dev, "failed to initialize device\n");
208 goto bad3;
209 }
210
211 /* setup interrupt service routine */
212 193
213 ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); 194 ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
214 if (ret) { 195 if (ret) {
215 dev_err(&pdev->dev, "request_irq failed\n"); 196 dev_err(&pdev->dev, "request_irq failed\n");
216 goto bad4; 197 goto err_irq;
217 } 198 }
218 199
219 sc->irq = pdev->irq; 200 sc->irq = pdev->irq;
220 201
221 ah = sc->sc_ah; 202 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
222 ath9k_hw_name(ah, hw_name, sizeof(hw_name)); 203 ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
204 if (ret) {
205 dev_err(&pdev->dev, "Failed to initialize device\n");
206 goto err_init;
207 }
208
209 ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
223 printk(KERN_INFO 210 printk(KERN_INFO
224 "%s: %s mem=0x%lx, irq=%d\n", 211 "%s: %s mem=0x%lx, irq=%d\n",
225 wiphy_name(hw->wiphy), 212 wiphy_name(hw->wiphy),
@@ -227,15 +214,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
227 (unsigned long)mem, pdev->irq); 214 (unsigned long)mem, pdev->irq);
228 215
229 return 0; 216 return 0;
230bad4: 217
231 ath_detach(sc); 218err_init:
232bad3: 219 free_irq(sc->irq, sc);
220err_irq:
233 ieee80211_free_hw(hw); 221 ieee80211_free_hw(hw);
234bad2: 222err_alloc_hw:
235 pci_iounmap(pdev, mem); 223 pci_iounmap(pdev, mem);
236bad1: 224err_iomap:
237 pci_release_region(pdev, 0); 225 pci_release_region(pdev, 0);
238bad: 226err_region:
227 /* Nothing */
228err_dma:
239 pci_disable_device(pdev); 229 pci_disable_device(pdev);
240 return ret; 230 return ret;
241} 231}
@@ -245,8 +235,15 @@ static void ath_pci_remove(struct pci_dev *pdev)
245 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 235 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
246 struct ath_wiphy *aphy = hw->priv; 236 struct ath_wiphy *aphy = hw->priv;
247 struct ath_softc *sc = aphy->sc; 237 struct ath_softc *sc = aphy->sc;
238 void __iomem *mem = sc->mem;
239
240 ath9k_deinit_device(sc);
241 free_irq(sc->irq, sc);
242 ieee80211_free_hw(sc->hw);
248 243
249 ath_cleanup(sc); 244 pci_iounmap(pdev, mem);
245 pci_disable_device(pdev);
246 pci_release_region(pdev, 0);
250} 247}
251 248
252#ifdef CONFIG_PM 249#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index c915954d4d5b..2880507f9d3f 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -668,7 +668,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
668 struct ieee80211_tx_rate *rates = tx_info->control.rates; 668 struct ieee80211_tx_rate *rates = tx_info->control.rates;
669 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 669 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
670 __le16 fc = hdr->frame_control; 670 __le16 fc = hdr->frame_control;
671 u8 try_per_rate, i = 0, rix, nrix; 671 u8 try_per_rate, i = 0, rix;
672 int is_probe = 0; 672 int is_probe = 0;
673 673
674 if (rate_control_send_low(sta, priv_sta, txrc)) 674 if (rate_control_send_low(sta, priv_sta, txrc))
@@ -678,48 +678,47 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
678 * For Multi Rate Retry we use a different number of 678 * For Multi Rate Retry we use a different number of
679 * retry attempt counts. This ends up looking like this: 679 * retry attempt counts. This ends up looking like this:
680 * 680 *
681 * MRR[0] = 2 681 * MRR[0] = 4
682 * MRR[1] = 2 682 * MRR[1] = 4
683 * MRR[2] = 2 683 * MRR[2] = 4
684 * MRR[3] = 4 684 * MRR[3] = 8
685 * 685 *
686 */ 686 */
687 try_per_rate = sc->hw->max_rate_tries; 687 try_per_rate = 4;
688 688
689 rate_table = sc->cur_rate_table; 689 rate_table = sc->cur_rate_table;
690 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 690 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
691 nrix = rix;
692 691
693 if (is_probe) { 692 if (is_probe) {
694 /* set one try for probe rates. For the 693 /* set one try for probe rates. For the
695 * probes don't enable rts */ 694 * probes don't enable rts */
696 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 695 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
697 1, nrix, 0); 696 1, rix, 0);
698 697
699 /* Get the next tried/allowed rate. No RTS for the next series 698 /* Get the next tried/allowed rate. No RTS for the next series
700 * after the probe rate 699 * after the probe rate
701 */ 700 */
702 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 701 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
703 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 702 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
704 try_per_rate, nrix, 0); 703 try_per_rate, rix, 0);
705 704
706 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 705 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
707 } else { 706 } else {
708 /* Set the choosen rate. No RTS for first series entry. */ 707 /* Set the choosen rate. No RTS for first series entry. */
709 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 708 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
710 try_per_rate, nrix, 0); 709 try_per_rate, rix, 0);
711 } 710 }
712 711
713 /* Fill in the other rates for multirate retry */ 712 /* Fill in the other rates for multirate retry */
714 for ( ; i < 4; i++) { 713 for ( ; i < 4; i++) {
715 /* Use twice the number of tries for the last MRR segment. */ 714 /* Use twice the number of tries for the last MRR segment. */
716 if (i + 1 == 4) 715 if (i + 1 == 4)
717 try_per_rate = 4; 716 try_per_rate = 8;
718 717
719 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 718 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
720 /* All other rates in the series have RTS enabled */ 719 /* All other rates in the series have RTS enabled */
721 ath_rc_rate_set_series(rate_table, &rates[i], txrc, 720 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
722 try_per_rate, nrix, 1); 721 try_per_rate, rix, 1);
723 } 722 }
724 723
725 /* 724 /*
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 9eb96f506998..4f6d6fd442f4 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -57,6 +57,10 @@ enum {
57 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 57 || (_phy == WLAN_RC_PHY_HT_40_DS) \
58 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ 58 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
59 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) 59 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
60#define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \
61 || (_phy == WLAN_RC_PHY_HT_20_DS) \
62 || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
63 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI))
60#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ 64#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
61 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 65 || (_phy == WLAN_RC_PHY_HT_40_DS) \
62 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ 66 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 477365e5ae69..1ca42e5148c8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -364,10 +364,10 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
364 if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) 364 if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
365 return; /* not from our current AP */ 365 return; /* not from our current AP */
366 366
367 sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; 367 sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
368 368
369 if (sc->sc_flags & SC_OP_BEACON_SYNC) { 369 if (sc->ps_flags & PS_BEACON_SYNC) {
370 sc->sc_flags &= ~SC_OP_BEACON_SYNC; 370 sc->ps_flags &= ~PS_BEACON_SYNC;
371 ath_print(common, ATH_DBG_PS, 371 ath_print(common, ATH_DBG_PS,
372 "Reconfigure Beacon timers based on " 372 "Reconfigure Beacon timers based on "
373 "timestamp from the AP\n"); 373 "timestamp from the AP\n");
@@ -384,17 +384,17 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
384 */ 384 */
385 ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " 385 ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
386 "buffered broadcast/multicast frame(s)\n"); 386 "buffered broadcast/multicast frame(s)\n");
387 sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON; 387 sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON;
388 return; 388 return;
389 } 389 }
390 390
391 if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) { 391 if (sc->ps_flags & PS_WAIT_FOR_CAB) {
392 /* 392 /*
393 * This can happen if a broadcast frame is dropped or the AP 393 * This can happen if a broadcast frame is dropped or the AP
394 * fails to send a frame indicating that all CAB frames have 394 * fails to send a frame indicating that all CAB frames have
395 * been delivered. 395 * been delivered.
396 */ 396 */
397 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; 397 sc->ps_flags &= ~PS_WAIT_FOR_CAB;
398 ath_print(common, ATH_DBG_PS, 398 ath_print(common, ATH_DBG_PS,
399 "PS wait for CAB frames timed out\n"); 399 "PS wait for CAB frames timed out\n");
400 } 400 }
@@ -408,10 +408,10 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
408 hdr = (struct ieee80211_hdr *)skb->data; 408 hdr = (struct ieee80211_hdr *)skb->data;
409 409
410 /* Process Beacon and CAB receive in PS state */ 410 /* Process Beacon and CAB receive in PS state */
411 if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) && 411 if ((sc->ps_flags & PS_WAIT_FOR_BEACON) &&
412 ieee80211_is_beacon(hdr->frame_control)) 412 ieee80211_is_beacon(hdr->frame_control))
413 ath_rx_ps_beacon(sc, skb); 413 ath_rx_ps_beacon(sc, skb);
414 else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) && 414 else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
415 (ieee80211_is_data(hdr->frame_control) || 415 (ieee80211_is_data(hdr->frame_control) ||
416 ieee80211_is_action(hdr->frame_control)) && 416 ieee80211_is_action(hdr->frame_control)) &&
417 is_multicast_ether_addr(hdr->addr1) && 417 is_multicast_ether_addr(hdr->addr1) &&
@@ -420,20 +420,20 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
420 * No more broadcast/multicast frames to be received at this 420 * No more broadcast/multicast frames to be received at this
421 * point. 421 * point.
422 */ 422 */
423 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; 423 sc->ps_flags &= ~PS_WAIT_FOR_CAB;
424 ath_print(common, ATH_DBG_PS, 424 ath_print(common, ATH_DBG_PS,
425 "All PS CAB frames received, back to sleep\n"); 425 "All PS CAB frames received, back to sleep\n");
426 } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) && 426 } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
427 !is_multicast_ether_addr(hdr->addr1) && 427 !is_multicast_ether_addr(hdr->addr1) &&
428 !ieee80211_has_morefrags(hdr->frame_control)) { 428 !ieee80211_has_morefrags(hdr->frame_control)) {
429 sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA; 429 sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
430 ath_print(common, ATH_DBG_PS, 430 ath_print(common, ATH_DBG_PS,
431 "Going back to sleep after having received " 431 "Going back to sleep after having received "
432 "PS-Poll data (0x%x)\n", 432 "PS-Poll data (0x%lx)\n",
433 sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 433 sc->ps_flags & (PS_WAIT_FOR_BEACON |
434 SC_OP_WAIT_FOR_CAB | 434 PS_WAIT_FOR_CAB |
435 SC_OP_WAIT_FOR_PSPOLL_DATA | 435 PS_WAIT_FOR_PSPOLL_DATA |
436 SC_OP_WAIT_FOR_TX_ACK)); 436 PS_WAIT_FOR_TX_ACK));
437 } 437 }
438} 438}
439 439
@@ -571,6 +571,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
571 hw = ath_get_virt_hw(sc, hdr); 571 hw = ath_get_virt_hw(sc, hdr);
572 rx_stats = &ds->ds_rxstat; 572 rx_stats = &ds->ds_rxstat;
573 573
574 ath_debug_stat_rx(sc, bf);
575
574 /* 576 /*
575 * If we're asked to flush receive queue, directly 577 * If we're asked to flush receive queue, directly
576 * chain it back at the queue without processing it. 578 * chain it back at the queue without processing it.
@@ -631,9 +633,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
631 sc->rx.rxotherant = 0; 633 sc->rx.rxotherant = 0;
632 } 634 }
633 635
634 if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 636 if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON |
635 SC_OP_WAIT_FOR_CAB | 637 PS_WAIT_FOR_CAB |
636 SC_OP_WAIT_FOR_PSPOLL_DATA))) 638 PS_WAIT_FOR_PSPOLL_DATA)))
637 ath_rx_ps(sc, skb); 639 ath_rx_ps(sc, skb);
638 640
639 ath_rx_send_to_mac80211(hw, sc, skb, rxs); 641 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8e653fb937a1..72cfa8ebd9ae 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1547,9 +1547,9 @@ enum {
1547 1547
1548#define AR_BT_COEX_WEIGHT 0x8174 1548#define AR_BT_COEX_WEIGHT 0x8174
1549#define AR_BT_COEX_WGHT 0xff55 1549#define AR_BT_COEX_WGHT 0xff55
1550#define AR_STOMP_ALL_WLAN_WGHT 0xffcc 1550#define AR_STOMP_ALL_WLAN_WGHT 0xfcfc
1551#define AR_STOMP_LOW_WLAN_WGHT 0xaaa8 1551#define AR_STOMP_LOW_WLAN_WGHT 0xa8a8
1552#define AR_STOMP_NONE_WLAN_WGHT 0xaa00 1552#define AR_STOMP_NONE_WLAN_WGHT 0x0000
1553#define AR_BTCOEX_BT_WGHT 0x0000ffff 1553#define AR_BTCOEX_BT_WGHT 0x0000ffff
1554#define AR_BTCOEX_BT_WGHT_S 0 1554#define AR_BTCOEX_BT_WGHT_S 0
1555#define AR_BTCOEX_WL_WGHT 0xffff0000 1555#define AR_BTCOEX_WL_WGHT 0xffff0000
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index cd26caaf44e7..a43fbf84dab9 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -152,7 +152,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
152 152
153 SET_IEEE80211_PERM_ADDR(hw, addr); 153 SET_IEEE80211_PERM_ADDR(hw, addr);
154 154
155 ath_set_hw_capab(sc, hw); 155 ath9k_set_hw_capab(sc, hw);
156 156
157 error = ieee80211_register_hw(hw); 157 error = ieee80211_register_hw(hw);
158 158
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 29bf33692f71..47294f90bbe5 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1498 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 1498 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
1499 ctsrate |= rate->hw_value_short; 1499 ctsrate |= rate->hw_value_short;
1500 1500
1501 /*
1502 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
1503 * Check the first rate in the series to decide whether RTS/CTS
1504 * or CTS-to-self has to be used.
1505 */
1506 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1507 flags = ATH9K_TXDESC_CTSENA;
1508 else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
1509 flags = ATH9K_TXDESC_RTSENA;
1510
1511 /* FIXME: Handle aggregation protection */
1512 if (sc->config.ath_aggr_prot &&
1513 (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
1514 flags = ATH9K_TXDESC_RTSENA;
1515 }
1516
1517 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1518 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
1519 flags &= ~(ATH9K_TXDESC_RTSENA);
1520
1521 for (i = 0; i < 4; i++) { 1501 for (i = 0; i < 4; i++) {
1522 bool is_40, is_sgi, is_sp; 1502 bool is_40, is_sgi, is_sp;
1523 int phy; 1503 int phy;
@@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1529 series[i].Tries = rates[i].count; 1509 series[i].Tries = rates[i].count;
1530 series[i].ChSel = common->tx_chainmask; 1510 series[i].ChSel = common->tx_chainmask;
1531 1511
1532 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) 1512 if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
1513 (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
1533 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; 1514 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1515 flags |= ATH9K_TXDESC_RTSENA;
1516 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
1517 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1518 flags |= ATH9K_TXDESC_CTSENA;
1519 }
1520
1534 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1521 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1535 series[i].RateFlags |= ATH9K_RATESERIES_2040; 1522 series[i].RateFlags |= ATH9K_RATESERIES_2040;
1536 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) 1523 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
@@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1568 phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); 1555 phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
1569 } 1556 }
1570 1557
1558 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1559 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
1560 flags &= ~ATH9K_TXDESC_RTSENA;
1561
1562 /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
1563 if (flags & ATH9K_TXDESC_RTSENA)
1564 flags &= ~ATH9K_TXDESC_CTSENA;
1565
1571 /* set dur_update_en for l-sig computation except for PS-Poll frames */ 1566 /* set dur_update_en for l-sig computation except for PS-Poll frames */
1572 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, 1567 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
1573 bf->bf_lastbf->bf_desc, 1568 bf->bf_lastbf->bf_desc,
@@ -1648,7 +1643,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1648 /* tag if this is a nullfunc frame to enable PS when AP acks it */ 1643 /* tag if this is a nullfunc frame to enable PS when AP acks it */
1649 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { 1644 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
1650 bf->bf_isnullfunc = true; 1645 bf->bf_isnullfunc = true;
1651 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; 1646 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1652 } else 1647 } else
1653 bf->bf_isnullfunc = false; 1648 bf->bf_isnullfunc = false;
1654 1649
@@ -1858,15 +1853,15 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1858 skb_pull(skb, padsize); 1853 skb_pull(skb, padsize);
1859 } 1854 }
1860 1855
1861 if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) { 1856 if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
1862 sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK; 1857 sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
1863 ath_print(common, ATH_DBG_PS, 1858 ath_print(common, ATH_DBG_PS,
1864 "Going back to sleep after having " 1859 "Going back to sleep after having "
1865 "received TX status (0x%x)\n", 1860 "received TX status (0x%lx)\n",
1866 sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 1861 sc->ps_flags & (PS_WAIT_FOR_BEACON |
1867 SC_OP_WAIT_FOR_CAB | 1862 PS_WAIT_FOR_CAB |
1868 SC_OP_WAIT_FOR_PSPOLL_DATA | 1863 PS_WAIT_FOR_PSPOLL_DATA |
1869 SC_OP_WAIT_FOR_TX_ACK)); 1864 PS_WAIT_FOR_TX_ACK));
1870 } 1865 }
1871 1866
1872 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) 1867 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
@@ -2053,11 +2048,10 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2053 */ 2048 */
2054 if (bf->bf_isnullfunc && 2049 if (bf->bf_isnullfunc &&
2055 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2050 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
2056 if ((sc->sc_flags & SC_OP_PS_ENABLED)) { 2051 if ((sc->ps_flags & PS_ENABLED))
2057 sc->ps_enabled = true; 2052 ath9k_enable_ps(sc);
2058 ath9k_hw_setrxabort(sc->sc_ah, 1); 2053 else
2059 } else 2054 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2060 sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
2061 } 2055 }
2062 2056
2063 /* 2057 /*
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index d6b685a06c5e..8263633c003c 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -65,11 +65,11 @@ enum ATH_DEBUG {
65#define ATH_DBG_DEFAULT (ATH_DBG_FATAL) 65#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
66 66
67#ifdef CONFIG_ATH_DEBUG 67#ifdef CONFIG_ATH_DEBUG
68void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...); 68void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
69 __attribute__ ((format (printf, 3, 4)));
69#else 70#else
70static inline void ath_print(struct ath_common *common, 71static inline void __attribute__ ((format (printf, 3, 4)))
71 int dbg_mask, 72ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
72 const char *fmt, ...)
73{ 73{
74} 74}
75#endif /* CONFIG_ATH_DEBUG */ 75#endif /* CONFIG_ATH_DEBUG */
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 039ac490465c..04abd1f556b7 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -110,8 +110,9 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
110 110
111static inline bool is_wwr_sku(u16 regd) 111static inline bool is_wwr_sku(u16 regd)
112{ 112{
113 return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 113 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
114 (regd == WORLD); 114 (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
115 (regd == WORLD));
115} 116}
116 117
117static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 118static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 64c12e1bced3..073be566d05e 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -3,6 +3,7 @@ config B43
3 depends on SSB_POSSIBLE && MAC80211 && HAS_DMA 3 depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
4 select SSB 4 select SSB
5 select FW_LOADER 5 select FW_LOADER
6 select SSB_BLOCKIO
6 ---help--- 7 ---help---
7 b43 is a driver for the Broadcom 43xx series wireless devices. 8 b43 is a driver for the Broadcom 43xx series wireless devices.
8 9
@@ -78,14 +79,6 @@ config B43_SDIO
78 79
79 If unsure, say N. 80 If unsure, say N.
80 81
81# Data transfers to the device via PIO
82# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
83config B43_PIO
84 bool
85 depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
86 select SSB_BLOCKIO
87 default y
88
89config B43_NPHY 82config B43_NPHY
90 bool "Pre IEEE 802.11n support (BROKEN)" 83 bool "Pre IEEE 802.11n support (BROKEN)"
91 depends on B43 && EXPERIMENTAL && BROKEN 84 depends on B43 && EXPERIMENTAL && BROKEN
@@ -137,12 +130,4 @@ config B43_DEBUG
137 for production use. 130 for production use.
138 Only say Y, if you are debugging a problem in the b43 driver sourcecode. 131 Only say Y, if you are debugging a problem in the b43 driver sourcecode.
139 132
140config B43_FORCE_PIO
141 bool "Force usage of PIO instead of DMA"
142 depends on B43 && B43_DEBUG
143 ---help---
144 This will disable DMA and always enable PIO instead.
145 133
146 Say N!
147 This is only for debugging the PIO engine code. You do
148 _NOT_ want to enable this.
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 84772a2542dc..5e83b6f0a3a0 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -12,7 +12,7 @@ b43-y += xmit.o
12b43-y += lo.o 12b43-y += lo.o
13b43-y += wa.o 13b43-y += wa.o
14b43-y += dma.o 14b43-y += dma.o
15b43-$(CONFIG_B43_PIO) += pio.o 15b43-y += pio.o
16b43-y += rfkill.o 16b43-y += rfkill.o
17b43-$(CONFIG_B43_LEDS) += leds.o 17b43-$(CONFIG_B43_LEDS) += leds.o
18b43-$(CONFIG_B43_PCMCIA) += pcmcia.o 18b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index c484cc253892..6a6ab0f630e5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -254,6 +254,14 @@ enum {
254#define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */ 254#define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */
255#define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */ 255#define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */
256#define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */ 256#define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */
257/* SHM_SHARED tx iq workarounds */
258#define B43_SHM_SH_NPHY_TXIQW0 0x0700
259#define B43_SHM_SH_NPHY_TXIQW1 0x0702
260#define B43_SHM_SH_NPHY_TXIQW2 0x0704
261#define B43_SHM_SH_NPHY_TXIQW3 0x0706
262/* SHM_SHARED tx pwr ctrl */
263#define B43_SHM_SH_NPHY_TXPWR_INDX0 0x0708
264#define B43_SHM_SH_NPHY_TXPWR_INDX1 0x070E
257 265
258/* SHM_SCRATCH offsets */ 266/* SHM_SCRATCH offsets */
259#define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */ 267#define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */
@@ -822,11 +830,9 @@ struct b43_wl {
822 /* The device LEDs. */ 830 /* The device LEDs. */
823 struct b43_leds leds; 831 struct b43_leds leds;
824 832
825#ifdef CONFIG_B43_PIO
826 /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */ 833 /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
827 u8 pio_scratchspace[110] __attribute__((__aligned__(8))); 834 u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
828 u8 pio_tailspace[4] __attribute__((__aligned__(8))); 835 u8 pio_tailspace[4] __attribute__((__aligned__(8)));
829#endif /* CONFIG_B43_PIO */
830}; 836};
831 837
832static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) 838static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
@@ -877,20 +883,9 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
877 883
878static inline bool b43_using_pio_transfers(struct b43_wldev *dev) 884static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
879{ 885{
880#ifdef CONFIG_B43_PIO
881 return dev->__using_pio_transfers; 886 return dev->__using_pio_transfers;
882#else
883 return 0;
884#endif
885} 887}
886 888
887#ifdef CONFIG_B43_FORCE_PIO
888# define B43_FORCE_PIO 1
889#else
890# define B43_FORCE_PIO 0
891#endif
892
893
894/* Message printing */ 889/* Message printing */
895void b43info(struct b43_wl *wl, const char *fmt, ...) 890void b43info(struct b43_wl *wl, const char *fmt, ...)
896 __attribute__ ((format(printf, 2, 3))); 891 __attribute__ ((format(printf, 2, 3)));
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 88d1fd02d40a..be7abf8916ad 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1369,7 +1369,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1369 b43err(dev->wl, "DMA tx mapping failure\n"); 1369 b43err(dev->wl, "DMA tx mapping failure\n");
1370 goto out; 1370 goto out;
1371 } 1371 }
1372 ring->nr_tx_packets++;
1373 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || 1372 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
1374 should_inject_overflow(ring)) { 1373 should_inject_overflow(ring)) {
1375 /* This TX ring is full. */ 1374 /* This TX ring is full. */
@@ -1500,22 +1499,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1500 } 1499 }
1501} 1500}
1502 1501
1503void b43_dma_get_tx_stats(struct b43_wldev *dev,
1504 struct ieee80211_tx_queue_stats *stats)
1505{
1506 const int nr_queues = dev->wl->hw->queues;
1507 struct b43_dmaring *ring;
1508 int i;
1509
1510 for (i = 0; i < nr_queues; i++) {
1511 ring = select_ring_by_priority(dev, i);
1512
1513 stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
1514 stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
1515 stats[i].count = ring->nr_tx_packets;
1516 }
1517}
1518
1519static void dma_rx(struct b43_dmaring *ring, int *slot) 1502static void dma_rx(struct b43_dmaring *ring, int *slot)
1520{ 1503{
1521 const struct b43_dma_ops *ops = ring->ops; 1504 const struct b43_dma_ops *ops = ring->ops;
@@ -1653,7 +1636,6 @@ void b43_dma_tx_resume(struct b43_wldev *dev)
1653 b43_power_saving_ctl_bits(dev, 0); 1636 b43_power_saving_ctl_bits(dev, 0);
1654} 1637}
1655 1638
1656#ifdef CONFIG_B43_PIO
1657static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, 1639static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
1658 u16 mmio_base, bool enable) 1640 u16 mmio_base, bool enable)
1659{ 1641{
@@ -1687,4 +1669,3 @@ void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
1687 mmio_base = b43_dmacontroller_base(type, engine_index); 1669 mmio_base = b43_dmacontroller_base(type, engine_index);
1688 direct_fifo_rx(dev, type, mmio_base, enable); 1670 direct_fifo_rx(dev, type, mmio_base, enable);
1689} 1671}
1690#endif /* CONFIG_B43_PIO */
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index f7ab37c4cdbc..dc91944d6022 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -228,8 +228,6 @@ struct b43_dmaring {
228 int used_slots; 228 int used_slots;
229 /* Currently used slot in the ring. */ 229 /* Currently used slot in the ring. */
230 int current_slot; 230 int current_slot;
231 /* Total number of packets sent. Statistics only. */
232 unsigned int nr_tx_packets;
233 /* Frameoffset in octets. */ 231 /* Frameoffset in octets. */
234 u32 frameoffset; 232 u32 frameoffset;
235 /* Descriptor buffer size. */ 233 /* Descriptor buffer size. */
@@ -278,9 +276,6 @@ void b43_dma_free(struct b43_wldev *dev);
278void b43_dma_tx_suspend(struct b43_wldev *dev); 276void b43_dma_tx_suspend(struct b43_wldev *dev);
279void b43_dma_tx_resume(struct b43_wldev *dev); 277void b43_dma_tx_resume(struct b43_wldev *dev);
280 278
281void b43_dma_get_tx_stats(struct b43_wldev *dev,
282 struct ieee80211_tx_queue_stats *stats);
283
284int b43_dma_tx(struct b43_wldev *dev, 279int b43_dma_tx(struct b43_wldev *dev,
285 struct sk_buff *skb); 280 struct sk_buff *skb);
286void b43_dma_handle_txstatus(struct b43_wldev *dev, 281void b43_dma_handle_txstatus(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index fcbf0e27d9f3..8f7a8c0ec27d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -67,7 +67,12 @@ MODULE_AUTHOR("Gábor Stefanik");
67MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
68 68
69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); 69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
70 70MODULE_FIRMWARE("b43/ucode11.fw");
71MODULE_FIRMWARE("b43/ucode13.fw");
72MODULE_FIRMWARE("b43/ucode14.fw");
73MODULE_FIRMWARE("b43/ucode15.fw");
74MODULE_FIRMWARE("b43/ucode5.fw");
75MODULE_FIRMWARE("b43/ucode9.fw");
71 76
72static int modparam_bad_frames_preempt; 77static int modparam_bad_frames_preempt;
73module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); 78module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
@@ -102,6 +107,9 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
102module_param_named(verbose, b43_modparam_verbose, int, 0644); 107module_param_named(verbose, b43_modparam_verbose, int, 0644);
103MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); 108MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
104 109
110static int modparam_pio;
111module_param_named(pio, modparam_pio, int, 0444);
112MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
105 113
106static const struct ssb_device_id b43_ssb_tbl[] = { 114static const struct ssb_device_id b43_ssb_tbl[] = {
107 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), 115 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -110,6 +118,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
110 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), 118 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
111 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), 119 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
112 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), 120 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
121 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 12),
113 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), 122 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
114 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), 123 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
115 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), 124 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
@@ -842,8 +851,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
842} 851}
843 852
844static void b43_op_update_tkip_key(struct ieee80211_hw *hw, 853static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
845 struct ieee80211_key_conf *keyconf, const u8 *addr, 854 struct ieee80211_vif *vif,
846 u32 iv32, u16 *phase1key) 855 struct ieee80211_key_conf *keyconf,
856 struct ieee80211_sta *sta,
857 u32 iv32, u16 *phase1key)
847{ 858{
848 struct b43_wl *wl = hw_to_b43_wl(hw); 859 struct b43_wl *wl = hw_to_b43_wl(hw);
849 struct b43_wldev *dev; 860 struct b43_wldev *dev;
@@ -852,19 +863,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
852 if (B43_WARN_ON(!modparam_hwtkip)) 863 if (B43_WARN_ON(!modparam_hwtkip))
853 return; 864 return;
854 865
855 mutex_lock(&wl->mutex); 866 /* This is only called from the RX path through mac80211, where
856 867 * our mutex is already locked. */
868 B43_WARN_ON(!mutex_is_locked(&wl->mutex));
857 dev = wl->current_dev; 869 dev = wl->current_dev;
858 if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) 870 B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
859 goto out_unlock;
860 871
861 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ 872 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
862 873
863 rx_tkip_phase1_write(dev, index, iv32, phase1key); 874 rx_tkip_phase1_write(dev, index, iv32, phase1key);
864 keymac_write(dev, index, addr); 875 /* only pairwise TKIP keys are supported right now */
865 876 if (WARN_ON(!sta))
866out_unlock: 877 return;
867 mutex_unlock(&wl->mutex); 878 keymac_write(dev, index, sta->addr);
868} 879}
869 880
870static void do_key_write(struct b43_wldev *dev, 881static void do_key_write(struct b43_wldev *dev,
@@ -1793,8 +1804,8 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
1793 dma_reason[4], dma_reason[5]); 1804 dma_reason[4], dma_reason[5]);
1794 b43err(dev->wl, "This device does not support DMA " 1805 b43err(dev->wl, "This device does not support DMA "
1795 "on your system. Please use PIO instead.\n"); 1806 "on your system. Please use PIO instead.\n");
1796 b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in " 1807 b43err(dev->wl, "Unload the b43 module and reload "
1797 "your kernel configuration.\n"); 1808 "with 'pio=1'\n");
1798 return; 1809 return;
1799 } 1810 }
1800 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { 1811 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -3345,27 +3356,6 @@ out_unlock:
3345 return err; 3356 return err;
3346} 3357}
3347 3358
3348static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
3349 struct ieee80211_tx_queue_stats *stats)
3350{
3351 struct b43_wl *wl = hw_to_b43_wl(hw);
3352 struct b43_wldev *dev;
3353 int err = -ENODEV;
3354
3355 mutex_lock(&wl->mutex);
3356 dev = wl->current_dev;
3357 if (dev && b43_status(dev) >= B43_STAT_STARTED) {
3358 if (b43_using_pio_transfers(dev))
3359 b43_pio_get_tx_stats(dev, stats);
3360 else
3361 b43_dma_get_tx_stats(dev, stats);
3362 err = 0;
3363 }
3364 mutex_unlock(&wl->mutex);
3365
3366 return err;
3367}
3368
3369static int b43_op_get_stats(struct ieee80211_hw *hw, 3359static int b43_op_get_stats(struct ieee80211_hw *hw,
3370 struct ieee80211_low_level_stats *stats) 3360 struct ieee80211_low_level_stats *stats)
3371{ 3361{
@@ -3569,6 +3559,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3569 dev = wl->current_dev; 3559 dev = wl->current_dev;
3570 phy = &dev->phy; 3560 phy = &dev->phy;
3571 3561
3562 if (conf_is_ht(conf))
3563 phy->is_40mhz =
3564 (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
3565 else
3566 phy->is_40mhz = false;
3567
3572 b43_mac_suspend(dev); 3568 b43_mac_suspend(dev);
3573 3569
3574 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) 3570 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
@@ -3970,6 +3966,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3970 } 3966 }
3971 3967
3972 /* We are ready to run. */ 3968 /* We are ready to run. */
3969 ieee80211_wake_queues(dev->wl->hw);
3973 b43_set_status(dev, B43_STAT_STARTED); 3970 b43_set_status(dev, B43_STAT_STARTED);
3974 3971
3975 /* Start data flow (TX/RX). */ 3972 /* Start data flow (TX/RX). */
@@ -4360,7 +4357,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4360 4357
4361 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || 4358 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
4362 (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || 4359 (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
4363 B43_FORCE_PIO) { 4360 modparam_pio) {
4364 dev->__using_pio_transfers = 1; 4361 dev->__using_pio_transfers = 1;
4365 err = b43_pio_init(dev); 4362 err = b43_pio_init(dev);
4366 } else { 4363 } else {
@@ -4379,8 +4376,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4379 4376
4380 ieee80211_wake_queues(dev->wl->hw); 4377 ieee80211_wake_queues(dev->wl->hw);
4381 4378
4382 ieee80211_wake_queues(dev->wl->hw);
4383
4384 b43_set_status(dev, B43_STAT_INITIALIZED); 4379 b43_set_status(dev, B43_STAT_INITIALIZED);
4385 4380
4386out: 4381out:
@@ -4395,7 +4390,7 @@ err_busdown:
4395} 4390}
4396 4391
4397static int b43_op_add_interface(struct ieee80211_hw *hw, 4392static int b43_op_add_interface(struct ieee80211_hw *hw,
4398 struct ieee80211_if_init_conf *conf) 4393 struct ieee80211_vif *vif)
4399{ 4394{
4400 struct b43_wl *wl = hw_to_b43_wl(hw); 4395 struct b43_wl *wl = hw_to_b43_wl(hw);
4401 struct b43_wldev *dev; 4396 struct b43_wldev *dev;
@@ -4403,24 +4398,24 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4403 4398
4404 /* TODO: allow WDS/AP devices to coexist */ 4399 /* TODO: allow WDS/AP devices to coexist */
4405 4400
4406 if (conf->type != NL80211_IFTYPE_AP && 4401 if (vif->type != NL80211_IFTYPE_AP &&
4407 conf->type != NL80211_IFTYPE_MESH_POINT && 4402 vif->type != NL80211_IFTYPE_MESH_POINT &&
4408 conf->type != NL80211_IFTYPE_STATION && 4403 vif->type != NL80211_IFTYPE_STATION &&
4409 conf->type != NL80211_IFTYPE_WDS && 4404 vif->type != NL80211_IFTYPE_WDS &&
4410 conf->type != NL80211_IFTYPE_ADHOC) 4405 vif->type != NL80211_IFTYPE_ADHOC)
4411 return -EOPNOTSUPP; 4406 return -EOPNOTSUPP;
4412 4407
4413 mutex_lock(&wl->mutex); 4408 mutex_lock(&wl->mutex);
4414 if (wl->operating) 4409 if (wl->operating)
4415 goto out_mutex_unlock; 4410 goto out_mutex_unlock;
4416 4411
4417 b43dbg(wl, "Adding Interface type %d\n", conf->type); 4412 b43dbg(wl, "Adding Interface type %d\n", vif->type);
4418 4413
4419 dev = wl->current_dev; 4414 dev = wl->current_dev;
4420 wl->operating = 1; 4415 wl->operating = 1;
4421 wl->vif = conf->vif; 4416 wl->vif = vif;
4422 wl->if_type = conf->type; 4417 wl->if_type = vif->type;
4423 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 4418 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
4424 4419
4425 b43_adjust_opmode(dev); 4420 b43_adjust_opmode(dev);
4426 b43_set_pretbtt(dev); 4421 b43_set_pretbtt(dev);
@@ -4435,17 +4430,17 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4435} 4430}
4436 4431
4437static void b43_op_remove_interface(struct ieee80211_hw *hw, 4432static void b43_op_remove_interface(struct ieee80211_hw *hw,
4438 struct ieee80211_if_init_conf *conf) 4433 struct ieee80211_vif *vif)
4439{ 4434{
4440 struct b43_wl *wl = hw_to_b43_wl(hw); 4435 struct b43_wl *wl = hw_to_b43_wl(hw);
4441 struct b43_wldev *dev = wl->current_dev; 4436 struct b43_wldev *dev = wl->current_dev;
4442 4437
4443 b43dbg(wl, "Removing Interface type %d\n", conf->type); 4438 b43dbg(wl, "Removing Interface type %d\n", vif->type);
4444 4439
4445 mutex_lock(&wl->mutex); 4440 mutex_lock(&wl->mutex);
4446 4441
4447 B43_WARN_ON(!wl->operating); 4442 B43_WARN_ON(!wl->operating);
4448 B43_WARN_ON(wl->vif != conf->vif); 4443 B43_WARN_ON(wl->vif != vif);
4449 wl->vif = NULL; 4444 wl->vif = NULL;
4450 4445
4451 wl->operating = 0; 4446 wl->operating = 0;
@@ -4586,7 +4581,6 @@ static const struct ieee80211_ops b43_hw_ops = {
4586 .set_key = b43_op_set_key, 4581 .set_key = b43_op_set_key,
4587 .update_tkip_key = b43_op_update_tkip_key, 4582 .update_tkip_key = b43_op_update_tkip_key,
4588 .get_stats = b43_op_get_stats, 4583 .get_stats = b43_op_get_stats,
4589 .get_tx_stats = b43_op_get_tx_stats,
4590 .get_tsf = b43_op_get_tsf, 4584 .get_tsf = b43_op_get_tsf,
4591 .set_tsf = b43_op_set_tsf, 4585 .set_tsf = b43_op_set_tsf,
4592 .start = b43_op_start, 4586 .start = b43_op_start,
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 75b26e175e8f..8f7d7eff2d80 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
421{ 421{
422 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); 422 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
423} 423}
424
425/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
426struct b43_c32 b43_cordic(int theta)
427{
428 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
429 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
430 229, 115, 57, 29, };
431 u8 i;
432 s32 tmp;
433 s8 signx = 1;
434 u32 angle = 0;
435 struct b43_c32 ret = { .i = 39797, .q = 0, };
436
437 while (theta > (180 << 16))
438 theta -= (360 << 16);
439 while (theta < -(180 << 16))
440 theta += (360 << 16);
441
442 if (theta > (90 << 16)) {
443 theta -= (180 << 16);
444 signx = -1;
445 } else if (theta < -(90 << 16)) {
446 theta += (180 << 16);
447 signx = -1;
448 }
449
450 for (i = 0; i <= 17; i++) {
451 if (theta > angle) {
452 tmp = ret.i - (ret.q >> i);
453 ret.q += ret.i >> i;
454 ret.i = tmp;
455 angle += arctg[i];
456 } else {
457 tmp = ret.i + (ret.q >> i);
458 ret.q -= ret.i >> i;
459 ret.i = tmp;
460 angle -= arctg[i];
461 }
462 }
463
464 ret.i *= signx;
465 ret.q *= signx;
466
467 return ret;
468}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 9edd4e8e0c85..bd480b481bfc 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -5,6 +5,12 @@
5 5
6struct b43_wldev; 6struct b43_wldev;
7 7
8/* Complex number using 2 32-bit signed integers */
9struct b43_c32 { s32 i, q; };
10
11#define CORDIC_CONVERT(value) (((value) >= 0) ? \
12 ((((value) >> 15) + 1) >> 1) : \
13 -((((-(value)) >> 15) + 1) >> 1))
8 14
9/* PHY register routing bits */ 15/* PHY register routing bits */
10#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ 16#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
@@ -212,6 +218,9 @@ struct b43_phy {
212 bool supports_2ghz; 218 bool supports_2ghz;
213 bool supports_5ghz; 219 bool supports_5ghz;
214 220
221 /* HT info */
222 bool is_40mhz;
223
215 /* GMODE bit enabled? */ 224 /* GMODE bit enabled? */
216 bool gmode; 225 bool gmode;
217 226
@@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
418 */ 427 */
419void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); 428void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
420 429
430struct b43_c32 b43_cordic(int theta);
421 431
422#endif /* LINUX_B43_PHY_COMMON_H_ */ 432#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3e046ec1ff86..185219e0a552 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -80,6 +80,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
80 dev->phy.lp = NULL; 80 dev->phy.lp = NULL;
81} 81}
82 82
83/* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
83static void lpphy_read_band_sprom(struct b43_wldev *dev) 84static void lpphy_read_band_sprom(struct b43_wldev *dev)
84{ 85{
85 struct b43_phy_lp *lpphy = dev->phy.lp; 86 struct b43_phy_lp *lpphy = dev->phy.lp;
@@ -101,6 +102,12 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
101 maxpwr = bus->sprom.maxpwr_bg; 102 maxpwr = bus->sprom.maxpwr_bg;
102 lpphy->max_tx_pwr_med_band = maxpwr; 103 lpphy->max_tx_pwr_med_band = maxpwr;
103 cckpo = bus->sprom.cck2gpo; 104 cckpo = bus->sprom.cck2gpo;
105 /*
106 * We don't read SPROM's opo as specs say. On rev8 SPROMs
107 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
108 * and SPROM rev below 8.
109 */
110 B43_WARN_ON(bus->sprom.revision < 8);
104 ofdmpo = bus->sprom.ofdm2gpo; 111 ofdmpo = bus->sprom.ofdm2gpo;
105 if (cckpo) { 112 if (cckpo) {
106 for (i = 0; i < 4; i++) { 113 for (i = 0; i < 4; i++) {
@@ -1703,19 +1710,6 @@ static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = {
1703 .c0 = 0, 1710 .c0 = 0,
1704}; 1711};
1705 1712
1706static u8 lpphy_nbits(s32 val)
1707{
1708 u32 tmp = abs(val);
1709 u8 nbits = 0;
1710
1711 while (tmp != 0) {
1712 nbits++;
1713 tmp >>= 1;
1714 }
1715
1716 return nbits;
1717}
1718
1719static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples) 1713static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
1720{ 1714{
1721 struct lpphy_iq_est iq_est; 1715 struct lpphy_iq_est iq_est;
@@ -1742,8 +1736,8 @@ static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
1742 goto out; 1736 goto out;
1743 } 1737 }
1744 1738
1745 prod_msb = lpphy_nbits(prod); 1739 prod_msb = fls(abs(prod));
1746 q_msb = lpphy_nbits(qpwr); 1740 q_msb = fls(abs(qpwr));
1747 tmp1 = prod_msb - 20; 1741 tmp1 = prod_msb - 20;
1748 1742
1749 if (tmp1 >= 0) { 1743 if (tmp1 >= 0) {
@@ -1773,47 +1767,6 @@ out:
1773 return ret; 1767 return ret;
1774} 1768}
1775 1769
1776/* Complex number using 2 32-bit signed integers */
1777typedef struct {s32 i, q;} lpphy_c32;
1778
1779static lpphy_c32 lpphy_cordic(int theta)
1780{
1781 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
1782 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
1783 229, 115, 57, 29, };
1784 int i, tmp, signx = 1, angle = 0;
1785 lpphy_c32 ret = { .i = 39797, .q = 0, };
1786
1787 theta = clamp_t(int, theta, -180, 180);
1788
1789 if (theta > 90) {
1790 theta -= 180;
1791 signx = -1;
1792 } else if (theta < -90) {
1793 theta += 180;
1794 signx = -1;
1795 }
1796
1797 for (i = 0; i <= 17; i++) {
1798 if (theta > angle) {
1799 tmp = ret.i - (ret.q >> i);
1800 ret.q += ret.i >> i;
1801 ret.i = tmp;
1802 angle += arctg[i];
1803 } else {
1804 tmp = ret.i + (ret.q >> i);
1805 ret.q -= ret.i >> i;
1806 ret.i = tmp;
1807 angle -= arctg[i];
1808 }
1809 }
1810
1811 ret.i *= signx;
1812 ret.q *= signx;
1813
1814 return ret;
1815}
1816
1817static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, 1770static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
1818 u16 wait) 1771 u16 wait)
1819{ 1772{
@@ -1831,8 +1784,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1831{ 1784{
1832 struct b43_phy_lp *lpphy = dev->phy.lp; 1785 struct b43_phy_lp *lpphy = dev->phy.lp;
1833 u16 buf[64]; 1786 u16 buf[64];
1834 int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; 1787 int i, samples = 0, angle = 0;
1835 lpphy_c32 sample; 1788 int rotation = (((36 * freq) / 20) << 16) / 100;
1789 struct b43_c32 sample;
1836 1790
1837 lpphy->tx_tone_freq = freq; 1791 lpphy->tx_tone_freq = freq;
1838 1792
@@ -1848,10 +1802,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1848 } 1802 }
1849 1803
1850 for (i = 0; i < samples; i++) { 1804 for (i = 0; i < samples; i++) {
1851 sample = lpphy_cordic(angle); 1805 sample = b43_cordic(angle);
1852 angle += rotation; 1806 angle += rotation;
1853 buf[i] = ((sample.i * max) & 0xFF) << 8; 1807 buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
1854 buf[i] |= (sample.q * max) & 0xFF; 1808 buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
1855 } 1809 }
1856 1810
1857 b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); 1811 b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 992318a78077..795bb1e3345d 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -28,7 +28,50 @@
28#include "b43.h" 28#include "b43.h"
29#include "phy_n.h" 29#include "phy_n.h"
30#include "tables_nphy.h" 30#include "tables_nphy.h"
31#include "main.h"
31 32
33struct nphy_txgains {
34 u16 txgm[2];
35 u16 pga[2];
36 u16 pad[2];
37 u16 ipa[2];
38};
39
40struct nphy_iqcal_params {
41 u16 txgm;
42 u16 pga;
43 u16 pad;
44 u16 ipa;
45 u16 cal_gain;
46 u16 ncorr[5];
47};
48
49struct nphy_iq_est {
50 s32 iq0_prod;
51 u32 i0_pwr;
52 u32 q0_pwr;
53 s32 iq1_prod;
54 u32 i1_pwr;
55 u32 q1_pwr;
56};
57
58enum b43_nphy_rf_sequence {
59 B43_RFSEQ_RX2TX,
60 B43_RFSEQ_TX2RX,
61 B43_RFSEQ_RESET2RX,
62 B43_RFSEQ_UPDATE_GAINH,
63 B43_RFSEQ_UPDATE_GAINL,
64 B43_RFSEQ_UPDATE_GAINU,
65};
66
67static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
68 u8 *events, u8 *delays, u8 length);
69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
70 enum b43_nphy_rf_sequence seq);
71static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
72 u16 value, u8 core, bool off);
73static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
74 u16 value, u8 core);
32 75
33void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 76void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
34{//TODO 77{//TODO
@@ -197,173 +240,1020 @@ void b43_nphy_radio_turn_off(struct b43_wldev *dev)
197 ~B43_NPHY_RFCTL_CMD_EN); 240 ~B43_NPHY_RFCTL_CMD_EN);
198} 241}
199 242
200#define ntab_upload(dev, offset, data) do { \ 243/*
201 unsigned int i; \ 244 * Upload the N-PHY tables.
202 for (i = 0; i < (offset##_SIZE); i++) \ 245 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables
203 b43_ntab_write(dev, (offset) + i, (data)[i]); \ 246 */
204 } while (0)
205
206/* Upload the N-PHY tables. */
207static void b43_nphy_tables_init(struct b43_wldev *dev) 247static void b43_nphy_tables_init(struct b43_wldev *dev)
208{ 248{
209 /* Static tables */ 249 if (dev->phy.rev < 3)
210 ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); 250 b43_nphy_rev0_1_2_tables_init(dev);
211 ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup); 251 else
212 ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap); 252 b43_nphy_rev3plus_tables_init(dev);
213 ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn); 253}
214 ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel); 254
215 ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot); 255/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
216 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); 256static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
217 ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0); 257{
218 ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1); 258 struct b43_phy_n *nphy = dev->phy.n;
219 ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0); 259 enum ieee80211_band band;
220 ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1); 260 u16 tmp;
221 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); 261
222 ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest); 262 if (!enable) {
223 ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs); 263 nphy->rfctrl_intc1_save = b43_phy_read(dev,
224 264 B43_NPHY_RFCTL_INTC1);
225 /* Volatile tables */ 265 nphy->rfctrl_intc2_save = b43_phy_read(dev,
226 ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10); 266 B43_NPHY_RFCTL_INTC2);
227 ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11); 267 band = b43_current_band(dev->wl);
228 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); 268 if (dev->phy.rev >= 3) {
229 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); 269 if (band == IEEE80211_BAND_5GHZ)
230 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); 270 tmp = 0x600;
231 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); 271 else
232 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); 272 tmp = 0x480;
233 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); 273 } else {
234 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); 274 if (band == IEEE80211_BAND_5GHZ)
235 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); 275 tmp = 0x180;
236 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); 276 else
237 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); 277 tmp = 0x120;
278 }
279 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
280 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
281 } else {
282 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1,
283 nphy->rfctrl_intc1_save);
284 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2,
285 nphy->rfctrl_intc2_save);
286 }
238} 287}
239 288
240static void b43_nphy_workarounds(struct b43_wldev *dev) 289/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
290static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
291{
292 struct b43_phy_n *nphy = dev->phy.n;
293 u16 tmp;
294 enum ieee80211_band band = b43_current_band(dev->wl);
295 bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
296 (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ);
297
298 if (dev->phy.rev >= 3) {
299 if (ipa) {
300 tmp = 4;
301 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
302 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
303 }
304
305 tmp = 1;
306 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
307 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
308 }
309}
310
311/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
312static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
313{
314 u32 tmslow;
315
316 if (dev->phy.type != B43_PHYTYPE_N)
317 return;
318
319 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
320 if (force)
321 tmslow |= SSB_TMSLOW_FGC;
322 else
323 tmslow &= ~SSB_TMSLOW_FGC;
324 ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
325}
326
327/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
328static void b43_nphy_reset_cca(struct b43_wldev *dev)
329{
330 u16 bbcfg;
331
332 b43_nphy_bmac_clock_fgc(dev, 1);
333 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
334 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
335 udelay(1);
336 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
337 b43_nphy_bmac_clock_fgc(dev, 0);
338 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
339}
340
341/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
342static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
343{
344 u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
345
346 mimocfg |= B43_NPHY_MIMOCFG_AUTO;
347 if (preamble == 1)
348 mimocfg |= B43_NPHY_MIMOCFG_GFMIX;
349 else
350 mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX;
351
352 b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
353}
354
355/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
356static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
357{
358 struct b43_phy_n *nphy = dev->phy.n;
359
360 bool override = false;
361 u16 chain = 0x33;
362
363 if (nphy->txrx_chain == 0) {
364 chain = 0x11;
365 override = true;
366 } else if (nphy->txrx_chain == 1) {
367 chain = 0x22;
368 override = true;
369 }
370
371 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
372 ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
373 chain);
374
375 if (override)
376 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
377 B43_NPHY_RFSEQMODE_CAOVER);
378 else
379 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
380 ~B43_NPHY_RFSEQMODE_CAOVER);
381}
382
383/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
384static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
385 u16 samps, u8 time, bool wait)
386{
387 int i;
388 u16 tmp;
389
390 b43_phy_write(dev, B43_NPHY_IQEST_SAMCNT, samps);
391 b43_phy_maskset(dev, B43_NPHY_IQEST_WT, ~B43_NPHY_IQEST_WT_VAL, time);
392 if (wait)
393 b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_MODE);
394 else
395 b43_phy_mask(dev, B43_NPHY_IQEST_CMD, ~B43_NPHY_IQEST_CMD_MODE);
396
397 b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_START);
398
399 for (i = 1000; i; i--) {
400 tmp = b43_phy_read(dev, B43_NPHY_IQEST_CMD);
401 if (!(tmp & B43_NPHY_IQEST_CMD_START)) {
402 est->i0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI0) << 16) |
403 b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO0);
404 est->q0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI0) << 16) |
405 b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO0);
406 est->iq0_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI0) << 16) |
407 b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO0);
408
409 est->i1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI1) << 16) |
410 b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO1);
411 est->q1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI1) << 16) |
412 b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO1);
413 est->iq1_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI1) << 16) |
414 b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO1);
415 return;
416 }
417 udelay(10);
418 }
419 memset(est, 0, sizeof(*est));
420}
421
422/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
423static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
424 struct b43_phy_n_iq_comp *pcomp)
425{
426 if (write) {
427 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPA0, pcomp->a0);
428 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPB0, pcomp->b0);
429 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPA1, pcomp->a1);
430 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPB1, pcomp->b1);
431 } else {
432 pcomp->a0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPA0);
433 pcomp->b0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPB0);
434 pcomp->a1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPA1);
435 pcomp->b1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPB1);
436 }
437}
438
439/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
440static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
441{
442 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
443
444 b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]);
445 if (core == 0) {
446 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]);
447 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
448 } else {
449 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
450 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
451 }
452 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]);
453 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]);
454 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]);
455 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]);
456 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]);
457 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]);
458 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
459 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
460}
461
462/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
463static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
464{
465 u8 rxval, txval;
466 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
467
468 regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
469 if (core == 0) {
470 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
471 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
472 } else {
473 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
474 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
475 }
476 regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
477 regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
478 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
479 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
480 regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1);
481 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
482 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
483 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
484
485 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
486 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
487
488 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS,
489 ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
490 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
491 ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT));
492 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
493 (core << B43_NPHY_RFSEQCA_RXEN_SHIFT));
494 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS,
495 (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT));
496
497 if (core == 0) {
498 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007);
499 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007);
500 } else {
501 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007);
502 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
503 }
504
505 b43_nphy_rf_control_intc_override(dev, 2, 0, 3);
506 b43_nphy_rf_control_override(dev, 8, 0, 3, false);
507 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
508
509 if (core == 0) {
510 rxval = 1;
511 txval = 8;
512 } else {
513 rxval = 4;
514 txval = 2;
515 }
516 b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
517 b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
518}
519
520/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
521static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
522{
523 int i;
524 s32 iq;
525 u32 ii;
526 u32 qq;
527 int iq_nbits, qq_nbits;
528 int arsh, brsh;
529 u16 tmp, a, b;
530
531 struct nphy_iq_est est;
532 struct b43_phy_n_iq_comp old;
533 struct b43_phy_n_iq_comp new = { };
534 bool error = false;
535
536 if (mask == 0)
537 return;
538
539 b43_nphy_rx_iq_coeffs(dev, false, &old);
540 b43_nphy_rx_iq_coeffs(dev, true, &new);
541 b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false);
542 new = old;
543
544 for (i = 0; i < 2; i++) {
545 if (i == 0 && (mask & 1)) {
546 iq = est.iq0_prod;
547 ii = est.i0_pwr;
548 qq = est.q0_pwr;
549 } else if (i == 1 && (mask & 2)) {
550 iq = est.iq1_prod;
551 ii = est.i1_pwr;
552 qq = est.q1_pwr;
553 } else {
554 B43_WARN_ON(1);
555 continue;
556 }
557
558 if (ii + qq < 2) {
559 error = true;
560 break;
561 }
562
563 iq_nbits = fls(abs(iq));
564 qq_nbits = fls(qq);
565
566 arsh = iq_nbits - 20;
567 if (arsh >= 0) {
568 a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
569 tmp = ii >> arsh;
570 } else {
571 a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
572 tmp = ii << -arsh;
573 }
574 if (tmp == 0) {
575 error = true;
576 break;
577 }
578 a /= tmp;
579
580 brsh = qq_nbits - 11;
581 if (brsh >= 0) {
582 b = (qq << (31 - qq_nbits));
583 tmp = ii >> brsh;
584 } else {
585 b = (qq << (31 - qq_nbits));
586 tmp = ii << -brsh;
587 }
588 if (tmp == 0) {
589 error = true;
590 break;
591 }
592 b = int_sqrt(b / tmp - a * a) - (1 << 10);
593
594 if (i == 0 && (mask & 0x1)) {
595 if (dev->phy.rev >= 3) {
596 new.a0 = a & 0x3FF;
597 new.b0 = b & 0x3FF;
598 } else {
599 new.a0 = b & 0x3FF;
600 new.b0 = a & 0x3FF;
601 }
602 } else if (i == 1 && (mask & 0x2)) {
603 if (dev->phy.rev >= 3) {
604 new.a1 = a & 0x3FF;
605 new.b1 = b & 0x3FF;
606 } else {
607 new.a1 = b & 0x3FF;
608 new.b1 = a & 0x3FF;
609 }
610 }
611 }
612
613 if (error)
614 new = old;
615
616 b43_nphy_rx_iq_coeffs(dev, true, &new);
617}
618
619/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
620static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
621{
622 u16 array[4];
623 int i;
624
625 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50);
626 for (i = 0; i < 4; i++)
627 array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
628
629 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]);
630 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]);
631 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW2, array[2]);
632 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
633}
634
635/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
636static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st)
637{
638 b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
639 b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
640}
641
642/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
643static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
644{
645 clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES);
646 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
647}
648
649/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
650static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
651{
652 u16 tmp;
653
654 if (dev->dev->id.revision == 16)
655 b43_mac_suspend(dev);
656
657 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
658 tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN |
659 B43_NPHY_CLASSCTL_WAITEDEN);
660 tmp &= ~mask;
661 tmp |= (val & mask);
662 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
663
664 if (dev->dev->id.revision == 16)
665 b43_mac_enable(dev);
666
667 return tmp;
668}
669
670/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
671static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
241{ 672{
242 struct b43_phy *phy = &dev->phy; 673 struct b43_phy *phy = &dev->phy;
243 unsigned int i; 674 struct b43_phy_n *nphy = phy->n;
244 675
245 b43_phy_set(dev, B43_NPHY_IQFLIP, 676 if (enable) {
246 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); 677 u16 clip[] = { 0xFFFF, 0xFFFF };
247 if (1 /* FIXME band is 2.4GHz */) { 678 if (nphy->deaf_count++ == 0) {
248 b43_phy_set(dev, B43_NPHY_CLASSCTL, 679 nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
249 B43_NPHY_CLASSCTL_CCKEN); 680 b43_nphy_classifier(dev, 0x7, 0);
250 } else { 681 b43_nphy_read_clip_detection(dev, nphy->clip_state);
251 b43_phy_mask(dev, B43_NPHY_CLASSCTL, 682 b43_nphy_write_clip_detection(dev, clip);
252 ~B43_NPHY_CLASSCTL_CCKEN); 683 }
253 } 684 b43_nphy_reset_cca(dev);
254 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); 685 } else {
255 b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); 686 if (--nphy->deaf_count == 0) {
256 687 b43_nphy_classifier(dev, 0x7, nphy->classifier_state);
257 /* Fixup some tables */ 688 b43_nphy_write_clip_detection(dev, nphy->clip_state);
258 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); 689 }
259 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); 690 }
260 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); 691}
261 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); 692
262 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); 693/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
263 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); 694static void b43_nphy_stop_playback(struct b43_wldev *dev)
264 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); 695{
265 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); 696 struct b43_phy_n *nphy = dev->phy.n;
266 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); 697 u16 tmp;
267 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); 698
268 699 if (nphy->hang_avoid)
269 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); 700 b43_nphy_stay_in_carrier_search(dev, 1);
270 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); 701
271 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); 702 tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
272 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); 703 if (tmp & 0x1)
273 704 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
274 //TODO set RF sequence 705 else if (tmp & 0x2)
275 706 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000);
276 /* Set narrowband clip threshold */ 707
277 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); 708 b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
278 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); 709
279 710 if (nphy->bb_mult_save & 0x80000000) {
280 /* Set wideband clip 2 threshold */ 711 tmp = nphy->bb_mult_save & 0xFFFF;
281 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, 712 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
282 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, 713 nphy->bb_mult_save = 0;
283 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); 714 }
284 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, 715
285 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 716 if (nphy->hang_avoid)
286 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); 717 b43_nphy_stay_in_carrier_search(dev, 0);
287 718}
288 /* Set Clip 2 detect */ 719
289 b43_phy_set(dev, B43_NPHY_C1_CGAINI, 720/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
290 B43_NPHY_C1_CGAINI_CL2DETECT); 721static void b43_nphy_spur_workaround(struct b43_wldev *dev)
291 b43_phy_set(dev, B43_NPHY_C2_CGAINI, 722{
292 B43_NPHY_C2_CGAINI_CL2DETECT); 723 struct b43_phy_n *nphy = dev->phy.n;
293 724
294 if (0 /*FIXME*/) { 725 unsigned int channel;
295 /* Set dwell lengths */ 726 int tone[2] = { 57, 58 };
296 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); 727 u32 noise[2] = { 0x3FF, 0x3FF };
297 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); 728
298 b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); 729 B43_WARN_ON(dev->phy.rev < 3);
299 b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); 730
300 731 if (nphy->hang_avoid)
301 /* Set gain backoff */ 732 b43_nphy_stay_in_carrier_search(dev, 1);
302 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, 733
303 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 734 /* FIXME: channel = radio_chanspec */
304 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); 735
305 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, 736 if (nphy->gband_spurwar_en) {
306 ~B43_NPHY_C2_CGAINI_GAINBKOFF, 737 /* TODO: N PHY Adjust Analog Pfbw (7) */
307 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); 738 if (channel == 11 && dev->phy.is_40mhz)
739 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
740 else
741 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
742 /* TODO: N PHY Adjust CRS Min Power (0x1E) */
743 }
744
745 if (nphy->aband_spurwar_en) {
746 if (channel == 54) {
747 tone[0] = 0x20;
748 noise[0] = 0x25F;
749 } else if (channel == 38 || channel == 102 || channel == 118) {
750 if (0 /* FIXME */) {
751 tone[0] = 0x20;
752 noise[0] = 0x21F;
753 } else {
754 tone[0] = 0;
755 noise[0] = 0;
756 }
757 } else if (channel == 134) {
758 tone[0] = 0x20;
759 noise[0] = 0x21F;
760 } else if (channel == 151) {
761 tone[0] = 0x10;
762 noise[0] = 0x23F;
763 } else if (channel == 153 || channel == 161) {
764 tone[0] = 0x30;
765 noise[0] = 0x23F;
766 } else {
767 tone[0] = 0;
768 noise[0] = 0;
769 }
770
771 if (!tone[0] && !noise[0])
772 ; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/
773 else
774 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
775 }
776
777 if (nphy->hang_avoid)
778 b43_nphy_stay_in_carrier_search(dev, 0);
779}
780
781/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
782static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
783{
784 struct b43_phy_n *nphy = dev->phy.n;
785 u8 i, j;
786 u8 code;
787
788 /* TODO: for PHY >= 3
789 s8 *lna1_gain, *lna2_gain;
790 u8 *gain_db, *gain_bits;
791 u16 *rfseq_init;
792 u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
793 u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
794 */
795
796 u8 rfseq_events[3] = { 6, 8, 7 };
797 u8 rfseq_delays[3] = { 10, 30, 1 };
798
799 if (dev->phy.rev >= 3) {
800 /* TODO */
801 } else {
802 /* Set Clip 2 detect */
803 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
804 B43_NPHY_C1_CGAINI_CL2DETECT);
805 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
806 B43_NPHY_C2_CGAINI_CL2DETECT);
807
808 /* Set narrowband clip threshold */
809 b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
810 b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
811
812 if (!dev->phy.is_40mhz) {
813 /* Set dwell lengths */
814 b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
815 b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
816 b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
817 b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
818 }
819
820 /* Set wideband clip 2 threshold */
821 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
822 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
823 21);
824 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
825 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
826 21);
827
828 if (!dev->phy.is_40mhz) {
829 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
830 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
831 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
832 ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1);
833 b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI,
834 ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1);
835 b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI,
836 ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
837 }
838
839 b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
840
841 if (nphy->gain_boost) {
842 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
843 dev->phy.is_40mhz)
844 code = 4;
845 else
846 code = 5;
847 } else {
848 code = dev->phy.is_40mhz ? 6 : 7;
849 }
308 850
309 /* Set HPVGA2 index */ 851 /* Set HPVGA2 index */
310 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, 852 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
311 ~B43_NPHY_C1_INITGAIN_HPVGA2, 853 ~B43_NPHY_C1_INITGAIN_HPVGA2,
312 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); 854 code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
313 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, 855 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
314 ~B43_NPHY_C2_INITGAIN_HPVGA2, 856 ~B43_NPHY_C2_INITGAIN_HPVGA2,
315 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); 857 code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
858
859 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
860 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
861 (code << 8 | 0x7C));
862 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
863 (code << 8 | 0x7C));
864
865 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */
866
867 if (nphy->elna_gain_config) {
868 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
869 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
870 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
871 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
872 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
873
874 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08);
875 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
876 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
877 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
878 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
879
880 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
881 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
882 (code << 8 | 0x74));
883 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
884 (code << 8 | 0x74));
885 }
316 886
317 //FIXME verify that the specs really mean to use autoinc here. 887 if (dev->phy.rev == 2) {
318 for (i = 0; i < 3; i++) 888 for (i = 0; i < 4; i++) {
319 b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); 889 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
890 (0x0400 * i) + 0x0020);
891 for (j = 0; j < 21; j++)
892 b43_phy_write(dev,
893 B43_NPHY_TABLE_DATALO, 3 * j);
894 }
895
896 b43_nphy_set_rf_sequence(dev, 5,
897 rfseq_events, rfseq_delays, 3);
898 b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
899 (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV,
900 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
901
902 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
903 b43_phy_maskset(dev, B43_PHY_N(0xC5D),
904 0xFF80, 4);
905 }
320 } 906 }
907}
321 908
322 /* Set minimum gain value */ 909/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
323 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, 910static void b43_nphy_workarounds(struct b43_wldev *dev)
324 ~B43_NPHY_C1_MINGAIN, 911{
325 23 << B43_NPHY_C1_MINGAIN_SHIFT); 912 struct ssb_bus *bus = dev->dev->bus;
326 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, 913 struct b43_phy *phy = &dev->phy;
327 ~B43_NPHY_C2_MINGAIN, 914 struct b43_phy_n *nphy = phy->n;
328 23 << B43_NPHY_C2_MINGAIN_SHIFT);
329 915
330 if (phy->rev < 2) { 916 u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 };
331 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, 917 u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 };
332 ~B43_NPHY_SCRAM_SIGCTL_SCM); 918
919 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
920 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
921
922 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
923 b43_nphy_classifier(dev, 1, 0);
924 else
925 b43_nphy_classifier(dev, 1, 1);
926
927 if (nphy->hang_avoid)
928 b43_nphy_stay_in_carrier_search(dev, 1);
929
930 b43_phy_set(dev, B43_NPHY_IQFLIP,
931 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
932
933 if (dev->phy.rev >= 3) {
934 /* TODO */
935 } else {
936 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
937 nphy->band5g_pwrgain) {
938 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
939 b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
940 } else {
941 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
942 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
943 }
944
945 /* TODO: convert to b43_ntab_write? */
946 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
947 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
948 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
949 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
950 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
951 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
952 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
953 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
954
955 if (dev->phy.rev < 2) {
956 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
957 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
958 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
959 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
960 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
961 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
962 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
963 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
964 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
965 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
966 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
967 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
968 }
969
970 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
971 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
972 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
973 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
974
975 if (bus->sprom.boardflags2_lo & 0x100 &&
976 bus->boardinfo.type == 0x8B) {
977 delays1[0] = 0x1;
978 delays1[5] = 0x14;
979 }
980 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
981 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
982
983 b43_nphy_gain_crtl_workarounds(dev);
984
985 if (dev->phy.rev < 2) {
986 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
987 ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
988 } else if (dev->phy.rev == 2) {
989 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
990 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
991 }
992
993 if (dev->phy.rev < 2)
994 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
995 ~B43_NPHY_SCRAM_SIGCTL_SCM);
996
997 /* Set phase track alpha and beta */
998 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
999 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
1000 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
1001 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
1002 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
1003 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
1004
1005 b43_phy_mask(dev, B43_NPHY_PIL_DW1,
1006 (u16)~B43_NPHY_PIL_DW_64QAM);
1007 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
1008 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
1009 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
1010
1011 if (dev->phy.rev == 2)
1012 b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
1013 B43_NPHY_FINERX2_CGC_DECGC);
333 } 1014 }
334 1015
335 /* Set phase track alpha and beta */ 1016 if (nphy->hang_avoid)
336 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); 1017 b43_nphy_stay_in_carrier_search(dev, 0);
337 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
338 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
339 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
340 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
341 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
342} 1018}
343 1019
344static void b43_nphy_reset_cca(struct b43_wldev *dev) 1020/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
1021static int b43_nphy_load_samples(struct b43_wldev *dev,
1022 struct b43_c32 *samples, u16 len) {
1023 struct b43_phy_n *nphy = dev->phy.n;
1024 u16 i;
1025 u32 *data;
1026
1027 data = kzalloc(len * sizeof(u32), GFP_KERNEL);
1028 if (!data) {
1029 b43err(dev->wl, "allocation for samples loading failed\n");
1030 return -ENOMEM;
1031 }
1032 if (nphy->hang_avoid)
1033 b43_nphy_stay_in_carrier_search(dev, 1);
1034
1035 for (i = 0; i < len; i++) {
1036 data[i] = (samples[i].i & 0x3FF << 10);
1037 data[i] |= samples[i].q & 0x3FF;
1038 }
1039 b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data);
1040
1041 kfree(data);
1042 if (nphy->hang_avoid)
1043 b43_nphy_stay_in_carrier_search(dev, 0);
1044 return 0;
1045}
1046
1047/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
1048static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1049 bool test)
345{ 1050{
346 u16 bbcfg; 1051 int i;
1052 u16 bw, len, rot, angle;
1053 struct b43_c32 *samples;
347 1054
348 ssb_write32(dev->dev, SSB_TMSLOW, 1055
349 ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC); 1056 bw = (dev->phy.is_40mhz) ? 40 : 20;
350 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); 1057 len = bw << 3;
351 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA); 1058
352 b43_phy_write(dev, B43_NPHY_BBCFG, 1059 if (test) {
353 bbcfg & ~B43_NPHY_BBCFG_RSTCCA); 1060 if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX)
354 ssb_write32(dev->dev, SSB_TMSLOW, 1061 bw = 82;
355 ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC); 1062 else
1063 bw = 80;
1064
1065 if (dev->phy.is_40mhz)
1066 bw <<= 1;
1067
1068 len = bw << 1;
1069 }
1070
1071 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
1072 if (!samples) {
1073 b43err(dev->wl, "allocation for samples generation failed\n");
1074 return 0;
1075 }
1076 rot = (((freq * 36) / bw) << 16) / 100;
1077 angle = 0;
1078
1079 for (i = 0; i < len; i++) {
1080 samples[i] = b43_cordic(angle);
1081 angle += rot;
1082 samples[i].q = CORDIC_CONVERT(samples[i].q * max);
1083 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
1084 }
1085
1086 i = b43_nphy_load_samples(dev, samples, len);
1087 kfree(samples);
1088 return (i < 0) ? 0 : len;
356} 1089}
357 1090
358enum b43_nphy_rf_sequence { 1091/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
359 B43_RFSEQ_RX2TX, 1092static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
360 B43_RFSEQ_TX2RX, 1093 u16 wait, bool iqmode, bool dac_test)
361 B43_RFSEQ_RESET2RX, 1094{
362 B43_RFSEQ_UPDATE_GAINH, 1095 struct b43_phy_n *nphy = dev->phy.n;
363 B43_RFSEQ_UPDATE_GAINL, 1096 int i;
364 B43_RFSEQ_UPDATE_GAINU, 1097 u16 seq_mode;
365}; 1098 u32 tmp;
1099
1100 if (nphy->hang_avoid)
1101 b43_nphy_stay_in_carrier_search(dev, true);
1102
1103 if ((nphy->bb_mult_save & 0x80000000) == 0) {
1104 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1105 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1106 }
1107
1108 if (!dev->phy.is_40mhz)
1109 tmp = 0x6464;
1110 else
1111 tmp = 0x4747;
1112 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1113
1114 if (nphy->hang_avoid)
1115 b43_nphy_stay_in_carrier_search(dev, false);
1116
1117 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1118
1119 if (loops != 0xFFFF)
1120 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1));
1121 else
1122 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops);
1123
1124 b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait);
1125
1126 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
1127
1128 b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER);
1129 if (iqmode) {
1130 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1131 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1132 } else {
1133 if (dac_test)
1134 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1135 else
1136 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1137 }
1138 for (i = 0; i < 100; i++) {
1139 if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) {
1140 i = 0;
1141 break;
1142 }
1143 udelay(10);
1144 }
1145 if (i)
1146 b43err(dev->wl, "run samples timeout\n");
1147
1148 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
1149}
1150
1151/*
1152 * Transmits a known value for LO calibration
1153 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1154 */
1155static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1156 bool iqmode, bool dac_test)
1157{
1158 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1159 if (samp == 0)
1160 return -1;
1161 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1162 return 0;
1163}
1164
1165/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
1166static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
1167{
1168 struct b43_phy_n *nphy = dev->phy.n;
1169 int i, j;
1170 u32 tmp;
1171 u32 cur_real, cur_imag, real_part, imag_part;
1172
1173 u16 buffer[7];
1174
1175 if (nphy->hang_avoid)
1176 b43_nphy_stay_in_carrier_search(dev, true);
1177
1178 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
1179
1180 for (i = 0; i < 2; i++) {
1181 tmp = ((buffer[i * 2] & 0x3FF) << 10) |
1182 (buffer[i * 2 + 1] & 0x3FF);
1183 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
1184 (((i + 26) << 10) | 320));
1185 for (j = 0; j < 128; j++) {
1186 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
1187 ((tmp >> 16) & 0xFFFF));
1188 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
1189 (tmp & 0xFFFF));
1190 }
1191 }
1192
1193 for (i = 0; i < 2; i++) {
1194 tmp = buffer[5 + i];
1195 real_part = (tmp >> 8) & 0xFF;
1196 imag_part = (tmp & 0xFF);
1197 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
1198 (((i + 26) << 10) | 448));
1199
1200 if (dev->phy.rev >= 3) {
1201 cur_real = real_part;
1202 cur_imag = imag_part;
1203 tmp = ((cur_real & 0xFF) << 8) | (cur_imag & 0xFF);
1204 }
1205
1206 for (j = 0; j < 128; j++) {
1207 if (dev->phy.rev < 3) {
1208 cur_real = (real_part * loscale[j] + 128) >> 8;
1209 cur_imag = (imag_part * loscale[j] + 128) >> 8;
1210 tmp = ((cur_real & 0xFF) << 8) |
1211 (cur_imag & 0xFF);
1212 }
1213 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
1214 ((tmp >> 16) & 0xFFFF));
1215 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
1216 (tmp & 0xFFFF));
1217 }
1218 }
1219
1220 if (dev->phy.rev >= 3) {
1221 b43_shm_write16(dev, B43_SHM_SHARED,
1222 B43_SHM_SH_NPHY_TXPWR_INDX0, 0xFFFF);
1223 b43_shm_write16(dev, B43_SHM_SHARED,
1224 B43_SHM_SH_NPHY_TXPWR_INDX1, 0xFFFF);
1225 }
1226
1227 if (nphy->hang_avoid)
1228 b43_nphy_stay_in_carrier_search(dev, false);
1229}
1230
1231/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
1232static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
1233 u8 *events, u8 *delays, u8 length)
1234{
1235 struct b43_phy_n *nphy = dev->phy.n;
1236 u8 i;
1237 u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F;
1238 u16 offset1 = cmd << 4;
1239 u16 offset2 = offset1 + 0x80;
366 1240
1241 if (nphy->hang_avoid)
1242 b43_nphy_stay_in_carrier_search(dev, true);
1243
1244 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events);
1245 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays);
1246
1247 for (i = length; i < 16; i++) {
1248 b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end);
1249 b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1);
1250 }
1251
1252 if (nphy->hang_avoid)
1253 b43_nphy_stay_in_carrier_search(dev, false);
1254}
1255
1256/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
367static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 1257static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
368 enum b43_nphy_rf_sequence seq) 1258 enum b43_nphy_rf_sequence seq)
369{ 1259{
@@ -376,6 +1266,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
376 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, 1266 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU,
377 }; 1267 };
378 int i; 1268 int i;
1269 u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
379 1270
380 B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); 1271 B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
381 1272
@@ -389,8 +1280,181 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
389 } 1280 }
390 b43err(dev->wl, "RF sequence status timeout\n"); 1281 b43err(dev->wl, "RF sequence status timeout\n");
391ok: 1282ok:
392 b43_phy_mask(dev, B43_NPHY_RFSEQMODE, 1283 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
393 ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); 1284}
1285
1286/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
1287static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
1288 u16 value, u8 core, bool off)
1289{
1290 int i;
1291 u8 index = fls(field);
1292 u8 addr, en_addr, val_addr;
1293 /* we expect only one bit set */
1294 B43_WARN_ON(field & (~(1 << (index - 1))));
1295
1296 if (dev->phy.rev >= 3) {
1297 const struct nphy_rf_control_override_rev3 *rf_ctrl;
1298 for (i = 0; i < 2; i++) {
1299 if (index == 0 || index == 16) {
1300 b43err(dev->wl,
1301 "Unsupported RF Ctrl Override call\n");
1302 return;
1303 }
1304
1305 rf_ctrl = &tbl_rf_control_override_rev3[index - 1];
1306 en_addr = B43_PHY_N((i == 0) ?
1307 rf_ctrl->en_addr0 : rf_ctrl->en_addr1);
1308 val_addr = B43_PHY_N((i == 0) ?
1309 rf_ctrl->val_addr0 : rf_ctrl->val_addr1);
1310
1311 if (off) {
1312 b43_phy_mask(dev, en_addr, ~(field));
1313 b43_phy_mask(dev, val_addr,
1314 ~(rf_ctrl->val_mask));
1315 } else {
1316 if (core == 0 || ((1 << core) & i) != 0) {
1317 b43_phy_set(dev, en_addr, field);
1318 b43_phy_maskset(dev, val_addr,
1319 ~(rf_ctrl->val_mask),
1320 (value << rf_ctrl->val_shift));
1321 }
1322 }
1323 }
1324 } else {
1325 const struct nphy_rf_control_override_rev2 *rf_ctrl;
1326 if (off) {
1327 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field));
1328 value = 0;
1329 } else {
1330 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field);
1331 }
1332
1333 for (i = 0; i < 2; i++) {
1334 if (index <= 1 || index == 16) {
1335 b43err(dev->wl,
1336 "Unsupported RF Ctrl Override call\n");
1337 return;
1338 }
1339
1340 if (index == 2 || index == 10 ||
1341 (index >= 13 && index <= 15)) {
1342 core = 1;
1343 }
1344
1345 rf_ctrl = &tbl_rf_control_override_rev2[index - 2];
1346 addr = B43_PHY_N((i == 0) ?
1347 rf_ctrl->addr0 : rf_ctrl->addr1);
1348
1349 if ((core & (1 << i)) != 0)
1350 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
1351 (value << rf_ctrl->shift));
1352
1353 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
1354 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1355 B43_NPHY_RFCTL_CMD_START);
1356 udelay(1);
1357 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE);
1358 }
1359 }
1360}
1361
1362/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
1363static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
1364 u16 value, u8 core)
1365{
1366 u8 i, j;
1367 u16 reg, tmp, val;
1368
1369 B43_WARN_ON(dev->phy.rev < 3);
1370 B43_WARN_ON(field > 4);
1371
1372 for (i = 0; i < 2; i++) {
1373 if ((core == 1 && i == 1) || (core == 2 && !i))
1374 continue;
1375
1376 reg = (i == 0) ?
1377 B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
1378 b43_phy_mask(dev, reg, 0xFBFF);
1379
1380 switch (field) {
1381 case 0:
1382 b43_phy_write(dev, reg, 0);
1383 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1384 break;
1385 case 1:
1386 if (!i) {
1387 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1,
1388 0xFC3F, (value << 6));
1389 b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1,
1390 0xFFFE, 1);
1391 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1392 B43_NPHY_RFCTL_CMD_START);
1393 for (j = 0; j < 100; j++) {
1394 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
1395 j = 0;
1396 break;
1397 }
1398 udelay(10);
1399 }
1400 if (j)
1401 b43err(dev->wl,
1402 "intc override timeout\n");
1403 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1,
1404 0xFFFE);
1405 } else {
1406 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2,
1407 0xFC3F, (value << 6));
1408 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
1409 0xFFFE, 1);
1410 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1411 B43_NPHY_RFCTL_CMD_RXTX);
1412 for (j = 0; j < 100; j++) {
1413 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
1414 j = 0;
1415 break;
1416 }
1417 udelay(10);
1418 }
1419 if (j)
1420 b43err(dev->wl,
1421 "intc override timeout\n");
1422 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
1423 0xFFFE);
1424 }
1425 break;
1426 case 2:
1427 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1428 tmp = 0x0020;
1429 val = value << 5;
1430 } else {
1431 tmp = 0x0010;
1432 val = value << 4;
1433 }
1434 b43_phy_maskset(dev, reg, ~tmp, val);
1435 break;
1436 case 3:
1437 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1438 tmp = 0x0001;
1439 val = value;
1440 } else {
1441 tmp = 0x0004;
1442 val = value << 2;
1443 }
1444 b43_phy_maskset(dev, reg, ~tmp, val);
1445 break;
1446 case 4:
1447 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1448 tmp = 0x0002;
1449 val = value << 1;
1450 } else {
1451 tmp = 0x0008;
1452 val = value << 3;
1453 }
1454 b43_phy_maskset(dev, reg, ~tmp, val);
1455 break;
1456 }
1457 }
394} 1458}
395 1459
396static void b43_nphy_bphy_init(struct b43_wldev *dev) 1460static void b43_nphy_bphy_init(struct b43_wldev *dev)
@@ -411,81 +1475,1680 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
411 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); 1475 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
412} 1476}
413 1477
414/* RSSI Calibration */ 1478/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
415static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type) 1479static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
1480 s8 offset, u8 core, u8 rail, u8 type)
416{ 1481{
417 //TODO 1482 u16 tmp;
1483 bool core1or5 = (core == 1) || (core == 5);
1484 bool core2or5 = (core == 2) || (core == 5);
1485
1486 offset = clamp_val(offset, -32, 31);
1487 tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
1488
1489 if (core1or5 && (rail == 0) && (type == 2))
1490 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
1491 if (core1or5 && (rail == 1) && (type == 2))
1492 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
1493 if (core2or5 && (rail == 0) && (type == 2))
1494 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
1495 if (core2or5 && (rail == 1) && (type == 2))
1496 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
1497 if (core1or5 && (rail == 0) && (type == 0))
1498 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
1499 if (core1or5 && (rail == 1) && (type == 0))
1500 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
1501 if (core2or5 && (rail == 0) && (type == 0))
1502 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
1503 if (core2or5 && (rail == 1) && (type == 0))
1504 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
1505 if (core1or5 && (rail == 0) && (type == 1))
1506 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
1507 if (core1or5 && (rail == 1) && (type == 1))
1508 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
1509 if (core2or5 && (rail == 0) && (type == 1))
1510 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
1511 if (core2or5 && (rail == 1) && (type == 1))
1512 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
1513 if (core1or5 && (rail == 0) && (type == 6))
1514 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
1515 if (core1or5 && (rail == 1) && (type == 6))
1516 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
1517 if (core2or5 && (rail == 0) && (type == 6))
1518 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
1519 if (core2or5 && (rail == 1) && (type == 6))
1520 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
1521 if (core1or5 && (rail == 0) && (type == 3))
1522 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
1523 if (core1or5 && (rail == 1) && (type == 3))
1524 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
1525 if (core2or5 && (rail == 0) && (type == 3))
1526 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
1527 if (core2or5 && (rail == 1) && (type == 3))
1528 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
1529 if (core1or5 && (type == 4))
1530 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
1531 if (core2or5 && (type == 4))
1532 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
1533 if (core1or5 && (type == 5))
1534 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
1535 if (core2or5 && (type == 5))
1536 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
1537}
1538
1539static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1540{
1541 u16 val;
1542
1543 if (type < 3)
1544 val = 0;
1545 else if (type == 6)
1546 val = 1;
1547 else if (type == 3)
1548 val = 2;
1549 else
1550 val = 3;
1551
1552 val = (val << 12) | (val << 14);
1553 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
1554 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
1555
1556 if (type < 3) {
1557 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
1558 (type + 1) << 4);
1559 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
1560 (type + 1) << 4);
1561 }
1562
1563 /* TODO use some definitions */
1564 if (code == 0) {
1565 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
1566 if (type < 3) {
1567 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
1568 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
1569 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
1570 udelay(20);
1571 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
1572 }
1573 } else {
1574 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
1575 0x3000);
1576 if (type < 3) {
1577 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
1578 0xFEC7, 0x0180);
1579 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
1580 0xEFDC, (code << 1 | 0x1021));
1581 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
1582 udelay(20);
1583 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
1584 }
1585 }
1586}
1587
1588static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1589{
1590 struct b43_phy_n *nphy = dev->phy.n;
1591 u8 i;
1592 u16 reg, val;
1593
1594 if (code == 0) {
1595 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF);
1596 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF);
1597 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF);
1598 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF);
1599 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF);
1600 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF);
1601 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3);
1602 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3);
1603 } else {
1604 for (i = 0; i < 2; i++) {
1605 if ((code == 1 && i == 1) || (code == 2 && !i))
1606 continue;
1607
1608 reg = (i == 0) ?
1609 B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER;
1610 b43_phy_maskset(dev, reg, 0xFDFF, 0x0200);
1611
1612 if (type < 3) {
1613 reg = (i == 0) ?
1614 B43_NPHY_AFECTL_C1 :
1615 B43_NPHY_AFECTL_C2;
1616 b43_phy_maskset(dev, reg, 0xFCFF, 0);
1617
1618 reg = (i == 0) ?
1619 B43_NPHY_RFCTL_LUT_TRSW_UP1 :
1620 B43_NPHY_RFCTL_LUT_TRSW_UP2;
1621 b43_phy_maskset(dev, reg, 0xFFC3, 0);
1622
1623 if (type == 0)
1624 val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8;
1625 else if (type == 1)
1626 val = 16;
1627 else
1628 val = 32;
1629 b43_phy_set(dev, reg, val);
1630
1631 reg = (i == 0) ?
1632 B43_NPHY_TXF_40CO_B1S0 :
1633 B43_NPHY_TXF_40CO_B32S1;
1634 b43_phy_set(dev, reg, 0x0020);
1635 } else {
1636 if (type == 6)
1637 val = 0x0100;
1638 else if (type == 3)
1639 val = 0x0200;
1640 else
1641 val = 0x0300;
1642
1643 reg = (i == 0) ?
1644 B43_NPHY_AFECTL_C1 :
1645 B43_NPHY_AFECTL_C2;
1646
1647 b43_phy_maskset(dev, reg, 0xFCFF, val);
1648 b43_phy_maskset(dev, reg, 0xF3FF, val << 2);
1649
1650 if (type != 3 && type != 6) {
1651 enum ieee80211_band band =
1652 b43_current_band(dev->wl);
1653
1654 if ((nphy->ipa2g_on &&
1655 band == IEEE80211_BAND_2GHZ) ||
1656 (nphy->ipa5g_on &&
1657 band == IEEE80211_BAND_5GHZ))
1658 val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1659 else
1660 val = 0x11;
1661 reg = (i == 0) ? 0x2000 : 0x3000;
1662 reg |= B2055_PADDRV;
1663 b43_radio_write16(dev, reg, val);
1664
1665 reg = (i == 0) ?
1666 B43_NPHY_AFECTL_OVER1 :
1667 B43_NPHY_AFECTL_OVER;
1668 b43_phy_set(dev, reg, 0x0200);
1669 }
1670 }
1671 }
1672 }
1673}
1674
1675/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
1676static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1677{
1678 if (dev->phy.rev >= 3)
1679 b43_nphy_rev3_rssi_select(dev, code, type);
1680 else
1681 b43_nphy_rev2_rssi_select(dev, code, type);
1682}
1683
1684/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
1685static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
1686{
1687 int i;
1688 for (i = 0; i < 2; i++) {
1689 if (type == 2) {
1690 if (i == 0) {
1691 b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
1692 0xFC, buf[0]);
1693 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1694 0xFC, buf[1]);
1695 } else {
1696 b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
1697 0xFC, buf[2 * i]);
1698 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1699 0xFC, buf[2 * i + 1]);
1700 }
1701 } else {
1702 if (i == 0)
1703 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1704 0xF3, buf[0] << 2);
1705 else
1706 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1707 0xF3, buf[2 * i + 1] << 2);
1708 }
1709 }
1710}
1711
1712/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
1713static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1714 u8 nsamp)
1715{
1716 int i;
1717 int out;
1718 u16 save_regs_phy[9];
1719 u16 s[2];
1720
1721 if (dev->phy.rev >= 3) {
1722 save_regs_phy[0] = b43_phy_read(dev,
1723 B43_NPHY_RFCTL_LUT_TRSW_UP1);
1724 save_regs_phy[1] = b43_phy_read(dev,
1725 B43_NPHY_RFCTL_LUT_TRSW_UP2);
1726 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1727 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1728 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
1729 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1730 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
1731 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
1732 }
1733
1734 b43_nphy_rssi_select(dev, 5, type);
1735
1736 if (dev->phy.rev < 2) {
1737 save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
1738 b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
1739 }
1740
1741 for (i = 0; i < 4; i++)
1742 buf[i] = 0;
1743
1744 for (i = 0; i < nsamp; i++) {
1745 if (dev->phy.rev < 2) {
1746 s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
1747 s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
1748 } else {
1749 s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
1750 s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
1751 }
1752
1753 buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
1754 buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
1755 buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
1756 buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
1757 }
1758 out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
1759 (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
1760
1761 if (dev->phy.rev < 2)
1762 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
1763
1764 if (dev->phy.rev >= 3) {
1765 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
1766 save_regs_phy[0]);
1767 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1768 save_regs_phy[1]);
1769 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
1770 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
1771 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
1772 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
1773 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
1774 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
1775 }
1776
1777 return out;
1778}
1779
1780/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
1781static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1782{
1783 int i, j;
1784 u8 state[4];
1785 u8 code, val;
1786 u16 class, override;
1787 u8 regs_save_radio[2];
1788 u16 regs_save_phy[2];
1789 s8 offset[4];
1790
1791 u16 clip_state[2];
1792 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1793 s32 results_min[4] = { };
1794 u8 vcm_final[4] = { };
1795 s32 results[4][4] = { };
1796 s32 miniq[4][2] = { };
1797
1798 if (type == 2) {
1799 code = 0;
1800 val = 6;
1801 } else if (type < 2) {
1802 code = 25;
1803 val = 4;
1804 } else {
1805 B43_WARN_ON(1);
1806 return;
1807 }
1808
1809 class = b43_nphy_classifier(dev, 0, 0);
1810 b43_nphy_classifier(dev, 7, 4);
1811 b43_nphy_read_clip_detection(dev, clip_state);
1812 b43_nphy_write_clip_detection(dev, clip_off);
1813
1814 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1815 override = 0x140;
1816 else
1817 override = 0x110;
1818
1819 regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1820 regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
1821 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
1822 b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
1823
1824 regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1825 regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
1826 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
1827 b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
1828
1829 state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
1830 state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
1831 b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
1832 b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
1833 state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
1834 state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
1835
1836 b43_nphy_rssi_select(dev, 5, type);
1837 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
1838 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
1839
1840 for (i = 0; i < 4; i++) {
1841 u8 tmp[4];
1842 for (j = 0; j < 4; j++)
1843 tmp[j] = i;
1844 if (type != 1)
1845 b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
1846 b43_nphy_poll_rssi(dev, type, results[i], 8);
1847 if (type < 2)
1848 for (j = 0; j < 2; j++)
1849 miniq[i][j] = min(results[i][2 * j],
1850 results[i][2 * j + 1]);
1851 }
1852
1853 for (i = 0; i < 4; i++) {
1854 s32 mind = 40;
1855 u8 minvcm = 0;
1856 s32 minpoll = 249;
1857 s32 curr;
1858 for (j = 0; j < 4; j++) {
1859 if (type == 2)
1860 curr = abs(results[j][i]);
1861 else
1862 curr = abs(miniq[j][i / 2] - code * 8);
1863
1864 if (curr < mind) {
1865 mind = curr;
1866 minvcm = j;
1867 }
1868
1869 if (results[j][i] < minpoll)
1870 minpoll = results[j][i];
1871 }
1872 results_min[i] = minpoll;
1873 vcm_final[i] = minvcm;
1874 }
1875
1876 if (type != 1)
1877 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
1878
1879 for (i = 0; i < 4; i++) {
1880 offset[i] = (code * 8) - results[vcm_final[i]][i];
1881
1882 if (offset[i] < 0)
1883 offset[i] = -((abs(offset[i]) + 4) / 8);
1884 else
1885 offset[i] = (offset[i] + 4) / 8;
1886
1887 if (results_min[i] == 248)
1888 offset[i] = code - 32;
1889
1890 if (i % 2 == 0)
1891 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
1892 type);
1893 else
1894 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
1895 type);
1896 }
1897
1898 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
1899 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
1900
1901 switch (state[2]) {
1902 case 1:
1903 b43_nphy_rssi_select(dev, 1, 2);
1904 break;
1905 case 4:
1906 b43_nphy_rssi_select(dev, 1, 0);
1907 break;
1908 case 2:
1909 b43_nphy_rssi_select(dev, 1, 1);
1910 break;
1911 default:
1912 b43_nphy_rssi_select(dev, 1, 1);
1913 break;
1914 }
1915
1916 switch (state[3]) {
1917 case 1:
1918 b43_nphy_rssi_select(dev, 2, 2);
1919 break;
1920 case 4:
1921 b43_nphy_rssi_select(dev, 2, 0);
1922 break;
1923 default:
1924 b43_nphy_rssi_select(dev, 2, 1);
1925 break;
1926 }
1927
1928 b43_nphy_rssi_select(dev, 0, type);
1929
1930 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
1931 b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
1932 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
1933 b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
1934
1935 b43_nphy_classifier(dev, 7, class);
1936 b43_nphy_write_clip_detection(dev, clip_state);
1937}
1938
1939/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1940static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1941{
1942 /* TODO */
1943}
1944
1945/*
1946 * RSSI Calibration
1947 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
1948 */
1949static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1950{
1951 if (dev->phy.rev >= 3) {
1952 b43_nphy_rev3_rssi_cal(dev);
1953 } else {
1954 b43_nphy_rev2_rssi_cal(dev, 2);
1955 b43_nphy_rev2_rssi_cal(dev, 0);
1956 b43_nphy_rev2_rssi_cal(dev, 1);
1957 }
418} 1958}
419 1959
1960/*
1961 * Restore RSSI Calibration
1962 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
1963 */
1964static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
1965{
1966 struct b43_phy_n *nphy = dev->phy.n;
1967
1968 u16 *rssical_radio_regs = NULL;
1969 u16 *rssical_phy_regs = NULL;
1970
1971 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1972 if (!nphy->rssical_chanspec_2G)
1973 return;
1974 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1975 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1976 } else {
1977 if (!nphy->rssical_chanspec_5G)
1978 return;
1979 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1980 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1981 }
1982
1983 /* TODO use some definitions */
1984 b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]);
1985 b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]);
1986
1987 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]);
1988 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]);
1989 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, rssical_phy_regs[2]);
1990 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, rssical_phy_regs[3]);
1991
1992 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, rssical_phy_regs[4]);
1993 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, rssical_phy_regs[5]);
1994 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, rssical_phy_regs[6]);
1995 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, rssical_phy_regs[7]);
1996
1997 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, rssical_phy_regs[8]);
1998 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, rssical_phy_regs[9]);
1999 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, rssical_phy_regs[10]);
2000 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
2001}
2002
2003/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
2004static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
2005{
2006 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2007 if (dev->phy.rev >= 6) {
2008 /* TODO If the chip is 47162
2009 return txpwrctrl_tx_gain_ipa_rev5 */
2010 return txpwrctrl_tx_gain_ipa_rev6;
2011 } else if (dev->phy.rev >= 5) {
2012 return txpwrctrl_tx_gain_ipa_rev5;
2013 } else {
2014 return txpwrctrl_tx_gain_ipa;
2015 }
2016 } else {
2017 return txpwrctrl_tx_gain_ipa_5g;
2018 }
2019}
2020
2021/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
2022static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2023{
2024 struct b43_phy_n *nphy = dev->phy.n;
2025 u16 *save = nphy->tx_rx_cal_radio_saveregs;
2026 u16 tmp;
2027 u8 offset, i;
2028
2029 if (dev->phy.rev >= 3) {
2030 for (i = 0; i < 2; i++) {
2031 tmp = (i == 0) ? 0x2000 : 0x3000;
2032 offset = i * 11;
2033
2034 save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL);
2035 save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL);
2036 save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS);
2037 save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS);
2038 save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS);
2039 save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV);
2040 save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1);
2041 save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2);
2042 save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL);
2043 save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC);
2044 save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1);
2045
2046 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2047 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A);
2048 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
2049 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
2050 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
2051 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
2052 if (nphy->ipa5g_on) {
2053 b43_radio_write16(dev, tmp | B2055_PADDRV, 4);
2054 b43_radio_write16(dev, tmp | B2055_XOCTL1, 1);
2055 } else {
2056 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
2057 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F);
2058 }
2059 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
2060 } else {
2061 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06);
2062 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
2063 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
2064 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
2065 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
2066 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0);
2067 if (nphy->ipa2g_on) {
2068 b43_radio_write16(dev, tmp | B2055_PADDRV, 6);
2069 b43_radio_write16(dev, tmp | B2055_XOCTL2,
2070 (dev->phy.rev < 5) ? 0x11 : 0x01);
2071 } else {
2072 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
2073 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
2074 }
2075 }
2076 b43_radio_write16(dev, tmp | B2055_XOREGUL, 0);
2077 b43_radio_write16(dev, tmp | B2055_XOMISC, 0);
2078 b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0);
2079 }
2080 } else {
2081 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1);
2082 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
2083
2084 save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2);
2085 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54);
2086
2087 save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1);
2088 b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29);
2089
2090 save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2);
2091 b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54);
2092
2093 save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX);
2094 save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX);
2095
2096 if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) &
2097 B43_NPHY_BANDCTL_5GHZ)) {
2098 b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04);
2099 b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04);
2100 } else {
2101 b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20);
2102 b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20);
2103 }
2104
2105 if (dev->phy.rev < 2) {
2106 b43_radio_set(dev, B2055_C1_TX_BB_MXGM, 0x20);
2107 b43_radio_set(dev, B2055_C2_TX_BB_MXGM, 0x20);
2108 } else {
2109 b43_radio_mask(dev, B2055_C1_TX_BB_MXGM, ~0x20);
2110 b43_radio_mask(dev, B2055_C2_TX_BB_MXGM, ~0x20);
2111 }
2112 }
2113}
2114
2115/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
2116static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
2117 struct nphy_txgains target,
2118 struct nphy_iqcal_params *params)
2119{
2120 int i, j, indx;
2121 u16 gain;
2122
2123 if (dev->phy.rev >= 3) {
2124 params->txgm = target.txgm[core];
2125 params->pga = target.pga[core];
2126 params->pad = target.pad[core];
2127 params->ipa = target.ipa[core];
2128 params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2129 (params->pad << 4) | (params->ipa);
2130 for (j = 0; j < 5; j++)
2131 params->ncorr[j] = 0x79;
2132 } else {
2133 gain = (target.pad[core]) | (target.pga[core] << 4) |
2134 (target.txgm[core] << 8);
2135
2136 indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
2137 1 : 0;
2138 for (i = 0; i < 9; i++)
2139 if (tbl_iqcal_gainparams[indx][i][0] == gain)
2140 break;
2141 i = min(i, 8);
2142
2143 params->txgm = tbl_iqcal_gainparams[indx][i][1];
2144 params->pga = tbl_iqcal_gainparams[indx][i][2];
2145 params->pad = tbl_iqcal_gainparams[indx][i][3];
2146 params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
2147 (params->pad << 2);
2148 for (j = 0; j < 4; j++)
2149 params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
2150 }
2151}
2152
2153/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
2154static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
2155{
2156 struct b43_phy_n *nphy = dev->phy.n;
2157 int i;
2158 u16 scale, entry;
2159
2160 u16 tmp = nphy->txcal_bbmult;
2161 if (core == 0)
2162 tmp >>= 8;
2163 tmp &= 0xff;
2164
2165 for (i = 0; i < 18; i++) {
2166 scale = (ladder_lo[i].percent * tmp) / 100;
2167 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
2168 b43_ntab_write(dev, B43_NTAB16(15, i), entry);
2169
2170 scale = (ladder_iq[i].percent * tmp) / 100;
2171 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
2172 b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry);
2173 }
2174}
2175
2176/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
2177static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
2178{
2179 int i;
2180 for (i = 0; i < 15; i++)
2181 b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
2182 tbl_tx_filter_coef_rev4[2][i]);
2183}
2184
2185/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
2186static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
2187{
2188 int i, j;
2189 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
2190 u16 offset[] = { 0x186, 0x195, 0x2C5 };
2191
2192 for (i = 0; i < 3; i++)
2193 for (j = 0; j < 15; j++)
2194 b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2195 tbl_tx_filter_coef_rev4[i][j]);
2196
2197 if (dev->phy.is_40mhz) {
2198 for (j = 0; j < 15; j++)
2199 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2200 tbl_tx_filter_coef_rev4[3][j]);
2201 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2202 for (j = 0; j < 15; j++)
2203 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2204 tbl_tx_filter_coef_rev4[5][j]);
2205 }
2206
2207 if (dev->phy.channel == 14)
2208 for (j = 0; j < 15; j++)
2209 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2210 tbl_tx_filter_coef_rev4[6][j]);
2211}
2212
2213/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
2214static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
2215{
2216 struct b43_phy_n *nphy = dev->phy.n;
2217
2218 u16 curr_gain[2];
2219 struct nphy_txgains target;
2220 const u32 *table = NULL;
2221
2222 if (nphy->txpwrctrl == 0) {
2223 int i;
2224
2225 if (nphy->hang_avoid)
2226 b43_nphy_stay_in_carrier_search(dev, true);
2227 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain);
2228 if (nphy->hang_avoid)
2229 b43_nphy_stay_in_carrier_search(dev, false);
2230
2231 for (i = 0; i < 2; ++i) {
2232 if (dev->phy.rev >= 3) {
2233 target.ipa[i] = curr_gain[i] & 0x000F;
2234 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
2235 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2236 target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
2237 } else {
2238 target.ipa[i] = curr_gain[i] & 0x0003;
2239 target.pad[i] = (curr_gain[i] & 0x000C) >> 2;
2240 target.pga[i] = (curr_gain[i] & 0x0070) >> 4;
2241 target.txgm[i] = (curr_gain[i] & 0x0380) >> 7;
2242 }
2243 }
2244 } else {
2245 int i;
2246 u16 index[2];
2247 index[0] = (b43_phy_read(dev, B43_NPHY_C1_TXPCTL_STAT) &
2248 B43_NPHY_TXPCTL_STAT_BIDX) >>
2249 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
2250 index[1] = (b43_phy_read(dev, B43_NPHY_C2_TXPCTL_STAT) &
2251 B43_NPHY_TXPCTL_STAT_BIDX) >>
2252 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
2253
2254 for (i = 0; i < 2; ++i) {
2255 if (dev->phy.rev >= 3) {
2256 enum ieee80211_band band =
2257 b43_current_band(dev->wl);
2258
2259 if ((nphy->ipa2g_on &&
2260 band == IEEE80211_BAND_2GHZ) ||
2261 (nphy->ipa5g_on &&
2262 band == IEEE80211_BAND_5GHZ)) {
2263 table = b43_nphy_get_ipa_gain_table(dev);
2264 } else {
2265 if (band == IEEE80211_BAND_5GHZ) {
2266 if (dev->phy.rev == 3)
2267 table = b43_ntab_tx_gain_rev3_5ghz;
2268 else if (dev->phy.rev == 4)
2269 table = b43_ntab_tx_gain_rev4_5ghz;
2270 else
2271 table = b43_ntab_tx_gain_rev5plus_5ghz;
2272 } else {
2273 table = b43_ntab_tx_gain_rev3plus_2ghz;
2274 }
2275 }
2276
2277 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
2278 target.pad[i] = (table[index[i]] >> 20) & 0xF;
2279 target.pga[i] = (table[index[i]] >> 24) & 0xF;
2280 target.txgm[i] = (table[index[i]] >> 28) & 0xF;
2281 } else {
2282 table = b43_ntab_tx_gain_rev0_1_2;
2283
2284 target.ipa[i] = (table[index[i]] >> 16) & 0x3;
2285 target.pad[i] = (table[index[i]] >> 18) & 0x3;
2286 target.pga[i] = (table[index[i]] >> 20) & 0x7;
2287 target.txgm[i] = (table[index[i]] >> 23) & 0x7;
2288 }
2289 }
2290 }
2291
2292 return target;
2293}
2294
2295/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
2296static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
2297{
2298 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2299
2300 if (dev->phy.rev >= 3) {
2301 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]);
2302 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
2303 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
2304 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]);
2305 b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]);
2306 b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]);
2307 b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]);
2308 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]);
2309 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]);
2310 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
2311 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
2312 b43_nphy_reset_cca(dev);
2313 } else {
2314 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]);
2315 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]);
2316 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
2317 b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]);
2318 b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]);
2319 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]);
2320 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]);
2321 }
2322}
2323
2324/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2325static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2326{
2327 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2328 u16 tmp;
2329
2330 regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2331 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2332 if (dev->phy.rev >= 3) {
2333 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00);
2334 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00);
2335
2336 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
2337 regs[2] = tmp;
2338 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600);
2339
2340 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2341 regs[3] = tmp;
2342 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600);
2343
2344 regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG);
2345 b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX);
2346
2347 tmp = b43_ntab_read(dev, B43_NTAB16(8, 3));
2348 regs[5] = tmp;
2349 b43_ntab_write(dev, B43_NTAB16(8, 3), 0);
2350
2351 tmp = b43_ntab_read(dev, B43_NTAB16(8, 19));
2352 regs[6] = tmp;
2353 b43_ntab_write(dev, B43_NTAB16(8, 19), 0);
2354 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2355 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2356
2357 b43_nphy_rf_control_intc_override(dev, 2, 1, 3);
2358 b43_nphy_rf_control_intc_override(dev, 1, 2, 1);
2359 b43_nphy_rf_control_intc_override(dev, 1, 8, 2);
2360
2361 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
2362 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2363 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2364 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2365 } else {
2366 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2367 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2368 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2369 regs[2] = tmp;
2370 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000);
2371 tmp = b43_ntab_read(dev, B43_NTAB16(8, 2));
2372 regs[3] = tmp;
2373 tmp |= 0x2000;
2374 b43_ntab_write(dev, B43_NTAB16(8, 2), tmp);
2375 tmp = b43_ntab_read(dev, B43_NTAB16(8, 18));
2376 regs[4] = tmp;
2377 tmp |= 0x2000;
2378 b43_ntab_write(dev, B43_NTAB16(8, 18), tmp);
2379 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2380 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2381 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2382 tmp = 0x0180;
2383 else
2384 tmp = 0x0120;
2385 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
2386 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
2387 }
2388}
2389
2390/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2391static void b43_nphy_save_cal(struct b43_wldev *dev)
2392{
2393 struct b43_phy_n *nphy = dev->phy.n;
2394
2395 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2396 u16 *txcal_radio_regs = NULL;
2397 u8 *iqcal_chanspec;
2398 u16 *table = NULL;
2399
2400 if (nphy->hang_avoid)
2401 b43_nphy_stay_in_carrier_search(dev, 1);
2402
2403 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2404 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
2405 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
2406 iqcal_chanspec = &nphy->iqcal_chanspec_2G;
2407 table = nphy->cal_cache.txcal_coeffs_2G;
2408 } else {
2409 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
2410 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
2411 iqcal_chanspec = &nphy->iqcal_chanspec_5G;
2412 table = nphy->cal_cache.txcal_coeffs_5G;
2413 }
2414
2415 b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2416 /* TODO use some definitions */
2417 if (dev->phy.rev >= 3) {
2418 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2419 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2420 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2421 txcal_radio_regs[3] = b43_radio_read(dev, 0x3022);
2422 txcal_radio_regs[4] = b43_radio_read(dev, 0x2023);
2423 txcal_radio_regs[5] = b43_radio_read(dev, 0x2024);
2424 txcal_radio_regs[6] = b43_radio_read(dev, 0x3023);
2425 txcal_radio_regs[7] = b43_radio_read(dev, 0x3024);
2426 } else {
2427 txcal_radio_regs[0] = b43_radio_read(dev, 0x8B);
2428 txcal_radio_regs[1] = b43_radio_read(dev, 0xBA);
2429 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2430 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2431 }
2432 *iqcal_chanspec = nphy->radio_chanspec;
2433 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
2434
2435 if (nphy->hang_avoid)
2436 b43_nphy_stay_in_carrier_search(dev, 0);
2437}
2438
2439/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2440static void b43_nphy_restore_cal(struct b43_wldev *dev)
2441{
2442 struct b43_phy_n *nphy = dev->phy.n;
2443
2444 u16 coef[4];
2445 u16 *loft = NULL;
2446 u16 *table = NULL;
2447
2448 int i;
2449 u16 *txcal_radio_regs = NULL;
2450 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2451
2452 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2453 if (nphy->iqcal_chanspec_2G == 0)
2454 return;
2455 table = nphy->cal_cache.txcal_coeffs_2G;
2456 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2457 } else {
2458 if (nphy->iqcal_chanspec_5G == 0)
2459 return;
2460 table = nphy->cal_cache.txcal_coeffs_5G;
2461 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
2462 }
2463
2464 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table);
2465
2466 for (i = 0; i < 4; i++) {
2467 if (dev->phy.rev >= 3)
2468 table[i] = coef[i];
2469 else
2470 coef[i] = 0;
2471 }
2472
2473 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef);
2474 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft);
2475 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft);
2476
2477 if (dev->phy.rev < 2)
2478 b43_nphy_tx_iq_workaround(dev);
2479
2480 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2481 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
2482 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
2483 } else {
2484 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
2485 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
2486 }
2487
2488 /* TODO use some definitions */
2489 if (dev->phy.rev >= 3) {
2490 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
2491 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
2492 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
2493 b43_radio_write(dev, 0x3022, txcal_radio_regs[3]);
2494 b43_radio_write(dev, 0x2023, txcal_radio_regs[4]);
2495 b43_radio_write(dev, 0x2024, txcal_radio_regs[5]);
2496 b43_radio_write(dev, 0x3023, txcal_radio_regs[6]);
2497 b43_radio_write(dev, 0x3024, txcal_radio_regs[7]);
2498 } else {
2499 b43_radio_write(dev, 0x8B, txcal_radio_regs[0]);
2500 b43_radio_write(dev, 0xBA, txcal_radio_regs[1]);
2501 b43_radio_write(dev, 0x8D, txcal_radio_regs[2]);
2502 b43_radio_write(dev, 0xBC, txcal_radio_regs[3]);
2503 }
2504 b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs);
2505}
2506
2507/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
2508static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2509 struct nphy_txgains target,
2510 bool full, bool mphase)
2511{
2512 struct b43_phy_n *nphy = dev->phy.n;
2513 int i;
2514 int error = 0;
2515 int freq;
2516 bool avoid = false;
2517 u8 length;
2518 u16 tmp, core, type, count, max, numb, last, cmd;
2519 const u16 *table;
2520 bool phy6or5x;
2521
2522 u16 buffer[11];
2523 u16 diq_start = 0;
2524 u16 save[2];
2525 u16 gain[2];
2526 struct nphy_iqcal_params params[2];
2527 bool updated[2] = { };
2528
2529 b43_nphy_stay_in_carrier_search(dev, true);
2530
2531 if (dev->phy.rev >= 4) {
2532 avoid = nphy->hang_avoid;
2533 nphy->hang_avoid = 0;
2534 }
2535
2536 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
2537
2538 for (i = 0; i < 2; i++) {
2539 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
2540 gain[i] = params[i].cal_gain;
2541 }
2542
2543 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain);
2544
2545 b43_nphy_tx_cal_radio_setup(dev);
2546 b43_nphy_tx_cal_phy_setup(dev);
2547
2548 phy6or5x = dev->phy.rev >= 6 ||
2549 (dev->phy.rev == 5 && nphy->ipa2g_on &&
2550 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
2551 if (phy6or5x) {
2552 if (dev->phy.is_40mhz) {
2553 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2554 tbl_tx_iqlo_cal_loft_ladder_40);
2555 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2556 tbl_tx_iqlo_cal_iqimb_ladder_40);
2557 } else {
2558 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2559 tbl_tx_iqlo_cal_loft_ladder_20);
2560 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2561 tbl_tx_iqlo_cal_iqimb_ladder_20);
2562 }
2563 }
2564
2565 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
2566
2567 if (!dev->phy.is_40mhz)
2568 freq = 2500;
2569 else
2570 freq = 5000;
2571
2572 if (nphy->mphase_cal_phase_id > 2)
2573 b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
2574 0xFFFF, 0, true, false);
2575 else
2576 error = b43_nphy_tx_tone(dev, freq, 250, true, false);
2577
2578 if (error == 0) {
2579 if (nphy->mphase_cal_phase_id > 2) {
2580 table = nphy->mphase_txcal_bestcoeffs;
2581 length = 11;
2582 if (dev->phy.rev < 3)
2583 length -= 2;
2584 } else {
2585 if (!full && nphy->txiqlocal_coeffsvalid) {
2586 table = nphy->txiqlocal_bestc;
2587 length = 11;
2588 if (dev->phy.rev < 3)
2589 length -= 2;
2590 } else {
2591 full = true;
2592 if (dev->phy.rev >= 3) {
2593 table = tbl_tx_iqlo_cal_startcoefs_nphyrev3;
2594 length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3;
2595 } else {
2596 table = tbl_tx_iqlo_cal_startcoefs;
2597 length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS;
2598 }
2599 }
2600 }
2601
2602 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table);
2603
2604 if (full) {
2605 if (dev->phy.rev >= 3)
2606 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3;
2607 else
2608 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL;
2609 } else {
2610 if (dev->phy.rev >= 3)
2611 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3;
2612 else
2613 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL;
2614 }
2615
2616 if (mphase) {
2617 count = nphy->mphase_txcal_cmdidx;
2618 numb = min(max,
2619 (u16)(count + nphy->mphase_txcal_numcmds));
2620 } else {
2621 count = 0;
2622 numb = max;
2623 }
2624
2625 for (; count < numb; count++) {
2626 if (full) {
2627 if (dev->phy.rev >= 3)
2628 cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count];
2629 else
2630 cmd = tbl_tx_iqlo_cal_cmds_fullcal[count];
2631 } else {
2632 if (dev->phy.rev >= 3)
2633 cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count];
2634 else
2635 cmd = tbl_tx_iqlo_cal_cmds_recal[count];
2636 }
2637
2638 core = (cmd & 0x3000) >> 12;
2639 type = (cmd & 0x0F00) >> 8;
2640
2641 if (phy6or5x && updated[core] == 0) {
2642 b43_nphy_update_tx_cal_ladder(dev, core);
2643 updated[core] = 1;
2644 }
2645
2646 tmp = (params[core].ncorr[type] << 8) | 0x66;
2647 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
2648
2649 if (type == 1 || type == 3 || type == 4) {
2650 buffer[0] = b43_ntab_read(dev,
2651 B43_NTAB16(15, 69 + core));
2652 diq_start = buffer[0];
2653 buffer[0] = 0;
2654 b43_ntab_write(dev, B43_NTAB16(15, 69 + core),
2655 0);
2656 }
2657
2658 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
2659 for (i = 0; i < 2000; i++) {
2660 tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD);
2661 if (tmp & 0xC000)
2662 break;
2663 udelay(10);
2664 }
2665
2666 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2667 buffer);
2668 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length,
2669 buffer);
2670
2671 if (type == 1 || type == 3 || type == 4)
2672 buffer[0] = diq_start;
2673 }
2674
2675 if (mphase)
2676 nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb;
2677
2678 last = (dev->phy.rev < 3) ? 6 : 7;
2679
2680 if (!mphase || nphy->mphase_cal_phase_id == last) {
2681 b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer);
2682 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer);
2683 if (dev->phy.rev < 3) {
2684 buffer[0] = 0;
2685 buffer[1] = 0;
2686 buffer[2] = 0;
2687 buffer[3] = 0;
2688 }
2689 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2690 buffer);
2691 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2,
2692 buffer);
2693 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2694 buffer);
2695 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
2696 buffer);
2697 length = 11;
2698 if (dev->phy.rev < 3)
2699 length -= 2;
2700 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2701 nphy->txiqlocal_bestc);
2702 nphy->txiqlocal_coeffsvalid = true;
2703 /* TODO: Set nphy->txiqlocal_chanspec to
2704 the current channel */
2705 } else {
2706 length = 11;
2707 if (dev->phy.rev < 3)
2708 length -= 2;
2709 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2710 nphy->mphase_txcal_bestcoeffs);
2711 }
2712
2713 b43_nphy_stop_playback(dev);
2714 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
2715 }
2716
2717 b43_nphy_tx_cal_phy_cleanup(dev);
2718 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
2719
2720 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
2721 b43_nphy_tx_iq_workaround(dev);
2722
2723 if (dev->phy.rev >= 4)
2724 nphy->hang_avoid = avoid;
2725
2726 b43_nphy_stay_in_carrier_search(dev, false);
2727
2728 return error;
2729}
2730
2731/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
2732static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2733{
2734 struct b43_phy_n *nphy = dev->phy.n;
2735 u8 i;
2736 u16 buffer[7];
2737 bool equal = true;
2738
2739 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */)
2740 return;
2741
2742 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
2743 for (i = 0; i < 4; i++) {
2744 if (buffer[i] != nphy->txiqlocal_bestc[i]) {
2745 equal = false;
2746 break;
2747 }
2748 }
2749
2750 if (!equal) {
2751 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4,
2752 nphy->txiqlocal_bestc);
2753 for (i = 0; i < 4; i++)
2754 buffer[i] = 0;
2755 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2756 buffer);
2757 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2758 &nphy->txiqlocal_bestc[5]);
2759 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
2760 &nphy->txiqlocal_bestc[5]);
2761 }
2762}
2763
2764/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
2765static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2766 struct nphy_txgains target, u8 type, bool debug)
2767{
2768 struct b43_phy_n *nphy = dev->phy.n;
2769 int i, j, index;
2770 u8 rfctl[2];
2771 u8 afectl_core;
2772 u16 tmp[6];
2773 u16 cur_hpf1, cur_hpf2, cur_lna;
2774 u32 real, imag;
2775 enum ieee80211_band band;
2776
2777 u8 use;
2778 u16 cur_hpf;
2779 u16 lna[3] = { 3, 3, 1 };
2780 u16 hpf1[3] = { 7, 2, 0 };
2781 u16 hpf2[3] = { 2, 0, 0 };
2782 u32 power[3] = { };
2783 u16 gain_save[2];
2784 u16 cal_gain[2];
2785 struct nphy_iqcal_params cal_params[2];
2786 struct nphy_iq_est est;
2787 int ret = 0;
2788 bool playtone = true;
2789 int desired = 13;
2790
2791 b43_nphy_stay_in_carrier_search(dev, 1);
2792
2793 if (dev->phy.rev < 2)
2794 b43_nphy_reapply_tx_cal_coeffs(dev);
2795 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
2796 for (i = 0; i < 2; i++) {
2797 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
2798 cal_gain[i] = cal_params[i].cal_gain;
2799 }
2800 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain);
2801
2802 for (i = 0; i < 2; i++) {
2803 if (i == 0) {
2804 rfctl[0] = B43_NPHY_RFCTL_INTC1;
2805 rfctl[1] = B43_NPHY_RFCTL_INTC2;
2806 afectl_core = B43_NPHY_AFECTL_C1;
2807 } else {
2808 rfctl[0] = B43_NPHY_RFCTL_INTC2;
2809 rfctl[1] = B43_NPHY_RFCTL_INTC1;
2810 afectl_core = B43_NPHY_AFECTL_C2;
2811 }
2812
2813 tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
2814 tmp[2] = b43_phy_read(dev, afectl_core);
2815 tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2816 tmp[4] = b43_phy_read(dev, rfctl[0]);
2817 tmp[5] = b43_phy_read(dev, rfctl[1]);
2818
2819 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
2820 (u16)~B43_NPHY_RFSEQCA_RXDIS,
2821 ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
2822 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
2823 (1 - i));
2824 b43_phy_set(dev, afectl_core, 0x0006);
2825 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006);
2826
2827 band = b43_current_band(dev->wl);
2828
2829 if (nphy->rxcalparams & 0xFF000000) {
2830 if (band == IEEE80211_BAND_5GHZ)
2831 b43_phy_write(dev, rfctl[0], 0x140);
2832 else
2833 b43_phy_write(dev, rfctl[0], 0x110);
2834 } else {
2835 if (band == IEEE80211_BAND_5GHZ)
2836 b43_phy_write(dev, rfctl[0], 0x180);
2837 else
2838 b43_phy_write(dev, rfctl[0], 0x120);
2839 }
2840
2841 if (band == IEEE80211_BAND_5GHZ)
2842 b43_phy_write(dev, rfctl[1], 0x148);
2843 else
2844 b43_phy_write(dev, rfctl[1], 0x114);
2845
2846 if (nphy->rxcalparams & 0x10000) {
2847 b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC,
2848 (i + 1));
2849 b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC,
2850 (2 - i));
2851 }
2852
2853 for (j = 0; i < 4; j++) {
2854 if (j < 3) {
2855 cur_lna = lna[j];
2856 cur_hpf1 = hpf1[j];
2857 cur_hpf2 = hpf2[j];
2858 } else {
2859 if (power[1] > 10000) {
2860 use = 1;
2861 cur_hpf = cur_hpf1;
2862 index = 2;
2863 } else {
2864 if (power[0] > 10000) {
2865 use = 1;
2866 cur_hpf = cur_hpf1;
2867 index = 1;
2868 } else {
2869 index = 0;
2870 use = 2;
2871 cur_hpf = cur_hpf2;
2872 }
2873 }
2874 cur_lna = lna[index];
2875 cur_hpf1 = hpf1[index];
2876 cur_hpf2 = hpf2[index];
2877 cur_hpf += desired - hweight32(power[index]);
2878 cur_hpf = clamp_val(cur_hpf, 0, 10);
2879 if (use == 1)
2880 cur_hpf1 = cur_hpf;
2881 else
2882 cur_hpf2 = cur_hpf;
2883 }
2884
2885 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
2886 (cur_lna << 2));
2887 b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3,
2888 false);
2889 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
2890 b43_nphy_stop_playback(dev);
2891
2892 if (playtone) {
2893 ret = b43_nphy_tx_tone(dev, 4000,
2894 (nphy->rxcalparams & 0xFFFF),
2895 false, false);
2896 playtone = false;
2897 } else {
2898 b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
2899 false, false);
2900 }
2901
2902 if (ret == 0) {
2903 if (j < 3) {
2904 b43_nphy_rx_iq_est(dev, &est, 1024, 32,
2905 false);
2906 if (i == 0) {
2907 real = est.i0_pwr;
2908 imag = est.q0_pwr;
2909 } else {
2910 real = est.i1_pwr;
2911 imag = est.q1_pwr;
2912 }
2913 power[i] = ((real + imag) / 1024) + 1;
2914 } else {
2915 b43_nphy_calc_rx_iq_comp(dev, 1 << i);
2916 }
2917 b43_nphy_stop_playback(dev);
2918 }
2919
2920 if (ret != 0)
2921 break;
2922 }
2923
2924 b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC);
2925 b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC);
2926 b43_phy_write(dev, rfctl[1], tmp[5]);
2927 b43_phy_write(dev, rfctl[0], tmp[4]);
2928 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]);
2929 b43_phy_write(dev, afectl_core, tmp[2]);
2930 b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]);
2931
2932 if (ret != 0)
2933 break;
2934 }
2935
2936 b43_nphy_rf_control_override(dev, 0x400, 0, 3, true);
2937 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
2938 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
2939
2940 b43_nphy_stay_in_carrier_search(dev, 0);
2941
2942 return ret;
2943}
2944
2945static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
2946 struct nphy_txgains target, u8 type, bool debug)
2947{
2948 return -1;
2949}
2950
2951/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
2952static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
2953 struct nphy_txgains target, u8 type, bool debug)
2954{
2955 if (dev->phy.rev >= 3)
2956 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
2957 else
2958 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
2959}
2960
2961/*
2962 * Init N-PHY
2963 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
2964 */
420int b43_phy_initn(struct b43_wldev *dev) 2965int b43_phy_initn(struct b43_wldev *dev)
421{ 2966{
2967 struct ssb_bus *bus = dev->dev->bus;
422 struct b43_phy *phy = &dev->phy; 2968 struct b43_phy *phy = &dev->phy;
2969 struct b43_phy_n *nphy = phy->n;
2970 u8 tx_pwr_state;
2971 struct nphy_txgains target;
423 u16 tmp; 2972 u16 tmp;
2973 enum ieee80211_band tmp2;
2974 bool do_rssi_cal;
424 2975
425 //TODO: Spectral management 2976 u16 clip[2];
2977 bool do_cal = false;
2978
2979 if ((dev->phy.rev >= 3) &&
2980 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
2981 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
2982 chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
2983 }
2984 nphy->deaf_count = 0;
426 b43_nphy_tables_init(dev); 2985 b43_nphy_tables_init(dev);
2986 nphy->crsminpwr_adjusted = false;
2987 nphy->noisevars_adjusted = false;
427 2988
428 /* Clear all overrides */ 2989 /* Clear all overrides */
429 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); 2990 if (dev->phy.rev >= 3) {
2991 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
2992 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
2993 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
2994 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
2995 } else {
2996 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
2997 }
430 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0); 2998 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
431 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0); 2999 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
432 b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0); 3000 if (dev->phy.rev < 6) {
433 b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0); 3001 b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
3002 b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
3003 }
434 b43_phy_mask(dev, B43_NPHY_RFSEQMODE, 3004 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
435 ~(B43_NPHY_RFSEQMODE_CAOVER | 3005 ~(B43_NPHY_RFSEQMODE_CAOVER |
436 B43_NPHY_RFSEQMODE_TROVER)); 3006 B43_NPHY_RFSEQMODE_TROVER));
3007 if (dev->phy.rev >= 3)
3008 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, 0);
437 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0); 3009 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);
438 3010
439 tmp = (phy->rev < 2) ? 64 : 59; 3011 if (dev->phy.rev <= 2) {
440 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, 3012 tmp = (dev->phy.rev == 2) ? 0x3B : 0x40;
441 ~B43_NPHY_BPHY_CTL3_SCALE, 3013 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
442 tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT); 3014 ~B43_NPHY_BPHY_CTL3_SCALE,
443 3015 tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
3016 }
444 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); 3017 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
445 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); 3018 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
446 3019
447 b43_phy_write(dev, B43_NPHY_TXREALFD, 184); 3020 if (bus->sprom.boardflags2_lo & 0x100 ||
448 b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200); 3021 (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
449 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80); 3022 bus->boardinfo.type == 0x8B))
450 b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511); 3023 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
3024 else
3025 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
3026 b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 0xC8);
3027 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
3028 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
451 3029
452 //TODO MIMO-Config 3030 b43_nphy_update_mimo_config(dev, nphy->preamble_override);
453 //TODO Update TX/RX chain 3031 b43_nphy_update_txrx_chain(dev);
454 3032
455 if (phy->rev < 2) { 3033 if (phy->rev < 2) {
456 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); 3034 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
457 b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4); 3035 b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
458 } 3036 }
3037
3038 tmp2 = b43_current_band(dev->wl);
3039 if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) ||
3040 (nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) {
3041 b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
3042 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
3043 nphy->papd_epsilon_offset[0] << 7);
3044 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
3045 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
3046 nphy->papd_epsilon_offset[1] << 7);
3047 b43_nphy_int_pa_set_tx_dig_filters(dev);
3048 } else if (phy->rev >= 5) {
3049 b43_nphy_ext_pa_set_tx_dig_filters(dev);
3050 }
3051
459 b43_nphy_workarounds(dev); 3052 b43_nphy_workarounds(dev);
460 b43_nphy_reset_cca(dev);
461 3053
462 ssb_write32(dev->dev, SSB_TMSLOW, 3054 /* Reset CCA, in init code it differs a little from standard way */
463 ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN); 3055 b43_nphy_bmac_clock_fgc(dev, 1);
3056 tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
3057 b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
3058 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
3059 b43_nphy_bmac_clock_fgc(dev, 0);
3060
3061 /* TODO N PHY MAC PHY Clock Set with argument 1 */
3062
3063 b43_nphy_pa_override(dev, false);
464 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 3064 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
465 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); 3065 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3066 b43_nphy_pa_override(dev, true);
3067
3068 b43_nphy_classifier(dev, 0, 0);
3069 b43_nphy_read_clip_detection(dev, clip);
3070 tx_pwr_state = nphy->txpwrctrl;
3071 /* TODO N PHY TX power control with argument 0
3072 (turning off power control) */
3073 /* TODO Fix the TX Power Settings */
3074 /* TODO N PHY TX Power Control Idle TSSI */
3075 /* TODO N PHY TX Power Control Setup */
3076
3077 if (phy->rev >= 3) {
3078 /* TODO */
3079 } else {
3080 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128,
3081 b43_ntab_tx_gain_rev0_1_2);
3082 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128,
3083 b43_ntab_tx_gain_rev0_1_2);
3084 }
3085
3086 if (nphy->phyrxchain != 3)
3087 ;/* TODO N PHY RX Core Set State with phyrxchain as argument */
3088 if (nphy->mphase_cal_phase_id > 0)
3089 ;/* TODO PHY Periodic Calibration Multi-Phase Restart */
3090
3091 do_rssi_cal = false;
3092 if (phy->rev >= 3) {
3093 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3094 do_rssi_cal = (nphy->rssical_chanspec_2G == 0);
3095 else
3096 do_rssi_cal = (nphy->rssical_chanspec_5G == 0);
3097
3098 if (do_rssi_cal)
3099 b43_nphy_rssi_cal(dev);
3100 else
3101 b43_nphy_restore_rssi_cal(dev);
3102 } else {
3103 b43_nphy_rssi_cal(dev);
3104 }
3105
3106 if (!((nphy->measure_hold & 0x6) != 0)) {
3107 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3108 do_cal = (nphy->iqcal_chanspec_2G == 0);
3109 else
3110 do_cal = (nphy->iqcal_chanspec_5G == 0);
3111
3112 if (nphy->mute)
3113 do_cal = false;
3114
3115 if (do_cal) {
3116 target = b43_nphy_get_tx_gains(dev);
3117
3118 if (nphy->antsel_type == 2)
3119 ;/*TODO NPHY Superswitch Init with argument 1*/
3120 if (nphy->perical != 2) {
3121 b43_nphy_rssi_cal(dev);
3122 if (phy->rev >= 3) {
3123 nphy->cal_orig_pwr_idx[0] =
3124 nphy->txpwrindex[0].index_internal;
3125 nphy->cal_orig_pwr_idx[1] =
3126 nphy->txpwrindex[1].index_internal;
3127 /* TODO N PHY Pre Calibrate TX Gain */
3128 target = b43_nphy_get_tx_gains(dev);
3129 }
3130 }
3131 }
3132 }
3133
3134 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
3135 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
3136 b43_nphy_save_cal(dev);
3137 else if (nphy->mphase_cal_phase_id == 0)
3138 ;/* N PHY Periodic Calibration with argument 3 */
3139 } else {
3140 b43_nphy_restore_cal(dev);
3141 }
466 3142
467 b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */ 3143 b43_nphy_tx_pwr_ctrl_coef_setup(dev);
468 //TODO read core1/2 clip1 thres regs 3144 /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
469 3145 b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
470 if (1 /* FIXME Band is 2.4GHz */) 3146 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
471 b43_nphy_bphy_init(dev); 3147 if (phy->rev >= 3 && phy->rev <= 6)
472 //TODO disable TX power control 3148 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
473 //TODO Fix the TX power settings 3149 b43_nphy_tx_lp_fbw(dev);
474 //TODO Init periodic calibration with reason 3 3150 if (phy->rev >= 3)
475 b43_nphy_rssi_cal(dev, 2); 3151 b43_nphy_spur_workaround(dev);
476 b43_nphy_rssi_cal(dev, 0);
477 b43_nphy_rssi_cal(dev, 1);
478 //TODO get TX gain
479 //TODO init superswitch
480 //TODO calibrate LO
481 //TODO idle TSSI TX pctl
482 //TODO TX power control power setup
483 //TODO table writes
484 //TODO TX power control coefficients
485 //TODO enable TX power control
486 //TODO control antenna selection
487 //TODO init radar detection
488 //TODO reset channel if changed
489 3152
490 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); 3153 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
491 return 0; 3154 return 0;
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 1749aef4147d..403aad3f894f 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -231,6 +231,7 @@
231#define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */ 231#define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */
232#define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */ 232#define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */
233#define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */ 233#define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */
234#define B43_NPHY_AFECTL_OVER1 B43_PHY_N(0x08F) /* AFE control override 1 */
234#define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */ 235#define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */
235#define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */ 236#define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */
236#define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0 237#define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0
@@ -705,6 +706,10 @@
705#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */ 706#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */
706#define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ 707#define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */
707#define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 708#define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0
709#define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */
710#define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */
711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
708 713
709 714
710 715
@@ -919,8 +924,99 @@
919 924
920struct b43_wldev; 925struct b43_wldev;
921 926
927struct b43_phy_n_iq_comp {
928 s16 a0;
929 s16 b0;
930 s16 a1;
931 s16 b1;
932};
933
934struct b43_phy_n_rssical_cache {
935 u16 rssical_radio_regs_2G[2];
936 u16 rssical_phy_regs_2G[12];
937
938 u16 rssical_radio_regs_5G[2];
939 u16 rssical_phy_regs_5G[12];
940};
941
942struct b43_phy_n_cal_cache {
943 u16 txcal_radio_regs_2G[8];
944 u16 txcal_coeffs_2G[8];
945 struct b43_phy_n_iq_comp rxcal_coeffs_2G;
946
947 u16 txcal_radio_regs_5G[8];
948 u16 txcal_coeffs_5G[8];
949 struct b43_phy_n_iq_comp rxcal_coeffs_5G;
950};
951
952struct b43_phy_n_txpwrindex {
953 s8 index;
954 s8 index_internal;
955 s8 index_internal_save;
956 u16 AfectrlOverride;
957 u16 AfeCtrlDacGain;
958 u16 rad_gain;
959 u8 bbmult;
960 u16 iqcomp_a;
961 u16 iqcomp_b;
962 u16 locomp;
963};
964
922struct b43_phy_n { 965struct b43_phy_n {
923 //TODO lots of missing stuff 966 u8 antsel_type;
967 u8 cal_orig_pwr_idx[2];
968 u8 measure_hold;
969 u8 phyrxchain;
970 u8 perical;
971 u32 deaf_count;
972 u32 rxcalparams;
973 bool hang_avoid;
974 bool mute;
975 u16 papd_epsilon_offset[2];
976 s32 preamble_override;
977 u32 bb_mult_save;
978 u16 radio_chanspec;
979
980 bool gain_boost;
981 bool elna_gain_config;
982 bool band5g_pwrgain;
983
984 u8 mphase_cal_phase_id;
985 u16 mphase_txcal_cmdidx;
986 u16 mphase_txcal_numcmds;
987 u16 mphase_txcal_bestcoeffs[11];
988
989 u8 txpwrctrl;
990 u16 txcal_bbmult;
991 u16 txiqlocal_bestc[11];
992 bool txiqlocal_coeffsvalid;
993 struct b43_phy_n_txpwrindex txpwrindex[2];
994
995 u8 txrx_chain;
996 u16 tx_rx_cal_phy_saveregs[11];
997 u16 tx_rx_cal_radio_saveregs[22];
998
999 u16 rfctrl_intc1_save;
1000 u16 rfctrl_intc2_save;
1001
1002 u16 classifier_state;
1003 u16 clip_state[2];
1004
1005 bool aband_spurwar_en;
1006 bool gband_spurwar_en;
1007
1008 bool ipa2g_on;
1009 u8 iqcal_chanspec_2G;
1010 u8 rssical_chanspec_2G;
1011
1012 bool ipa5g_on;
1013 u8 iqcal_chanspec_5G;
1014 u8 rssical_chanspec_5G;
1015
1016 struct b43_phy_n_rssical_cache rssical_cache;
1017 struct b43_phy_n_cal_cache cal_cache;
1018 bool crsminpwr_adjusted;
1019 bool noisevars_adjusted;
924}; 1020};
925 1021
926 1022
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index c01b8e02412f..a6062c3e89a5 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -559,7 +559,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
559 b43err(dev->wl, "PIO transmission failure\n"); 559 b43err(dev->wl, "PIO transmission failure\n");
560 goto out; 560 goto out;
561 } 561 }
562 q->nr_tx_packets++;
563 562
564 B43_WARN_ON(q->buffer_used > q->buffer_size); 563 B43_WARN_ON(q->buffer_used > q->buffer_size);
565 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || 564 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
@@ -605,22 +604,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
605 } 604 }
606} 605}
607 606
608void b43_pio_get_tx_stats(struct b43_wldev *dev,
609 struct ieee80211_tx_queue_stats *stats)
610{
611 const int nr_queues = dev->wl->hw->queues;
612 struct b43_pio_txqueue *q;
613 int i;
614
615 for (i = 0; i < nr_queues; i++) {
616 q = select_queue_by_priority(dev, i);
617
618 stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
619 stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
620 stats[i].count = q->nr_tx_packets;
621 }
622}
623
624/* Returns whether we should fetch another frame. */ 607/* Returns whether we should fetch another frame. */
625static bool pio_rx_frame(struct b43_pio_rxqueue *q) 608static bool pio_rx_frame(struct b43_pio_rxqueue *q)
626{ 609{
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index 7dd649c9ddad..1e516147424f 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -55,8 +55,6 @@
55#define B43_PIO_MAX_NR_TXPACKETS 32 55#define B43_PIO_MAX_NR_TXPACKETS 32
56 56
57 57
58#ifdef CONFIG_B43_PIO
59
60struct b43_pio_txpacket { 58struct b43_pio_txpacket {
61 /* Pointer to the TX queue we belong to. */ 59 /* Pointer to the TX queue we belong to. */
62 struct b43_pio_txqueue *queue; 60 struct b43_pio_txqueue *queue;
@@ -92,9 +90,6 @@ struct b43_pio_txqueue {
92 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS]; 90 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
93 struct list_head packets_list; 91 struct list_head packets_list;
94 92
95 /* Total number of transmitted packets. */
96 unsigned int nr_tx_packets;
97
98 /* Shortcut to the 802.11 core revision. This is to 93 /* Shortcut to the 802.11 core revision. This is to
99 * avoid horrible pointer dereferencing in the fastpaths. */ 94 * avoid horrible pointer dereferencing in the fastpaths. */
100 u8 rev; 95 u8 rev;
@@ -162,49 +157,9 @@ void b43_pio_free(struct b43_wldev *dev);
162int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); 157int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
163void b43_pio_handle_txstatus(struct b43_wldev *dev, 158void b43_pio_handle_txstatus(struct b43_wldev *dev,
164 const struct b43_txstatus *status); 159 const struct b43_txstatus *status);
165void b43_pio_get_tx_stats(struct b43_wldev *dev,
166 struct ieee80211_tx_queue_stats *stats);
167void b43_pio_rx(struct b43_pio_rxqueue *q); 160void b43_pio_rx(struct b43_pio_rxqueue *q);
168 161
169void b43_pio_tx_suspend(struct b43_wldev *dev); 162void b43_pio_tx_suspend(struct b43_wldev *dev);
170void b43_pio_tx_resume(struct b43_wldev *dev); 163void b43_pio_tx_resume(struct b43_wldev *dev);
171 164
172
173#else /* CONFIG_B43_PIO */
174
175
176static inline int b43_pio_init(struct b43_wldev *dev)
177{
178 return 0;
179}
180static inline void b43_pio_free(struct b43_wldev *dev)
181{
182}
183static inline void b43_pio_stop(struct b43_wldev *dev)
184{
185}
186static inline int b43_pio_tx(struct b43_wldev *dev,
187 struct sk_buff *skb)
188{
189 return 0;
190}
191static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
192 const struct b43_txstatus *status)
193{
194}
195static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
196 struct ieee80211_tx_queue_stats *stats)
197{
198}
199static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
200{
201}
202static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
203{
204}
205static inline void b43_pio_tx_resume(struct b43_wldev *dev)
206{
207}
208
209#endif /* CONFIG_B43_PIO */
210#endif /* B43_PIO_H_ */ 165#endif /* B43_PIO_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4e2336315545..a00d509150f7 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1336,7 +1336,7 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel)
1336} 1336}
1337 1337
1338 1338
1339const u8 b43_ntab_adjustpower0[] = { 1339static const u8 b43_ntab_adjustpower0[] = {
1340 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 1340 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
1341 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 1341 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
1342 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 1342 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1355,7 +1355,7 @@ const u8 b43_ntab_adjustpower0[] = {
1355 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 1355 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
1356}; 1356};
1357 1357
1358const u8 b43_ntab_adjustpower1[] = { 1358static const u8 b43_ntab_adjustpower1[] = {
1359 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 1359 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
1360 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 1360 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
1361 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 1361 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1374,11 +1374,11 @@ const u8 b43_ntab_adjustpower1[] = {
1374 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 1374 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
1375}; 1375};
1376 1376
1377const u16 b43_ntab_bdi[] = { 1377static const u16 b43_ntab_bdi[] = {
1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2, 1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2,
1379}; 1379};
1380 1380
1381const u32 b43_ntab_channelest[] = { 1381static const u32 b43_ntab_channelest[] = {
1382 0x44444444, 0x44444444, 0x44444444, 0x44444444, 1382 0x44444444, 0x44444444, 0x44444444, 0x44444444,
1383 0x44444444, 0x44444444, 0x44444444, 0x44444444, 1383 0x44444444, 0x44444444, 0x44444444, 0x44444444,
1384 0x10101010, 0x10101010, 0x10101010, 0x10101010, 1384 0x10101010, 0x10101010, 0x10101010, 0x10101010,
@@ -1405,7 +1405,7 @@ const u32 b43_ntab_channelest[] = {
1405 0x10101010, 0x10101010, 0x10101010, 0x10101010, 1405 0x10101010, 0x10101010, 0x10101010, 0x10101010,
1406}; 1406};
1407 1407
1408const u8 b43_ntab_estimatepowerlt0[] = { 1408static const u8 b43_ntab_estimatepowerlt0[] = {
1409 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 1409 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
1410 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 1410 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
1411 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 1411 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1416,7 +1416,7 @@ const u8 b43_ntab_estimatepowerlt0[] = {
1416 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 1416 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
1417}; 1417};
1418 1418
1419const u8 b43_ntab_estimatepowerlt1[] = { 1419static const u8 b43_ntab_estimatepowerlt1[] = {
1420 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 1420 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
1421 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 1421 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
1422 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 1422 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1427,14 +1427,14 @@ const u8 b43_ntab_estimatepowerlt1[] = {
1427 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 1427 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
1428}; 1428};
1429 1429
1430const u8 b43_ntab_framelookup[] = { 1430static const u8 b43_ntab_framelookup[] = {
1431 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16, 1431 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16,
1432 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E, 1432 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E,
1433 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A, 1433 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A,
1434 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A, 1434 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A,
1435}; 1435};
1436 1436
1437const u32 b43_ntab_framestruct[] = { 1437static const u32 b43_ntab_framestruct[] = {
1438 0x08004A04, 0x00100000, 0x01000A05, 0x00100020, 1438 0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
1439 0x09804506, 0x00100030, 0x09804507, 0x00100030, 1439 0x09804506, 0x00100030, 0x09804507, 0x00100030,
1440 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1440 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1645,7 +1645,7 @@ const u32 b43_ntab_framestruct[] = {
1645 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1645 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1646}; 1646};
1647 1647
1648const u32 b43_ntab_gainctl0[] = { 1648static const u32 b43_ntab_gainctl0[] = {
1649 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, 1649 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
1650 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, 1650 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
1651 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, 1651 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1680,7 +1680,7 @@ const u32 b43_ntab_gainctl0[] = {
1680 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, 1680 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
1681}; 1681};
1682 1682
1683const u32 b43_ntab_gainctl1[] = { 1683static const u32 b43_ntab_gainctl1[] = {
1684 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, 1684 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
1685 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, 1685 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
1686 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, 1686 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1715,12 +1715,12 @@ const u32 b43_ntab_gainctl1[] = {
1715 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, 1715 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
1716}; 1716};
1717 1717
1718const u32 b43_ntab_intlevel[] = { 1718static const u32 b43_ntab_intlevel[] = {
1719 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46, 1719 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46,
1720 0x00C1188D, 0x080024D2, 0x00000070, 1720 0x00C1188D, 0x080024D2, 0x00000070,
1721}; 1721};
1722 1722
1723const u32 b43_ntab_iqlt0[] = { 1723static const u32 b43_ntab_iqlt0[] = {
1724 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1724 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1725 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1725 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1726 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1726 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1755,7 +1755,7 @@ const u32 b43_ntab_iqlt0[] = {
1755 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1755 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1756}; 1756};
1757 1757
1758const u32 b43_ntab_iqlt1[] = { 1758static const u32 b43_ntab_iqlt1[] = {
1759 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1759 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1760 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1760 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1761 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1761 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1790,7 +1790,7 @@ const u32 b43_ntab_iqlt1[] = {
1790 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1790 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1791}; 1791};
1792 1792
1793const u16 b43_ntab_loftlt0[] = { 1793static const u16 b43_ntab_loftlt0[] = {
1794 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1794 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
1795 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, 1795 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
1796 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1796 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1815,7 +1815,7 @@ const u16 b43_ntab_loftlt0[] = {
1815 0x0002, 0x0103, 1815 0x0002, 0x0103,
1816}; 1816};
1817 1817
1818const u16 b43_ntab_loftlt1[] = { 1818static const u16 b43_ntab_loftlt1[] = {
1819 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1819 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
1820 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, 1820 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
1821 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1821 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1840,7 +1840,7 @@ const u16 b43_ntab_loftlt1[] = {
1840 0x0002, 0x0103, 1840 0x0002, 0x0103,
1841}; 1841};
1842 1842
1843const u8 b43_ntab_mcs[] = { 1843static const u8 b43_ntab_mcs[] = {
1844 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C, 1844 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C,
1845 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C, 1845 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C,
1846 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C, 1846 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C,
@@ -1859,7 +1859,7 @@ const u8 b43_ntab_mcs[] = {
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860}; 1860};
1861 1861
1862const u32 b43_ntab_noisevar10[] = { 1862static const u32 b43_ntab_noisevar10[] = {
1863 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1863 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1864 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1864 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1865 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1865 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1926,7 +1926,7 @@ const u32 b43_ntab_noisevar10[] = {
1926 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1926 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1927}; 1927};
1928 1928
1929const u32 b43_ntab_noisevar11[] = { 1929static const u32 b43_ntab_noisevar11[] = {
1930 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1930 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1931 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1931 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1932 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1932 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1993,7 +1993,7 @@ const u32 b43_ntab_noisevar11[] = {
1993 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1993 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1994}; 1994};
1995 1995
1996const u16 b43_ntab_pilot[] = { 1996static const u16 b43_ntab_pilot[] = {
1997 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 1997 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08,
1998 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5, 1998 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5,
1999 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82, 1999 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82,
@@ -2011,12 +2011,12 @@ const u16 b43_ntab_pilot[] = {
2011 0xF0A0, 0xF028, 0xFFFF, 0xFFFF, 2011 0xF0A0, 0xF028, 0xFFFF, 0xFFFF,
2012}; 2012};
2013 2013
2014const u32 b43_ntab_pilotlt[] = { 2014static const u32 b43_ntab_pilotlt[] = {
2015 0x76540123, 0x62407351, 0x76543201, 0x76540213, 2015 0x76540123, 0x62407351, 0x76543201, 0x76540213,
2016 0x76540123, 0x76430521, 2016 0x76540123, 0x76430521,
2017}; 2017};
2018 2018
2019const u32 b43_ntab_tdi20a0[] = { 2019static const u32 b43_ntab_tdi20a0[] = {
2020 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0, 2020 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0,
2021 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D, 2021 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D,
2022 0x00020301, 0x00030504, 0x00040708, 0x0005090B, 2022 0x00020301, 0x00030504, 0x00040708, 0x0005090B,
@@ -2033,7 +2033,7 @@ const u32 b43_ntab_tdi20a0[] = {
2033 0x00000000, 0x00000000, 0x00000000, 2033 0x00000000, 0x00000000, 0x00000000,
2034}; 2034};
2035 2035
2036const u32 b43_ntab_tdi20a1[] = { 2036static const u32 b43_ntab_tdi20a1[] = {
2037 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630, 2037 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630,
2038 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D, 2038 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D,
2039 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B, 2039 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B,
@@ -2050,7 +2050,7 @@ const u32 b43_ntab_tdi20a1[] = {
2050 0x00000000, 0x00000000, 0x00000000, 2050 0x00000000, 0x00000000, 0x00000000,
2051}; 2051};
2052 2052
2053const u32 b43_ntab_tdi40a0[] = { 2053static const u32 b43_ntab_tdi40a0[] = {
2054 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2, 2054 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2,
2055 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C, 2055 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C,
2056 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2, 2056 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2,
@@ -2081,7 +2081,7 @@ const u32 b43_ntab_tdi40a0[] = {
2081 0x00000000, 0x00000000, 2081 0x00000000, 0x00000000,
2082}; 2082};
2083 2083
2084const u32 b43_ntab_tdi40a1[] = { 2084static const u32 b43_ntab_tdi40a1[] = {
2085 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD, 2085 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD,
2086 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07, 2086 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07,
2087 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D, 2087 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D,
@@ -2112,7 +2112,7 @@ const u32 b43_ntab_tdi40a1[] = {
2112 0x00000000, 0x00000000, 2112 0x00000000, 0x00000000,
2113}; 2113};
2114 2114
2115const u32 b43_ntab_tdtrn[] = { 2115static const u32 b43_ntab_tdtrn[] = {
2116 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6, 2116 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6,
2117 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68, 2117 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68,
2118 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52, 2118 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52,
@@ -2291,7 +2291,7 @@ const u32 b43_ntab_tdtrn[] = {
2291 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE, 2291 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE,
2292}; 2292};
2293 2293
2294const u32 b43_ntab_tmap[] = { 2294static const u32 b43_ntab_tmap[] = {
2295 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888, 2295 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
2296 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8, 2296 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
2297 0xF1111110, 0x11111111, 0x11F11111, 0x00000111, 2297 0xF1111110, 0x11111111, 0x11F11111, 0x00000111,
@@ -2406,6 +2406,544 @@ const u32 b43_ntab_tmap[] = {
2406 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2406 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2407}; 2407};
2408 2408
2409const u32 b43_ntab_tx_gain_rev0_1_2[] = {
2410 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
2411 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
2412 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
2413 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
2414 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
2415 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
2416 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
2417 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
2418 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
2419 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
2420 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
2421 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
2422 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
2423 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
2424 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
2425 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
2426 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
2427 0x03902942, 0x03902844, 0x03902842, 0x03902744,
2428 0x03902742, 0x03902644, 0x03902642, 0x03902544,
2429 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
2430 0x03802a42, 0x03802944, 0x03802942, 0x03802844,
2431 0x03802842, 0x03802744, 0x03802742, 0x03802644,
2432 0x03802642, 0x03802544, 0x03802542, 0x03802444,
2433 0x03802442, 0x03802344, 0x03802342, 0x03802244,
2434 0x03802242, 0x03802144, 0x03802142, 0x03802044,
2435 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
2436 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
2437 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
2438 0x03801a42, 0x03801944, 0x03801942, 0x03801844,
2439 0x03801842, 0x03801744, 0x03801742, 0x03801644,
2440 0x03801642, 0x03801544, 0x03801542, 0x03801444,
2441 0x03801442, 0x03801344, 0x03801342, 0x00002b00,
2442};
2443
2444const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
2445 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
2446 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
2447 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
2448 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
2449 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
2450 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
2451 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
2452 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
2453 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
2454 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
2455 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
2456 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
2457 0x19410044, 0x19410042, 0x19410040, 0x1941003e,
2458 0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
2459 0x18410044, 0x18410042, 0x18410040, 0x1841003e,
2460 0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
2461 0x17410044, 0x17410042, 0x17410040, 0x1741003e,
2462 0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
2463 0x16410044, 0x16410042, 0x16410040, 0x1641003e,
2464 0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
2465 0x15410044, 0x15410042, 0x15410040, 0x1541003e,
2466 0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
2467 0x14410044, 0x14410042, 0x14410040, 0x1441003e,
2468 0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
2469 0x13410044, 0x13410042, 0x13410040, 0x1341003e,
2470 0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
2471 0x12410044, 0x12410042, 0x12410040, 0x1241003e,
2472 0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
2473 0x11410044, 0x11410042, 0x11410040, 0x1141003e,
2474 0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
2475 0x10410044, 0x10410042, 0x10410040, 0x1041003e,
2476 0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
2477};
2478
2479const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
2480 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
2481 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
2482 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
2483 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
2484 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
2485 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
2486 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
2487 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
2488 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
2489 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
2490 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
2491 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
2492 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
2493 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
2494 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
2495 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
2496 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
2497 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
2498 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
2499 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
2500 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
2501 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
2502 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
2503 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
2504 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
2505 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
2506 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
2507 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
2508 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
2509 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
2510 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
2511 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
2512};
2513
2514const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
2515 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
2516 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
2517 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
2518 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
2519 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
2520 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
2521 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
2522 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
2523 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
2524 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
2525 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
2526 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
2527 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
2528 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
2529 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
2530 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
2531 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
2532 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
2533 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
2534 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
2535 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
2536 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
2537 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
2538 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
2539 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
2540 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
2541 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
2542 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
2543 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
2544 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
2545 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
2546 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
2547};
2548
2549const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
2550 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
2551 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
2552 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
2553 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
2554 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
2555 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
2556 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
2557 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
2558 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
2559 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
2560 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
2561 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
2562 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
2563 0x09620039, 0x09620037, 0x09620035, 0x09620033,
2564 0x08620044, 0x08620042, 0x08620040, 0x0862003e,
2565 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
2566 0x07620043, 0x07620042, 0x07620040, 0x0762003f,
2567 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
2568 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
2569 0x06620039, 0x06620037, 0x06620035, 0x06620033,
2570 0x05620046, 0x05620044, 0x05620042, 0x05620040,
2571 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
2572 0x04620044, 0x04620042, 0x04620040, 0x0462003e,
2573 0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
2574 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
2575 0x03620038, 0x03620037, 0x03620035, 0x03620033,
2576 0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
2577 0x02620046, 0x02620044, 0x02620043, 0x02620042,
2578 0x0162004a, 0x01620048, 0x01620046, 0x01620044,
2579 0x01620043, 0x01620042, 0x01620041, 0x01620040,
2580 0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
2581 0x0062003b, 0x00620039, 0x00620037, 0x00620035,
2582};
2583
2584const u32 txpwrctrl_tx_gain_ipa[] = {
2585 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
2586 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
2587 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
2588 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
2589 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
2590 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
2591 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
2592 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
2593 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
2594 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
2595 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
2596 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
2597 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
2598 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
2599 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
2600 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
2601 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
2602 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
2603 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
2604 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
2605 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
2606 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
2607 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
2608 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
2609 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
2610 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
2611 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
2612 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
2613 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
2614 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
2615 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
2616 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
2617};
2618
2619const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
2620 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
2621 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
2622 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
2623 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
2624 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
2625 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
2626 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
2627 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
2628 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
2629 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
2630 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
2631 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
2632 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
2633 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
2634 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
2635 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
2636 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
2637 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
2638 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
2639 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
2640 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
2641 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
2642 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
2643 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
2644 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
2645 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
2646 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
2647 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
2648 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
2649 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
2650 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
2651 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
2652};
2653
2654const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
2655 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
2656 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
2657 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
2658 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
2659 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
2660 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
2661 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
2662 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
2663 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
2664 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
2665 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
2666 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
2667 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
2668 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
2669 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
2670 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
2671 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
2672 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
2673 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
2674 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
2675 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
2676 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
2677 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
2678 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
2679 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
2680 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
2681 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
2682 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
2683 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
2684 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
2685 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
2686 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
2687};
2688
2689const u32 txpwrctrl_tx_gain_ipa_5g[] = {
2690 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
2691 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
2692 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
2693 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
2694 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
2695 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
2696 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
2697 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
2698 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
2699 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
2700 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
2701 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
2702 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
2703 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
2704 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
2705 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
2706 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
2707 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
2708 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
2709 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
2710 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
2711 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
2712 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
2713 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
2714 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
2715 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
2716 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
2717 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
2718 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
2719 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
2720 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
2721 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
2722};
2723
2724const u16 tbl_iqcal_gainparams[2][9][8] = {
2725 {
2726 { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
2727 { 0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69 },
2728 { 0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68 },
2729 { 0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67 },
2730 { 0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66 },
2731 { 0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65 },
2732 { 0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65 },
2733 { 0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65 },
2734 { 0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65 }
2735 },
2736 {
2737 { 0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
2738 { 0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
2739 { 0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79 },
2740 { 0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78 },
2741 { 0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78 },
2742 { 0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78 },
2743 { 0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78 },
2744 { 0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78 },
2745 { 0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78 }
2746 }
2747};
2748
2749const struct nphy_txiqcal_ladder ladder_lo[] = {
2750 { 3, 0 },
2751 { 4, 0 },
2752 { 6, 0 },
2753 { 9, 0 },
2754 { 13, 0 },
2755 { 18, 0 },
2756 { 25, 0 },
2757 { 25, 1 },
2758 { 25, 2 },
2759 { 25, 3 },
2760 { 25, 4 },
2761 { 25, 5 },
2762 { 25, 6 },
2763 { 25, 7 },
2764 { 35, 7 },
2765 { 50, 7 },
2766 { 71, 7 },
2767 { 100, 7 }
2768};
2769
2770const struct nphy_txiqcal_ladder ladder_iq[] = {
2771 { 3, 0 },
2772 { 4, 0 },
2773 { 6, 0 },
2774 { 9, 0 },
2775 { 13, 0 },
2776 { 18, 0 },
2777 { 25, 0 },
2778 { 35, 0 },
2779 { 50, 0 },
2780 { 71, 0 },
2781 { 100, 0 },
2782 { 100, 1 },
2783 { 100, 2 },
2784 { 100, 3 },
2785 { 100, 4 },
2786 { 100, 5 },
2787 { 100, 6 },
2788 { 100, 7 }
2789};
2790
2791const u16 loscale[] = {
2792 256, 256, 271, 271,
2793 287, 256, 256, 271,
2794 271, 287, 287, 304,
2795 304, 256, 256, 271,
2796 271, 287, 287, 304,
2797 304, 322, 322, 341,
2798 341, 362, 362, 383,
2799 383, 256, 256, 271,
2800 271, 287, 287, 304,
2801 304, 322, 322, 256,
2802 256, 271, 271, 287,
2803 287, 304, 304, 322,
2804 322, 341, 341, 362,
2805 362, 256, 256, 271,
2806 271, 287, 287, 304,
2807 304, 322, 322, 256,
2808 256, 271, 271, 287,
2809 287, 304, 304, 322,
2810 322, 341, 341, 362,
2811 362, 256, 256, 271,
2812 271, 287, 287, 304,
2813 304, 322, 322, 341,
2814 341, 362, 362, 383,
2815 383, 406, 406, 430,
2816 430, 455, 455, 482,
2817 482, 511, 511, 541,
2818 541, 573, 573, 607,
2819 607, 643, 643, 681,
2820 681, 722, 722, 764,
2821 764, 810, 810, 858,
2822 858, 908, 908, 962,
2823 962, 1019, 1019, 256
2824};
2825
2826const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
2827 0x0200, 0x0300, 0x0400, 0x0700,
2828 0x0900, 0x0c00, 0x1200, 0x1201,
2829 0x1202, 0x1203, 0x1204, 0x1205,
2830 0x1206, 0x1207, 0x1907, 0x2307,
2831 0x3207, 0x4707
2832};
2833
2834const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
2835 0x0300, 0x0500, 0x0700, 0x0900,
2836 0x0d00, 0x1100, 0x1900, 0x1901,
2837 0x1902, 0x1903, 0x1904, 0x1905,
2838 0x1906, 0x1907, 0x2407, 0x3207,
2839 0x4607, 0x6407
2840};
2841
2842const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
2843 0x0100, 0x0200, 0x0400, 0x0700,
2844 0x0900, 0x0c00, 0x1200, 0x1900,
2845 0x2300, 0x3200, 0x4700, 0x4701,
2846 0x4702, 0x4703, 0x4704, 0x4705,
2847 0x4706, 0x4707
2848};
2849
2850const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
2851 0x0200, 0x0300, 0x0600, 0x0900,
2852 0x0d00, 0x1100, 0x1900, 0x2400,
2853 0x3200, 0x4600, 0x6400, 0x6401,
2854 0x6402, 0x6403, 0x6404, 0x6405,
2855 0x6406, 0x6407
2856};
2857
2858const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3] = { };
2859
2860const u16 tbl_tx_iqlo_cal_startcoefs[B43_NTAB_TX_IQLO_CAL_STARTCOEFS] = { };
2861
2862const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
2863 0x8423, 0x8323, 0x8073, 0x8256,
2864 0x8045, 0x8223, 0x9423, 0x9323,
2865 0x9073, 0x9256, 0x9045, 0x9223
2866};
2867
2868const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
2869 0x8101, 0x8253, 0x8053, 0x8234,
2870 0x8034, 0x9101, 0x9253, 0x9053,
2871 0x9234, 0x9034
2872};
2873
2874const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
2875 0x8123, 0x8264, 0x8086, 0x8245,
2876 0x8056, 0x9123, 0x9264, 0x9086,
2877 0x9245, 0x9056
2878};
2879
2880const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
2881 0x8434, 0x8334, 0x8084, 0x8267,
2882 0x8056, 0x8234, 0x9434, 0x9334,
2883 0x9084, 0x9267, 0x9056, 0x9234
2884};
2885
2886const s16 tbl_tx_filter_coef_rev4[7][15] = {
2887 { -377, 137, -407, 208, -1527,
2888 956, 93, 186, 93, 230,
2889 -44, 230, 20, -191, 201 },
2890 { -77, 20, -98, 49, -93,
2891 60, 56, 111, 56, 26,
2892 -5, 26, 34, -32, 34 },
2893 { -360, 164, -376, 164, -1533,
2894 576, 308, -314, 308, 121,
2895 -73, 121, 91, 124, 91 },
2896 { -295, 200, -363, 142, -1391,
2897 826, 151, 301, 151, 151,
2898 301, 151, 602, -752, 602 },
2899 { -92, 58, -96, 49, -104,
2900 44, 17, 35, 17, 12,
2901 25, 12, 13, 27, 13 },
2902 { -375, 136, -399, 209, -1479,
2903 949, 130, 260, 130, 230,
2904 -44, 230, 201, -191, 201 },
2905 { 0xed9, 0xc8, 0xe95, 0x8e, 0xa91,
2906 0x33a, 0x97, 0x12d, 0x97, 0x97,
2907 0x12d, 0x97, 0x25a, 0xd10, 0x25a }
2908};
2909
2910/* addr0, addr1, bmask, shift */
2911const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = {
2912 { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */
2913 { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */
2914 { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */
2915 { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */
2916 { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */
2917 { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */
2918 { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */
2919 { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */
2920 { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */
2921 { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */
2922 { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */
2923 { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */
2924 { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */
2925 { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */
2926};
2927
2928/* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */
2929const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
2930 { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */
2931 { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
2932 { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
2933 { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
2934 { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
2935 { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
2936 { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
2937 { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
2938 { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
2939 { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
2940 { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
2941 { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
2942 { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */
2943 { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */
2944 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
2945};
2946
2409static inline void assert_ntab_array_sizes(void) 2947static inline void assert_ntab_array_sizes(void)
2410{ 2948{
2411#undef check 2949#undef check
@@ -2442,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void)
2442#undef check 2980#undef check
2443} 2981}
2444 2982
2983u32 b43_ntab_read(struct b43_wldev *dev, u32 offset)
2984{
2985 u32 type, value;
2986
2987 type = offset & B43_NTAB_TYPEMASK;
2988 offset &= ~B43_NTAB_TYPEMASK;
2989 B43_WARN_ON(offset > 0xFFFF);
2990
2991 switch (type) {
2992 case B43_NTAB_8BIT:
2993 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
2994 value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
2995 break;
2996 case B43_NTAB_16BIT:
2997 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
2998 value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
2999 break;
3000 case B43_NTAB_32BIT:
3001 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3002 value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
3003 value <<= 16;
3004 value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3005 break;
3006 default:
3007 B43_WARN_ON(1);
3008 value = 0;
3009 }
3010
3011 return value;
3012}
3013
3014void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
3015 unsigned int nr_elements, void *_data)
3016{
3017 u32 type;
3018 u8 *data = _data;
3019 unsigned int i;
3020
3021 type = offset & B43_NTAB_TYPEMASK;
3022 offset &= ~B43_NTAB_TYPEMASK;
3023 B43_WARN_ON(offset > 0xFFFF);
3024
3025 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3026
3027 for (i = 0; i < nr_elements; i++) {
3028 switch (type) {
3029 case B43_NTAB_8BIT:
3030 *data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
3031 data++;
3032 break;
3033 case B43_NTAB_16BIT:
3034 *((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3035 data += 2;
3036 break;
3037 case B43_NTAB_32BIT:
3038 *((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
3039 *((u32 *)data) <<= 16;
3040 *((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3041 data += 4;
3042 break;
3043 default:
3044 B43_WARN_ON(1);
3045 }
3046 }
3047}
3048
2445void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) 3049void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2446{ 3050{
2447 u32 type; 3051 u32 type;
@@ -2474,3 +3078,91 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2474 /* Some compiletime assertions... */ 3078 /* Some compiletime assertions... */
2475 assert_ntab_array_sizes(); 3079 assert_ntab_array_sizes();
2476} 3080}
3081
3082void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
3083 unsigned int nr_elements, const void *_data)
3084{
3085 u32 type, value;
3086 const u8 *data = _data;
3087 unsigned int i;
3088
3089 type = offset & B43_NTAB_TYPEMASK;
3090 offset &= ~B43_NTAB_TYPEMASK;
3091 B43_WARN_ON(offset > 0xFFFF);
3092
3093 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3094
3095 for (i = 0; i < nr_elements; i++) {
3096 switch (type) {
3097 case B43_NTAB_8BIT:
3098 value = *data;
3099 data++;
3100 B43_WARN_ON(value & ~0xFF);
3101 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
3102 break;
3103 case B43_NTAB_16BIT:
3104 value = *((u16 *)data);
3105 data += 2;
3106 B43_WARN_ON(value & ~0xFFFF);
3107 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
3108 break;
3109 case B43_NTAB_32BIT:
3110 value = *((u32 *)data);
3111 data += 4;
3112 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16);
3113 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
3114 value & 0xFFFF);
3115 break;
3116 default:
3117 B43_WARN_ON(1);
3118 }
3119 }
3120}
3121
3122#define ntab_upload(dev, offset, data) do { \
3123 unsigned int i; \
3124 for (i = 0; i < (offset##_SIZE); i++) \
3125 b43_ntab_write(dev, (offset) + i, (data)[i]); \
3126 } while (0)
3127
3128void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
3129{
3130 /* Static tables */
3131 ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
3132 ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
3133 ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
3134 ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
3135 ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
3136 ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
3137 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
3138 ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
3139 ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
3140 ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
3141 ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
3142 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
3143 ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
3144 ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
3145
3146 /* Volatile tables */
3147 ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
3148 ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
3149 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
3150 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
3151 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
3152 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
3153 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
3154 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
3155 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
3156 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
3157 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
3158 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
3159}
3160
3161void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
3162{
3163 /* Static tables */
3164 /* TODO */
3165
3166 /* Volatile tables */
3167 /* TODO */
3168}
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 4d498b053ec7..9c1c6ecd3672 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -46,6 +46,27 @@ struct b43_nphy_channeltab_entry {
46 46
47struct b43_wldev; 47struct b43_wldev;
48 48
49struct nphy_txiqcal_ladder {
50 u8 percent;
51 u8 g_env;
52};
53
54struct nphy_rf_control_override_rev2 {
55 u8 addr0;
56 u8 addr1;
57 u16 bmask;
58 u8 shift;
59};
60
61struct nphy_rf_control_override_rev3 {
62 u16 val_mask;
63 u8 val_shift;
64 u8 en_addr0;
65 u8 val_addr0;
66 u8 en_addr1;
67 u8 val_addr1;
68};
69
49/* Upload the default register value table. 70/* Upload the default register value table.
50 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz 71 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
51 * table is uploaded. If "ignore_uploadflag" is true, we upload any value 72 * table is uploaded. If "ignore_uploadflag" is true, we upload any value
@@ -126,34 +147,57 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
126#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ 147#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
127#define B43_NTAB_C1_LOFEEDTH_SIZE 128 148#define B43_NTAB_C1_LOFEEDTH_SIZE 128
128 149
150#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
151#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
152#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
153#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_20_SIZE 18
154#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3 11
155#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS 9
156#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3 12
157#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL 10
158#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10
159#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12
160
161u32 b43_ntab_read(struct b43_wldev *dev, u32 offset);
162void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
163 unsigned int nr_elements, void *_data);
129void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); 164void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
130 165void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
131extern const u8 b43_ntab_adjustpower0[]; 166 unsigned int nr_elements, const void *_data);
132extern const u8 b43_ntab_adjustpower1[]; 167
133extern const u16 b43_ntab_bdi[]; 168void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
134extern const u32 b43_ntab_channelest[]; 169void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
135extern const u8 b43_ntab_estimatepowerlt0[]; 170
136extern const u8 b43_ntab_estimatepowerlt1[]; 171extern const u32 b43_ntab_tx_gain_rev0_1_2[];
137extern const u8 b43_ntab_framelookup[]; 172extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
138extern const u32 b43_ntab_framestruct[]; 173extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
139extern const u32 b43_ntab_gainctl0[]; 174extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
140extern const u32 b43_ntab_gainctl1[]; 175extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
141extern const u32 b43_ntab_intlevel[]; 176
142extern const u32 b43_ntab_iqlt0[]; 177extern const u32 txpwrctrl_tx_gain_ipa[];
143extern const u32 b43_ntab_iqlt1[]; 178extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
144extern const u16 b43_ntab_loftlt0[]; 179extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
145extern const u16 b43_ntab_loftlt1[]; 180extern const u32 txpwrctrl_tx_gain_ipa_5g[];
146extern const u8 b43_ntab_mcs[]; 181extern const u16 tbl_iqcal_gainparams[2][9][8];
147extern const u32 b43_ntab_noisevar10[]; 182extern const struct nphy_txiqcal_ladder ladder_lo[];
148extern const u32 b43_ntab_noisevar11[]; 183extern const struct nphy_txiqcal_ladder ladder_iq[];
149extern const u16 b43_ntab_pilot[]; 184extern const u16 loscale[];
150extern const u32 b43_ntab_pilotlt[]; 185
151extern const u32 b43_ntab_tdi20a0[]; 186extern const u16 tbl_tx_iqlo_cal_loft_ladder_40[];
152extern const u32 b43_ntab_tdi20a1[]; 187extern const u16 tbl_tx_iqlo_cal_loft_ladder_20[];
153extern const u32 b43_ntab_tdi40a0[]; 188extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[];
154extern const u32 b43_ntab_tdi40a1[]; 189extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[];
155extern const u32 b43_ntab_tdtrn[]; 190extern const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[];
156extern const u32 b43_ntab_tmap[]; 191extern const u16 tbl_tx_iqlo_cal_startcoefs[];
157 192extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
193extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
194extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
195extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
196extern const s16 tbl_tx_filter_coef_rev4[7][15];
197
198extern const struct nphy_rf_control_override_rev2
199 tbl_rf_control_override_rev2[];
200extern const struct nphy_rf_control_override_rev3
201 tbl_rf_control_override_rev3[];
158 202
159#endif /* B43_TABLES_NPHY_H_ */ 203#endif /* B43_TABLES_NPHY_H_ */
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 0a86bdf53154..8b9387c6ff36 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1411,7 +1411,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1411 b43legacyerr(dev->wl, "DMA tx mapping failure\n"); 1411 b43legacyerr(dev->wl, "DMA tx mapping failure\n");
1412 goto out_unlock; 1412 goto out_unlock;
1413 } 1413 }
1414 ring->nr_tx_packets++;
1415 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1414 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1416 should_inject_overflow(ring)) { 1415 should_inject_overflow(ring)) {
1417 /* This TX ring is full. */ 1416 /* This TX ring is full. */
@@ -1527,25 +1526,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1527 spin_unlock(&ring->lock); 1526 spin_unlock(&ring->lock);
1528} 1527}
1529 1528
1530void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
1531 struct ieee80211_tx_queue_stats *stats)
1532{
1533 const int nr_queues = dev->wl->hw->queues;
1534 struct b43legacy_dmaring *ring;
1535 unsigned long flags;
1536 int i;
1537
1538 for (i = 0; i < nr_queues; i++) {
1539 ring = priority_to_txring(dev, i);
1540
1541 spin_lock_irqsave(&ring->lock, flags);
1542 stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
1543 stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
1544 stats[i].count = ring->nr_tx_packets;
1545 spin_unlock_irqrestore(&ring->lock, flags);
1546 }
1547}
1548
1549static void dma_rx(struct b43legacy_dmaring *ring, 1529static void dma_rx(struct b43legacy_dmaring *ring,
1550 int *slot) 1530 int *slot)
1551{ 1531{
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 2f186003c31e..f9681041c2d8 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -243,8 +243,6 @@ struct b43legacy_dmaring {
243 int used_slots; 243 int used_slots;
244 /* Currently used slot in the ring. */ 244 /* Currently used slot in the ring. */
245 int current_slot; 245 int current_slot;
246 /* Total number of packets sent. Statistics only. */
247 unsigned int nr_tx_packets;
248 /* Frameoffset in octets. */ 246 /* Frameoffset in octets. */
249 u32 frameoffset; 247 u32 frameoffset;
250 /* Descriptor buffer size. */ 248 /* Descriptor buffer size. */
@@ -292,9 +290,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev);
292void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev); 290void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
293void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev); 291void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
294 292
295void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
296 struct ieee80211_tx_queue_stats *stats);
297
298int b43legacy_dma_tx(struct b43legacy_wldev *dev, 293int b43legacy_dma_tx(struct b43legacy_wldev *dev,
299 struct sk_buff *skb); 294 struct sk_buff *skb);
300void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, 295void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
@@ -315,11 +310,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
315{ 310{
316} 311}
317static inline 312static inline
318void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
319 struct ieee80211_tx_queue_stats *stats)
320{
321}
322static inline
323int b43legacy_dma_tx(struct b43legacy_wldev *dev, 313int b43legacy_dma_tx(struct b43legacy_wldev *dev,
324 struct sk_buff *skb) 314 struct sk_buff *skb)
325{ 315{
diff --git a/drivers/net/wireless/b43legacy/leds.h b/drivers/net/wireless/b43legacy/leds.h
index 82167a90088f..9ff6750dc57f 100644
--- a/drivers/net/wireless/b43legacy/leds.h
+++ b/drivers/net/wireless/b43legacy/leds.h
@@ -45,7 +45,7 @@ enum b43legacy_led_behaviour {
45void b43legacy_leds_init(struct b43legacy_wldev *dev); 45void b43legacy_leds_init(struct b43legacy_wldev *dev);
46void b43legacy_leds_exit(struct b43legacy_wldev *dev); 46void b43legacy_leds_exit(struct b43legacy_wldev *dev);
47 47
48#else /* CONFIG_B43EGACY_LEDS */ 48#else /* CONFIG_B43LEGACY_LEDS */
49/* LED support disabled */ 49/* LED support disabled */
50 50
51struct b43legacy_led { 51struct b43legacy_led {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index ab6a18c2e9d9..08523a45e23b 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -61,6 +61,8 @@ MODULE_AUTHOR("Michael Buesch");
61MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
62 62
63MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); 63MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
64MODULE_FIRMWARE("b43legacy/ucode2.fw");
65MODULE_FIRMWARE("b43legacy/ucode4.fw");
64 66
65#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO) 67#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
66static int modparam_pio; 68static int modparam_pio;
@@ -2444,29 +2446,6 @@ static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
2444 return 0; 2446 return 0;
2445} 2447}
2446 2448
2447static int b43legacy_op_get_tx_stats(struct ieee80211_hw *hw,
2448 struct ieee80211_tx_queue_stats *stats)
2449{
2450 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2451 struct b43legacy_wldev *dev = wl->current_dev;
2452 unsigned long flags;
2453 int err = -ENODEV;
2454
2455 if (!dev)
2456 goto out;
2457 spin_lock_irqsave(&wl->irq_lock, flags);
2458 if (likely(b43legacy_status(dev) >= B43legacy_STAT_STARTED)) {
2459 if (b43legacy_using_pio(dev))
2460 b43legacy_pio_get_tx_stats(dev, stats);
2461 else
2462 b43legacy_dma_get_tx_stats(dev, stats);
2463 err = 0;
2464 }
2465 spin_unlock_irqrestore(&wl->irq_lock, flags);
2466out:
2467 return err;
2468}
2469
2470static int b43legacy_op_get_stats(struct ieee80211_hw *hw, 2449static int b43legacy_op_get_stats(struct ieee80211_hw *hw,
2471 struct ieee80211_low_level_stats *stats) 2450 struct ieee80211_low_level_stats *stats)
2472{ 2451{
@@ -2921,6 +2900,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
2921 goto out; 2900 goto out;
2922 } 2901 }
2923 /* We are ready to run. */ 2902 /* We are ready to run. */
2903 ieee80211_wake_queues(dev->wl->hw);
2924 b43legacy_set_status(dev, B43legacy_STAT_STARTED); 2904 b43legacy_set_status(dev, B43legacy_STAT_STARTED);
2925 2905
2926 /* Start data flow (TX/RX) */ 2906 /* Start data flow (TX/RX) */
@@ -3341,6 +3321,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
3341 b43legacy_security_init(dev); 3321 b43legacy_security_init(dev);
3342 b43legacy_rng_init(wl); 3322 b43legacy_rng_init(wl);
3343 3323
3324 ieee80211_wake_queues(dev->wl->hw);
3344 b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); 3325 b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
3345 3326
3346 b43legacy_leds_init(dev); 3327 b43legacy_leds_init(dev);
@@ -3361,7 +3342,7 @@ err_kfree_lo_control:
3361} 3342}
3362 3343
3363static int b43legacy_op_add_interface(struct ieee80211_hw *hw, 3344static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
3364 struct ieee80211_if_init_conf *conf) 3345 struct ieee80211_vif *vif)
3365{ 3346{
3366 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 3347 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3367 struct b43legacy_wldev *dev; 3348 struct b43legacy_wldev *dev;
@@ -3370,23 +3351,23 @@ static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
3370 3351
3371 /* TODO: allow WDS/AP devices to coexist */ 3352 /* TODO: allow WDS/AP devices to coexist */
3372 3353
3373 if (conf->type != NL80211_IFTYPE_AP && 3354 if (vif->type != NL80211_IFTYPE_AP &&
3374 conf->type != NL80211_IFTYPE_STATION && 3355 vif->type != NL80211_IFTYPE_STATION &&
3375 conf->type != NL80211_IFTYPE_WDS && 3356 vif->type != NL80211_IFTYPE_WDS &&
3376 conf->type != NL80211_IFTYPE_ADHOC) 3357 vif->type != NL80211_IFTYPE_ADHOC)
3377 return -EOPNOTSUPP; 3358 return -EOPNOTSUPP;
3378 3359
3379 mutex_lock(&wl->mutex); 3360 mutex_lock(&wl->mutex);
3380 if (wl->operating) 3361 if (wl->operating)
3381 goto out_mutex_unlock; 3362 goto out_mutex_unlock;
3382 3363
3383 b43legacydbg(wl, "Adding Interface type %d\n", conf->type); 3364 b43legacydbg(wl, "Adding Interface type %d\n", vif->type);
3384 3365
3385 dev = wl->current_dev; 3366 dev = wl->current_dev;
3386 wl->operating = 1; 3367 wl->operating = 1;
3387 wl->vif = conf->vif; 3368 wl->vif = vif;
3388 wl->if_type = conf->type; 3369 wl->if_type = vif->type;
3389 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 3370 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
3390 3371
3391 spin_lock_irqsave(&wl->irq_lock, flags); 3372 spin_lock_irqsave(&wl->irq_lock, flags);
3392 b43legacy_adjust_opmode(dev); 3373 b43legacy_adjust_opmode(dev);
@@ -3403,18 +3384,18 @@ static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
3403} 3384}
3404 3385
3405static void b43legacy_op_remove_interface(struct ieee80211_hw *hw, 3386static void b43legacy_op_remove_interface(struct ieee80211_hw *hw,
3406 struct ieee80211_if_init_conf *conf) 3387 struct ieee80211_vif *vif)
3407{ 3388{
3408 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 3389 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3409 struct b43legacy_wldev *dev = wl->current_dev; 3390 struct b43legacy_wldev *dev = wl->current_dev;
3410 unsigned long flags; 3391 unsigned long flags;
3411 3392
3412 b43legacydbg(wl, "Removing Interface type %d\n", conf->type); 3393 b43legacydbg(wl, "Removing Interface type %d\n", vif->type);
3413 3394
3414 mutex_lock(&wl->mutex); 3395 mutex_lock(&wl->mutex);
3415 3396
3416 B43legacy_WARN_ON(!wl->operating); 3397 B43legacy_WARN_ON(!wl->operating);
3417 B43legacy_WARN_ON(wl->vif != conf->vif); 3398 B43legacy_WARN_ON(wl->vif != vif);
3418 wl->vif = NULL; 3399 wl->vif = NULL;
3419 3400
3420 wl->operating = 0; 3401 wl->operating = 0;
@@ -3509,7 +3490,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3509 .bss_info_changed = b43legacy_op_bss_info_changed, 3490 .bss_info_changed = b43legacy_op_bss_info_changed,
3510 .configure_filter = b43legacy_op_configure_filter, 3491 .configure_filter = b43legacy_op_configure_filter,
3511 .get_stats = b43legacy_op_get_stats, 3492 .get_stats = b43legacy_op_get_stats,
3512 .get_tx_stats = b43legacy_op_get_tx_stats,
3513 .start = b43legacy_op_start, 3493 .start = b43legacy_op_start,
3514 .stop = b43legacy_op_stop, 3494 .stop = b43legacy_op_stop,
3515 .set_tim = b43legacy_op_beacon_set_tim, 3495 .set_tim = b43legacy_op_beacon_set_tim,
@@ -3960,7 +3940,7 @@ static struct ssb_driver b43legacy_ssb_driver = {
3960 3940
3961static void b43legacy_print_driverinfo(void) 3941static void b43legacy_print_driverinfo(void)
3962{ 3942{
3963 const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "", 3943 const char *feat_pci = "", *feat_leds = "",
3964 *feat_pio = "", *feat_dma = ""; 3944 *feat_pio = "", *feat_dma = "";
3965 3945
3966#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT 3946#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
@@ -3969,9 +3949,6 @@ static void b43legacy_print_driverinfo(void)
3969#ifdef CONFIG_B43LEGACY_LEDS 3949#ifdef CONFIG_B43LEGACY_LEDS
3970 feat_leds = "L"; 3950 feat_leds = "L";
3971#endif 3951#endif
3972#ifdef CONFIG_B43LEGACY_RFKILL
3973 feat_rfkill = "R";
3974#endif
3975#ifdef CONFIG_B43LEGACY_PIO 3952#ifdef CONFIG_B43LEGACY_PIO
3976 feat_pio = "I"; 3953 feat_pio = "I";
3977#endif 3954#endif
@@ -3979,9 +3956,9 @@ static void b43legacy_print_driverinfo(void)
3979 feat_dma = "D"; 3956 feat_dma = "D";
3980#endif 3957#endif
3981 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " 3958 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
3982 "[ Features: %s%s%s%s%s, Firmware-ID: " 3959 "[ Features: %s%s%s%s, Firmware-ID: "
3983 B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", 3960 B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
3984 feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); 3961 feat_pci, feat_leds, feat_pio, feat_dma);
3985} 3962}
3986 3963
3987static int __init b43legacy_init(void) 3964static int __init b43legacy_init(void)
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 51866c9a2769..017c0e9c37ef 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -477,7 +477,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
477 477
478 list_move_tail(&packet->list, &queue->txqueue); 478 list_move_tail(&packet->list, &queue->txqueue);
479 queue->nr_txfree--; 479 queue->nr_txfree--;
480 queue->nr_tx_packets++;
481 B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS); 480 B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS);
482 481
483 tasklet_schedule(&queue->txtask); 482 tasklet_schedule(&queue->txtask);
@@ -546,18 +545,6 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
546 tasklet_schedule(&queue->txtask); 545 tasklet_schedule(&queue->txtask);
547} 546}
548 547
549void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
550 struct ieee80211_tx_queue_stats *stats)
551{
552 struct b43legacy_pio *pio = &dev->pio;
553 struct b43legacy_pioqueue *queue;
554
555 queue = pio->queue1;
556 stats[0].len = B43legacy_PIO_MAXTXPACKETS - queue->nr_txfree;
557 stats[0].limit = B43legacy_PIO_MAXTXPACKETS;
558 stats[0].count = queue->nr_tx_packets;
559}
560
561static void pio_rx_error(struct b43legacy_pioqueue *queue, 548static void pio_rx_error(struct b43legacy_pioqueue *queue,
562 int clear_buffers, 549 int clear_buffers,
563 const char *error) 550 const char *error)
diff --git a/drivers/net/wireless/b43legacy/pio.h b/drivers/net/wireless/b43legacy/pio.h
index 464fec05a06d..8e6773ea6e75 100644
--- a/drivers/net/wireless/b43legacy/pio.h
+++ b/drivers/net/wireless/b43legacy/pio.h
@@ -74,10 +74,6 @@ struct b43legacy_pioqueue {
74 * posted to the device. We are waiting for the txstatus. 74 * posted to the device. We are waiting for the txstatus.
75 */ 75 */
76 struct list_head txrunning; 76 struct list_head txrunning;
77 /* Total number or packets sent.
78 * (This counter can obviously wrap).
79 */
80 unsigned int nr_tx_packets;
81 struct tasklet_struct txtask; 77 struct tasklet_struct txtask;
82 struct b43legacy_pio_txpacket 78 struct b43legacy_pio_txpacket
83 tx_packets_cache[B43legacy_PIO_MAXTXPACKETS]; 79 tx_packets_cache[B43legacy_PIO_MAXTXPACKETS];
@@ -106,8 +102,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
106 struct sk_buff *skb); 102 struct sk_buff *skb);
107void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, 103void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
108 const struct b43legacy_txstatus *status); 104 const struct b43legacy_txstatus *status);
109void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
110 struct ieee80211_tx_queue_stats *stats);
111void b43legacy_pio_rx(struct b43legacy_pioqueue *queue); 105void b43legacy_pio_rx(struct b43legacy_pioqueue *queue);
112 106
113/* Suspend TX queue in hardware. */ 107/* Suspend TX queue in hardware. */
@@ -140,11 +134,6 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
140{ 134{
141} 135}
142static inline 136static inline
143void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
144 struct ieee80211_tx_queue_stats *stats)
145{
146}
147static inline
148void b43legacy_pio_rx(struct b43legacy_pioqueue *queue) 137void b43legacy_pio_rx(struct b43legacy_pioqueue *queue)
149{ 138{
150} 139}
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index c9640a3e02c9..d19748d90aaf 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -794,13 +794,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
794 PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus", 794 PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
795 0x7a954bd9, 0x74be00c6), 795 0x7a954bd9, 0x74be00c6),
796 PCMCIA_DEVICE_PROD_ID123( 796 PCMCIA_DEVICE_PROD_ID123(
797 "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P",
798 0x4b801a17, 0x6345a0bf, 0xc9049a39),
799 /* D-Link DWL-650 Rev. P1; manfid 0x000b, 0x7110 */
800 PCMCIA_DEVICE_PROD_ID123(
801 "D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10",
802 0x1a424a1c, 0x6ea57632, 0xdd97a26b),
803 PCMCIA_DEVICE_PROD_ID123(
804 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", 797 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
805 0xe6ec52ce, 0x08649af2, 0x4b74baa0), 798 0xe6ec52ce, 0x08649af2, 0x4b74baa0),
806 PCMCIA_DEVICE_PROD_ID123( 799 PCMCIA_DEVICE_PROD_ID123(
@@ -834,14 +827,12 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
834 "Ver. 1.00", 827 "Ver. 1.00",
835 0x5cd01705, 0x4271660f, 0x9d08ee12), 828 0x5cd01705, 0x4271660f, 0x9d08ee12),
836 PCMCIA_DEVICE_PROD_ID123( 829 PCMCIA_DEVICE_PROD_ID123(
837 "corega", "WL PCCL-11", "ISL37300P",
838 0xa21501a, 0x59868926, 0xc9049a39),
839 PCMCIA_DEVICE_PROD_ID123(
840 "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
841 0xa5f472c2, 0x9c05598d, 0xc9049a39),
842 PCMCIA_DEVICE_PROD_ID123(
843 "Wireless LAN" , "11Mbps PC Card", "Version 01.02", 830 "Wireless LAN" , "11Mbps PC Card", "Version 01.02",
844 0x4b8870ff, 0x70e946d1, 0x4b74baa0), 831 0x4b8870ff, 0x70e946d1, 0x4b74baa0),
832 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
833 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
834 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
835 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
845 PCMCIA_DEVICE_NULL 836 PCMCIA_DEVICE_NULL
846}; 837};
847MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); 838MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index ff9b5c882184..d70732819423 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2618,6 +2618,15 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
2618 int events = 0; 2618 int events = 0;
2619 u16 ev; 2619 u16 ev;
2620 2620
2621 /* Detect early interrupt before driver is fully configued */
2622 if (!dev->base_addr) {
2623 if (net_ratelimit()) {
2624 printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
2625 dev->name);
2626 }
2627 return IRQ_HANDLED;
2628 }
2629
2621 iface = netdev_priv(dev); 2630 iface = netdev_priv(dev);
2622 local = iface->local; 2631 local = iface->local;
2623 2632
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b16b06c2031f..dc8ed1527666 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,14 +1,8 @@
1config IWLWIFI 1config IWLWIFI
2 tristate "Intel Wireless Wifi" 2 tristate "Intel Wireless Wifi"
3 depends on PCI && MAC80211 && EXPERIMENTAL 3 depends on PCI && MAC80211
4 select FW_LOADER 4 select FW_LOADER
5 5
6config IWLWIFI_SPECTRUM_MEASUREMENT
7 bool "Enable Spectrum Measurement in iwlagn driver"
8 depends on IWLWIFI
9 ---help---
10 This option will enable spectrum measurement for the iwlagn driver.
11
12config IWLWIFI_DEBUG 6config IWLWIFI_DEBUG
13 bool "Enable full debugging output in iwlagn and iwl3945 drivers" 7 bool "Enable full debugging output in iwlagn and iwl3945 drivers"
14 depends on IWLWIFI 8 depends on IWLWIFI
@@ -120,9 +114,3 @@ config IWL3945
120 inserted in and removed from the running kernel whenever you want), 114 inserted in and removed from the running kernel whenever you want),
121 say M here and read <file:Documentation/kbuild/modules.txt>. The 115 say M here and read <file:Documentation/kbuild/modules.txt>. The
122 module will be called iwl3945. 116 module will be called iwl3945.
123
124config IWL3945_SPECTRUM_MEASUREMENT
125 bool "Enable Spectrum Measurement in iwl3945 driver"
126 depends on IWL3945
127 ---help---
128 This option will enable spectrum measurement for the iwl3945 driver.
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 7f82044af242..4e378faee650 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -3,7 +3,6 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
4iwlcore-objs += iwl-scan.o iwl-led.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
7iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
8 7
9CFLAGS_iwl-devtrace.o := -I$(src) 8CFLAGS_iwl-devtrace.o := -I$(src)
@@ -20,3 +19,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
20# 3945 19# 3945
21obj-$(CONFIG_IWL3945) += iwl3945.o 20obj-$(CONFIG_IWL3945) += iwl3945.o
22iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o 21iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
22
23ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 8414178bcff4..3bf2e6e9b2d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); 89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
90} 90}
91 91
92static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
93 .min_nrg_cck = 95,
94 .max_nrg_cck = 0, /* not used, set to 0 */
95 .auto_corr_min_ofdm = 90,
96 .auto_corr_min_ofdm_mrc = 170,
97 .auto_corr_min_ofdm_x1 = 120,
98 .auto_corr_min_ofdm_mrc_x1 = 240,
99
100 .auto_corr_max_ofdm = 120,
101 .auto_corr_max_ofdm_mrc = 210,
102 .auto_corr_max_ofdm_x1 = 155,
103 .auto_corr_max_ofdm_mrc_x1 = 290,
104
105 .auto_corr_min_cck = 125,
106 .auto_corr_max_cck = 200,
107 .auto_corr_min_cck_mrc = 170,
108 .auto_corr_max_cck_mrc = 400,
109 .nrg_th_cck = 95,
110 .nrg_th_ofdm = 95,
111
112 .barker_corr_th_min = 190,
113 .barker_corr_th_min_mrc = 390,
114 .nrg_th_cca = 62,
115};
116
117static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
118{
119 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
120 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
121 priv->cfg->num_of_queues =
122 priv->cfg->mod_params->num_of_queues;
123
124 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
125 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
126 priv->hw_params.scd_bc_tbls_size =
127 priv->cfg->num_of_queues *
128 sizeof(struct iwl5000_scd_bc_tbl);
129 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
130 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
131 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
132
133 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
134 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
135
136 priv->hw_params.max_bsm_size = 0;
137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
138 BIT(IEEE80211_BAND_5GHZ);
139 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
140
141 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
142 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
143 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
144 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
145
146 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
147 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
148
149 /* Set initial sensitivity parameters */
150 /* Set initial calibration set */
151 priv->hw_params.sens = &iwl1000_sensitivity;
152 priv->hw_params.calib_init_cfg =
153 BIT(IWL_CALIB_XTAL) |
154 BIT(IWL_CALIB_LO) |
155 BIT(IWL_CALIB_TX_IQ) |
156 BIT(IWL_CALIB_TX_IQ_PERD) |
157 BIT(IWL_CALIB_BASE_BAND);
158
159 return 0;
160}
161
92static struct iwl_lib_ops iwl1000_lib = { 162static struct iwl_lib_ops iwl1000_lib = {
93 .set_hw_params = iwl5000_hw_set_hw_params, 163 .set_hw_params = iwl1000_hw_set_hw_params,
94 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 164 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
95 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 165 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
96 .txq_set_sched = iwl5000_txq_set_sched, 166 .txq_set_sched = iwl5000_txq_set_sched,
@@ -105,6 +175,8 @@ static struct iwl_lib_ops iwl1000_lib = {
105 .load_ucode = iwl5000_load_ucode, 175 .load_ucode = iwl5000_load_ucode,
106 .dump_nic_event_log = iwl_dump_nic_event_log, 176 .dump_nic_event_log = iwl_dump_nic_event_log,
107 .dump_nic_error_log = iwl_dump_nic_error_log, 177 .dump_nic_error_log = iwl_dump_nic_error_log,
178 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh,
108 .init_alive_start = iwl5000_init_alive_start, 180 .init_alive_start = iwl5000_init_alive_start,
109 .alive_notify = iwl5000_alive_notify, 181 .alive_notify = iwl5000_alive_notify,
110 .send_tx_power = iwl5000_send_tx_power, 182 .send_tx_power = iwl5000_send_tx_power,
@@ -138,9 +210,10 @@ static struct iwl_lib_ops iwl1000_lib = {
138 .temperature = iwl5000_temperature, 210 .temperature = iwl5000_temperature,
139 .set_ct_kill = iwl1000_set_ct_threshold, 211 .set_ct_kill = iwl1000_set_ct_threshold,
140 }, 212 },
213 .add_bcast_station = iwl_add_bcast_station,
141}; 214};
142 215
143static struct iwl_ops iwl1000_ops = { 216static const struct iwl_ops iwl1000_ops = {
144 .ucode = &iwl5000_ucode, 217 .ucode = &iwl5000_ucode,
145 .lib = &iwl1000_lib, 218 .lib = &iwl1000_lib,
146 .hcmd = &iwl5000_hcmd, 219 .hcmd = &iwl5000_hcmd,
@@ -173,7 +246,8 @@ struct iwl_cfg iwl1000_bgn_cfg = {
173 .use_rts_for_ht = true, /* use rts/cts protection */ 246 .use_rts_for_ht = true, /* use rts/cts protection */
174 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
175 .support_ct_kill_exit = true, 248 .support_ct_kill_exit = true,
176 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
250 .chain_noise_scale = 1000,
177}; 251};
178 252
179struct iwl_cfg iwl1000_bg_cfg = { 253struct iwl_cfg iwl1000_bg_cfg = {
@@ -200,6 +274,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
200 .led_compensation = 51, 274 .led_compensation = 51,
201 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 275 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
202 .support_ct_kill_exit = true, 276 .support_ct_kill_exit = true,
277 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
278 .chain_noise_scale = 1000,
203}; 279};
204 280
205MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 281MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
index 08ce259a0e60..042f6bc0df13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6fd10d443ba3..3a876a8ece38 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index a871d09d598f..abe2b739c4dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 5a1033ca7aaa..ce990adc51e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index d4b49883b30e..47909f94271e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 234891d8cc10..521584b99fd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -45,8 +45,8 @@
45#include "iwl-sta.h" 45#include "iwl-sta.h"
46#include "iwl-3945.h" 46#include "iwl-3945.h"
47#include "iwl-eeprom.h" 47#include "iwl-eeprom.h"
48#include "iwl-helpers.h"
49#include "iwl-core.h" 48#include "iwl-core.h"
49#include "iwl-helpers.h"
50#include "iwl-led.h" 50#include "iwl-led.h"
51#include "iwl-3945-led.h" 51#include "iwl-3945-led.h"
52 52
@@ -1951,11 +1951,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1951 } 1951 }
1952 1952
1953 /* Add the broadcast address so we can send broadcast frames */ 1953 /* Add the broadcast address so we can send broadcast frames */
1954 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) == 1954 priv->cfg->ops->lib->add_bcast_station(priv);
1955 IWL_INVALID_STATION) {
1956 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
1957 return -EIO;
1958 }
1959 1955
1960 /* If we have set the ASSOC_MSK and we are in BSS mode then 1956 /* If we have set the ASSOC_MSK and we are in BSS mode then
1961 * add the IWL_AP_ID to the station rate table */ 1957 * add the IWL_AP_ID to the station rate table */
@@ -2474,11 +2470,9 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2474 memset((void *)&priv->hw_params, 0, 2470 memset((void *)&priv->hw_params, 0,
2475 sizeof(struct iwl_hw_params)); 2471 sizeof(struct iwl_hw_params));
2476 2472
2477 priv->shared_virt = 2473 priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev,
2478 pci_alloc_consistent(priv->pci_dev, 2474 sizeof(struct iwl3945_shared),
2479 sizeof(struct iwl3945_shared), 2475 &priv->shared_phys, GFP_KERNEL);
2480 &priv->shared_phys);
2481
2482 if (!priv->shared_virt) { 2476 if (!priv->shared_virt) {
2483 IWL_ERR(priv, "failed to allocate pci memory\n"); 2477 IWL_ERR(priv, "failed to allocate pci memory\n");
2484 mutex_unlock(&priv->mutex); 2478 mutex_unlock(&priv->mutex);
@@ -2796,6 +2790,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2796 .post_associate = iwl3945_post_associate, 2790 .post_associate = iwl3945_post_associate,
2797 .isr = iwl_isr_legacy, 2791 .isr = iwl_isr_legacy,
2798 .config_ap = iwl3945_config_ap, 2792 .config_ap = iwl3945_config_ap,
2793 .add_bcast_station = iwl3945_add_bcast_station,
2799}; 2794};
2800 2795
2801static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2796static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2804,7 +2799,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2804 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2799 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2805}; 2800};
2806 2801
2807static struct iwl_ops iwl3945_ops = { 2802static const struct iwl_ops iwl3945_ops = {
2808 .ucode = &iwl3945_ucode, 2803 .ucode = &iwl3945_ucode,
2809 .lib = &iwl3945_lib, 2804 .lib = &iwl3945_lib,
2810 .hcmd = &iwl3945_hcmd, 2805 .hcmd = &iwl3945_hcmd,
@@ -2830,6 +2825,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2830 .ht_greenfield_support = false, 2825 .ht_greenfield_support = false,
2831 .led_compensation = 64, 2826 .led_compensation = 64,
2832 .broken_powersave = true, 2827 .broken_powersave = true,
2828 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2833}; 2829};
2834 2830
2835static struct iwl_cfg iwl3945_abg_cfg = { 2831static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,6 +2843,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2847 .ht_greenfield_support = false, 2843 .ht_greenfield_support = false,
2848 .led_compensation = 64, 2844 .led_compensation = 64,
2849 .broken_powersave = true, 2845 .broken_powersave = true,
2846 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2850}; 2847};
2851 2848
2852struct pci_device_id iwl3945_hw_card_ids[] = { 2849struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 531fa125f5a6..ae94babe595b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -171,24 +171,6 @@ struct iwl3945_frame {
171 171
172#define SCAN_INTERVAL 100 172#define SCAN_INTERVAL 100
173 173
174#define STATUS_HCMD_ACTIVE 0 /* host command in progress */
175#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */
176#define STATUS_INT_ENABLED 2
177#define STATUS_RF_KILL_HW 3
178#define STATUS_INIT 5
179#define STATUS_ALIVE 6
180#define STATUS_READY 7
181#define STATUS_TEMPERATURE 8
182#define STATUS_GEO_CONFIGURED 9
183#define STATUS_EXIT_PENDING 10
184#define STATUS_STATISTICS 12
185#define STATUS_SCANNING 13
186#define STATUS_SCAN_ABORTING 14
187#define STATUS_SCAN_HW 15
188#define STATUS_POWER_PMI 16
189#define STATUS_FW_ERROR 17
190#define STATUS_CONF_PENDING 18
191
192#define MAX_TID_COUNT 9 174#define MAX_TID_COUNT 9
193 175
194#define IWL_INVALID_RATE 0xFF 176#define IWL_INVALID_RATE 0xFF
@@ -226,7 +208,8 @@ extern void iwl3945_rx_replenish(void *data);
226extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 208extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
227extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 209extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
228 struct ieee80211_hdr *hdr,int left); 210 struct ieee80211_hdr *hdr,int left);
229extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 211extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
212 char **buf, bool display);
230extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 213extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
231 214
232/* 215/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index c606366b582c..67ef562e8db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 31462813bac0..1bd2cd836026 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -581,6 +581,13 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
581 581
582 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); 582 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
583 583
584 /* make sure all queue are not stopped */
585 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
586 for (i = 0; i < 4; i++)
587 atomic_set(&priv->queue_stop_count[i], 0);
588
589 /* reset to 0 to enable all the queue first */
590 priv->txq_ctx_active_msk = 0;
584 /* Map each Tx/cmd queue to its corresponding fifo */ 591 /* Map each Tx/cmd queue to its corresponding fifo */
585 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { 592 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
586 int ac = default_queue_to_tx_fifo[i]; 593 int ac = default_queue_to_tx_fifo[i];
@@ -2206,9 +2213,10 @@ static struct iwl_lib_ops iwl4965_lib = {
2206 .temperature = iwl4965_temperature_calib, 2213 .temperature = iwl4965_temperature_calib,
2207 .set_ct_kill = iwl4965_set_ct_threshold, 2214 .set_ct_kill = iwl4965_set_ct_threshold,
2208 }, 2215 },
2216 .add_bcast_station = iwl_add_bcast_station,
2209}; 2217};
2210 2218
2211static struct iwl_ops iwl4965_ops = { 2219static const struct iwl_ops iwl4965_ops = {
2212 .ucode = &iwl4965_ucode, 2220 .ucode = &iwl4965_ucode,
2213 .lib = &iwl4965_lib, 2221 .lib = &iwl4965_lib,
2214 .hcmd = &iwl4965_hcmd, 2222 .hcmd = &iwl4965_hcmd,
@@ -2239,7 +2247,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2247 .broken_powersave = true,
2240 .led_compensation = 61, 2248 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2249 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2242 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 2250 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2243}; 2251};
2244 2252
2245/* Module firmware */ 2253/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index bc056e9ab85f..714e032f6217 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index cffaae772d51..e476acb53aa7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -179,14 +179,24 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
179 data->delta_gain_code[i] = 0; 179 data->delta_gain_code[i] = 0;
180 continue; 180 continue;
181 } 181 }
182 delta_g = (1000 * ((s32)average_noise[default_chain] - 182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
183 (s32)average_noise[i])) / 1500; 185 (s32)average_noise[i])) / 1500;
186
184 /* bound gain by 2 bits value max, 3rd bit is sign */ 187 /* bound gain by 2 bits value max, 3rd bit is sign */
185 data->delta_gain_code[i] = 188 data->delta_gain_code[i] =
186 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
187 190
188 if (delta_g < 0) 191 if (delta_g < 0)
189 /* set negative sign */ 192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
190 data->delta_gain_code[i] |= (1 << 2); 200 data->delta_gain_code[i] |= (1 << 2);
191 } 201 }
192 202
@@ -263,8 +273,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
263 273
264 .auto_corr_max_ofdm = 120, 274 .auto_corr_max_ofdm = 120,
265 .auto_corr_max_ofdm_mrc = 210, 275 .auto_corr_max_ofdm_mrc = 210,
266 .auto_corr_max_ofdm_x1 = 155, 276 .auto_corr_max_ofdm_x1 = 120,
267 .auto_corr_max_ofdm_mrc_x1 = 290, 277 .auto_corr_max_ofdm_mrc_x1 = 240,
268 278
269 .auto_corr_min_cck = 125, 279 .auto_corr_min_cck = 125,
270 .auto_corr_max_cck = 200, 280 .auto_corr_max_cck = 200,
@@ -412,12 +422,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
412/* 422/*
413 * ucode 423 * ucode
414 */ 424 */
415static int iwl5000_load_section(struct iwl_priv *priv, 425static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
416 struct fw_desc *image, 426 struct fw_desc *image, u32 dst_addr)
417 u32 dst_addr)
418{ 427{
419 dma_addr_t phy_addr = image->p_addr; 428 dma_addr_t phy_addr = image->p_addr;
420 u32 byte_cnt = image->len; 429 u32 byte_cnt = image->len;
430 int ret;
431
432 priv->ucode_write_complete = 0;
421 433
422 iwl_write_direct32(priv, 434 iwl_write_direct32(priv,
423 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 435 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +459,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
447 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 459 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
448 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 460 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
449 461
450 return 0; 462 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
451}
452
453static int iwl5000_load_given_ucode(struct iwl_priv *priv,
454 struct fw_desc *inst_image,
455 struct fw_desc *data_image)
456{
457 int ret = 0;
458
459 ret = iwl5000_load_section(priv, inst_image,
460 IWL50_RTC_INST_LOWER_BOUND);
461 if (ret)
462 return ret;
463
464 IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
465 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 463 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
466 priv->ucode_write_complete, 5 * HZ); 464 priv->ucode_write_complete, 5 * HZ);
467 if (ret == -ERESTARTSYS) { 465 if (ret == -ERESTARTSYS) {
468 IWL_ERR(priv, "Could not load the INST uCode section due " 466 IWL_ERR(priv, "Could not load the %s uCode section due "
469 "to interrupt\n"); 467 "to interrupt\n", name);
470 return ret; 468 return ret;
471 } 469 }
472 if (!ret) { 470 if (!ret) {
473 IWL_ERR(priv, "Could not load the INST uCode section\n"); 471 IWL_ERR(priv, "Could not load the %s uCode section\n",
472 name);
474 return -ETIMEDOUT; 473 return -ETIMEDOUT;
475 } 474 }
476 475
477 priv->ucode_write_complete = 0; 476 return 0;
478 477}
479 ret = iwl5000_load_section(
480 priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
481 if (ret)
482 return ret;
483 478
484 IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); 479static int iwl5000_load_given_ucode(struct iwl_priv *priv,
480 struct fw_desc *inst_image,
481 struct fw_desc *data_image)
482{
483 int ret = 0;
485 484
486 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 485 ret = iwl5000_load_section(priv, "INST", inst_image,
487 priv->ucode_write_complete, 5 * HZ); 486 IWL50_RTC_INST_LOWER_BOUND);
488 if (ret == -ERESTARTSYS) { 487 if (ret)
489 IWL_ERR(priv, "Could not load the INST uCode section due "
490 "to interrupt\n");
491 return ret; 488 return ret;
492 } else if (!ret) {
493 IWL_ERR(priv, "Could not load the DATA uCode section\n");
494 return -ETIMEDOUT;
495 } else
496 ret = 0;
497 489
498 priv->ucode_write_complete = 0; 490 return iwl5000_load_section(priv, "DATA", data_image,
499 491 IWL50_RTC_DATA_LOWER_BOUND);
500 return ret;
501} 492}
502 493
503int iwl5000_load_ucode(struct iwl_priv *priv) 494int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -657,6 +648,13 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
657 648
658 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); 649 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
659 650
651 /* make sure all queue are not stopped */
652 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
653 for (i = 0; i < 4; i++)
654 atomic_set(&priv->queue_stop_count[i], 0);
655
656 /* reset to 0 to enable all the queue first */
657 priv->txq_ctx_active_msk = 0;
660 /* map qos queues to fifos one-to-one */ 658 /* map qos queues to fifos one-to-one */
661 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { 659 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
662 int ac = iwl5000_default_queue_to_tx_fifo[i]; 660 int ac = iwl5000_default_queue_to_tx_fifo[i];
@@ -781,7 +779,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
781 779
782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 780 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
783 781
784 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 782 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
785 scd_bc_tbl[txq_id]. 783 scd_bc_tbl[txq_id].
786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 784 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
787} 785}
@@ -800,12 +798,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
800 if (txq_id != IWL_CMD_QUEUE_NUM) 798 if (txq_id != IWL_CMD_QUEUE_NUM)
801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 799 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
802 800
803 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 801 bc_ent = cpu_to_le16(1 | (sta_id << 12));
804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; 802 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
805 803
806 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 804 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
807 scd_bc_tbl[txq_id]. 805 scd_bc_tbl[txq_id].
808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 806 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
809} 807}
810 808
811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, 809static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1464,6 +1462,8 @@ struct iwl_lib_ops iwl5000_lib = {
1464 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1462 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1465 .dump_nic_event_log = iwl_dump_nic_event_log, 1463 .dump_nic_event_log = iwl_dump_nic_event_log,
1466 .dump_nic_error_log = iwl_dump_nic_error_log, 1464 .dump_nic_error_log = iwl_dump_nic_error_log,
1465 .dump_csr = iwl_dump_csr,
1466 .dump_fh = iwl_dump_fh,
1467 .load_ucode = iwl5000_load_ucode, 1467 .load_ucode = iwl5000_load_ucode,
1468 .init_alive_start = iwl5000_init_alive_start, 1468 .init_alive_start = iwl5000_init_alive_start,
1469 .alive_notify = iwl5000_alive_notify, 1469 .alive_notify = iwl5000_alive_notify,
@@ -1499,6 +1499,7 @@ struct iwl_lib_ops iwl5000_lib = {
1499 .temperature = iwl5000_temperature, 1499 .temperature = iwl5000_temperature,
1500 .set_ct_kill = iwl5000_set_ct_threshold, 1500 .set_ct_kill = iwl5000_set_ct_threshold,
1501 }, 1501 },
1502 .add_bcast_station = iwl_add_bcast_station,
1502}; 1503};
1503 1504
1504static struct iwl_lib_ops iwl5150_lib = { 1505static struct iwl_lib_ops iwl5150_lib = {
@@ -1516,6 +1517,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1516 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1517 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1517 .dump_nic_event_log = iwl_dump_nic_event_log, 1518 .dump_nic_event_log = iwl_dump_nic_event_log,
1518 .dump_nic_error_log = iwl_dump_nic_error_log, 1519 .dump_nic_error_log = iwl_dump_nic_error_log,
1520 .dump_csr = iwl_dump_csr,
1519 .load_ucode = iwl5000_load_ucode, 1521 .load_ucode = iwl5000_load_ucode,
1520 .init_alive_start = iwl5000_init_alive_start, 1522 .init_alive_start = iwl5000_init_alive_start,
1521 .alive_notify = iwl5000_alive_notify, 1523 .alive_notify = iwl5000_alive_notify,
@@ -1551,9 +1553,10 @@ static struct iwl_lib_ops iwl5150_lib = {
1551 .temperature = iwl5150_temperature, 1553 .temperature = iwl5150_temperature,
1552 .set_ct_kill = iwl5150_set_ct_threshold, 1554 .set_ct_kill = iwl5150_set_ct_threshold,
1553 }, 1555 },
1556 .add_bcast_station = iwl_add_bcast_station,
1554}; 1557};
1555 1558
1556static struct iwl_ops iwl5000_ops = { 1559static const struct iwl_ops iwl5000_ops = {
1557 .ucode = &iwl5000_ucode, 1560 .ucode = &iwl5000_ucode,
1558 .lib = &iwl5000_lib, 1561 .lib = &iwl5000_lib,
1559 .hcmd = &iwl5000_hcmd, 1562 .hcmd = &iwl5000_hcmd,
@@ -1561,7 +1564,7 @@ static struct iwl_ops iwl5000_ops = {
1561 .led = &iwlagn_led_ops, 1564 .led = &iwlagn_led_ops,
1562}; 1565};
1563 1566
1564static struct iwl_ops iwl5150_ops = { 1567static const struct iwl_ops iwl5150_ops = {
1565 .ucode = &iwl5000_ucode, 1568 .ucode = &iwl5000_ucode,
1566 .lib = &iwl5150_lib, 1569 .lib = &iwl5150_lib,
1567 .hcmd = &iwl5000_hcmd, 1570 .hcmd = &iwl5000_hcmd,
@@ -1598,7 +1601,8 @@ struct iwl_cfg iwl5300_agn_cfg = {
1598 .led_compensation = 51, 1601 .led_compensation = 51,
1599 .use_rts_for_ht = true, /* use rts/cts protection */ 1602 .use_rts_for_ht = true, /* use rts/cts protection */
1600 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1601 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1604 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605 .chain_noise_scale = 1000,
1602}; 1606};
1603 1607
1604struct iwl_cfg iwl5100_bgn_cfg = { 1608struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1623,6 +1627,8 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1623 .led_compensation = 51, 1627 .led_compensation = 51,
1624 .use_rts_for_ht = true, /* use rts/cts protection */ 1628 .use_rts_for_ht = true, /* use rts/cts protection */
1625 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1630 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1631 .chain_noise_scale = 1000,
1626}; 1632};
1627 1633
1628struct iwl_cfg iwl5100_abg_cfg = { 1634struct iwl_cfg iwl5100_abg_cfg = {
@@ -1645,6 +1651,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
1645 .use_bsm = false, 1651 .use_bsm = false,
1646 .led_compensation = 51, 1652 .led_compensation = 51,
1647 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1655 .chain_noise_scale = 1000,
1648}; 1656};
1649 1657
1650struct iwl_cfg iwl5100_agn_cfg = { 1658struct iwl_cfg iwl5100_agn_cfg = {
@@ -1669,7 +1677,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
1669 .led_compensation = 51, 1677 .led_compensation = 51,
1670 .use_rts_for_ht = true, /* use rts/cts protection */ 1678 .use_rts_for_ht = true, /* use rts/cts protection */
1671 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1679 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1672 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1680 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1681 .chain_noise_scale = 1000,
1673}; 1682};
1674 1683
1675struct iwl_cfg iwl5350_agn_cfg = { 1684struct iwl_cfg iwl5350_agn_cfg = {
@@ -1694,7 +1703,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
1694 .led_compensation = 51, 1703 .led_compensation = 51,
1695 .use_rts_for_ht = true, /* use rts/cts protection */ 1704 .use_rts_for_ht = true, /* use rts/cts protection */
1696 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1705 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1697 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1706 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1707 .chain_noise_scale = 1000,
1698}; 1708};
1699 1709
1700struct iwl_cfg iwl5150_agn_cfg = { 1710struct iwl_cfg iwl5150_agn_cfg = {
@@ -1719,7 +1729,8 @@ struct iwl_cfg iwl5150_agn_cfg = {
1719 .led_compensation = 51, 1729 .led_compensation = 51,
1720 .use_rts_for_ht = true, /* use rts/cts protection */ 1730 .use_rts_for_ht = true, /* use rts/cts protection */
1721 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1731 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1722 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 1732 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1733 .chain_noise_scale = 1000,
1723}; 1734};
1724 1735
1725struct iwl_cfg iwl5150_abg_cfg = { 1736struct iwl_cfg iwl5150_abg_cfg = {
@@ -1742,6 +1753,8 @@ struct iwl_cfg iwl5150_abg_cfg = {
1742 .use_bsm = false, 1753 .use_bsm = false,
1743 .led_compensation = 51, 1754 .led_compensation = 51,
1744 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1755 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1756 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1757 .chain_noise_scale = 1000,
1745}; 1758};
1746 1759
1747MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1760MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 90185777d98b..ddba39999997 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 74e571049273..c4844adff92a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -70,6 +70,14 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
70 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 70 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
71} 71}
72 72
73/* Indicate calibration version to uCode. */
74static void iwl6050_set_calib_version(struct iwl_priv *priv)
75{
76 if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
77 iwl_set_bit(priv, CSR_GP_DRIVER_REG,
78 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
79}
80
73/* NIC configuration for 6000 series */ 81/* NIC configuration for 6000 series */
74static void iwl6000_nic_config(struct iwl_priv *priv) 82static void iwl6000_nic_config(struct iwl_priv *priv)
75{ 83{
@@ -96,6 +104,8 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
96 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); 104 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
97 } 105 }
98 /* else do nothing, uCode configured */ 106 /* else do nothing, uCode configured */
107 if (priv->cfg->ops->lib->temp_ops.set_calib_version)
108 priv->cfg->ops->lib->temp_ops.set_calib_version(priv);
99} 109}
100 110
101static struct iwl_sensitivity_ranges iwl6000_sensitivity = { 111static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
@@ -108,7 +118,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
108 118
109 .auto_corr_max_ofdm = 145, 119 .auto_corr_max_ofdm = 145,
110 .auto_corr_max_ofdm_mrc = 232, 120 .auto_corr_max_ofdm_mrc = 232,
111 .auto_corr_max_ofdm_x1 = 145, 121 .auto_corr_max_ofdm_x1 = 110,
112 .auto_corr_max_ofdm_mrc_x1 = 232, 122 .auto_corr_max_ofdm_mrc_x1 = 232,
113 123
114 .auto_corr_min_cck = 125, 124 .auto_corr_min_cck = 125,
@@ -158,11 +168,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
158 /* Set initial sensitivity parameters */ 168 /* Set initial sensitivity parameters */
159 /* Set initial calibration set */ 169 /* Set initial calibration set */
160 priv->hw_params.sens = &iwl6000_sensitivity; 170 priv->hw_params.sens = &iwl6000_sensitivity;
161 priv->hw_params.calib_init_cfg = 171 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
172 case CSR_HW_REV_TYPE_6x50:
173 priv->hw_params.calib_init_cfg =
174 BIT(IWL_CALIB_XTAL) |
175 BIT(IWL_CALIB_DC) |
176 BIT(IWL_CALIB_LO) |
177 BIT(IWL_CALIB_TX_IQ) |
178 BIT(IWL_CALIB_BASE_BAND);
179
180 break;
181 default:
182 priv->hw_params.calib_init_cfg =
162 BIT(IWL_CALIB_XTAL) | 183 BIT(IWL_CALIB_XTAL) |
163 BIT(IWL_CALIB_LO) | 184 BIT(IWL_CALIB_LO) |
164 BIT(IWL_CALIB_TX_IQ) | 185 BIT(IWL_CALIB_TX_IQ) |
165 BIT(IWL_CALIB_BASE_BAND); 186 BIT(IWL_CALIB_BASE_BAND);
187 break;
188 }
189
166 return 0; 190 return 0;
167} 191}
168 192
@@ -215,6 +239,8 @@ static struct iwl_lib_ops iwl6000_lib = {
215 .load_ucode = iwl5000_load_ucode, 239 .load_ucode = iwl5000_load_ucode,
216 .dump_nic_event_log = iwl_dump_nic_event_log, 240 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 241 .dump_nic_error_log = iwl_dump_nic_error_log,
242 .dump_csr = iwl_dump_csr,
243 .dump_fh = iwl_dump_fh,
218 .init_alive_start = iwl5000_init_alive_start, 244 .init_alive_start = iwl5000_init_alive_start,
219 .alive_notify = iwl5000_alive_notify, 245 .alive_notify = iwl5000_alive_notify,
220 .send_tx_power = iwl5000_send_tx_power, 246 .send_tx_power = iwl5000_send_tx_power,
@@ -250,9 +276,10 @@ static struct iwl_lib_ops iwl6000_lib = {
250 .temperature = iwl5000_temperature, 276 .temperature = iwl5000_temperature,
251 .set_ct_kill = iwl6000_set_ct_threshold, 277 .set_ct_kill = iwl6000_set_ct_threshold,
252 }, 278 },
279 .add_bcast_station = iwl_add_bcast_station,
253}; 280};
254 281
255static struct iwl_ops iwl6000_ops = { 282static const struct iwl_ops iwl6000_ops = {
256 .ucode = &iwl5000_ucode, 283 .ucode = &iwl5000_ucode,
257 .lib = &iwl6000_lib, 284 .lib = &iwl6000_lib,
258 .hcmd = &iwl5000_hcmd, 285 .hcmd = &iwl5000_hcmd,
@@ -260,18 +287,68 @@ static struct iwl_ops iwl6000_ops = {
260 .led = &iwlagn_led_ops, 287 .led = &iwlagn_led_ops,
261}; 288};
262 289
263static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = { 290static struct iwl_lib_ops iwl6050_lib = {
264 .get_hcmd_size = iwl5000_get_hcmd_size, 291 .set_hw_params = iwl6000_hw_set_hw_params,
265 .build_addsta_hcmd = iwl5000_build_addsta_hcmd, 292 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
266 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, 293 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
267 .calc_rssi = iwl5000_calc_rssi, 294 .txq_set_sched = iwl5000_txq_set_sched,
295 .txq_agg_enable = iwl5000_txq_agg_enable,
296 .txq_agg_disable = iwl5000_txq_agg_disable,
297 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
298 .txq_free_tfd = iwl_hw_txq_free_tfd,
299 .txq_init = iwl_hw_tx_queue_init,
300 .rx_handler_setup = iwl5000_rx_handler_setup,
301 .setup_deferred_work = iwl5000_setup_deferred_work,
302 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
303 .load_ucode = iwl5000_load_ucode,
304 .dump_nic_event_log = iwl_dump_nic_event_log,
305 .dump_nic_error_log = iwl_dump_nic_error_log,
306 .dump_csr = iwl_dump_csr,
307 .dump_fh = iwl_dump_fh,
308 .init_alive_start = iwl5000_init_alive_start,
309 .alive_notify = iwl5000_alive_notify,
310 .send_tx_power = iwl5000_send_tx_power,
311 .update_chain_flags = iwl_update_chain_flags,
312 .set_channel_switch = iwl6000_hw_channel_switch,
313 .apm_ops = {
314 .init = iwl_apm_init,
315 .stop = iwl_apm_stop,
316 .config = iwl6000_nic_config,
317 .set_pwr_src = iwl_set_pwr_src,
318 },
319 .eeprom_ops = {
320 .regulatory_bands = {
321 EEPROM_5000_REG_BAND_1_CHANNELS,
322 EEPROM_5000_REG_BAND_2_CHANNELS,
323 EEPROM_5000_REG_BAND_3_CHANNELS,
324 EEPROM_5000_REG_BAND_4_CHANNELS,
325 EEPROM_5000_REG_BAND_5_CHANNELS,
326 EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
327 EEPROM_5000_REG_BAND_52_HT40_CHANNELS
328 },
329 .verify_signature = iwlcore_eeprom_verify_signature,
330 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
331 .release_semaphore = iwlcore_eeprom_release_semaphore,
332 .calib_version = iwl5000_eeprom_calib_version,
333 .query_addr = iwl5000_eeprom_query_addr,
334 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
335 },
336 .post_associate = iwl_post_associate,
337 .isr = iwl_isr_ict,
338 .config_ap = iwl_config_ap,
339 .temp_ops = {
340 .temperature = iwl5000_temperature,
341 .set_ct_kill = iwl6000_set_ct_threshold,
342 .set_calib_version = iwl6050_set_calib_version,
343 },
344 .add_bcast_station = iwl_add_bcast_station,
268}; 345};
269 346
270static struct iwl_ops iwl6050_ops = { 347static const struct iwl_ops iwl6050_ops = {
271 .ucode = &iwl5000_ucode, 348 .ucode = &iwl5000_ucode,
272 .lib = &iwl6000_lib, 349 .lib = &iwl6050_lib,
273 .hcmd = &iwl5000_hcmd, 350 .hcmd = &iwl5000_hcmd,
274 .utils = &iwl6050_hcmd_utils, 351 .utils = &iwl5000_hcmd_utils,
275 .led = &iwlagn_led_ops, 352 .led = &iwlagn_led_ops,
276}; 353};
277 354
@@ -306,7 +383,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
306 .supports_idle = true, 383 .supports_idle = true,
307 .adv_thermal_throttle = true, 384 .adv_thermal_throttle = true,
308 .support_ct_kill_exit = true, 385 .support_ct_kill_exit = true,
309 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
387 .chain_noise_scale = 1000,
310}; 388};
311 389
312struct iwl_cfg iwl6000i_2abg_cfg = { 390struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -336,6 +414,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
336 .supports_idle = true, 414 .supports_idle = true,
337 .adv_thermal_throttle = true, 415 .adv_thermal_throttle = true,
338 .support_ct_kill_exit = true, 416 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
418 .chain_noise_scale = 1000,
339}; 419};
340 420
341struct iwl_cfg iwl6000i_2bg_cfg = { 421struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -365,6 +445,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
365 .supports_idle = true, 445 .supports_idle = true,
366 .adv_thermal_throttle = true, 446 .adv_thermal_throttle = true,
367 .support_ct_kill_exit = true, 447 .support_ct_kill_exit = true,
448 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
449 .chain_noise_scale = 1000,
368}; 450};
369 451
370struct iwl_cfg iwl6050_2agn_cfg = { 452struct iwl_cfg iwl6050_2agn_cfg = {
@@ -395,7 +477,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 477 .supports_idle = true,
396 .adv_thermal_throttle = true, 478 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 479 .support_ct_kill_exit = true,
398 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC, 480 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
481 .chain_noise_scale = 1500,
399}; 482};
400 483
401struct iwl_cfg iwl6050_2abg_cfg = { 484struct iwl_cfg iwl6050_2abg_cfg = {
@@ -425,6 +508,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
425 .supports_idle = true, 508 .supports_idle = true,
426 .adv_thermal_throttle = true, 509 .adv_thermal_throttle = true,
427 .support_ct_kill_exit = true, 510 .support_ct_kill_exit = true,
511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
512 .chain_noise_scale = 1500,
428}; 513};
429 514
430struct iwl_cfg iwl6000_3agn_cfg = { 515struct iwl_cfg iwl6000_3agn_cfg = {
@@ -455,7 +540,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
455 .supports_idle = true, 540 .supports_idle = true,
456 .adv_thermal_throttle = true, 541 .adv_thermal_throttle = true,
457 .support_ct_kill_exit = true, 542 .support_ct_kill_exit = true,
458 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, 543 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
544 .chain_noise_scale = 1000,
459}; 545};
460 546
461MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 547MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
index 3bccba20f6da..1a24946bc203 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
index ab55f92a161d..a594e4fdc6b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index b93e49158196..8bf7c20b9d39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -298,10 +298,23 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
298 struct iwl_lq_sta *lq_data, u8 tid, 298 struct iwl_lq_sta *lq_data, u8 tid,
299 struct ieee80211_sta *sta) 299 struct ieee80211_sta *sta)
300{ 300{
301 int ret;
302
301 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { 303 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
302 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 304 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
303 sta->addr, tid); 305 sta->addr, tid);
304 ieee80211_start_tx_ba_session(sta, tid); 306 ret = ieee80211_start_tx_ba_session(sta, tid);
307 if (ret == -EAGAIN) {
308 /*
309 * driver and mac80211 is out of sync
310 * this might be cause by reloading firmware
311 * stop the tx ba session here
312 */
313 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
314 tid);
315 ret = ieee80211_stop_tx_ba_session(sta, tid,
316 WLAN_BACK_INITIATOR);
317 }
305 } 318 }
306} 319}
307 320
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index affc0c5a2f2c..e71923961e69 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -191,7 +191,7 @@ enum {
191 IWL_RATE_2M_MASK) 191 IWL_RATE_2M_MASK)
192 192
193#define IWL_CCK_RATES_MASK \ 193#define IWL_CCK_RATES_MASK \
194 (IWL_BASIC_RATES_MASK | \ 194 (IWL_CCK_BASIC_RATES_MASK | \
195 IWL_RATE_5M_MASK | \ 195 IWL_RATE_5M_MASK | \
196 IWL_RATE_11M_MASK) 196 IWL_RATE_11M_MASK)
197 197
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1c9866daf815..c5b724eaf306 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -73,13 +73,7 @@
73#define VD 73#define VD
74#endif 74#endif
75 75
76#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT 76#define DRV_VERSION IWLWIFI_VERSION VD
77#define VS "s"
78#else
79#define VS
80#endif
81
82#define DRV_VERSION IWLWIFI_VERSION VD VS
83 77
84 78
85MODULE_DESCRIPTION(DRV_DESCRIPTION); 79MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -203,7 +197,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
203 priv->start_calib = 0; 197 priv->start_calib = 0;
204 198
205 /* Add the broadcast address so we can send broadcast frames */ 199 /* Add the broadcast address so we can send broadcast frames */
206 iwl_add_bcast_station(priv); 200 priv->cfg->ops->lib->add_bcast_station(priv);
201
207 202
208 /* If we have set the ASSOC_MSK and we are in BSS mode then 203 /* If we have set the ASSOC_MSK and we are in BSS mode then
209 * add the IWL_AP_ID to the station rate table */ 204 * add the IWL_AP_ID to the station rate table */
@@ -657,6 +652,131 @@ static void iwl_bg_statistics_periodic(unsigned long data)
657 iwl_send_statistics_request(priv, CMD_ASYNC, false); 652 iwl_send_statistics_request(priv, CMD_ASYNC, false);
658} 653}
659 654
655
656static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
657 u32 start_idx, u32 num_events,
658 u32 mode)
659{
660 u32 i;
661 u32 ptr; /* SRAM byte address of log data */
662 u32 ev, time, data; /* event log data */
663 unsigned long reg_flags;
664
665 if (mode == 0)
666 ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
667 else
668 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
669
670 /* Make sure device is powered up for SRAM reads */
671 spin_lock_irqsave(&priv->reg_lock, reg_flags);
672 if (iwl_grab_nic_access(priv)) {
673 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
674 return;
675 }
676
677 /* Set starting address; reads will auto-increment */
678 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
679 rmb();
680
681 /*
682 * "time" is actually "data" for mode 0 (no timestamp).
683 * place event id # at far right for easier visual parsing.
684 */
685 for (i = 0; i < num_events; i++) {
686 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
687 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
688 if (mode == 0) {
689 trace_iwlwifi_dev_ucode_cont_event(priv,
690 0, time, ev);
691 } else {
692 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
693 trace_iwlwifi_dev_ucode_cont_event(priv,
694 time, data, ev);
695 }
696 }
697 /* Allow device to power down */
698 iwl_release_nic_access(priv);
699 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
700}
701
702static void iwl_continuous_event_trace(struct iwl_priv *priv)
703{
704 u32 capacity; /* event log capacity in # entries */
705 u32 base; /* SRAM byte address of event log header */
706 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
707 u32 num_wraps; /* # times uCode wrapped to top of log */
708 u32 next_entry; /* index of next entry to be written by uCode */
709
710 if (priv->ucode_type == UCODE_INIT)
711 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
712 else
713 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
714 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
715 capacity = iwl_read_targ_mem(priv, base);
716 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
717 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
718 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
719 } else
720 return;
721
722 if (num_wraps == priv->event_log.num_wraps) {
723 iwl_print_cont_event_trace(priv,
724 base, priv->event_log.next_entry,
725 next_entry - priv->event_log.next_entry,
726 mode);
727 priv->event_log.non_wraps_count++;
728 } else {
729 if ((num_wraps - priv->event_log.num_wraps) > 1)
730 priv->event_log.wraps_more_count++;
731 else
732 priv->event_log.wraps_once_count++;
733 trace_iwlwifi_dev_ucode_wrap_event(priv,
734 num_wraps - priv->event_log.num_wraps,
735 next_entry, priv->event_log.next_entry);
736 if (next_entry < priv->event_log.next_entry) {
737 iwl_print_cont_event_trace(priv, base,
738 priv->event_log.next_entry,
739 capacity - priv->event_log.next_entry,
740 mode);
741
742 iwl_print_cont_event_trace(priv, base, 0,
743 next_entry, mode);
744 } else {
745 iwl_print_cont_event_trace(priv, base,
746 next_entry, capacity - next_entry,
747 mode);
748
749 iwl_print_cont_event_trace(priv, base, 0,
750 next_entry, mode);
751 }
752 }
753 priv->event_log.num_wraps = num_wraps;
754 priv->event_log.next_entry = next_entry;
755}
756
757/**
758 * iwl_bg_ucode_trace - Timer callback to log ucode event
759 *
760 * The timer is continually set to execute every
761 * UCODE_TRACE_PERIOD milliseconds after the last timer expired
762 * this function is to perform continuous uCode event logging operation
763 * if enabled
764 */
765static void iwl_bg_ucode_trace(unsigned long data)
766{
767 struct iwl_priv *priv = (struct iwl_priv *)data;
768
769 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
770 return;
771
772 if (priv->event_log.ucode_trace) {
773 iwl_continuous_event_trace(priv);
774 /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
775 mod_timer(&priv->ucode_trace,
776 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
777 }
778}
779
660static void iwl_rx_beacon_notif(struct iwl_priv *priv, 780static void iwl_rx_beacon_notif(struct iwl_priv *priv,
661 struct iwl_rx_mem_buffer *rxb) 781 struct iwl_rx_mem_buffer *rxb)
662{ 782{
@@ -689,12 +809,14 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
689 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 809 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
690 unsigned long status = priv->status; 810 unsigned long status = priv->status;
691 811
692 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 812 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
693 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 813 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
694 (flags & SW_CARD_DISABLED) ? "Kill" : "On"); 814 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
815 (flags & CT_CARD_DISABLED) ?
816 "Reached" : "Not reached");
695 817
696 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | 818 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
697 RF_CARD_DISABLED)) { 819 CT_CARD_DISABLED)) {
698 820
699 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, 821 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
700 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 822 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
@@ -708,10 +830,10 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
708 iwl_write_direct32(priv, HBUS_TARG_MBX_C, 830 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
709 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); 831 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
710 } 832 }
711 if (flags & RF_CARD_DISABLED) 833 if (flags & CT_CARD_DISABLED)
712 iwl_tt_enter_ct_kill(priv); 834 iwl_tt_enter_ct_kill(priv);
713 } 835 }
714 if (!(flags & RF_CARD_DISABLED)) 836 if (!(flags & CT_CARD_DISABLED))
715 iwl_tt_exit_ct_kill(priv); 837 iwl_tt_exit_ct_kill(priv);
716 838
717 if (flags & HW_CARD_DISABLED) 839 if (flags & HW_CARD_DISABLED)
@@ -761,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
761 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 883 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
762 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 884 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
763 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 885 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
886 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
887 iwl_rx_spectrum_measure_notif;
764 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 888 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
765 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 889 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
766 iwl_rx_pm_debug_statistics_notif; 890 iwl_rx_pm_debug_statistics_notif;
@@ -774,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
774 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; 898 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
775 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 899 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
776 900
777 iwl_setup_spectrum_handlers(priv);
778 iwl_setup_rx_scan_handlers(priv); 901 iwl_setup_rx_scan_handlers(priv);
779 902
780 /* status change handler */ 903 /* status change handler */
@@ -1634,7 +1757,7 @@ static const char *desc_lookup_text[] = {
1634 "DEBUG_1", 1757 "DEBUG_1",
1635 "DEBUG_2", 1758 "DEBUG_2",
1636 "DEBUG_3", 1759 "DEBUG_3",
1637 "UNKNOWN" 1760 "ADVANCED SYSASSERT"
1638}; 1761};
1639 1762
1640static const char *desc_lookup(int i) 1763static const char *desc_lookup(int i)
@@ -1705,8 +1828,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1705 * iwl_print_event_log - Dump error event log to syslog 1828 * iwl_print_event_log - Dump error event log to syslog
1706 * 1829 *
1707 */ 1830 */
1708static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, 1831static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1709 u32 num_events, u32 mode) 1832 u32 num_events, u32 mode,
1833 int pos, char **buf, size_t bufsz)
1710{ 1834{
1711 u32 i; 1835 u32 i;
1712 u32 base; /* SRAM byte address of event log header */ 1836 u32 base; /* SRAM byte address of event log header */
@@ -1716,7 +1840,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1716 unsigned long reg_flags; 1840 unsigned long reg_flags;
1717 1841
1718 if (num_events == 0) 1842 if (num_events == 0)
1719 return; 1843 return pos;
1720 if (priv->ucode_type == UCODE_INIT) 1844 if (priv->ucode_type == UCODE_INIT)
1721 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1845 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1722 else 1846 else
@@ -1744,27 +1868,44 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1744 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1868 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1745 if (mode == 0) { 1869 if (mode == 0) {
1746 /* data, ev */ 1870 /* data, ev */
1747 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1871 if (bufsz) {
1748 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); 1872 pos += scnprintf(*buf + pos, bufsz - pos,
1873 "EVT_LOG:0x%08x:%04u\n",
1874 time, ev);
1875 } else {
1876 trace_iwlwifi_dev_ucode_event(priv, 0,
1877 time, ev);
1878 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
1879 time, ev);
1880 }
1749 } else { 1881 } else {
1750 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1882 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1751 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", 1883 if (bufsz) {
1884 pos += scnprintf(*buf + pos, bufsz - pos,
1885 "EVT_LOGT:%010u:0x%08x:%04u\n",
1886 time, data, ev);
1887 } else {
1888 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1752 time, data, ev); 1889 time, data, ev);
1753 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1890 trace_iwlwifi_dev_ucode_event(priv, time,
1891 data, ev);
1892 }
1754 } 1893 }
1755 } 1894 }
1756 1895
1757 /* Allow device to power down */ 1896 /* Allow device to power down */
1758 iwl_release_nic_access(priv); 1897 iwl_release_nic_access(priv);
1759 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1898 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1899 return pos;
1760} 1900}
1761 1901
1762/** 1902/**
1763 * iwl_print_last_event_logs - Dump the newest # of event log to syslog 1903 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
1764 */ 1904 */
1765static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1905static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1766 u32 num_wraps, u32 next_entry, 1906 u32 num_wraps, u32 next_entry,
1767 u32 size, u32 mode) 1907 u32 size, u32 mode,
1908 int pos, char **buf, size_t bufsz)
1768{ 1909{
1769 /* 1910 /*
1770 * display the newest DEFAULT_LOG_ENTRIES entries 1911 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1772,21 +1913,26 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1772 */ 1913 */
1773 if (num_wraps) { 1914 if (num_wraps) {
1774 if (next_entry < size) { 1915 if (next_entry < size) {
1775 iwl_print_event_log(priv, 1916 pos = iwl_print_event_log(priv,
1776 capacity - (size - next_entry), 1917 capacity - (size - next_entry),
1777 size - next_entry, mode); 1918 size - next_entry, mode,
1778 iwl_print_event_log(priv, 0, 1919 pos, buf, bufsz);
1779 next_entry, mode); 1920 pos = iwl_print_event_log(priv, 0,
1921 next_entry, mode,
1922 pos, buf, bufsz);
1780 } else 1923 } else
1781 iwl_print_event_log(priv, next_entry - size, 1924 pos = iwl_print_event_log(priv, next_entry - size,
1782 size, mode); 1925 size, mode, pos, buf, bufsz);
1783 } else { 1926 } else {
1784 if (next_entry < size) 1927 if (next_entry < size) {
1785 iwl_print_event_log(priv, 0, next_entry, mode); 1928 pos = iwl_print_event_log(priv, 0, next_entry,
1786 else 1929 mode, pos, buf, bufsz);
1787 iwl_print_event_log(priv, next_entry - size, 1930 } else {
1788 size, mode); 1931 pos = iwl_print_event_log(priv, next_entry - size,
1932 size, mode, pos, buf, bufsz);
1933 }
1789 } 1934 }
1935 return pos;
1790} 1936}
1791 1937
1792/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1938/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1794,7 +1940,8 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1794 1940
1795#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) 1941#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1796 1942
1797void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1943int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1944 char **buf, bool display)
1798{ 1945{
1799 u32 base; /* SRAM byte address of event log header */ 1946 u32 base; /* SRAM byte address of event log header */
1800 u32 capacity; /* event log capacity in # entries */ 1947 u32 capacity; /* event log capacity in # entries */
@@ -1802,6 +1949,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1802 u32 num_wraps; /* # times uCode wrapped to top of log */ 1949 u32 num_wraps; /* # times uCode wrapped to top of log */
1803 u32 next_entry; /* index of next entry to be written by uCode */ 1950 u32 next_entry; /* index of next entry to be written by uCode */
1804 u32 size; /* # entries that we'll print */ 1951 u32 size; /* # entries that we'll print */
1952 int pos = 0;
1953 size_t bufsz = 0;
1805 1954
1806 if (priv->ucode_type == UCODE_INIT) 1955 if (priv->ucode_type == UCODE_INIT)
1807 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1956 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
@@ -1812,7 +1961,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1812 IWL_ERR(priv, 1961 IWL_ERR(priv,
1813 "Invalid event log pointer 0x%08X for %s uCode\n", 1962 "Invalid event log pointer 0x%08X for %s uCode\n",
1814 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1963 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1815 return; 1964 return -EINVAL;
1816 } 1965 }
1817 1966
1818 /* event log header */ 1967 /* event log header */
@@ -1838,7 +1987,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1838 /* bail out if nothing in log */ 1987 /* bail out if nothing in log */
1839 if (size == 0) { 1988 if (size == 0) {
1840 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1989 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1841 return; 1990 return pos;
1842 } 1991 }
1843 1992
1844#ifdef CONFIG_IWLWIFI_DEBUG 1993#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1853,6 +2002,15 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1853 size); 2002 size);
1854 2003
1855#ifdef CONFIG_IWLWIFI_DEBUG 2004#ifdef CONFIG_IWLWIFI_DEBUG
2005 if (display) {
2006 if (full_log)
2007 bufsz = capacity * 48;
2008 else
2009 bufsz = size * 48;
2010 *buf = kmalloc(bufsz, GFP_KERNEL);
2011 if (!*buf)
2012 return -ENOMEM;
2013 }
1856 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 2014 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1857 /* 2015 /*
1858 * if uCode has wrapped back to top of log, 2016 * if uCode has wrapped back to top of log,
@@ -1860,17 +2018,22 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1860 * i.e the next one that uCode would fill. 2018 * i.e the next one that uCode would fill.
1861 */ 2019 */
1862 if (num_wraps) 2020 if (num_wraps)
1863 iwl_print_event_log(priv, next_entry, 2021 pos = iwl_print_event_log(priv, next_entry,
1864 capacity - next_entry, mode); 2022 capacity - next_entry, mode,
2023 pos, buf, bufsz);
1865 /* (then/else) start at top of log */ 2024 /* (then/else) start at top of log */
1866 iwl_print_event_log(priv, 0, next_entry, mode); 2025 pos = iwl_print_event_log(priv, 0,
2026 next_entry, mode, pos, buf, bufsz);
1867 } else 2027 } else
1868 iwl_print_last_event_logs(priv, capacity, num_wraps, 2028 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1869 next_entry, size, mode); 2029 next_entry, size, mode,
2030 pos, buf, bufsz);
1870#else 2031#else
1871 iwl_print_last_event_logs(priv, capacity, num_wraps, 2032 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1872 next_entry, size, mode); 2033 next_entry, size, mode,
2034 pos, buf, bufsz);
1873#endif 2035#endif
2036 return pos;
1874} 2037}
1875 2038
1876/** 2039/**
@@ -2276,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2276 return; 2439 return;
2277} 2440}
2278 2441
2279static void iwl_bg_up(struct work_struct *data)
2280{
2281 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
2282
2283 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2284 return;
2285
2286 mutex_lock(&priv->mutex);
2287 __iwl_up(priv);
2288 mutex_unlock(&priv->mutex);
2289}
2290
2291static void iwl_bg_restart(struct work_struct *data) 2442static void iwl_bg_restart(struct work_struct *data)
2292{ 2443{
2293 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 2444 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2304,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data)
2304 ieee80211_restart_hw(priv->hw); 2455 ieee80211_restart_hw(priv->hw);
2305 } else { 2456 } else {
2306 iwl_down(priv); 2457 iwl_down(priv);
2307 queue_work(priv->workqueue, &priv->up); 2458
2459 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2460 return;
2461
2462 mutex_lock(&priv->mutex);
2463 __iwl_up(priv);
2464 mutex_unlock(&priv->mutex);
2308 } 2465 }
2309} 2466}
2310 2467
@@ -2440,7 +2597,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2440 * Not a mac80211 entry point function, but it fits in with all the 2597 * Not a mac80211 entry point function, but it fits in with all the
2441 * other mac80211 functions grouped here. 2598 * other mac80211 functions grouped here.
2442 */ 2599 */
2443static int iwl_setup_mac(struct iwl_priv *priv) 2600static int iwl_mac_setup_register(struct iwl_priv *priv)
2444{ 2601{
2445 int ret; 2602 int ret;
2446 struct ieee80211_hw *hw = priv->hw; 2603 struct ieee80211_hw *hw = priv->hw;
@@ -2456,6 +2613,10 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2456 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 2613 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
2457 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 2614 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
2458 2615
2616 if (priv->cfg->sku & IWL_SKU_N)
2617 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2618 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2619
2459 hw->sta_data_size = sizeof(struct iwl_station_priv); 2620 hw->sta_data_size = sizeof(struct iwl_station_priv);
2460 hw->wiphy->interface_modes = 2621 hw->wiphy->interface_modes =
2461 BIT(NL80211_IFTYPE_STATION) | 2622 BIT(NL80211_IFTYPE_STATION) |
@@ -2470,7 +2631,7 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2470 */ 2631 */
2471 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2632 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2472 2633
2473 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 2634 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1;
2474 /* we create the 802.11 header and a zero-length SSID element */ 2635 /* we create the 802.11 header and a zero-length SSID element */
2475 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 2636 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
2476 2637
@@ -2668,14 +2829,18 @@ void iwl_config_ap(struct iwl_priv *priv)
2668} 2829}
2669 2830
2670static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, 2831static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2671 struct ieee80211_key_conf *keyconf, const u8 *addr, 2832 struct ieee80211_vif *vif,
2672 u32 iv32, u16 *phase1key) 2833 struct ieee80211_key_conf *keyconf,
2834 struct ieee80211_sta *sta,
2835 u32 iv32, u16 *phase1key)
2673{ 2836{
2674 2837
2675 struct iwl_priv *priv = hw->priv; 2838 struct iwl_priv *priv = hw->priv;
2676 IWL_DEBUG_MAC80211(priv, "enter\n"); 2839 IWL_DEBUG_MAC80211(priv, "enter\n");
2677 2840
2678 iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key); 2841 iwl_update_tkip_key(priv, keyconf,
2842 sta ? sta->addr : iwl_bcast_addr,
2843 iv32, phase1key);
2679 2844
2680 IWL_DEBUG_MAC80211(priv, "leave\n"); 2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2681} 2846}
@@ -2776,14 +2941,28 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2776 return ret; 2941 return ret;
2777 case IEEE80211_AMPDU_TX_START: 2942 case IEEE80211_AMPDU_TX_START:
2778 IWL_DEBUG_HT(priv, "start Tx\n"); 2943 IWL_DEBUG_HT(priv, "start Tx\n");
2779 return iwl_tx_agg_start(priv, sta->addr, tid, ssn); 2944 ret = iwl_tx_agg_start(priv, sta->addr, tid, ssn);
2945 if (ret == 0) {
2946 priv->agg_tids_count++;
2947 IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
2948 priv->agg_tids_count);
2949 }
2950 return ret;
2780 case IEEE80211_AMPDU_TX_STOP: 2951 case IEEE80211_AMPDU_TX_STOP:
2781 IWL_DEBUG_HT(priv, "stop Tx\n"); 2952 IWL_DEBUG_HT(priv, "stop Tx\n");
2782 ret = iwl_tx_agg_stop(priv, sta->addr, tid); 2953 ret = iwl_tx_agg_stop(priv, sta->addr, tid);
2954 if ((ret == 0) && (priv->agg_tids_count > 0)) {
2955 priv->agg_tids_count--;
2956 IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
2957 priv->agg_tids_count);
2958 }
2783 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2959 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2784 return 0; 2960 return 0;
2785 else 2961 else
2786 return ret; 2962 return ret;
2963 case IEEE80211_AMPDU_TX_OPERATIONAL:
2964 /* do nothing */
2965 return -EOPNOTSUPP;
2787 default: 2966 default:
2788 IWL_DEBUG_HT(priv, "unknown\n"); 2967 IWL_DEBUG_HT(priv, "unknown\n");
2789 return -EINVAL; 2968 return -EINVAL;
@@ -2833,6 +3012,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2833 break; 3012 break;
2834 case STA_NOTIFY_AWAKE: 3013 case STA_NOTIFY_AWAKE:
2835 WARN_ON(!sta_priv->client); 3014 WARN_ON(!sta_priv->client);
3015 if (!sta_priv->asleep)
3016 break;
2836 sta_priv->asleep = false; 3017 sta_priv->asleep = false;
2837 sta_id = iwl_find_station(priv, sta->addr); 3018 sta_id = iwl_find_station(priv, sta->addr);
2838 if (sta_id != IWL_INVALID_STATION) 3019 if (sta_id != IWL_INVALID_STATION)
@@ -3109,7 +3290,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3109 3290
3110 init_waitqueue_head(&priv->wait_command_queue); 3291 init_waitqueue_head(&priv->wait_command_queue);
3111 3292
3112 INIT_WORK(&priv->up, iwl_bg_up);
3113 INIT_WORK(&priv->restart, iwl_bg_restart); 3293 INIT_WORK(&priv->restart, iwl_bg_restart);
3114 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3294 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3115 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3295 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
@@ -3126,6 +3306,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3126 priv->statistics_periodic.data = (unsigned long)priv; 3306 priv->statistics_periodic.data = (unsigned long)priv;
3127 priv->statistics_periodic.function = iwl_bg_statistics_periodic; 3307 priv->statistics_periodic.function = iwl_bg_statistics_periodic;
3128 3308
3309 init_timer(&priv->ucode_trace);
3310 priv->ucode_trace.data = (unsigned long)priv;
3311 priv->ucode_trace.function = iwl_bg_ucode_trace;
3312
3129 if (!priv->cfg->use_isr_legacy) 3313 if (!priv->cfg->use_isr_legacy)
3130 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3314 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3131 iwl_irq_tasklet, (unsigned long)priv); 3315 iwl_irq_tasklet, (unsigned long)priv);
@@ -3144,6 +3328,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3144 cancel_delayed_work(&priv->alive_start); 3328 cancel_delayed_work(&priv->alive_start);
3145 cancel_work_sync(&priv->beacon_update); 3329 cancel_work_sync(&priv->beacon_update);
3146 del_timer_sync(&priv->statistics_periodic); 3330 del_timer_sync(&priv->statistics_periodic);
3331 del_timer_sync(&priv->ucode_trace);
3147} 3332}
3148 3333
3149static void iwl_init_hw_rates(struct iwl_priv *priv, 3334static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3179,6 +3364,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3179 INIT_LIST_HEAD(&priv->free_frames); 3364 INIT_LIST_HEAD(&priv->free_frames);
3180 3365
3181 mutex_init(&priv->mutex); 3366 mutex_init(&priv->mutex);
3367 mutex_init(&priv->sync_cmd_mutex);
3182 3368
3183 /* Clear the driver's (not device's) station table */ 3369 /* Clear the driver's (not device's) station table */
3184 iwl_clear_stations_table(priv); 3370 iwl_clear_stations_table(priv);
@@ -3188,6 +3374,15 @@ static int iwl_init_drv(struct iwl_priv *priv)
3188 priv->band = IEEE80211_BAND_2GHZ; 3374 priv->band = IEEE80211_BAND_2GHZ;
3189 3375
3190 priv->iw_mode = NL80211_IFTYPE_STATION; 3376 priv->iw_mode = NL80211_IFTYPE_STATION;
3377 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3378 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3379 priv->agg_tids_count = 0;
3380
3381 /* initialize force reset */
3382 priv->force_reset[IWL_RF_RESET].reset_duration =
3383 IWL_DELAY_NEXT_FORCE_RF_RESET;
3384 priv->force_reset[IWL_FW_RESET].reset_duration =
3385 IWL_DELAY_NEXT_FORCE_FW_RELOAD;
3191 3386
3192 /* Choose which receivers/antennas to use */ 3387 /* Choose which receivers/antennas to use */
3193 if (priv->cfg->ops->hcmd->set_rxon_chain) 3388 if (priv->cfg->ops->hcmd->set_rxon_chain)
@@ -3264,7 +3459,6 @@ static struct ieee80211_ops iwl_hw_ops = {
3264 .set_key = iwl_mac_set_key, 3459 .set_key = iwl_mac_set_key,
3265 .update_tkip_key = iwl_mac_update_tkip_key, 3460 .update_tkip_key = iwl_mac_update_tkip_key,
3266 .get_stats = iwl_mac_get_stats, 3461 .get_stats = iwl_mac_get_stats,
3267 .get_tx_stats = iwl_mac_get_tx_stats,
3268 .conf_tx = iwl_mac_conf_tx, 3462 .conf_tx = iwl_mac_conf_tx,
3269 .reset_tsf = iwl_mac_reset_tsf, 3463 .reset_tsf = iwl_mac_reset_tsf,
3270 .bss_info_changed = iwl_bss_info_changed, 3464 .bss_info_changed = iwl_bss_info_changed,
@@ -3365,6 +3559,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3365 */ 3559 */
3366 spin_lock_init(&priv->reg_lock); 3560 spin_lock_init(&priv->reg_lock);
3367 spin_lock_init(&priv->lock); 3561 spin_lock_init(&priv->lock);
3562
3563 /*
3564 * stop and reset the on-board processor just in case it is in a
3565 * strange state ... like being left stranded by a primary kernel
3566 * and this is now the kdump kernel trying to start up
3567 */
3568 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
3569
3368 iwl_hw_detect(priv); 3570 iwl_hw_detect(priv);
3369 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", 3571 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
3370 priv->cfg->name, priv->hw_rev); 3572 priv->cfg->name, priv->hw_rev);
@@ -3439,9 +3641,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3439 iwl_setup_deferred_work(priv); 3641 iwl_setup_deferred_work(priv);
3440 iwl_setup_rx_handlers(priv); 3642 iwl_setup_rx_handlers(priv);
3441 3643
3442 /********************************** 3644 /*********************************************
3443 * 8. Setup and register mac80211 3645 * 8. Enable interrupts and read RFKILL state
3444 **********************************/ 3646 *********************************************/
3445 3647
3446 /* enable interrupts if needed: hw bug w/a */ 3648 /* enable interrupts if needed: hw bug w/a */
3447 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); 3649 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
@@ -3452,14 +3654,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3452 3654
3453 iwl_enable_interrupts(priv); 3655 iwl_enable_interrupts(priv);
3454 3656
3455 err = iwl_setup_mac(priv);
3456 if (err)
3457 goto out_remove_sysfs;
3458
3459 err = iwl_dbgfs_register(priv, DRV_NAME);
3460 if (err)
3461 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3462
3463 /* If platform's RF_KILL switch is NOT set to KILL */ 3657 /* If platform's RF_KILL switch is NOT set to KILL */
3464 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) 3658 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
3465 clear_bit(STATUS_RF_KILL_HW, &priv->status); 3659 clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -3471,6 +3665,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3471 3665
3472 iwl_power_initialize(priv); 3666 iwl_power_initialize(priv);
3473 iwl_tt_initialize(priv); 3667 iwl_tt_initialize(priv);
3668
3669 /**************************************************
3670 * 9. Setup and register with mac80211 and debugfs
3671 **************************************************/
3672 err = iwl_mac_setup_register(priv);
3673 if (err)
3674 goto out_remove_sysfs;
3675
3676 err = iwl_dbgfs_register(priv, DRV_NAME);
3677 if (err)
3678 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3679
3474 return 0; 3680 return 0;
3475 3681
3476 out_remove_sysfs: 3682 out_remove_sysfs:
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 95a57b36a7ea..845831ac053e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -414,7 +414,6 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ 414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
415static int iwl_sensitivity_write(struct iwl_priv *priv) 415static int iwl_sensitivity_write(struct iwl_priv *priv)
416{ 416{
417 int ret = 0;
418 struct iwl_sensitivity_cmd cmd ; 417 struct iwl_sensitivity_cmd cmd ;
419 struct iwl_sensitivity_data *data = NULL; 418 struct iwl_sensitivity_data *data = NULL;
420 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
@@ -477,11 +476,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
477 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), 476 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
478 sizeof(u16)*HD_TABLE_SIZE); 477 sizeof(u16)*HD_TABLE_SIZE);
479 478
480 ret = iwl_send_cmd(priv, &cmd_out); 479 return iwl_send_cmd(priv, &cmd_out);
481 if (ret)
482 IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
483
484 return ret;
485} 480}
486 481
487void iwl_init_sensitivity(struct iwl_priv *priv) 482void iwl_init_sensitivity(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index b6cef989a796..2b7b1df83ba0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e91507531923..ab3c77b92cc8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -120,7 +120,6 @@ enum {
120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67, 120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
121 121
122 /* 802.11h related */ 122 /* 802.11h related */
123 RADAR_NOTIFICATION = 0x70, /* not used */
124 REPLY_QUIET_CMD = 0x71, /* not used */ 123 REPLY_QUIET_CMD = 0x71, /* not used */
125 REPLY_CHANNEL_SWITCH = 0x72, 124 REPLY_CHANNEL_SWITCH = 0x72,
126 CHANNEL_SWITCH_NOTIFICATION = 0x73, 125 CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@ -2248,10 +2247,22 @@ struct iwl_link_quality_cmd {
2248 __le32 reserved2; 2247 __le32 reserved2;
2249} __attribute__ ((packed)); 2248} __attribute__ ((packed));
2250 2249
2250/*
2251 * BT configuration enable flags:
2252 * bit 0 - 1: BT channel announcement enabled
2253 * 0: disable
2254 * bit 1 - 1: priority of BT device enabled
2255 * 0: disable
2256 * bit 2 - 1: BT 2 wire support enabled
2257 * 0: disable
2258 */
2259#define BT_COEX_DISABLE (0x0)
2260#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
2261#define BT_ENABLE_PRIORITY BIT(1)
2262#define BT_ENABLE_2_WIRE BIT(2)
2263
2251#define BT_COEX_DISABLE (0x0) 2264#define BT_COEX_DISABLE (0x0)
2252#define BT_COEX_MODE_2W (0x1) 2265#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
2253#define BT_COEX_MODE_3W (0x2)
2254#define BT_COEX_MODE_4W (0x3)
2255 2266
2256#define BT_LEAD_TIME_MIN (0x0) 2267#define BT_LEAD_TIME_MIN (0x0)
2257#define BT_LEAD_TIME_DEF (0x1E) 2268#define BT_LEAD_TIME_DEF (0x1E)
@@ -2510,7 +2521,7 @@ struct iwl_card_state_notif {
2510 2521
2511#define HW_CARD_DISABLED 0x01 2522#define HW_CARD_DISABLED 0x01
2512#define SW_CARD_DISABLED 0x02 2523#define SW_CARD_DISABLED 0x02
2513#define RF_CARD_DISABLED 0x04 2524#define CT_CARD_DISABLED 0x04
2514#define RXON_CARD_DISABLED 0x10 2525#define RXON_CARD_DISABLED 0x10
2515 2526
2516struct iwl_ct_kill_config { 2527struct iwl_ct_kill_config {
@@ -2984,7 +2995,7 @@ struct statistics_rx_ht_phy {
2984 __le32 agg_crc32_good; 2995 __le32 agg_crc32_good;
2985 __le32 agg_mpdu_cnt; 2996 __le32 agg_mpdu_cnt;
2986 __le32 agg_cnt; 2997 __le32 agg_cnt;
2987 __le32 reserved2; 2998 __le32 unsupport_mcs;
2988} __attribute__ ((packed)); 2999} __attribute__ ((packed));
2989 3000
2990#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) 3001#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
@@ -3087,8 +3098,8 @@ struct statistics_div {
3087} __attribute__ ((packed)); 3098} __attribute__ ((packed));
3088 3099
3089struct statistics_general { 3100struct statistics_general {
3090 __le32 temperature; 3101 __le32 temperature; /* radio temperature */
3091 __le32 temperature_m; 3102 __le32 temperature_m; /* for 5000 and up, this is radio voltage */
3092 struct statistics_dbg dbg; 3103 struct statistics_dbg dbg;
3093 __le32 sleep_time; 3104 __le32 sleep_time;
3094 __le32 slots_out; 3105 __le32 slots_out;
@@ -3096,7 +3107,12 @@ struct statistics_general {
3096 __le32 ttl_timestamp; 3107 __le32 ttl_timestamp;
3097 struct statistics_div div; 3108 struct statistics_div div;
3098 __le32 rx_enable_counter; 3109 __le32 rx_enable_counter;
3099 __le32 reserved1; 3110 /*
3111 * num_of_sos_states:
3112 * count the number of times we have to re-tune
3113 * in order to get out of bad PHY status
3114 */
3115 __le32 num_of_sos_states;
3100 __le32 reserved2; 3116 __le32 reserved2;
3101 __le32 reserved3; 3117 __le32 reserved3;
3102} __attribute__ ((packed)); 3118} __attribute__ ((packed));
@@ -3161,13 +3177,30 @@ struct iwl_notif_statistics {
3161 3177
3162/* 3178/*
3163 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) 3179 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
3180 *
3181 * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
3182 * in regardless of how many missed beacons, which mean when driver receive the
3183 * notification, inside the command, it can find all the beacons information
3184 * which include number of total missed beacons, number of consecutive missed
3185 * beacons, number of beacons received and number of beacons expected to
3186 * receive.
3187 *
3188 * If uCode detected consecutive_missed_beacons > 5, it will reset the radio
3189 * in order to bring the radio/PHY back to working state; which has no relation
3190 * to when driver will perform sensitivity calibration.
3191 *
3192 * Driver should set it own missed_beacon_threshold to decide when to perform
3193 * sensitivity calibration based on number of consecutive missed beacons in
3194 * order to improve overall performance, especially in noisy environment.
3195 *
3164 */ 3196 */
3165/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, 3197
3166 * then this notification will be sent. */ 3198#define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
3167#define CONSECUTIVE_MISSED_BCONS_TH 20 3199#define IWL_MISSED_BEACON_THRESHOLD_DEF (5)
3200#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF
3168 3201
3169struct iwl_missed_beacon_notif { 3202struct iwl_missed_beacon_notif {
3170 __le32 consequtive_missed_beacons; 3203 __le32 consecutive_missed_beacons;
3171 __le32 total_missed_becons; 3204 __le32 total_missed_becons;
3172 __le32 num_expected_beacons; 3205 __le32 num_expected_beacons;
3173 __le32 num_recvd_beacons; 3206 __le32 num_recvd_beacons;
@@ -3437,11 +3470,7 @@ enum {
3437 IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, 3470 IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7,
3438 IWL_PHY_CALIBRATE_DC_CMD = 8, 3471 IWL_PHY_CALIBRATE_DC_CMD = 8,
3439 IWL_PHY_CALIBRATE_LO_CMD = 9, 3472 IWL_PHY_CALIBRATE_LO_CMD = 9,
3440 IWL_PHY_CALIBRATE_RX_BB_CMD = 10,
3441 IWL_PHY_CALIBRATE_TX_IQ_CMD = 11, 3473 IWL_PHY_CALIBRATE_TX_IQ_CMD = 11,
3442 IWL_PHY_CALIBRATE_RX_IQ_CMD = 12,
3443 IWL_PHY_CALIBRATION_NOISE_CMD = 13,
3444 IWL_PHY_CALIBRATE_AGC_TABLE_CMD = 14,
3445 IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, 3474 IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
3446 IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, 3475 IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16,
3447 IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, 3476 IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index f36f804804fc..112149e9b31e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -47,6 +47,26 @@ MODULE_VERSION(IWLWIFI_VERSION);
47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50/*
51 * set bt_coex_active to true, uCode will do kill/defer
52 * every time the priority line is asserted (BT is sending signals on the
53 * priority line in the PCIx).
54 * set bt_coex_active to false, uCode will ignore the BT activity and
55 * perform the normal operation
56 *
57 * User might experience transmit issue on some platform due to WiFi/BT
58 * co-exist problem. The possible behaviors are:
59 * Able to scan and finding all the available AP
60 * Not able to associate with any AP
61 * On those platforms, WiFi communication can be restored by set
62 * "bt_coex_active" module parameter to "false"
63 *
64 * default: bt_coex_active = true (BT_COEX_ENABLE)
65 */
66static bool bt_coex_active = true;
67module_param(bt_coex_active, bool, S_IRUGO);
68MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
69
50static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { 70static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
51 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 71 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
52 0, COEX_UNASSOC_IDLE_FLAGS}, 72 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -257,8 +277,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
257 spin_lock_irqsave(&priv->lock, flags); 277 spin_lock_irqsave(&priv->lock, flags);
258 priv->cfg->ops->lib->apm_ops.init(priv); 278 priv->cfg->ops->lib->apm_ops.init(priv);
259 279
260 /* Set interrupt coalescing timer to 512 usecs */ 280 /* Set interrupt coalescing calibration timer to default (512 usecs) */
261 iwl_write8(priv, CSR_INT_COALESCING, 512 / 32); 281 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
262 282
263 spin_unlock_irqrestore(&priv->lock, flags); 283 spin_unlock_irqrestore(&priv->lock, flags);
264 284
@@ -450,8 +470,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
450 if (priv->cfg->ht_greenfield_support) 470 if (priv->cfg->ht_greenfield_support)
451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 471 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 472 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
453 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
454 (priv->cfg->sm_ps_mode << 2));
455 max_bit_rate = MAX_BIT_RATE_20_MHZ; 473 max_bit_rate = MAX_BIT_RATE_20_MHZ;
456 if (priv->hw_params.ht40_channel & BIT(band)) { 474 if (priv->hw_params.ht40_channel & BIT(band)) {
457 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 475 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +654,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
636 654
637static bool is_single_rx_stream(struct iwl_priv *priv) 655static bool is_single_rx_stream(struct iwl_priv *priv)
638{ 656{
639 return !priv->current_ht_config.is_ht || 657 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
640 priv->current_ht_config.single_chain_sufficient; 658 priv->current_ht_config.single_chain_sufficient;
641} 659}
642 660
@@ -1003,28 +1021,18 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
1003 */ 1021 */
1004static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) 1022static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
1005{ 1023{
1006 int idle_cnt = active_cnt; 1024 /* # Rx chains when idling, depending on SMPS mode */
1007 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 1025 switch (priv->current_ht_config.smps) {
1008 1026 case IEEE80211_SMPS_STATIC:
1009 /* # Rx chains when idling and maybe trying to save power */ 1027 case IEEE80211_SMPS_DYNAMIC:
1010 switch (priv->cfg->sm_ps_mode) { 1028 return IWL_NUM_IDLE_CHAINS_SINGLE;
1011 case WLAN_HT_CAP_SM_PS_STATIC: 1029 case IEEE80211_SMPS_OFF:
1012 idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; 1030 return active_cnt;
1013 break;
1014 case WLAN_HT_CAP_SM_PS_DYNAMIC:
1015 idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
1016 IWL_NUM_IDLE_CHAINS_SINGLE;
1017 break;
1018 case WLAN_HT_CAP_SM_PS_DISABLED:
1019 break;
1020 case WLAN_HT_CAP_SM_PS_INVALID:
1021 default: 1031 default:
1022 IWL_ERR(priv, "invalid sm_ps mode %u\n", 1032 WARN(1, "invalid SMPS mode %d",
1023 priv->cfg->sm_ps_mode); 1033 priv->current_ht_config.smps);
1024 WARN_ON(1); 1034 return active_cnt;
1025 break;
1026 } 1035 }
1027 return idle_cnt;
1028} 1036}
1029 1037
1030/* up to 4 chains */ 1038/* up to 4 chains */
@@ -1363,7 +1371,11 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1363 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1371 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1364 1372
1365 priv->cfg->ops->lib->dump_nic_error_log(priv); 1373 priv->cfg->ops->lib->dump_nic_error_log(priv);
1366 priv->cfg->ops->lib->dump_nic_event_log(priv, false); 1374 if (priv->cfg->ops->lib->dump_csr)
1375 priv->cfg->ops->lib->dump_csr(priv);
1376 if (priv->cfg->ops->lib->dump_fh)
1377 priv->cfg->ops->lib->dump_fh(priv, NULL, false);
1378 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1367#ifdef CONFIG_IWLWIFI_DEBUG 1379#ifdef CONFIG_IWLWIFI_DEBUG
1368 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1380 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1369 iwl_print_rx_config_cmd(priv); 1381 iwl_print_rx_config_cmd(priv);
@@ -1658,9 +1670,9 @@ EXPORT_SYMBOL(iwl_set_tx_power);
1658void iwl_free_isr_ict(struct iwl_priv *priv) 1670void iwl_free_isr_ict(struct iwl_priv *priv)
1659{ 1671{
1660 if (priv->ict_tbl_vir) { 1672 if (priv->ict_tbl_vir) {
1661 pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) + 1673 dma_free_coherent(&priv->pci_dev->dev,
1662 PAGE_SIZE, priv->ict_tbl_vir, 1674 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1663 priv->ict_tbl_dma); 1675 priv->ict_tbl_vir, priv->ict_tbl_dma);
1664 priv->ict_tbl_vir = NULL; 1676 priv->ict_tbl_vir = NULL;
1665 } 1677 }
1666} 1678}
@@ -1676,9 +1688,9 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv)
1676 if (priv->cfg->use_isr_legacy) 1688 if (priv->cfg->use_isr_legacy)
1677 return 0; 1689 return 0;
1678 /* allocate shrared data table */ 1690 /* allocate shrared data table */
1679 priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) * 1691 priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev,
1680 ICT_COUNT) + PAGE_SIZE, 1692 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1681 &priv->ict_tbl_dma); 1693 &priv->ict_tbl_dma, GFP_KERNEL);
1682 if (!priv->ict_tbl_vir) 1694 if (!priv->ict_tbl_vir)
1683 return -ENOMEM; 1695 return -ENOMEM;
1684 1696
@@ -1813,6 +1825,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1813 if (val == 0xffffffff) 1825 if (val == 0xffffffff)
1814 val = 0; 1826 val = 0;
1815 1827
1828 /*
1829 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1830 * (bit 15 before shifting it to 31) to clear when using interrupt
1831 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1832 * so we use them to decide on the real state of the Rx bit.
1833 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1834 */
1835 if (val & 0xC0000)
1836 val |= 0x8000;
1837
1816 inta = (0xff & val) | ((0xff00 & val) << 16); 1838 inta = (0xff & val) | ((0xff00 & val) << 16);
1817 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", 1839 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
1818 inta, inta_mask, val); 1840 inta, inta_mask, val);
@@ -1975,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
1975int iwl_send_bt_config(struct iwl_priv *priv) 1997int iwl_send_bt_config(struct iwl_priv *priv)
1976{ 1998{
1977 struct iwl_bt_cmd bt_cmd = { 1999 struct iwl_bt_cmd bt_cmd = {
1978 .flags = BT_COEX_MODE_4W,
1979 .lead_time = BT_LEAD_TIME_DEF, 2000 .lead_time = BT_LEAD_TIME_DEF,
1980 .max_kill = BT_MAX_KILL_DEF, 2001 .max_kill = BT_MAX_KILL_DEF,
1981 .kill_ack_mask = 0, 2002 .kill_ack_mask = 0,
1982 .kill_cts_mask = 0, 2003 .kill_cts_mask = 0,
1983 }; 2004 };
1984 2005
2006 if (!bt_coex_active)
2007 bt_cmd.flags = BT_COEX_DISABLE;
2008 else
2009 bt_cmd.flags = BT_COEX_ENABLE;
2010
2011 IWL_DEBUG_INFO(priv, "BT coex %s\n",
2012 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
2013
1985 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, 2014 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
1986 sizeof(struct iwl_bt_cmd), &bt_cmd); 2015 sizeof(struct iwl_bt_cmd), &bt_cmd);
1987} 2016}
@@ -2599,44 +2628,43 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
2599EXPORT_SYMBOL(iwl_set_mode); 2628EXPORT_SYMBOL(iwl_set_mode);
2600 2629
2601int iwl_mac_add_interface(struct ieee80211_hw *hw, 2630int iwl_mac_add_interface(struct ieee80211_hw *hw,
2602 struct ieee80211_if_init_conf *conf) 2631 struct ieee80211_vif *vif)
2603{ 2632{
2604 struct iwl_priv *priv = hw->priv; 2633 struct iwl_priv *priv = hw->priv;
2605 unsigned long flags; 2634 int err = 0;
2606 2635
2607 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); 2636 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
2637
2638 mutex_lock(&priv->mutex);
2608 2639
2609 if (priv->vif) { 2640 if (priv->vif) {
2610 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2641 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2611 return -EOPNOTSUPP; 2642 err = -EOPNOTSUPP;
2643 goto out;
2612 } 2644 }
2613 2645
2614 spin_lock_irqsave(&priv->lock, flags); 2646 priv->vif = vif;
2615 priv->vif = conf->vif; 2647 priv->iw_mode = vif->type;
2616 priv->iw_mode = conf->type;
2617
2618 spin_unlock_irqrestore(&priv->lock, flags);
2619
2620 mutex_lock(&priv->mutex);
2621 2648
2622 if (conf->mac_addr) { 2649 if (vif->addr) {
2623 IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); 2650 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2624 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); 2651 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2625 } 2652 }
2626 2653
2627 if (iwl_set_mode(priv, conf->type) == -EAGAIN) 2654 if (iwl_set_mode(priv, vif->type) == -EAGAIN)
2628 /* we are not ready, will run again when ready */ 2655 /* we are not ready, will run again when ready */
2629 set_bit(STATUS_MODE_PENDING, &priv->status); 2656 set_bit(STATUS_MODE_PENDING, &priv->status);
2630 2657
2658 out:
2631 mutex_unlock(&priv->mutex); 2659 mutex_unlock(&priv->mutex);
2632 2660
2633 IWL_DEBUG_MAC80211(priv, "leave\n"); 2661 IWL_DEBUG_MAC80211(priv, "leave\n");
2634 return 0; 2662 return err;
2635} 2663}
2636EXPORT_SYMBOL(iwl_mac_add_interface); 2664EXPORT_SYMBOL(iwl_mac_add_interface);
2637 2665
2638void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2666void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2639 struct ieee80211_if_init_conf *conf) 2667 struct ieee80211_vif *vif)
2640{ 2668{
2641 struct iwl_priv *priv = hw->priv; 2669 struct iwl_priv *priv = hw->priv;
2642 2670
@@ -2649,7 +2677,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2649 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2677 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2650 iwlcore_commit_rxon(priv); 2678 iwlcore_commit_rxon(priv);
2651 } 2679 }
2652 if (priv->vif == conf->vif) { 2680 if (priv->vif == vif) {
2653 priv->vif = NULL; 2681 priv->vif = NULL;
2654 memset(priv->bssid, 0, ETH_ALEN); 2682 memset(priv->bssid, 0, ETH_ALEN);
2655 } 2683 }
@@ -2689,6 +2717,21 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2689 IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); 2717 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
2690 } 2718 }
2691 2719
2720 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
2721 IEEE80211_CONF_CHANGE_CHANNEL)) {
2722 /* mac80211 uses static for non-HT which is what we want */
2723 priv->current_ht_config.smps = conf->smps_mode;
2724
2725 /*
2726 * Recalculate chain counts.
2727 *
2728 * If monitor mode is enabled then mac80211 will
2729 * set up the SM PS mode to OFF if an HT channel is
2730 * configured.
2731 */
2732 if (priv->cfg->ops->hcmd->set_rxon_chain)
2733 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2734 }
2692 2735
2693 /* during scanning mac80211 will delay channel setting until 2736 /* during scanning mac80211 will delay channel setting until
2694 * scan finish with changed = 0 2737 * scan finish with changed = 0
@@ -2786,10 +2829,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2786 iwl_set_tx_power(priv, conf->power_level, false); 2829 iwl_set_tx_power(priv, conf->power_level, false);
2787 } 2830 }
2788 2831
2789 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2790 if (priv->cfg->ops->hcmd->set_rxon_chain)
2791 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2792
2793 if (!iwl_is_ready(priv)) { 2832 if (!iwl_is_ready(priv)) {
2794 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2833 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2795 goto out; 2834 goto out;
@@ -2812,42 +2851,6 @@ out:
2812} 2851}
2813EXPORT_SYMBOL(iwl_mac_config); 2852EXPORT_SYMBOL(iwl_mac_config);
2814 2853
2815int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
2816 struct ieee80211_tx_queue_stats *stats)
2817{
2818 struct iwl_priv *priv = hw->priv;
2819 int i, avail;
2820 struct iwl_tx_queue *txq;
2821 struct iwl_queue *q;
2822 unsigned long flags;
2823
2824 IWL_DEBUG_MAC80211(priv, "enter\n");
2825
2826 if (!iwl_is_ready_rf(priv)) {
2827 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
2828 return -EIO;
2829 }
2830
2831 spin_lock_irqsave(&priv->lock, flags);
2832
2833 for (i = 0; i < AC_NUM; i++) {
2834 txq = &priv->txq[i];
2835 q = &txq->q;
2836 avail = iwl_queue_space(q);
2837
2838 stats[i].len = q->n_window - avail;
2839 stats[i].limit = q->n_window - q->high_mark;
2840 stats[i].count = q->n_window;
2841
2842 }
2843 spin_unlock_irqrestore(&priv->lock, flags);
2844
2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2846
2847 return 0;
2848}
2849EXPORT_SYMBOL(iwl_mac_get_tx_stats);
2850
2851void iwl_mac_reset_tsf(struct ieee80211_hw *hw) 2854void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2852{ 2855{
2853 struct iwl_priv *priv = hw->priv; 2856 struct iwl_priv *priv = hw->priv;
@@ -3197,6 +3200,207 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
3197EXPORT_SYMBOL(iwl_update_stats); 3200EXPORT_SYMBOL(iwl_update_stats);
3198#endif 3201#endif
3199 3202
3203const static char *get_csr_string(int cmd)
3204{
3205 switch (cmd) {
3206 IWL_CMD(CSR_HW_IF_CONFIG_REG);
3207 IWL_CMD(CSR_INT_COALESCING);
3208 IWL_CMD(CSR_INT);
3209 IWL_CMD(CSR_INT_MASK);
3210 IWL_CMD(CSR_FH_INT_STATUS);
3211 IWL_CMD(CSR_GPIO_IN);
3212 IWL_CMD(CSR_RESET);
3213 IWL_CMD(CSR_GP_CNTRL);
3214 IWL_CMD(CSR_HW_REV);
3215 IWL_CMD(CSR_EEPROM_REG);
3216 IWL_CMD(CSR_EEPROM_GP);
3217 IWL_CMD(CSR_OTP_GP_REG);
3218 IWL_CMD(CSR_GIO_REG);
3219 IWL_CMD(CSR_GP_UCODE_REG);
3220 IWL_CMD(CSR_GP_DRIVER_REG);
3221 IWL_CMD(CSR_UCODE_DRV_GP1);
3222 IWL_CMD(CSR_UCODE_DRV_GP2);
3223 IWL_CMD(CSR_LED_REG);
3224 IWL_CMD(CSR_DRAM_INT_TBL_REG);
3225 IWL_CMD(CSR_GIO_CHICKEN_BITS);
3226 IWL_CMD(CSR_ANA_PLL_CFG);
3227 IWL_CMD(CSR_HW_REV_WA_REG);
3228 IWL_CMD(CSR_DBG_HPET_MEM_REG);
3229 default:
3230 return "UNKNOWN";
3231
3232 }
3233}
3234
3235void iwl_dump_csr(struct iwl_priv *priv)
3236{
3237 int i;
3238 u32 csr_tbl[] = {
3239 CSR_HW_IF_CONFIG_REG,
3240 CSR_INT_COALESCING,
3241 CSR_INT,
3242 CSR_INT_MASK,
3243 CSR_FH_INT_STATUS,
3244 CSR_GPIO_IN,
3245 CSR_RESET,
3246 CSR_GP_CNTRL,
3247 CSR_HW_REV,
3248 CSR_EEPROM_REG,
3249 CSR_EEPROM_GP,
3250 CSR_OTP_GP_REG,
3251 CSR_GIO_REG,
3252 CSR_GP_UCODE_REG,
3253 CSR_GP_DRIVER_REG,
3254 CSR_UCODE_DRV_GP1,
3255 CSR_UCODE_DRV_GP2,
3256 CSR_LED_REG,
3257 CSR_DRAM_INT_TBL_REG,
3258 CSR_GIO_CHICKEN_BITS,
3259 CSR_ANA_PLL_CFG,
3260 CSR_HW_REV_WA_REG,
3261 CSR_DBG_HPET_MEM_REG
3262 };
3263 IWL_ERR(priv, "CSR values:\n");
3264 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
3265 "CSR_INT_PERIODIC_REG)\n");
3266 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
3267 IWL_ERR(priv, " %25s: 0X%08x\n",
3268 get_csr_string(csr_tbl[i]),
3269 iwl_read32(priv, csr_tbl[i]));
3270 }
3271}
3272EXPORT_SYMBOL(iwl_dump_csr);
3273
3274const static char *get_fh_string(int cmd)
3275{
3276 switch (cmd) {
3277 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
3278 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
3279 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
3280 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
3281 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
3282 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
3283 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
3284 IWL_CMD(FH_TSSR_TX_STATUS_REG);
3285 IWL_CMD(FH_TSSR_TX_ERROR_REG);
3286 default:
3287 return "UNKNOWN";
3288
3289 }
3290}
3291
3292int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
3293{
3294 int i;
3295#ifdef CONFIG_IWLWIFI_DEBUG
3296 int pos = 0;
3297 size_t bufsz = 0;
3298#endif
3299 u32 fh_tbl[] = {
3300 FH_RSCSR_CHNL0_STTS_WPTR_REG,
3301 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
3302 FH_RSCSR_CHNL0_WPTR,
3303 FH_MEM_RCSR_CHNL0_CONFIG_REG,
3304 FH_MEM_RSSR_SHARED_CTRL_REG,
3305 FH_MEM_RSSR_RX_STATUS_REG,
3306 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
3307 FH_TSSR_TX_STATUS_REG,
3308 FH_TSSR_TX_ERROR_REG
3309 };
3310#ifdef CONFIG_IWLWIFI_DEBUG
3311 if (display) {
3312 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
3313 *buf = kmalloc(bufsz, GFP_KERNEL);
3314 if (!*buf)
3315 return -ENOMEM;
3316 pos += scnprintf(*buf + pos, bufsz - pos,
3317 "FH register values:\n");
3318 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3319 pos += scnprintf(*buf + pos, bufsz - pos,
3320 " %34s: 0X%08x\n",
3321 get_fh_string(fh_tbl[i]),
3322 iwl_read_direct32(priv, fh_tbl[i]));
3323 }
3324 return pos;
3325 }
3326#endif
3327 IWL_ERR(priv, "FH register values:\n");
3328 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3329 IWL_ERR(priv, " %34s: 0X%08x\n",
3330 get_fh_string(fh_tbl[i]),
3331 iwl_read_direct32(priv, fh_tbl[i]));
3332 }
3333 return 0;
3334}
3335EXPORT_SYMBOL(iwl_dump_fh);
3336
3337static void iwl_force_rf_reset(struct iwl_priv *priv)
3338{
3339 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3340 return;
3341
3342 if (!iwl_is_associated(priv)) {
3343 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
3344 return;
3345 }
3346 /*
3347 * There is no easy and better way to force reset the radio,
3348 * the only known method is switching channel which will force to
3349 * reset and tune the radio.
3350 * Use internal short scan (single channel) operation to should
3351 * achieve this objective.
3352 * Driver should reset the radio when number of consecutive missed
3353 * beacon, or any other uCode error condition detected.
3354 */
3355 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
3356 iwl_internal_short_hw_scan(priv);
3357 return;
3358}
3359
3360
3361int iwl_force_reset(struct iwl_priv *priv, int mode)
3362{
3363 struct iwl_force_reset *force_reset;
3364
3365 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3366 return -EINVAL;
3367
3368 if (mode >= IWL_MAX_FORCE_RESET) {
3369 IWL_DEBUG_INFO(priv, "invalid reset request.\n");
3370 return -EINVAL;
3371 }
3372 force_reset = &priv->force_reset[mode];
3373 force_reset->reset_request_count++;
3374 if (force_reset->last_force_reset_jiffies &&
3375 time_after(force_reset->last_force_reset_jiffies +
3376 force_reset->reset_duration, jiffies)) {
3377 IWL_DEBUG_INFO(priv, "force reset rejected\n");
3378 force_reset->reset_reject_count++;
3379 return -EAGAIN;
3380 }
3381 force_reset->reset_success_count++;
3382 force_reset->last_force_reset_jiffies = jiffies;
3383 IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode);
3384 switch (mode) {
3385 case IWL_RF_RESET:
3386 iwl_force_rf_reset(priv);
3387 break;
3388 case IWL_FW_RESET:
3389 IWL_ERR(priv, "On demand firmware reload\n");
3390 /* Set the FW error flag -- cleared on iwl_down */
3391 set_bit(STATUS_FW_ERROR, &priv->status);
3392 wake_up_interruptible(&priv->wait_command_queue);
3393 /*
3394 * Keep the restart process from trying to send host
3395 * commands by clearing the INIT status bit
3396 */
3397 clear_bit(STATUS_READY, &priv->status);
3398 queue_work(priv->workqueue, &priv->restart);
3399 break;
3400 }
3401 return 0;
3402}
3403
3200#ifdef CONFIG_PM 3404#ifdef CONFIG_PM
3201 3405
3202int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3406int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index fe37d6a6bf97..4ef7739f9e8e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -63,8 +63,6 @@
63#ifndef __iwl_core_h__ 63#ifndef __iwl_core_h__
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include <linux/utsrelease.h>
67
68/************************ 66/************************
69 * forward declarations * 67 * forward declarations *
70 ************************/ 68 ************************/
@@ -72,8 +70,8 @@ struct iwl_host_cmd;
72struct iwl_cmd; 70struct iwl_cmd;
73 71
74 72
75#define IWLWIFI_VERSION UTS_RELEASE "-k" 73#define IWLWIFI_VERSION "in-tree:"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
77#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
78 76
79#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 77#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -119,6 +117,7 @@ struct iwl_apm_ops {
119struct iwl_temp_ops { 117struct iwl_temp_ops {
120 void (*temperature)(struct iwl_priv *priv); 118 void (*temperature)(struct iwl_priv *priv);
121 void (*set_ct_kill)(struct iwl_priv *priv); 119 void (*set_ct_kill)(struct iwl_priv *priv);
120 void (*set_calib_version)(struct iwl_priv *priv);
122}; 121};
123 122
124struct iwl_ucode_ops { 123struct iwl_ucode_ops {
@@ -169,8 +168,11 @@ struct iwl_lib_ops {
169 int (*is_valid_rtc_data_addr)(u32 addr); 168 int (*is_valid_rtc_data_addr)(u32 addr);
170 /* 1st ucode load */ 169 /* 1st ucode load */
171 int (*load_ucode)(struct iwl_priv *priv); 170 int (*load_ucode)(struct iwl_priv *priv);
172 void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); 171 int (*dump_nic_event_log)(struct iwl_priv *priv,
172 bool full_log, char **buf, bool display);
173 void (*dump_nic_error_log)(struct iwl_priv *priv); 173 void (*dump_nic_error_log)(struct iwl_priv *priv);
174 void (*dump_csr)(struct iwl_priv *priv);
175 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 176 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 177 /* power management */
176 struct iwl_apm_ops apm_ops; 178 struct iwl_apm_ops apm_ops;
@@ -187,6 +189,8 @@ struct iwl_lib_ops {
187 189
188 /* temperature */ 190 /* temperature */
189 struct iwl_temp_ops temp_ops; 191 struct iwl_temp_ops temp_ops;
192 /* station management */
193 void (*add_bcast_station)(struct iwl_priv *priv);
190}; 194};
191 195
192struct iwl_led_ops { 196struct iwl_led_ops {
@@ -230,8 +234,9 @@ struct iwl_mod_params {
230 * @chain_noise_num_beacons: number of beacons used to compute chain noise 234 * @chain_noise_num_beacons: number of beacons used to compute chain noise
231 * @adv_thermal_throttle: support advance thermal throttle 235 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 236 * @support_ct_kill_exit: support ct kill exit condition
233 * @sm_ps_mode: spatial multiplexing power save mode
234 * @support_wimax_coexist: support wimax/wifi co-exist 237 * @support_wimax_coexist: support wimax/wifi co-exist
238 * @plcp_delta_threshold: plcp error rate threshold used to trigger
239 * radio tuning when there is a high receiving plcp error rate
235 * 240 *
236 * We enable the driver to be backward compatible wrt API version. The 241 * We enable the driver to be backward compatible wrt API version. The
237 * driver specifies which APIs it supports (with @ucode_api_max being the 242 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -287,8 +292,9 @@ struct iwl_cfg {
287 const bool supports_idle; 292 const bool supports_idle;
288 bool adv_thermal_throttle; 293 bool adv_thermal_throttle;
289 bool support_ct_kill_exit; 294 bool support_ct_kill_exit;
290 u8 sm_ps_mode;
291 const bool support_wimax_coexist; 295 const bool support_wimax_coexist;
296 u8 plcp_delta_threshold;
297 s32 chain_noise_scale;
292}; 298};
293 299
294/*************************** 300/***************************
@@ -332,13 +338,11 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
332int iwl_commit_rxon(struct iwl_priv *priv); 338int iwl_commit_rxon(struct iwl_priv *priv);
333int iwl_set_mode(struct iwl_priv *priv, int mode); 339int iwl_set_mode(struct iwl_priv *priv, int mode);
334int iwl_mac_add_interface(struct ieee80211_hw *hw, 340int iwl_mac_add_interface(struct ieee80211_hw *hw,
335 struct ieee80211_if_init_conf *conf); 341 struct ieee80211_vif *vif);
336void iwl_mac_remove_interface(struct ieee80211_hw *hw, 342void iwl_mac_remove_interface(struct ieee80211_hw *hw,
337 struct ieee80211_if_init_conf *conf); 343 struct ieee80211_vif *vif);
338int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 344int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
339void iwl_config_ap(struct iwl_priv *priv); 345void iwl_config_ap(struct iwl_priv *priv);
340int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
341 struct ieee80211_tx_queue_stats *stats);
342void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 346void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
343int iwl_alloc_txq_mem(struct iwl_priv *priv); 347int iwl_alloc_txq_mem(struct iwl_priv *priv);
344void iwl_free_txq_mem(struct iwl_priv *priv); 348void iwl_free_txq_mem(struct iwl_priv *priv);
@@ -411,13 +415,13 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
411void iwl_cmd_queue_free(struct iwl_priv *priv); 415void iwl_cmd_queue_free(struct iwl_priv *priv);
412int iwl_rx_queue_alloc(struct iwl_priv *priv); 416int iwl_rx_queue_alloc(struct iwl_priv *priv);
413void iwl_rx_handle(struct iwl_priv *priv); 417void iwl_rx_handle(struct iwl_priv *priv);
414int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 418void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
415 struct iwl_rx_queue *q); 419 struct iwl_rx_queue *q);
416void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 420void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
417void iwl_rx_replenish(struct iwl_priv *priv); 421void iwl_rx_replenish(struct iwl_priv *priv);
418void iwl_rx_replenish_now(struct iwl_priv *priv); 422void iwl_rx_replenish_now(struct iwl_priv *priv);
419int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 423int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
420int iwl_rx_queue_restock(struct iwl_priv *priv); 424void iwl_rx_queue_restock(struct iwl_priv *priv);
421int iwl_rx_queue_space(const struct iwl_rx_queue *q); 425int iwl_rx_queue_space(const struct iwl_rx_queue *q);
422void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority); 426void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
423void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 427void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
@@ -425,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
425/* Handlers */ 429/* Handlers */
426void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 430void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
427 struct iwl_rx_mem_buffer *rxb); 431 struct iwl_rx_mem_buffer *rxb);
432void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb);
428void iwl_rx_statistics(struct iwl_priv *priv, 434void iwl_rx_statistics(struct iwl_priv *priv,
429 struct iwl_rx_mem_buffer *rxb); 435 struct iwl_rx_mem_buffer *rxb);
430void iwl_reply_statistics(struct iwl_priv *priv, 436void iwl_reply_statistics(struct iwl_priv *priv,
@@ -445,9 +451,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
445void iwl_hw_txq_ctx_free(struct iwl_priv *priv); 451void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
446int iwl_hw_tx_queue_init(struct iwl_priv *priv, 452int iwl_hw_tx_queue_init(struct iwl_priv *priv,
447 struct iwl_tx_queue *txq); 453 struct iwl_tx_queue *txq);
448int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
449void iwl_free_tfds_in_queue(struct iwl_priv *priv, 454void iwl_free_tfds_in_queue(struct iwl_priv *priv,
450 int sta_id, int tid, int freed); 455 int sta_id, int tid, int freed);
456void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
451int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 457int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
452 int slots_num, u32 txq_id); 458 int slots_num, u32 txq_id);
453void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 459void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
@@ -497,6 +503,8 @@ void iwl_init_scan_params(struct iwl_priv *priv);
497int iwl_scan_cancel(struct iwl_priv *priv); 503int iwl_scan_cancel(struct iwl_priv *priv);
498int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 504int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
499int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 505int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
506int iwl_internal_short_hw_scan(struct iwl_priv *priv);
507int iwl_force_reset(struct iwl_priv *priv, int mode);
500u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 508u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
501 const u8 *ie, int ie_len, int left); 509 const u8 *ie, int ie_len, int left);
502void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 510void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@ -527,14 +535,6 @@ int iwl_send_calib_results(struct iwl_priv *priv);
527int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); 535int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
528void iwl_calib_free_results(struct iwl_priv *priv); 536void iwl_calib_free_results(struct iwl_priv *priv);
529 537
530/*******************************************************************************
531 * Spectrum Measureemtns in iwl-spectrum.c
532 ******************************************************************************/
533#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
534void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
535#else
536static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
537#endif
538/***************************************************** 538/*****************************************************
539 * S e n d i n g H o s t C o m m a n d s * 539 * S e n d i n g H o s t C o m m a n d s *
540 *****************************************************/ 540 *****************************************************/
@@ -583,7 +583,10 @@ int iwl_pci_resume(struct pci_dev *pdev);
583* Error Handling Debugging 583* Error Handling Debugging
584******************************************************/ 584******************************************************/
585void iwl_dump_nic_error_log(struct iwl_priv *priv); 585void iwl_dump_nic_error_log(struct iwl_priv *priv);
586void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 586int iwl_dump_nic_event_log(struct iwl_priv *priv,
587 bool full_log, char **buf, bool display);
588void iwl_dump_csr(struct iwl_priv *priv);
589int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
587#ifdef CONFIG_IWLWIFI_DEBUG 590#ifdef CONFIG_IWLWIFI_DEBUG
588void iwl_print_rx_config_cmd(struct iwl_priv *priv); 591void iwl_print_rx_config_cmd(struct iwl_priv *priv);
589#else 592#else
@@ -603,7 +606,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
603/*************** DRIVER STATUS FUNCTIONS *****/ 606/*************** DRIVER STATUS FUNCTIONS *****/
604 607
605#define STATUS_HCMD_ACTIVE 0 /* host command in progress */ 608#define STATUS_HCMD_ACTIVE 0 /* host command in progress */
606#define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ 609/* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */
607#define STATUS_INT_ENABLED 2 610#define STATUS_INT_ENABLED 2
608#define STATUS_RF_KILL_HW 3 611#define STATUS_RF_KILL_HW 3
609#define STATUS_CT_KILL 4 612#define STATUS_CT_KILL 4
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 1ec8cb4d5eae..808b7146bead 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -369,7 +369,7 @@
369#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) 369#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
370#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) 370#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
371#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) 371#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
372 372#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
373 373
374/* GIO Chicken Bits (PCI Express bus link power management) */ 374/* GIO Chicken Bits (PCI Express bus link power management) */
375#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) 375#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d61293ab67c9..1c7b53d511c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -67,57 +67,6 @@ do { \
67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ 67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
68} while (0) 68} while (0)
69 69
70#ifdef CONFIG_IWLWIFI_DEBUGFS
71struct iwl_debugfs {
72 const char *name;
73 struct dentry *dir_drv;
74 struct dentry *dir_data;
75 struct dentry *dir_debug;
76 struct dentry *dir_rf;
77 struct dir_data_files {
78 struct dentry *file_sram;
79 struct dentry *file_nvm;
80 struct dentry *file_stations;
81 struct dentry *file_log_event;
82 struct dentry *file_channels;
83 struct dentry *file_status;
84 struct dentry *file_interrupt;
85 struct dentry *file_qos;
86 struct dentry *file_thermal_throttling;
87 struct dentry *file_led;
88 struct dentry *file_disable_ht40;
89 struct dentry *file_sleep_level_override;
90 struct dentry *file_current_sleep_command;
91 } dbgfs_data_files;
92 struct dir_rf_files {
93 struct dentry *file_disable_sensitivity;
94 struct dentry *file_disable_chain_noise;
95 struct dentry *file_disable_tx_power;
96 } dbgfs_rf_files;
97 struct dir_debug_files {
98 struct dentry *file_rx_statistics;
99 struct dentry *file_tx_statistics;
100 struct dentry *file_traffic_log;
101 struct dentry *file_rx_queue;
102 struct dentry *file_tx_queue;
103 struct dentry *file_ucode_rx_stats;
104 struct dentry *file_ucode_tx_stats;
105 struct dentry *file_ucode_general_stats;
106 struct dentry *file_sensitivity;
107 struct dentry *file_chain_noise;
108 struct dentry *file_tx_power;
109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_ucode_statistics;
111 struct dentry *file_clear_traffic_statistics;
112 } dbgfs_debug_files;
113 u32 sram_offset;
114 u32 sram_len;
115};
116
117int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
118void iwl_dbgfs_unregister(struct iwl_priv *priv);
119#endif
120
121#else 70#else
122#define IWL_DEBUG(__priv, level, fmt, args...) 71#define IWL_DEBUG(__priv, level, fmt, args...)
123#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) 72#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
@@ -126,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
126{} 75{}
127#endif /* CONFIG_IWLWIFI_DEBUG */ 76#endif /* CONFIG_IWLWIFI_DEBUG */
128 77
129 78#ifdef CONFIG_IWLWIFI_DEBUGFS
130 79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
131#ifndef CONFIG_IWLWIFI_DEBUGFS 80void iwl_dbgfs_unregister(struct iwl_priv *priv);
81#else
132static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 82static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
133{ 83{
134 return 0; 84 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 21e0f6699daf..7bf44f146799 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -41,43 +41,28 @@
41#include "iwl-calib.h" 41#include "iwl-calib.h"
42 42
43/* create and remove of files */ 43/* create and remove of files */
44#define DEBUGFS_ADD_DIR(name, parent) do { \ 44#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
45 dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ 45 if (!debugfs_create_file(#name, mode, parent, priv, \
46 if (!(dbgfs->dir_##name)) \ 46 &iwl_dbgfs_##name##_ops)) \
47 goto err; \ 47 goto err; \
48} while (0) 48} while (0)
49 49
50#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 50#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
51 dbgfs->dbgfs_##parent##_files.file_##name = \ 51 struct dentry *__tmp; \
52 debugfs_create_file(#name, mode, \ 52 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
53 dbgfs->dir_##parent, priv, \ 53 parent, ptr); \
54 &iwl_dbgfs_##name##_ops); \ 54 if (IS_ERR(__tmp) || !__tmp) \
55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 55 goto err; \
56 goto err; \
57} while (0) 56} while (0)
58 57
59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 58#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
60 dbgfs->dbgfs_##parent##_files.file_##name = \ 59 struct dentry *__tmp; \
61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 60 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
62 dbgfs->dir_##parent, ptr); \ 61 parent, ptr); \
63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 62 if (IS_ERR(__tmp) || !__tmp) \
64 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 63 goto err; \
65 goto err; \
66} while (0) 64} while (0)
67 65
68#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
69 dbgfs->dbgfs_##parent##_files.file_##name = \
70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \
71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
72 || !dbgfs->dbgfs_##parent##_files.file_##name) \
73 goto err; \
74} while (0)
75
76#define DEBUGFS_REMOVE(name) do { \
77 debugfs_remove(name); \
78 name = NULL; \
79} while (0);
80
81/* file operation */ 66/* file operation */
82#define DEBUGFS_READ_FUNC(name) \ 67#define DEBUGFS_READ_FUNC(name) \
83static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 68static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
@@ -125,7 +110,7 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
125 char __user *user_buf, 110 char __user *user_buf,
126 size_t count, loff_t *ppos) { 111 size_t count, loff_t *ppos) {
127 112
128 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 113 struct iwl_priv *priv = file->private_data;
129 char *buf; 114 char *buf;
130 int pos = 0; 115 int pos = 0;
131 116
@@ -184,7 +169,7 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
184 char __user *user_buf, 169 char __user *user_buf,
185 size_t count, loff_t *ppos) { 170 size_t count, loff_t *ppos) {
186 171
187 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 172 struct iwl_priv *priv = file->private_data;
188 char *buf; 173 char *buf;
189 int pos = 0; 174 int pos = 0;
190 int cnt; 175 int cnt;
@@ -232,28 +217,28 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
232 ssize_t ret; 217 ssize_t ret;
233 int i; 218 int i;
234 int pos = 0; 219 int pos = 0;
235 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 220 struct iwl_priv *priv = file->private_data;
236 size_t bufsz; 221 size_t bufsz;
237 222
238 /* default is to dump the entire data segment */ 223 /* default is to dump the entire data segment */
239 if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) { 224 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
240 priv->dbgfs->sram_offset = 0x800000; 225 priv->dbgfs_sram_offset = 0x800000;
241 if (priv->ucode_type == UCODE_INIT) 226 if (priv->ucode_type == UCODE_INIT)
242 priv->dbgfs->sram_len = priv->ucode_init_data.len; 227 priv->dbgfs_sram_len = priv->ucode_init_data.len;
243 else 228 else
244 priv->dbgfs->sram_len = priv->ucode_data.len; 229 priv->dbgfs_sram_len = priv->ucode_data.len;
245 } 230 }
246 bufsz = 30 + priv->dbgfs->sram_len * sizeof(char) * 10; 231 bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10;
247 buf = kmalloc(bufsz, GFP_KERNEL); 232 buf = kmalloc(bufsz, GFP_KERNEL);
248 if (!buf) 233 if (!buf)
249 return -ENOMEM; 234 return -ENOMEM;
250 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 235 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
251 priv->dbgfs->sram_len); 236 priv->dbgfs_sram_len);
252 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 237 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
253 priv->dbgfs->sram_offset); 238 priv->dbgfs_sram_offset);
254 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 239 for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
255 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 240 val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
256 priv->dbgfs->sram_len - i); 241 priv->dbgfs_sram_len - i);
257 if (i < 4) { 242 if (i < 4) {
258 switch (i) { 243 switch (i) {
259 case 1: 244 case 1:
@@ -293,11 +278,11 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
293 return -EFAULT; 278 return -EFAULT;
294 279
295 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 280 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
296 priv->dbgfs->sram_offset = offset; 281 priv->dbgfs_sram_offset = offset;
297 priv->dbgfs->sram_len = len; 282 priv->dbgfs_sram_len = len;
298 } else { 283 } else {
299 priv->dbgfs->sram_offset = 0; 284 priv->dbgfs_sram_offset = 0;
300 priv->dbgfs->sram_len = 0; 285 priv->dbgfs_sram_len = 0;
301 } 286 }
302 287
303 return count; 288 return count;
@@ -306,7 +291,7 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 291static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
307 size_t count, loff_t *ppos) 292 size_t count, loff_t *ppos)
308{ 293{
309 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 294 struct iwl_priv *priv = file->private_data;
310 struct iwl_station_entry *station; 295 struct iwl_station_entry *station;
311 int max_sta = priv->hw_params.max_stations; 296 int max_sta = priv->hw_params.max_stations;
312 char *buf; 297 char *buf;
@@ -376,7 +361,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
376 loff_t *ppos) 361 loff_t *ppos)
377{ 362{
378 ssize_t ret; 363 ssize_t ret;
379 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 364 struct iwl_priv *priv = file->private_data;
380 int pos = 0, ofs = 0, buf_size = 0; 365 int pos = 0, ofs = 0, buf_size = 0;
381 const u8 *ptr; 366 const u8 *ptr;
382 char *buf; 367 char *buf;
@@ -420,6 +405,24 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
420 return ret; 405 return ret;
421} 406}
422 407
408static ssize_t iwl_dbgfs_log_event_read(struct file *file,
409 char __user *user_buf,
410 size_t count, loff_t *ppos)
411{
412 struct iwl_priv *priv = file->private_data;
413 char *buf;
414 int pos = 0;
415 ssize_t ret = -ENOMEM;
416
417 ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
418 priv, true, &buf, true);
419 if (buf) {
420 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
421 kfree(buf);
422 }
423 return ret;
424}
425
423static ssize_t iwl_dbgfs_log_event_write(struct file *file, 426static ssize_t iwl_dbgfs_log_event_write(struct file *file,
424 const char __user *user_buf, 427 const char __user *user_buf,
425 size_t count, loff_t *ppos) 428 size_t count, loff_t *ppos)
@@ -436,7 +439,8 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
436 if (sscanf(buf, "%d", &event_log_flag) != 1) 439 if (sscanf(buf, "%d", &event_log_flag) != 1)
437 return -EFAULT; 440 return -EFAULT;
438 if (event_log_flag == 1) 441 if (event_log_flag == 1)
439 priv->cfg->ops->lib->dump_nic_event_log(priv, true); 442 priv->cfg->ops->lib->dump_nic_event_log(priv, true,
443 NULL, false);
440 444
441 return count; 445 return count;
442} 446}
@@ -446,7 +450,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
446static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 450static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
447 size_t count, loff_t *ppos) 451 size_t count, loff_t *ppos)
448{ 452{
449 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 453 struct iwl_priv *priv = file->private_data;
450 struct ieee80211_channel *channels = NULL; 454 struct ieee80211_channel *channels = NULL;
451 const struct ieee80211_supported_band *supp_band = NULL; 455 const struct ieee80211_supported_band *supp_band = NULL;
452 int pos = 0, i, bufsz = PAGE_SIZE; 456 int pos = 0, i, bufsz = PAGE_SIZE;
@@ -519,15 +523,13 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
519 char __user *user_buf, 523 char __user *user_buf,
520 size_t count, loff_t *ppos) { 524 size_t count, loff_t *ppos) {
521 525
522 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 526 struct iwl_priv *priv = file->private_data;
523 char buf[512]; 527 char buf[512];
524 int pos = 0; 528 int pos = 0;
525 const size_t bufsz = sizeof(buf); 529 const size_t bufsz = sizeof(buf);
526 530
527 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 531 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
528 test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 532 test_bit(STATUS_HCMD_ACTIVE, &priv->status));
529 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
530 test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
531 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 533 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
532 test_bit(STATUS_INT_ENABLED, &priv->status)); 534 test_bit(STATUS_INT_ENABLED, &priv->status));
533 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 535 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
@@ -567,7 +569,7 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
567 char __user *user_buf, 569 char __user *user_buf,
568 size_t count, loff_t *ppos) { 570 size_t count, loff_t *ppos) {
569 571
570 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 572 struct iwl_priv *priv = file->private_data;
571 int pos = 0; 573 int pos = 0;
572 int cnt = 0; 574 int cnt = 0;
573 char *buf; 575 char *buf;
@@ -654,7 +656,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
654static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 656static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
655 size_t count, loff_t *ppos) 657 size_t count, loff_t *ppos)
656{ 658{
657 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 659 struct iwl_priv *priv = file->private_data;
658 int pos = 0, i; 660 int pos = 0, i;
659 char buf[256]; 661 char buf[256];
660 const size_t bufsz = sizeof(buf); 662 const size_t bufsz = sizeof(buf);
@@ -677,7 +679,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
677static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 679static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
678 size_t count, loff_t *ppos) 680 size_t count, loff_t *ppos)
679{ 681{
680 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 682 struct iwl_priv *priv = file->private_data;
681 int pos = 0; 683 int pos = 0;
682 char buf[256]; 684 char buf[256];
683 const size_t bufsz = sizeof(buf); 685 const size_t bufsz = sizeof(buf);
@@ -703,7 +705,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
703 char __user *user_buf, 705 char __user *user_buf,
704 size_t count, loff_t *ppos) 706 size_t count, loff_t *ppos)
705{ 707{
706 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 708 struct iwl_priv *priv = file->private_data;
707 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 709 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
708 struct iwl_tt_restriction *restriction; 710 struct iwl_tt_restriction *restriction;
709 char buf[100]; 711 char buf[100];
@@ -763,7 +765,7 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
763 char __user *user_buf, 765 char __user *user_buf,
764 size_t count, loff_t *ppos) 766 size_t count, loff_t *ppos)
765{ 767{
766 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 768 struct iwl_priv *priv = file->private_data;
767 char buf[100]; 769 char buf[100];
768 int pos = 0; 770 int pos = 0;
769 const size_t bufsz = sizeof(buf); 771 const size_t bufsz = sizeof(buf);
@@ -811,7 +813,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
811 813
812 priv->power_data.debug_sleep_level_override = value; 814 priv->power_data.debug_sleep_level_override = value;
813 815
816 mutex_lock(&priv->mutex);
814 iwl_power_update_mode(priv, true); 817 iwl_power_update_mode(priv, true);
818 mutex_unlock(&priv->mutex);
815 819
816 return count; 820 return count;
817} 821}
@@ -820,7 +824,7 @@ static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
820 char __user *user_buf, 824 char __user *user_buf,
821 size_t count, loff_t *ppos) 825 size_t count, loff_t *ppos)
822{ 826{
823 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 827 struct iwl_priv *priv = file->private_data;
824 char buf[10]; 828 char buf[10];
825 int pos, value; 829 int pos, value;
826 const size_t bufsz = sizeof(buf); 830 const size_t bufsz = sizeof(buf);
@@ -838,7 +842,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
838 char __user *user_buf, 842 char __user *user_buf,
839 size_t count, loff_t *ppos) 843 size_t count, loff_t *ppos)
840{ 844{
841 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 845 struct iwl_priv *priv = file->private_data;
842 char buf[200]; 846 char buf[200];
843 int pos = 0, i; 847 int pos = 0, i;
844 const size_t bufsz = sizeof(buf); 848 const size_t bufsz = sizeof(buf);
@@ -859,7 +863,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
859} 863}
860 864
861DEBUGFS_READ_WRITE_FILE_OPS(sram); 865DEBUGFS_READ_WRITE_FILE_OPS(sram);
862DEBUGFS_WRITE_FILE_OPS(log_event); 866DEBUGFS_READ_WRITE_FILE_OPS(log_event);
863DEBUGFS_READ_FILE_OPS(nvm); 867DEBUGFS_READ_FILE_OPS(nvm);
864DEBUGFS_READ_FILE_OPS(stations); 868DEBUGFS_READ_FILE_OPS(stations);
865DEBUGFS_READ_FILE_OPS(channels); 869DEBUGFS_READ_FILE_OPS(channels);
@@ -976,7 +980,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
976 char __user *user_buf, 980 char __user *user_buf,
977 size_t count, loff_t *ppos) { 981 size_t count, loff_t *ppos) {
978 982
979 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 983 struct iwl_priv *priv = file->private_data;
980 struct iwl_tx_queue *txq; 984 struct iwl_tx_queue *txq;
981 struct iwl_queue *q; 985 struct iwl_queue *q;
982 char *buf; 986 char *buf;
@@ -1022,7 +1026,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1022 char __user *user_buf, 1026 char __user *user_buf,
1023 size_t count, loff_t *ppos) { 1027 size_t count, loff_t *ppos) {
1024 1028
1025 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1029 struct iwl_priv *priv = file->private_data;
1026 struct iwl_rx_queue *rxq = &priv->rxq; 1030 struct iwl_rx_queue *rxq = &priv->rxq;
1027 char buf[256]; 1031 char buf[256];
1028 int pos = 0; 1032 int pos = 0;
@@ -1063,36 +1067,33 @@ static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1063 return p; 1067 return p;
1064} 1068}
1065 1069
1070static const char ucode_stats_header[] =
1071 "%-32s current acumulative delta max\n";
1072static const char ucode_stats_short_format[] =
1073 " %-30s %10u\n";
1074static const char ucode_stats_format[] =
1075 " %-30s %10u %10u %10u %10u\n";
1066 1076
1067static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1077static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1068 char __user *user_buf, 1078 char __user *user_buf,
1069 size_t count, loff_t *ppos) 1079 size_t count, loff_t *ppos)
1070{ 1080{
1071 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1081 struct iwl_priv *priv = file->private_data;
1072 int pos = 0; 1082 int pos = 0;
1073 char *buf; 1083 char *buf;
1074 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1084 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1075 sizeof(struct statistics_rx_non_phy) * 20 + 1085 sizeof(struct statistics_rx_non_phy) * 40 +
1076 sizeof(struct statistics_rx_ht_phy) * 20 + 400; 1086 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1077 ssize_t ret; 1087 ssize_t ret;
1078 struct statistics_rx_phy *ofdm, *accum_ofdm; 1088 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1079 struct statistics_rx_phy *cck, *accum_cck; 1089 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1080 struct statistics_rx_non_phy *general, *accum_general; 1090 struct statistics_rx_non_phy *general, *accum_general;
1081 struct statistics_rx_ht_phy *ht, *accum_ht; 1091 struct statistics_rx_non_phy *delta_general, *max_general;
1092 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1082 1093
1083 if (!iwl_is_alive(priv)) 1094 if (!iwl_is_alive(priv))
1084 return -EAGAIN; 1095 return -EAGAIN;
1085 1096
1086 /* make request to uCode to retrieve statistics information */
1087 mutex_lock(&priv->mutex);
1088 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1089 mutex_unlock(&priv->mutex);
1090
1091 if (ret) {
1092 IWL_ERR(priv,
1093 "Error sending statistics request: %zd\n", ret);
1094 return -EAGAIN;
1095 }
1096 buf = kzalloc(bufsz, GFP_KERNEL); 1097 buf = kzalloc(bufsz, GFP_KERNEL);
1097 if (!buf) { 1098 if (!buf) {
1098 IWL_ERR(priv, "Can not allocate Buffer\n"); 1099 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1111,264 +1112,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1111 accum_cck = &priv->accum_statistics.rx.cck; 1112 accum_cck = &priv->accum_statistics.rx.cck;
1112 accum_general = &priv->accum_statistics.rx.general; 1113 accum_general = &priv->accum_statistics.rx.general;
1113 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 1114 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1115 delta_ofdm = &priv->delta_statistics.rx.ofdm;
1116 delta_cck = &priv->delta_statistics.rx.cck;
1117 delta_general = &priv->delta_statistics.rx.general;
1118 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1119 max_ofdm = &priv->max_delta.rx.ofdm;
1120 max_cck = &priv->max_delta.rx.cck;
1121 max_general = &priv->max_delta.rx.general;
1122 max_ht = &priv->max_delta.rx.ofdm_ht;
1123
1114 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1124 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1115 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); 1125 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1116 pos += scnprintf(buf + pos, bufsz - pos, 1126 "Statistics_Rx - OFDM:");
1117 "\t\t\tcurrent\t\t\taccumulative\n"); 1127 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1118 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1128 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1119 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); 1129 accum_ofdm->ina_cnt,
1120 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1130 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1121 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); 1131 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1122 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1132 "fina_cnt:",
1123 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); 1133 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1124 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1134 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1125 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); 1135 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1126 pos += scnprintf(buf + pos, bufsz - pos, 1136 "plcp_err:",
1127 "overrun_err:\t\t%u\t\t\t%u\n", 1137 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1138 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1139 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1140 "crc32_err:",
1141 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1142 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1143 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1144 "overrun_err:",
1128 le32_to_cpu(ofdm->overrun_err), 1145 le32_to_cpu(ofdm->overrun_err),
1129 accum_ofdm->overrun_err); 1146 accum_ofdm->overrun_err,
1130 pos += scnprintf(buf + pos, bufsz - pos, 1147 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1131 "early_overrun_err:\t%u\t\t\t%u\n", 1148 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1149 "early_overrun_err:",
1132 le32_to_cpu(ofdm->early_overrun_err), 1150 le32_to_cpu(ofdm->early_overrun_err),
1133 accum_ofdm->early_overrun_err); 1151 accum_ofdm->early_overrun_err,
1134 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1152 delta_ofdm->early_overrun_err,
1153 max_ofdm->early_overrun_err);
1154 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1155 "crc32_good:",
1135 le32_to_cpu(ofdm->crc32_good), 1156 le32_to_cpu(ofdm->crc32_good),
1136 accum_ofdm->crc32_good); 1157 accum_ofdm->crc32_good,
1137 pos += scnprintf(buf + pos, bufsz - pos, 1158 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1138 "false_alarm_cnt:\t%u\t\t\t%u\n", 1159 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1160 "false_alarm_cnt:",
1139 le32_to_cpu(ofdm->false_alarm_cnt), 1161 le32_to_cpu(ofdm->false_alarm_cnt),
1140 accum_ofdm->false_alarm_cnt); 1162 accum_ofdm->false_alarm_cnt,
1141 pos += scnprintf(buf + pos, bufsz - pos, 1163 delta_ofdm->false_alarm_cnt,
1142 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1164 max_ofdm->false_alarm_cnt);
1165 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1166 "fina_sync_err_cnt:",
1143 le32_to_cpu(ofdm->fina_sync_err_cnt), 1167 le32_to_cpu(ofdm->fina_sync_err_cnt),
1144 accum_ofdm->fina_sync_err_cnt); 1168 accum_ofdm->fina_sync_err_cnt,
1145 pos += scnprintf(buf + pos, bufsz - pos, 1169 delta_ofdm->fina_sync_err_cnt,
1146 "sfd_timeout:\t\t%u\t\t\t%u\n", 1170 max_ofdm->fina_sync_err_cnt);
1171 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1172 "sfd_timeout:",
1147 le32_to_cpu(ofdm->sfd_timeout), 1173 le32_to_cpu(ofdm->sfd_timeout),
1148 accum_ofdm->sfd_timeout); 1174 accum_ofdm->sfd_timeout,
1149 pos += scnprintf(buf + pos, bufsz - pos, 1175 delta_ofdm->sfd_timeout,
1150 "fina_timeout:\t\t%u\t\t\t%u\n", 1176 max_ofdm->sfd_timeout);
1177 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1178 "fina_timeout:",
1151 le32_to_cpu(ofdm->fina_timeout), 1179 le32_to_cpu(ofdm->fina_timeout),
1152 accum_ofdm->fina_timeout); 1180 accum_ofdm->fina_timeout,
1153 pos += scnprintf(buf + pos, bufsz - pos, 1181 delta_ofdm->fina_timeout,
1154 "unresponded_rts:\t%u\t\t\t%u\n", 1182 max_ofdm->fina_timeout);
1183 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1184 "unresponded_rts:",
1155 le32_to_cpu(ofdm->unresponded_rts), 1185 le32_to_cpu(ofdm->unresponded_rts),
1156 accum_ofdm->unresponded_rts); 1186 accum_ofdm->unresponded_rts,
1157 pos += scnprintf(buf + pos, bufsz - pos, 1187 delta_ofdm->unresponded_rts,
1158 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1188 max_ofdm->unresponded_rts);
1189 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1190 "rxe_frame_lmt_ovrun:",
1159 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1191 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1160 accum_ofdm->rxe_frame_limit_overrun); 1192 accum_ofdm->rxe_frame_limit_overrun,
1161 pos += scnprintf(buf + pos, bufsz - pos, 1193 delta_ofdm->rxe_frame_limit_overrun,
1162 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1194 max_ofdm->rxe_frame_limit_overrun);
1195 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1196 "sent_ack_cnt:",
1163 le32_to_cpu(ofdm->sent_ack_cnt), 1197 le32_to_cpu(ofdm->sent_ack_cnt),
1164 accum_ofdm->sent_ack_cnt); 1198 accum_ofdm->sent_ack_cnt,
1165 pos += scnprintf(buf + pos, bufsz - pos, 1199 delta_ofdm->sent_ack_cnt,
1166 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1200 max_ofdm->sent_ack_cnt);
1201 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1202 "sent_cts_cnt:",
1167 le32_to_cpu(ofdm->sent_cts_cnt), 1203 le32_to_cpu(ofdm->sent_cts_cnt),
1168 accum_ofdm->sent_cts_cnt); 1204 accum_ofdm->sent_cts_cnt,
1169 pos += scnprintf(buf + pos, bufsz - pos, 1205 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1170 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1206 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1207 "sent_ba_rsp_cnt:",
1171 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1208 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1172 accum_ofdm->sent_ba_rsp_cnt); 1209 accum_ofdm->sent_ba_rsp_cnt,
1173 pos += scnprintf(buf + pos, bufsz - pos, 1210 delta_ofdm->sent_ba_rsp_cnt,
1174 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1211 max_ofdm->sent_ba_rsp_cnt);
1212 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1213 "dsp_self_kill:",
1175 le32_to_cpu(ofdm->dsp_self_kill), 1214 le32_to_cpu(ofdm->dsp_self_kill),
1176 accum_ofdm->dsp_self_kill); 1215 accum_ofdm->dsp_self_kill,
1177 pos += scnprintf(buf + pos, bufsz - pos, 1216 delta_ofdm->dsp_self_kill,
1178 "mh_format_err:\t\t%u\t\t\t%u\n", 1217 max_ofdm->dsp_self_kill);
1218 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1219 "mh_format_err:",
1179 le32_to_cpu(ofdm->mh_format_err), 1220 le32_to_cpu(ofdm->mh_format_err),
1180 accum_ofdm->mh_format_err); 1221 accum_ofdm->mh_format_err,
1181 pos += scnprintf(buf + pos, bufsz - pos, 1222 delta_ofdm->mh_format_err,
1182 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1223 max_ofdm->mh_format_err);
1224 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1225 "re_acq_main_rssi_sum:",
1183 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1226 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1184 accum_ofdm->re_acq_main_rssi_sum); 1227 accum_ofdm->re_acq_main_rssi_sum,
1185 1228 delta_ofdm->re_acq_main_rssi_sum,
1186 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); 1229 max_ofdm->re_acq_main_rssi_sum);
1187 pos += scnprintf(buf + pos, bufsz - pos, 1230
1188 "\t\t\tcurrent\t\t\taccumulative\n"); 1231 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1189 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1232 "Statistics_Rx - CCK:");
1190 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); 1233 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1191 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1234 "ina_cnt:",
1192 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); 1235 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1193 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1236 delta_cck->ina_cnt, max_cck->ina_cnt);
1194 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); 1237 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1195 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1238 "fina_cnt:",
1196 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); 1239 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1197 pos += scnprintf(buf + pos, bufsz - pos, 1240 delta_cck->fina_cnt, max_cck->fina_cnt);
1198 "overrun_err:\t\t%u\t\t\t%u\n", 1241 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1242 "plcp_err:",
1243 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1244 delta_cck->plcp_err, max_cck->plcp_err);
1245 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1246 "crc32_err:",
1247 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1248 delta_cck->crc32_err, max_cck->crc32_err);
1249 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1250 "overrun_err:",
1199 le32_to_cpu(cck->overrun_err), 1251 le32_to_cpu(cck->overrun_err),
1200 accum_cck->overrun_err); 1252 accum_cck->overrun_err,
1201 pos += scnprintf(buf + pos, bufsz - pos, 1253 delta_cck->overrun_err, max_cck->overrun_err);
1202 "early_overrun_err:\t%u\t\t\t%u\n", 1254 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1255 "early_overrun_err:",
1203 le32_to_cpu(cck->early_overrun_err), 1256 le32_to_cpu(cck->early_overrun_err),
1204 accum_cck->early_overrun_err); 1257 accum_cck->early_overrun_err,
1205 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1258 delta_cck->early_overrun_err,
1206 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); 1259 max_cck->early_overrun_err);
1207 pos += scnprintf(buf + pos, bufsz - pos, 1260 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1208 "false_alarm_cnt:\t%u\t\t\t%u\n", 1261 "crc32_good:",
1262 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1263 delta_cck->crc32_good,
1264 max_cck->crc32_good);
1265 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1266 "false_alarm_cnt:",
1209 le32_to_cpu(cck->false_alarm_cnt), 1267 le32_to_cpu(cck->false_alarm_cnt),
1210 accum_cck->false_alarm_cnt); 1268 accum_cck->false_alarm_cnt,
1211 pos += scnprintf(buf + pos, bufsz - pos, 1269 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1212 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1270 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1271 "fina_sync_err_cnt:",
1213 le32_to_cpu(cck->fina_sync_err_cnt), 1272 le32_to_cpu(cck->fina_sync_err_cnt),
1214 accum_cck->fina_sync_err_cnt); 1273 accum_cck->fina_sync_err_cnt,
1215 pos += scnprintf(buf + pos, bufsz - pos, 1274 delta_cck->fina_sync_err_cnt,
1216 "sfd_timeout:\t\t%u\t\t\t%u\n", 1275 max_cck->fina_sync_err_cnt);
1276 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1277 "sfd_timeout:",
1217 le32_to_cpu(cck->sfd_timeout), 1278 le32_to_cpu(cck->sfd_timeout),
1218 accum_cck->sfd_timeout); 1279 accum_cck->sfd_timeout,
1219 pos += scnprintf(buf + pos, bufsz - pos, 1280 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1220 "fina_timeout:\t\t%u\t\t\t%u\n", 1281 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1282 "fina_timeout:",
1221 le32_to_cpu(cck->fina_timeout), 1283 le32_to_cpu(cck->fina_timeout),
1222 accum_cck->fina_timeout); 1284 accum_cck->fina_timeout,
1223 pos += scnprintf(buf + pos, bufsz - pos, 1285 delta_cck->fina_timeout, max_cck->fina_timeout);
1224 "unresponded_rts:\t%u\t\t\t%u\n", 1286 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1287 "unresponded_rts:",
1225 le32_to_cpu(cck->unresponded_rts), 1288 le32_to_cpu(cck->unresponded_rts),
1226 accum_cck->unresponded_rts); 1289 accum_cck->unresponded_rts,
1227 pos += scnprintf(buf + pos, bufsz - pos, 1290 delta_cck->unresponded_rts,
1228 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1291 max_cck->unresponded_rts);
1292 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1293 "rxe_frame_lmt_ovrun:",
1229 le32_to_cpu(cck->rxe_frame_limit_overrun), 1294 le32_to_cpu(cck->rxe_frame_limit_overrun),
1230 accum_cck->rxe_frame_limit_overrun); 1295 accum_cck->rxe_frame_limit_overrun,
1231 pos += scnprintf(buf + pos, bufsz - pos, 1296 delta_cck->rxe_frame_limit_overrun,
1232 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1297 max_cck->rxe_frame_limit_overrun);
1298 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1299 "sent_ack_cnt:",
1233 le32_to_cpu(cck->sent_ack_cnt), 1300 le32_to_cpu(cck->sent_ack_cnt),
1234 accum_cck->sent_ack_cnt); 1301 accum_cck->sent_ack_cnt,
1235 pos += scnprintf(buf + pos, bufsz - pos, 1302 delta_cck->sent_ack_cnt,
1236 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1303 max_cck->sent_ack_cnt);
1304 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1305 "sent_cts_cnt:",
1237 le32_to_cpu(cck->sent_cts_cnt), 1306 le32_to_cpu(cck->sent_cts_cnt),
1238 accum_cck->sent_cts_cnt); 1307 accum_cck->sent_cts_cnt,
1239 pos += scnprintf(buf + pos, bufsz - pos, 1308 delta_cck->sent_cts_cnt,
1240 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1309 max_cck->sent_cts_cnt);
1310 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1311 "sent_ba_rsp_cnt:",
1241 le32_to_cpu(cck->sent_ba_rsp_cnt), 1312 le32_to_cpu(cck->sent_ba_rsp_cnt),
1242 accum_cck->sent_ba_rsp_cnt); 1313 accum_cck->sent_ba_rsp_cnt,
1243 pos += scnprintf(buf + pos, bufsz - pos, 1314 delta_cck->sent_ba_rsp_cnt,
1244 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1315 max_cck->sent_ba_rsp_cnt);
1316 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1317 "dsp_self_kill:",
1245 le32_to_cpu(cck->dsp_self_kill), 1318 le32_to_cpu(cck->dsp_self_kill),
1246 accum_cck->dsp_self_kill); 1319 accum_cck->dsp_self_kill,
1247 pos += scnprintf(buf + pos, bufsz - pos, 1320 delta_cck->dsp_self_kill,
1248 "mh_format_err:\t\t%u\t\t\t%u\n", 1321 max_cck->dsp_self_kill);
1322 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1323 "mh_format_err:",
1249 le32_to_cpu(cck->mh_format_err), 1324 le32_to_cpu(cck->mh_format_err),
1250 accum_cck->mh_format_err); 1325 accum_cck->mh_format_err,
1251 pos += scnprintf(buf + pos, bufsz - pos, 1326 delta_cck->mh_format_err, max_cck->mh_format_err);
1252 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1327 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1328 "re_acq_main_rssi_sum:",
1253 le32_to_cpu(cck->re_acq_main_rssi_sum), 1329 le32_to_cpu(cck->re_acq_main_rssi_sum),
1254 accum_cck->re_acq_main_rssi_sum); 1330 accum_cck->re_acq_main_rssi_sum,
1255 1331 delta_cck->re_acq_main_rssi_sum,
1256 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); 1332 max_cck->re_acq_main_rssi_sum);
1257 pos += scnprintf(buf + pos, bufsz - pos, 1333
1258 "\t\t\tcurrent\t\t\taccumulative\n"); 1334 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1259 pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", 1335 "Statistics_Rx - GENERAL:");
1336 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1337 "bogus_cts:",
1260 le32_to_cpu(general->bogus_cts), 1338 le32_to_cpu(general->bogus_cts),
1261 accum_general->bogus_cts); 1339 accum_general->bogus_cts,
1262 pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", 1340 delta_general->bogus_cts, max_general->bogus_cts);
1341 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1342 "bogus_ack:",
1263 le32_to_cpu(general->bogus_ack), 1343 le32_to_cpu(general->bogus_ack),
1264 accum_general->bogus_ack); 1344 accum_general->bogus_ack,
1265 pos += scnprintf(buf + pos, bufsz - pos, 1345 delta_general->bogus_ack, max_general->bogus_ack);
1266 "non_bssid_frames:\t%u\t\t\t%u\n", 1346 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1347 "non_bssid_frames:",
1267 le32_to_cpu(general->non_bssid_frames), 1348 le32_to_cpu(general->non_bssid_frames),
1268 accum_general->non_bssid_frames); 1349 accum_general->non_bssid_frames,
1269 pos += scnprintf(buf + pos, bufsz - pos, 1350 delta_general->non_bssid_frames,
1270 "filtered_frames:\t%u\t\t\t%u\n", 1351 max_general->non_bssid_frames);
1352 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1353 "filtered_frames:",
1271 le32_to_cpu(general->filtered_frames), 1354 le32_to_cpu(general->filtered_frames),
1272 accum_general->filtered_frames); 1355 accum_general->filtered_frames,
1273 pos += scnprintf(buf + pos, bufsz - pos, 1356 delta_general->filtered_frames,
1274 "non_channel_beacons:\t%u\t\t\t%u\n", 1357 max_general->filtered_frames);
1358 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1359 "non_channel_beacons:",
1275 le32_to_cpu(general->non_channel_beacons), 1360 le32_to_cpu(general->non_channel_beacons),
1276 accum_general->non_channel_beacons); 1361 accum_general->non_channel_beacons,
1277 pos += scnprintf(buf + pos, bufsz - pos, 1362 delta_general->non_channel_beacons,
1278 "channel_beacons:\t%u\t\t\t%u\n", 1363 max_general->non_channel_beacons);
1364 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1365 "channel_beacons:",
1279 le32_to_cpu(general->channel_beacons), 1366 le32_to_cpu(general->channel_beacons),
1280 accum_general->channel_beacons); 1367 accum_general->channel_beacons,
1281 pos += scnprintf(buf + pos, bufsz - pos, 1368 delta_general->channel_beacons,
1282 "num_missed_bcon:\t%u\t\t\t%u\n", 1369 max_general->channel_beacons);
1370 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1371 "num_missed_bcon:",
1283 le32_to_cpu(general->num_missed_bcon), 1372 le32_to_cpu(general->num_missed_bcon),
1284 accum_general->num_missed_bcon); 1373 accum_general->num_missed_bcon,
1285 pos += scnprintf(buf + pos, bufsz - pos, 1374 delta_general->num_missed_bcon,
1286 "adc_rx_saturation_time:\t%u\t\t\t%u\n", 1375 max_general->num_missed_bcon);
1376 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1377 "adc_rx_saturation_time:",
1287 le32_to_cpu(general->adc_rx_saturation_time), 1378 le32_to_cpu(general->adc_rx_saturation_time),
1288 accum_general->adc_rx_saturation_time); 1379 accum_general->adc_rx_saturation_time,
1289 pos += scnprintf(buf + pos, bufsz - pos, 1380 delta_general->adc_rx_saturation_time,
1290 "ina_detect_search_tm:\t%u\t\t\t%u\n", 1381 max_general->adc_rx_saturation_time);
1382 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1383 "ina_detect_search_tm:",
1291 le32_to_cpu(general->ina_detection_search_time), 1384 le32_to_cpu(general->ina_detection_search_time),
1292 accum_general->ina_detection_search_time); 1385 accum_general->ina_detection_search_time,
1293 pos += scnprintf(buf + pos, bufsz - pos, 1386 delta_general->ina_detection_search_time,
1294 "beacon_silence_rssi_a:\t%u\t\t\t%u\n", 1387 max_general->ina_detection_search_time);
1388 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1389 "beacon_silence_rssi_a:",
1295 le32_to_cpu(general->beacon_silence_rssi_a), 1390 le32_to_cpu(general->beacon_silence_rssi_a),
1296 accum_general->beacon_silence_rssi_a); 1391 accum_general->beacon_silence_rssi_a,
1297 pos += scnprintf(buf + pos, bufsz - pos, 1392 delta_general->beacon_silence_rssi_a,
1298 "beacon_silence_rssi_b:\t%u\t\t\t%u\n", 1393 max_general->beacon_silence_rssi_a);
1394 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1395 "beacon_silence_rssi_b:",
1299 le32_to_cpu(general->beacon_silence_rssi_b), 1396 le32_to_cpu(general->beacon_silence_rssi_b),
1300 accum_general->beacon_silence_rssi_b); 1397 accum_general->beacon_silence_rssi_b,
1301 pos += scnprintf(buf + pos, bufsz - pos, 1398 delta_general->beacon_silence_rssi_b,
1302 "beacon_silence_rssi_c:\t%u\t\t\t%u\n", 1399 max_general->beacon_silence_rssi_b);
1400 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1401 "beacon_silence_rssi_c:",
1303 le32_to_cpu(general->beacon_silence_rssi_c), 1402 le32_to_cpu(general->beacon_silence_rssi_c),
1304 accum_general->beacon_silence_rssi_c); 1403 accum_general->beacon_silence_rssi_c,
1305 pos += scnprintf(buf + pos, bufsz - pos, 1404 delta_general->beacon_silence_rssi_c,
1306 "interference_data_flag:\t%u\t\t\t%u\n", 1405 max_general->beacon_silence_rssi_c);
1406 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1407 "interference_data_flag:",
1307 le32_to_cpu(general->interference_data_flag), 1408 le32_to_cpu(general->interference_data_flag),
1308 accum_general->interference_data_flag); 1409 accum_general->interference_data_flag,
1309 pos += scnprintf(buf + pos, bufsz - pos, 1410 delta_general->interference_data_flag,
1310 "channel_load:\t\t%u\t\t\t%u\n", 1411 max_general->interference_data_flag);
1412 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1413 "channel_load:",
1311 le32_to_cpu(general->channel_load), 1414 le32_to_cpu(general->channel_load),
1312 accum_general->channel_load); 1415 accum_general->channel_load,
1313 pos += scnprintf(buf + pos, bufsz - pos, 1416 delta_general->channel_load,
1314 "dsp_false_alarms:\t%u\t\t\t%u\n", 1417 max_general->channel_load);
1418 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1419 "dsp_false_alarms:",
1315 le32_to_cpu(general->dsp_false_alarms), 1420 le32_to_cpu(general->dsp_false_alarms),
1316 accum_general->dsp_false_alarms); 1421 accum_general->dsp_false_alarms,
1317 pos += scnprintf(buf + pos, bufsz - pos, 1422 delta_general->dsp_false_alarms,
1318 "beacon_rssi_a:\t\t%u\t\t\t%u\n", 1423 max_general->dsp_false_alarms);
1424 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1425 "beacon_rssi_a:",
1319 le32_to_cpu(general->beacon_rssi_a), 1426 le32_to_cpu(general->beacon_rssi_a),
1320 accum_general->beacon_rssi_a); 1427 accum_general->beacon_rssi_a,
1321 pos += scnprintf(buf + pos, bufsz - pos, 1428 delta_general->beacon_rssi_a,
1322 "beacon_rssi_b:\t\t%u\t\t\t%u\n", 1429 max_general->beacon_rssi_a);
1430 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1431 "beacon_rssi_b:",
1323 le32_to_cpu(general->beacon_rssi_b), 1432 le32_to_cpu(general->beacon_rssi_b),
1324 accum_general->beacon_rssi_b); 1433 accum_general->beacon_rssi_b,
1325 pos += scnprintf(buf + pos, bufsz - pos, 1434 delta_general->beacon_rssi_b,
1326 "beacon_rssi_c:\t\t%u\t\t\t%u\n", 1435 max_general->beacon_rssi_b);
1436 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1437 "beacon_rssi_c:",
1327 le32_to_cpu(general->beacon_rssi_c), 1438 le32_to_cpu(general->beacon_rssi_c),
1328 accum_general->beacon_rssi_c); 1439 accum_general->beacon_rssi_c,
1329 pos += scnprintf(buf + pos, bufsz - pos, 1440 delta_general->beacon_rssi_c,
1330 "beacon_energy_a:\t%u\t\t\t%u\n", 1441 max_general->beacon_rssi_c);
1442 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1443 "beacon_energy_a:",
1331 le32_to_cpu(general->beacon_energy_a), 1444 le32_to_cpu(general->beacon_energy_a),
1332 accum_general->beacon_energy_a); 1445 accum_general->beacon_energy_a,
1333 pos += scnprintf(buf + pos, bufsz - pos, 1446 delta_general->beacon_energy_a,
1334 "beacon_energy_b:\t%u\t\t\t%u\n", 1447 max_general->beacon_energy_a);
1448 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1449 "beacon_energy_b:",
1335 le32_to_cpu(general->beacon_energy_b), 1450 le32_to_cpu(general->beacon_energy_b),
1336 accum_general->beacon_energy_b); 1451 accum_general->beacon_energy_b,
1337 pos += scnprintf(buf + pos, bufsz - pos, 1452 delta_general->beacon_energy_b,
1338 "beacon_energy_c:\t%u\t\t\t%u\n", 1453 max_general->beacon_energy_b);
1454 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1455 "beacon_energy_c:",
1339 le32_to_cpu(general->beacon_energy_c), 1456 le32_to_cpu(general->beacon_energy_c),
1340 accum_general->beacon_energy_c); 1457 accum_general->beacon_energy_c,
1458 delta_general->beacon_energy_c,
1459 max_general->beacon_energy_c);
1341 1460
1342 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); 1461 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1343 pos += scnprintf(buf + pos, bufsz - pos, 1462 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1344 "\t\t\tcurrent\t\t\taccumulative\n"); 1463 "Statistics_Rx - OFDM_HT:");
1345 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1464 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1346 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); 1465 "plcp_err:",
1347 pos += scnprintf(buf + pos, bufsz - pos, 1466 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1348 "overrun_err:\t\t%u\t\t\t%u\n", 1467 delta_ht->plcp_err, max_ht->plcp_err);
1349 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); 1468 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1350 pos += scnprintf(buf + pos, bufsz - pos, 1469 "overrun_err:",
1351 "early_overrun_err:\t%u\t\t\t%u\n", 1470 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1471 delta_ht->overrun_err, max_ht->overrun_err);
1472 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1473 "early_overrun_err:",
1352 le32_to_cpu(ht->early_overrun_err), 1474 le32_to_cpu(ht->early_overrun_err),
1353 accum_ht->early_overrun_err); 1475 accum_ht->early_overrun_err,
1354 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1476 delta_ht->early_overrun_err,
1355 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); 1477 max_ht->early_overrun_err);
1356 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1478 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1357 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); 1479 "crc32_good:",
1358 pos += scnprintf(buf + pos, bufsz - pos, 1480 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1359 "mh_format_err:\t\t%u\t\t\t%u\n", 1481 delta_ht->crc32_good, max_ht->crc32_good);
1482 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1483 "crc32_err:",
1484 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1485 delta_ht->crc32_err, max_ht->crc32_err);
1486 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1487 "mh_format_err:",
1360 le32_to_cpu(ht->mh_format_err), 1488 le32_to_cpu(ht->mh_format_err),
1361 accum_ht->mh_format_err); 1489 accum_ht->mh_format_err,
1362 pos += scnprintf(buf + pos, bufsz - pos, 1490 delta_ht->mh_format_err, max_ht->mh_format_err);
1363 "agg_crc32_good:\t\t%u\t\t\t%u\n", 1491 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1492 "agg_crc32_good:",
1364 le32_to_cpu(ht->agg_crc32_good), 1493 le32_to_cpu(ht->agg_crc32_good),
1365 accum_ht->agg_crc32_good); 1494 accum_ht->agg_crc32_good,
1366 pos += scnprintf(buf + pos, bufsz - pos, 1495 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1367 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", 1496 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1497 "agg_mpdu_cnt:",
1368 le32_to_cpu(ht->agg_mpdu_cnt), 1498 le32_to_cpu(ht->agg_mpdu_cnt),
1369 accum_ht->agg_mpdu_cnt); 1499 accum_ht->agg_mpdu_cnt,
1370 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1500 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1371 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1501 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1502 "agg_cnt:",
1503 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1504 delta_ht->agg_cnt, max_ht->agg_cnt);
1505 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1506 "unsupport_mcs:",
1507 le32_to_cpu(ht->unsupport_mcs),
1508 accum_ht->unsupport_mcs,
1509 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1372 1510
1373 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1511 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1374 kfree(buf); 1512 kfree(buf);
@@ -1379,26 +1517,16 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1379 char __user *user_buf, 1517 char __user *user_buf,
1380 size_t count, loff_t *ppos) 1518 size_t count, loff_t *ppos)
1381{ 1519{
1382 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1520 struct iwl_priv *priv = file->private_data;
1383 int pos = 0; 1521 int pos = 0;
1384 char *buf; 1522 char *buf;
1385 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1523 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1386 ssize_t ret; 1524 ssize_t ret;
1387 struct statistics_tx *tx, *accum_tx; 1525 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1388 1526
1389 if (!iwl_is_alive(priv)) 1527 if (!iwl_is_alive(priv))
1390 return -EAGAIN; 1528 return -EAGAIN;
1391 1529
1392 /* make request to uCode to retrieve statistics information */
1393 mutex_lock(&priv->mutex);
1394 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1395 mutex_unlock(&priv->mutex);
1396
1397 if (ret) {
1398 IWL_ERR(priv,
1399 "Error sending statistics request: %zd\n", ret);
1400 return -EAGAIN;
1401 }
1402 buf = kzalloc(bufsz, GFP_KERNEL); 1530 buf = kzalloc(bufsz, GFP_KERNEL);
1403 if (!buf) { 1531 if (!buf) {
1404 IWL_ERR(priv, "Can not allocate Buffer\n"); 1532 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1411,106 +1539,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1411 */ 1539 */
1412 tx = &priv->statistics.tx; 1540 tx = &priv->statistics.tx;
1413 accum_tx = &priv->accum_statistics.tx; 1541 accum_tx = &priv->accum_statistics.tx;
1542 delta_tx = &priv->delta_statistics.tx;
1543 max_tx = &priv->max_delta.tx;
1414 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1544 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1415 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); 1545 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1416 pos += scnprintf(buf + pos, bufsz - pos, 1546 "Statistics_Tx:");
1417 "\t\t\tcurrent\t\t\taccumulative\n"); 1547 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1418 pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", 1548 "preamble:",
1419 le32_to_cpu(tx->preamble_cnt), 1549 le32_to_cpu(tx->preamble_cnt),
1420 accum_tx->preamble_cnt); 1550 accum_tx->preamble_cnt,
1421 pos += scnprintf(buf + pos, bufsz - pos, 1551 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1422 "rx_detected_cnt:\t\t%u\t\t\t%u\n", 1552 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1553 "rx_detected_cnt:",
1423 le32_to_cpu(tx->rx_detected_cnt), 1554 le32_to_cpu(tx->rx_detected_cnt),
1424 accum_tx->rx_detected_cnt); 1555 accum_tx->rx_detected_cnt,
1425 pos += scnprintf(buf + pos, bufsz - pos, 1556 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1426 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", 1557 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1558 "bt_prio_defer_cnt:",
1427 le32_to_cpu(tx->bt_prio_defer_cnt), 1559 le32_to_cpu(tx->bt_prio_defer_cnt),
1428 accum_tx->bt_prio_defer_cnt); 1560 accum_tx->bt_prio_defer_cnt,
1429 pos += scnprintf(buf + pos, bufsz - pos, 1561 delta_tx->bt_prio_defer_cnt,
1430 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", 1562 max_tx->bt_prio_defer_cnt);
1563 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1564 "bt_prio_kill_cnt:",
1431 le32_to_cpu(tx->bt_prio_kill_cnt), 1565 le32_to_cpu(tx->bt_prio_kill_cnt),
1432 accum_tx->bt_prio_kill_cnt); 1566 accum_tx->bt_prio_kill_cnt,
1433 pos += scnprintf(buf + pos, bufsz - pos, 1567 delta_tx->bt_prio_kill_cnt,
1434 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", 1568 max_tx->bt_prio_kill_cnt);
1569 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1570 "few_bytes_cnt:",
1435 le32_to_cpu(tx->few_bytes_cnt), 1571 le32_to_cpu(tx->few_bytes_cnt),
1436 accum_tx->few_bytes_cnt); 1572 accum_tx->few_bytes_cnt,
1437 pos += scnprintf(buf + pos, bufsz - pos, 1573 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1438 "cts_timeout:\t\t\t%u\t\t\t%u\n", 1574 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); 1575 "cts_timeout:",
1440 pos += scnprintf(buf + pos, bufsz - pos, 1576 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1441 "ack_timeout:\t\t\t%u\t\t\t%u\n", 1577 delta_tx->cts_timeout, max_tx->cts_timeout);
1578 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1579 "ack_timeout:",
1442 le32_to_cpu(tx->ack_timeout), 1580 le32_to_cpu(tx->ack_timeout),
1443 accum_tx->ack_timeout); 1581 accum_tx->ack_timeout,
1444 pos += scnprintf(buf + pos, bufsz - pos, 1582 delta_tx->ack_timeout, max_tx->ack_timeout);
1445 "expected_ack_cnt:\t\t%u\t\t\t%u\n", 1583 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1584 "expected_ack_cnt:",
1446 le32_to_cpu(tx->expected_ack_cnt), 1585 le32_to_cpu(tx->expected_ack_cnt),
1447 accum_tx->expected_ack_cnt); 1586 accum_tx->expected_ack_cnt,
1448 pos += scnprintf(buf + pos, bufsz - pos, 1587 delta_tx->expected_ack_cnt,
1449 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", 1588 max_tx->expected_ack_cnt);
1589 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1590 "actual_ack_cnt:",
1450 le32_to_cpu(tx->actual_ack_cnt), 1591 le32_to_cpu(tx->actual_ack_cnt),
1451 accum_tx->actual_ack_cnt); 1592 accum_tx->actual_ack_cnt,
1452 pos += scnprintf(buf + pos, bufsz - pos, 1593 delta_tx->actual_ack_cnt,
1453 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", 1594 max_tx->actual_ack_cnt);
1595 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1596 "dump_msdu_cnt:",
1454 le32_to_cpu(tx->dump_msdu_cnt), 1597 le32_to_cpu(tx->dump_msdu_cnt),
1455 accum_tx->dump_msdu_cnt); 1598 accum_tx->dump_msdu_cnt,
1456 pos += scnprintf(buf + pos, bufsz - pos, 1599 delta_tx->dump_msdu_cnt,
1457 "abort_nxt_frame_mismatch:" 1600 max_tx->dump_msdu_cnt);
1458 "\t%u\t\t\t%u\n", 1601 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1602 "abort_nxt_frame_mismatch:",
1459 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1603 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1460 accum_tx->burst_abort_next_frame_mismatch_cnt); 1604 accum_tx->burst_abort_next_frame_mismatch_cnt,
1461 pos += scnprintf(buf + pos, bufsz - pos, 1605 delta_tx->burst_abort_next_frame_mismatch_cnt,
1462 "abort_missing_nxt_frame:" 1606 max_tx->burst_abort_next_frame_mismatch_cnt);
1463 "\t%u\t\t\t%u\n", 1607 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1608 "abort_missing_nxt_frame:",
1464 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1609 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1465 accum_tx->burst_abort_missing_next_frame_cnt); 1610 accum_tx->burst_abort_missing_next_frame_cnt,
1466 pos += scnprintf(buf + pos, bufsz - pos, 1611 delta_tx->burst_abort_missing_next_frame_cnt,
1467 "cts_timeout_collision:\t\t%u\t\t\t%u\n", 1612 max_tx->burst_abort_missing_next_frame_cnt);
1613 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1614 "cts_timeout_collision:",
1468 le32_to_cpu(tx->cts_timeout_collision), 1615 le32_to_cpu(tx->cts_timeout_collision),
1469 accum_tx->cts_timeout_collision); 1616 accum_tx->cts_timeout_collision,
1470 pos += scnprintf(buf + pos, bufsz - pos, 1617 delta_tx->cts_timeout_collision,
1471 "ack_ba_timeout_collision:\t%u\t\t\t%u\n", 1618 max_tx->cts_timeout_collision);
1619 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1620 "ack_ba_timeout_collision:",
1472 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1621 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1473 accum_tx->ack_or_ba_timeout_collision); 1622 accum_tx->ack_or_ba_timeout_collision,
1474 pos += scnprintf(buf + pos, bufsz - pos, 1623 delta_tx->ack_or_ba_timeout_collision,
1475 "agg ba_timeout:\t\t\t%u\t\t\t%u\n", 1624 max_tx->ack_or_ba_timeout_collision);
1625 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1626 "agg ba_timeout:",
1476 le32_to_cpu(tx->agg.ba_timeout), 1627 le32_to_cpu(tx->agg.ba_timeout),
1477 accum_tx->agg.ba_timeout); 1628 accum_tx->agg.ba_timeout,
1478 pos += scnprintf(buf + pos, bufsz - pos, 1629 delta_tx->agg.ba_timeout,
1479 "agg ba_resched_frames:\t\t%u\t\t\t%u\n", 1630 max_tx->agg.ba_timeout);
1631 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1632 "agg ba_resched_frames:",
1480 le32_to_cpu(tx->agg.ba_reschedule_frames), 1633 le32_to_cpu(tx->agg.ba_reschedule_frames),
1481 accum_tx->agg.ba_reschedule_frames); 1634 accum_tx->agg.ba_reschedule_frames,
1482 pos += scnprintf(buf + pos, bufsz - pos, 1635 delta_tx->agg.ba_reschedule_frames,
1483 "agg scd_query_agg_frame:\t%u\t\t\t%u\n", 1636 max_tx->agg.ba_reschedule_frames);
1637 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1638 "agg scd_query_agg_frame:",
1484 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1639 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1485 accum_tx->agg.scd_query_agg_frame_cnt); 1640 accum_tx->agg.scd_query_agg_frame_cnt,
1486 pos += scnprintf(buf + pos, bufsz - pos, 1641 delta_tx->agg.scd_query_agg_frame_cnt,
1487 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", 1642 max_tx->agg.scd_query_agg_frame_cnt);
1643 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1644 "agg scd_query_no_agg:",
1488 le32_to_cpu(tx->agg.scd_query_no_agg), 1645 le32_to_cpu(tx->agg.scd_query_no_agg),
1489 accum_tx->agg.scd_query_no_agg); 1646 accum_tx->agg.scd_query_no_agg,
1490 pos += scnprintf(buf + pos, bufsz - pos, 1647 delta_tx->agg.scd_query_no_agg,
1491 "agg scd_query_agg:\t\t%u\t\t\t%u\n", 1648 max_tx->agg.scd_query_no_agg);
1649 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1650 "agg scd_query_agg:",
1492 le32_to_cpu(tx->agg.scd_query_agg), 1651 le32_to_cpu(tx->agg.scd_query_agg),
1493 accum_tx->agg.scd_query_agg); 1652 accum_tx->agg.scd_query_agg,
1494 pos += scnprintf(buf + pos, bufsz - pos, 1653 delta_tx->agg.scd_query_agg,
1495 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", 1654 max_tx->agg.scd_query_agg);
1655 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1656 "agg scd_query_mismatch:",
1496 le32_to_cpu(tx->agg.scd_query_mismatch), 1657 le32_to_cpu(tx->agg.scd_query_mismatch),
1497 accum_tx->agg.scd_query_mismatch); 1658 accum_tx->agg.scd_query_mismatch,
1498 pos += scnprintf(buf + pos, bufsz - pos, 1659 delta_tx->agg.scd_query_mismatch,
1499 "agg frame_not_ready:\t\t%u\t\t\t%u\n", 1660 max_tx->agg.scd_query_mismatch);
1661 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1662 "agg frame_not_ready:",
1500 le32_to_cpu(tx->agg.frame_not_ready), 1663 le32_to_cpu(tx->agg.frame_not_ready),
1501 accum_tx->agg.frame_not_ready); 1664 accum_tx->agg.frame_not_ready,
1502 pos += scnprintf(buf + pos, bufsz - pos, 1665 delta_tx->agg.frame_not_ready,
1503 "agg underrun:\t\t\t%u\t\t\t%u\n", 1666 max_tx->agg.frame_not_ready);
1667 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1668 "agg underrun:",
1504 le32_to_cpu(tx->agg.underrun), 1669 le32_to_cpu(tx->agg.underrun),
1505 accum_tx->agg.underrun); 1670 accum_tx->agg.underrun,
1506 pos += scnprintf(buf + pos, bufsz - pos, 1671 delta_tx->agg.underrun, max_tx->agg.underrun);
1507 "agg bt_prio_kill:\t\t%u\t\t\t%u\n", 1672 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1673 "agg bt_prio_kill:",
1508 le32_to_cpu(tx->agg.bt_prio_kill), 1674 le32_to_cpu(tx->agg.bt_prio_kill),
1509 accum_tx->agg.bt_prio_kill); 1675 accum_tx->agg.bt_prio_kill,
1510 pos += scnprintf(buf + pos, bufsz - pos, 1676 delta_tx->agg.bt_prio_kill,
1511 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", 1677 max_tx->agg.bt_prio_kill);
1678 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1679 "agg rx_ba_rsp_cnt:",
1512 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1680 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1513 accum_tx->agg.rx_ba_rsp_cnt); 1681 accum_tx->agg.rx_ba_rsp_cnt,
1682 delta_tx->agg.rx_ba_rsp_cnt,
1683 max_tx->agg.rx_ba_rsp_cnt);
1514 1684
1515 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1685 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1516 kfree(buf); 1686 kfree(buf);
@@ -1521,28 +1691,19 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1521 char __user *user_buf, 1691 char __user *user_buf,
1522 size_t count, loff_t *ppos) 1692 size_t count, loff_t *ppos)
1523{ 1693{
1524 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1694 struct iwl_priv *priv = file->private_data;
1525 int pos = 0; 1695 int pos = 0;
1526 char *buf; 1696 char *buf;
1527 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1697 int bufsz = sizeof(struct statistics_general) * 10 + 300;
1528 ssize_t ret; 1698 ssize_t ret;
1529 struct statistics_general *general, *accum_general; 1699 struct statistics_general *general, *accum_general;
1530 struct statistics_dbg *dbg, *accum_dbg; 1700 struct statistics_general *delta_general, *max_general;
1531 struct statistics_div *div, *accum_div; 1701 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1702 struct statistics_div *div, *accum_div, *delta_div, *max_div;
1532 1703
1533 if (!iwl_is_alive(priv)) 1704 if (!iwl_is_alive(priv))
1534 return -EAGAIN; 1705 return -EAGAIN;
1535 1706
1536 /* make request to uCode to retrieve statistics information */
1537 mutex_lock(&priv->mutex);
1538 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1539 mutex_unlock(&priv->mutex);
1540
1541 if (ret) {
1542 IWL_ERR(priv,
1543 "Error sending statistics request: %zd\n", ret);
1544 return -EAGAIN;
1545 }
1546 buf = kzalloc(bufsz, GFP_KERNEL); 1707 buf = kzalloc(bufsz, GFP_KERNEL);
1547 if (!buf) { 1708 if (!buf) {
1548 IWL_ERR(priv, "Can not allocate Buffer\n"); 1709 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1557,52 +1718,78 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1557 dbg = &priv->statistics.general.dbg; 1718 dbg = &priv->statistics.general.dbg;
1558 div = &priv->statistics.general.div; 1719 div = &priv->statistics.general.div;
1559 accum_general = &priv->accum_statistics.general; 1720 accum_general = &priv->accum_statistics.general;
1721 delta_general = &priv->delta_statistics.general;
1722 max_general = &priv->max_delta.general;
1560 accum_dbg = &priv->accum_statistics.general.dbg; 1723 accum_dbg = &priv->accum_statistics.general.dbg;
1724 delta_dbg = &priv->delta_statistics.general.dbg;
1725 max_dbg = &priv->max_delta.general.dbg;
1561 accum_div = &priv->accum_statistics.general.div; 1726 accum_div = &priv->accum_statistics.general.div;
1727 delta_div = &priv->delta_statistics.general.div;
1728 max_div = &priv->max_delta.general.div;
1562 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1729 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1563 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); 1730 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1564 pos += scnprintf(buf + pos, bufsz - pos, 1731 "Statistics_General:");
1565 "\t\t\tcurrent\t\t\taccumulative\n"); 1732 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1566 pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", 1733 "temperature:",
1567 le32_to_cpu(general->temperature)); 1734 le32_to_cpu(general->temperature));
1568 pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", 1735 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1736 "temperature_m:",
1569 le32_to_cpu(general->temperature_m)); 1737 le32_to_cpu(general->temperature_m));
1570 pos += scnprintf(buf + pos, bufsz - pos, 1738 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1571 "burst_check:\t\t\t%u\t\t\t%u\n", 1739 "burst_check:",
1572 le32_to_cpu(dbg->burst_check), 1740 le32_to_cpu(dbg->burst_check),
1573 accum_dbg->burst_check); 1741 accum_dbg->burst_check,
1574 pos += scnprintf(buf + pos, bufsz - pos, 1742 delta_dbg->burst_check, max_dbg->burst_check);
1575 "burst_count:\t\t\t%u\t\t\t%u\n", 1743 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1744 "burst_count:",
1576 le32_to_cpu(dbg->burst_count), 1745 le32_to_cpu(dbg->burst_count),
1577 accum_dbg->burst_count); 1746 accum_dbg->burst_count,
1578 pos += scnprintf(buf + pos, bufsz - pos, 1747 delta_dbg->burst_count, max_dbg->burst_count);
1579 "sleep_time:\t\t\t%u\t\t\t%u\n", 1748 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1749 "sleep_time:",
1580 le32_to_cpu(general->sleep_time), 1750 le32_to_cpu(general->sleep_time),
1581 accum_general->sleep_time); 1751 accum_general->sleep_time,
1582 pos += scnprintf(buf + pos, bufsz - pos, 1752 delta_general->sleep_time, max_general->sleep_time);
1583 "slots_out:\t\t\t%u\t\t\t%u\n", 1753 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1754 "slots_out:",
1584 le32_to_cpu(general->slots_out), 1755 le32_to_cpu(general->slots_out),
1585 accum_general->slots_out); 1756 accum_general->slots_out,
1586 pos += scnprintf(buf + pos, bufsz - pos, 1757 delta_general->slots_out, max_general->slots_out);
1587 "slots_idle:\t\t\t%u\t\t\t%u\n", 1758 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1759 "slots_idle:",
1588 le32_to_cpu(general->slots_idle), 1760 le32_to_cpu(general->slots_idle),
1589 accum_general->slots_idle); 1761 accum_general->slots_idle,
1762 delta_general->slots_idle, max_general->slots_idle);
1590 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", 1763 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1591 le32_to_cpu(general->ttl_timestamp)); 1764 le32_to_cpu(general->ttl_timestamp));
1592 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", 1765 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1593 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); 1766 "tx_on_a:",
1594 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", 1767 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1595 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); 1768 delta_div->tx_on_a, max_div->tx_on_a);
1596 pos += scnprintf(buf + pos, bufsz - pos, 1769 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1597 "exec_time:\t\t\t%u\t\t\t%u\n", 1770 "tx_on_b:",
1598 le32_to_cpu(div->exec_time), accum_div->exec_time); 1771 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1599 pos += scnprintf(buf + pos, bufsz - pos, 1772 delta_div->tx_on_b, max_div->tx_on_b);
1600 "probe_time:\t\t\t%u\t\t\t%u\n", 1773 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1601 le32_to_cpu(div->probe_time), accum_div->probe_time); 1774 "exec_time:",
1602 pos += scnprintf(buf + pos, bufsz - pos, 1775 le32_to_cpu(div->exec_time), accum_div->exec_time,
1603 "rx_enable_counter:\t\t%u\t\t\t%u\n", 1776 delta_div->exec_time, max_div->exec_time);
1777 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1778 "probe_time:",
1779 le32_to_cpu(div->probe_time), accum_div->probe_time,
1780 delta_div->probe_time, max_div->probe_time);
1781 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1782 "rx_enable_counter:",
1604 le32_to_cpu(general->rx_enable_counter), 1783 le32_to_cpu(general->rx_enable_counter),
1605 accum_general->rx_enable_counter); 1784 accum_general->rx_enable_counter,
1785 delta_general->rx_enable_counter,
1786 max_general->rx_enable_counter);
1787 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1788 "num_of_sos_states:",
1789 le32_to_cpu(general->num_of_sos_states),
1790 accum_general->num_of_sos_states,
1791 delta_general->num_of_sos_states,
1792 max_general->num_of_sos_states);
1606 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1793 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1607 kfree(buf); 1794 kfree(buf);
1608 return ret; 1795 return ret;
@@ -1612,7 +1799,7 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1612 char __user *user_buf, 1799 char __user *user_buf,
1613 size_t count, loff_t *ppos) { 1800 size_t count, loff_t *ppos) {
1614 1801
1615 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1802 struct iwl_priv *priv = file->private_data;
1616 int pos = 0; 1803 int pos = 0;
1617 int cnt = 0; 1804 int cnt = 0;
1618 char *buf; 1805 char *buf;
@@ -1693,7 +1880,7 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1693 char __user *user_buf, 1880 char __user *user_buf,
1694 size_t count, loff_t *ppos) { 1881 size_t count, loff_t *ppos) {
1695 1882
1696 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1883 struct iwl_priv *priv = file->private_data;
1697 int pos = 0; 1884 int pos = 0;
1698 int cnt = 0; 1885 int cnt = 0;
1699 char *buf; 1886 char *buf;
@@ -1751,26 +1938,15 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1751 char __user *user_buf, 1938 char __user *user_buf,
1752 size_t count, loff_t *ppos) { 1939 size_t count, loff_t *ppos) {
1753 1940
1754 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1941 struct iwl_priv *priv = file->private_data;
1755 char buf[128]; 1942 char buf[128];
1756 int pos = 0; 1943 int pos = 0;
1757 ssize_t ret;
1758 const size_t bufsz = sizeof(buf); 1944 const size_t bufsz = sizeof(buf);
1759 struct statistics_tx *tx; 1945 struct statistics_tx *tx;
1760 1946
1761 if (!iwl_is_alive(priv)) 1947 if (!iwl_is_alive(priv))
1762 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1948 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1763 else { 1949 else {
1764 /* make request to uCode to retrieve statistics information */
1765 mutex_lock(&priv->mutex);
1766 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1767 mutex_unlock(&priv->mutex);
1768
1769 if (ret) {
1770 IWL_ERR(priv, "Error sending statistics request: %zd\n",
1771 ret);
1772 return -EAGAIN;
1773 }
1774 tx = &priv->statistics.tx; 1950 tx = &priv->statistics.tx;
1775 if (tx->tx_power.ant_a || 1951 if (tx->tx_power.ant_a ||
1776 tx->tx_power.ant_b || 1952 tx->tx_power.ant_b ||
@@ -1802,7 +1978,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1802 char __user *user_buf, 1978 char __user *user_buf,
1803 size_t count, loff_t *ppos) 1979 size_t count, loff_t *ppos)
1804{ 1980{
1805 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1981 struct iwl_priv *priv = file->private_data;
1806 char buf[60]; 1982 char buf[60];
1807 int pos = 0; 1983 int pos = 0;
1808 const size_t bufsz = sizeof(buf); 1984 const size_t bufsz = sizeof(buf);
@@ -1845,6 +2021,262 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1845 return count; 2021 return count;
1846} 2022}
1847 2023
2024static ssize_t iwl_dbgfs_csr_write(struct file *file,
2025 const char __user *user_buf,
2026 size_t count, loff_t *ppos)
2027{
2028 struct iwl_priv *priv = file->private_data;
2029 char buf[8];
2030 int buf_size;
2031 int csr;
2032
2033 memset(buf, 0, sizeof(buf));
2034 buf_size = min(count, sizeof(buf) - 1);
2035 if (copy_from_user(buf, user_buf, buf_size))
2036 return -EFAULT;
2037 if (sscanf(buf, "%d", &csr) != 1)
2038 return -EFAULT;
2039
2040 if (priv->cfg->ops->lib->dump_csr)
2041 priv->cfg->ops->lib->dump_csr(priv);
2042
2043 return count;
2044}
2045
2046static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2047 char __user *user_buf,
2048 size_t count, loff_t *ppos) {
2049
2050 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2051 int pos = 0;
2052 char buf[128];
2053 const size_t bufsz = sizeof(buf);
2054 ssize_t ret;
2055
2056 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2057 priv->event_log.ucode_trace ? "On" : "Off");
2058 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
2059 priv->event_log.non_wraps_count);
2060 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
2061 priv->event_log.wraps_once_count);
2062 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2063 priv->event_log.wraps_more_count);
2064
2065 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2066 return ret;
2067}
2068
2069static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2070 const char __user *user_buf,
2071 size_t count, loff_t *ppos)
2072{
2073 struct iwl_priv *priv = file->private_data;
2074 char buf[8];
2075 int buf_size;
2076 int trace;
2077
2078 memset(buf, 0, sizeof(buf));
2079 buf_size = min(count, sizeof(buf) - 1);
2080 if (copy_from_user(buf, user_buf, buf_size))
2081 return -EFAULT;
2082 if (sscanf(buf, "%d", &trace) != 1)
2083 return -EFAULT;
2084
2085 if (trace) {
2086 priv->event_log.ucode_trace = true;
2087 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2088 mod_timer(&priv->ucode_trace,
2089 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
2090 } else {
2091 priv->event_log.ucode_trace = false;
2092 del_timer_sync(&priv->ucode_trace);
2093 }
2094
2095 return count;
2096}
2097
2098static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2099 char __user *user_buf,
2100 size_t count, loff_t *ppos)
2101{
2102 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2103 char *buf;
2104 int pos = 0;
2105 ssize_t ret = -EFAULT;
2106
2107 if (priv->cfg->ops->lib->dump_fh) {
2108 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
2109 if (buf) {
2110 ret = simple_read_from_buffer(user_buf,
2111 count, ppos, buf, pos);
2112 kfree(buf);
2113 }
2114 }
2115
2116 return ret;
2117}
2118
2119static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2120 char __user *user_buf,
2121 size_t count, loff_t *ppos) {
2122
2123 struct iwl_priv *priv = file->private_data;
2124 int pos = 0;
2125 char buf[12];
2126 const size_t bufsz = sizeof(buf);
2127 ssize_t ret;
2128
2129 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2130 priv->missed_beacon_threshold);
2131
2132 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2133 return ret;
2134}
2135
2136static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2137 const char __user *user_buf,
2138 size_t count, loff_t *ppos)
2139{
2140 struct iwl_priv *priv = file->private_data;
2141 char buf[8];
2142 int buf_size;
2143 int missed;
2144
2145 memset(buf, 0, sizeof(buf));
2146 buf_size = min(count, sizeof(buf) - 1);
2147 if (copy_from_user(buf, user_buf, buf_size))
2148 return -EFAULT;
2149 if (sscanf(buf, "%d", &missed) != 1)
2150 return -EINVAL;
2151
2152 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2153 missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2154 priv->missed_beacon_threshold =
2155 IWL_MISSED_BEACON_THRESHOLD_DEF;
2156 else
2157 priv->missed_beacon_threshold = missed;
2158
2159 return count;
2160}
2161
2162static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2163 const char __user *user_buf,
2164 size_t count, loff_t *ppos)
2165{
2166 struct iwl_priv *priv = file->private_data;
2167 char buf[8];
2168 int buf_size;
2169 int scan;
2170
2171 memset(buf, 0, sizeof(buf));
2172 buf_size = min(count, sizeof(buf) - 1);
2173 if (copy_from_user(buf, user_buf, buf_size))
2174 return -EFAULT;
2175 if (sscanf(buf, "%d", &scan) != 1)
2176 return -EINVAL;
2177
2178 iwl_internal_short_hw_scan(priv);
2179
2180 return count;
2181}
2182
2183static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2184 char __user *user_buf,
2185 size_t count, loff_t *ppos) {
2186
2187 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2188 int pos = 0;
2189 char buf[12];
2190 const size_t bufsz = sizeof(buf);
2191 ssize_t ret;
2192
2193 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2194 priv->cfg->plcp_delta_threshold);
2195
2196 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2197 return ret;
2198}
2199
2200static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2201 const char __user *user_buf,
2202 size_t count, loff_t *ppos) {
2203
2204 struct iwl_priv *priv = file->private_data;
2205 char buf[8];
2206 int buf_size;
2207 int plcp;
2208
2209 memset(buf, 0, sizeof(buf));
2210 buf_size = min(count, sizeof(buf) - 1);
2211 if (copy_from_user(buf, user_buf, buf_size))
2212 return -EFAULT;
2213 if (sscanf(buf, "%d", &plcp) != 1)
2214 return -EINVAL;
2215 if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2216 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2217 priv->cfg->plcp_delta_threshold =
2218 IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
2219 else
2220 priv->cfg->plcp_delta_threshold = plcp;
2221 return count;
2222}
2223
2224static ssize_t iwl_dbgfs_force_reset_read(struct file *file,
2225 char __user *user_buf,
2226 size_t count, loff_t *ppos) {
2227
2228 struct iwl_priv *priv = file->private_data;
2229 int i, pos = 0;
2230 char buf[300];
2231 const size_t bufsz = sizeof(buf);
2232 struct iwl_force_reset *force_reset;
2233
2234 for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
2235 force_reset = &priv->force_reset[i];
2236 pos += scnprintf(buf + pos, bufsz - pos,
2237 "Force reset method %d\n", i);
2238 pos += scnprintf(buf + pos, bufsz - pos,
2239 "\tnumber of reset request: %d\n",
2240 force_reset->reset_request_count);
2241 pos += scnprintf(buf + pos, bufsz - pos,
2242 "\tnumber of reset request success: %d\n",
2243 force_reset->reset_success_count);
2244 pos += scnprintf(buf + pos, bufsz - pos,
2245 "\tnumber of reset request reject: %d\n",
2246 force_reset->reset_reject_count);
2247 pos += scnprintf(buf + pos, bufsz - pos,
2248 "\treset duration: %lu\n",
2249 force_reset->reset_duration);
2250 }
2251 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2252}
2253
2254static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
2255 const char __user *user_buf,
2256 size_t count, loff_t *ppos) {
2257
2258 struct iwl_priv *priv = file->private_data;
2259 char buf[8];
2260 int buf_size;
2261 int reset, ret;
2262
2263 memset(buf, 0, sizeof(buf));
2264 buf_size = min(count, sizeof(buf) - 1);
2265 if (copy_from_user(buf, user_buf, buf_size))
2266 return -EFAULT;
2267 if (sscanf(buf, "%d", &reset) != 1)
2268 return -EINVAL;
2269 switch (reset) {
2270 case IWL_RF_RESET:
2271 case IWL_FW_RESET:
2272 ret = iwl_force_reset(priv, reset);
2273 break;
2274 default:
2275 return -EINVAL;
2276 }
2277 return ret ? ret : count;
2278}
2279
1848DEBUGFS_READ_FILE_OPS(rx_statistics); 2280DEBUGFS_READ_FILE_OPS(rx_statistics);
1849DEBUGFS_READ_FILE_OPS(tx_statistics); 2281DEBUGFS_READ_FILE_OPS(tx_statistics);
1850DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2282DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1859,6 +2291,13 @@ DEBUGFS_READ_FILE_OPS(tx_power);
1859DEBUGFS_READ_FILE_OPS(power_save_status); 2291DEBUGFS_READ_FILE_OPS(power_save_status);
1860DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 2292DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1861DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 2293DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2294DEBUGFS_WRITE_FILE_OPS(csr);
2295DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2296DEBUGFS_READ_FILE_OPS(fh_reg);
2297DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2298DEBUGFS_WRITE_FILE_OPS(internal_scan);
2299DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2300DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1862 2301
1863/* 2302/*
1864 * Create the debugfs files and directories 2303 * Create the debugfs files and directories
@@ -1866,69 +2305,74 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1866 */ 2305 */
1867int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 2306int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1868{ 2307{
1869 struct iwl_debugfs *dbgfs;
1870 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 2308 struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1871 int ret = 0; 2309 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1872 2310
1873 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 2311 dir_drv = debugfs_create_dir(name, phyd);
1874 if (!dbgfs) { 2312 if (!dir_drv)
1875 ret = -ENOMEM; 2313 return -ENOMEM;
1876 goto err; 2314
1877 } 2315 priv->debugfs_dir = dir_drv;
1878 2316
1879 priv->dbgfs = dbgfs; 2317 dir_data = debugfs_create_dir("data", dir_drv);
1880 dbgfs->name = name; 2318 if (!dir_data)
1881 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 2319 goto err;
1882 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 2320 dir_rf = debugfs_create_dir("rf", dir_drv);
1883 ret = -ENOENT; 2321 if (!dir_rf)
2322 goto err;
2323 dir_debug = debugfs_create_dir("debug", dir_drv);
2324 if (!dir_debug)
1884 goto err; 2325 goto err;
1885 }
1886 2326
1887 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 2327 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1888 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 2328 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1889 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 2329 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
1890 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 2330 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1891 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 2331 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1892 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); 2332 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1893 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 2333 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1894 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 2334 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1895 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 2335 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1896 DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); 2336 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
1897 DEBUGFS_ADD_FILE(qos, data, S_IRUSR); 2337 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1898 DEBUGFS_ADD_FILE(led, data, S_IRUSR); 2338 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
1899 DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); 2339 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1900 DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); 2340 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1901 DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); 2341 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1902 DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); 2342 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1903 DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); 2343 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1904 DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); 2344 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1905 DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); 2345 DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
1906 DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); 2346 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
1907 DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); 2347 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
1908 DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); 2348 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
1909 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2349 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
1910 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2350 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1911 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2351 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2352 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2353 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2354 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1912 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2355 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1913 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2356 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1914 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2357 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1915 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2358 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1916 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2359 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1917 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2360 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2361 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
1918 } 2362 }
1919 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2363 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
1920 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2364 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1921 &priv->disable_chain_noise_cal); 2365 &priv->disable_chain_noise_cal);
1922 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 2366 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1923 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 2367 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1924 DEBUGFS_ADD_BOOL(disable_tx_power, rf, 2368 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1925 &priv->disable_tx_power_cal); 2369 &priv->disable_tx_power_cal);
1926 return 0; 2370 return 0;
1927 2371
1928err: 2372err:
1929 IWL_ERR(priv, "Can't open the debugfs directory\n"); 2373 IWL_ERR(priv, "Can't create the debugfs directory\n");
1930 iwl_dbgfs_unregister(priv); 2374 iwl_dbgfs_unregister(priv);
1931 return ret; 2375 return -ENOMEM;
1932} 2376}
1933EXPORT_SYMBOL(iwl_dbgfs_register); 2377EXPORT_SYMBOL(iwl_dbgfs_register);
1934 2378
@@ -1938,56 +2382,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
1938 */ 2382 */
1939void iwl_dbgfs_unregister(struct iwl_priv *priv) 2383void iwl_dbgfs_unregister(struct iwl_priv *priv)
1940{ 2384{
1941 if (!priv->dbgfs) 2385 if (!priv->debugfs_dir)
1942 return; 2386 return;
1943 2387
1944 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); 2388 debugfs_remove_recursive(priv->debugfs_dir);
1945 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); 2389 priv->debugfs_dir = NULL;
1946 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
1947 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
1948 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
1949 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
1950 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
1951 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
1952 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
1953 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
1954 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
1955 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
1956 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
1957 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
1958 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
1959 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
1960 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
1961 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
1962 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
1963 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
1964 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
1965 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1966 file_clear_ucode_statistics);
1967 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1968 file_clear_traffic_statistics);
1969 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1970 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1971 file_ucode_rx_stats);
1972 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1973 file_ucode_tx_stats);
1974 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1975 file_ucode_general_stats);
1976 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1977 file_sensitivity);
1978 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1979 file_chain_noise);
1980 }
1981 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1982 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
1983 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
1984 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1985 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1986 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
1987 DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
1988 DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
1989 kfree(priv->dbgfs);
1990 priv->dbgfs = NULL;
1991} 2390}
1992EXPORT_SYMBOL(iwl_dbgfs_unregister); 2391EXPORT_SYMBOL(iwl_dbgfs_unregister);
1993 2392
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 3822cf53e368..7914d65a5a55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -512,6 +512,7 @@ struct iwl_ht_config {
512 bool is_ht; 512 bool is_ht;
513 bool is_40mhz; 513 bool is_40mhz;
514 bool single_chain_sufficient; 514 bool single_chain_sufficient;
515 enum ieee80211_smps_mode smps; /* current smps mode */
515 /* BSS related data */ 516 /* BSS related data */
516 u8 extension_chan_offset; 517 u8 extension_chan_offset;
517 u8 ht_protection; 518 u8 ht_protection;
@@ -984,6 +985,74 @@ struct iwl_switch_rxon {
984 __le16 channel; 985 __le16 channel;
985}; 986};
986 987
988/*
989 * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
990 * to perform continuous uCode event logging operation if enabled
991 */
992#define UCODE_TRACE_PERIOD (100)
993
994/*
995 * iwl_event_log: current uCode event log position
996 *
997 * @ucode_trace: enable/disable ucode continuous trace timer
998 * @num_wraps: how many times the event buffer wraps
999 * @next_entry: the entry just before the next one that uCode would fill
1000 * @non_wraps_count: counter for no wrap detected when dump ucode events
1001 * @wraps_once_count: counter for wrap once detected when dump ucode events
1002 * @wraps_more_count: counter for wrap more than once detected
1003 * when dump ucode events
1004 */
1005struct iwl_event_log {
1006 bool ucode_trace;
1007 u32 num_wraps;
1008 u32 next_entry;
1009 int non_wraps_count;
1010 int wraps_once_count;
1011 int wraps_more_count;
1012};
1013
1014/*
1015 * host interrupt timeout value
1016 * used with setting interrupt coalescing timer
1017 * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
1018 *
1019 * default interrupt coalescing timer is 64 x 32 = 2048 usecs
1020 * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
1021 */
1022#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
1023#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
1024#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
1025#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
1026#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
1027#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
1028
1029/*
1030 * This is the threshold value of plcp error rate per 100mSecs. It is
1031 * used to set and check for the validity of plcp_delta.
1032 */
1033#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)
1034#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
1035#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
1036#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200)
1037#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
1038
1039#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
1040#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
1041
1042enum iwl_reset {
1043 IWL_RF_RESET = 0,
1044 IWL_FW_RESET,
1045 IWL_MAX_FORCE_RESET,
1046};
1047
1048struct iwl_force_reset {
1049 int reset_request_count;
1050 int reset_success_count;
1051 int reset_reject_count;
1052 unsigned long reset_duration;
1053 unsigned long last_force_reset_jiffies;
1054};
1055
987struct iwl_priv { 1056struct iwl_priv {
988 1057
989 /* ieee device used by generic ieee processing code */ 1058 /* ieee device used by generic ieee processing code */
@@ -1004,13 +1073,22 @@ struct iwl_priv {
1004 1073
1005 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 1074 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
1006 1075
1007#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
1008 /* spectrum measurement report caching */ 1076 /* spectrum measurement report caching */
1009 struct iwl_spectrum_notification measure_report; 1077 struct iwl_spectrum_notification measure_report;
1010 u8 measurement_status; 1078 u8 measurement_status;
1011#endif 1079
1012 /* ucode beacon time */ 1080 /* ucode beacon time */
1013 u32 ucode_beacon_time; 1081 u32 ucode_beacon_time;
1082 int missed_beacon_threshold;
1083
1084 /* storing the jiffies when the plcp error rate is received */
1085 unsigned long plcp_jiffies;
1086
1087 /* reporting the number of tids has AGG on. 0 means no AGGREGATION */
1088 u8 agg_tids_count;
1089
1090 /* force reset */
1091 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
1014 1092
1015 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1093 /* we allocate array of iwl4965_channel_info for NIC's valid channels.
1016 * Access via channel # using indirect index array */ 1094 * Access via channel # using indirect index array */
@@ -1029,7 +1107,6 @@ struct iwl_priv {
1029 struct iwl_calib_result calib_results[IWL_CALIB_MAX]; 1107 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
1030 1108
1031 /* Scan related variables */ 1109 /* Scan related variables */
1032 unsigned long last_scan_jiffies;
1033 unsigned long next_scan_jiffies; 1110 unsigned long next_scan_jiffies;
1034 unsigned long scan_start; 1111 unsigned long scan_start;
1035 unsigned long scan_pass_start; 1112 unsigned long scan_pass_start;
@@ -1037,6 +1114,7 @@ struct iwl_priv {
1037 void *scan; 1114 void *scan;
1038 int scan_bands; 1115 int scan_bands;
1039 struct cfg80211_scan_request *scan_request; 1116 struct cfg80211_scan_request *scan_request;
1117 bool is_internal_short_scan;
1040 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1118 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
1041 u8 mgmt_tx_ant; 1119 u8 mgmt_tx_ant;
1042 1120
@@ -1045,6 +1123,7 @@ struct iwl_priv {
1045 spinlock_t hcmd_lock; /* protect hcmd */ 1123 spinlock_t hcmd_lock; /* protect hcmd */
1046 spinlock_t reg_lock; /* protect hw register access */ 1124 spinlock_t reg_lock; /* protect hw register access */
1047 struct mutex mutex; 1125 struct mutex mutex;
1126 struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
1048 1127
1049 /* basic pci-network driver stuff */ 1128 /* basic pci-network driver stuff */
1050 struct pci_dev *pci_dev; 1129 struct pci_dev *pci_dev;
@@ -1135,6 +1214,8 @@ struct iwl_priv {
1135 struct iwl_notif_statistics statistics; 1214 struct iwl_notif_statistics statistics;
1136#ifdef CONFIG_IWLWIFI_DEBUG 1215#ifdef CONFIG_IWLWIFI_DEBUG
1137 struct iwl_notif_statistics accum_statistics; 1216 struct iwl_notif_statistics accum_statistics;
1217 struct iwl_notif_statistics delta_statistics;
1218 struct iwl_notif_statistics max_delta;
1138#endif 1219#endif
1139 1220
1140 /* context information */ 1221 /* context information */
@@ -1207,15 +1288,10 @@ struct iwl_priv {
1207 1288
1208 struct workqueue_struct *workqueue; 1289 struct workqueue_struct *workqueue;
1209 1290
1210 struct work_struct up;
1211 struct work_struct restart; 1291 struct work_struct restart;
1212 struct work_struct calibrated_work;
1213 struct work_struct scan_completed; 1292 struct work_struct scan_completed;
1214 struct work_struct rx_replenish; 1293 struct work_struct rx_replenish;
1215 struct work_struct abort_scan; 1294 struct work_struct abort_scan;
1216 struct work_struct update_link_led;
1217 struct work_struct auth_work;
1218 struct work_struct report_work;
1219 struct work_struct request_scan; 1295 struct work_struct request_scan;
1220 struct work_struct beacon_update; 1296 struct work_struct beacon_update;
1221 struct work_struct tt_work; 1297 struct work_struct tt_work;
@@ -1251,7 +1327,8 @@ struct iwl_priv {
1251 u16 rx_traffic_idx; 1327 u16 rx_traffic_idx;
1252 u8 *tx_traffic; 1328 u8 *tx_traffic;
1253 u8 *rx_traffic; 1329 u8 *rx_traffic;
1254 struct iwl_debugfs *dbgfs; 1330 struct dentry *debugfs_dir;
1331 u32 dbgfs_sram_offset, dbgfs_sram_len;
1255#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1332#endif /* CONFIG_IWLWIFI_DEBUGFS */
1256#endif /* CONFIG_IWLWIFI_DEBUG */ 1333#endif /* CONFIG_IWLWIFI_DEBUG */
1257 1334
@@ -1261,6 +1338,7 @@ struct iwl_priv {
1261 u32 disable_tx_power_cal; 1338 u32 disable_tx_power_cal;
1262 struct work_struct run_time_calib_work; 1339 struct work_struct run_time_calib_work;
1263 struct timer_list statistics_periodic; 1340 struct timer_list statistics_periodic;
1341 struct timer_list ucode_trace;
1264 bool hw_ready; 1342 bool hw_ready;
1265 /*For 3945*/ 1343 /*For 3945*/
1266#define IWL_DEFAULT_TX_POWER 0x0F 1344#define IWL_DEFAULT_TX_POWER 0x0F
@@ -1268,6 +1346,8 @@ struct iwl_priv {
1268 struct iwl3945_notif_statistics statistics_39; 1346 struct iwl3945_notif_statistics statistics_39;
1269 1347
1270 u32 sta_supp_rates; 1348 u32 sta_supp_rates;
1349
1350 struct iwl_event_log event_log;
1271}; /*iwl_priv */ 1351}; /*iwl_priv */
1272 1352
1273static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1353static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 83cc4e500a96..36580d8d8b8d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -37,4 +37,6 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
40#endif 42#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index d9c7363b1bbb..ff4d012ce260 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -91,6 +91,50 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
91); 91);
92 92
93#undef TRACE_SYSTEM 93#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi_ucode
95
96TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
97 TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
98 TP_ARGS(priv, time, data, ev),
99 TP_STRUCT__entry(
100 PRIV_ENTRY
101
102 __field(u32, time)
103 __field(u32, data)
104 __field(u32, ev)
105 ),
106 TP_fast_assign(
107 PRIV_ASSIGN;
108 __entry->time = time;
109 __entry->data = data;
110 __entry->ev = ev;
111 ),
112 TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
113 __entry->priv, __entry->time, __entry->data, __entry->ev)
114);
115
116TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
117 TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
118 TP_ARGS(priv, wraps, n_entry, p_entry),
119 TP_STRUCT__entry(
120 PRIV_ENTRY
121
122 __field(u32, wraps)
123 __field(u32, n_entry)
124 __field(u32, p_entry)
125 ),
126 TP_fast_assign(
127 PRIV_ASSIGN;
128 __entry->wraps = wraps;
129 __entry->n_entry = n_entry;
130 __entry->p_entry = p_entry;
131 ),
132 TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
133 __entry->priv, __entry->wraps, __entry->n_entry,
134 __entry->p_entry)
135);
136
137#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi 138#define TRACE_SYSTEM iwlwifi
95 139
96TRACE_EVENT(iwlwifi_dev_hcmd, 140TRACE_EVENT(iwlwifi_dev_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 4a30969689ff..fd37152abae3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 0cd9c02ee044..4e1ba824dc50 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 65fa8a69fd5a..113c3669b9ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -379,6 +379,25 @@
379 379
380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010) 380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010)
381 381
382/**
383 * Bit fields for TSSR(Tx Shared Status & Control) error status register:
384 * 31: Indicates an address error when accessed to internal memory
385 * uCode/driver must write "1" in order to clear this flag
386 * 30: Indicates that Host did not send the expected number of dwords to FH
387 * uCode/driver must write "1" in order to clear this flag
388 * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA
389 * command was received from the scheduler while the TRB was already full
390 * with previous command
391 * uCode/driver must write "1" in order to clear this flag
392 * 7-0: Each status bit indicates a channel's TxCredit error. When an error
393 * bit is set, it indicates that the FH has received a full indication
394 * from the RTC TxFIFO and the current value of the TxCredit counter was
395 * not equal to zero. This mean that the credit mechanism was not
396 * synchronized to the TxFIFO status
397 * uCode/driver must write "1" in order to clear this flag
398 */
399#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
400
382#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) 401#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
383#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16) 402#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
384 403
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 30e9ea6d54ec..73681c4fefe7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -58,7 +58,6 @@ const char *get_cmd_string(u8 cmd)
58 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 58 IWL_CMD(COEX_PRIORITY_TABLE_CMD);
59 IWL_CMD(COEX_MEDIUM_NOTIFICATION); 59 IWL_CMD(COEX_MEDIUM_NOTIFICATION);
60 IWL_CMD(COEX_EVENT_CMD); 60 IWL_CMD(COEX_EVENT_CMD);
61 IWL_CMD(RADAR_NOTIFICATION);
62 IWL_CMD(REPLY_QUIET_CMD); 61 IWL_CMD(REPLY_QUIET_CMD);
63 IWL_CMD(REPLY_CHANNEL_SWITCH); 62 IWL_CMD(REPLY_CHANNEL_SWITCH);
64 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); 63 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
@@ -165,15 +164,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
165 /* A synchronous command can not have a callback set. */ 164 /* A synchronous command can not have a callback set. */
166 BUG_ON(cmd->callback); 165 BUG_ON(cmd->callback);
167 166
168 if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { 167 IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
169 IWL_ERR(priv,
170 "Error sending %s: Already sending a host command\n",
171 get_cmd_string(cmd->id)); 168 get_cmd_string(cmd->id));
172 ret = -EBUSY; 169 mutex_lock(&priv->sync_cmd_mutex);
173 goto out;
174 }
175 170
176 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 171 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
172 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n",
173 get_cmd_string(cmd->id));
177 174
178 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 175 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
179 if (cmd_idx < 0) { 176 if (cmd_idx < 0) {
@@ -194,6 +191,8 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
194 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 191 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
195 192
196 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 193 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
194 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
195 get_cmd_string(cmd->id));
197 ret = -ETIMEDOUT; 196 ret = -ETIMEDOUT;
198 goto cancel; 197 goto cancel;
199 } 198 }
@@ -238,7 +237,7 @@ fail:
238 cmd->reply_page = 0; 237 cmd->reply_page = 0;
239 } 238 }
240out: 239out:
241 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); 240 mutex_unlock(&priv->sync_cmd_mutex);
242 return ret; 241 return ret;
243} 242}
244EXPORT_SYMBOL(iwl_send_cmd_sync); 243EXPORT_SYMBOL(iwl_send_cmd_sync);
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index bd0b12efb5c7..51a67fb2e185 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -80,8 +80,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
80 struct fw_desc *desc) 80 struct fw_desc *desc)
81{ 81{
82 if (desc->v_addr) 82 if (desc->v_addr)
83 pci_free_consistent(pci_dev, desc->len, 83 dma_free_coherent(&pci_dev->dev, desc->len,
84 desc->v_addr, desc->p_addr); 84 desc->v_addr, desc->p_addr);
85 desc->v_addr = NULL; 85 desc->v_addr = NULL;
86 desc->len = 0; 86 desc->len = 0;
87} 87}
@@ -89,7 +89,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
89static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, 89static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
90 struct fw_desc *desc) 90 struct fw_desc *desc)
91{ 91{
92 desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); 92 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
93 &desc->p_addr, GFP_KERNEL);
93 return (desc->v_addr != NULL) ? 0 : -ENOMEM; 94 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
94} 95}
95 96
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index e552d4c4bdbe..c719baf2585a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 46c7a95b88f0..a6f9c918aabc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index f47f053f02ea..49a70baa3fb6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 8ccc0bb1d9ed..1a1a9f081cc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -303,13 +303,12 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
303 sizeof(struct iwl_powertable_cmd), cmd); 303 sizeof(struct iwl_powertable_cmd), cmd);
304} 304}
305 305
306 306/* priv->mutex must be held */
307int iwl_power_update_mode(struct iwl_priv *priv, bool force) 307int iwl_power_update_mode(struct iwl_priv *priv, bool force)
308{ 308{
309 int ret = 0; 309 int ret = 0;
310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
311 bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) && 311 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
312 (priv->hw->conf.flags & IEEE80211_CONF_PS);
313 bool update_chains; 312 bool update_chains;
314 struct iwl_powertable_cmd cmd; 313 struct iwl_powertable_cmd cmd;
315 int dtimper; 314 int dtimper;
@@ -319,7 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
319 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 318 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
320 319
321 if (priv->vif) 320 if (priv->vif)
322 dtimper = priv->vif->bss_conf.dtim_period; 321 dtimper = priv->hw->conf.ps_dtim_period;
323 else 322 else
324 dtimper = 1; 323 dtimper = 1;
325 324
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 310c32e8f698..5db91c10dcc8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6d95832db06d..d2d2a9174900 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2dbce85404aa..0d09f571e185 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -123,12 +123,11 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
123/** 123/**
124 * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue 124 * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
125 */ 125 */
126int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) 126void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
127{ 127{
128 unsigned long flags; 128 unsigned long flags;
129 u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; 129 u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
130 u32 reg; 130 u32 reg;
131 int ret = 0;
132 131
133 spin_lock_irqsave(&q->lock, flags); 132 spin_lock_irqsave(&q->lock, flags);
134 133
@@ -161,7 +160,6 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
161 160
162 exit_unlock: 161 exit_unlock:
163 spin_unlock_irqrestore(&q->lock, flags); 162 spin_unlock_irqrestore(&q->lock, flags);
164 return ret;
165} 163}
166EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); 164EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);
167/** 165/**
@@ -184,14 +182,13 @@ static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
184 * also updates the memory address in the firmware to reference the new 182 * also updates the memory address in the firmware to reference the new
185 * target buffer. 183 * target buffer.
186 */ 184 */
187int iwl_rx_queue_restock(struct iwl_priv *priv) 185void iwl_rx_queue_restock(struct iwl_priv *priv)
188{ 186{
189 struct iwl_rx_queue *rxq = &priv->rxq; 187 struct iwl_rx_queue *rxq = &priv->rxq;
190 struct list_head *element; 188 struct list_head *element;
191 struct iwl_rx_mem_buffer *rxb; 189 struct iwl_rx_mem_buffer *rxb;
192 unsigned long flags; 190 unsigned long flags;
193 int write; 191 int write;
194 int ret = 0;
195 192
196 spin_lock_irqsave(&rxq->lock, flags); 193 spin_lock_irqsave(&rxq->lock, flags);
197 write = rxq->write & ~0x7; 194 write = rxq->write & ~0x7;
@@ -220,10 +217,8 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
220 spin_lock_irqsave(&rxq->lock, flags); 217 spin_lock_irqsave(&rxq->lock, flags);
221 rxq->need_update = 1; 218 rxq->need_update = 1;
222 spin_unlock_irqrestore(&rxq->lock, flags); 219 spin_unlock_irqrestore(&rxq->lock, flags);
223 ret = iwl_rx_queue_update_write_ptr(priv, rxq); 220 iwl_rx_queue_update_write_ptr(priv, rxq);
224 } 221 }
225
226 return ret;
227} 222}
228EXPORT_SYMBOL(iwl_rx_queue_restock); 223EXPORT_SYMBOL(iwl_rx_queue_restock);
229 224
@@ -350,10 +345,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
350 } 345 }
351 } 346 }
352 347
353 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, 348 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
354 rxq->dma_addr); 349 rxq->dma_addr);
355 pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), 350 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
356 rxq->rb_stts, rxq->rb_stts_dma); 351 rxq->rb_stts, rxq->rb_stts_dma);
357 rxq->bd = NULL; 352 rxq->bd = NULL;
358 rxq->rb_stts = NULL; 353 rxq->rb_stts = NULL;
359} 354}
@@ -362,7 +357,7 @@ EXPORT_SYMBOL(iwl_rx_queue_free);
362int iwl_rx_queue_alloc(struct iwl_priv *priv) 357int iwl_rx_queue_alloc(struct iwl_priv *priv)
363{ 358{
364 struct iwl_rx_queue *rxq = &priv->rxq; 359 struct iwl_rx_queue *rxq = &priv->rxq;
365 struct pci_dev *dev = priv->pci_dev; 360 struct device *dev = &priv->pci_dev->dev;
366 int i; 361 int i;
367 362
368 spin_lock_init(&rxq->lock); 363 spin_lock_init(&rxq->lock);
@@ -370,12 +365,13 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
370 INIT_LIST_HEAD(&rxq->rx_used); 365 INIT_LIST_HEAD(&rxq->rx_used);
371 366
372 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ 367 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
373 rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); 368 rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr,
369 GFP_KERNEL);
374 if (!rxq->bd) 370 if (!rxq->bd)
375 goto err_bd; 371 goto err_bd;
376 372
377 rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status), 373 rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status),
378 &rxq->rb_stts_dma); 374 &rxq->rb_stts_dma, GFP_KERNEL);
379 if (!rxq->rb_stts) 375 if (!rxq->rb_stts)
380 goto err_rb; 376 goto err_rb;
381 377
@@ -392,8 +388,8 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
392 return 0; 388 return 0;
393 389
394err_rb: 390err_rb:
395 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, 391 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
396 rxq->dma_addr); 392 rxq->dma_addr);
397err_bd: 393err_bd:
398 return -ENOMEM; 394 return -ENOMEM;
399} 395}
@@ -473,8 +469,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| 469 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); 470 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
475 471
476 /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ 472 /* Set interrupt coalescing timer to default (2048 usecs) */
477 iwl_write8(priv, CSR_INT_COALESCING, 0x40); 473 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
478 474
479 return 0; 475 return 0;
480} 476}
@@ -499,9 +495,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
499 struct iwl_missed_beacon_notif *missed_beacon; 495 struct iwl_missed_beacon_notif *missed_beacon;
500 496
501 missed_beacon = &pkt->u.missed_beacon; 497 missed_beacon = &pkt->u.missed_beacon;
502 if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { 498 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
499 priv->missed_beacon_threshold) {
503 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 500 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
504 le32_to_cpu(missed_beacon->consequtive_missed_beacons), 501 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
505 le32_to_cpu(missed_beacon->total_missed_becons), 502 le32_to_cpu(missed_beacon->total_missed_becons),
506 le32_to_cpu(missed_beacon->num_recvd_beacons), 503 le32_to_cpu(missed_beacon->num_recvd_beacons),
507 le32_to_cpu(missed_beacon->num_expected_beacons)); 504 le32_to_cpu(missed_beacon->num_expected_beacons));
@@ -511,6 +508,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
511} 508}
512EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 509EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
513 510
511void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
512 struct iwl_rx_mem_buffer *rxb)
513{
514 struct iwl_rx_packet *pkt = rxb_addr(rxb);
515 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
516
517 if (!report->state) {
518 IWL_DEBUG_11H(priv,
519 "Spectrum Measure Notification: Start\n");
520 return;
521 }
522
523 memcpy(&priv->measure_report, report, sizeof(*report));
524 priv->measurement_status |= MEASUREMENT_READY;
525}
526EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
527
528
514 529
515/* Calculate noise level, based on measurements during network silence just 530/* Calculate noise level, based on measurements during network silence just
516 * before arriving beacon. This measurement can be done only if we know 531 * before arriving beacon. This measurement can be done only if we know
@@ -564,15 +579,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
564 int i; 579 int i;
565 __le32 *prev_stats; 580 __le32 *prev_stats;
566 u32 *accum_stats; 581 u32 *accum_stats;
582 u32 *delta, *max_delta;
567 583
568 prev_stats = (__le32 *)&priv->statistics; 584 prev_stats = (__le32 *)&priv->statistics;
569 accum_stats = (u32 *)&priv->accum_statistics; 585 accum_stats = (u32 *)&priv->accum_statistics;
586 delta = (u32 *)&priv->delta_statistics;
587 max_delta = (u32 *)&priv->max_delta;
570 588
571 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 589 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
572 i += sizeof(__le32), stats++, prev_stats++, accum_stats++) 590 i += sizeof(__le32), stats++, prev_stats++, delta++,
573 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) 591 max_delta++, accum_stats++) {
574 *accum_stats += (le32_to_cpu(*stats) - 592 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
593 *delta = (le32_to_cpu(*stats) -
575 le32_to_cpu(*prev_stats)); 594 le32_to_cpu(*prev_stats));
595 *accum_stats += *delta;
596 if (*delta > *max_delta)
597 *max_delta = *delta;
598 }
599 }
576 600
577 /* reset accumulative statistics for "no-counter" type statistics */ 601 /* reset accumulative statistics for "no-counter" type statistics */
578 priv->accum_statistics.general.temperature = 602 priv->accum_statistics.general.temperature =
@@ -592,11 +616,23 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
592 616
593#define REG_RECALIB_PERIOD (60) 617#define REG_RECALIB_PERIOD (60)
594 618
619/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
620#define ACK_CNT_RATIO (50)
621#define BA_TIMEOUT_CNT (5)
622#define BA_TIMEOUT_MAX (16)
623
624#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
595void iwl_rx_statistics(struct iwl_priv *priv, 625void iwl_rx_statistics(struct iwl_priv *priv,
596 struct iwl_rx_mem_buffer *rxb) 626 struct iwl_rx_mem_buffer *rxb)
597{ 627{
598 int change; 628 int change;
599 struct iwl_rx_packet *pkt = rxb_addr(rxb); 629 struct iwl_rx_packet *pkt = rxb_addr(rxb);
630 int combined_plcp_delta;
631 unsigned int plcp_msec;
632 unsigned long plcp_received_jiffies;
633 int actual_ack_cnt_delta;
634 int expected_ack_cnt_delta;
635 int ba_timeout_delta;
600 636
601 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 637 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
602 (int)sizeof(priv->statistics), 638 (int)sizeof(priv->statistics),
@@ -611,6 +647,94 @@ void iwl_rx_statistics(struct iwl_priv *priv,
611#ifdef CONFIG_IWLWIFI_DEBUG 647#ifdef CONFIG_IWLWIFI_DEBUG
612 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 648 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
613#endif 649#endif
650 actual_ack_cnt_delta = le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
651 le32_to_cpu(priv->statistics.tx.actual_ack_cnt);
652 expected_ack_cnt_delta = le32_to_cpu(
653 pkt->u.stats.tx.expected_ack_cnt) -
654 le32_to_cpu(priv->statistics.tx.expected_ack_cnt);
655 ba_timeout_delta = le32_to_cpu(
656 pkt->u.stats.tx.agg.ba_timeout) -
657 le32_to_cpu(priv->statistics.tx.agg.ba_timeout);
658 if ((priv->agg_tids_count > 0) &&
659 (expected_ack_cnt_delta > 0) &&
660 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) <
661 ACK_CNT_RATIO) &&
662 (ba_timeout_delta > BA_TIMEOUT_CNT)) {
663 IWL_DEBUG_RADIO(priv,
664 "actual_ack_cnt delta = %d, expected_ack_cnt = %d\n",
665 actual_ack_cnt_delta, expected_ack_cnt_delta);
666
667#ifdef CONFIG_IWLWIFI_DEBUG
668 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
669 priv->delta_statistics.tx.rx_detected_cnt);
670 IWL_DEBUG_RADIO(priv,
671 "ack_or_ba_timeout_collision delta = %d\n",
672 priv->delta_statistics.tx.ack_or_ba_timeout_collision);
673#endif
674 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
675 ba_timeout_delta);
676 if ((actual_ack_cnt_delta == 0) &&
677 (ba_timeout_delta >=
678 BA_TIMEOUT_MAX)) {
679 IWL_DEBUG_RADIO(priv,
680 "call iwl_force_reset(IWL_FW_RESET)\n");
681 iwl_force_reset(priv, IWL_FW_RESET);
682 } else {
683 IWL_DEBUG_RADIO(priv,
684 "call iwl_force_reset(IWL_RF_RESET)\n");
685 iwl_force_reset(priv, IWL_RF_RESET);
686 }
687 }
688 /*
689 * check for plcp_err and trigger radio reset if it exceeds
690 * the plcp error threshold plcp_delta.
691 */
692 plcp_received_jiffies = jiffies;
693 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
694 (long) priv->plcp_jiffies);
695 priv->plcp_jiffies = plcp_received_jiffies;
696 /*
697 * check to make sure plcp_msec is not 0 to prevent division
698 * by zero.
699 */
700 if (plcp_msec) {
701 combined_plcp_delta =
702 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
703 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
704 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
705 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
706
707 if ((combined_plcp_delta > 0) &&
708 ((combined_plcp_delta * 100) / plcp_msec) >
709 priv->cfg->plcp_delta_threshold) {
710 /*
711 * if plcp_err exceed the threshold, the following
712 * data is printed in csv format:
713 * Text: plcp_err exceeded %d,
714 * Received ofdm.plcp_err,
715 * Current ofdm.plcp_err,
716 * Received ofdm_ht.plcp_err,
717 * Current ofdm_ht.plcp_err,
718 * combined_plcp_delta,
719 * plcp_msec
720 */
721 IWL_DEBUG_RADIO(priv, PLCP_MSG,
722 priv->cfg->plcp_delta_threshold,
723 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
724 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
725 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
726 le32_to_cpu(
727 priv->statistics.rx.ofdm_ht.plcp_err),
728 combined_plcp_delta, plcp_msec);
729
730 /*
731 * Reset the RF radio due to the high plcp
732 * error rate
733 */
734 iwl_force_reset(priv, IWL_RF_RESET);
735 }
736 }
737
614 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 738 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
615 739
616 set_bit(STATUS_STATISTICS, &priv->status); 740 set_bit(STATUS_STATISTICS, &priv->status);
@@ -638,11 +762,13 @@ void iwl_reply_statistics(struct iwl_priv *priv,
638 struct iwl_rx_packet *pkt = rxb_addr(rxb); 762 struct iwl_rx_packet *pkt = rxb_addr(rxb);
639 763
640 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 764 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
641 memset(&priv->statistics, 0,
642 sizeof(struct iwl_notif_statistics));
643#ifdef CONFIG_IWLWIFI_DEBUG 765#ifdef CONFIG_IWLWIFI_DEBUG
644 memset(&priv->accum_statistics, 0, 766 memset(&priv->accum_statistics, 0,
645 sizeof(struct iwl_notif_statistics)); 767 sizeof(struct iwl_notif_statistics));
768 memset(&priv->delta_statistics, 0,
769 sizeof(struct iwl_notif_statistics));
770 memset(&priv->max_delta, 0,
771 sizeof(struct iwl_notif_statistics));
646#endif 772#endif
647 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 773 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
648 } 774 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index fa1c89ba6459..dd9ff2ed645a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -192,19 +192,17 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
192 IWL_DEBUG_SCAN(priv, "Scan ch.res: " 192 IWL_DEBUG_SCAN(priv, "Scan ch.res: "
193 "%d [802.11%s] " 193 "%d [802.11%s] "
194 "(TSF: 0x%08X:%08X) - %d " 194 "(TSF: 0x%08X:%08X) - %d "
195 "elapsed=%lu usec (%dms since last)\n", 195 "elapsed=%lu usec\n",
196 notif->channel, 196 notif->channel,
197 notif->band ? "bg" : "a", 197 notif->band ? "bg" : "a",
198 le32_to_cpu(notif->tsf_high), 198 le32_to_cpu(notif->tsf_high),
199 le32_to_cpu(notif->tsf_low), 199 le32_to_cpu(notif->tsf_low),
200 le32_to_cpu(notif->statistics[0]), 200 le32_to_cpu(notif->statistics[0]),
201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, 201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
202 jiffies_to_msecs(elapsed_jiffies
203 (priv->last_scan_jiffies, jiffies)));
204#endif 202#endif
205 203
206 priv->last_scan_jiffies = jiffies; 204 if (!priv->is_internal_short_scan)
207 priv->next_scan_jiffies = 0; 205 priv->next_scan_jiffies = 0;
208} 206}
209 207
210/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 208/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -250,8 +248,9 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
250 goto reschedule; 248 goto reschedule;
251 } 249 }
252 250
253 priv->last_scan_jiffies = jiffies; 251 if (!priv->is_internal_short_scan)
254 priv->next_scan_jiffies = 0; 252 priv->next_scan_jiffies = 0;
253
255 IWL_DEBUG_INFO(priv, "Setting scan to off\n"); 254 IWL_DEBUG_INFO(priv, "Setting scan to off\n");
256 255
257 clear_bit(STATUS_SCANNING, &priv->status); 256 clear_bit(STATUS_SCANNING, &priv->status);
@@ -314,6 +313,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
314} 313}
315EXPORT_SYMBOL(iwl_get_passive_dwell_time); 314EXPORT_SYMBOL(iwl_get_passive_dwell_time);
316 315
316static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
317 enum ieee80211_band band,
318 struct iwl_scan_channel *scan_ch)
319{
320 const struct ieee80211_supported_band *sband;
321 const struct iwl_channel_info *ch_info;
322 u16 passive_dwell = 0;
323 u16 active_dwell = 0;
324 int i, added = 0;
325 u16 channel = 0;
326
327 sband = iwl_get_hw_mode(priv, band);
328 if (!sband) {
329 IWL_ERR(priv, "invalid band\n");
330 return added;
331 }
332
333 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
334 passive_dwell = iwl_get_passive_dwell_time(priv, band);
335
336 if (passive_dwell <= active_dwell)
337 passive_dwell = active_dwell + 1;
338
339 /* only scan single channel, good enough to reset the RF */
340 /* pick the first valid not in-use channel */
341 if (band == IEEE80211_BAND_5GHZ) {
342 for (i = 14; i < priv->channel_count; i++) {
343 if (priv->channel_info[i].channel !=
344 le16_to_cpu(priv->staging_rxon.channel)) {
345 channel = priv->channel_info[i].channel;
346 ch_info = iwl_get_channel_info(priv,
347 band, channel);
348 if (is_channel_valid(ch_info))
349 break;
350 }
351 }
352 } else {
353 for (i = 0; i < 14; i++) {
354 if (priv->channel_info[i].channel !=
355 le16_to_cpu(priv->staging_rxon.channel)) {
356 channel =
357 priv->channel_info[i].channel;
358 ch_info = iwl_get_channel_info(priv,
359 band, channel);
360 if (is_channel_valid(ch_info))
361 break;
362 }
363 }
364 }
365 if (channel) {
366 scan_ch->channel = cpu_to_le16(channel);
367 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
368 scan_ch->active_dwell = cpu_to_le16(active_dwell);
369 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
370 /* Set txpower levels to defaults */
371 scan_ch->dsp_atten = 110;
372 if (band == IEEE80211_BAND_5GHZ)
373 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
374 else
375 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
376 added++;
377 } else
378 IWL_ERR(priv, "no valid channel found\n");
379 return added;
380}
381
317static int iwl_get_channels_for_scan(struct iwl_priv *priv, 382static int iwl_get_channels_for_scan(struct iwl_priv *priv,
318 enum ieee80211_band band, 383 enum ieee80211_band band,
319 u8 is_active, u8 n_probes, 384 u8 is_active, u8 n_probes,
@@ -404,23 +469,9 @@ EXPORT_SYMBOL(iwl_init_scan_params);
404 469
405static int iwl_scan_initiate(struct iwl_priv *priv) 470static int iwl_scan_initiate(struct iwl_priv *priv)
406{ 471{
407 if (!iwl_is_ready_rf(priv)) {
408 IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
409 return -EIO;
410 }
411
412 if (test_bit(STATUS_SCANNING, &priv->status)) {
413 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
414 return -EAGAIN;
415 }
416
417 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
418 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
419 return -EAGAIN;
420 }
421
422 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 472 IWL_DEBUG_INFO(priv, "Starting scan...\n");
423 set_bit(STATUS_SCANNING, &priv->status); 473 set_bit(STATUS_SCANNING, &priv->status);
474 priv->is_internal_short_scan = false;
424 priv->scan_start = jiffies; 475 priv->scan_start = jiffies;
425 priv->scan_pass_start = priv->scan_start; 476 priv->scan_pass_start = priv->scan_start;
426 477
@@ -449,6 +500,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
449 goto out_unlock; 500 goto out_unlock;
450 } 501 }
451 502
503 if (test_bit(STATUS_SCANNING, &priv->status)) {
504 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
505 ret = -EAGAIN;
506 goto out_unlock;
507 }
508
509 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
510 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
511 ret = -EAGAIN;
512 goto out_unlock;
513 }
514
452 /* We don't schedule scan within next_scan_jiffies period. 515 /* We don't schedule scan within next_scan_jiffies period.
453 * Avoid scanning during possible EAPOL exchange, return 516 * Avoid scanning during possible EAPOL exchange, return
454 * success immediately. 517 * success immediately.
@@ -461,15 +524,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
461 goto out_unlock; 524 goto out_unlock;
462 } 525 }
463 526
464 /* if we just finished scan ask for delay */
465 if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
466 time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
467 IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
468 queue_work(priv->workqueue, &priv->scan_completed);
469 ret = 0;
470 goto out_unlock;
471 }
472
473 priv->scan_bands = 0; 527 priv->scan_bands = 0;
474 for (i = 0; i < req->n_channels; i++) 528 for (i = 0; i < req->n_channels; i++)
475 priv->scan_bands |= BIT(req->channels[i]->band); 529 priv->scan_bands |= BIT(req->channels[i]->band);
@@ -488,6 +542,46 @@ out_unlock:
488} 542}
489EXPORT_SYMBOL(iwl_mac_hw_scan); 543EXPORT_SYMBOL(iwl_mac_hw_scan);
490 544
545/*
546 * internal short scan, this function should only been called while associated.
547 * It will reset and tune the radio to prevent possible RF related problem
548 */
549int iwl_internal_short_hw_scan(struct iwl_priv *priv)
550{
551 int ret = 0;
552
553 if (!iwl_is_ready_rf(priv)) {
554 ret = -EIO;
555 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
556 goto out;
557 }
558 if (test_bit(STATUS_SCANNING, &priv->status)) {
559 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
560 ret = -EAGAIN;
561 goto out;
562 }
563 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
564 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
565 ret = -EAGAIN;
566 goto out;
567 }
568
569 priv->scan_bands = 0;
570 if (priv->band == IEEE80211_BAND_5GHZ)
571 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
572 else
573 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
574
575 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
576 set_bit(STATUS_SCANNING, &priv->status);
577 priv->is_internal_short_scan = true;
578 queue_work(priv->workqueue, &priv->request_scan);
579
580out:
581 return ret;
582}
583EXPORT_SYMBOL(iwl_internal_short_hw_scan);
584
491#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 585#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
492 586
493void iwl_bg_scan_check(struct work_struct *data) 587void iwl_bg_scan_check(struct work_struct *data)
@@ -544,14 +638,26 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
544 if (left < 0) 638 if (left < 0)
545 return 0; 639 return 0;
546 *pos++ = WLAN_EID_SSID; 640 *pos++ = WLAN_EID_SSID;
547 *pos++ = 0; 641 if (!priv->is_internal_short_scan &&
548 642 priv->scan_request->n_ssids) {
549 len += 2; 643 struct cfg80211_ssid *ssid =
644 priv->scan_request->ssids;
645
646 /* Broadcast if ssid_len is 0 */
647 *pos++ = ssid->ssid_len;
648 memcpy(pos, ssid->ssid, ssid->ssid_len);
649 pos += ssid->ssid_len;
650 len += 2 + ssid->ssid_len;
651 } else {
652 *pos++ = 0;
653 len += 2;
654 }
550 655
551 if (WARN_ON(left < ie_len)) 656 if (WARN_ON(left < ie_len))
552 return len; 657 return len;
553 658
554 memcpy(pos, ies, ie_len); 659 if (ies)
660 memcpy(pos, ies, ie_len);
555 len += ie_len; 661 len += ie_len;
556 left -= ie_len; 662 left -= ie_len;
557 663
@@ -654,7 +760,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
654 unsigned long flags; 760 unsigned long flags;
655 761
656 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 762 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
657
658 spin_lock_irqsave(&priv->lock, flags); 763 spin_lock_irqsave(&priv->lock, flags);
659 interval = priv->beacon_int; 764 interval = priv->beacon_int;
660 spin_unlock_irqrestore(&priv->lock, flags); 765 spin_unlock_irqrestore(&priv->lock, flags);
@@ -672,21 +777,29 @@ static void iwl_bg_request_scan(struct work_struct *data)
672 scan_suspend_time, interval); 777 scan_suspend_time, interval);
673 } 778 }
674 779
675 if (priv->scan_request->n_ssids) { 780 if (priv->is_internal_short_scan) {
676 int i, p = 0; 781 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
782 } else if (priv->scan_request->n_ssids) {
677 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 783 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
678 for (i = 0; i < priv->scan_request->n_ssids; i++) { 784 /*
679 /* always does wildcard anyway */ 785 * The first SSID to scan is stuffed into the probe request
680 if (!priv->scan_request->ssids[i].ssid_len) 786 * template and the remaining ones are handled through the
681 continue; 787 * direct_scan array.
682 scan->direct_scan[p].id = WLAN_EID_SSID; 788 */
683 scan->direct_scan[p].len = 789 if (priv->scan_request->n_ssids > 1) {
684 priv->scan_request->ssids[i].ssid_len; 790 int i, p = 0;
685 memcpy(scan->direct_scan[p].ssid, 791 for (i = 1; i < priv->scan_request->n_ssids; i++) {
686 priv->scan_request->ssids[i].ssid, 792 if (!priv->scan_request->ssids[i].ssid_len)
687 priv->scan_request->ssids[i].ssid_len); 793 continue;
688 n_probes++; 794 scan->direct_scan[p].id = WLAN_EID_SSID;
689 p++; 795 scan->direct_scan[p].len =
796 priv->scan_request->ssids[i].ssid_len;
797 memcpy(scan->direct_scan[p].ssid,
798 priv->scan_request->ssids[i].ssid,
799 priv->scan_request->ssids[i].ssid_len);
800 n_probes++;
801 p++;
802 }
690 } 803 }
691 is_active = true; 804 is_active = true;
692 } else 805 } else
@@ -753,24 +866,38 @@ static void iwl_bg_request_scan(struct work_struct *data)
753 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 866 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
754 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 867 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
755 scan->rx_chain = cpu_to_le16(rx_chain); 868 scan->rx_chain = cpu_to_le16(rx_chain);
756 cmd_len = iwl_fill_probe_req(priv, 869 if (!priv->is_internal_short_scan) {
757 (struct ieee80211_mgmt *)scan->data, 870 cmd_len = iwl_fill_probe_req(priv,
758 priv->scan_request->ie, 871 (struct ieee80211_mgmt *)scan->data,
759 priv->scan_request->ie_len, 872 priv->scan_request->ie,
760 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 873 priv->scan_request->ie_len,
874 IWL_MAX_SCAN_SIZE - sizeof(*scan));
875 } else {
876 cmd_len = iwl_fill_probe_req(priv,
877 (struct ieee80211_mgmt *)scan->data,
878 NULL, 0,
879 IWL_MAX_SCAN_SIZE - sizeof(*scan));
761 880
881 }
762 scan->tx_cmd.len = cpu_to_le16(cmd_len); 882 scan->tx_cmd.len = cpu_to_le16(cmd_len);
763
764 if (iwl_is_monitor_mode(priv)) 883 if (iwl_is_monitor_mode(priv))
765 scan->filter_flags = RXON_FILTER_PROMISC_MSK; 884 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
766 885
767 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | 886 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
768 RXON_FILTER_BCON_AWARE_MSK); 887 RXON_FILTER_BCON_AWARE_MSK);
769 888
770 scan->channel_count = 889 if (priv->is_internal_short_scan) {
771 iwl_get_channels_for_scan(priv, band, is_active, n_probes, 890 scan->channel_count =
772 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 891 iwl_get_single_channel_for_scan(priv, band,
773 892 (void *)&scan->data[le16_to_cpu(
893 scan->tx_cmd.len)]);
894 } else {
895 scan->channel_count =
896 iwl_get_channels_for_scan(priv, band,
897 is_active, n_probes,
898 (void *)&scan->data[le16_to_cpu(
899 scan->tx_cmd.len)]);
900 }
774 if (scan->channel_count == 0) { 901 if (scan->channel_count == 0) {
775 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 902 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
776 goto done; 903 goto done;
@@ -831,7 +958,12 @@ void iwl_bg_scan_completed(struct work_struct *work)
831 958
832 cancel_delayed_work(&priv->scan_check); 959 cancel_delayed_work(&priv->scan_check);
833 960
834 ieee80211_scan_completed(priv->hw, false); 961 if (!priv->is_internal_short_scan)
962 ieee80211_scan_completed(priv->hw, false);
963 else {
964 priv->is_internal_short_scan = false;
965 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
966 }
835 967
836 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 968 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
837 return; 969 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
deleted file mode 100644
index 1ea5cd345fe8..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38
39#include <net/mac80211.h>
40
41#include "iwl-eeprom.h"
42#include "iwl-dev.h"
43#include "iwl-core.h"
44#include "iwl-io.h"
45#include "iwl-spectrum.h"
46
47#define BEACON_TIME_MASK_LOW 0x00FFFFFF
48#define BEACON_TIME_MASK_HIGH 0xFF000000
49#define TIME_UNIT 1024
50
51/*
52 * extended beacon time format
53 * time in usec will be changed into a 32-bit value in 8:24 format
54 * the high 1 byte is the beacon counts
55 * the lower 3 bytes is the time in usec within one beacon interval
56 */
57
58/* TOOD: was used in sysfs debug interface need to add to mac */
59#if 0
60static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
61{
62 u32 quot;
63 u32 rem;
64 u32 interval = beacon_interval * 1024;
65
66 if (!interval || !usec)
67 return 0;
68
69 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
70 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
71
72 return (quot << 24) + rem;
73}
74
75/* base is usually what we get from ucode with each received frame,
76 * the same as HW timer counter counting down
77 */
78
79static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
80{
81 u32 base_low = base & BEACON_TIME_MASK_LOW;
82 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
83 u32 interval = beacon_interval * TIME_UNIT;
84 u32 res = (base & BEACON_TIME_MASK_HIGH) +
85 (addon & BEACON_TIME_MASK_HIGH);
86
87 if (base_low > addon_low)
88 res += base_low - addon_low;
89 else if (base_low < addon_low) {
90 res += interval + base_low - addon_low;
91 res += (1 << 24);
92 } else
93 res += (1 << 24);
94
95 return cpu_to_le32(res);
96}
97static int iwl_get_measurement(struct iwl_priv *priv,
98 struct ieee80211_measurement_params *params,
99 u8 type)
100{
101 struct iwl4965_spectrum_cmd spectrum;
102 struct iwl_rx_packet *res;
103 struct iwl_host_cmd cmd = {
104 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
105 .data = (void *)&spectrum,
106 .meta.flags = CMD_WANT_SKB,
107 };
108 u32 add_time = le64_to_cpu(params->start_time);
109 int rc;
110 int spectrum_resp_status;
111 int duration = le16_to_cpu(params->duration);
112
113 if (iwl_is_associated(priv))
114 add_time =
115 iwl_usecs_to_beacons(
116 le64_to_cpu(params->start_time) - priv->last_tsf,
117 le16_to_cpu(priv->rxon_timing.beacon_interval));
118
119 memset(&spectrum, 0, sizeof(spectrum));
120
121 spectrum.channel_count = cpu_to_le16(1);
122 spectrum.flags =
123 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
124 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
125 cmd.len = sizeof(spectrum);
126 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
127
128 if (iwl_is_associated(priv))
129 spectrum.start_time =
130 iwl_add_beacon_time(priv->last_beacon_time,
131 add_time,
132 le16_to_cpu(priv->rxon_timing.beacon_interval));
133 else
134 spectrum.start_time = 0;
135
136 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
137 spectrum.channels[0].channel = params->channel;
138 spectrum.channels[0].type = type;
139 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
140 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
141 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
142
143 rc = iwl_send_cmd_sync(priv, &cmd);
144 if (rc)
145 return rc;
146
147 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
148 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
149 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
150 rc = -EIO;
151 }
152
153 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
154 switch (spectrum_resp_status) {
155 case 0: /* Command will be handled */
156 if (res->u.spectrum.id != 0xff) {
157 IWL_DEBUG_INFO(priv,
158 "Replaced existing measurement: %d\n",
159 res->u.spectrum.id);
160 priv->measurement_status &= ~MEASUREMENT_READY;
161 }
162 priv->measurement_status |= MEASUREMENT_ACTIVE;
163 rc = 0;
164 break;
165
166 case 1: /* Command will not be handled */
167 rc = -EAGAIN;
168 break;
169 }
170
171 dev_kfree_skb_any(cmd.meta.u.skb);
172
173 return rc;
174}
175#endif
176
177static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
178 struct iwl_rx_mem_buffer *rxb)
179{
180 struct iwl_rx_packet *pkt = rxb_addr(rxb);
181 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
182
183 if (!report->state) {
184 IWL_DEBUG_11H(priv,
185 "Spectrum Measure Notification: Start\n");
186 return;
187 }
188
189 memcpy(&priv->measure_report, report, sizeof(*report));
190 priv->measurement_status |= MEASUREMENT_READY;
191}
192
193void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
194{
195 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
196 iwl_rx_spectrum_measure_notif;
197}
198EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index a77c1e619062..af6babee2891 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ieee80211 subsystem header files. 5 * Portions of this file are derived from the ieee80211 subsystem header files.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 90fbdb25399e..4a6686fa6b36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
82 82
83/* priv->sta_lock must be held */
83static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 84static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
84{ 85{
85 unsigned long flags;
86
87 spin_lock_irqsave(&priv->sta_lock, flags);
88 86
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) 87 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 88 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
91 sta_id); 89 sta_id, priv->stations[sta_id].sta.sta.addr);
92
93 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
94 IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
95 priv->stations[sta_id].sta.sta.addr);
96 90
97 spin_unlock_irqrestore(&priv->sta_lock, flags); 91 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
92 IWL_DEBUG_ASSOC(priv,
93 "STA id %u addr %pM already present in uCode (according to driver)\n",
94 sta_id, priv->stations[sta_id].sta.sta.addr);
95 } else {
96 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
97 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
98 sta_id, priv->stations[sta_id].sta.sta.addr);
99 }
98} 100}
99 101
100static void iwl_add_sta_callback(struct iwl_priv *priv, 102static void iwl_process_add_sta_resp(struct iwl_priv *priv,
101 struct iwl_device_cmd *cmd, 103 struct iwl_addsta_cmd *addsta,
102 struct iwl_rx_packet *pkt) 104 struct iwl_rx_packet *pkt,
105 bool sync)
103{ 106{
104 struct iwl_addsta_cmd *addsta =
105 (struct iwl_addsta_cmd *)cmd->cmd.payload;
106 u8 sta_id = addsta->sta.sta_id; 107 u8 sta_id = addsta->sta.sta_id;
108 unsigned long flags;
107 109
108 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 110 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
109 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 111 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
110 pkt->hdr.flags); 112 pkt->hdr.flags);
111 return; 113 return;
112 } 114 }
113 115
116 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
117 sta_id);
118
119 spin_lock_irqsave(&priv->sta_lock, flags);
120
114 switch (pkt->u.add_sta.status) { 121 switch (pkt->u.add_sta.status) {
115 case ADD_STA_SUCCESS_MSK: 122 case ADD_STA_SUCCESS_MSK:
123 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
116 iwl_sta_ucode_activate(priv, sta_id); 124 iwl_sta_ucode_activate(priv, sta_id);
117 /* fall through */ 125 break;
126 case ADD_STA_NO_ROOM_IN_TABLE:
127 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
128 sta_id);
129 break;
130 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
131 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
132 sta_id);
133 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
136 sta_id);
137 break;
118 default: 138 default:
119 IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", 139 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
120 pkt->u.add_sta.status); 140 pkt->u.add_sta.status);
121 break; 141 break;
122 } 142 }
143
144 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
145 priv->stations[sta_id].sta.mode ==
146 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
147 sta_id, priv->stations[sta_id].sta.sta.addr);
148
149 /*
150 * XXX: The MAC address in the command buffer is often changed from
151 * the original sent to the device. That is, the MAC address
152 * written to the command buffer often is not the same MAC adress
153 * read from the command buffer when the command returns. This
154 * issue has not yet been resolved and this debugging is left to
155 * observe the problem.
156 */
157 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
158 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags);
169}
170
171static void iwl_add_sta_callback(struct iwl_priv *priv,
172 struct iwl_device_cmd *cmd,
173 struct iwl_rx_packet *pkt)
174{
175 struct iwl_addsta_cmd *addsta =
176 (struct iwl_addsta_cmd *)cmd->cmd.payload;
177
178 iwl_process_add_sta_resp(priv, addsta, pkt, false);
179
123} 180}
124 181
125int iwl_send_add_sta(struct iwl_priv *priv, 182int iwl_send_add_sta(struct iwl_priv *priv,
@@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
145 if (ret || (flags & CMD_ASYNC)) 202 if (ret || (flags & CMD_ASYNC))
146 return ret; 203 return ret;
147 204
148 pkt = (struct iwl_rx_packet *)cmd.reply_page;
149 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
150 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
151 pkt->hdr.flags);
152 ret = -EIO;
153 }
154
155 if (ret == 0) { 205 if (ret == 0) {
156 switch (pkt->u.add_sta.status) { 206 pkt = (struct iwl_rx_packet *)cmd.reply_page;
157 case ADD_STA_SUCCESS_MSK: 207 iwl_process_add_sta_resp(priv, sta, pkt, true);
158 iwl_sta_ucode_activate(priv, sta->sta.sta_id);
159 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
160 break;
161 default:
162 ret = -EIO;
163 IWL_WARN(priv, "REPLY_ADD_STA failed\n");
164 break;
165 }
166 } 208 }
167 iwl_free_pages(priv, cmd.reply_page); 209 iwl_free_pages(priv, cmd.reply_page);
168 210
@@ -1003,24 +1045,19 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1003 struct ieee80211_sta_ht_cap *cur_ht_config = NULL; 1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1004 u8 sta_id; 1046 u8 sta_id;
1005 1047
1006 /* Add station to device's station table */
1007
1008 /* 1048 /*
1009 * XXX: This check is definitely not correct, if we're an AP 1049 * Set HT capabilities. It is ok to set this struct even if not using
1010 * it'll always be false which is not what we want, but 1050 * HT config: the priv->current_ht_config.is_ht flag will just be false
1011 * it doesn't look like iwlagn is prepared to be an HT
1012 * AP anyway.
1013 */ 1051 */
1014 if (priv->current_ht_config.is_ht) { 1052 rcu_read_lock();
1015 rcu_read_lock(); 1053 sta = ieee80211_find_sta(priv->vif, addr);
1016 sta = ieee80211_find_sta(priv->vif, addr); 1054 if (sta) {
1017 if (sta) { 1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1018 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); 1056 cur_ht_config = &ht_config;
1019 cur_ht_config = &ht_config;
1020 }
1021 rcu_read_unlock();
1022 } 1057 }
1058 rcu_read_unlock();
1023 1059
1060 /* Add station to device's station table */
1024 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); 1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1025 1062
1026 /* Set up default rate scaling table in device's station table */ 1063 /* Set up default rate scaling table in device's station table */
@@ -1085,6 +1122,7 @@ static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1085 */ 1122 */
1086void iwl_add_bcast_station(struct iwl_priv *priv) 1123void iwl_add_bcast_station(struct iwl_priv *priv)
1087{ 1124{
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1088 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1089 1127
1090 /* Set up default rate scaling table in device's station table */ 1128 /* Set up default rate scaling table in device's station table */
@@ -1093,6 +1131,16 @@ void iwl_add_bcast_station(struct iwl_priv *priv)
1093EXPORT_SYMBOL(iwl_add_bcast_station); 1131EXPORT_SYMBOL(iwl_add_bcast_station);
1094 1132
1095/** 1133/**
1134 * iwl3945_add_bcast_station - add broadcast station into station table.
1135 */
1136void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1140}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station);
1142
1143/**
1096 * iwl_get_sta_id - Find station's index within station table 1144 * iwl_get_sta_id - Find station's index within station table
1097 * 1145 *
1098 * If new IBSS station, create new entry in station table 1146 * If new IBSS station, create new entry in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 8d052de2d405..2dc35fe28f56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
53 53
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55void iwl_add_bcast_station(struct iwl_priv *priv); 55void iwl_add_bcast_station(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv);
56int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
57void iwl_clear_stations_table(struct iwl_priv *priv); 58void iwl_clear_stations_table(struct iwl_priv *priv);
58int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 59int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 8f4071562857..10701b8eef23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -60,7 +60,8 @@ static const u16 default_tid_to_tx_fifo[] = {
60static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, 60static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
61 struct iwl_dma_ptr *ptr, size_t size) 61 struct iwl_dma_ptr *ptr, size_t size)
62{ 62{
63 ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma); 63 ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
64 GFP_KERNEL);
64 if (!ptr->addr) 65 if (!ptr->addr)
65 return -ENOMEM; 66 return -ENOMEM;
66 ptr->size = size; 67 ptr->size = size;
@@ -73,21 +74,20 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
73 if (unlikely(!ptr->addr)) 74 if (unlikely(!ptr->addr))
74 return; 75 return;
75 76
76 pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma); 77 dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
77 memset(ptr, 0, sizeof(*ptr)); 78 memset(ptr, 0, sizeof(*ptr));
78} 79}
79 80
80/** 81/**
81 * iwl_txq_update_write_ptr - Send new write index to hardware 82 * iwl_txq_update_write_ptr - Send new write index to hardware
82 */ 83 */
83int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) 84void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
84{ 85{
85 u32 reg = 0; 86 u32 reg = 0;
86 int ret = 0;
87 int txq_id = txq->q.id; 87 int txq_id = txq->q.id;
88 88
89 if (txq->need_update == 0) 89 if (txq->need_update == 0)
90 return ret; 90 return;
91 91
92 /* if we're trying to save power */ 92 /* if we're trying to save power */
93 if (test_bit(STATUS_POWER_PMI, &priv->status)) { 93 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
@@ -101,7 +101,7 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
101 txq_id, reg); 101 txq_id, reg);
102 iwl_set_bit(priv, CSR_GP_CNTRL, 102 iwl_set_bit(priv, CSR_GP_CNTRL,
103 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 103 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
104 return ret; 104 return;
105 } 105 }
106 106
107 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 107 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
@@ -114,8 +114,6 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
114 txq->q.write_ptr | (txq_id << 8)); 114 txq->q.write_ptr | (txq_id << 8));
115 115
116 txq->need_update = 0; 116 txq->need_update = 0;
117
118 return ret;
119} 117}
120EXPORT_SYMBOL(iwl_txq_update_write_ptr); 118EXPORT_SYMBOL(iwl_txq_update_write_ptr);
121 119
@@ -146,7 +144,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
146{ 144{
147 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 145 struct iwl_tx_queue *txq = &priv->txq[txq_id];
148 struct iwl_queue *q = &txq->q; 146 struct iwl_queue *q = &txq->q;
149 struct pci_dev *dev = priv->pci_dev; 147 struct device *dev = &priv->pci_dev->dev;
150 int i; 148 int i;
151 149
152 if (q->n_bd == 0) 150 if (q->n_bd == 0)
@@ -163,8 +161,8 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
163 161
164 /* De-alloc circular buffer of TFDs */ 162 /* De-alloc circular buffer of TFDs */
165 if (txq->q.n_bd) 163 if (txq->q.n_bd)
166 pci_free_consistent(dev, priv->hw_params.tfd_size * 164 dma_free_coherent(dev, priv->hw_params.tfd_size *
167 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 165 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
168 166
169 /* De-alloc array of per-TFD driver data */ 167 /* De-alloc array of per-TFD driver data */
170 kfree(txq->txb); 168 kfree(txq->txb);
@@ -193,7 +191,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
193{ 191{
194 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; 192 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
195 struct iwl_queue *q = &txq->q; 193 struct iwl_queue *q = &txq->q;
196 struct pci_dev *dev = priv->pci_dev; 194 struct device *dev = &priv->pci_dev->dev;
197 int i; 195 int i;
198 196
199 if (q->n_bd == 0) 197 if (q->n_bd == 0)
@@ -205,8 +203,8 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
205 203
206 /* De-alloc circular buffer of TFDs */ 204 /* De-alloc circular buffer of TFDs */
207 if (txq->q.n_bd) 205 if (txq->q.n_bd)
208 pci_free_consistent(dev, priv->hw_params.tfd_size * 206 dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd,
209 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 207 txq->tfds, txq->q.dma_addr);
210 208
211 /* deallocate arrays */ 209 /* deallocate arrays */
212 kfree(txq->cmd); 210 kfree(txq->cmd);
@@ -297,7 +295,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
297static int iwl_tx_queue_alloc(struct iwl_priv *priv, 295static int iwl_tx_queue_alloc(struct iwl_priv *priv,
298 struct iwl_tx_queue *txq, u32 id) 296 struct iwl_tx_queue *txq, u32 id)
299{ 297{
300 struct pci_dev *dev = priv->pci_dev; 298 struct device *dev = &priv->pci_dev->dev;
301 size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; 299 size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
302 300
303 /* Driver private data, only for Tx (not command) queues, 301 /* Driver private data, only for Tx (not command) queues,
@@ -316,8 +314,8 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
316 314
317 /* Circular buffer of transmit frame descriptors (TFDs), 315 /* Circular buffer of transmit frame descriptors (TFDs),
318 * shared with device */ 316 * shared with device */
319 txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr); 317 txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,
320 318 GFP_KERNEL);
321 if (!txq->tfds) { 319 if (!txq->tfds) {
322 IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); 320 IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
323 goto error; 321 goto error;
@@ -745,7 +743,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
745 u8 tid = 0; 743 u8 tid = 0;
746 u8 *qc = NULL; 744 u8 *qc = NULL;
747 unsigned long flags; 745 unsigned long flags;
748 int ret;
749 746
750 spin_lock_irqsave(&priv->lock, flags); 747 spin_lock_irqsave(&priv->lock, flags);
751 if (iwl_is_rfkill(priv)) { 748 if (iwl_is_rfkill(priv)) {
@@ -820,8 +817,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
820 hdr->seq_ctrl |= cpu_to_le16(seq_number); 817 hdr->seq_ctrl |= cpu_to_le16(seq_number);
821 seq_number += 0x10; 818 seq_number += 0x10;
822 /* aggregation is on for this <sta,tid> */ 819 /* aggregation is on for this <sta,tid> */
823 if (info->flags & IEEE80211_TX_CTL_AMPDU) 820 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
821 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
824 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; 822 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
823 }
825 } 824 }
826 825
827 txq = &priv->txq[txq_id]; 826 txq = &priv->txq[txq_id];
@@ -963,7 +962,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
963 962
964 /* Tell device the write index *just past* this latest filled TFD */ 963 /* Tell device the write index *just past* this latest filled TFD */
965 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 964 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
966 ret = iwl_txq_update_write_ptr(priv, txq); 965 iwl_txq_update_write_ptr(priv, txq);
967 spin_unlock_irqrestore(&priv->lock, flags); 966 spin_unlock_irqrestore(&priv->lock, flags);
968 967
969 /* 968 /*
@@ -977,9 +976,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
977 if (sta_priv && sta_priv->client) 976 if (sta_priv && sta_priv->client)
978 atomic_inc(&sta_priv->pending_frames); 977 atomic_inc(&sta_priv->pending_frames);
979 978
980 if (ret)
981 return ret;
982
983 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) { 979 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
984 if (wait_write_ptr) { 980 if (wait_write_ptr) {
985 spin_lock_irqsave(&priv->lock, flags); 981 spin_lock_irqsave(&priv->lock, flags);
@@ -1018,7 +1014,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1018 struct iwl_cmd_meta *out_meta; 1014 struct iwl_cmd_meta *out_meta;
1019 dma_addr_t phys_addr; 1015 dma_addr_t phys_addr;
1020 unsigned long flags; 1016 unsigned long flags;
1021 int len, ret; 1017 int len;
1022 u32 idx; 1018 u32 idx;
1023 u16 fix_size; 1019 u16 fix_size;
1024 1020
@@ -1115,10 +1111,10 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1115 1111
1116 /* Increment and update queue's write index */ 1112 /* Increment and update queue's write index */
1117 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1113 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1118 ret = iwl_txq_update_write_ptr(priv, txq); 1114 iwl_txq_update_write_ptr(priv, txq);
1119 1115
1120 spin_unlock_irqrestore(&priv->hcmd_lock, flags); 1116 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
1121 return ret ? ret : idx; 1117 return idx;
1122} 1118}
1123 1119
1124static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb) 1120static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
@@ -1260,6 +1256,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1260 1256
1261 if (!(meta->flags & CMD_ASYNC)) { 1257 if (!(meta->flags & CMD_ASYNC)) {
1262 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1258 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1259 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
1260 get_cmd_string(cmd->hdr.cmd));
1263 wake_up_interruptible(&priv->wait_command_queue); 1261 wake_up_interruptible(&priv->wait_command_queue);
1264 } 1262 }
1265} 1263}
@@ -1346,7 +1344,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1346{ 1344{
1347 int tx_fifo_id, txq_id, sta_id, ssn = -1; 1345 int tx_fifo_id, txq_id, sta_id, ssn = -1;
1348 struct iwl_tid_data *tid_data; 1346 struct iwl_tid_data *tid_data;
1349 int ret, write_ptr, read_ptr; 1347 int write_ptr, read_ptr;
1350 unsigned long flags; 1348 unsigned long flags;
1351 1349
1352 if (!ra) { 1350 if (!ra) {
@@ -1398,13 +1396,17 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1398 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1396 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1399 1397
1400 spin_lock_irqsave(&priv->lock, flags); 1398 spin_lock_irqsave(&priv->lock, flags);
1401 ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, 1399 /*
1400 * the only reason this call can fail is queue number out of range,
1401 * which can happen if uCode is reloaded and all the station
1402 * information are lost. if it is outside the range, there is no need
1403 * to deactivate the uCode queue, just return "success" to allow
1404 * mac80211 to clean up it own data.
1405 */
1406 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
1402 tx_fifo_id); 1407 tx_fifo_id);
1403 spin_unlock_irqrestore(&priv->lock, flags); 1408 spin_unlock_irqrestore(&priv->lock, flags);
1404 1409
1405 if (ret)
1406 return ret;
1407
1408 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); 1410 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1409 1411
1410 return 0; 1412 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f8e4e4b18d02..54daa38ecba3 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -53,9 +53,10 @@
53#include "iwl-commands.h" 53#include "iwl-commands.h"
54#include "iwl-sta.h" 54#include "iwl-sta.h"
55#include "iwl-3945.h" 55#include "iwl-3945.h"
56#include "iwl-helpers.h"
57#include "iwl-core.h" 56#include "iwl-core.h"
57#include "iwl-helpers.h"
58#include "iwl-dev.h" 58#include "iwl-dev.h"
59#include "iwl-spectrum.h"
59 60
60/* 61/*
61 * module name, copyright, version, etc. 62 * module name, copyright, version, etc.
@@ -70,14 +71,13 @@
70#define VD 71#define VD
71#endif 72#endif
72 73
73#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 74/*
74#define VS "s" 75 * add "s" to indicate spectrum measurement included.
75#else 76 * we add it here to be consistent with previous releases in which
76#define VS 77 * this was configurable.
77#endif 78 */
78 79#define DRV_VERSION IWLWIFI_VERSION VD "s"
79#define DRV_VERSION IWLWIFI_VERSION VD VS 80#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
80#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
81#define DRV_AUTHOR "<ilw@linux.intel.com>" 81#define DRV_AUTHOR "<ilw@linux.intel.com>"
82 82
83MODULE_DESCRIPTION(DRV_DESCRIPTION); 83MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -352,10 +352,10 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
352static void iwl3945_unset_hw_params(struct iwl_priv *priv) 352static void iwl3945_unset_hw_params(struct iwl_priv *priv)
353{ 353{
354 if (priv->shared_virt) 354 if (priv->shared_virt)
355 pci_free_consistent(priv->pci_dev, 355 dma_free_coherent(&priv->pci_dev->dev,
356 sizeof(struct iwl3945_shared), 356 sizeof(struct iwl3945_shared),
357 priv->shared_virt, 357 priv->shared_virt,
358 priv->shared_phys); 358 priv->shared_phys);
359} 359}
360 360
361static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, 361static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
@@ -478,7 +478,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
478 u8 wait_write_ptr = 0; 478 u8 wait_write_ptr = 0;
479 u8 *qc = NULL; 479 u8 *qc = NULL;
480 unsigned long flags; 480 unsigned long flags;
481 int rc;
482 481
483 spin_lock_irqsave(&priv->lock, flags); 482 spin_lock_irqsave(&priv->lock, flags);
484 if (iwl_is_rfkill(priv)) { 483 if (iwl_is_rfkill(priv)) {
@@ -663,12 +662,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
663 662
664 /* Tell device the write index *just past* this latest filled TFD */ 663 /* Tell device the write index *just past* this latest filled TFD */
665 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 664 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
666 rc = iwl_txq_update_write_ptr(priv, txq); 665 iwl_txq_update_write_ptr(priv, txq);
667 spin_unlock_irqrestore(&priv->lock, flags); 666 spin_unlock_irqrestore(&priv->lock, flags);
668 667
669 if (rc)
670 return rc;
671
672 if ((iwl_queue_space(q) < q->high_mark) 668 if ((iwl_queue_space(q) < q->high_mark)
673 && priv->mac80211_registered) { 669 && priv->mac80211_registered) {
674 if (wait_write_ptr) { 670 if (wait_write_ptr) {
@@ -689,10 +685,6 @@ drop:
689 return -1; 685 return -1;
690} 686}
691 687
692#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
693
694#include "iwl-spectrum.h"
695
696#define BEACON_TIME_MASK_LOW 0x00FFFFFF 688#define BEACON_TIME_MASK_LOW 0x00FFFFFF
697#define BEACON_TIME_MASK_HIGH 0xFF000000 689#define BEACON_TIME_MASK_HIGH 0xFF000000
698#define TIME_UNIT 1024 690#define TIME_UNIT 1024
@@ -819,7 +811,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
819 811
820 return rc; 812 return rc;
821} 813}
822#endif
823 814
824static void iwl3945_rx_reply_alive(struct iwl_priv *priv, 815static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
825 struct iwl_rx_mem_buffer *rxb) 816 struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +953,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
962 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; 953 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
963 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 954 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
964 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 955 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
956 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
957 iwl_rx_spectrum_measure_notif;
965 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 958 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
966 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 959 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
967 iwl_rx_pm_debug_statistics_notif; 960 iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +968,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
975 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 968 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
976 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 969 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
977 970
978 iwl_setup_spectrum_handlers(priv);
979 iwl_setup_rx_scan_handlers(priv); 971 iwl_setup_rx_scan_handlers(priv);
980 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 972 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
981 973
@@ -1067,13 +1059,13 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
1067 * also updates the memory address in the firmware to reference the new 1059 * also updates the memory address in the firmware to reference the new
1068 * target buffer. 1060 * target buffer.
1069 */ 1061 */
1070static int iwl3945_rx_queue_restock(struct iwl_priv *priv) 1062static void iwl3945_rx_queue_restock(struct iwl_priv *priv)
1071{ 1063{
1072 struct iwl_rx_queue *rxq = &priv->rxq; 1064 struct iwl_rx_queue *rxq = &priv->rxq;
1073 struct list_head *element; 1065 struct list_head *element;
1074 struct iwl_rx_mem_buffer *rxb; 1066 struct iwl_rx_mem_buffer *rxb;
1075 unsigned long flags; 1067 unsigned long flags;
1076 int write, rc; 1068 int write;
1077 1069
1078 spin_lock_irqsave(&rxq->lock, flags); 1070 spin_lock_irqsave(&rxq->lock, flags);
1079 write = rxq->write & ~0x7; 1071 write = rxq->write & ~0x7;
@@ -1103,12 +1095,8 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1103 spin_lock_irqsave(&rxq->lock, flags); 1095 spin_lock_irqsave(&rxq->lock, flags);
1104 rxq->need_update = 1; 1096 rxq->need_update = 1;
1105 spin_unlock_irqrestore(&rxq->lock, flags); 1097 spin_unlock_irqrestore(&rxq->lock, flags);
1106 rc = iwl_rx_queue_update_write_ptr(priv, rxq); 1098 iwl_rx_queue_update_write_ptr(priv, rxq);
1107 if (rc)
1108 return rc;
1109 } 1099 }
1110
1111 return 0;
1112} 1100}
1113 1101
1114/** 1102/**
@@ -1253,10 +1241,10 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx
1253 } 1241 }
1254 } 1242 }
1255 1243
1256 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, 1244 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
1257 rxq->dma_addr); 1245 rxq->dma_addr);
1258 pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), 1246 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
1259 rxq->rb_stts, rxq->rb_stts_dma); 1247 rxq->rb_stts, rxq->rb_stts_dma);
1260 rxq->bd = NULL; 1248 rxq->bd = NULL;
1261 rxq->rb_stts = NULL; 1249 rxq->rb_stts = NULL;
1262} 1250}
@@ -1518,8 +1506,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1518 * iwl3945_print_event_log - Dump error event log to syslog 1506 * iwl3945_print_event_log - Dump error event log to syslog
1519 * 1507 *
1520 */ 1508 */
1521static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1509static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1522 u32 num_events, u32 mode) 1510 u32 num_events, u32 mode,
1511 int pos, char **buf, size_t bufsz)
1523{ 1512{
1524 u32 i; 1513 u32 i;
1525 u32 base; /* SRAM byte address of event log header */ 1514 u32 base; /* SRAM byte address of event log header */
@@ -1529,7 +1518,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1529 unsigned long reg_flags; 1518 unsigned long reg_flags;
1530 1519
1531 if (num_events == 0) 1520 if (num_events == 0)
1532 return; 1521 return pos;
1533 1522
1534 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1523 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1535 1524
@@ -1555,26 +1544,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1555 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1544 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1556 if (mode == 0) { 1545 if (mode == 0) {
1557 /* data, ev */ 1546 /* data, ev */
1558 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1547 if (bufsz) {
1559 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1548 pos += scnprintf(*buf + pos, bufsz - pos,
1549 "0x%08x:%04u\n",
1550 time, ev);
1551 } else {
1552 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1553 trace_iwlwifi_dev_ucode_event(priv, 0,
1554 time, ev);
1555 }
1560 } else { 1556 } else {
1561 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1557 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1562 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1558 if (bufsz) {
1563 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1559 pos += scnprintf(*buf + pos, bufsz - pos,
1560 "%010u:0x%08x:%04u\n",
1561 time, data, ev);
1562 } else {
1563 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1564 time, data, ev);
1565 trace_iwlwifi_dev_ucode_event(priv, time,
1566 data, ev);
1567 }
1564 } 1568 }
1565 } 1569 }
1566 1570
1567 /* Allow device to power down */ 1571 /* Allow device to power down */
1568 iwl_release_nic_access(priv); 1572 iwl_release_nic_access(priv);
1569 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1573 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1574 return pos;
1570} 1575}
1571 1576
1572/** 1577/**
1573 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1578 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1574 */ 1579 */
1575static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1580static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1576 u32 num_wraps, u32 next_entry, 1581 u32 num_wraps, u32 next_entry,
1577 u32 size, u32 mode) 1582 u32 size, u32 mode,
1583 int pos, char **buf, size_t bufsz)
1578{ 1584{
1579 /* 1585 /*
1580 * display the newest DEFAULT_LOG_ENTRIES entries 1586 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1582,21 +1588,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1582 */ 1588 */
1583 if (num_wraps) { 1589 if (num_wraps) {
1584 if (next_entry < size) { 1590 if (next_entry < size) {
1585 iwl3945_print_event_log(priv, 1591 pos = iwl3945_print_event_log(priv,
1586 capacity - (size - next_entry), 1592 capacity - (size - next_entry),
1587 size - next_entry, mode); 1593 size - next_entry, mode,
1588 iwl3945_print_event_log(priv, 0, 1594 pos, buf, bufsz);
1589 next_entry, mode); 1595 pos = iwl3945_print_event_log(priv, 0,
1596 next_entry, mode,
1597 pos, buf, bufsz);
1590 } else 1598 } else
1591 iwl3945_print_event_log(priv, next_entry - size, 1599 pos = iwl3945_print_event_log(priv, next_entry - size,
1592 size, mode); 1600 size, mode,
1601 pos, buf, bufsz);
1593 } else { 1602 } else {
1594 if (next_entry < size) 1603 if (next_entry < size)
1595 iwl3945_print_event_log(priv, 0, next_entry, mode); 1604 pos = iwl3945_print_event_log(priv, 0,
1605 next_entry, mode,
1606 pos, buf, bufsz);
1596 else 1607 else
1597 iwl3945_print_event_log(priv, next_entry - size, 1608 pos = iwl3945_print_event_log(priv, next_entry - size,
1598 size, mode); 1609 size, mode,
1610 pos, buf, bufsz);
1599 } 1611 }
1612 return pos;
1600} 1613}
1601 1614
1602/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1615/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1604,7 +1617,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1604 1617
1605#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1618#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1606 1619
1607void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1620int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1621 char **buf, bool display)
1608{ 1622{
1609 u32 base; /* SRAM byte address of event log header */ 1623 u32 base; /* SRAM byte address of event log header */
1610 u32 capacity; /* event log capacity in # entries */ 1624 u32 capacity; /* event log capacity in # entries */
@@ -1612,11 +1626,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1612 u32 num_wraps; /* # times uCode wrapped to top of log */ 1626 u32 num_wraps; /* # times uCode wrapped to top of log */
1613 u32 next_entry; /* index of next entry to be written by uCode */ 1627 u32 next_entry; /* index of next entry to be written by uCode */
1614 u32 size; /* # entries that we'll print */ 1628 u32 size; /* # entries that we'll print */
1629 int pos = 0;
1630 size_t bufsz = 0;
1615 1631
1616 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1632 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1617 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1633 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1618 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1634 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1619 return; 1635 return -EINVAL;
1620 } 1636 }
1621 1637
1622 /* event log header */ 1638 /* event log header */
@@ -1642,7 +1658,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1642 /* bail out if nothing in log */ 1658 /* bail out if nothing in log */
1643 if (size == 0) { 1659 if (size == 0) {
1644 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1660 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1645 return; 1661 return pos;
1646 } 1662 }
1647 1663
1648#ifdef CONFIG_IWLWIFI_DEBUG 1664#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1658,25 +1674,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1658 size); 1674 size);
1659 1675
1660#ifdef CONFIG_IWLWIFI_DEBUG 1676#ifdef CONFIG_IWLWIFI_DEBUG
1677 if (display) {
1678 if (full_log)
1679 bufsz = capacity * 48;
1680 else
1681 bufsz = size * 48;
1682 *buf = kmalloc(bufsz, GFP_KERNEL);
1683 if (!*buf)
1684 return -ENOMEM;
1685 }
1661 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1686 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1662 /* if uCode has wrapped back to top of log, 1687 /* if uCode has wrapped back to top of log,
1663 * start at the oldest entry, 1688 * start at the oldest entry,
1664 * i.e the next one that uCode would fill. 1689 * i.e the next one that uCode would fill.
1665 */ 1690 */
1666 if (num_wraps) 1691 if (num_wraps)
1667 iwl3945_print_event_log(priv, next_entry, 1692 pos = iwl3945_print_event_log(priv, next_entry,
1668 capacity - next_entry, mode); 1693 capacity - next_entry, mode,
1694 pos, buf, bufsz);
1669 1695
1670 /* (then/else) start at top of log */ 1696 /* (then/else) start at top of log */
1671 iwl3945_print_event_log(priv, 0, next_entry, mode); 1697 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1698 pos, buf, bufsz);
1672 } else 1699 } else
1673 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1700 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1674 next_entry, size, mode); 1701 next_entry, size, mode,
1702 pos, buf, bufsz);
1675#else 1703#else
1676 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1704 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1677 next_entry, size, mode); 1705 next_entry, size, mode,
1706 pos, buf, bufsz);
1678#endif 1707#endif
1679 1708 return pos;
1680} 1709}
1681 1710
1682static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1711static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2996,18 +3025,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2996 mutex_unlock(&priv->mutex); 3025 mutex_unlock(&priv->mutex);
2997} 3026}
2998 3027
2999static void iwl3945_bg_up(struct work_struct *data)
3000{
3001 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
3002
3003 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3004 return;
3005
3006 mutex_lock(&priv->mutex);
3007 __iwl3945_up(priv);
3008 mutex_unlock(&priv->mutex);
3009}
3010
3011static void iwl3945_bg_restart(struct work_struct *data) 3028static void iwl3945_bg_restart(struct work_struct *data)
3012{ 3029{
3013 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3030 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3024,7 +3041,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
3024 ieee80211_restart_hw(priv->hw); 3041 ieee80211_restart_hw(priv->hw);
3025 } else { 3042 } else {
3026 iwl3945_down(priv); 3043 iwl3945_down(priv);
3027 queue_work(priv->workqueue, &priv->up); 3044
3045 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3046 return;
3047
3048 mutex_lock(&priv->mutex);
3049 __iwl3945_up(priv);
3050 mutex_unlock(&priv->mutex);
3028 } 3051 }
3029} 3052}
3030 3053
@@ -3528,8 +3551,6 @@ static ssize_t store_filter_flags(struct device *d,
3528static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3551static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3529 store_filter_flags); 3552 store_filter_flags);
3530 3553
3531#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3532
3533static ssize_t show_measurement(struct device *d, 3554static ssize_t show_measurement(struct device *d,
3534 struct device_attribute *attr, char *buf) 3555 struct device_attribute *attr, char *buf)
3535{ 3556{
@@ -3599,7 +3620,6 @@ static ssize_t store_measurement(struct device *d,
3599 3620
3600static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, 3621static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3601 show_measurement, store_measurement); 3622 show_measurement, store_measurement);
3602#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
3603 3623
3604static ssize_t store_retry_rate(struct device *d, 3624static ssize_t store_retry_rate(struct device *d,
3605 struct device_attribute *attr, 3625 struct device_attribute *attr,
@@ -3748,7 +3768,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3748 3768
3749 init_waitqueue_head(&priv->wait_command_queue); 3769 init_waitqueue_head(&priv->wait_command_queue);
3750 3770
3751 INIT_WORK(&priv->up, iwl3945_bg_up);
3752 INIT_WORK(&priv->restart, iwl3945_bg_restart); 3771 INIT_WORK(&priv->restart, iwl3945_bg_restart);
3753 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); 3772 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
3754 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3773 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
@@ -3782,9 +3801,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3782 &dev_attr_dump_errors.attr, 3801 &dev_attr_dump_errors.attr,
3783 &dev_attr_flags.attr, 3802 &dev_attr_flags.attr,
3784 &dev_attr_filter_flags.attr, 3803 &dev_attr_filter_flags.attr,
3785#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3786 &dev_attr_measurement.attr, 3804 &dev_attr_measurement.attr,
3787#endif
3788 &dev_attr_retry_rate.attr, 3805 &dev_attr_retry_rate.attr,
3789 &dev_attr_statistics.attr, 3806 &dev_attr_statistics.attr,
3790 &dev_attr_status.attr, 3807 &dev_attr_status.attr,
@@ -3810,7 +3827,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3810 .config = iwl_mac_config, 3827 .config = iwl_mac_config,
3811 .configure_filter = iwl_configure_filter, 3828 .configure_filter = iwl_configure_filter,
3812 .set_key = iwl3945_mac_set_key, 3829 .set_key = iwl3945_mac_set_key,
3813 .get_tx_stats = iwl_mac_get_tx_stats,
3814 .conf_tx = iwl_mac_conf_tx, 3830 .conf_tx = iwl_mac_conf_tx,
3815 .reset_tsf = iwl_mac_reset_tsf, 3831 .reset_tsf = iwl_mac_reset_tsf,
3816 .bss_info_changed = iwl_bss_info_changed, 3832 .bss_info_changed = iwl_bss_info_changed,
@@ -3831,6 +3847,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3831 INIT_LIST_HEAD(&priv->free_frames); 3847 INIT_LIST_HEAD(&priv->free_frames);
3832 3848
3833 mutex_init(&priv->mutex); 3849 mutex_init(&priv->mutex);
3850 mutex_init(&priv->sync_cmd_mutex);
3834 3851
3835 /* Clear the driver's (not device's) station table */ 3852 /* Clear the driver's (not device's) station table */
3836 iwl_clear_stations_table(priv); 3853 iwl_clear_stations_table(priv);
@@ -3840,6 +3857,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3840 priv->band = IEEE80211_BAND_2GHZ; 3857 priv->band = IEEE80211_BAND_2GHZ;
3841 3858
3842 priv->iw_mode = NL80211_IFTYPE_STATION; 3859 priv->iw_mode = NL80211_IFTYPE_STATION;
3860 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3843 3861
3844 iwl_reset_qos(priv); 3862 iwl_reset_qos(priv);
3845 3863
@@ -4022,6 +4040,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4022 spin_lock_init(&priv->reg_lock); 4040 spin_lock_init(&priv->reg_lock);
4023 spin_lock_init(&priv->lock); 4041 spin_lock_init(&priv->lock);
4024 4042
4043 /*
4044 * stop and reset the on-board processor just in case it is in a
4045 * strange state ... like being left stranded by a primary kernel
4046 * and this is now the kdump kernel trying to start up
4047 */
4048 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
4049
4025 /*********************** 4050 /***********************
4026 * 4. Read EEPROM 4051 * 4. Read EEPROM
4027 * ********************/ 4052 * ********************/
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 842811142bef..79ffa3b98d73 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -268,7 +268,7 @@ struct iwm_priv {
268 268
269 struct sk_buff_head rx_list; 269 struct sk_buff_head rx_list;
270 struct list_head rx_tickets; 270 struct list_head rx_tickets;
271 struct list_head rx_packets[IWM_RX_ID_HASH + 1]; 271 struct list_head rx_packets[IWM_RX_ID_HASH];
272 struct workqueue_struct *rx_wq; 272 struct workqueue_struct *rx_wq;
273 struct work_struct rx_worker; 273 struct work_struct rx_worker;
274 274
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 64d16fe37f9a..6b53ae122680 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -868,36 +868,35 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
868 struct iwm_umac_notif_mgt_frame *mgt_frame = 868 struct iwm_umac_notif_mgt_frame *mgt_frame =
869 (struct iwm_umac_notif_mgt_frame *)buf; 869 (struct iwm_umac_notif_mgt_frame *)buf;
870 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame; 870 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
871 u8 *ie;
872 871
873 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame, 872 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
874 le16_to_cpu(mgt_frame->len)); 873 le16_to_cpu(mgt_frame->len));
875 874
876 if (ieee80211_is_assoc_req(mgt->frame_control)) { 875 if (ieee80211_is_assoc_req(mgt->frame_control)) {
877 ie = mgt->u.assoc_req.variable;; 876 iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
878 iwm->req_ie_len = 877 - offsetof(struct ieee80211_mgmt,
879 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 878 u.assoc_req.variable);
880 kfree(iwm->req_ie); 879 kfree(iwm->req_ie);
881 iwm->req_ie = kmemdup(mgt->u.assoc_req.variable, 880 iwm->req_ie = kmemdup(mgt->u.assoc_req.variable,
882 iwm->req_ie_len, GFP_KERNEL); 881 iwm->req_ie_len, GFP_KERNEL);
883 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) { 882 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
884 ie = mgt->u.reassoc_req.variable;; 883 iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
885 iwm->req_ie_len = 884 - offsetof(struct ieee80211_mgmt,
886 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 885 u.reassoc_req.variable);
887 kfree(iwm->req_ie); 886 kfree(iwm->req_ie);
888 iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable, 887 iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable,
889 iwm->req_ie_len, GFP_KERNEL); 888 iwm->req_ie_len, GFP_KERNEL);
890 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) { 889 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
891 ie = mgt->u.assoc_resp.variable;; 890 iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
892 iwm->resp_ie_len = 891 - offsetof(struct ieee80211_mgmt,
893 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 892 u.assoc_resp.variable);
894 kfree(iwm->resp_ie); 893 kfree(iwm->resp_ie);
895 iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable, 894 iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable,
896 iwm->resp_ie_len, GFP_KERNEL); 895 iwm->resp_ie_len, GFP_KERNEL);
897 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) { 896 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
898 ie = mgt->u.reassoc_resp.variable;; 897 iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
899 iwm->resp_ie_len = 898 - offsetof(struct ieee80211_mgmt,
900 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 899 u.reassoc_resp.variable);
901 kfree(iwm->resp_ie); 900 kfree(iwm->resp_ie);
902 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable, 901 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
903 iwm->resp_ie_len, GFP_KERNEL); 902 iwm->resp_ie_len, GFP_KERNEL);
@@ -1534,6 +1533,33 @@ static void classify8023(struct sk_buff *skb)
1534 } 1533 }
1535} 1534}
1536 1535
1536static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
1537{
1538 struct wireless_dev *wdev = iwm_to_wdev(iwm);
1539 struct net_device *ndev = iwm_to_ndev(iwm);
1540 struct sk_buff_head list;
1541 struct sk_buff *frame;
1542
1543 IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
1544
1545 __skb_queue_head_init(&list);
1546 ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0);
1547
1548 while ((frame = __skb_dequeue(&list))) {
1549 ndev->stats.rx_packets++;
1550 ndev->stats.rx_bytes += frame->len;
1551
1552 frame->protocol = eth_type_trans(frame, ndev);
1553 frame->ip_summed = CHECKSUM_NONE;
1554 memset(frame->cb, 0, sizeof(frame->cb));
1555
1556 if (netif_rx_ni(frame) == NET_RX_DROP) {
1557 IWM_ERR(iwm, "Packet dropped\n");
1558 ndev->stats.rx_dropped++;
1559 }
1560 }
1561}
1562
1537static void iwm_rx_process_packet(struct iwm_priv *iwm, 1563static void iwm_rx_process_packet(struct iwm_priv *iwm,
1538 struct iwm_rx_packet *packet, 1564 struct iwm_rx_packet *packet,
1539 struct iwm_rx_ticket_node *ticket_node) 1565 struct iwm_rx_ticket_node *ticket_node)
@@ -1548,25 +1574,34 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
1548 switch (le16_to_cpu(ticket_node->ticket->action)) { 1574 switch (le16_to_cpu(ticket_node->ticket->action)) {
1549 case IWM_RX_TICKET_RELEASE: 1575 case IWM_RX_TICKET_RELEASE:
1550 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n"); 1576 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
1551 classify8023(skb); 1577
1552 iwm_rx_adjust_packet(iwm, packet, ticket_node); 1578 iwm_rx_adjust_packet(iwm, packet, ticket_node);
1579 skb->dev = iwm_to_ndev(iwm);
1580 classify8023(skb);
1581
1582 if (le16_to_cpu(ticket_node->ticket->flags) &
1583 IWM_RX_TICKET_AMSDU_MSK) {
1584 iwm_rx_process_amsdu(iwm, skb);
1585 break;
1586 }
1587
1553 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype); 1588 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
1554 if (ret < 0) { 1589 if (ret < 0) {
1555 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - " 1590 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
1556 "%d\n", ret); 1591 "%d\n", ret);
1592 kfree_skb(packet->skb);
1557 break; 1593 break;
1558 } 1594 }
1559 1595
1560 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len); 1596 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
1561 1597
1562 skb->dev = iwm_to_ndev(iwm); 1598 ndev->stats.rx_packets++;
1599 ndev->stats.rx_bytes += skb->len;
1600
1563 skb->protocol = eth_type_trans(skb, ndev); 1601 skb->protocol = eth_type_trans(skb, ndev);
1564 skb->ip_summed = CHECKSUM_NONE; 1602 skb->ip_summed = CHECKSUM_NONE;
1565 memset(skb->cb, 0, sizeof(skb->cb)); 1603 memset(skb->cb, 0, sizeof(skb->cb));
1566 1604
1567 ndev->stats.rx_packets++;
1568 ndev->stats.rx_bytes += skb->len;
1569
1570 if (netif_rx_ni(skb) == NET_RX_DROP) { 1605 if (netif_rx_ni(skb) == NET_RX_DROP) {
1571 IWM_ERR(iwm, "Packet dropped\n"); 1606 IWM_ERR(iwm, "Packet dropped\n");
1572 ndev->stats.rx_dropped++; 1607 ndev->stats.rx_dropped++;
diff --git a/drivers/net/wireless/libertas/Kconfig b/drivers/net/wireless/libertas/Kconfig
index 30aa9d48d67e..0485c9957575 100644
--- a/drivers/net/wireless/libertas/Kconfig
+++ b/drivers/net/wireless/libertas/Kconfig
@@ -37,3 +37,9 @@ config LIBERTAS_DEBUG
37 depends on LIBERTAS 37 depends on LIBERTAS
38 ---help--- 38 ---help---
39 Debugging support. 39 Debugging support.
40
41config LIBERTAS_MESH
42 bool "Enable mesh support"
43 depends on LIBERTAS
44 help
45 This enables Libertas' MESH support, used by e.g. the OLPC people.
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index b188cd97a053..45e870e33117 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -5,11 +5,11 @@ libertas-y += cmdresp.o
5libertas-y += debugfs.o 5libertas-y += debugfs.o
6libertas-y += ethtool.o 6libertas-y += ethtool.o
7libertas-y += main.o 7libertas-y += main.o
8libertas-y += mesh.o
9libertas-y += rx.o 8libertas-y += rx.o
10libertas-y += scan.o 9libertas-y += scan.o
11libertas-y += tx.o 10libertas-y += tx.o
12libertas-y += wext.o 11libertas-y += wext.o
12libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
13 13
14usb8xxx-objs += if_usb.o 14usb8xxx-objs += if_usb.o
15libertas_cs-objs += if_cs.o 15libertas_cs-objs += if_cs.o
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 751067369ba8..f03d5e4e59c3 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -390,10 +390,8 @@ int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
390 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); 390 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
391 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); 391 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
392 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); 392 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
393 if (!ret && cmd_action == CMD_ACT_GET) { 393 if (!ret && cmd_action == CMD_ACT_GET)
394 priv->ratebitmap = le16_to_cpu(cmd.bitmap);
395 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); 394 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
396 }
397 395
398 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 396 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
399 return ret; 397 return ret;
@@ -807,8 +805,7 @@ static int lbs_try_associate(struct lbs_private *priv,
807 } 805 }
808 806
809 /* Use short preamble only when both the BSS and firmware support it */ 807 /* Use short preamble only when both the BSS and firmware support it */
810 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 808 if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
811 (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
812 preamble = RADIO_PREAMBLE_SHORT; 809 preamble = RADIO_PREAMBLE_SHORT;
813 810
814 ret = lbs_set_radio(priv, preamble, 1); 811 ret = lbs_set_radio(priv, preamble, 1);
@@ -939,8 +936,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
939 } 936 }
940 937
941 /* Use short preamble only when both the BSS and firmware support it */ 938 /* Use short preamble only when both the BSS and firmware support it */
942 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 939 if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
943 (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
944 lbs_deb_join("AdhocJoin: Short preamble\n"); 940 lbs_deb_join("AdhocJoin: Short preamble\n");
945 preamble = RADIO_PREAMBLE_SHORT; 941 preamble = RADIO_PREAMBLE_SHORT;
946 } 942 }
@@ -1049,7 +1045,7 @@ static int lbs_adhoc_start(struct lbs_private *priv,
1049 struct assoc_request *assoc_req) 1045 struct assoc_request *assoc_req)
1050{ 1046{
1051 struct cmd_ds_802_11_ad_hoc_start cmd; 1047 struct cmd_ds_802_11_ad_hoc_start cmd;
1052 u8 preamble = RADIO_PREAMBLE_LONG; 1048 u8 preamble = RADIO_PREAMBLE_SHORT;
1053 size_t ratesize = 0; 1049 size_t ratesize = 0;
1054 u16 tmpcap = 0; 1050 u16 tmpcap = 0;
1055 int ret = 0; 1051 int ret = 0;
@@ -1057,11 +1053,6 @@ static int lbs_adhoc_start(struct lbs_private *priv,
1057 1053
1058 lbs_deb_enter(LBS_DEB_ASSOC); 1054 lbs_deb_enter(LBS_DEB_ASSOC);
1059 1055
1060 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
1061 lbs_deb_join("ADHOC_START: Will use short preamble\n");
1062 preamble = RADIO_PREAMBLE_SHORT;
1063 }
1064
1065 ret = lbs_set_radio(priv, preamble, 1); 1056 ret = lbs_set_radio(priv, preamble, 1);
1066 if (ret) 1057 if (ret)
1067 goto out; 1058 goto out;
@@ -1169,11 +1160,11 @@ int lbs_adhoc_stop(struct lbs_private *priv)
1169static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, 1160static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1170 struct bss_descriptor *match_bss) 1161 struct bss_descriptor *match_bss)
1171{ 1162{
1172 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1163 if (!secinfo->wep_enabled &&
1173 && !secinfo->WPA2enabled 1164 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1174 && match_bss->wpa_ie[0] != WLAN_EID_GENERIC 1165 match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
1175 && match_bss->rsn_ie[0] != WLAN_EID_RSN 1166 match_bss->rsn_ie[0] != WLAN_EID_RSN &&
1176 && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1167 !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1177 return 1; 1168 return 1;
1178 else 1169 else
1179 return 0; 1170 return 0;
@@ -1182,9 +1173,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1182static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, 1173static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1183 struct bss_descriptor *match_bss) 1174 struct bss_descriptor *match_bss)
1184{ 1175{
1185 if (secinfo->wep_enabled && !secinfo->WPAenabled 1176 if (secinfo->wep_enabled &&
1186 && !secinfo->WPA2enabled 1177 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1187 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1178 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1188 return 1; 1179 return 1;
1189 else 1180 else
1190 return 0; 1181 return 0;
@@ -1193,8 +1184,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1193static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, 1184static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
1194 struct bss_descriptor *match_bss) 1185 struct bss_descriptor *match_bss)
1195{ 1186{
1196 if (!secinfo->wep_enabled && secinfo->WPAenabled 1187 if (!secinfo->wep_enabled && secinfo->WPAenabled &&
1197 && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) 1188 (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
1198 /* privacy bit may NOT be set in some APs like LinkSys WRT54G 1189 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
1199 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ 1190 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
1200 ) 1191 )
@@ -1219,11 +1210,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
1219static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, 1210static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
1220 struct bss_descriptor *match_bss) 1211 struct bss_descriptor *match_bss)
1221{ 1212{
1222 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1213 if (!secinfo->wep_enabled &&
1223 && !secinfo->WPA2enabled 1214 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1224 && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) 1215 (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
1225 && (match_bss->rsn_ie[0] != WLAN_EID_RSN) 1216 (match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
1226 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1217 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1227 return 1; 1218 return 1;
1228 else 1219 else
1229 return 0; 1220 return 0;
@@ -1534,8 +1525,8 @@ static int assoc_helper_associate(struct lbs_private *priv,
1534 /* If we're given and 'any' BSSID, try associating based on SSID */ 1525 /* If we're given and 'any' BSSID, try associating based on SSID */
1535 1526
1536 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1527 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1537 if (compare_ether_addr(bssid_any, assoc_req->bssid) 1528 if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
1538 && compare_ether_addr(bssid_off, assoc_req->bssid)) { 1529 compare_ether_addr(bssid_off, assoc_req->bssid)) {
1539 ret = assoc_helper_bssid(priv, assoc_req); 1530 ret = assoc_helper_bssid(priv, assoc_req);
1540 done = 1; 1531 done = 1;
1541 } 1532 }
@@ -1621,11 +1612,9 @@ static int assoc_helper_channel(struct lbs_private *priv,
1621 goto restore_mesh; 1612 goto restore_mesh;
1622 } 1613 }
1623 1614
1624 if ( assoc_req->secinfo.wep_enabled 1615 if (assoc_req->secinfo.wep_enabled &&
1625 && (assoc_req->wep_keys[0].len 1616 (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
1626 || assoc_req->wep_keys[1].len 1617 assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
1627 || assoc_req->wep_keys[2].len
1628 || assoc_req->wep_keys[3].len)) {
1629 /* Make sure WEP keys are re-sent to firmware */ 1618 /* Make sure WEP keys are re-sent to firmware */
1630 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1619 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1631 } 1620 }
@@ -1992,14 +1981,14 @@ void lbs_association_worker(struct work_struct *work)
1992 assoc_req->secinfo.auth_mode); 1981 assoc_req->secinfo.auth_mode);
1993 1982
1994 /* If 'any' SSID was specified, find an SSID to associate with */ 1983 /* If 'any' SSID was specified, find an SSID to associate with */
1995 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) 1984 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
1996 && !assoc_req->ssid_len) 1985 !assoc_req->ssid_len)
1997 find_any_ssid = 1; 1986 find_any_ssid = 1;
1998 1987
1999 /* But don't use 'any' SSID if there's a valid locked BSSID to use */ 1988 /* But don't use 'any' SSID if there's a valid locked BSSID to use */
2000 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1989 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
2001 if (compare_ether_addr(assoc_req->bssid, bssid_any) 1990 if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
2002 && compare_ether_addr(assoc_req->bssid, bssid_off)) 1991 compare_ether_addr(assoc_req->bssid, bssid_off))
2003 find_any_ssid = 0; 1992 find_any_ssid = 0;
2004 } 1993 }
2005 1994
@@ -2061,13 +2050,6 @@ void lbs_association_worker(struct work_struct *work)
2061 goto out; 2050 goto out;
2062 } 2051 }
2063 2052
2064 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
2065 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2066 ret = assoc_helper_wep_keys(priv, assoc_req);
2067 if (ret)
2068 goto out;
2069 }
2070
2071 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 2053 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
2072 ret = assoc_helper_secinfo(priv, assoc_req); 2054 ret = assoc_helper_secinfo(priv, assoc_req);
2073 if (ret) 2055 if (ret)
@@ -2080,18 +2062,31 @@ void lbs_association_worker(struct work_struct *work)
2080 goto out; 2062 goto out;
2081 } 2063 }
2082 2064
2083 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) 2065 /*
2084 || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 2066 * v10 FW wants WPA keys to be set/cleared before WEP key operations,
2067 * otherwise it will fail to correctly associate to WEP networks.
2068 * Other firmware versions don't appear to care.
2069 */
2070 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) ||
2071 test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
2085 ret = assoc_helper_wpa_keys(priv, assoc_req); 2072 ret = assoc_helper_wpa_keys(priv, assoc_req);
2086 if (ret) 2073 if (ret)
2087 goto out; 2074 goto out;
2088 } 2075 }
2089 2076
2077 if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) ||
2078 test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2079 ret = assoc_helper_wep_keys(priv, assoc_req);
2080 if (ret)
2081 goto out;
2082 }
2083
2084
2090 /* SSID/BSSID should be the _last_ config option set, because they 2085 /* SSID/BSSID should be the _last_ config option set, because they
2091 * trigger the association attempt. 2086 * trigger the association attempt.
2092 */ 2087 */
2093 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) 2088 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
2094 || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 2089 test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
2095 int success = 1; 2090 int success = 1;
2096 2091
2097 ret = assoc_helper_associate(priv, assoc_req); 2092 ret = assoc_helper_associate(priv, assoc_req);
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index b9b371bfa30f..42051f7cad6d 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -143,19 +143,6 @@ int lbs_update_hw_spec(struct lbs_private *priv)
143 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", 143 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
144 cmd.hwifversion, cmd.version); 144 cmd.hwifversion, cmd.version);
145 145
146 /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
147 /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
148 /* 5.110.22 have mesh command with 0xa3 command id */
149 /* 10.0.0.p0 FW brings in mesh config command with different id */
150 /* Check FW version MSB and initialize mesh_fw_ver */
151 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
152 priv->mesh_fw_ver = MESH_FW_OLD;
153 else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
154 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
155 priv->mesh_fw_ver = MESH_FW_NEW;
156 else
157 priv->mesh_fw_ver = MESH_NONE;
158
159 /* Clamp region code to 8-bit since FW spec indicates that it should 146 /* Clamp region code to 8-bit since FW spec indicates that it should
160 * only ever be 8-bit, even though the field size is 16-bit. Some firmware 147 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
161 * returns non-zero high 8 bits here. 148 * returns non-zero high 8 bits here.
@@ -855,9 +842,6 @@ int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
855 if (priv->fwrelease < 0x09000000) { 842 if (priv->fwrelease < 0x09000000) {
856 switch (preamble) { 843 switch (preamble) {
857 case RADIO_PREAMBLE_SHORT: 844 case RADIO_PREAMBLE_SHORT:
858 if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
859 goto out;
860 /* Fall through */
861 case RADIO_PREAMBLE_AUTO: 845 case RADIO_PREAMBLE_AUTO:
862 case RADIO_PREAMBLE_LONG: 846 case RADIO_PREAMBLE_LONG:
863 cmd.control = cpu_to_le16(preamble); 847 cmd.control = cpu_to_le16(preamble);
@@ -1011,6 +995,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1011 ret = 0; 995 ret = 0;
1012 break; 996 break;
1013 997
998#ifdef CONFIG_LIBERTAS_MESH
999
1014 case CMD_BT_ACCESS: 1000 case CMD_BT_ACCESS:
1015 ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); 1001 ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
1016 break; 1002 break;
@@ -1019,6 +1005,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1019 ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); 1005 ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
1020 break; 1006 break;
1021 1007
1008#endif
1009
1022 case CMD_802_11_BEACON_CTRL: 1010 case CMD_802_11_BEACON_CTRL:
1023 ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); 1011 ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
1024 break; 1012 break;
@@ -1317,7 +1305,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
1317 if ((priv->psmode != LBS802_11POWERMODECAM) && 1305 if ((priv->psmode != LBS802_11POWERMODECAM) &&
1318 (priv->psstate == PS_STATE_FULL_POWER) && 1306 (priv->psstate == PS_STATE_FULL_POWER) &&
1319 ((priv->connect_status == LBS_CONNECTED) || 1307 ((priv->connect_status == LBS_CONNECTED) ||
1320 (priv->mesh_connect_status == LBS_CONNECTED))) { 1308 lbs_mesh_connected(priv))) {
1321 if (priv->secinfo.WPAenabled || 1309 if (priv->secinfo.WPAenabled ||
1322 priv->secinfo.WPA2enabled) { 1310 priv->secinfo.WPA2enabled) {
1323 /* check for valid WPA group keys */ 1311 /* check for valid WPA group keys */
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 2862748aef70..cb4138a55fdf 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -110,18 +110,6 @@ int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val);
110int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val); 110int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val);
111 111
112 112
113/* Mesh related */
114
115int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
116 struct cmd_ds_mesh_access *cmd);
117
118int lbs_mesh_config_send(struct lbs_private *priv,
119 struct cmd_ds_mesh_config *cmd,
120 uint16_t action, uint16_t type);
121
122int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
123
124
125/* Commands only used in wext.c, assoc. and scan.c */ 113/* Commands only used in wext.c, assoc. and scan.c */
126 114
127int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, 115int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 21d57690c20a..e7470442f76b 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -240,11 +240,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
240 /* Now we got response from FW, cancel the command timer */ 240 /* Now we got response from FW, cancel the command timer */
241 del_timer(&priv->command_timer); 241 del_timer(&priv->command_timer);
242 priv->cmd_timed_out = 0; 242 priv->cmd_timed_out = 0;
243 if (priv->nr_retries) {
244 lbs_pr_info("Received result %x to command %x after %d retries\n",
245 result, curcmd, priv->nr_retries);
246 priv->nr_retries = 0;
247 }
248 243
249 /* Store the response code to cur_cmd_retcode. */ 244 /* Store the response code to cur_cmd_retcode. */
250 priv->cur_cmd_retcode = result; 245 priv->cur_cmd_retcode = result;
@@ -485,20 +480,8 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
485 break; 480 break;
486 481
487 case MACREG_INT_CODE_MESH_AUTO_STARTED: 482 case MACREG_INT_CODE_MESH_AUTO_STARTED:
488 /* Ignore spurious autostart events if autostart is disabled */ 483 /* Ignore spurious autostart events */
489 if (!priv->mesh_autostart_enabled) { 484 lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
490 lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
491 break;
492 }
493 lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
494 priv->mesh_connect_status = LBS_CONNECTED;
495 if (priv->mesh_open) {
496 netif_carrier_on(priv->mesh_dev);
497 if (!priv->tx_pending_len)
498 netif_wake_queue(priv->mesh_dev);
499 }
500 priv->mode = IW_MODE_ADHOC;
501 schedule_work(&priv->sync_channel);
502 break; 485 break;
503 486
504 default: 487 default:
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 6b6ea9f7bf5b..ea3f10ef4e00 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -397,13 +397,6 @@ enum KEY_INFO_WPA {
397 KEY_INFO_WPA_ENABLED = 0x04 397 KEY_INFO_WPA_ENABLED = 0x04
398}; 398};
399 399
400/** mesh_fw_ver */
401enum _mesh_fw_ver {
402 MESH_NONE = 0, /* MESH is not supported */
403 MESH_FW_OLD, /* MESH is supported in FW V5 */
404 MESH_FW_NEW, /* MESH is supported in FW V10 and newer */
405};
406
407/* Default values for fwt commands. */ 400/* Default values for fwt commands. */
408#define FWT_DEFAULT_METRIC 0 401#define FWT_DEFAULT_METRIC 0
409#define FWT_DEFAULT_DIR 1 402#define FWT_DEFAULT_DIR 1
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 6a8d2b291d8c..efb2519d9d74 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -39,15 +39,14 @@ struct lbs_private {
39 39
40 /* Mesh */ 40 /* Mesh */
41 struct net_device *mesh_dev; /* Virtual device */ 41 struct net_device *mesh_dev; /* Virtual device */
42#ifdef CONFIG_LIBERTAS_MESH
42 u32 mesh_connect_status; 43 u32 mesh_connect_status;
43 struct lbs_mesh_stats mstats; 44 struct lbs_mesh_stats mstats;
44 int mesh_open; 45 int mesh_open;
45 int mesh_fw_ver;
46 int mesh_autostart_enabled;
47 uint16_t mesh_tlv; 46 uint16_t mesh_tlv;
48 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; 47 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
49 u8 mesh_ssid_len; 48 u8 mesh_ssid_len;
50 struct work_struct sync_channel; 49#endif
51 50
52 /* Monitor mode */ 51 /* Monitor mode */
53 struct net_device *rtap_net_dev; 52 struct net_device *rtap_net_dev;
@@ -110,7 +109,6 @@ struct lbs_private {
110 struct list_head cmdpendingq; /* pending command buffers */ 109 struct list_head cmdpendingq; /* pending command buffers */
111 wait_queue_head_t cmd_pending; 110 wait_queue_head_t cmd_pending;
112 struct timer_list command_timer; 111 struct timer_list command_timer;
113 int nr_retries;
114 int cmd_timed_out; 112 int cmd_timed_out;
115 113
116 /* Command responses sent from the hardware to the driver */ 114 /* Command responses sent from the hardware to the driver */
@@ -176,9 +174,7 @@ struct lbs_private {
176 struct bss_descriptor *networks; 174 struct bss_descriptor *networks;
177 struct assoc_request * pending_assoc_req; 175 struct assoc_request * pending_assoc_req;
178 struct assoc_request * in_progress_assoc_req; 176 struct assoc_request * in_progress_assoc_req;
179 u16 capability;
180 uint16_t enablehwauto; 177 uint16_t enablehwauto;
181 uint16_t ratebitmap;
182 178
183 /* ADHOC */ 179 /* ADHOC */
184 u16 beacon_period; 180 u16 beacon_period;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 63d020374c2b..3804a58d7f4e 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -114,9 +114,11 @@ const struct ethtool_ops lbs_ethtool_ops = {
114 .get_drvinfo = lbs_ethtool_get_drvinfo, 114 .get_drvinfo = lbs_ethtool_get_drvinfo,
115 .get_eeprom = lbs_ethtool_get_eeprom, 115 .get_eeprom = lbs_ethtool_get_eeprom,
116 .get_eeprom_len = lbs_ethtool_get_eeprom_len, 116 .get_eeprom_len = lbs_ethtool_get_eeprom_len,
117#ifdef CONFIG_LIBERTAS_MESH
117 .get_sset_count = lbs_mesh_ethtool_get_sset_count, 118 .get_sset_count = lbs_mesh_ethtool_get_sset_count,
118 .get_ethtool_stats = lbs_mesh_ethtool_get_stats, 119 .get_ethtool_stats = lbs_mesh_ethtool_get_stats,
119 .get_strings = lbs_mesh_ethtool_get_strings, 120 .get_strings = lbs_mesh_ethtool_get_strings,
121#endif
120 .get_wol = lbs_ethtool_get_wol, 122 .get_wol = lbs_ethtool_get_wol,
121 .set_wol = lbs_ethtool_set_wol, 123 .set_wol = lbs_ethtool_set_wol,
122}; 124};
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index bf4bfbae6227..3ea03f259ee7 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -23,6 +23,7 @@
23#include <linux/kthread.h> 23#include <linux/kthread.h>
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/netdevice.h> 25#include <linux/netdevice.h>
26#include <linux/semaphore.h>
26#include <linux/spi/libertas_spi.h> 27#include <linux/spi/libertas_spi.h>
27#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
28 29
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index db38a5a719fa..f5d641efd50a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -123,7 +123,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
123 if (priv->monitormode == monitor_mode) 123 if (priv->monitormode == monitor_mode)
124 return strlen(buf); 124 return strlen(buf);
125 if (!priv->monitormode) { 125 if (!priv->monitormode) {
126 if (priv->infra_open || priv->mesh_open) 126 if (priv->infra_open || lbs_mesh_open(priv))
127 return -EBUSY; 127 return -EBUSY;
128 if (priv->mode == IW_MODE_INFRA) 128 if (priv->mode == IW_MODE_INFRA)
129 lbs_cmd_80211_deauthenticate(priv, 129 lbs_cmd_80211_deauthenticate(priv,
@@ -533,31 +533,14 @@ static int lbs_thread(void *data)
533 if (priv->cmd_timed_out && priv->cur_cmd) { 533 if (priv->cmd_timed_out && priv->cur_cmd) {
534 struct cmd_ctrl_node *cmdnode = priv->cur_cmd; 534 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
535 535
536 if (++priv->nr_retries > 3) { 536 lbs_pr_info("Timeout submitting command 0x%04x\n",
537 lbs_pr_info("Excessive timeouts submitting " 537 le16_to_cpu(cmdnode->cmdbuf->command));
538 "command 0x%04x\n", 538 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
539 le16_to_cpu(cmdnode->cmdbuf->command)); 539 if (priv->reset_card)
540 lbs_complete_command(priv, cmdnode, -ETIMEDOUT); 540 priv->reset_card(priv);
541 priv->nr_retries = 0;
542 if (priv->reset_card)
543 priv->reset_card(priv);
544 } else {
545 priv->cur_cmd = NULL;
546 priv->dnld_sent = DNLD_RES_RECEIVED;
547 lbs_pr_info("requeueing command 0x%04x due "
548 "to timeout (#%d)\n",
549 le16_to_cpu(cmdnode->cmdbuf->command),
550 priv->nr_retries);
551
552 /* Stick it back at the _top_ of the pending queue
553 for immediate resubmission */
554 list_add(&cmdnode->list, &priv->cmdpendingq);
555 }
556 } 541 }
557 priv->cmd_timed_out = 0; 542 priv->cmd_timed_out = 0;
558 543
559
560
561 if (!priv->fw_ready) 544 if (!priv->fw_ready)
562 continue; 545 continue;
563 546
@@ -619,7 +602,7 @@ static int lbs_thread(void *data)
619 if (priv->connect_status == LBS_CONNECTED) 602 if (priv->connect_status == LBS_CONNECTED)
620 netif_wake_queue(priv->dev); 603 netif_wake_queue(priv->dev);
621 if (priv->mesh_dev && 604 if (priv->mesh_dev &&
622 priv->mesh_connect_status == LBS_CONNECTED) 605 lbs_mesh_connected(priv))
623 netif_wake_queue(priv->mesh_dev); 606 netif_wake_queue(priv->mesh_dev);
624 } 607 }
625 } 608 }
@@ -729,7 +712,7 @@ done:
729 * This function handles the timeout of command sending. 712 * This function handles the timeout of command sending.
730 * It will re-send the same command again. 713 * It will re-send the same command again.
731 */ 714 */
732static void command_timer_fn(unsigned long data) 715static void lbs_cmd_timeout_handler(unsigned long data)
733{ 716{
734 struct lbs_private *priv = (struct lbs_private *)data; 717 struct lbs_private *priv = (struct lbs_private *)data;
735 unsigned long flags; 718 unsigned long flags;
@@ -806,18 +789,6 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
806 return 0; 789 return 0;
807} 790}
808 791
809static void lbs_sync_channel_worker(struct work_struct *work)
810{
811 struct lbs_private *priv = container_of(work, struct lbs_private,
812 sync_channel);
813
814 lbs_deb_enter(LBS_DEB_MAIN);
815 if (lbs_update_channel(priv))
816 lbs_pr_info("Channel synchronization failed.");
817 lbs_deb_leave(LBS_DEB_MAIN);
818}
819
820
821static int lbs_init_adapter(struct lbs_private *priv) 792static int lbs_init_adapter(struct lbs_private *priv)
822{ 793{
823 size_t bufsize; 794 size_t bufsize;
@@ -845,14 +816,12 @@ static int lbs_init_adapter(struct lbs_private *priv)
845 memset(priv->current_addr, 0xff, ETH_ALEN); 816 memset(priv->current_addr, 0xff, ETH_ALEN);
846 817
847 priv->connect_status = LBS_DISCONNECTED; 818 priv->connect_status = LBS_DISCONNECTED;
848 priv->mesh_connect_status = LBS_DISCONNECTED;
849 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 819 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
850 priv->mode = IW_MODE_INFRA; 820 priv->mode = IW_MODE_INFRA;
851 priv->channel = DEFAULT_AD_HOC_CHANNEL; 821 priv->channel = DEFAULT_AD_HOC_CHANNEL;
852 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 822 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
853 priv->radio_on = 1; 823 priv->radio_on = 1;
854 priv->enablehwauto = 1; 824 priv->enablehwauto = 1;
855 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
856 priv->psmode = LBS802_11POWERMODECAM; 825 priv->psmode = LBS802_11POWERMODECAM;
857 priv->psstate = PS_STATE_FULL_POWER; 826 priv->psstate = PS_STATE_FULL_POWER;
858 priv->is_deep_sleep = 0; 827 priv->is_deep_sleep = 0;
@@ -862,7 +831,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
862 831
863 mutex_init(&priv->lock); 832 mutex_init(&priv->lock);
864 833
865 setup_timer(&priv->command_timer, command_timer_fn, 834 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
866 (unsigned long)priv); 835 (unsigned long)priv);
867 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, 836 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
868 (unsigned long)priv); 837 (unsigned long)priv);
@@ -997,11 +966,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
997 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); 966 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
998 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 967 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
999 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 968 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
1000 INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
1001
1002 priv->mesh_open = 0;
1003 sprintf(priv->mesh_ssid, "mesh");
1004 priv->mesh_ssid_len = 4;
1005 969
1006 priv->wol_criteria = 0xffffffff; 970 priv->wol_criteria = 0xffffffff;
1007 priv->wol_gpio = 0xff; 971 priv->wol_gpio = 0xff;
@@ -1075,6 +1039,17 @@ void lbs_remove_card(struct lbs_private *priv)
1075EXPORT_SYMBOL_GPL(lbs_remove_card); 1039EXPORT_SYMBOL_GPL(lbs_remove_card);
1076 1040
1077 1041
1042static int lbs_rtap_supported(struct lbs_private *priv)
1043{
1044 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
1045 return 1;
1046
1047 /* newer firmware use a capability mask */
1048 return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
1049 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
1050}
1051
1052
1078int lbs_start_card(struct lbs_private *priv) 1053int lbs_start_card(struct lbs_private *priv)
1079{ 1054{
1080 struct net_device *dev = priv->dev; 1055 struct net_device *dev = priv->dev;
@@ -1094,12 +1069,14 @@ int lbs_start_card(struct lbs_private *priv)
1094 1069
1095 lbs_update_channel(priv); 1070 lbs_update_channel(priv);
1096 1071
1072 lbs_init_mesh(priv);
1073
1097 /* 1074 /*
1098 * While rtap isn't related to mesh, only mesh-enabled 1075 * While rtap isn't related to mesh, only mesh-enabled
1099 * firmware implements the rtap functionality via 1076 * firmware implements the rtap functionality via
1100 * CMD_802_11_MONITOR_MODE. 1077 * CMD_802_11_MONITOR_MODE.
1101 */ 1078 */
1102 if (lbs_init_mesh(priv)) { 1079 if (lbs_rtap_supported(priv)) {
1103 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1080 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1104 lbs_pr_err("cannot register lbs_rtap attribute\n"); 1081 lbs_pr_err("cannot register lbs_rtap attribute\n");
1105 } 1082 }
@@ -1133,7 +1110,9 @@ void lbs_stop_card(struct lbs_private *priv)
1133 netif_carrier_off(dev); 1110 netif_carrier_off(dev);
1134 1111
1135 lbs_debugfs_remove_one(priv); 1112 lbs_debugfs_remove_one(priv);
1136 if (lbs_deinit_mesh(priv)) 1113 lbs_deinit_mesh(priv);
1114
1115 if (lbs_rtap_supported(priv))
1137 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1116 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1138 1117
1139 /* Delete the timeout of the currently processing command */ 1118 /* Delete the timeout of the currently processing command */
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 2f91c9b808af..954cd00f7452 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1,4 +1,3 @@
1#include <linux/moduleparam.h>
2#include <linux/delay.h> 1#include <linux/delay.h>
3#include <linux/etherdevice.h> 2#include <linux/etherdevice.h>
4#include <linux/netdevice.h> 3#include <linux/netdevice.h>
@@ -196,7 +195,14 @@ int lbs_init_mesh(struct lbs_private *priv)
196 195
197 lbs_deb_enter(LBS_DEB_MESH); 196 lbs_deb_enter(LBS_DEB_MESH);
198 197
199 if (priv->mesh_fw_ver == MESH_FW_OLD) { 198 priv->mesh_connect_status = LBS_DISCONNECTED;
199
200 /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
201 /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
202 /* 5.110.22 have mesh command with 0xa3 command id */
203 /* 10.0.0.p0 FW brings in mesh config command with different id */
204 /* Check FW version MSB and initialize mesh_fw_ver */
205 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
200 /* Enable mesh, if supported, and work out which TLV it uses. 206 /* Enable mesh, if supported, and work out which TLV it uses.
201 0x100 + 291 is an unofficial value used in 5.110.20.pXX 207 0x100 + 291 is an unofficial value used in 5.110.20.pXX
202 0x100 + 37 is the official value used in 5.110.21.pXX 208 0x100 + 37 is the official value used in 5.110.21.pXX
@@ -218,7 +224,9 @@ int lbs_init_mesh(struct lbs_private *priv)
218 priv->channel)) 224 priv->channel))
219 priv->mesh_tlv = 0; 225 priv->mesh_tlv = 0;
220 } 226 }
221 } else if (priv->mesh_fw_ver == MESH_FW_NEW) { 227 } else
228 if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
229 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
222 /* 10.0.0.pXX new firmwares should succeed with TLV 230 /* 10.0.0.pXX new firmwares should succeed with TLV
223 * 0x100+37; Do not invoke command with old TLV. 231 * 0x100+37; Do not invoke command with old TLV.
224 */ 232 */
@@ -227,7 +235,12 @@ int lbs_init_mesh(struct lbs_private *priv)
227 priv->channel)) 235 priv->channel))
228 priv->mesh_tlv = 0; 236 priv->mesh_tlv = 0;
229 } 237 }
238
239
230 if (priv->mesh_tlv) { 240 if (priv->mesh_tlv) {
241 sprintf(priv->mesh_ssid, "mesh");
242 priv->mesh_ssid_len = 4;
243
231 lbs_add_mesh(priv); 244 lbs_add_mesh(priv);
232 245
233 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 246 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
@@ -416,10 +429,10 @@ struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
416 struct net_device *dev, struct rxpd *rxpd) 429 struct net_device *dev, struct rxpd *rxpd)
417{ 430{
418 if (priv->mesh_dev) { 431 if (priv->mesh_dev) {
419 if (priv->mesh_fw_ver == MESH_FW_OLD) { 432 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
420 if (rxpd->rx_control & RxPD_MESH_FRAME) 433 if (rxpd->rx_control & RxPD_MESH_FRAME)
421 dev = priv->mesh_dev; 434 dev = priv->mesh_dev;
422 } else if (priv->mesh_fw_ver == MESH_FW_NEW) { 435 } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
423 if (rxpd->u.bss.bss_num == MESH_IFACE_ID) 436 if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
424 dev = priv->mesh_dev; 437 dev = priv->mesh_dev;
425 } 438 }
@@ -432,9 +445,9 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
432 struct net_device *dev, struct txpd *txpd) 445 struct net_device *dev, struct txpd *txpd)
433{ 446{
434 if (dev == priv->mesh_dev) { 447 if (dev == priv->mesh_dev) {
435 if (priv->mesh_fw_ver == MESH_FW_OLD) 448 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
436 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); 449 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
437 else if (priv->mesh_fw_ver == MESH_FW_NEW) 450 else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
438 txpd->u.bss.bss_num = MESH_IFACE_ID; 451 txpd->u.bss.bss_num = MESH_IFACE_ID;
439 } 452 }
440} 453}
@@ -538,7 +551,7 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
538 * Command id is 0xac for v10 FW along with mesh interface 551 * Command id is 0xac for v10 FW along with mesh interface
539 * id in bits 14-13-12. 552 * id in bits 14-13-12.
540 */ 553 */
541 if (priv->mesh_fw_ver == MESH_FW_NEW) 554 if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
542 command = CMD_MESH_CONFIG | 555 command = CMD_MESH_CONFIG |
543 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET); 556 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
544 557
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
index fea9b5d005fc..e2573303a328 100644
--- a/drivers/net/wireless/libertas/mesh.h
+++ b/drivers/net/wireless/libertas/mesh.h
@@ -9,6 +9,8 @@
9#include <net/lib80211.h> 9#include <net/lib80211.h>
10 10
11 11
12#ifdef CONFIG_LIBERTAS_MESH
13
12/* Mesh statistics */ 14/* Mesh statistics */
13struct lbs_mesh_stats { 15struct lbs_mesh_stats {
14 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */ 16 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
@@ -46,11 +48,20 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
46/* Command handling */ 48/* Command handling */
47 49
48struct cmd_ds_command; 50struct cmd_ds_command;
51struct cmd_ds_mesh_access;
52struct cmd_ds_mesh_config;
49 53
50int lbs_cmd_bt_access(struct cmd_ds_command *cmd, 54int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
51 u16 cmd_action, void *pdata_buf); 55 u16 cmd_action, void *pdata_buf);
52int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, 56int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
53 u16 cmd_action, void *pdata_buf); 57 u16 cmd_action, void *pdata_buf);
58int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
59 struct cmd_ds_mesh_access *cmd);
60int lbs_mesh_config_send(struct lbs_private *priv,
61 struct cmd_ds_mesh_config *cmd,
62 uint16_t action, uint16_t type);
63int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
64
54 65
55 66
56/* Persistent configuration */ 67/* Persistent configuration */
@@ -75,4 +86,25 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
75 uint32_t stringset, uint8_t *s); 86 uint32_t stringset, uint8_t *s);
76 87
77 88
89/* Accessors */
90
91#define lbs_mesh_open(priv) (priv->mesh_open)
92#define lbs_mesh_connected(priv) (priv->mesh_connect_status == LBS_CONNECTED)
93
94#else
95
96#define lbs_init_mesh(priv)
97#define lbs_deinit_mesh(priv)
98#define lbs_add_mesh(priv)
99#define lbs_remove_mesh(priv)
100#define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
101#define lbs_mesh_set_txpd(priv, dev, txpd)
102#define lbs_mesh_config(priv, enable, chan)
103#define lbs_mesh_open(priv) (0)
104#define lbs_mesh_connected(priv) (0)
105
106#endif
107
108
109
78#endif 110#endif
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index b0b1c7841500..220361e69cd3 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -635,7 +635,7 @@ out:
635 if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) 635 if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len)
636 netif_wake_queue(priv->dev); 636 netif_wake_queue(priv->dev);
637 637
638 if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && 638 if (priv->mesh_dev && lbs_mesh_connected(priv) &&
639 !priv->tx_pending_len) 639 !priv->tx_pending_len)
640 netif_wake_queue(priv->mesh_dev); 640 netif_wake_queue(priv->mesh_dev);
641 641
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 315d1ce286ca..52d244ea3d97 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -198,7 +198,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
198 if (priv->connect_status == LBS_CONNECTED) 198 if (priv->connect_status == LBS_CONNECTED)
199 netif_wake_queue(priv->dev); 199 netif_wake_queue(priv->dev);
200 200
201 if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) 201 if (priv->mesh_dev && lbs_mesh_connected(priv))
202 netif_wake_queue(priv->mesh_dev); 202 netif_wake_queue(priv->mesh_dev);
203} 203}
204EXPORT_SYMBOL_GPL(lbs_send_tx_feedback); 204EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 4b1aab593a84..71f88a08e090 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -192,7 +192,7 @@ static void copy_active_data_rates(struct lbs_private *priv, u8 *rates)
192 lbs_deb_enter(LBS_DEB_WEXT); 192 lbs_deb_enter(LBS_DEB_WEXT);
193 193
194 if ((priv->connect_status != LBS_CONNECTED) && 194 if ((priv->connect_status != LBS_CONNECTED) &&
195 (priv->mesh_connect_status != LBS_CONNECTED)) 195 !lbs_mesh_connected(priv))
196 memcpy(rates, lbs_bg_rates, MAX_RATES); 196 memcpy(rates, lbs_bg_rates, MAX_RATES);
197 else 197 else
198 memcpy(rates, priv->curbssparams.rates, MAX_RATES); 198 memcpy(rates, priv->curbssparams.rates, MAX_RATES);
@@ -298,6 +298,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
298 return 0; 298 return 0;
299} 299}
300 300
301#ifdef CONFIG_LIBERTAS_MESH
301static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, 302static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
302 struct iw_point *dwrq, char *extra) 303 struct iw_point *dwrq, char *extra)
303{ 304{
@@ -307,7 +308,7 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
307 308
308 /* Use nickname to indicate that mesh is on */ 309 /* Use nickname to indicate that mesh is on */
309 310
310 if (priv->mesh_connect_status == LBS_CONNECTED) { 311 if (lbs_mesh_connected(priv)) {
311 strncpy(extra, "Mesh", 12); 312 strncpy(extra, "Mesh", 12);
312 extra[12] = '\0'; 313 extra[12] = '\0';
313 dwrq->length = strlen(extra); 314 dwrq->length = strlen(extra);
@@ -321,6 +322,7 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
321 lbs_deb_leave(LBS_DEB_WEXT); 322 lbs_deb_leave(LBS_DEB_WEXT);
322 return 0; 323 return 0;
323} 324}
325#endif
324 326
325static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, 327static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
326 struct iw_param *vwrq, char *extra) 328 struct iw_param *vwrq, char *extra)
@@ -422,6 +424,7 @@ static int lbs_get_mode(struct net_device *dev,
422 return 0; 424 return 0;
423} 425}
424 426
427#ifdef CONFIG_LIBERTAS_MESH
425static int mesh_wlan_get_mode(struct net_device *dev, 428static int mesh_wlan_get_mode(struct net_device *dev,
426 struct iw_request_info *info, u32 * uwrq, 429 struct iw_request_info *info, u32 * uwrq,
427 char *extra) 430 char *extra)
@@ -433,6 +436,7 @@ static int mesh_wlan_get_mode(struct net_device *dev,
433 lbs_deb_leave(LBS_DEB_WEXT); 436 lbs_deb_leave(LBS_DEB_WEXT);
434 return 0; 437 return 0;
435} 438}
439#endif
436 440
437static int lbs_get_txpow(struct net_device *dev, 441static int lbs_get_txpow(struct net_device *dev,
438 struct iw_request_info *info, 442 struct iw_request_info *info,
@@ -863,7 +867,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
863 867
864 /* If we're not associated, all quality values are meaningless */ 868 /* If we're not associated, all quality values are meaningless */
865 if ((priv->connect_status != LBS_CONNECTED) && 869 if ((priv->connect_status != LBS_CONNECTED) &&
866 (priv->mesh_connect_status != LBS_CONNECTED)) 870 !lbs_mesh_connected(priv))
867 goto out; 871 goto out;
868 872
869 /* Quality by RSSI */ 873 /* Quality by RSSI */
@@ -1010,6 +1014,7 @@ out:
1010 return ret; 1014 return ret;
1011} 1015}
1012 1016
1017#ifdef CONFIG_LIBERTAS_MESH
1013static int lbs_mesh_set_freq(struct net_device *dev, 1018static int lbs_mesh_set_freq(struct net_device *dev,
1014 struct iw_request_info *info, 1019 struct iw_request_info *info,
1015 struct iw_freq *fwrq, char *extra) 1020 struct iw_freq *fwrq, char *extra)
@@ -1061,6 +1066,7 @@ out:
1061 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1066 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1062 return ret; 1067 return ret;
1063} 1068}
1069#endif
1064 1070
1065static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, 1071static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
1066 struct iw_param *vwrq, char *extra) 1072 struct iw_param *vwrq, char *extra)
@@ -2108,6 +2114,7 @@ out:
2108 return ret; 2114 return ret;
2109} 2115}
2110 2116
2117#ifdef CONFIG_LIBERTAS_MESH
2111static int lbs_mesh_get_essid(struct net_device *dev, 2118static int lbs_mesh_get_essid(struct net_device *dev,
2112 struct iw_request_info *info, 2119 struct iw_request_info *info,
2113 struct iw_point *dwrq, char *extra) 2120 struct iw_point *dwrq, char *extra)
@@ -2161,6 +2168,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
2161 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 2168 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
2162 return ret; 2169 return ret;
2163} 2170}
2171#endif
2164 2172
2165/** 2173/**
2166 * @brief Connect to the AP or Ad-hoc Network with specific bssid 2174 * @brief Connect to the AP or Ad-hoc Network with specific bssid
@@ -2267,7 +2275,13 @@ static const iw_handler lbs_handler[] = {
2267 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2275 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2268 (iw_handler) NULL, /* SIOCSIWPMKSA */ 2276 (iw_handler) NULL, /* SIOCSIWPMKSA */
2269}; 2277};
2278struct iw_handler_def lbs_handler_def = {
2279 .num_standard = ARRAY_SIZE(lbs_handler),
2280 .standard = (iw_handler *) lbs_handler,
2281 .get_wireless_stats = lbs_get_wireless_stats,
2282};
2270 2283
2284#ifdef CONFIG_LIBERTAS_MESH
2271static const iw_handler mesh_wlan_handler[] = { 2285static const iw_handler mesh_wlan_handler[] = {
2272 (iw_handler) NULL, /* SIOCSIWCOMMIT */ 2286 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2273 (iw_handler) lbs_get_name, /* SIOCGIWNAME */ 2287 (iw_handler) lbs_get_name, /* SIOCGIWNAME */
@@ -2325,14 +2339,10 @@ static const iw_handler mesh_wlan_handler[] = {
2325 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2339 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2326 (iw_handler) NULL, /* SIOCSIWPMKSA */ 2340 (iw_handler) NULL, /* SIOCSIWPMKSA */
2327}; 2341};
2328struct iw_handler_def lbs_handler_def = {
2329 .num_standard = ARRAY_SIZE(lbs_handler),
2330 .standard = (iw_handler *) lbs_handler,
2331 .get_wireless_stats = lbs_get_wireless_stats,
2332};
2333 2342
2334struct iw_handler_def mesh_handler_def = { 2343struct iw_handler_def mesh_handler_def = {
2335 .num_standard = ARRAY_SIZE(mesh_wlan_handler), 2344 .num_standard = ARRAY_SIZE(mesh_wlan_handler),
2336 .standard = (iw_handler *) mesh_wlan_handler, 2345 .standard = (iw_handler *) mesh_wlan_handler,
2337 .get_wireless_stats = lbs_get_wireless_stats, 2346 .get_wireless_stats = lbs_get_wireless_stats,
2338}; 2347};
2348#endif
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 26a1abd5bb03..6ab30033c26c 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -318,14 +318,14 @@ static void lbtf_op_stop(struct ieee80211_hw *hw)
318} 318}
319 319
320static int lbtf_op_add_interface(struct ieee80211_hw *hw, 320static int lbtf_op_add_interface(struct ieee80211_hw *hw,
321 struct ieee80211_if_init_conf *conf) 321 struct ieee80211_vif *vif)
322{ 322{
323 struct lbtf_private *priv = hw->priv; 323 struct lbtf_private *priv = hw->priv;
324 if (priv->vif != NULL) 324 if (priv->vif != NULL)
325 return -EOPNOTSUPP; 325 return -EOPNOTSUPP;
326 326
327 priv->vif = conf->vif; 327 priv->vif = vif;
328 switch (conf->type) { 328 switch (vif->type) {
329 case NL80211_IFTYPE_MESH_POINT: 329 case NL80211_IFTYPE_MESH_POINT:
330 case NL80211_IFTYPE_AP: 330 case NL80211_IFTYPE_AP:
331 lbtf_set_mode(priv, LBTF_AP_MODE); 331 lbtf_set_mode(priv, LBTF_AP_MODE);
@@ -337,12 +337,12 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw,
337 priv->vif = NULL; 337 priv->vif = NULL;
338 return -EOPNOTSUPP; 338 return -EOPNOTSUPP;
339 } 339 }
340 lbtf_set_mac_address(priv, (u8 *) conf->mac_addr); 340 lbtf_set_mac_address(priv, (u8 *) vif->addr);
341 return 0; 341 return 0;
342} 342}
343 343
344static void lbtf_op_remove_interface(struct ieee80211_hw *hw, 344static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
345 struct ieee80211_if_init_conf *conf) 345 struct ieee80211_vif *vif)
346{ 346{
347 struct lbtf_private *priv = hw->priv; 347 struct lbtf_private *priv = hw->priv;
348 348
@@ -555,6 +555,9 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev)
555 priv->band.n_channels = ARRAY_SIZE(lbtf_channels); 555 priv->band.n_channels = ARRAY_SIZE(lbtf_channels);
556 priv->band.channels = priv->channels; 556 priv->band.channels = priv->channels;
557 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 557 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
558 hw->wiphy->interface_modes =
559 BIT(NL80211_IFTYPE_STATION) |
560 BIT(NL80211_IFTYPE_ADHOC);
558 skb_queue_head_init(&priv->bc_ps_buf); 561 skb_queue_head_init(&priv->bc_ps_buf);
559 562
560 SET_IEEE80211_DEV(hw, dmdev); 563 SET_IEEE80211_DEV(hw, dmdev);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 88e41176e7fd..6ea77e95277b 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -32,6 +32,10 @@ static int radios = 2;
32module_param(radios, int, 0444); 32module_param(radios, int, 0444);
33MODULE_PARM_DESC(radios, "Number of simulated radios"); 33MODULE_PARM_DESC(radios, "Number of simulated radios");
34 34
35static bool fake_hw_scan;
36module_param(fake_hw_scan, bool, 0444);
37MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler");
38
35/** 39/**
36 * enum hwsim_regtest - the type of regulatory tests we offer 40 * enum hwsim_regtest - the type of regulatory tests we offer
37 * 41 *
@@ -281,6 +285,8 @@ struct mac80211_hwsim_data {
281 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; 285 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
282 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 286 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
283 287
288 struct mac_address addresses[2];
289
284 struct ieee80211_channel *channel; 290 struct ieee80211_channel *channel;
285 unsigned long beacon_int; /* in jiffies unit */ 291 unsigned long beacon_int; /* in jiffies unit */
286 unsigned int rx_filter; 292 unsigned int rx_filter;
@@ -436,6 +442,38 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
436} 442}
437 443
438 444
445struct mac80211_hwsim_addr_match_data {
446 bool ret;
447 const u8 *addr;
448};
449
450static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
451 struct ieee80211_vif *vif)
452{
453 struct mac80211_hwsim_addr_match_data *md = data;
454 if (memcmp(mac, md->addr, ETH_ALEN) == 0)
455 md->ret = true;
456}
457
458
459static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
460 const u8 *addr)
461{
462 struct mac80211_hwsim_addr_match_data md;
463
464 if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0)
465 return true;
466
467 md.ret = false;
468 md.addr = addr;
469 ieee80211_iterate_active_interfaces_atomic(data->hw,
470 mac80211_hwsim_addr_iter,
471 &md);
472
473 return md.ret;
474}
475
476
439static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 477static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
440 struct sk_buff *skb) 478 struct sk_buff *skb)
441{ 479{
@@ -488,8 +526,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
488 if (nskb == NULL) 526 if (nskb == NULL)
489 continue; 527 continue;
490 528
491 if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr, 529 if (mac80211_hwsim_addr_match(data2, hdr->addr1))
492 ETH_ALEN) == 0)
493 ack = true; 530 ack = true;
494 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 531 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
495 ieee80211_rx_irqsafe(data2->hw, nskb); 532 ieee80211_rx_irqsafe(data2->hw, nskb);
@@ -553,24 +590,24 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
553 590
554 591
555static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, 592static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
556 struct ieee80211_if_init_conf *conf) 593 struct ieee80211_vif *vif)
557{ 594{
558 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", 595 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
559 wiphy_name(hw->wiphy), __func__, conf->type, 596 wiphy_name(hw->wiphy), __func__, vif->type,
560 conf->mac_addr); 597 vif->addr);
561 hwsim_set_magic(conf->vif); 598 hwsim_set_magic(vif);
562 return 0; 599 return 0;
563} 600}
564 601
565 602
566static void mac80211_hwsim_remove_interface( 603static void mac80211_hwsim_remove_interface(
567 struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) 604 struct ieee80211_hw *hw, struct ieee80211_vif *vif)
568{ 605{
569 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", 606 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
570 wiphy_name(hw->wiphy), __func__, conf->type, 607 wiphy_name(hw->wiphy), __func__, vif->type,
571 conf->mac_addr); 608 vif->addr);
572 hwsim_check_magic(conf->vif); 609 hwsim_check_magic(vif);
573 hwsim_clear_magic(conf->vif); 610 hwsim_clear_magic(vif);
574} 611}
575 612
576 613
@@ -618,12 +655,26 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
618{ 655{
619 struct mac80211_hwsim_data *data = hw->priv; 656 struct mac80211_hwsim_data *data = hw->priv;
620 struct ieee80211_conf *conf = &hw->conf; 657 struct ieee80211_conf *conf = &hw->conf;
621 658 static const char *chantypes[4] = {
622 printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n", 659 [NL80211_CHAN_NO_HT] = "noht",
660 [NL80211_CHAN_HT20] = "ht20",
661 [NL80211_CHAN_HT40MINUS] = "ht40-",
662 [NL80211_CHAN_HT40PLUS] = "ht40+",
663 };
664 static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
665 [IEEE80211_SMPS_AUTOMATIC] = "auto",
666 [IEEE80211_SMPS_OFF] = "off",
667 [IEEE80211_SMPS_STATIC] = "static",
668 [IEEE80211_SMPS_DYNAMIC] = "dynamic",
669 };
670
671 printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
623 wiphy_name(hw->wiphy), __func__, 672 wiphy_name(hw->wiphy), __func__,
624 conf->channel->center_freq, 673 conf->channel->center_freq,
674 chantypes[conf->channel_type],
625 !!(conf->flags & IEEE80211_CONF_IDLE), 675 !!(conf->flags & IEEE80211_CONF_IDLE),
626 !!(conf->flags & IEEE80211_CONF_PS)); 676 !!(conf->flags & IEEE80211_CONF_PS),
677 smps_modes[conf->smps_mode]);
627 678
628 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); 679 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
629 680
@@ -720,23 +771,41 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
720 } 771 }
721} 772}
722 773
774static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
775 struct ieee80211_vif *vif,
776 struct ieee80211_sta *sta)
777{
778 hwsim_check_magic(vif);
779 hwsim_set_sta_magic(sta);
780
781 return 0;
782}
783
784static int mac80211_hwsim_sta_remove(struct ieee80211_hw *hw,
785 struct ieee80211_vif *vif,
786 struct ieee80211_sta *sta)
787{
788 hwsim_check_magic(vif);
789 hwsim_clear_sta_magic(sta);
790
791 return 0;
792}
793
723static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw, 794static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
724 struct ieee80211_vif *vif, 795 struct ieee80211_vif *vif,
725 enum sta_notify_cmd cmd, 796 enum sta_notify_cmd cmd,
726 struct ieee80211_sta *sta) 797 struct ieee80211_sta *sta)
727{ 798{
728 hwsim_check_magic(vif); 799 hwsim_check_magic(vif);
800
729 switch (cmd) { 801 switch (cmd) {
730 case STA_NOTIFY_ADD:
731 hwsim_set_sta_magic(sta);
732 break;
733 case STA_NOTIFY_REMOVE:
734 hwsim_clear_sta_magic(sta);
735 break;
736 case STA_NOTIFY_SLEEP: 802 case STA_NOTIFY_SLEEP:
737 case STA_NOTIFY_AWAKE: 803 case STA_NOTIFY_AWAKE:
738 /* TODO: make good use of these flags */ 804 /* TODO: make good use of these flags */
739 break; 805 break;
806 default:
807 WARN(1, "Invalid sta notify: %d\n", cmd);
808 break;
740 } 809 }
741} 810}
742 811
@@ -827,7 +896,77 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
827} 896}
828#endif 897#endif
829 898
830static const struct ieee80211_ops mac80211_hwsim_ops = 899static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
900 struct ieee80211_vif *vif,
901 enum ieee80211_ampdu_mlme_action action,
902 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
903{
904 switch (action) {
905 case IEEE80211_AMPDU_TX_START:
906 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
907 break;
908 case IEEE80211_AMPDU_TX_STOP:
909 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
910 break;
911 case IEEE80211_AMPDU_TX_OPERATIONAL:
912 break;
913 case IEEE80211_AMPDU_RX_START:
914 case IEEE80211_AMPDU_RX_STOP:
915 break;
916 default:
917 return -EOPNOTSUPP;
918 }
919
920 return 0;
921}
922
923static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
924{
925 /*
926 * In this special case, there's nothing we need to
927 * do because hwsim does transmission synchronously.
928 * In the future, when it does transmissions via
929 * userspace, we may need to do something.
930 */
931}
932
933struct hw_scan_done {
934 struct delayed_work w;
935 struct ieee80211_hw *hw;
936};
937
938static void hw_scan_done(struct work_struct *work)
939{
940 struct hw_scan_done *hsd =
941 container_of(work, struct hw_scan_done, w.work);
942
943 ieee80211_scan_completed(hsd->hw, false);
944 kfree(hsd);
945}
946
947static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
948 struct cfg80211_scan_request *req)
949{
950 struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL);
951 int i;
952
953 if (!hsd)
954 return -ENOMEM;
955
956 hsd->hw = hw;
957 INIT_DELAYED_WORK(&hsd->w, hw_scan_done);
958
959 printk(KERN_DEBUG "hwsim scan request\n");
960 for (i = 0; i < req->n_channels; i++)
961 printk(KERN_DEBUG "hwsim scan freq %d\n",
962 req->channels[i]->center_freq);
963
964 ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ);
965
966 return 0;
967}
968
969static struct ieee80211_ops mac80211_hwsim_ops =
831{ 970{
832 .tx = mac80211_hwsim_tx, 971 .tx = mac80211_hwsim_tx,
833 .start = mac80211_hwsim_start, 972 .start = mac80211_hwsim_start,
@@ -837,10 +976,14 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
837 .config = mac80211_hwsim_config, 976 .config = mac80211_hwsim_config,
838 .configure_filter = mac80211_hwsim_configure_filter, 977 .configure_filter = mac80211_hwsim_configure_filter,
839 .bss_info_changed = mac80211_hwsim_bss_info_changed, 978 .bss_info_changed = mac80211_hwsim_bss_info_changed,
979 .sta_add = mac80211_hwsim_sta_add,
980 .sta_remove = mac80211_hwsim_sta_remove,
840 .sta_notify = mac80211_hwsim_sta_notify, 981 .sta_notify = mac80211_hwsim_sta_notify,
841 .set_tim = mac80211_hwsim_set_tim, 982 .set_tim = mac80211_hwsim_set_tim,
842 .conf_tx = mac80211_hwsim_conf_tx, 983 .conf_tx = mac80211_hwsim_conf_tx,
843 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) 984 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
985 .ampdu_action = mac80211_hwsim_ampdu_action,
986 .flush = mac80211_hwsim_flush,
844}; 987};
845 988
846 989
@@ -1035,6 +1178,9 @@ static int __init init_mac80211_hwsim(void)
1035 if (radios < 1 || radios > 100) 1178 if (radios < 1 || radios > 100)
1036 return -EINVAL; 1179 return -EINVAL;
1037 1180
1181 if (fake_hw_scan)
1182 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
1183
1038 spin_lock_init(&hwsim_radio_lock); 1184 spin_lock_init(&hwsim_radio_lock);
1039 INIT_LIST_HEAD(&hwsim_radios); 1185 INIT_LIST_HEAD(&hwsim_radios);
1040 1186
@@ -1072,7 +1218,11 @@ static int __init init_mac80211_hwsim(void)
1072 SET_IEEE80211_DEV(hw, data->dev); 1218 SET_IEEE80211_DEV(hw, data->dev);
1073 addr[3] = i >> 8; 1219 addr[3] = i >> 8;
1074 addr[4] = i; 1220 addr[4] = i;
1075 SET_IEEE80211_PERM_ADDR(hw, addr); 1221 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
1222 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
1223 data->addresses[1].addr[0] |= 0x40;
1224 hw->wiphy->n_addresses = 2;
1225 hw->wiphy->addresses = data->addresses;
1076 1226
1077 hw->channel_change_time = 1; 1227 hw->channel_change_time = 1;
1078 hw->queues = 4; 1228 hw->queues = 4;
@@ -1082,7 +1232,9 @@ static int __init init_mac80211_hwsim(void)
1082 BIT(NL80211_IFTYPE_MESH_POINT); 1232 BIT(NL80211_IFTYPE_MESH_POINT);
1083 1233
1084 hw->flags = IEEE80211_HW_MFP_CAPABLE | 1234 hw->flags = IEEE80211_HW_MFP_CAPABLE |
1085 IEEE80211_HW_SIGNAL_DBM; 1235 IEEE80211_HW_SIGNAL_DBM |
1236 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
1237 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS;
1086 1238
1087 /* ask mac80211 to reserve space for magic */ 1239 /* ask mac80211 to reserve space for magic */
1088 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 1240 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 59f92105b0c2..ac65e13eb0de 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2,7 +2,7 @@
2 * drivers/net/wireless/mwl8k.c 2 * drivers/net/wireless/mwl8k.c
3 * Driver for Marvell TOPDOG 802.11 Wireless cards 3 * Driver for Marvell TOPDOG 802.11 Wireless cards
4 * 4 *
5 * Copyright (C) 2008-2009 Marvell Semiconductor Inc. 5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6 * 6 *
7 * This file is licensed under the terms of the GNU General Public 7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any 8 * License version 2. This program is licensed "as is" without any
@@ -26,7 +26,7 @@
26 26
27#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 27#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
28#define MWL8K_NAME KBUILD_MODNAME 28#define MWL8K_NAME KBUILD_MODNAME
29#define MWL8K_VERSION "0.10" 29#define MWL8K_VERSION "0.12"
30 30
31/* Register definitions */ 31/* Register definitions */
32#define MWL8K_HIU_GEN_PTR 0x00000c10 32#define MWL8K_HIU_GEN_PTR 0x00000c10
@@ -92,8 +92,7 @@ struct mwl8k_device_info {
92 char *part_name; 92 char *part_name;
93 char *helper_image; 93 char *helper_image;
94 char *fw_image; 94 char *fw_image;
95 struct rxd_ops *rxd_ops; 95 struct rxd_ops *ap_rxd_ops;
96 u16 modes;
97}; 96};
98 97
99struct mwl8k_rx_queue { 98struct mwl8k_rx_queue {
@@ -120,34 +119,36 @@ struct mwl8k_tx_queue {
120 /* sw appends here */ 119 /* sw appends here */
121 int tail; 120 int tail;
122 121
123 struct ieee80211_tx_queue_stats stats; 122 unsigned int len;
124 struct mwl8k_tx_desc *txd; 123 struct mwl8k_tx_desc *txd;
125 dma_addr_t txd_dma; 124 dma_addr_t txd_dma;
126 struct sk_buff **skb; 125 struct sk_buff **skb;
127}; 126};
128 127
129/* Pointers to the firmware data and meta information about it. */ 128struct mwl8k_priv {
130struct mwl8k_firmware { 129 struct ieee80211_hw *hw;
131 /* Boot helper code */ 130 struct pci_dev *pdev;
132 struct firmware *helper;
133 131
134 /* Microcode */ 132 struct mwl8k_device_info *device_info;
135 struct firmware *ucode;
136};
137 133
138struct mwl8k_priv {
139 void __iomem *sram; 134 void __iomem *sram;
140 void __iomem *regs; 135 void __iomem *regs;
141 struct ieee80211_hw *hw;
142 136
143 struct pci_dev *pdev; 137 /* firmware */
138 struct firmware *fw_helper;
139 struct firmware *fw_ucode;
144 140
145 struct mwl8k_device_info *device_info; 141 /* hardware/firmware parameters */
146 bool ap_fw; 142 bool ap_fw;
147 struct rxd_ops *rxd_ops; 143 struct rxd_ops *rxd_ops;
148 144 struct ieee80211_supported_band band_24;
149 /* firmware files and meta data */ 145 struct ieee80211_channel channels_24[14];
150 struct mwl8k_firmware fw; 146 struct ieee80211_rate rates_24[14];
147 struct ieee80211_supported_band band_50;
148 struct ieee80211_channel channels_50[4];
149 struct ieee80211_rate rates_50[9];
150 u32 ap_macids_supported;
151 u32 sta_macids_supported;
151 152
152 /* firmware access */ 153 /* firmware access */
153 struct mutex fw_mutex; 154 struct mutex fw_mutex;
@@ -161,9 +162,9 @@ struct mwl8k_priv {
161 /* TX quiesce completion, protected by fw_mutex and tx_lock */ 162 /* TX quiesce completion, protected by fw_mutex and tx_lock */
162 struct completion *tx_wait; 163 struct completion *tx_wait;
163 164
164 struct ieee80211_vif *vif; 165 /* List of interfaces. */
165 166 u32 macids_used;
166 struct ieee80211_channel *current_channel; 167 struct list_head vif_list;
167 168
168 /* power management status cookie from firmware */ 169 /* power management status cookie from firmware */
169 u32 *cookie; 170 u32 *cookie;
@@ -182,11 +183,6 @@ struct mwl8k_priv {
182 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 183 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
183 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 184 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
184 185
185 /* PHY parameters */
186 struct ieee80211_supported_band band;
187 struct ieee80211_channel channels[14];
188 struct ieee80211_rate rates[14];
189
190 bool radio_on; 186 bool radio_on;
191 bool radio_short_preamble; 187 bool radio_short_preamble;
192 bool sniffer_enabled; 188 bool sniffer_enabled;
@@ -205,32 +201,33 @@ struct mwl8k_priv {
205 */ 201 */
206 struct work_struct finalize_join_worker; 202 struct work_struct finalize_join_worker;
207 203
208 /* Tasklet to reclaim TX descriptors and buffers after tx */ 204 /* Tasklet to perform TX reclaim. */
209 struct tasklet_struct tx_reclaim_task; 205 struct tasklet_struct poll_tx_task;
206
207 /* Tasklet to perform RX. */
208 struct tasklet_struct poll_rx_task;
210}; 209};
211 210
212/* Per interface specific private data */ 211/* Per interface specific private data */
213struct mwl8k_vif { 212struct mwl8k_vif {
214 /* backpointer to parent config block */ 213 struct list_head list;
215 struct mwl8k_priv *priv; 214 struct ieee80211_vif *vif;
216
217 /* BSS config of AP or IBSS from mac80211*/
218 struct ieee80211_bss_conf bss_info;
219
220 /* BSSID of AP or IBSS */
221 u8 bssid[ETH_ALEN];
222 u8 mac_addr[ETH_ALEN];
223 215
224 /* Index into station database.Returned by update_sta_db call */ 216 /* Firmware macid for this vif. */
225 u8 peer_id; 217 int macid;
226 218
227 /* Non AMPDU sequence number assigned by driver */ 219 /* Non AMPDU sequence number assigned by driver. */
228 u16 seqno; 220 u16 seqno;
229}; 221};
230
231#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 222#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
232 223
233static const struct ieee80211_channel mwl8k_channels[] = { 224struct mwl8k_sta {
225 /* Index into station database. Returned by UPDATE_STADB. */
226 u8 peer_id;
227};
228#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
229
230static const struct ieee80211_channel mwl8k_channels_24[] = {
234 { .center_freq = 2412, .hw_value = 1, }, 231 { .center_freq = 2412, .hw_value = 1, },
235 { .center_freq = 2417, .hw_value = 2, }, 232 { .center_freq = 2417, .hw_value = 2, },
236 { .center_freq = 2422, .hw_value = 3, }, 233 { .center_freq = 2422, .hw_value = 3, },
@@ -242,9 +239,12 @@ static const struct ieee80211_channel mwl8k_channels[] = {
242 { .center_freq = 2452, .hw_value = 9, }, 239 { .center_freq = 2452, .hw_value = 9, },
243 { .center_freq = 2457, .hw_value = 10, }, 240 { .center_freq = 2457, .hw_value = 10, },
244 { .center_freq = 2462, .hw_value = 11, }, 241 { .center_freq = 2462, .hw_value = 11, },
242 { .center_freq = 2467, .hw_value = 12, },
243 { .center_freq = 2472, .hw_value = 13, },
244 { .center_freq = 2484, .hw_value = 14, },
245}; 245};
246 246
247static const struct ieee80211_rate mwl8k_rates[] = { 247static const struct ieee80211_rate mwl8k_rates_24[] = {
248 { .bitrate = 10, .hw_value = 2, }, 248 { .bitrate = 10, .hw_value = 2, },
249 { .bitrate = 20, .hw_value = 4, }, 249 { .bitrate = 20, .hw_value = 4, },
250 { .bitrate = 55, .hw_value = 11, }, 250 { .bitrate = 55, .hw_value = 11, },
@@ -261,8 +261,23 @@ static const struct ieee80211_rate mwl8k_rates[] = {
261 { .bitrate = 720, .hw_value = 144, }, 261 { .bitrate = 720, .hw_value = 144, },
262}; 262};
263 263
264static const u8 mwl8k_rateids[12] = { 264static const struct ieee80211_channel mwl8k_channels_50[] = {
265 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 265 { .center_freq = 5180, .hw_value = 36, },
266 { .center_freq = 5200, .hw_value = 40, },
267 { .center_freq = 5220, .hw_value = 44, },
268 { .center_freq = 5240, .hw_value = 48, },
269};
270
271static const struct ieee80211_rate mwl8k_rates_50[] = {
272 { .bitrate = 60, .hw_value = 12, },
273 { .bitrate = 90, .hw_value = 18, },
274 { .bitrate = 120, .hw_value = 24, },
275 { .bitrate = 180, .hw_value = 36, },
276 { .bitrate = 240, .hw_value = 48, },
277 { .bitrate = 360, .hw_value = 72, },
278 { .bitrate = 480, .hw_value = 96, },
279 { .bitrate = 540, .hw_value = 108, },
280 { .bitrate = 720, .hw_value = 144, },
266}; 281};
267 282
268/* Set or get info from Firmware */ 283/* Set or get info from Firmware */
@@ -278,6 +293,7 @@ static const u8 mwl8k_rateids[12] = {
278#define MWL8K_CMD_RADIO_CONTROL 0x001c 293#define MWL8K_CMD_RADIO_CONTROL 0x001c
279#define MWL8K_CMD_RF_TX_POWER 0x001e 294#define MWL8K_CMD_RF_TX_POWER 0x001e
280#define MWL8K_CMD_RF_ANTENNA 0x0020 295#define MWL8K_CMD_RF_ANTENNA 0x0020
296#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
281#define MWL8K_CMD_SET_PRE_SCAN 0x0107 297#define MWL8K_CMD_SET_PRE_SCAN 0x0107
282#define MWL8K_CMD_SET_POST_SCAN 0x0108 298#define MWL8K_CMD_SET_POST_SCAN 0x0108
283#define MWL8K_CMD_SET_RF_CHANNEL 0x010a 299#define MWL8K_CMD_SET_RF_CHANNEL 0x010a
@@ -291,8 +307,10 @@ static const u8 mwl8k_rateids[12] = {
291#define MWL8K_CMD_MIMO_CONFIG 0x0125 307#define MWL8K_CMD_MIMO_CONFIG 0x0125
292#define MWL8K_CMD_USE_FIXED_RATE 0x0126 308#define MWL8K_CMD_USE_FIXED_RATE 0x0126
293#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 309#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
294#define MWL8K_CMD_SET_MAC_ADDR 0x0202 310#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
295#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 311#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
312#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
313#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
296#define MWL8K_CMD_UPDATE_STADB 0x1123 314#define MWL8K_CMD_UPDATE_STADB 0x1123
297 315
298static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) 316static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
@@ -310,6 +328,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
310 MWL8K_CMDNAME(RADIO_CONTROL); 328 MWL8K_CMDNAME(RADIO_CONTROL);
311 MWL8K_CMDNAME(RF_TX_POWER); 329 MWL8K_CMDNAME(RF_TX_POWER);
312 MWL8K_CMDNAME(RF_ANTENNA); 330 MWL8K_CMDNAME(RF_ANTENNA);
331 MWL8K_CMDNAME(SET_BEACON);
313 MWL8K_CMDNAME(SET_PRE_SCAN); 332 MWL8K_CMDNAME(SET_PRE_SCAN);
314 MWL8K_CMDNAME(SET_POST_SCAN); 333 MWL8K_CMDNAME(SET_POST_SCAN);
315 MWL8K_CMDNAME(SET_RF_CHANNEL); 334 MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -325,6 +344,8 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
325 MWL8K_CMDNAME(ENABLE_SNIFFER); 344 MWL8K_CMDNAME(ENABLE_SNIFFER);
326 MWL8K_CMDNAME(SET_MAC_ADDR); 345 MWL8K_CMDNAME(SET_MAC_ADDR);
327 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 346 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
347 MWL8K_CMDNAME(BSS_START);
348 MWL8K_CMDNAME(SET_NEW_STN);
328 MWL8K_CMDNAME(UPDATE_STADB); 349 MWL8K_CMDNAME(UPDATE_STADB);
329 default: 350 default:
330 snprintf(buf, bufsize, "0x%x", cmd); 351 snprintf(buf, bufsize, "0x%x", cmd);
@@ -355,8 +376,8 @@ static void mwl8k_release_fw(struct firmware **fw)
355 376
356static void mwl8k_release_firmware(struct mwl8k_priv *priv) 377static void mwl8k_release_firmware(struct mwl8k_priv *priv)
357{ 378{
358 mwl8k_release_fw(&priv->fw.ucode); 379 mwl8k_release_fw(&priv->fw_ucode);
359 mwl8k_release_fw(&priv->fw.helper); 380 mwl8k_release_fw(&priv->fw_helper);
360} 381}
361 382
362/* Request fw image */ 383/* Request fw image */
@@ -377,7 +398,7 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv)
377 int rc; 398 int rc;
378 399
379 if (di->helper_image != NULL) { 400 if (di->helper_image != NULL) {
380 rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw.helper); 401 rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper);
381 if (rc) { 402 if (rc) {
382 printk(KERN_ERR "%s: Error requesting helper " 403 printk(KERN_ERR "%s: Error requesting helper "
383 "firmware file %s\n", pci_name(priv->pdev), 404 "firmware file %s\n", pci_name(priv->pdev),
@@ -386,24 +407,22 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv)
386 } 407 }
387 } 408 }
388 409
389 rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw.ucode); 410 rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode);
390 if (rc) { 411 if (rc) {
391 printk(KERN_ERR "%s: Error requesting firmware file %s\n", 412 printk(KERN_ERR "%s: Error requesting firmware file %s\n",
392 pci_name(priv->pdev), di->fw_image); 413 pci_name(priv->pdev), di->fw_image);
393 mwl8k_release_fw(&priv->fw.helper); 414 mwl8k_release_fw(&priv->fw_helper);
394 return rc; 415 return rc;
395 } 416 }
396 417
397 return 0; 418 return 0;
398} 419}
399 420
400MODULE_FIRMWARE("mwl8k/helper_8687.fw");
401MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
402
403struct mwl8k_cmd_pkt { 421struct mwl8k_cmd_pkt {
404 __le16 code; 422 __le16 code;
405 __le16 length; 423 __le16 length;
406 __le16 seq_num; 424 __u8 seq_num;
425 __u8 macid;
407 __le16 result; 426 __le16 result;
408 char payload[0]; 427 char payload[0];
409} __attribute__((packed)); 428} __attribute__((packed));
@@ -461,6 +480,7 @@ static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
461 480
462 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); 481 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
463 cmd->seq_num = 0; 482 cmd->seq_num = 0;
483 cmd->macid = 0;
464 cmd->result = 0; 484 cmd->result = 0;
465 485
466 done = 0; 486 done = 0;
@@ -551,13 +571,12 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
551static int mwl8k_load_firmware(struct ieee80211_hw *hw) 571static int mwl8k_load_firmware(struct ieee80211_hw *hw)
552{ 572{
553 struct mwl8k_priv *priv = hw->priv; 573 struct mwl8k_priv *priv = hw->priv;
554 struct firmware *fw = priv->fw.ucode; 574 struct firmware *fw = priv->fw_ucode;
555 struct mwl8k_device_info *di = priv->device_info;
556 int rc; 575 int rc;
557 int loops; 576 int loops;
558 577
559 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) { 578 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
560 struct firmware *helper = priv->fw.helper; 579 struct firmware *helper = priv->fw_helper;
561 580
562 if (helper == NULL) { 581 if (helper == NULL) {
563 printk(KERN_ERR "%s: helper image needed but none " 582 printk(KERN_ERR "%s: helper image needed but none "
@@ -584,10 +603,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
584 return rc; 603 return rc;
585 } 604 }
586 605
587 if (di->modes & BIT(NL80211_IFTYPE_AP)) 606 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
588 iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
589 else
590 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
591 607
592 loops = 500000; 608 loops = 500000;
593 do { 609 do {
@@ -610,91 +626,6 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
610} 626}
611 627
612 628
613/*
614 * Defines shared between transmission and reception.
615 */
616/* HT control fields for firmware */
617struct ewc_ht_info {
618 __le16 control1;
619 __le16 control2;
620 __le16 control3;
621} __attribute__((packed));
622
623/* Firmware Station database operations */
624#define MWL8K_STA_DB_ADD_ENTRY 0
625#define MWL8K_STA_DB_MODIFY_ENTRY 1
626#define MWL8K_STA_DB_DEL_ENTRY 2
627#define MWL8K_STA_DB_FLUSH 3
628
629/* Peer Entry flags - used to define the type of the peer node */
630#define MWL8K_PEER_TYPE_ACCESSPOINT 2
631
632struct peer_capability_info {
633 /* Peer type - AP vs. STA. */
634 __u8 peer_type;
635
636 /* Basic 802.11 capabilities from assoc resp. */
637 __le16 basic_caps;
638
639 /* Set if peer supports 802.11n high throughput (HT). */
640 __u8 ht_support;
641
642 /* Valid if HT is supported. */
643 __le16 ht_caps;
644 __u8 extended_ht_caps;
645 struct ewc_ht_info ewc_info;
646
647 /* Legacy rate table. Intersection of our rates and peer rates. */
648 __u8 legacy_rates[12];
649
650 /* HT rate table. Intersection of our rates and peer rates. */
651 __u8 ht_rates[16];
652 __u8 pad[16];
653
654 /* If set, interoperability mode, no proprietary extensions. */
655 __u8 interop;
656 __u8 pad2;
657 __u8 station_id;
658 __le16 amsdu_enabled;
659} __attribute__((packed));
660
661/* Inline functions to manipulate QoS field in data descriptor. */
662static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
663{
664 u16 val_mask = 1 << 4;
665
666 /* End of Service Period Bit 4 */
667 return qos | val_mask;
668}
669
670static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy)
671{
672 u16 val_mask = 0x3;
673 u8 shift = 5;
674 u16 qos_mask = ~(val_mask << shift);
675
676 /* Ack Policy Bit 5-6 */
677 return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
678}
679
680static inline u16 mwl8k_qos_setbit_amsdu(u16 qos)
681{
682 u16 val_mask = 1 << 7;
683
684 /* AMSDU present Bit 7 */
685 return qos | val_mask;
686}
687
688static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len)
689{
690 u16 val_mask = 0xff;
691 u8 shift = 8;
692 u16 qos_mask = ~(val_mask << shift);
693
694 /* Queue Length Bits 8-15 */
695 return (qos & qos_mask) | ((len & val_mask) << shift);
696}
697
698/* DMA header used by firmware and hardware. */ 629/* DMA header used by firmware and hardware. */
699struct mwl8k_dma_data { 630struct mwl8k_dma_data {
700 __le16 fwlen; 631 __le16 fwlen;
@@ -761,9 +692,9 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb)
761 692
762 693
763/* 694/*
764 * Packet reception for 88w8366. 695 * Packet reception for 88w8366 AP firmware.
765 */ 696 */
766struct mwl8k_rxd_8366 { 697struct mwl8k_rxd_8366_ap {
767 __le16 pkt_len; 698 __le16 pkt_len;
768 __u8 sq2; 699 __u8 sq2;
769 __u8 rate; 700 __u8 rate;
@@ -781,23 +712,23 @@ struct mwl8k_rxd_8366 {
781 __u8 rx_ctrl; 712 __u8 rx_ctrl;
782} __attribute__((packed)); 713} __attribute__((packed));
783 714
784#define MWL8K_8366_RATE_INFO_MCS_FORMAT 0x80 715#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80
785#define MWL8K_8366_RATE_INFO_40MHZ 0x40 716#define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40
786#define MWL8K_8366_RATE_INFO_RATEID(x) ((x) & 0x3f) 717#define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f)
787 718
788#define MWL8K_8366_RX_CTRL_OWNED_BY_HOST 0x80 719#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80
789 720
790static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr) 721static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
791{ 722{
792 struct mwl8k_rxd_8366 *rxd = _rxd; 723 struct mwl8k_rxd_8366_ap *rxd = _rxd;
793 724
794 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); 725 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
795 rxd->rx_ctrl = MWL8K_8366_RX_CTRL_OWNED_BY_HOST; 726 rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST;
796} 727}
797 728
798static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len) 729static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
799{ 730{
800 struct mwl8k_rxd_8366 *rxd = _rxd; 731 struct mwl8k_rxd_8366_ap *rxd = _rxd;
801 732
802 rxd->pkt_len = cpu_to_le16(len); 733 rxd->pkt_len = cpu_to_le16(len);
803 rxd->pkt_phys_addr = cpu_to_le32(addr); 734 rxd->pkt_phys_addr = cpu_to_le32(addr);
@@ -806,12 +737,12 @@ static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len)
806} 737}
807 738
808static int 739static int
809mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status, 740mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
810 __le16 *qos) 741 __le16 *qos)
811{ 742{
812 struct mwl8k_rxd_8366 *rxd = _rxd; 743 struct mwl8k_rxd_8366_ap *rxd = _rxd;
813 744
814 if (!(rxd->rx_ctrl & MWL8K_8366_RX_CTRL_OWNED_BY_HOST)) 745 if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST))
815 return -1; 746 return -1;
816 rmb(); 747 rmb();
817 748
@@ -820,23 +751,29 @@ mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status,
820 status->signal = -rxd->rssi; 751 status->signal = -rxd->rssi;
821 status->noise = -rxd->noise_floor; 752 status->noise = -rxd->noise_floor;
822 753
823 if (rxd->rate & MWL8K_8366_RATE_INFO_MCS_FORMAT) { 754 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
824 status->flag |= RX_FLAG_HT; 755 status->flag |= RX_FLAG_HT;
825 if (rxd->rate & MWL8K_8366_RATE_INFO_40MHZ) 756 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ)
826 status->flag |= RX_FLAG_40MHZ; 757 status->flag |= RX_FLAG_40MHZ;
827 status->rate_idx = MWL8K_8366_RATE_INFO_RATEID(rxd->rate); 758 status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate);
828 } else { 759 } else {
829 int i; 760 int i;
830 761
831 for (i = 0; i < ARRAY_SIZE(mwl8k_rates); i++) { 762 for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
832 if (mwl8k_rates[i].hw_value == rxd->rate) { 763 if (mwl8k_rates_24[i].hw_value == rxd->rate) {
833 status->rate_idx = i; 764 status->rate_idx = i;
834 break; 765 break;
835 } 766 }
836 } 767 }
837 } 768 }
838 769
839 status->band = IEEE80211_BAND_2GHZ; 770 if (rxd->channel > 14) {
771 status->band = IEEE80211_BAND_5GHZ;
772 if (!(status->flag & RX_FLAG_HT))
773 status->rate_idx -= 5;
774 } else {
775 status->band = IEEE80211_BAND_2GHZ;
776 }
840 status->freq = ieee80211_channel_to_frequency(rxd->channel); 777 status->freq = ieee80211_channel_to_frequency(rxd->channel);
841 778
842 *qos = rxd->qos_control; 779 *qos = rxd->qos_control;
@@ -844,17 +781,17 @@ mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status,
844 return le16_to_cpu(rxd->pkt_len); 781 return le16_to_cpu(rxd->pkt_len);
845} 782}
846 783
847static struct rxd_ops rxd_8366_ops = { 784static struct rxd_ops rxd_8366_ap_ops = {
848 .rxd_size = sizeof(struct mwl8k_rxd_8366), 785 .rxd_size = sizeof(struct mwl8k_rxd_8366_ap),
849 .rxd_init = mwl8k_rxd_8366_init, 786 .rxd_init = mwl8k_rxd_8366_ap_init,
850 .rxd_refill = mwl8k_rxd_8366_refill, 787 .rxd_refill = mwl8k_rxd_8366_ap_refill,
851 .rxd_process = mwl8k_rxd_8366_process, 788 .rxd_process = mwl8k_rxd_8366_ap_process,
852}; 789};
853 790
854/* 791/*
855 * Packet reception for 88w8687. 792 * Packet reception for STA firmware.
856 */ 793 */
857struct mwl8k_rxd_8687 { 794struct mwl8k_rxd_sta {
858 __le16 pkt_len; 795 __le16 pkt_len;
859 __u8 link_quality; 796 __u8 link_quality;
860 __u8 noise_level; 797 __u8 noise_level;
@@ -871,26 +808,26 @@ struct mwl8k_rxd_8687 {
871 __u8 pad2[2]; 808 __u8 pad2[2];
872} __attribute__((packed)); 809} __attribute__((packed));
873 810
874#define MWL8K_8687_RATE_INFO_SHORTPRE 0x8000 811#define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000
875#define MWL8K_8687_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3) 812#define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3)
876#define MWL8K_8687_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f) 813#define MWL8K_STA_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f)
877#define MWL8K_8687_RATE_INFO_40MHZ 0x0004 814#define MWL8K_STA_RATE_INFO_40MHZ 0x0004
878#define MWL8K_8687_RATE_INFO_SHORTGI 0x0002 815#define MWL8K_STA_RATE_INFO_SHORTGI 0x0002
879#define MWL8K_8687_RATE_INFO_MCS_FORMAT 0x0001 816#define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001
880 817
881#define MWL8K_8687_RX_CTRL_OWNED_BY_HOST 0x02 818#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02
882 819
883static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr) 820static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
884{ 821{
885 struct mwl8k_rxd_8687 *rxd = _rxd; 822 struct mwl8k_rxd_sta *rxd = _rxd;
886 823
887 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); 824 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
888 rxd->rx_ctrl = MWL8K_8687_RX_CTRL_OWNED_BY_HOST; 825 rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
889} 826}
890 827
891static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len) 828static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
892{ 829{
893 struct mwl8k_rxd_8687 *rxd = _rxd; 830 struct mwl8k_rxd_sta *rxd = _rxd;
894 831
895 rxd->pkt_len = cpu_to_le16(len); 832 rxd->pkt_len = cpu_to_le16(len);
896 rxd->pkt_phys_addr = cpu_to_le32(addr); 833 rxd->pkt_phys_addr = cpu_to_le32(addr);
@@ -899,13 +836,13 @@ static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len)
899} 836}
900 837
901static int 838static int
902mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status, 839mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
903 __le16 *qos) 840 __le16 *qos)
904{ 841{
905 struct mwl8k_rxd_8687 *rxd = _rxd; 842 struct mwl8k_rxd_sta *rxd = _rxd;
906 u16 rate_info; 843 u16 rate_info;
907 844
908 if (!(rxd->rx_ctrl & MWL8K_8687_RX_CTRL_OWNED_BY_HOST)) 845 if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
909 return -1; 846 return -1;
910 rmb(); 847 rmb();
911 848
@@ -915,19 +852,25 @@ mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status,
915 852
916 status->signal = -rxd->rssi; 853 status->signal = -rxd->rssi;
917 status->noise = -rxd->noise_level; 854 status->noise = -rxd->noise_level;
918 status->antenna = MWL8K_8687_RATE_INFO_ANTSELECT(rate_info); 855 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
919 status->rate_idx = MWL8K_8687_RATE_INFO_RATEID(rate_info); 856 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
920 857
921 if (rate_info & MWL8K_8687_RATE_INFO_SHORTPRE) 858 if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
922 status->flag |= RX_FLAG_SHORTPRE; 859 status->flag |= RX_FLAG_SHORTPRE;
923 if (rate_info & MWL8K_8687_RATE_INFO_40MHZ) 860 if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
924 status->flag |= RX_FLAG_40MHZ; 861 status->flag |= RX_FLAG_40MHZ;
925 if (rate_info & MWL8K_8687_RATE_INFO_SHORTGI) 862 if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
926 status->flag |= RX_FLAG_SHORT_GI; 863 status->flag |= RX_FLAG_SHORT_GI;
927 if (rate_info & MWL8K_8687_RATE_INFO_MCS_FORMAT) 864 if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
928 status->flag |= RX_FLAG_HT; 865 status->flag |= RX_FLAG_HT;
929 866
930 status->band = IEEE80211_BAND_2GHZ; 867 if (rxd->channel > 14) {
868 status->band = IEEE80211_BAND_5GHZ;
869 if (!(status->flag & RX_FLAG_HT))
870 status->rate_idx -= 5;
871 } else {
872 status->band = IEEE80211_BAND_2GHZ;
873 }
931 status->freq = ieee80211_channel_to_frequency(rxd->channel); 874 status->freq = ieee80211_channel_to_frequency(rxd->channel);
932 875
933 *qos = rxd->qos_control; 876 *qos = rxd->qos_control;
@@ -935,11 +878,11 @@ mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status,
935 return le16_to_cpu(rxd->pkt_len); 878 return le16_to_cpu(rxd->pkt_len);
936} 879}
937 880
938static struct rxd_ops rxd_8687_ops = { 881static struct rxd_ops rxd_sta_ops = {
939 .rxd_size = sizeof(struct mwl8k_rxd_8687), 882 .rxd_size = sizeof(struct mwl8k_rxd_sta),
940 .rxd_init = mwl8k_rxd_8687_init, 883 .rxd_init = mwl8k_rxd_sta_init,
941 .rxd_refill = mwl8k_rxd_8687_refill, 884 .rxd_refill = mwl8k_rxd_sta_refill,
942 .rxd_process = mwl8k_rxd_8687_process, 885 .rxd_process = mwl8k_rxd_sta_process,
943}; 886};
944 887
945 888
@@ -1153,16 +1096,18 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
1153 * Packet transmission. 1096 * Packet transmission.
1154 */ 1097 */
1155 1098
1156/* Transmit packet ACK policy */
1157#define MWL8K_TXD_ACK_POLICY_NORMAL 0
1158#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
1159
1160#define MWL8K_TXD_STATUS_OK 0x00000001 1099#define MWL8K_TXD_STATUS_OK 0x00000001
1161#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002 1100#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
1162#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004 1101#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
1163#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008 1102#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
1164#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000 1103#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
1165 1104
1105#define MWL8K_QOS_QLEN_UNSPEC 0xff00
1106#define MWL8K_QOS_ACK_POLICY_MASK 0x0060
1107#define MWL8K_QOS_ACK_POLICY_NORMAL 0x0000
1108#define MWL8K_QOS_ACK_POLICY_BLOCKACK 0x0060
1109#define MWL8K_QOS_EOSP 0x0010
1110
1166struct mwl8k_tx_desc { 1111struct mwl8k_tx_desc {
1167 __le32 status; 1112 __le32 status;
1168 __u8 data_rate; 1113 __u8 data_rate;
@@ -1187,8 +1132,7 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1187 int size; 1132 int size;
1188 int i; 1133 int i;
1189 1134
1190 memset(&txq->stats, 0, sizeof(struct ieee80211_tx_queue_stats)); 1135 txq->len = 0;
1191 txq->stats.limit = MWL8K_TX_DESCS;
1192 txq->head = 0; 1136 txq->head = 0;
1193 txq->tail = 0; 1137 txq->tail = 0;
1194 1138
@@ -1264,7 +1208,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1264 printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d " 1208 printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
1265 "fw_owned=%d drv_owned=%d unused=%d\n", 1209 "fw_owned=%d drv_owned=%d unused=%d\n",
1266 wiphy_name(hw->wiphy), i, 1210 wiphy_name(hw->wiphy), i,
1267 txq->stats.len, txq->head, txq->tail, 1211 txq->len, txq->head, txq->tail,
1268 fw_owned, drv_owned, unused); 1212 fw_owned, drv_owned, unused);
1269 } 1213 }
1270} 1214}
@@ -1272,7 +1216,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1272/* 1216/*
1273 * Must be called with priv->fw_mutex held and tx queues stopped. 1217 * Must be called with priv->fw_mutex held and tx queues stopped.
1274 */ 1218 */
1275#define MWL8K_TX_WAIT_TIMEOUT_MS 1000 1219#define MWL8K_TX_WAIT_TIMEOUT_MS 5000
1276 1220
1277static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) 1221static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1278{ 1222{
@@ -1316,8 +1260,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1316 } 1260 }
1317 1261
1318 if (priv->pending_tx_pkts < oldcount) { 1262 if (priv->pending_tx_pkts < oldcount) {
1319 printk(KERN_NOTICE "%s: timeout waiting for tx " 1263 printk(KERN_NOTICE "%s: waiting for tx rings "
1320 "rings to drain (%d -> %d pkts), retrying\n", 1264 "to drain (%d -> %d pkts)\n",
1321 wiphy_name(hw->wiphy), oldcount, 1265 wiphy_name(hw->wiphy), oldcount,
1322 priv->pending_tx_pkts); 1266 priv->pending_tx_pkts);
1323 retry = 1; 1267 retry = 1;
@@ -1342,13 +1286,15 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1342 MWL8K_TXD_STATUS_OK_RETRY | \ 1286 MWL8K_TXD_STATUS_OK_RETRY | \
1343 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1287 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1344 1288
1345static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force) 1289static int
1290mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1346{ 1291{
1347 struct mwl8k_priv *priv = hw->priv; 1292 struct mwl8k_priv *priv = hw->priv;
1348 struct mwl8k_tx_queue *txq = priv->txq + index; 1293 struct mwl8k_tx_queue *txq = priv->txq + index;
1349 int wake = 0; 1294 int processed;
1350 1295
1351 while (txq->stats.len > 0) { 1296 processed = 0;
1297 while (txq->len > 0 && limit--) {
1352 int tx; 1298 int tx;
1353 struct mwl8k_tx_desc *tx_desc; 1299 struct mwl8k_tx_desc *tx_desc;
1354 unsigned long addr; 1300 unsigned long addr;
@@ -1370,8 +1316,8 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1370 } 1316 }
1371 1317
1372 txq->head = (tx + 1) % MWL8K_TX_DESCS; 1318 txq->head = (tx + 1) % MWL8K_TX_DESCS;
1373 BUG_ON(txq->stats.len == 0); 1319 BUG_ON(txq->len == 0);
1374 txq->stats.len--; 1320 txq->len--;
1375 priv->pending_tx_pkts--; 1321 priv->pending_tx_pkts--;
1376 1322
1377 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1323 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
@@ -1395,11 +1341,13 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1395 1341
1396 ieee80211_tx_status_irqsafe(hw, skb); 1342 ieee80211_tx_status_irqsafe(hw, skb);
1397 1343
1398 wake = 1; 1344 processed++;
1399 } 1345 }
1400 1346
1401 if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1347 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
1402 ieee80211_wake_queue(hw, index); 1348 ieee80211_wake_queue(hw, index);
1349
1350 return processed;
1403} 1351}
1404 1352
1405/* must be called only when the card's transmit is completely halted */ 1353/* must be called only when the card's transmit is completely halted */
@@ -1408,7 +1356,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1408 struct mwl8k_priv *priv = hw->priv; 1356 struct mwl8k_priv *priv = hw->priv;
1409 struct mwl8k_tx_queue *txq = priv->txq + index; 1357 struct mwl8k_tx_queue *txq = priv->txq + index;
1410 1358
1411 mwl8k_txq_reclaim(hw, index, 1); 1359 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1412 1360
1413 kfree(txq->skb); 1361 kfree(txq->skb);
1414 txq->skb = NULL; 1362 txq->skb = NULL;
@@ -1446,11 +1394,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1446 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1394 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1447 1395
1448 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1396 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1449 u16 seqno = mwl8k_vif->seqno;
1450
1451 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1397 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1452 wh->seq_ctrl |= cpu_to_le16(seqno << 4); 1398 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
1453 mwl8k_vif->seqno = seqno++ % 4096; 1399 mwl8k_vif->seqno += 0x10;
1454 } 1400 }
1455 1401
1456 /* Setup firmware control bit fields for each frame type. */ 1402 /* Setup firmware control bit fields for each frame type. */
@@ -1459,24 +1405,17 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1459 if (ieee80211_is_mgmt(wh->frame_control) || 1405 if (ieee80211_is_mgmt(wh->frame_control) ||
1460 ieee80211_is_ctl(wh->frame_control)) { 1406 ieee80211_is_ctl(wh->frame_control)) {
1461 txdatarate = 0; 1407 txdatarate = 0;
1462 qos = mwl8k_qos_setbit_eosp(qos); 1408 qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP;
1463 /* Set Queue size to unspecified */
1464 qos = mwl8k_qos_setbit_qlen(qos, 0xff);
1465 } else if (ieee80211_is_data(wh->frame_control)) { 1409 } else if (ieee80211_is_data(wh->frame_control)) {
1466 txdatarate = 1; 1410 txdatarate = 1;
1467 if (is_multicast_ether_addr(wh->addr1)) 1411 if (is_multicast_ether_addr(wh->addr1))
1468 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX; 1412 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
1469 1413
1470 /* Send pkt in an aggregate if AMPDU frame. */ 1414 qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
1471 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) 1415 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
1472 qos = mwl8k_qos_setbit_ack(qos, 1416 qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK;
1473 MWL8K_TXD_ACK_POLICY_BLOCKACK);
1474 else 1417 else
1475 qos = mwl8k_qos_setbit_ack(qos, 1418 qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
1476 MWL8K_TXD_ACK_POLICY_NORMAL);
1477
1478 if (qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
1479 qos = mwl8k_qos_setbit_amsdu(qos);
1480 } 1419 }
1481 1420
1482 dma = pci_map_single(priv->pdev, skb->data, 1421 dma = pci_map_single(priv->pdev, skb->data,
@@ -1503,12 +1442,14 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1503 tx->pkt_phys_addr = cpu_to_le32(dma); 1442 tx->pkt_phys_addr = cpu_to_le32(dma);
1504 tx->pkt_len = cpu_to_le16(skb->len); 1443 tx->pkt_len = cpu_to_le16(skb->len);
1505 tx->rate_info = 0; 1444 tx->rate_info = 0;
1506 tx->peer_id = mwl8k_vif->peer_id; 1445 if (!priv->ap_fw && tx_info->control.sta != NULL)
1446 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1447 else
1448 tx->peer_id = 0;
1507 wmb(); 1449 wmb();
1508 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1450 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1509 1451
1510 txq->stats.count++; 1452 txq->len++;
1511 txq->stats.len++;
1512 priv->pending_tx_pkts++; 1453 priv->pending_tx_pkts++;
1513 1454
1514 txq->tail++; 1455 txq->tail++;
@@ -1656,6 +1597,56 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1656 return rc; 1597 return rc;
1657} 1598}
1658 1599
1600static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
1601 struct ieee80211_vif *vif,
1602 struct mwl8k_cmd_pkt *cmd)
1603{
1604 if (vif != NULL)
1605 cmd->macid = MWL8K_VIF(vif)->macid;
1606 return mwl8k_post_cmd(hw, cmd);
1607}
1608
1609/*
1610 * Setup code shared between STA and AP firmware images.
1611 */
1612static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
1613{
1614 struct mwl8k_priv *priv = hw->priv;
1615
1616 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
1617 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
1618
1619 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
1620 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
1621
1622 priv->band_24.band = IEEE80211_BAND_2GHZ;
1623 priv->band_24.channels = priv->channels_24;
1624 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
1625 priv->band_24.bitrates = priv->rates_24;
1626 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
1627
1628 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
1629}
1630
1631static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
1632{
1633 struct mwl8k_priv *priv = hw->priv;
1634
1635 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
1636 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
1637
1638 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
1639 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
1640
1641 priv->band_50.band = IEEE80211_BAND_5GHZ;
1642 priv->band_50.channels = priv->channels_50;
1643 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
1644 priv->band_50.bitrates = priv->rates_50;
1645 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
1646
1647 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
1648}
1649
1659/* 1650/*
1660 * CMD_GET_HW_SPEC (STA version). 1651 * CMD_GET_HW_SPEC (STA version).
1661 */ 1652 */
@@ -1678,6 +1669,89 @@ struct mwl8k_cmd_get_hw_spec_sta {
1678 __le32 total_rxd; 1669 __le32 total_rxd;
1679} __attribute__((packed)); 1670} __attribute__((packed));
1680 1671
1672#define MWL8K_CAP_MAX_AMSDU 0x20000000
1673#define MWL8K_CAP_GREENFIELD 0x08000000
1674#define MWL8K_CAP_AMPDU 0x04000000
1675#define MWL8K_CAP_RX_STBC 0x01000000
1676#define MWL8K_CAP_TX_STBC 0x00800000
1677#define MWL8K_CAP_SHORTGI_40MHZ 0x00400000
1678#define MWL8K_CAP_SHORTGI_20MHZ 0x00200000
1679#define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000
1680#define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000
1681#define MWL8K_CAP_DELAY_BA 0x00003000
1682#define MWL8K_CAP_MIMO 0x00000200
1683#define MWL8K_CAP_40MHZ 0x00000100
1684#define MWL8K_CAP_BAND_MASK 0x00000007
1685#define MWL8K_CAP_5GHZ 0x00000004
1686#define MWL8K_CAP_2GHZ4 0x00000001
1687
1688static void
1689mwl8k_set_ht_caps(struct ieee80211_hw *hw,
1690 struct ieee80211_supported_band *band, u32 cap)
1691{
1692 int rx_streams;
1693 int tx_streams;
1694
1695 band->ht_cap.ht_supported = 1;
1696
1697 if (cap & MWL8K_CAP_MAX_AMSDU)
1698 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
1699 if (cap & MWL8K_CAP_GREENFIELD)
1700 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
1701 if (cap & MWL8K_CAP_AMPDU) {
1702 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
1703 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1704 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1705 }
1706 if (cap & MWL8K_CAP_RX_STBC)
1707 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
1708 if (cap & MWL8K_CAP_TX_STBC)
1709 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
1710 if (cap & MWL8K_CAP_SHORTGI_40MHZ)
1711 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
1712 if (cap & MWL8K_CAP_SHORTGI_20MHZ)
1713 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
1714 if (cap & MWL8K_CAP_DELAY_BA)
1715 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
1716 if (cap & MWL8K_CAP_40MHZ)
1717 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1718
1719 rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
1720 tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
1721
1722 band->ht_cap.mcs.rx_mask[0] = 0xff;
1723 if (rx_streams >= 2)
1724 band->ht_cap.mcs.rx_mask[1] = 0xff;
1725 if (rx_streams >= 3)
1726 band->ht_cap.mcs.rx_mask[2] = 0xff;
1727 band->ht_cap.mcs.rx_mask[4] = 0x01;
1728 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1729
1730 if (rx_streams != tx_streams) {
1731 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
1732 band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
1733 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1734 }
1735}
1736
1737static void
1738mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
1739{
1740 struct mwl8k_priv *priv = hw->priv;
1741
1742 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
1743 mwl8k_setup_2ghz_band(hw);
1744 if (caps & MWL8K_CAP_MIMO)
1745 mwl8k_set_ht_caps(hw, &priv->band_24, caps);
1746 }
1747
1748 if (caps & MWL8K_CAP_5GHZ) {
1749 mwl8k_setup_5ghz_band(hw);
1750 if (caps & MWL8K_CAP_MIMO)
1751 mwl8k_set_ht_caps(hw, &priv->band_50, caps);
1752 }
1753}
1754
1681static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) 1755static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1682{ 1756{
1683 struct mwl8k_priv *priv = hw->priv; 1757 struct mwl8k_priv *priv = hw->priv;
@@ -1708,6 +1782,9 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1708 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1782 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1709 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1783 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1710 priv->hw_rev = cmd->hw_rev; 1784 priv->hw_rev = cmd->hw_rev;
1785 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
1786 priv->ap_macids_supported = 0x00000000;
1787 priv->sta_macids_supported = 0x00000001;
1711 } 1788 }
1712 1789
1713 kfree(cmd); 1790 kfree(cmd);
@@ -1761,6 +1838,9 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1761 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1838 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1762 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1839 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1763 priv->hw_rev = cmd->hw_rev; 1840 priv->hw_rev = cmd->hw_rev;
1841 mwl8k_setup_2ghz_band(hw);
1842 priv->ap_macids_supported = 0x000000ff;
1843 priv->sta_macids_supported = 0x00000000;
1764 1844
1765 off = le32_to_cpu(cmd->wcbbase0) & 0xffff; 1845 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1766 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off); 1846 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
@@ -1806,7 +1886,9 @@ struct mwl8k_cmd_set_hw_spec {
1806 __le32 total_rxd; 1886 __le32 total_rxd;
1807} __attribute__((packed)); 1887} __attribute__((packed));
1808 1888
1809#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 1889#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
1890#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
1891#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
1810 1892
1811static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) 1893static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1812{ 1894{
@@ -1827,7 +1909,9 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1827 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1909 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1828 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1910 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1829 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 1911 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1830 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT); 1912 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
1913 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
1914 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
1831 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 1915 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1832 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 1916 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1833 1917
@@ -1897,9 +1981,9 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1897} 1981}
1898 1982
1899/* 1983/*
1900 * CMD_802_11_GET_STAT. 1984 * CMD_GET_STAT.
1901 */ 1985 */
1902struct mwl8k_cmd_802_11_get_stat { 1986struct mwl8k_cmd_get_stat {
1903 struct mwl8k_cmd_pkt header; 1987 struct mwl8k_cmd_pkt header;
1904 __le32 stats[64]; 1988 __le32 stats[64];
1905} __attribute__((packed)); 1989} __attribute__((packed));
@@ -1909,10 +1993,10 @@ struct mwl8k_cmd_802_11_get_stat {
1909#define MWL8K_STAT_FCS_ERROR 24 1993#define MWL8K_STAT_FCS_ERROR 24
1910#define MWL8K_STAT_RTS_SUCCESS 11 1994#define MWL8K_STAT_RTS_SUCCESS 11
1911 1995
1912static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw, 1996static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw,
1913 struct ieee80211_low_level_stats *stats) 1997 struct ieee80211_low_level_stats *stats)
1914{ 1998{
1915 struct mwl8k_cmd_802_11_get_stat *cmd; 1999 struct mwl8k_cmd_get_stat *cmd;
1916 int rc; 2000 int rc;
1917 2001
1918 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2002 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1939,9 +2023,9 @@ static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
1939} 2023}
1940 2024
1941/* 2025/*
1942 * CMD_802_11_RADIO_CONTROL. 2026 * CMD_RADIO_CONTROL.
1943 */ 2027 */
1944struct mwl8k_cmd_802_11_radio_control { 2028struct mwl8k_cmd_radio_control {
1945 struct mwl8k_cmd_pkt header; 2029 struct mwl8k_cmd_pkt header;
1946 __le16 action; 2030 __le16 action;
1947 __le16 control; 2031 __le16 control;
@@ -1949,10 +2033,10 @@ struct mwl8k_cmd_802_11_radio_control {
1949} __attribute__((packed)); 2033} __attribute__((packed));
1950 2034
1951static int 2035static int
1952mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force) 2036mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1953{ 2037{
1954 struct mwl8k_priv *priv = hw->priv; 2038 struct mwl8k_priv *priv = hw->priv;
1955 struct mwl8k_cmd_802_11_radio_control *cmd; 2039 struct mwl8k_cmd_radio_control *cmd;
1956 int rc; 2040 int rc;
1957 2041
1958 if (enable == priv->radio_on && !force) 2042 if (enable == priv->radio_on && !force)
@@ -1977,36 +2061,32 @@ mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1977 return rc; 2061 return rc;
1978} 2062}
1979 2063
1980static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw) 2064static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw)
1981{ 2065{
1982 return mwl8k_cmd_802_11_radio_control(hw, 0, 0); 2066 return mwl8k_cmd_radio_control(hw, 0, 0);
1983} 2067}
1984 2068
1985static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw) 2069static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw)
1986{ 2070{
1987 return mwl8k_cmd_802_11_radio_control(hw, 1, 0); 2071 return mwl8k_cmd_radio_control(hw, 1, 0);
1988} 2072}
1989 2073
1990static int 2074static int
1991mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) 2075mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
1992{ 2076{
1993 struct mwl8k_priv *priv; 2077 struct mwl8k_priv *priv = hw->priv;
1994
1995 if (hw == NULL || hw->priv == NULL)
1996 return -EINVAL;
1997 priv = hw->priv;
1998 2078
1999 priv->radio_short_preamble = short_preamble; 2079 priv->radio_short_preamble = short_preamble;
2000 2080
2001 return mwl8k_cmd_802_11_radio_control(hw, 1, 1); 2081 return mwl8k_cmd_radio_control(hw, 1, 1);
2002} 2082}
2003 2083
2004/* 2084/*
2005 * CMD_802_11_RF_TX_POWER. 2085 * CMD_RF_TX_POWER.
2006 */ 2086 */
2007#define MWL8K_TX_POWER_LEVEL_TOTAL 8 2087#define MWL8K_TX_POWER_LEVEL_TOTAL 8
2008 2088
2009struct mwl8k_cmd_802_11_rf_tx_power { 2089struct mwl8k_cmd_rf_tx_power {
2010 struct mwl8k_cmd_pkt header; 2090 struct mwl8k_cmd_pkt header;
2011 __le16 action; 2091 __le16 action;
2012 __le16 support_level; 2092 __le16 support_level;
@@ -2015,9 +2095,9 @@ struct mwl8k_cmd_802_11_rf_tx_power {
2015 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; 2095 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
2016} __attribute__((packed)); 2096} __attribute__((packed));
2017 2097
2018static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm) 2098static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
2019{ 2099{
2020 struct mwl8k_cmd_802_11_rf_tx_power *cmd; 2100 struct mwl8k_cmd_rf_tx_power *cmd;
2021 int rc; 2101 int rc;
2022 2102
2023 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2103 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2069,6 +2149,36 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
2069} 2149}
2070 2150
2071/* 2151/*
2152 * CMD_SET_BEACON.
2153 */
2154struct mwl8k_cmd_set_beacon {
2155 struct mwl8k_cmd_pkt header;
2156 __le16 beacon_len;
2157 __u8 beacon[0];
2158};
2159
2160static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
2161 struct ieee80211_vif *vif, u8 *beacon, int len)
2162{
2163 struct mwl8k_cmd_set_beacon *cmd;
2164 int rc;
2165
2166 cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
2167 if (cmd == NULL)
2168 return -ENOMEM;
2169
2170 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
2171 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
2172 cmd->beacon_len = cpu_to_le16(len);
2173 memcpy(cmd->beacon, beacon, len);
2174
2175 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2176 kfree(cmd);
2177
2178 return rc;
2179}
2180
2181/*
2072 * CMD_SET_PRE_SCAN. 2182 * CMD_SET_PRE_SCAN.
2073 */ 2183 */
2074struct mwl8k_cmd_set_pre_scan { 2184struct mwl8k_cmd_set_pre_scan {
@@ -2103,7 +2213,7 @@ struct mwl8k_cmd_set_post_scan {
2103} __attribute__((packed)); 2213} __attribute__((packed));
2104 2214
2105static int 2215static int
2106mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac) 2216mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
2107{ 2217{
2108 struct mwl8k_cmd_set_post_scan *cmd; 2218 struct mwl8k_cmd_set_post_scan *cmd;
2109 int rc; 2219 int rc;
@@ -2134,8 +2244,9 @@ struct mwl8k_cmd_set_rf_channel {
2134} __attribute__((packed)); 2244} __attribute__((packed));
2135 2245
2136static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, 2246static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2137 struct ieee80211_channel *channel) 2247 struct ieee80211_conf *conf)
2138{ 2248{
2249 struct ieee80211_channel *channel = conf->channel;
2139 struct mwl8k_cmd_set_rf_channel *cmd; 2250 struct mwl8k_cmd_set_rf_channel *cmd;
2140 int rc; 2251 int rc;
2141 2252
@@ -2147,10 +2258,19 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2147 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2258 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2148 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2259 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2149 cmd->current_channel = channel->hw_value; 2260 cmd->current_channel = channel->hw_value;
2261
2150 if (channel->band == IEEE80211_BAND_2GHZ) 2262 if (channel->band == IEEE80211_BAND_2GHZ)
2151 cmd->channel_flags = cpu_to_le32(0x00000081); 2263 cmd->channel_flags |= cpu_to_le32(0x00000001);
2152 else 2264 else if (channel->band == IEEE80211_BAND_5GHZ)
2153 cmd->channel_flags = cpu_to_le32(0x00000000); 2265 cmd->channel_flags |= cpu_to_le32(0x00000004);
2266
2267 if (conf->channel_type == NL80211_CHAN_NO_HT ||
2268 conf->channel_type == NL80211_CHAN_HT20)
2269 cmd->channel_flags |= cpu_to_le32(0x00000080);
2270 else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
2271 cmd->channel_flags |= cpu_to_le32(0x000001900);
2272 else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
2273 cmd->channel_flags |= cpu_to_le32(0x000000900);
2154 2274
2155 rc = mwl8k_post_cmd(hw, &cmd->header); 2275 rc = mwl8k_post_cmd(hw, &cmd->header);
2156 kfree(cmd); 2276 kfree(cmd);
@@ -2159,85 +2279,75 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2159} 2279}
2160 2280
2161/* 2281/*
2162 * CMD_SET_SLOT. 2282 * CMD_SET_AID.
2163 */ 2283 */
2164struct mwl8k_cmd_set_slot { 2284#define MWL8K_FRAME_PROT_DISABLED 0x00
2165 struct mwl8k_cmd_pkt header; 2285#define MWL8K_FRAME_PROT_11G 0x07
2166 __le16 action; 2286#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
2167 __u8 short_slot; 2287#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
2168} __attribute__((packed));
2169
2170static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
2171{
2172 struct mwl8k_cmd_set_slot *cmd;
2173 int rc;
2174
2175 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2176 if (cmd == NULL)
2177 return -ENOMEM;
2178
2179 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
2180 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2181 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2182 cmd->short_slot = short_slot_time;
2183
2184 rc = mwl8k_post_cmd(hw, &cmd->header);
2185 kfree(cmd);
2186 2288
2187 return rc; 2289struct mwl8k_cmd_update_set_aid {
2188} 2290 struct mwl8k_cmd_pkt header;
2291 __le16 aid;
2189 2292
2190/* 2293 /* AP's MAC address (BSSID) */
2191 * CMD_MIMO_CONFIG. 2294 __u8 bssid[ETH_ALEN];
2192 */ 2295 __le16 protection_mode;
2193struct mwl8k_cmd_mimo_config { 2296 __u8 supp_rates[14];
2194 struct mwl8k_cmd_pkt header;
2195 __le32 action;
2196 __u8 rx_antenna_map;
2197 __u8 tx_antenna_map;
2198} __attribute__((packed)); 2297} __attribute__((packed));
2199 2298
2200static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx) 2299static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
2201{ 2300{
2202 struct mwl8k_cmd_mimo_config *cmd; 2301 int i;
2203 int rc; 2302 int j;
2204
2205 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2206 if (cmd == NULL)
2207 return -ENOMEM;
2208
2209 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
2210 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2211 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
2212 cmd->rx_antenna_map = rx;
2213 cmd->tx_antenna_map = tx;
2214 2303
2215 rc = mwl8k_post_cmd(hw, &cmd->header); 2304 /*
2216 kfree(cmd); 2305 * Clear nonstandard rates 4 and 13.
2306 */
2307 mask &= 0x1fef;
2217 2308
2218 return rc; 2309 for (i = 0, j = 0; i < 14; i++) {
2310 if (mask & (1 << i))
2311 rates[j++] = mwl8k_rates_24[i].hw_value;
2312 }
2219} 2313}
2220 2314
2221/* 2315static int
2222 * CMD_ENABLE_SNIFFER. 2316mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2223 */ 2317 struct ieee80211_vif *vif, u32 legacy_rate_mask)
2224struct mwl8k_cmd_enable_sniffer {
2225 struct mwl8k_cmd_pkt header;
2226 __le32 action;
2227} __attribute__((packed));
2228
2229static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2230{ 2318{
2231 struct mwl8k_cmd_enable_sniffer *cmd; 2319 struct mwl8k_cmd_update_set_aid *cmd;
2320 u16 prot_mode;
2232 int rc; 2321 int rc;
2233 2322
2234 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2323 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2235 if (cmd == NULL) 2324 if (cmd == NULL)
2236 return -ENOMEM; 2325 return -ENOMEM;
2237 2326
2238 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); 2327 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
2239 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2328 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2240 cmd->action = cpu_to_le32(!!enable); 2329 cmd->aid = cpu_to_le16(vif->bss_conf.aid);
2330 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
2331
2332 if (vif->bss_conf.use_cts_prot) {
2333 prot_mode = MWL8K_FRAME_PROT_11G;
2334 } else {
2335 switch (vif->bss_conf.ht_operation_mode &
2336 IEEE80211_HT_OP_MODE_PROTECTION) {
2337 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2338 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2339 break;
2340 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2341 prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2342 break;
2343 default:
2344 prot_mode = MWL8K_FRAME_PROT_DISABLED;
2345 break;
2346 }
2347 }
2348 cmd->protection_mode = cpu_to_le16(prot_mode);
2349
2350 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
2241 2351
2242 rc = mwl8k_post_cmd(hw, &cmd->header); 2352 rc = mwl8k_post_cmd(hw, &cmd->header);
2243 kfree(cmd); 2353 kfree(cmd);
@@ -2246,37 +2356,32 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2246} 2356}
2247 2357
2248/* 2358/*
2249 * CMD_SET_MAC_ADDR. 2359 * CMD_SET_RATE.
2250 */ 2360 */
2251struct mwl8k_cmd_set_mac_addr { 2361struct mwl8k_cmd_set_rate {
2252 struct mwl8k_cmd_pkt header; 2362 struct mwl8k_cmd_pkt header;
2253 union { 2363 __u8 legacy_rates[14];
2254 struct { 2364
2255 __le16 mac_type; 2365 /* Bitmap for supported MCS codes. */
2256 __u8 mac_addr[ETH_ALEN]; 2366 __u8 mcs_set[16];
2257 } mbss; 2367 __u8 reserved[16];
2258 __u8 mac_addr[ETH_ALEN];
2259 };
2260} __attribute__((packed)); 2368} __attribute__((packed));
2261 2369
2262static int mwl8k_set_mac_addr(struct ieee80211_hw *hw, u8 *mac) 2370static int
2371mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2372 u32 legacy_rate_mask, u8 *mcs_rates)
2263{ 2373{
2264 struct mwl8k_priv *priv = hw->priv; 2374 struct mwl8k_cmd_set_rate *cmd;
2265 struct mwl8k_cmd_set_mac_addr *cmd;
2266 int rc; 2375 int rc;
2267 2376
2268 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2377 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2269 if (cmd == NULL) 2378 if (cmd == NULL)
2270 return -ENOMEM; 2379 return -ENOMEM;
2271 2380
2272 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); 2381 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
2273 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2382 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2274 if (priv->ap_fw) { 2383 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
2275 cmd->mbss.mac_type = 0; 2384 memcpy(cmd->mcs_set, mcs_rates, 16);
2276 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2277 } else {
2278 memcpy(cmd->mac_addr, mac, ETH_ALEN);
2279 }
2280 2385
2281 rc = mwl8k_post_cmd(hw, &cmd->header); 2386 rc = mwl8k_post_cmd(hw, &cmd->header);
2282 kfree(cmd); 2387 kfree(cmd);
@@ -2284,29 +2389,40 @@ static int mwl8k_set_mac_addr(struct ieee80211_hw *hw, u8 *mac)
2284 return rc; 2389 return rc;
2285} 2390}
2286 2391
2287
2288/* 2392/*
2289 * CMD_SET_RATEADAPT_MODE. 2393 * CMD_FINALIZE_JOIN.
2290 */ 2394 */
2291struct mwl8k_cmd_set_rate_adapt_mode { 2395#define MWL8K_FJ_BEACON_MAXLEN 128
2396
2397struct mwl8k_cmd_finalize_join {
2292 struct mwl8k_cmd_pkt header; 2398 struct mwl8k_cmd_pkt header;
2293 __le16 action; 2399 __le32 sleep_interval; /* Number of beacon periods to sleep */
2294 __le16 mode; 2400 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
2295} __attribute__((packed)); 2401} __attribute__((packed));
2296 2402
2297static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode) 2403static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame,
2404 int framelen, int dtim)
2298{ 2405{
2299 struct mwl8k_cmd_set_rate_adapt_mode *cmd; 2406 struct mwl8k_cmd_finalize_join *cmd;
2407 struct ieee80211_mgmt *payload = frame;
2408 int payload_len;
2300 int rc; 2409 int rc;
2301 2410
2302 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2411 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2303 if (cmd == NULL) 2412 if (cmd == NULL)
2304 return -ENOMEM; 2413 return -ENOMEM;
2305 2414
2306 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE); 2415 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
2307 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2416 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2308 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2417 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
2309 cmd->mode = cpu_to_le16(mode); 2418
2419 payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
2420 if (payload_len < 0)
2421 payload_len = 0;
2422 else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2423 payload_len = MWL8K_FJ_BEACON_MAXLEN;
2424
2425 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
2310 2426
2311 rc = mwl8k_post_cmd(hw, &cmd->header); 2427 rc = mwl8k_post_cmd(hw, &cmd->header);
2312 kfree(cmd); 2428 kfree(cmd);
@@ -2315,59 +2431,57 @@ static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
2315} 2431}
2316 2432
2317/* 2433/*
2318 * CMD_SET_WMM_MODE. 2434 * CMD_SET_RTS_THRESHOLD.
2319 */ 2435 */
2320struct mwl8k_cmd_set_wmm { 2436struct mwl8k_cmd_set_rts_threshold {
2321 struct mwl8k_cmd_pkt header; 2437 struct mwl8k_cmd_pkt header;
2322 __le16 action; 2438 __le16 action;
2439 __le16 threshold;
2323} __attribute__((packed)); 2440} __attribute__((packed));
2324 2441
2325static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable) 2442static int
2443mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
2326{ 2444{
2327 struct mwl8k_priv *priv = hw->priv; 2445 struct mwl8k_cmd_set_rts_threshold *cmd;
2328 struct mwl8k_cmd_set_wmm *cmd;
2329 int rc; 2446 int rc;
2330 2447
2331 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2448 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2332 if (cmd == NULL) 2449 if (cmd == NULL)
2333 return -ENOMEM; 2450 return -ENOMEM;
2334 2451
2335 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); 2452 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
2336 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2453 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2337 cmd->action = cpu_to_le16(!!enable); 2454 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2455 cmd->threshold = cpu_to_le16(rts_thresh);
2338 2456
2339 rc = mwl8k_post_cmd(hw, &cmd->header); 2457 rc = mwl8k_post_cmd(hw, &cmd->header);
2340 kfree(cmd); 2458 kfree(cmd);
2341 2459
2342 if (!rc)
2343 priv->wmm_enabled = enable;
2344
2345 return rc; 2460 return rc;
2346} 2461}
2347 2462
2348/* 2463/*
2349 * CMD_SET_RTS_THRESHOLD. 2464 * CMD_SET_SLOT.
2350 */ 2465 */
2351struct mwl8k_cmd_rts_threshold { 2466struct mwl8k_cmd_set_slot {
2352 struct mwl8k_cmd_pkt header; 2467 struct mwl8k_cmd_pkt header;
2353 __le16 action; 2468 __le16 action;
2354 __le16 threshold; 2469 __u8 short_slot;
2355} __attribute__((packed)); 2470} __attribute__((packed));
2356 2471
2357static int mwl8k_rts_threshold(struct ieee80211_hw *hw, 2472static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
2358 u16 action, u16 threshold)
2359{ 2473{
2360 struct mwl8k_cmd_rts_threshold *cmd; 2474 struct mwl8k_cmd_set_slot *cmd;
2361 int rc; 2475 int rc;
2362 2476
2363 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2477 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2364 if (cmd == NULL) 2478 if (cmd == NULL)
2365 return -ENOMEM; 2479 return -ENOMEM;
2366 2480
2367 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); 2481 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
2368 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2482 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2369 cmd->action = cpu_to_le16(action); 2483 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2370 cmd->threshold = cpu_to_le16(threshold); 2484 cmd->short_slot = short_slot_time;
2371 2485
2372 rc = mwl8k_post_cmd(hw, &cmd->header); 2486 rc = mwl8k_post_cmd(hw, &cmd->header);
2373 kfree(cmd); 2487 kfree(cmd);
@@ -2426,9 +2540,9 @@ struct mwl8k_cmd_set_edca_params {
2426 MWL8K_SET_EDCA_AIFS) 2540 MWL8K_SET_EDCA_AIFS)
2427 2541
2428static int 2542static int
2429mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum, 2543mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2430 __u16 cw_min, __u16 cw_max, 2544 __u16 cw_min, __u16 cw_max,
2431 __u8 aifs, __u16 txop) 2545 __u8 aifs, __u16 txop)
2432{ 2546{
2433 struct mwl8k_priv *priv = hw->priv; 2547 struct mwl8k_priv *priv = hw->priv;
2434 struct mwl8k_cmd_set_edca_params *cmd; 2548 struct mwl8k_cmd_set_edca_params *cmd;
@@ -2438,12 +2552,6 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2438 if (cmd == NULL) 2552 if (cmd == NULL)
2439 return -ENOMEM; 2553 return -ENOMEM;
2440 2554
2441 /*
2442 * Queues 0 (BE) and 1 (BK) are swapped in hardware for
2443 * this call.
2444 */
2445 qnum ^= !(qnum >> 1);
2446
2447 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); 2555 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2448 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2556 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2449 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2557 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
@@ -2467,170 +2575,259 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2467} 2575}
2468 2576
2469/* 2577/*
2470 * CMD_FINALIZE_JOIN. 2578 * CMD_SET_WMM_MODE.
2471 */ 2579 */
2472#define MWL8K_FJ_BEACON_MAXLEN 128 2580struct mwl8k_cmd_set_wmm_mode {
2473
2474struct mwl8k_cmd_finalize_join {
2475 struct mwl8k_cmd_pkt header; 2581 struct mwl8k_cmd_pkt header;
2476 __le32 sleep_interval; /* Number of beacon periods to sleep */ 2582 __le16 action;
2477 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
2478} __attribute__((packed)); 2583} __attribute__((packed));
2479 2584
2480static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame, 2585static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
2481 int framelen, int dtim)
2482{ 2586{
2483 struct mwl8k_cmd_finalize_join *cmd; 2587 struct mwl8k_priv *priv = hw->priv;
2484 struct ieee80211_mgmt *payload = frame; 2588 struct mwl8k_cmd_set_wmm_mode *cmd;
2485 int payload_len;
2486 int rc; 2589 int rc;
2487 2590
2488 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2591 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2489 if (cmd == NULL) 2592 if (cmd == NULL)
2490 return -ENOMEM; 2593 return -ENOMEM;
2491 2594
2492 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); 2595 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
2493 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2596 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2494 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1); 2597 cmd->action = cpu_to_le16(!!enable);
2495
2496 payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
2497 if (payload_len < 0)
2498 payload_len = 0;
2499 else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2500 payload_len = MWL8K_FJ_BEACON_MAXLEN;
2501
2502 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
2503 2598
2504 rc = mwl8k_post_cmd(hw, &cmd->header); 2599 rc = mwl8k_post_cmd(hw, &cmd->header);
2505 kfree(cmd); 2600 kfree(cmd);
2506 2601
2602 if (!rc)
2603 priv->wmm_enabled = enable;
2604
2507 return rc; 2605 return rc;
2508} 2606}
2509 2607
2510/* 2608/*
2511 * CMD_UPDATE_STADB. 2609 * CMD_MIMO_CONFIG.
2512 */ 2610 */
2513struct mwl8k_cmd_update_sta_db { 2611struct mwl8k_cmd_mimo_config {
2514 struct mwl8k_cmd_pkt header; 2612 struct mwl8k_cmd_pkt header;
2613 __le32 action;
2614 __u8 rx_antenna_map;
2615 __u8 tx_antenna_map;
2616} __attribute__((packed));
2515 2617
2516 /* See STADB_ACTION_TYPE */ 2618static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
2517 __le32 action; 2619{
2620 struct mwl8k_cmd_mimo_config *cmd;
2621 int rc;
2518 2622
2519 /* Peer MAC address */ 2623 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2520 __u8 peer_addr[ETH_ALEN]; 2624 if (cmd == NULL)
2625 return -ENOMEM;
2521 2626
2522 __le32 reserved; 2627 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
2628 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2629 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
2630 cmd->rx_antenna_map = rx;
2631 cmd->tx_antenna_map = tx;
2523 2632
2524 /* Peer info - valid during add/update. */ 2633 rc = mwl8k_post_cmd(hw, &cmd->header);
2525 struct peer_capability_info peer_info; 2634 kfree(cmd);
2635
2636 return rc;
2637}
2638
2639/*
2640 * CMD_USE_FIXED_RATE (STA version).
2641 */
2642struct mwl8k_cmd_use_fixed_rate_sta {
2643 struct mwl8k_cmd_pkt header;
2644 __le32 action;
2645 __le32 allow_rate_drop;
2646 __le32 num_rates;
2647 struct {
2648 __le32 is_ht_rate;
2649 __le32 enable_retry;
2650 __le32 rate;
2651 __le32 retry_count;
2652 } rate_entry[8];
2653 __le32 rate_type;
2654 __le32 reserved1;
2655 __le32 reserved2;
2526} __attribute__((packed)); 2656} __attribute__((packed));
2527 2657
2528static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw, 2658#define MWL8K_USE_AUTO_RATE 0x0002
2529 struct ieee80211_vif *vif, __u32 action) 2659#define MWL8K_UCAST_RATE 0
2660
2661static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
2530{ 2662{
2531 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2663 struct mwl8k_cmd_use_fixed_rate_sta *cmd;
2532 struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2533 struct mwl8k_cmd_update_sta_db *cmd;
2534 struct peer_capability_info *peer_info;
2535 int rc; 2664 int rc;
2536 2665
2537 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2666 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2538 if (cmd == NULL) 2667 if (cmd == NULL)
2539 return -ENOMEM; 2668 return -ENOMEM;
2540 2669
2541 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); 2670 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2542 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2671 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2672 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2673 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
2543 2674
2544 cmd->action = cpu_to_le32(action); 2675 rc = mwl8k_post_cmd(hw, &cmd->header);
2545 peer_info = &cmd->peer_info; 2676 kfree(cmd);
2546 memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
2547 2677
2548 switch (action) { 2678 return rc;
2549 case MWL8K_STA_DB_ADD_ENTRY: 2679}
2550 case MWL8K_STA_DB_MODIFY_ENTRY:
2551 /* Build peer_info block */
2552 peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
2553 peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
2554 memcpy(peer_info->legacy_rates, mwl8k_rateids,
2555 sizeof(mwl8k_rateids));
2556 peer_info->interop = 1;
2557 peer_info->amsdu_enabled = 0;
2558
2559 rc = mwl8k_post_cmd(hw, &cmd->header);
2560 if (rc == 0)
2561 mv_vif->peer_id = peer_info->station_id;
2562 2680
2563 break; 2681/*
2682 * CMD_USE_FIXED_RATE (AP version).
2683 */
2684struct mwl8k_cmd_use_fixed_rate_ap {
2685 struct mwl8k_cmd_pkt header;
2686 __le32 action;
2687 __le32 allow_rate_drop;
2688 __le32 num_rates;
2689 struct mwl8k_rate_entry_ap {
2690 __le32 is_ht_rate;
2691 __le32 enable_retry;
2692 __le32 rate;
2693 __le32 retry_count;
2694 } rate_entry[4];
2695 u8 multicast_rate;
2696 u8 multicast_rate_type;
2697 u8 management_rate;
2698} __attribute__((packed));
2564 2699
2565 case MWL8K_STA_DB_DEL_ENTRY: 2700static int
2566 case MWL8K_STA_DB_FLUSH: 2701mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
2567 default: 2702{
2568 rc = mwl8k_post_cmd(hw, &cmd->header); 2703 struct mwl8k_cmd_use_fixed_rate_ap *cmd;
2569 if (rc == 0) 2704 int rc;
2570 mv_vif->peer_id = 0; 2705
2571 break; 2706 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2572 } 2707 if (cmd == NULL)
2708 return -ENOMEM;
2709
2710 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2711 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2712 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2713 cmd->multicast_rate = mcast;
2714 cmd->management_rate = mgmt;
2715
2716 rc = mwl8k_post_cmd(hw, &cmd->header);
2573 kfree(cmd); 2717 kfree(cmd);
2574 2718
2575 return rc; 2719 return rc;
2576} 2720}
2577 2721
2578/* 2722/*
2579 * CMD_SET_AID. 2723 * CMD_ENABLE_SNIFFER.
2580 */ 2724 */
2581#define MWL8K_FRAME_PROT_DISABLED 0x00 2725struct mwl8k_cmd_enable_sniffer {
2582#define MWL8K_FRAME_PROT_11G 0x07 2726 struct mwl8k_cmd_pkt header;
2583#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02 2727 __le32 action;
2584#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
2585
2586struct mwl8k_cmd_update_set_aid {
2587 struct mwl8k_cmd_pkt header;
2588 __le16 aid;
2589
2590 /* AP's MAC address (BSSID) */
2591 __u8 bssid[ETH_ALEN];
2592 __le16 protection_mode;
2593 __u8 supp_rates[14];
2594} __attribute__((packed)); 2728} __attribute__((packed));
2595 2729
2596static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw, 2730static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2597 struct ieee80211_vif *vif)
2598{ 2731{
2599 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2732 struct mwl8k_cmd_enable_sniffer *cmd;
2600 struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2601 struct mwl8k_cmd_update_set_aid *cmd;
2602 u16 prot_mode;
2603 int rc; 2733 int rc;
2604 2734
2605 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2735 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2606 if (cmd == NULL) 2736 if (cmd == NULL)
2607 return -ENOMEM; 2737 return -ENOMEM;
2608 2738
2609 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); 2739 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
2610 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2740 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2611 cmd->aid = cpu_to_le16(info->aid); 2741 cmd->action = cpu_to_le32(!!enable);
2612 2742
2613 memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN); 2743 rc = mwl8k_post_cmd(hw, &cmd->header);
2744 kfree(cmd);
2614 2745
2615 if (info->use_cts_prot) { 2746 return rc;
2616 prot_mode = MWL8K_FRAME_PROT_11G; 2747}
2748
2749/*
2750 * CMD_SET_MAC_ADDR.
2751 */
2752struct mwl8k_cmd_set_mac_addr {
2753 struct mwl8k_cmd_pkt header;
2754 union {
2755 struct {
2756 __le16 mac_type;
2757 __u8 mac_addr[ETH_ALEN];
2758 } mbss;
2759 __u8 mac_addr[ETH_ALEN];
2760 };
2761} __attribute__((packed));
2762
2763#define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0
2764#define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1
2765#define MWL8K_MAC_TYPE_PRIMARY_AP 2
2766#define MWL8K_MAC_TYPE_SECONDARY_AP 3
2767
2768static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
2769 struct ieee80211_vif *vif, u8 *mac)
2770{
2771 struct mwl8k_priv *priv = hw->priv;
2772 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2773 struct mwl8k_cmd_set_mac_addr *cmd;
2774 int mac_type;
2775 int rc;
2776
2777 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2778 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
2779 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
2780 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
2781 else
2782 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
2783 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
2784 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
2785 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2786 else
2787 mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
2788 }
2789
2790 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2791 if (cmd == NULL)
2792 return -ENOMEM;
2793
2794 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
2795 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2796 if (priv->ap_fw) {
2797 cmd->mbss.mac_type = cpu_to_le16(mac_type);
2798 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2617 } else { 2799 } else {
2618 switch (info->ht_operation_mode & 2800 memcpy(cmd->mac_addr, mac, ETH_ALEN);
2619 IEEE80211_HT_OP_MODE_PROTECTION) {
2620 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2621 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2622 break;
2623 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2624 prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2625 break;
2626 default:
2627 prot_mode = MWL8K_FRAME_PROT_DISABLED;
2628 break;
2629 }
2630 } 2801 }
2631 cmd->protection_mode = cpu_to_le16(prot_mode);
2632 2802
2633 memcpy(cmd->supp_rates, mwl8k_rateids, sizeof(mwl8k_rateids)); 2803 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2804 kfree(cmd);
2805
2806 return rc;
2807}
2808
2809/*
2810 * CMD_SET_RATEADAPT_MODE.
2811 */
2812struct mwl8k_cmd_set_rate_adapt_mode {
2813 struct mwl8k_cmd_pkt header;
2814 __le16 action;
2815 __le16 mode;
2816} __attribute__((packed));
2817
2818static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
2819{
2820 struct mwl8k_cmd_set_rate_adapt_mode *cmd;
2821 int rc;
2822
2823 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2824 if (cmd == NULL)
2825 return -ENOMEM;
2826
2827 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
2828 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2829 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2830 cmd->mode = cpu_to_le16(mode);
2634 2831
2635 rc = mwl8k_post_cmd(hw, &cmd->header); 2832 rc = mwl8k_post_cmd(hw, &cmd->header);
2636 kfree(cmd); 2833 kfree(cmd);
@@ -2639,115 +2836,255 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2639} 2836}
2640 2837
2641/* 2838/*
2642 * CMD_SET_RATE. 2839 * CMD_BSS_START.
2643 */ 2840 */
2644struct mwl8k_cmd_update_rateset { 2841struct mwl8k_cmd_bss_start {
2645 struct mwl8k_cmd_pkt header; 2842 struct mwl8k_cmd_pkt header;
2646 __u8 legacy_rates[14]; 2843 __le32 enable;
2647
2648 /* Bitmap for supported MCS codes. */
2649 __u8 mcs_set[16];
2650 __u8 reserved[16];
2651} __attribute__((packed)); 2844} __attribute__((packed));
2652 2845
2653static int mwl8k_update_rateset(struct ieee80211_hw *hw, 2846static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
2654 struct ieee80211_vif *vif) 2847 struct ieee80211_vif *vif, int enable)
2655{ 2848{
2656 struct mwl8k_cmd_update_rateset *cmd; 2849 struct mwl8k_cmd_bss_start *cmd;
2657 int rc; 2850 int rc;
2658 2851
2659 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2852 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2660 if (cmd == NULL) 2853 if (cmd == NULL)
2661 return -ENOMEM; 2854 return -ENOMEM;
2662 2855
2663 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); 2856 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START);
2664 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2857 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2665 memcpy(cmd->legacy_rates, mwl8k_rateids, sizeof(mwl8k_rateids)); 2858 cmd->enable = cpu_to_le32(enable);
2666 2859
2667 rc = mwl8k_post_cmd(hw, &cmd->header); 2860 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2668 kfree(cmd); 2861 kfree(cmd);
2669 2862
2670 return rc; 2863 return rc;
2671} 2864}
2672 2865
2673/* 2866/*
2674 * CMD_USE_FIXED_RATE. 2867 * CMD_SET_NEW_STN.
2675 */ 2868 */
2676#define MWL8K_RATE_TABLE_SIZE 8 2869struct mwl8k_cmd_set_new_stn {
2677#define MWL8K_UCAST_RATE 0 2870 struct mwl8k_cmd_pkt header;
2678#define MWL8K_USE_AUTO_RATE 0x0002 2871 __le16 aid;
2872 __u8 mac_addr[6];
2873 __le16 stn_id;
2874 __le16 action;
2875 __le16 rsvd;
2876 __le32 legacy_rates;
2877 __u8 ht_rates[4];
2878 __le16 cap_info;
2879 __le16 ht_capabilities_info;
2880 __u8 mac_ht_param_info;
2881 __u8 rev;
2882 __u8 control_channel;
2883 __u8 add_channel;
2884 __le16 op_mode;
2885 __le16 stbc;
2886 __u8 add_qos_info;
2887 __u8 is_qos_sta;
2888 __le32 fw_sta_ptr;
2889} __attribute__((packed));
2890
2891#define MWL8K_STA_ACTION_ADD 0
2892#define MWL8K_STA_ACTION_REMOVE 2
2893
2894static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
2895 struct ieee80211_vif *vif,
2896 struct ieee80211_sta *sta)
2897{
2898 struct mwl8k_cmd_set_new_stn *cmd;
2899 u32 rates;
2900 int rc;
2901
2902 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2903 if (cmd == NULL)
2904 return -ENOMEM;
2905
2906 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2907 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2908 cmd->aid = cpu_to_le16(sta->aid);
2909 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
2910 cmd->stn_id = cpu_to_le16(sta->aid);
2911 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
2912 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
2913 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
2914 else
2915 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
2916 cmd->legacy_rates = cpu_to_le32(rates);
2917 if (sta->ht_cap.ht_supported) {
2918 cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
2919 cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
2920 cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
2921 cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
2922 cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap);
2923 cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) |
2924 ((sta->ht_cap.ampdu_density & 7) << 2);
2925 cmd->is_qos_sta = 1;
2926 }
2927
2928 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2929 kfree(cmd);
2930
2931 return rc;
2932}
2933
2934static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
2935 struct ieee80211_vif *vif)
2936{
2937 struct mwl8k_cmd_set_new_stn *cmd;
2938 int rc;
2679 2939
2680struct mwl8k_rate_entry { 2940 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2681 /* Set to 1 if HT rate, 0 if legacy. */ 2941 if (cmd == NULL)
2682 __le32 is_ht_rate; 2942 return -ENOMEM;
2683 2943
2684 /* Set to 1 to use retry_count field. */ 2944 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2685 __le32 enable_retry; 2945 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2946 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
2686 2947
2687 /* Specified legacy rate or MCS. */ 2948 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2688 __le32 rate; 2949 kfree(cmd);
2689 2950
2690 /* Number of allowed retries. */ 2951 return rc;
2691 __le32 retry_count; 2952}
2953
2954static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
2955 struct ieee80211_vif *vif, u8 *addr)
2956{
2957 struct mwl8k_cmd_set_new_stn *cmd;
2958 int rc;
2959
2960 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2961 if (cmd == NULL)
2962 return -ENOMEM;
2963
2964 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2965 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2966 memcpy(cmd->mac_addr, addr, ETH_ALEN);
2967 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
2968
2969 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2970 kfree(cmd);
2971
2972 return rc;
2973}
2974
2975/*
2976 * CMD_UPDATE_STADB.
2977 */
2978struct ewc_ht_info {
2979 __le16 control1;
2980 __le16 control2;
2981 __le16 control3;
2692} __attribute__((packed)); 2982} __attribute__((packed));
2693 2983
2694struct mwl8k_rate_table { 2984struct peer_capability_info {
2695 /* 1 to allow specified rate and below */ 2985 /* Peer type - AP vs. STA. */
2696 __le32 allow_rate_drop; 2986 __u8 peer_type;
2697 __le32 num_rates; 2987
2698 struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE]; 2988 /* Basic 802.11 capabilities from assoc resp. */
2989 __le16 basic_caps;
2990
2991 /* Set if peer supports 802.11n high throughput (HT). */
2992 __u8 ht_support;
2993
2994 /* Valid if HT is supported. */
2995 __le16 ht_caps;
2996 __u8 extended_ht_caps;
2997 struct ewc_ht_info ewc_info;
2998
2999 /* Legacy rate table. Intersection of our rates and peer rates. */
3000 __u8 legacy_rates[12];
3001
3002 /* HT rate table. Intersection of our rates and peer rates. */
3003 __u8 ht_rates[16];
3004 __u8 pad[16];
3005
3006 /* If set, interoperability mode, no proprietary extensions. */
3007 __u8 interop;
3008 __u8 pad2;
3009 __u8 station_id;
3010 __le16 amsdu_enabled;
2699} __attribute__((packed)); 3011} __attribute__((packed));
2700 3012
2701struct mwl8k_cmd_use_fixed_rate { 3013struct mwl8k_cmd_update_stadb {
2702 struct mwl8k_cmd_pkt header; 3014 struct mwl8k_cmd_pkt header;
3015
3016 /* See STADB_ACTION_TYPE */
2703 __le32 action; 3017 __le32 action;
2704 struct mwl8k_rate_table rate_table;
2705 3018
2706 /* Unicast, Broadcast or Multicast */ 3019 /* Peer MAC address */
2707 __le32 rate_type; 3020 __u8 peer_addr[ETH_ALEN];
2708 __le32 reserved1; 3021
2709 __le32 reserved2; 3022 __le32 reserved;
3023
3024 /* Peer info - valid during add/update. */
3025 struct peer_capability_info peer_info;
2710} __attribute__((packed)); 3026} __attribute__((packed));
2711 3027
2712static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw, 3028#define MWL8K_STA_DB_MODIFY_ENTRY 1
2713 u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table) 3029#define MWL8K_STA_DB_DEL_ENTRY 2
3030
3031/* Peer Entry flags - used to define the type of the peer node */
3032#define MWL8K_PEER_TYPE_ACCESSPOINT 2
3033
3034static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
3035 struct ieee80211_vif *vif,
3036 struct ieee80211_sta *sta)
2714{ 3037{
2715 struct mwl8k_cmd_use_fixed_rate *cmd; 3038 struct mwl8k_cmd_update_stadb *cmd;
2716 int count; 3039 struct peer_capability_info *p;
3040 u32 rates;
2717 int rc; 3041 int rc;
2718 3042
2719 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3043 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2720 if (cmd == NULL) 3044 if (cmd == NULL)
2721 return -ENOMEM; 3045 return -ENOMEM;
2722 3046
2723 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); 3047 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2724 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 3048 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3049 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
3050 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
3051
3052 p = &cmd->peer_info;
3053 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
3054 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
3055 p->ht_support = sta->ht_cap.ht_supported;
3056 p->ht_caps = sta->ht_cap.cap;
3057 p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
3058 ((sta->ht_cap.ampdu_density & 7) << 2);
3059 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3060 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
3061 else
3062 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3063 legacy_rate_mask_to_array(p->legacy_rates, rates);
3064 memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
3065 p->interop = 1;
3066 p->amsdu_enabled = 0;
2725 3067
2726 cmd->action = cpu_to_le32(action); 3068 rc = mwl8k_post_cmd(hw, &cmd->header);
2727 cmd->rate_type = cpu_to_le32(rate_type); 3069 kfree(cmd);
2728 3070
2729 if (rate_table != NULL) { 3071 return rc ? rc : p->station_id;
2730 /* 3072}
2731 * Copy over each field manually so that endian 3073
2732 * conversion can be done. 3074static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
2733 */ 3075 struct ieee80211_vif *vif, u8 *addr)
2734 cmd->rate_table.allow_rate_drop = 3076{
2735 cpu_to_le32(rate_table->allow_rate_drop); 3077 struct mwl8k_cmd_update_stadb *cmd;
2736 cmd->rate_table.num_rates = 3078 int rc;
2737 cpu_to_le32(rate_table->num_rates); 3079
2738 3080 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2739 for (count = 0; count < rate_table->num_rates; count++) { 3081 if (cmd == NULL)
2740 struct mwl8k_rate_entry *dst = 3082 return -ENOMEM;
2741 &cmd->rate_table.rate_entry[count]; 3083
2742 struct mwl8k_rate_entry *src = 3084 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2743 &rate_table->rate_entry[count]; 3085 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2744 3086 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY);
2745 dst->is_ht_rate = cpu_to_le32(src->is_ht_rate); 3087 memcpy(cmd->peer_addr, addr, ETH_ALEN);
2746 dst->enable_retry = cpu_to_le32(src->enable_retry);
2747 dst->rate = cpu_to_le32(src->rate);
2748 dst->retry_count = cpu_to_le32(src->retry_count);
2749 }
2750 }
2751 3088
2752 rc = mwl8k_post_cmd(hw, &cmd->header); 3089 rc = mwl8k_post_cmd(hw, &cmd->header);
2753 kfree(cmd); 3090 kfree(cmd);
@@ -2766,19 +3103,22 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2766 u32 status; 3103 u32 status;
2767 3104
2768 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3105 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2769 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2770
2771 if (!status) 3106 if (!status)
2772 return IRQ_NONE; 3107 return IRQ_NONE;
2773 3108
2774 if (status & MWL8K_A2H_INT_TX_DONE) 3109 if (status & MWL8K_A2H_INT_TX_DONE) {
2775 tasklet_schedule(&priv->tx_reclaim_task); 3110 status &= ~MWL8K_A2H_INT_TX_DONE;
3111 tasklet_schedule(&priv->poll_tx_task);
3112 }
2776 3113
2777 if (status & MWL8K_A2H_INT_RX_READY) { 3114 if (status & MWL8K_A2H_INT_RX_READY) {
2778 while (rxq_process(hw, 0, 1)) 3115 status &= ~MWL8K_A2H_INT_RX_READY;
2779 rxq_refill(hw, 0, 1); 3116 tasklet_schedule(&priv->poll_rx_task);
2780 } 3117 }
2781 3118
3119 if (status)
3120 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3121
2782 if (status & MWL8K_A2H_INT_OPC_DONE) { 3122 if (status & MWL8K_A2H_INT_OPC_DONE) {
2783 if (priv->hostcmd_wait != NULL) 3123 if (priv->hostcmd_wait != NULL)
2784 complete(priv->hostcmd_wait); 3124 complete(priv->hostcmd_wait);
@@ -2793,6 +3133,53 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2793 return IRQ_HANDLED; 3133 return IRQ_HANDLED;
2794} 3134}
2795 3135
3136static void mwl8k_tx_poll(unsigned long data)
3137{
3138 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3139 struct mwl8k_priv *priv = hw->priv;
3140 int limit;
3141 int i;
3142
3143 limit = 32;
3144
3145 spin_lock_bh(&priv->tx_lock);
3146
3147 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3148 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3149
3150 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
3151 complete(priv->tx_wait);
3152 priv->tx_wait = NULL;
3153 }
3154
3155 spin_unlock_bh(&priv->tx_lock);
3156
3157 if (limit) {
3158 writel(~MWL8K_A2H_INT_TX_DONE,
3159 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3160 } else {
3161 tasklet_schedule(&priv->poll_tx_task);
3162 }
3163}
3164
3165static void mwl8k_rx_poll(unsigned long data)
3166{
3167 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3168 struct mwl8k_priv *priv = hw->priv;
3169 int limit;
3170
3171 limit = 32;
3172 limit -= rxq_process(hw, 0, limit);
3173 limit -= rxq_refill(hw, 0, limit);
3174
3175 if (limit) {
3176 writel(~MWL8K_A2H_INT_RX_READY,
3177 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3178 } else {
3179 tasklet_schedule(&priv->poll_rx_task);
3180 }
3181}
3182
2796 3183
2797/* 3184/*
2798 * Core driver operations. 3185 * Core driver operations.
@@ -2803,7 +3190,7 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2803 int index = skb_get_queue_mapping(skb); 3190 int index = skb_get_queue_mapping(skb);
2804 int rc; 3191 int rc;
2805 3192
2806 if (priv->current_channel == NULL) { 3193 if (!priv->radio_on) {
2807 printk(KERN_DEBUG "%s: dropped TX frame since radio " 3194 printk(KERN_DEBUG "%s: dropped TX frame since radio "
2808 "disabled\n", wiphy_name(hw->wiphy)); 3195 "disabled\n", wiphy_name(hw->wiphy));
2809 dev_kfree_skb(skb); 3196 dev_kfree_skb(skb);
@@ -2828,19 +3215,20 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2828 return -EIO; 3215 return -EIO;
2829 } 3216 }
2830 3217
2831 /* Enable tx reclaim tasklet */ 3218 /* Enable TX reclaim and RX tasklets. */
2832 tasklet_enable(&priv->tx_reclaim_task); 3219 tasklet_enable(&priv->poll_tx_task);
3220 tasklet_enable(&priv->poll_rx_task);
2833 3221
2834 /* Enable interrupts */ 3222 /* Enable interrupts */
2835 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3223 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2836 3224
2837 rc = mwl8k_fw_lock(hw); 3225 rc = mwl8k_fw_lock(hw);
2838 if (!rc) { 3226 if (!rc) {
2839 rc = mwl8k_cmd_802_11_radio_enable(hw); 3227 rc = mwl8k_cmd_radio_enable(hw);
2840 3228
2841 if (!priv->ap_fw) { 3229 if (!priv->ap_fw) {
2842 if (!rc) 3230 if (!rc)
2843 rc = mwl8k_enable_sniffer(hw, 0); 3231 rc = mwl8k_cmd_enable_sniffer(hw, 0);
2844 3232
2845 if (!rc) 3233 if (!rc)
2846 rc = mwl8k_cmd_set_pre_scan(hw); 3234 rc = mwl8k_cmd_set_pre_scan(hw);
@@ -2851,10 +3239,10 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2851 } 3239 }
2852 3240
2853 if (!rc) 3241 if (!rc)
2854 rc = mwl8k_cmd_setrateadaptmode(hw, 0); 3242 rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
2855 3243
2856 if (!rc) 3244 if (!rc)
2857 rc = mwl8k_set_wmm(hw, 0); 3245 rc = mwl8k_cmd_set_wmm_mode(hw, 0);
2858 3246
2859 mwl8k_fw_unlock(hw); 3247 mwl8k_fw_unlock(hw);
2860 } 3248 }
@@ -2862,7 +3250,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2862 if (rc) { 3250 if (rc) {
2863 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3251 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2864 free_irq(priv->pdev->irq, hw); 3252 free_irq(priv->pdev->irq, hw);
2865 tasklet_disable(&priv->tx_reclaim_task); 3253 tasklet_disable(&priv->poll_tx_task);
3254 tasklet_disable(&priv->poll_rx_task);
2866 } 3255 }
2867 3256
2868 return rc; 3257 return rc;
@@ -2873,7 +3262,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2873 struct mwl8k_priv *priv = hw->priv; 3262 struct mwl8k_priv *priv = hw->priv;
2874 int i; 3263 int i;
2875 3264
2876 mwl8k_cmd_802_11_radio_disable(hw); 3265 mwl8k_cmd_radio_disable(hw);
2877 3266
2878 ieee80211_stop_queues(hw); 3267 ieee80211_stop_queues(hw);
2879 3268
@@ -2886,36 +3275,27 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2886 if (priv->beacon_skb != NULL) 3275 if (priv->beacon_skb != NULL)
2887 dev_kfree_skb(priv->beacon_skb); 3276 dev_kfree_skb(priv->beacon_skb);
2888 3277
2889 /* Stop tx reclaim tasklet */ 3278 /* Stop TX reclaim and RX tasklets. */
2890 tasklet_disable(&priv->tx_reclaim_task); 3279 tasklet_disable(&priv->poll_tx_task);
3280 tasklet_disable(&priv->poll_rx_task);
2891 3281
2892 /* Return all skbs to mac80211 */ 3282 /* Return all skbs to mac80211 */
2893 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3283 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2894 mwl8k_txq_reclaim(hw, i, 1); 3284 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
2895} 3285}
2896 3286
2897static int mwl8k_add_interface(struct ieee80211_hw *hw, 3287static int mwl8k_add_interface(struct ieee80211_hw *hw,
2898 struct ieee80211_if_init_conf *conf) 3288 struct ieee80211_vif *vif)
2899{ 3289{
2900 struct mwl8k_priv *priv = hw->priv; 3290 struct mwl8k_priv *priv = hw->priv;
2901 struct mwl8k_vif *mwl8k_vif; 3291 struct mwl8k_vif *mwl8k_vif;
2902 3292 u32 macids_supported;
2903 /* 3293 int macid;
2904 * We only support one active interface at a time.
2905 */
2906 if (priv->vif != NULL)
2907 return -EBUSY;
2908
2909 /*
2910 * We only support managed interfaces for now.
2911 */
2912 if (conf->type != NL80211_IFTYPE_STATION)
2913 return -EINVAL;
2914 3294
2915 /* 3295 /*
2916 * Reject interface creation if sniffer mode is active, as 3296 * Reject interface creation if sniffer mode is active, as
2917 * STA operation is mutually exclusive with hardware sniffer 3297 * STA operation is mutually exclusive with hardware sniffer
2918 * mode. 3298 * mode. (Sniffer mode is only used on STA firmware.)
2919 */ 3299 */
2920 if (priv->sniffer_enabled) { 3300 if (priv->sniffer_enabled) {
2921 printk(KERN_INFO "%s: unable to create STA " 3301 printk(KERN_INFO "%s: unable to create STA "
@@ -2924,37 +3304,54 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
2924 return -EINVAL; 3304 return -EINVAL;
2925 } 3305 }
2926 3306
2927 /* Clean out driver private area */
2928 mwl8k_vif = MWL8K_VIF(conf->vif);
2929 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
2930 3307
2931 /* Set and save the mac address */ 3308 switch (vif->type) {
2932 mwl8k_set_mac_addr(hw, conf->mac_addr); 3309 case NL80211_IFTYPE_AP:
2933 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN); 3310 macids_supported = priv->ap_macids_supported;
3311 break;
3312 case NL80211_IFTYPE_STATION:
3313 macids_supported = priv->sta_macids_supported;
3314 break;
3315 default:
3316 return -EINVAL;
3317 }
2934 3318
2935 /* Back pointer to parent config block */ 3319 macid = ffs(macids_supported & ~priv->macids_used);
2936 mwl8k_vif->priv = priv; 3320 if (!macid--)
3321 return -EBUSY;
2937 3322
2938 /* Set Initial sequence number to zero */ 3323 /* Setup driver private area. */
3324 mwl8k_vif = MWL8K_VIF(vif);
3325 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
3326 mwl8k_vif->vif = vif;
3327 mwl8k_vif->macid = macid;
2939 mwl8k_vif->seqno = 0; 3328 mwl8k_vif->seqno = 0;
2940 3329
2941 priv->vif = conf->vif; 3330 /* Set the mac address. */
2942 priv->current_channel = NULL; 3331 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
3332
3333 if (priv->ap_fw)
3334 mwl8k_cmd_set_new_stn_add_self(hw, vif);
3335
3336 priv->macids_used |= 1 << mwl8k_vif->macid;
3337 list_add_tail(&mwl8k_vif->list, &priv->vif_list);
2943 3338
2944 return 0; 3339 return 0;
2945} 3340}
2946 3341
2947static void mwl8k_remove_interface(struct ieee80211_hw *hw, 3342static void mwl8k_remove_interface(struct ieee80211_hw *hw,
2948 struct ieee80211_if_init_conf *conf) 3343 struct ieee80211_vif *vif)
2949{ 3344{
2950 struct mwl8k_priv *priv = hw->priv; 3345 struct mwl8k_priv *priv = hw->priv;
3346 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2951 3347
2952 if (priv->vif == NULL) 3348 if (priv->ap_fw)
2953 return; 3349 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
2954 3350
2955 mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00"); 3351 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
2956 3352
2957 priv->vif = NULL; 3353 priv->macids_used &= ~(1 << mwl8k_vif->macid);
3354 list_del(&mwl8k_vif->list);
2958} 3355}
2959 3356
2960static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 3357static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2964,8 +3361,7 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2964 int rc; 3361 int rc;
2965 3362
2966 if (conf->flags & IEEE80211_CONF_IDLE) { 3363 if (conf->flags & IEEE80211_CONF_IDLE) {
2967 mwl8k_cmd_802_11_radio_disable(hw); 3364 mwl8k_cmd_radio_disable(hw);
2968 priv->current_channel = NULL;
2969 return 0; 3365 return 0;
2970 } 3366 }
2971 3367
@@ -2973,19 +3369,17 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2973 if (rc) 3369 if (rc)
2974 return rc; 3370 return rc;
2975 3371
2976 rc = mwl8k_cmd_802_11_radio_enable(hw); 3372 rc = mwl8k_cmd_radio_enable(hw);
2977 if (rc) 3373 if (rc)
2978 goto out; 3374 goto out;
2979 3375
2980 rc = mwl8k_cmd_set_rf_channel(hw, conf->channel); 3376 rc = mwl8k_cmd_set_rf_channel(hw, conf);
2981 if (rc) 3377 if (rc)
2982 goto out; 3378 goto out;
2983 3379
2984 priv->current_channel = conf->channel;
2985
2986 if (conf->power_level > 18) 3380 if (conf->power_level > 18)
2987 conf->power_level = 18; 3381 conf->power_level = 18;
2988 rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level); 3382 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
2989 if (rc) 3383 if (rc)
2990 goto out; 3384 goto out;
2991 3385
@@ -3003,79 +3397,160 @@ out:
3003 return rc; 3397 return rc;
3004} 3398}
3005 3399
3006static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, 3400static void
3007 struct ieee80211_vif *vif, 3401mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3008 struct ieee80211_bss_conf *info, 3402 struct ieee80211_bss_conf *info, u32 changed)
3009 u32 changed)
3010{ 3403{
3011 struct mwl8k_priv *priv = hw->priv; 3404 struct mwl8k_priv *priv = hw->priv;
3012 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 3405 u32 ap_legacy_rates;
3406 u8 ap_mcs_rates[16];
3013 int rc; 3407 int rc;
3014 3408
3015 if ((changed & BSS_CHANGED_ASSOC) == 0) 3409 if (mwl8k_fw_lock(hw))
3016 return; 3410 return;
3017 3411
3018 priv->capture_beacon = false; 3412 /*
3019 3413 * No need to capture a beacon if we're no longer associated.
3020 rc = mwl8k_fw_lock(hw); 3414 */
3021 if (rc) 3415 if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
3022 return; 3416 priv->capture_beacon = false;
3023 3417
3024 if (info->assoc) { 3418 /*
3025 memcpy(&mwl8k_vif->bss_info, info, 3419 * Get the AP's legacy and MCS rates.
3026 sizeof(struct ieee80211_bss_conf)); 3420 */
3421 if (vif->bss_conf.assoc) {
3422 struct ieee80211_sta *ap;
3027 3423
3028 memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN); 3424 rcu_read_lock();
3029 3425
3030 /* Install rates */ 3426 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
3031 rc = mwl8k_update_rateset(hw, vif); 3427 if (ap == NULL) {
3032 if (rc) 3428 rcu_read_unlock();
3033 goto out; 3429 goto out;
3430 }
3431
3432 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
3433 ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
3434 } else {
3435 ap_legacy_rates =
3436 ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3437 }
3438 memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
3034 3439
3035 /* Turn on rate adaptation */ 3440 rcu_read_unlock();
3036 rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE, 3441 }
3037 MWL8K_UCAST_RATE, NULL); 3442
3443 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
3444 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
3038 if (rc) 3445 if (rc)
3039 goto out; 3446 goto out;
3040 3447
3041 /* Set radio preamble */ 3448 rc = mwl8k_cmd_use_fixed_rate_sta(hw);
3042 rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
3043 if (rc) 3449 if (rc)
3044 goto out; 3450 goto out;
3451 }
3045 3452
3046 /* Set slot time */ 3453 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3047 rc = mwl8k_cmd_set_slot(hw, info->use_short_slot); 3454 rc = mwl8k_set_radio_preamble(hw,
3455 vif->bss_conf.use_short_preamble);
3048 if (rc) 3456 if (rc)
3049 goto out; 3457 goto out;
3458 }
3050 3459
3051 /* Update peer rate info */ 3460 if (changed & BSS_CHANGED_ERP_SLOT) {
3052 rc = mwl8k_cmd_update_sta_db(hw, vif, 3461 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
3053 MWL8K_STA_DB_MODIFY_ENTRY);
3054 if (rc) 3462 if (rc)
3055 goto out; 3463 goto out;
3464 }
3056 3465
3057 /* Set AID */ 3466 if (vif->bss_conf.assoc &&
3058 rc = mwl8k_cmd_set_aid(hw, vif); 3467 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
3468 BSS_CHANGED_HT))) {
3469 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
3059 if (rc) 3470 if (rc)
3060 goto out; 3471 goto out;
3472 }
3061 3473
3474 if (vif->bss_conf.assoc &&
3475 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
3062 /* 3476 /*
3063 * Finalize the join. Tell rx handler to process 3477 * Finalize the join. Tell rx handler to process
3064 * next beacon from our BSSID. 3478 * next beacon from our BSSID.
3065 */ 3479 */
3066 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN); 3480 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
3067 priv->capture_beacon = true; 3481 priv->capture_beacon = true;
3068 } else {
3069 rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
3070 memset(&mwl8k_vif->bss_info, 0,
3071 sizeof(struct ieee80211_bss_conf));
3072 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
3073 } 3482 }
3074 3483
3075out: 3484out:
3076 mwl8k_fw_unlock(hw); 3485 mwl8k_fw_unlock(hw);
3077} 3486}
3078 3487
3488static void
3489mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3490 struct ieee80211_bss_conf *info, u32 changed)
3491{
3492 int rc;
3493
3494 if (mwl8k_fw_lock(hw))
3495 return;
3496
3497 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3498 rc = mwl8k_set_radio_preamble(hw,
3499 vif->bss_conf.use_short_preamble);
3500 if (rc)
3501 goto out;
3502 }
3503
3504 if (changed & BSS_CHANGED_BASIC_RATES) {
3505 int idx;
3506 int rate;
3507
3508 /*
3509 * Use lowest supported basic rate for multicasts
3510 * and management frames (such as probe responses --
3511 * beacons will always go out at 1 Mb/s).
3512 */
3513 idx = ffs(vif->bss_conf.basic_rates);
3514 if (idx)
3515 idx--;
3516
3517 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3518 rate = mwl8k_rates_24[idx].hw_value;
3519 else
3520 rate = mwl8k_rates_50[idx].hw_value;
3521
3522 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
3523 }
3524
3525 if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
3526 struct sk_buff *skb;
3527
3528 skb = ieee80211_beacon_get(hw, vif);
3529 if (skb != NULL) {
3530 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
3531 kfree_skb(skb);
3532 }
3533 }
3534
3535 if (changed & BSS_CHANGED_BEACON_ENABLED)
3536 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
3537
3538out:
3539 mwl8k_fw_unlock(hw);
3540}
3541
3542static void
3543mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3544 struct ieee80211_bss_conf *info, u32 changed)
3545{
3546 struct mwl8k_priv *priv = hw->priv;
3547
3548 if (!priv->ap_fw)
3549 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
3550 else
3551 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
3552}
3553
3079static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 3554static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3080 int mc_count, struct dev_addr_list *mclist) 3555 int mc_count, struct dev_addr_list *mclist)
3081{ 3556{
@@ -3105,7 +3580,7 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3105 * operation, so refuse to enable sniffer mode if a STA 3580 * operation, so refuse to enable sniffer mode if a STA
3106 * interface is active. 3581 * interface is active.
3107 */ 3582 */
3108 if (priv->vif != NULL) { 3583 if (!list_empty(&priv->vif_list)) {
3109 if (net_ratelimit()) 3584 if (net_ratelimit())
3110 printk(KERN_INFO "%s: not enabling sniffer " 3585 printk(KERN_INFO "%s: not enabling sniffer "
3111 "mode because STA interface is active\n", 3586 "mode because STA interface is active\n",
@@ -3114,7 +3589,7 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3114 } 3589 }
3115 3590
3116 if (!priv->sniffer_enabled) { 3591 if (!priv->sniffer_enabled) {
3117 if (mwl8k_enable_sniffer(hw, 1)) 3592 if (mwl8k_cmd_enable_sniffer(hw, 1))
3118 return 0; 3593 return 0;
3119 priv->sniffer_enabled = true; 3594 priv->sniffer_enabled = true;
3120 } 3595 }
@@ -3126,6 +3601,14 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3126 return 1; 3601 return 1;
3127} 3602}
3128 3603
3604static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
3605{
3606 if (!list_empty(&priv->vif_list))
3607 return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
3608
3609 return NULL;
3610}
3611
3129static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3612static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3130 unsigned int changed_flags, 3613 unsigned int changed_flags,
3131 unsigned int *total_flags, 3614 unsigned int *total_flags,
@@ -3163,7 +3646,7 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3163 } 3646 }
3164 3647
3165 if (priv->sniffer_enabled) { 3648 if (priv->sniffer_enabled) {
3166 mwl8k_enable_sniffer(hw, 0); 3649 mwl8k_cmd_enable_sniffer(hw, 0);
3167 priv->sniffer_enabled = false; 3650 priv->sniffer_enabled = false;
3168 } 3651 }
3169 3652
@@ -3174,7 +3657,8 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3174 */ 3657 */
3175 mwl8k_cmd_set_pre_scan(hw); 3658 mwl8k_cmd_set_pre_scan(hw);
3176 } else { 3659 } else {
3177 u8 *bssid; 3660 struct mwl8k_vif *mwl8k_vif;
3661 const u8 *bssid;
3178 3662
3179 /* 3663 /*
3180 * Enable the BSS filter. 3664 * Enable the BSS filter.
@@ -3184,9 +3668,11 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3184 * (where the OUI part needs to be nonzero for 3668 * (where the OUI part needs to be nonzero for
3185 * the BSSID to be accepted by POST_SCAN). 3669 * the BSSID to be accepted by POST_SCAN).
3186 */ 3670 */
3187 bssid = "\x01\x00\x00\x00\x00\x00"; 3671 mwl8k_vif = mwl8k_first_vif(priv);
3188 if (priv->vif != NULL) 3672 if (mwl8k_vif != NULL)
3189 bssid = MWL8K_VIF(priv->vif)->bssid; 3673 bssid = mwl8k_vif->vif->bss_conf.bssid;
3674 else
3675 bssid = "\x01\x00\x00\x00\x00\x00";
3190 3676
3191 mwl8k_cmd_set_post_scan(hw, bssid); 3677 mwl8k_cmd_set_post_scan(hw, bssid);
3192 } 3678 }
@@ -3213,7 +3699,39 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3213 3699
3214static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3700static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3215{ 3701{
3216 return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value); 3702 return mwl8k_cmd_set_rts_threshold(hw, value);
3703}
3704
3705static int mwl8k_sta_remove(struct ieee80211_hw *hw,
3706 struct ieee80211_vif *vif,
3707 struct ieee80211_sta *sta)
3708{
3709 struct mwl8k_priv *priv = hw->priv;
3710
3711 if (priv->ap_fw)
3712 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
3713 else
3714 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
3715}
3716
3717static int mwl8k_sta_add(struct ieee80211_hw *hw,
3718 struct ieee80211_vif *vif,
3719 struct ieee80211_sta *sta)
3720{
3721 struct mwl8k_priv *priv = hw->priv;
3722 int ret;
3723
3724 if (!priv->ap_fw) {
3725 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
3726 if (ret >= 0) {
3727 MWL8K_STA(sta)->peer_id = ret;
3728 return 0;
3729 }
3730
3731 return ret;
3732 }
3733
3734 return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
3217} 3735}
3218 3736
3219static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3737static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -3225,14 +3743,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3225 rc = mwl8k_fw_lock(hw); 3743 rc = mwl8k_fw_lock(hw);
3226 if (!rc) { 3744 if (!rc) {
3227 if (!priv->wmm_enabled) 3745 if (!priv->wmm_enabled)
3228 rc = mwl8k_set_wmm(hw, 1); 3746 rc = mwl8k_cmd_set_wmm_mode(hw, 1);
3229 3747
3230 if (!rc) 3748 if (!rc)
3231 rc = mwl8k_set_edca_params(hw, queue, 3749 rc = mwl8k_cmd_set_edca_params(hw, queue,
3232 params->cw_min, 3750 params->cw_min,
3233 params->cw_max, 3751 params->cw_max,
3234 params->aifs, 3752 params->aifs,
3235 params->txop); 3753 params->txop);
3236 3754
3237 mwl8k_fw_unlock(hw); 3755 mwl8k_fw_unlock(hw);
3238 } 3756 }
@@ -3240,28 +3758,26 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3240 return rc; 3758 return rc;
3241} 3759}
3242 3760
3243static int mwl8k_get_tx_stats(struct ieee80211_hw *hw, 3761static int mwl8k_get_stats(struct ieee80211_hw *hw,
3244 struct ieee80211_tx_queue_stats *stats) 3762 struct ieee80211_low_level_stats *stats)
3245{ 3763{
3246 struct mwl8k_priv *priv = hw->priv; 3764 return mwl8k_cmd_get_stat(hw, stats);
3247 struct mwl8k_tx_queue *txq;
3248 int index;
3249
3250 spin_lock_bh(&priv->tx_lock);
3251 for (index = 0; index < MWL8K_TX_QUEUES; index++) {
3252 txq = priv->txq + index;
3253 memcpy(&stats[index], &txq->stats,
3254 sizeof(struct ieee80211_tx_queue_stats));
3255 }
3256 spin_unlock_bh(&priv->tx_lock);
3257
3258 return 0;
3259} 3765}
3260 3766
3261static int mwl8k_get_stats(struct ieee80211_hw *hw, 3767static int
3262 struct ieee80211_low_level_stats *stats) 3768mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3769 enum ieee80211_ampdu_mlme_action action,
3770 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3263{ 3771{
3264 return mwl8k_cmd_802_11_get_stat(hw, stats); 3772 switch (action) {
3773 case IEEE80211_AMPDU_RX_START:
3774 case IEEE80211_AMPDU_RX_STOP:
3775 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
3776 return -ENOTSUPP;
3777 return 0;
3778 default:
3779 return -ENOTSUPP;
3780 }
3265} 3781}
3266 3782
3267static const struct ieee80211_ops mwl8k_ops = { 3783static const struct ieee80211_ops mwl8k_ops = {
@@ -3275,67 +3791,72 @@ static const struct ieee80211_ops mwl8k_ops = {
3275 .prepare_multicast = mwl8k_prepare_multicast, 3791 .prepare_multicast = mwl8k_prepare_multicast,
3276 .configure_filter = mwl8k_configure_filter, 3792 .configure_filter = mwl8k_configure_filter,
3277 .set_rts_threshold = mwl8k_set_rts_threshold, 3793 .set_rts_threshold = mwl8k_set_rts_threshold,
3794 .sta_add = mwl8k_sta_add,
3795 .sta_remove = mwl8k_sta_remove,
3278 .conf_tx = mwl8k_conf_tx, 3796 .conf_tx = mwl8k_conf_tx,
3279 .get_tx_stats = mwl8k_get_tx_stats,
3280 .get_stats = mwl8k_get_stats, 3797 .get_stats = mwl8k_get_stats,
3798 .ampdu_action = mwl8k_ampdu_action,
3281}; 3799};
3282 3800
3283static void mwl8k_tx_reclaim_handler(unsigned long data)
3284{
3285 int i;
3286 struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
3287 struct mwl8k_priv *priv = hw->priv;
3288
3289 spin_lock_bh(&priv->tx_lock);
3290 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3291 mwl8k_txq_reclaim(hw, i, 0);
3292
3293 if (priv->tx_wait != NULL && !priv->pending_tx_pkts) {
3294 complete(priv->tx_wait);
3295 priv->tx_wait = NULL;
3296 }
3297 spin_unlock_bh(&priv->tx_lock);
3298}
3299
3300static void mwl8k_finalize_join_worker(struct work_struct *work) 3801static void mwl8k_finalize_join_worker(struct work_struct *work)
3301{ 3802{
3302 struct mwl8k_priv *priv = 3803 struct mwl8k_priv *priv =
3303 container_of(work, struct mwl8k_priv, finalize_join_worker); 3804 container_of(work, struct mwl8k_priv, finalize_join_worker);
3304 struct sk_buff *skb = priv->beacon_skb; 3805 struct sk_buff *skb = priv->beacon_skb;
3305 u8 dtim = MWL8K_VIF(priv->vif)->bss_info.dtim_period; 3806 struct ieee80211_mgmt *mgmt = (void *)skb->data;
3807 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
3808 const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
3809 mgmt->u.beacon.variable, len);
3810 int dtim_period = 1;
3306 3811
3307 mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim); 3812 if (tim && tim[1] >= 2)
3308 dev_kfree_skb(skb); 3813 dtim_period = tim[3];
3814
3815 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
3309 3816
3817 dev_kfree_skb(skb);
3310 priv->beacon_skb = NULL; 3818 priv->beacon_skb = NULL;
3311} 3819}
3312 3820
3313enum { 3821enum {
3314 MWL8687 = 0, 3822 MWL8363 = 0,
3823 MWL8687,
3315 MWL8366, 3824 MWL8366,
3316}; 3825};
3317 3826
3318static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { 3827static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3319 { 3828 [MWL8363] = {
3829 .part_name = "88w8363",
3830 .helper_image = "mwl8k/helper_8363.fw",
3831 .fw_image = "mwl8k/fmimage_8363.fw",
3832 },
3833 [MWL8687] = {
3320 .part_name = "88w8687", 3834 .part_name = "88w8687",
3321 .helper_image = "mwl8k/helper_8687.fw", 3835 .helper_image = "mwl8k/helper_8687.fw",
3322 .fw_image = "mwl8k/fmimage_8687.fw", 3836 .fw_image = "mwl8k/fmimage_8687.fw",
3323 .rxd_ops = &rxd_8687_ops,
3324 .modes = BIT(NL80211_IFTYPE_STATION),
3325 }, 3837 },
3326 { 3838 [MWL8366] = {
3327 .part_name = "88w8366", 3839 .part_name = "88w8366",
3328 .helper_image = "mwl8k/helper_8366.fw", 3840 .helper_image = "mwl8k/helper_8366.fw",
3329 .fw_image = "mwl8k/fmimage_8366.fw", 3841 .fw_image = "mwl8k/fmimage_8366.fw",
3330 .rxd_ops = &rxd_8366_ops, 3842 .ap_rxd_ops = &rxd_8366_ap_ops,
3331 .modes = 0,
3332 }, 3843 },
3333}; 3844};
3334 3845
3846MODULE_FIRMWARE("mwl8k/helper_8363.fw");
3847MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
3848MODULE_FIRMWARE("mwl8k/helper_8687.fw");
3849MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
3850MODULE_FIRMWARE("mwl8k/helper_8366.fw");
3851MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
3852
3335static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { 3853static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3854 { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
3855 { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
3336 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, 3856 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
3337 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, }, 3857 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
3338 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, }, 3858 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
3859 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
3339 { }, 3860 { },
3340}; 3861};
3341MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); 3862MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
@@ -3354,6 +3875,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3354 printed_version = 1; 3875 printed_version = 1;
3355 } 3876 }
3356 3877
3878
3357 rc = pci_enable_device(pdev); 3879 rc = pci_enable_device(pdev);
3358 if (rc) { 3880 if (rc) {
3359 printk(KERN_ERR "%s: Cannot enable new PCI device\n", 3881 printk(KERN_ERR "%s: Cannot enable new PCI device\n",
@@ -3370,6 +3892,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3370 3892
3371 pci_set_master(pdev); 3893 pci_set_master(pdev);
3372 3894
3895
3373 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); 3896 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
3374 if (hw == NULL) { 3897 if (hw == NULL) {
3375 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); 3898 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
@@ -3377,17 +3900,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3377 goto err_free_reg; 3900 goto err_free_reg;
3378 } 3901 }
3379 3902
3903 SET_IEEE80211_DEV(hw, &pdev->dev);
3904 pci_set_drvdata(pdev, hw);
3905
3380 priv = hw->priv; 3906 priv = hw->priv;
3381 priv->hw = hw; 3907 priv->hw = hw;
3382 priv->pdev = pdev; 3908 priv->pdev = pdev;
3383 priv->device_info = &mwl8k_info_tbl[id->driver_data]; 3909 priv->device_info = &mwl8k_info_tbl[id->driver_data];
3384 priv->rxd_ops = priv->device_info->rxd_ops;
3385 priv->sniffer_enabled = false;
3386 priv->wmm_enabled = false;
3387 priv->pending_tx_pkts = 0;
3388 3910
3389 SET_IEEE80211_DEV(hw, &pdev->dev);
3390 pci_set_drvdata(pdev, hw);
3391 3911
3392 priv->sram = pci_iomap(pdev, 0, 0x10000); 3912 priv->sram = pci_iomap(pdev, 0, 0x10000);
3393 if (priv->sram == NULL) { 3913 if (priv->sram == NULL) {
@@ -3410,16 +3930,46 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3410 } 3930 }
3411 } 3931 }
3412 3932
3413 memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
3414 priv->band.band = IEEE80211_BAND_2GHZ;
3415 priv->band.channels = priv->channels;
3416 priv->band.n_channels = ARRAY_SIZE(mwl8k_channels);
3417 priv->band.bitrates = priv->rates;
3418 priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates);
3419 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
3420 3933
3421 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates)); 3934 /* Reset firmware and hardware */
3422 memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates)); 3935 mwl8k_hw_reset(priv);
3936
3937 /* Ask userland hotplug daemon for the device firmware */
3938 rc = mwl8k_request_firmware(priv);
3939 if (rc) {
3940 printk(KERN_ERR "%s: Firmware files not found\n",
3941 wiphy_name(hw->wiphy));
3942 goto err_stop_firmware;
3943 }
3944
3945 /* Load firmware into hardware */
3946 rc = mwl8k_load_firmware(hw);
3947 if (rc) {
3948 printk(KERN_ERR "%s: Cannot start firmware\n",
3949 wiphy_name(hw->wiphy));
3950 goto err_stop_firmware;
3951 }
3952
3953 /* Reclaim memory once firmware is successfully loaded */
3954 mwl8k_release_firmware(priv);
3955
3956
3957 if (priv->ap_fw) {
3958 priv->rxd_ops = priv->device_info->ap_rxd_ops;
3959 if (priv->rxd_ops == NULL) {
3960 printk(KERN_ERR "%s: Driver does not have AP "
3961 "firmware image support for this hardware\n",
3962 wiphy_name(hw->wiphy));
3963 goto err_stop_firmware;
3964 }
3965 } else {
3966 priv->rxd_ops = &rxd_sta_ops;
3967 }
3968
3969 priv->sniffer_enabled = false;
3970 priv->wmm_enabled = false;
3971 priv->pending_tx_pkts = 0;
3972
3423 3973
3424 /* 3974 /*
3425 * Extra headroom is the size of the required DMA header 3975 * Extra headroom is the size of the required DMA header
@@ -3432,12 +3982,13 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3432 3982
3433 hw->queues = MWL8K_TX_QUEUES; 3983 hw->queues = MWL8K_TX_QUEUES;
3434 3984
3435 hw->wiphy->interface_modes = priv->device_info->modes;
3436
3437 /* Set rssi and noise values to dBm */ 3985 /* Set rssi and noise values to dBm */
3438 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; 3986 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
3439 hw->vif_data_size = sizeof(struct mwl8k_vif); 3987 hw->vif_data_size = sizeof(struct mwl8k_vif);
3440 priv->vif = NULL; 3988 hw->sta_data_size = sizeof(struct mwl8k_sta);
3989
3990 priv->macids_used = 0;
3991 INIT_LIST_HEAD(&priv->vif_list);
3441 3992
3442 /* Set default radio state and preamble */ 3993 /* Set default radio state and preamble */
3443 priv->radio_on = 0; 3994 priv->radio_on = 0;
@@ -3446,19 +3997,20 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3446 /* Finalize join worker */ 3997 /* Finalize join worker */
3447 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 3998 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
3448 3999
3449 /* TX reclaim tasklet */ 4000 /* TX reclaim and RX tasklets. */
3450 tasklet_init(&priv->tx_reclaim_task, 4001 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
3451 mwl8k_tx_reclaim_handler, (unsigned long)hw); 4002 tasklet_disable(&priv->poll_tx_task);
3452 tasklet_disable(&priv->tx_reclaim_task); 4003 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
4004 tasklet_disable(&priv->poll_rx_task);
3453 4005
3454 /* Power management cookie */ 4006 /* Power management cookie */
3455 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); 4007 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
3456 if (priv->cookie == NULL) 4008 if (priv->cookie == NULL)
3457 goto err_iounmap; 4009 goto err_stop_firmware;
3458 4010
3459 rc = mwl8k_rxq_init(hw, 0); 4011 rc = mwl8k_rxq_init(hw, 0);
3460 if (rc) 4012 if (rc)
3461 goto err_iounmap; 4013 goto err_free_cookie;
3462 rxq_refill(hw, 0, INT_MAX); 4014 rxq_refill(hw, 0, INT_MAX);
3463 4015
3464 mutex_init(&priv->fw_mutex); 4016 mutex_init(&priv->fw_mutex);
@@ -3478,7 +4030,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3478 4030
3479 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4031 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3480 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4032 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3481 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 4033 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
4034 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
3482 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 4035 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3483 4036
3484 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 4037 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
@@ -3489,31 +4042,9 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3489 goto err_free_queues; 4042 goto err_free_queues;
3490 } 4043 }
3491 4044
3492 /* Reset firmware and hardware */
3493 mwl8k_hw_reset(priv);
3494
3495 /* Ask userland hotplug daemon for the device firmware */
3496 rc = mwl8k_request_firmware(priv);
3497 if (rc) {
3498 printk(KERN_ERR "%s: Firmware files not found\n",
3499 wiphy_name(hw->wiphy));
3500 goto err_free_irq;
3501 }
3502
3503 /* Load firmware into hardware */
3504 rc = mwl8k_load_firmware(hw);
3505 if (rc) {
3506 printk(KERN_ERR "%s: Cannot start firmware\n",
3507 wiphy_name(hw->wiphy));
3508 goto err_stop_firmware;
3509 }
3510
3511 /* Reclaim memory once firmware is successfully loaded */
3512 mwl8k_release_firmware(priv);
3513
3514 /* 4045 /*
3515 * Temporarily enable interrupts. Initial firmware host 4046 * Temporarily enable interrupts. Initial firmware host
3516 * commands use interrupts and avoids polling. Disable 4047 * commands use interrupts and avoid polling. Disable
3517 * interrupts when done. 4048 * interrupts when done.
3518 */ 4049 */
3519 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4050 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
@@ -3529,22 +4060,29 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3529 if (rc) { 4060 if (rc) {
3530 printk(KERN_ERR "%s: Cannot initialise firmware\n", 4061 printk(KERN_ERR "%s: Cannot initialise firmware\n",
3531 wiphy_name(hw->wiphy)); 4062 wiphy_name(hw->wiphy));
3532 goto err_stop_firmware; 4063 goto err_free_irq;
3533 } 4064 }
3534 4065
4066 hw->wiphy->interface_modes = 0;
4067 if (priv->ap_macids_supported)
4068 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4069 if (priv->sta_macids_supported)
4070 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4071
4072
3535 /* Turn radio off */ 4073 /* Turn radio off */
3536 rc = mwl8k_cmd_802_11_radio_disable(hw); 4074 rc = mwl8k_cmd_radio_disable(hw);
3537 if (rc) { 4075 if (rc) {
3538 printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); 4076 printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
3539 goto err_stop_firmware; 4077 goto err_free_irq;
3540 } 4078 }
3541 4079
3542 /* Clear MAC address */ 4080 /* Clear MAC address */
3543 rc = mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00"); 4081 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
3544 if (rc) { 4082 if (rc) {
3545 printk(KERN_ERR "%s: Cannot clear MAC address\n", 4083 printk(KERN_ERR "%s: Cannot clear MAC address\n",
3546 wiphy_name(hw->wiphy)); 4084 wiphy_name(hw->wiphy));
3547 goto err_stop_firmware; 4085 goto err_free_irq;
3548 } 4086 }
3549 4087
3550 /* Disable interrupts */ 4088 /* Disable interrupts */
@@ -3555,7 +4093,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3555 if (rc) { 4093 if (rc) {
3556 printk(KERN_ERR "%s: Cannot register device\n", 4094 printk(KERN_ERR "%s: Cannot register device\n",
3557 wiphy_name(hw->wiphy)); 4095 wiphy_name(hw->wiphy));
3558 goto err_stop_firmware; 4096 goto err_free_queues;
3559 } 4097 }
3560 4098
3561 printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", 4099 printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
@@ -3567,10 +4105,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3567 4105
3568 return 0; 4106 return 0;
3569 4107
3570err_stop_firmware:
3571 mwl8k_hw_reset(priv);
3572 mwl8k_release_firmware(priv);
3573
3574err_free_irq: 4108err_free_irq:
3575 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4109 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3576 free_irq(priv->pdev->irq, hw); 4110 free_irq(priv->pdev->irq, hw);
@@ -3580,11 +4114,16 @@ err_free_queues:
3580 mwl8k_txq_deinit(hw, i); 4114 mwl8k_txq_deinit(hw, i);
3581 mwl8k_rxq_deinit(hw, 0); 4115 mwl8k_rxq_deinit(hw, 0);
3582 4116
3583err_iounmap: 4117err_free_cookie:
3584 if (priv->cookie != NULL) 4118 if (priv->cookie != NULL)
3585 pci_free_consistent(priv->pdev, 4, 4119 pci_free_consistent(priv->pdev, 4,
3586 priv->cookie, priv->cookie_dma); 4120 priv->cookie, priv->cookie_dma);
3587 4121
4122err_stop_firmware:
4123 mwl8k_hw_reset(priv);
4124 mwl8k_release_firmware(priv);
4125
4126err_iounmap:
3588 if (priv->regs != NULL) 4127 if (priv->regs != NULL)
3589 pci_iounmap(pdev, priv->regs); 4128 pci_iounmap(pdev, priv->regs);
3590 4129
@@ -3622,15 +4161,16 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3622 4161
3623 ieee80211_unregister_hw(hw); 4162 ieee80211_unregister_hw(hw);
3624 4163
3625 /* Remove tx reclaim tasklet */ 4164 /* Remove TX reclaim and RX tasklets. */
3626 tasklet_kill(&priv->tx_reclaim_task); 4165 tasklet_kill(&priv->poll_tx_task);
4166 tasklet_kill(&priv->poll_rx_task);
3627 4167
3628 /* Stop hardware */ 4168 /* Stop hardware */
3629 mwl8k_hw_reset(priv); 4169 mwl8k_hw_reset(priv);
3630 4170
3631 /* Return all skbs to mac80211 */ 4171 /* Return all skbs to mac80211 */
3632 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4172 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3633 mwl8k_txq_reclaim(hw, i, 1); 4173 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3634 4174
3635 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4175 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3636 mwl8k_txq_deinit(hw, i); 4176 mwl8k_txq_deinit(hw, i);
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index f27bb8367c98..1d4ada188eda 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -407,7 +407,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = {
407 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), 407 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
408 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), 408 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
409 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), 409 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
410 PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
411 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), 410 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
412 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), 411 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
413 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), 412 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
@@ -417,7 +416,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = {
417 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), 416 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
418 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), 417 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
419 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), 418 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
420 PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
421 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), 419 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
422 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), 420 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
423 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), 421 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
@@ -432,7 +430,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = {
432 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), 430 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
433 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), 431 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
434 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), 432 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
435 PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
436 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), 433 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
437 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), 434 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
438 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), 435 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
@@ -445,7 +442,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = {
445 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), 442 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
446 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), 443 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
447 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed), 444 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
448 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
449 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), 445 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
450 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), 446 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
451 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), 447 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
@@ -454,8 +450,11 @@ static struct pcmcia_device_id orinoco_cs_ids[] = {
454 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), 450 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
455 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), 451 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
456 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), 452 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
457 PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
458 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), 453 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
454 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
455 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
456 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
457 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
459 PCMCIA_DEVICE_NULL, 458 PCMCIA_DEVICE_NULL,
460}; 459};
461MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); 460MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 18012dbfb45d..4f752a21495f 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -33,21 +33,29 @@ MODULE_DESCRIPTION("Softmac Prism54 common code");
33MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
34MODULE_ALIAS("prism54common"); 34MODULE_ALIAS("prism54common");
35 35
36static int p54_sta_add_remove(struct ieee80211_hw *hw,
37 struct ieee80211_vif *vif,
38 struct ieee80211_sta *sta)
39{
40 struct p54_common *priv = hw->priv;
41
42 /*
43 * Notify the firmware that we don't want or we don't
44 * need to buffer frames for this station anymore.
45 */
46
47 p54_sta_unlock(priv, sta->addr);
48
49 return 0;
50}
51
36static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif, 52static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
37 enum sta_notify_cmd notify_cmd, 53 enum sta_notify_cmd notify_cmd,
38 struct ieee80211_sta *sta) 54 struct ieee80211_sta *sta)
39{ 55{
40 struct p54_common *priv = dev->priv; 56 struct p54_common *priv = dev->priv;
41 switch (notify_cmd) {
42 case STA_NOTIFY_ADD:
43 case STA_NOTIFY_REMOVE:
44 /*
45 * Notify the firmware that we don't want or we don't
46 * need to buffer frames for this station anymore.
47 */
48 57
49 p54_sta_unlock(priv, sta->addr); 58 switch (notify_cmd) {
50 break;
51 case STA_NOTIFY_AWAKE: 59 case STA_NOTIFY_AWAKE:
52 /* update the firmware's filter table */ 60 /* update the firmware's filter table */
53 p54_sta_unlock(priv, sta->addr); 61 p54_sta_unlock(priv, sta->addr);
@@ -216,7 +224,7 @@ static void p54_stop(struct ieee80211_hw *dev)
216} 224}
217 225
218static int p54_add_interface(struct ieee80211_hw *dev, 226static int p54_add_interface(struct ieee80211_hw *dev,
219 struct ieee80211_if_init_conf *conf) 227 struct ieee80211_vif *vif)
220{ 228{
221 struct p54_common *priv = dev->priv; 229 struct p54_common *priv = dev->priv;
222 230
@@ -226,28 +234,28 @@ static int p54_add_interface(struct ieee80211_hw *dev,
226 return -EOPNOTSUPP; 234 return -EOPNOTSUPP;
227 } 235 }
228 236
229 priv->vif = conf->vif; 237 priv->vif = vif;
230 238
231 switch (conf->type) { 239 switch (vif->type) {
232 case NL80211_IFTYPE_STATION: 240 case NL80211_IFTYPE_STATION:
233 case NL80211_IFTYPE_ADHOC: 241 case NL80211_IFTYPE_ADHOC:
234 case NL80211_IFTYPE_AP: 242 case NL80211_IFTYPE_AP:
235 case NL80211_IFTYPE_MESH_POINT: 243 case NL80211_IFTYPE_MESH_POINT:
236 priv->mode = conf->type; 244 priv->mode = vif->type;
237 break; 245 break;
238 default: 246 default:
239 mutex_unlock(&priv->conf_mutex); 247 mutex_unlock(&priv->conf_mutex);
240 return -EOPNOTSUPP; 248 return -EOPNOTSUPP;
241 } 249 }
242 250
243 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); 251 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
244 p54_setup_mac(priv); 252 p54_setup_mac(priv);
245 mutex_unlock(&priv->conf_mutex); 253 mutex_unlock(&priv->conf_mutex);
246 return 0; 254 return 0;
247} 255}
248 256
249static void p54_remove_interface(struct ieee80211_hw *dev, 257static void p54_remove_interface(struct ieee80211_hw *dev,
250 struct ieee80211_if_init_conf *conf) 258 struct ieee80211_vif *vif)
251{ 259{
252 struct p54_common *priv = dev->priv; 260 struct p54_common *priv = dev->priv;
253 261
@@ -358,16 +366,6 @@ static int p54_get_stats(struct ieee80211_hw *dev,
358 return 0; 366 return 0;
359} 367}
360 368
361static int p54_get_tx_stats(struct ieee80211_hw *dev,
362 struct ieee80211_tx_queue_stats *stats)
363{
364 struct p54_common *priv = dev->priv;
365
366 memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
367 sizeof(stats[0]) * dev->queues);
368 return 0;
369}
370
371static void p54_bss_info_changed(struct ieee80211_hw *dev, 369static void p54_bss_info_changed(struct ieee80211_hw *dev,
372 struct ieee80211_vif *vif, 370 struct ieee80211_vif *vif,
373 struct ieee80211_bss_conf *info, 371 struct ieee80211_bss_conf *info,
@@ -516,13 +514,14 @@ static const struct ieee80211_ops p54_ops = {
516 .remove_interface = p54_remove_interface, 514 .remove_interface = p54_remove_interface,
517 .set_tim = p54_set_tim, 515 .set_tim = p54_set_tim,
518 .sta_notify = p54_sta_notify, 516 .sta_notify = p54_sta_notify,
517 .sta_add = p54_sta_add_remove,
518 .sta_remove = p54_sta_add_remove,
519 .set_key = p54_set_key, 519 .set_key = p54_set_key,
520 .config = p54_config, 520 .config = p54_config,
521 .bss_info_changed = p54_bss_info_changed, 521 .bss_info_changed = p54_bss_info_changed,
522 .configure_filter = p54_configure_filter, 522 .configure_filter = p54_configure_filter,
523 .conf_tx = p54_conf_tx, 523 .conf_tx = p54_conf_tx,
524 .get_stats = p54_get_stats, 524 .get_stats = p54_get_stats,
525 .get_tx_stats = p54_get_tx_stats
526}; 525};
527 526
528struct ieee80211_hw *p54_init_common(size_t priv_data_len) 527struct ieee80211_hw *p54_init_common(size_t priv_data_len)
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 1afc39410e85..43a3b2ead81a 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -157,6 +157,12 @@ struct p54_led_dev {
157 157
158#endif /* CONFIG_P54_LEDS */ 158#endif /* CONFIG_P54_LEDS */
159 159
160struct p54_tx_queue_stats {
161 unsigned int len;
162 unsigned int limit;
163 unsigned int count;
164};
165
160struct p54_common { 166struct p54_common {
161 struct ieee80211_hw *hw; 167 struct ieee80211_hw *hw;
162 struct ieee80211_vif *vif; 168 struct ieee80211_vif *vif;
@@ -183,7 +189,7 @@ struct p54_common {
183 /* (e)DCF / QOS state */ 189 /* (e)DCF / QOS state */
184 bool use_short_slot; 190 bool use_short_slot;
185 spinlock_t tx_stats_lock; 191 spinlock_t tx_stats_lock;
186 struct ieee80211_tx_queue_stats tx_stats[8]; 192 struct p54_tx_queue_stats tx_stats[8];
187 struct p54_edcf_queue_param qos_params[8]; 193 struct p54_edcf_queue_param qos_params[8];
188 194
189 /* Radio data */ 195 /* Radio data */
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index a72f7c2577de..bda29c00f3ef 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
157 skb_tail_pointer(skb), 157 skb_tail_pointer(skb),
158 priv->common.rx_mtu + 32, 158 priv->common.rx_mtu + 32,
159 PCI_DMA_FROMDEVICE); 159 PCI_DMA_FROMDEVICE);
160
161 if (pci_dma_mapping_error(priv->pdev, mapping)) {
162 dev_kfree_skb_any(skb);
163 dev_err(&priv->pdev->dev,
164 "RX DMA Mapping error\n");
165 break;
166 }
167
160 desc->host_addr = cpu_to_le32(mapping); 168 desc->host_addr = cpu_to_le32(mapping);
161 desc->device_addr = 0; // FIXME: necessary? 169 desc->device_addr = 0; // FIXME: necessary?
162 desc->len = cpu_to_le16(priv->common.rx_mtu + 32); 170 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
@@ -226,14 +234,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
226 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf); 234 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
227} 235}
228 236
229/* caller must hold priv->lock */
230static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, 237static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
231 int ring_index, struct p54p_desc *ring, u32 ring_limit, 238 int ring_index, struct p54p_desc *ring, u32 ring_limit,
232 void **tx_buf) 239 struct sk_buff **tx_buf)
233{ 240{
234 struct p54p_priv *priv = dev->priv; 241 struct p54p_priv *priv = dev->priv;
235 struct p54p_ring_control *ring_control = priv->ring_control; 242 struct p54p_ring_control *ring_control = priv->ring_control;
236 struct p54p_desc *desc; 243 struct p54p_desc *desc;
244 struct sk_buff *skb;
237 u32 idx, i; 245 u32 idx, i;
238 246
239 i = (*index) % ring_limit; 247 i = (*index) % ring_limit;
@@ -242,9 +250,8 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
242 250
243 while (i != idx) { 251 while (i != idx) {
244 desc = &ring[i]; 252 desc = &ring[i];
245 if (tx_buf[i]) 253
246 if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i])) 254 skb = tx_buf[i];
247 p54_free_skb(dev, tx_buf[i]);
248 tx_buf[i] = NULL; 255 tx_buf[i] = NULL;
249 256
250 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), 257 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -255,17 +262,28 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
255 desc->len = 0; 262 desc->len = 0;
256 desc->flags = 0; 263 desc->flags = 0;
257 264
265 if (skb && FREE_AFTER_TX(skb))
266 p54_free_skb(dev, skb);
267
258 i++; 268 i++;
259 i %= ring_limit; 269 i %= ring_limit;
260 } 270 }
261} 271}
262 272
263static void p54p_rx_tasklet(unsigned long dev_id) 273static void p54p_tasklet(unsigned long dev_id)
264{ 274{
265 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id; 275 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
266 struct p54p_priv *priv = dev->priv; 276 struct p54p_priv *priv = dev->priv;
267 struct p54p_ring_control *ring_control = priv->ring_control; 277 struct p54p_ring_control *ring_control = priv->ring_control;
268 278
279 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
280 ARRAY_SIZE(ring_control->tx_mgmt),
281 priv->tx_buf_mgmt);
282
283 p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
284 ARRAY_SIZE(ring_control->tx_data),
285 priv->tx_buf_data);
286
269 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, 287 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
270 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); 288 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
271 289
@@ -280,59 +298,49 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
280{ 298{
281 struct ieee80211_hw *dev = dev_id; 299 struct ieee80211_hw *dev = dev_id;
282 struct p54p_priv *priv = dev->priv; 300 struct p54p_priv *priv = dev->priv;
283 struct p54p_ring_control *ring_control = priv->ring_control;
284 __le32 reg; 301 __le32 reg;
285 302
286 spin_lock(&priv->lock);
287 reg = P54P_READ(int_ident); 303 reg = P54P_READ(int_ident);
288 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { 304 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
289 spin_unlock(&priv->lock); 305 goto out;
290 return IRQ_HANDLED;
291 } 306 }
292
293 P54P_WRITE(int_ack, reg); 307 P54P_WRITE(int_ack, reg);
294 308
295 reg &= P54P_READ(int_enable); 309 reg &= P54P_READ(int_enable);
296 310
297 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { 311 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
298 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 312 tasklet_schedule(&priv->tasklet);
299 3, ring_control->tx_mgmt, 313 else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
300 ARRAY_SIZE(ring_control->tx_mgmt),
301 priv->tx_buf_mgmt);
302
303 p54p_check_tx_ring(dev, &priv->tx_idx_data,
304 1, ring_control->tx_data,
305 ARRAY_SIZE(ring_control->tx_data),
306 priv->tx_buf_data);
307
308 tasklet_schedule(&priv->rx_tasklet);
309
310 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
311 complete(&priv->boot_comp); 314 complete(&priv->boot_comp);
312 315
313 spin_unlock(&priv->lock); 316out:
314
315 return reg ? IRQ_HANDLED : IRQ_NONE; 317 return reg ? IRQ_HANDLED : IRQ_NONE;
316} 318}
317 319
318static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 320static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
319{ 321{
322 unsigned long flags;
320 struct p54p_priv *priv = dev->priv; 323 struct p54p_priv *priv = dev->priv;
321 struct p54p_ring_control *ring_control = priv->ring_control; 324 struct p54p_ring_control *ring_control = priv->ring_control;
322 unsigned long flags;
323 struct p54p_desc *desc; 325 struct p54p_desc *desc;
324 dma_addr_t mapping; 326 dma_addr_t mapping;
325 u32 device_idx, idx, i; 327 u32 device_idx, idx, i;
326 328
327 spin_lock_irqsave(&priv->lock, flags); 329 spin_lock_irqsave(&priv->lock, flags);
328
329 device_idx = le32_to_cpu(ring_control->device_idx[1]); 330 device_idx = le32_to_cpu(ring_control->device_idx[1]);
330 idx = le32_to_cpu(ring_control->host_idx[1]); 331 idx = le32_to_cpu(ring_control->host_idx[1]);
331 i = idx % ARRAY_SIZE(ring_control->tx_data); 332 i = idx % ARRAY_SIZE(ring_control->tx_data);
332 333
333 priv->tx_buf_data[i] = skb;
334 mapping = pci_map_single(priv->pdev, skb->data, skb->len, 334 mapping = pci_map_single(priv->pdev, skb->data, skb->len,
335 PCI_DMA_TODEVICE); 335 PCI_DMA_TODEVICE);
336 if (pci_dma_mapping_error(priv->pdev, mapping)) {
337 spin_unlock_irqrestore(&priv->lock, flags);
338 p54_free_skb(dev, skb);
339 dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
340 return ;
341 }
342 priv->tx_buf_data[i] = skb;
343
336 desc = &ring_control->tx_data[i]; 344 desc = &ring_control->tx_data[i];
337 desc->host_addr = cpu_to_le32(mapping); 345 desc->host_addr = cpu_to_le32(mapping);
338 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; 346 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
@@ -354,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev)
354 unsigned int i; 362 unsigned int i;
355 struct p54p_desc *desc; 363 struct p54p_desc *desc;
356 364
357 tasklet_kill(&priv->rx_tasklet);
358
359 P54P_WRITE(int_enable, cpu_to_le32(0)); 365 P54P_WRITE(int_enable, cpu_to_le32(0));
360 P54P_READ(int_enable); 366 P54P_READ(int_enable);
361 udelay(10); 367 udelay(10);
362 368
363 free_irq(priv->pdev->irq, dev); 369 free_irq(priv->pdev->irq, dev);
364 370
371 tasklet_kill(&priv->tasklet);
372
365 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 373 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
366 374
367 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) { 375 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
@@ -545,7 +553,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
545 priv->common.tx = p54p_tx; 553 priv->common.tx = p54p_tx;
546 554
547 spin_lock_init(&priv->lock); 555 spin_lock_init(&priv->lock);
548 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); 556 tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
549 557
550 err = request_firmware(&priv->firmware, "isl3886pci", 558 err = request_firmware(&priv->firmware, "isl3886pci",
551 &priv->pdev->dev); 559 &priv->pdev->dev);
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h
index fbb683953fb2..2feead617a3b 100644
--- a/drivers/net/wireless/p54/p54pci.h
+++ b/drivers/net/wireless/p54/p54pci.h
@@ -92,7 +92,7 @@ struct p54p_priv {
92 struct p54_common common; 92 struct p54_common common;
93 struct pci_dev *pdev; 93 struct pci_dev *pdev;
94 struct p54p_csr __iomem *map; 94 struct p54p_csr __iomem *map;
95 struct tasklet_struct rx_tasklet; 95 struct tasklet_struct tasklet;
96 const struct firmware *firmware; 96 const struct firmware *firmware;
97 spinlock_t lock; 97 spinlock_t lock;
98 struct p54p_ring_control *ring_control; 98 struct p54p_ring_control *ring_control;
@@ -101,8 +101,8 @@ struct p54p_priv {
101 u32 rx_idx_mgmt, tx_idx_mgmt; 101 u32 rx_idx_mgmt, tx_idx_mgmt;
102 struct sk_buff *rx_buf_data[8]; 102 struct sk_buff *rx_buf_data[8];
103 struct sk_buff *rx_buf_mgmt[4]; 103 struct sk_buff *rx_buf_mgmt[4];
104 void *tx_buf_data[32]; 104 struct sk_buff *tx_buf_data[32];
105 void *tx_buf_mgmt[4]; 105 struct sk_buff *tx_buf_mgmt[4];
106 struct completion boot_comp; 106 struct completion boot_comp;
107}; 107};
108 108
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 92af9b96bb7a..b3c4fbd80d8d 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -36,6 +36,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
36 /* Version 1 devices (pci chip + net2280) */ 36 /* Version 1 devices (pci chip + net2280) */
37 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ 37 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
38 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ 38 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
39 {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
39 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ 40 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
40 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */ 41 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
41 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */ 42 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
@@ -60,6 +61,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
60 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ 61 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
61 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ 62 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
62 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ 63 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
64 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
63 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ 65 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
64 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ 66 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
65 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ 67 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index b6dda2b27fb5..66057999a93c 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -183,10 +183,10 @@ static int p54_tx_qos_accounting_alloc(struct p54_common *priv,
183 struct sk_buff *skb, 183 struct sk_buff *skb,
184 const u16 p54_queue) 184 const u16 p54_queue)
185{ 185{
186 struct ieee80211_tx_queue_stats *queue; 186 struct p54_tx_queue_stats *queue;
187 unsigned long flags; 187 unsigned long flags;
188 188
189 if (WARN_ON(p54_queue > P54_QUEUE_NUM)) 189 if (WARN_ON(p54_queue >= P54_QUEUE_NUM))
190 return -EINVAL; 190 return -EINVAL;
191 191
192 queue = &priv->tx_stats[p54_queue]; 192 queue = &priv->tx_stats[p54_queue];
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2ecbedb26e15..305c106fdc1c 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2594,23 +2594,9 @@ end:
2594/* 2594/*
2595 * driver/device initialization 2595 * driver/device initialization
2596 */ 2596 */
2597static int bcm4320a_early_init(struct usbnet *usbdev) 2597static void rndis_copy_module_params(struct usbnet *usbdev)
2598{
2599 /* bcm4320a doesn't handle configuration parameters well. Try
2600 * set any and you get partially zeroed mac and broken device.
2601 */
2602
2603 return 0;
2604}
2605
2606static int bcm4320b_early_init(struct usbnet *usbdev)
2607{ 2598{
2608 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2599 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2609 char buf[8];
2610
2611 /* Early initialization settings, setting these won't have effect
2612 * if called after generic_rndis_bind().
2613 */
2614 2600
2615 priv->param_country[0] = modparam_country[0]; 2601 priv->param_country[0] = modparam_country[0];
2616 priv->param_country[1] = modparam_country[1]; 2602 priv->param_country[1] = modparam_country[1];
@@ -2652,6 +2638,32 @@ static int bcm4320b_early_init(struct usbnet *usbdev)
2652 priv->param_workaround_interval = 500; 2638 priv->param_workaround_interval = 500;
2653 else 2639 else
2654 priv->param_workaround_interval = modparam_workaround_interval; 2640 priv->param_workaround_interval = modparam_workaround_interval;
2641}
2642
2643static int bcm4320a_early_init(struct usbnet *usbdev)
2644{
2645 /* copy module parameters for bcm4320a so that iwconfig reports txpower
2646 * and workaround parameter is copied to private structure correctly.
2647 */
2648 rndis_copy_module_params(usbdev);
2649
2650 /* bcm4320a doesn't handle configuration parameters well. Try
2651 * set any and you get partially zeroed mac and broken device.
2652 */
2653
2654 return 0;
2655}
2656
2657static int bcm4320b_early_init(struct usbnet *usbdev)
2658{
2659 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2660 char buf[8];
2661
2662 rndis_copy_module_params(usbdev);
2663
2664 /* Early initialization settings, setting these won't have effect
2665 * if called after generic_rndis_bind().
2666 */
2655 2667
2656 rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); 2668 rndis_set_config_parameter_str(usbdev, "Country", priv->param_country);
2657 rndis_set_config_parameter_str(usbdev, "FrameBursting", 2669 rndis_set_config_parameter_str(usbdev, "FrameBursting",
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index bf60689aaabb..5239e082cd0f 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -54,17 +54,17 @@ config RT61PCI
54 When compiled as a module, this driver will be called rt61pci. 54 When compiled as a module, this driver will be called rt61pci.
55 55
56config RT2800PCI_PCI 56config RT2800PCI_PCI
57 tristate 57 boolean
58 depends on PCI 58 depends on PCI
59 default y 59 default y
60 60
61config RT2800PCI_SOC 61config RT2800PCI_SOC
62 tristate 62 boolean
63 depends on RALINK_RT288X || RALINK_RT305X 63 depends on RALINK_RT288X || RALINK_RT305X
64 default y 64 default y
65 65
66config RT2800PCI 66config RT2800PCI
67 tristate "Ralink rt2800 (PCI/PCMCIA) support (VERY EXPERIMENTAL)" 67 tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)"
68 depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL 68 depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL
69 select RT2800_LIB 69 select RT2800_LIB
70 select RT2X00_LIB_PCI if RT2800PCI_PCI 70 select RT2X00_LIB_PCI if RT2800PCI_PCI
@@ -75,7 +75,7 @@ config RT2800PCI
75 select CRC_CCITT 75 select CRC_CCITT
76 select EEPROM_93CX6 76 select EEPROM_93CX6
77 ---help--- 77 ---help---
78 This adds support for rt2800 wireless chipset family. 78 This adds support for rt2800/rt3000/rt3500 wireless chipset family.
79 Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052 79 Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052
80 80
81 This driver is non-functional at the moment and is intended for 81 This driver is non-functional at the moment and is intended for
@@ -83,6 +83,32 @@ config RT2800PCI
83 83
84 When compiled as a module, this driver will be called "rt2800pci.ko". 84 When compiled as a module, this driver will be called "rt2800pci.ko".
85 85
86if RT2800PCI
87
88config RT2800PCI_RT30XX
89 bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"
90 default n
91 ---help---
92 This adds support for rt30xx wireless chipset family to the
93 rt2800pci driver.
94 Supported chips: RT3090, RT3091 & RT3092
95
96 Support for these devices is non-functional at the moment and is
97 intended for testers and developers.
98
99config RT2800PCI_RT35XX
100 bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices"
101 default n
102 ---help---
103 This adds support for rt35xx wireless chipset family to the
104 rt2800pci driver.
105 Supported chips: RT3060, RT3062, RT3562, RT3592
106
107 Support for these devices is non-functional at the moment and is
108 intended for testers and developers.
109
110endif
111
86config RT2500USB 112config RT2500USB
87 tristate "Ralink rt2500 (USB) support" 113 tristate "Ralink rt2500 (USB) support"
88 depends on USB 114 depends on USB
@@ -126,6 +152,43 @@ config RT2800USB
126 152
127 When compiled as a module, this driver will be called "rt2800usb.ko". 153 When compiled as a module, this driver will be called "rt2800usb.ko".
128 154
155if RT2800USB
156
157config RT2800USB_RT30XX
158 bool "rt2800usb - Include support for rt30xx (USB) devices"
159 default n
160 ---help---
161 This adds support for rt30xx wireless chipset family to the
162 rt2800usb driver.
163 Supported chips: RT3070, RT3071 & RT3072
164
165 Support for these devices is non-functional at the moment and is
166 intended for testers and developers.
167
168config RT2800USB_RT35XX
169 bool "rt2800usb - Include support for rt35xx (USB) devices"
170 default n
171 ---help---
172 This adds support for rt35xx wireless chipset family to the
173 rt2800usb driver.
174 Supported chips: RT3572
175
176 Support for these devices is non-functional at the moment and is
177 intended for testers and developers.
178
179config RT2800USB_UNKNOWN
180 bool "rt2800usb - Include support for unknown (USB) devices"
181 default n
182 ---help---
183 This adds support for rt2800 family devices that are known to
184 have a rt2800 family chipset, but for which the exact chipset
185 is unknown.
186
187 Support status for these devices is unknown, and enabling these
188 devices may or may not work.
189
190endif
191
129config RT2800_LIB 192config RT2800_LIB
130 tristate 193 tristate
131 194
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index e7f46405a418..676814d3a81b 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -451,7 +451,7 @@ static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev,
451 /* 451 /*
452 * RF2420 chipset don't need any additional actions. 452 * RF2420 chipset don't need any additional actions.
453 */ 453 */
454 if (rt2x00_rf(&rt2x00dev->chip, RF2420)) 454 if (rt2x00_rf(rt2x00dev, RF2420))
455 return; 455 return;
456 456
457 /* 457 /*
@@ -1340,11 +1340,10 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1340 */ 1340 */
1341 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 1341 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
1342 rt2x00pci_register_read(rt2x00dev, CSR0, &reg); 1342 rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
1343 rt2x00_set_chip_rf(rt2x00dev, value, reg); 1343 rt2x00_set_chip(rt2x00dev, RT2460, value,
1344 rt2x00_print_chip(rt2x00dev); 1344 rt2x00_get_field32(reg, CSR0_REVISION));
1345 1345
1346 if (!rt2x00_rf(&rt2x00dev->chip, RF2420) && 1346 if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) {
1347 !rt2x00_rf(&rt2x00dev->chip, RF2421)) {
1348 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1347 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1349 return -ENODEV; 1348 return -ENODEV;
1350 } 1349 }
@@ -1562,7 +1561,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1562 .get_stats = rt2x00mac_get_stats, 1561 .get_stats = rt2x00mac_get_stats,
1563 .bss_info_changed = rt2x00mac_bss_info_changed, 1562 .bss_info_changed = rt2x00mac_bss_info_changed,
1564 .conf_tx = rt2400pci_conf_tx, 1563 .conf_tx = rt2400pci_conf_tx,
1565 .get_tx_stats = rt2x00mac_get_tx_stats,
1566 .get_tsf = rt2400pci_get_tsf, 1564 .get_tsf = rt2400pci_get_tsf,
1567 .tx_last_beacon = rt2400pci_tx_last_beacon, 1565 .tx_last_beacon = rt2400pci_tx_last_beacon,
1568 .rfkill_poll = rt2x00mac_rfkill_poll, 1566 .rfkill_poll = rt2x00mac_rfkill_poll,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index 6c21ef66dfe0..606137738848 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -65,6 +65,7 @@
65 * CSR0: ASIC revision number. 65 * CSR0: ASIC revision number.
66 */ 66 */
67#define CSR0 0x0000 67#define CSR0 0x0000
68#define CSR0_REVISION FIELD32(0x0000ffff)
68 69
69/* 70/*
70 * CSR1: System control register. 71 * CSR1: System control register.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 408fcfc120f5..c71266142ae9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -440,8 +440,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
440 /* 440 /*
441 * RT2525E and RT5222 need to flip TX I/Q 441 * RT2525E and RT5222 need to flip TX I/Q
442 */ 442 */
443 if (rt2x00_rf(&rt2x00dev->chip, RF2525E) || 443 if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
444 rt2x00_rf(&rt2x00dev->chip, RF5222)) {
445 rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1); 444 rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
446 rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1); 445 rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
447 rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1); 446 rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
@@ -449,7 +448,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
449 /* 448 /*
450 * RT2525E does not need RX I/Q Flip. 449 * RT2525E does not need RX I/Q Flip.
451 */ 450 */
452 if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) 451 if (rt2x00_rf(rt2x00dev, RF2525E))
453 rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0); 452 rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
454 } else { 453 } else {
455 rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0); 454 rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
@@ -475,14 +474,14 @@ static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
475 * Switch on tuning bits. 474 * Switch on tuning bits.
476 * For RT2523 devices we do not need to update the R1 register. 475 * For RT2523 devices we do not need to update the R1 register.
477 */ 476 */
478 if (!rt2x00_rf(&rt2x00dev->chip, RF2523)) 477 if (!rt2x00_rf(rt2x00dev, RF2523))
479 rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1); 478 rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1);
480 rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1); 479 rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1);
481 480
482 /* 481 /*
483 * For RT2525 we should first set the channel to half band higher. 482 * For RT2525 we should first set the channel to half band higher.
484 */ 483 */
485 if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { 484 if (rt2x00_rf(rt2x00dev, RF2525)) {
486 static const u32 vals[] = { 485 static const u32 vals[] = {
487 0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a, 486 0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a,
488 0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a, 487 0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a,
@@ -516,7 +515,7 @@ static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
516 * Switch off tuning bits. 515 * Switch off tuning bits.
517 * For RT2523 devices we do not need to update the R1 register. 516 * For RT2523 devices we do not need to update the R1 register.
518 */ 517 */
519 if (!rt2x00_rf(&rt2x00dev->chip, RF2523)) { 518 if (!rt2x00_rf(rt2x00dev, RF2523)) {
520 rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0); 519 rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0);
521 rt2500pci_rf_write(rt2x00dev, 1, rf->rf1); 520 rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
522 } 521 }
@@ -640,7 +639,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
640 * up to version C the link tuning should halt after 20 639 * up to version C the link tuning should halt after 20
641 * seconds while being associated. 640 * seconds while being associated.
642 */ 641 */
643 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && 642 if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D &&
644 rt2x00dev->intf_associated && count > 20) 643 rt2x00dev->intf_associated && count > 20)
645 return; 644 return;
646 645
@@ -650,7 +649,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
650 * should go straight to dynamic CCA tuning when they 649 * should go straight to dynamic CCA tuning when they
651 * are not associated. 650 * are not associated.
652 */ 651 */
653 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || 652 if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D ||
654 !rt2x00dev->intf_associated) 653 !rt2x00dev->intf_associated)
655 goto dynamic_cca_tune; 654 goto dynamic_cca_tune;
656 655
@@ -1504,15 +1503,15 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1504 */ 1503 */
1505 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 1504 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
1506 rt2x00pci_register_read(rt2x00dev, CSR0, &reg); 1505 rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
1507 rt2x00_set_chip_rf(rt2x00dev, value, reg); 1506 rt2x00_set_chip(rt2x00dev, RT2560, value,
1508 rt2x00_print_chip(rt2x00dev); 1507 rt2x00_get_field32(reg, CSR0_REVISION));
1509 1508
1510 if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && 1509 if (!rt2x00_rf(rt2x00dev, RF2522) &&
1511 !rt2x00_rf(&rt2x00dev->chip, RF2523) && 1510 !rt2x00_rf(rt2x00dev, RF2523) &&
1512 !rt2x00_rf(&rt2x00dev->chip, RF2524) && 1511 !rt2x00_rf(rt2x00dev, RF2524) &&
1513 !rt2x00_rf(&rt2x00dev->chip, RF2525) && 1512 !rt2x00_rf(rt2x00dev, RF2525) &&
1514 !rt2x00_rf(&rt2x00dev->chip, RF2525E) && 1513 !rt2x00_rf(rt2x00dev, RF2525E) &&
1515 !rt2x00_rf(&rt2x00dev->chip, RF5222)) { 1514 !rt2x00_rf(rt2x00dev, RF5222)) {
1516 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1515 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1517 return -ENODEV; 1516 return -ENODEV;
1518 } 1517 }
@@ -1744,22 +1743,22 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1744 spec->supported_bands = SUPPORT_BAND_2GHZ; 1743 spec->supported_bands = SUPPORT_BAND_2GHZ;
1745 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 1744 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
1746 1745
1747 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { 1746 if (rt2x00_rf(rt2x00dev, RF2522)) {
1748 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); 1747 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
1749 spec->channels = rf_vals_bg_2522; 1748 spec->channels = rf_vals_bg_2522;
1750 } else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) { 1749 } else if (rt2x00_rf(rt2x00dev, RF2523)) {
1751 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523); 1750 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
1752 spec->channels = rf_vals_bg_2523; 1751 spec->channels = rf_vals_bg_2523;
1753 } else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) { 1752 } else if (rt2x00_rf(rt2x00dev, RF2524)) {
1754 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524); 1753 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
1755 spec->channels = rf_vals_bg_2524; 1754 spec->channels = rf_vals_bg_2524;
1756 } else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { 1755 } else if (rt2x00_rf(rt2x00dev, RF2525)) {
1757 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525); 1756 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
1758 spec->channels = rf_vals_bg_2525; 1757 spec->channels = rf_vals_bg_2525;
1759 } else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { 1758 } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
1760 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); 1759 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
1761 spec->channels = rf_vals_bg_2525e; 1760 spec->channels = rf_vals_bg_2525e;
1762 } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { 1761 } else if (rt2x00_rf(rt2x00dev, RF5222)) {
1763 spec->supported_bands |= SUPPORT_BAND_5GHZ; 1762 spec->supported_bands |= SUPPORT_BAND_5GHZ;
1764 spec->num_channels = ARRAY_SIZE(rf_vals_5222); 1763 spec->num_channels = ARRAY_SIZE(rf_vals_5222);
1765 spec->channels = rf_vals_5222; 1764 spec->channels = rf_vals_5222;
@@ -1860,7 +1859,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1860 .get_stats = rt2x00mac_get_stats, 1859 .get_stats = rt2x00mac_get_stats,
1861 .bss_info_changed = rt2x00mac_bss_info_changed, 1860 .bss_info_changed = rt2x00mac_bss_info_changed,
1862 .conf_tx = rt2x00mac_conf_tx, 1861 .conf_tx = rt2x00mac_conf_tx,
1863 .get_tx_stats = rt2x00mac_get_tx_stats,
1864 .get_tsf = rt2500pci_get_tsf, 1862 .get_tsf = rt2500pci_get_tsf,
1865 .tx_last_beacon = rt2500pci_tx_last_beacon, 1863 .tx_last_beacon = rt2500pci_tx_last_beacon,
1866 .rfkill_poll = rt2x00mac_rfkill_poll, 1864 .rfkill_poll = rt2x00mac_rfkill_poll,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index b0075674c09b..6471f8e74b35 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -76,6 +76,7 @@
76 * CSR0: ASIC revision number. 76 * CSR0: ASIC revision number.
77 */ 77 */
78#define CSR0 0x0000 78#define CSR0 0x0000
79#define CSR0_REVISION FIELD32(0x0000ffff)
79 80
80/* 81/*
81 * CSR1: System control register. 82 * CSR1: System control register.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 83f2592c59de..ee34c137e7cd 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -565,8 +565,7 @@ static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
565 /* 565 /*
566 * RT2525E and RT5222 need to flip TX I/Q 566 * RT2525E and RT5222 need to flip TX I/Q
567 */ 567 */
568 if (rt2x00_rf(&rt2x00dev->chip, RF2525E) || 568 if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
569 rt2x00_rf(&rt2x00dev->chip, RF5222)) {
570 rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1); 569 rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
571 rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 1); 570 rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 1);
572 rt2x00_set_field16(&csr6, PHY_CSR6_OFDM_FLIP, 1); 571 rt2x00_set_field16(&csr6, PHY_CSR6_OFDM_FLIP, 1);
@@ -574,7 +573,7 @@ static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
574 /* 573 /*
575 * RT2525E does not need RX I/Q Flip. 574 * RT2525E does not need RX I/Q Flip.
576 */ 575 */
577 if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) 576 if (rt2x00_rf(rt2x00dev, RF2525E))
578 rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0); 577 rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
579 } else { 578 } else {
580 rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 0); 579 rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 0);
@@ -598,7 +597,7 @@ static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
598 /* 597 /*
599 * For RT2525E we should first set the channel to half band higher. 598 * For RT2525E we should first set the channel to half band higher.
600 */ 599 */
601 if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { 600 if (rt2x00_rf(rt2x00dev, RF2525E)) {
602 static const u32 vals[] = { 601 static const u32 vals[] = {
603 0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2, 602 0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
604 0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba, 603 0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
@@ -793,7 +792,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
793 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1); 792 rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
794 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); 793 rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
795 794
796 if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) { 795 if (rt2x00_rev(rt2x00dev) >= RT2570_VERSION_C) {
797 rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg); 796 rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
798 rt2x00_set_field16(&reg, PHY_CSR2_LNA, 0); 797 rt2x00_set_field16(&reg, PHY_CSR2_LNA, 0);
799 } else { 798 } else {
@@ -1409,21 +1408,18 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1409 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 1408 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
1410 rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg); 1409 rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
1411 rt2x00_set_chip(rt2x00dev, RT2570, value, reg); 1410 rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
1412 rt2x00_print_chip(rt2x00dev);
1413
1414 if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) ||
1415 rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
1416 1411
1412 if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) {
1417 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1413 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1418 return -ENODEV; 1414 return -ENODEV;
1419 } 1415 }
1420 1416
1421 if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && 1417 if (!rt2x00_rf(rt2x00dev, RF2522) &&
1422 !rt2x00_rf(&rt2x00dev->chip, RF2523) && 1418 !rt2x00_rf(rt2x00dev, RF2523) &&
1423 !rt2x00_rf(&rt2x00dev->chip, RF2524) && 1419 !rt2x00_rf(rt2x00dev, RF2524) &&
1424 !rt2x00_rf(&rt2x00dev->chip, RF2525) && 1420 !rt2x00_rf(rt2x00dev, RF2525) &&
1425 !rt2x00_rf(&rt2x00dev->chip, RF2525E) && 1421 !rt2x00_rf(rt2x00dev, RF2525E) &&
1426 !rt2x00_rf(&rt2x00dev->chip, RF5222)) { 1422 !rt2x00_rf(rt2x00dev, RF5222)) {
1427 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1423 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1428 return -ENODEV; 1424 return -ENODEV;
1429 } 1425 }
@@ -1667,22 +1663,22 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1667 spec->supported_bands = SUPPORT_BAND_2GHZ; 1663 spec->supported_bands = SUPPORT_BAND_2GHZ;
1668 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 1664 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
1669 1665
1670 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { 1666 if (rt2x00_rf(rt2x00dev, RF2522)) {
1671 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); 1667 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
1672 spec->channels = rf_vals_bg_2522; 1668 spec->channels = rf_vals_bg_2522;
1673 } else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) { 1669 } else if (rt2x00_rf(rt2x00dev, RF2523)) {
1674 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523); 1670 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
1675 spec->channels = rf_vals_bg_2523; 1671 spec->channels = rf_vals_bg_2523;
1676 } else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) { 1672 } else if (rt2x00_rf(rt2x00dev, RF2524)) {
1677 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524); 1673 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
1678 spec->channels = rf_vals_bg_2524; 1674 spec->channels = rf_vals_bg_2524;
1679 } else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { 1675 } else if (rt2x00_rf(rt2x00dev, RF2525)) {
1680 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525); 1676 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
1681 spec->channels = rf_vals_bg_2525; 1677 spec->channels = rf_vals_bg_2525;
1682 } else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { 1678 } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
1683 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); 1679 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
1684 spec->channels = rf_vals_bg_2525e; 1680 spec->channels = rf_vals_bg_2525e;
1685 } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { 1681 } else if (rt2x00_rf(rt2x00dev, RF5222)) {
1686 spec->supported_bands |= SUPPORT_BAND_5GHZ; 1682 spec->supported_bands |= SUPPORT_BAND_5GHZ;
1687 spec->num_channels = ARRAY_SIZE(rf_vals_5222); 1683 spec->num_channels = ARRAY_SIZE(rf_vals_5222);
1688 spec->channels = rf_vals_5222; 1684 spec->channels = rf_vals_5222;
@@ -1763,7 +1759,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1763 .get_stats = rt2x00mac_get_stats, 1759 .get_stats = rt2x00mac_get_stats,
1764 .bss_info_changed = rt2x00mac_bss_info_changed, 1760 .bss_info_changed = rt2x00mac_bss_info_changed,
1765 .conf_tx = rt2x00mac_conf_tx, 1761 .conf_tx = rt2x00mac_conf_tx,
1766 .get_tx_stats = rt2x00mac_get_tx_stats,
1767 .rfkill_poll = rt2x00mac_rfkill_poll, 1762 .rfkill_poll = rt2x00mac_rfkill_poll,
1768}; 1763};
1769 1764
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 1a7eae357fef..74c0433dba37 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -60,11 +60,11 @@
60/* 60/*
61 * Chipset version. 61 * Chipset version.
62 */ 62 */
63#define RT2860C_VERSION 0x28600100 63#define RT2860C_VERSION 0x0100
64#define RT2860D_VERSION 0x28600101 64#define RT2860D_VERSION 0x0101
65#define RT2880E_VERSION 0x28720200 65#define RT2880E_VERSION 0x0200
66#define RT2883_VERSION 0x28830300 66#define RT2883_VERSION 0x0300
67#define RT3070_VERSION 0x30700200 67#define RT3070_VERSION 0x0200
68 68
69/* 69/*
70 * Signal information. 70 * Signal information.
@@ -408,8 +408,8 @@
408 * ASIC_VER: 2860 or 2870 408 * ASIC_VER: 2860 or 2870
409 */ 409 */
410#define MAC_CSR0 0x1000 410#define MAC_CSR0 0x1000
411#define MAC_CSR0_ASIC_REV FIELD32(0x0000ffff) 411#define MAC_CSR0_REVISION FIELD32(0x0000ffff)
412#define MAC_CSR0_ASIC_VER FIELD32(0xffff0000) 412#define MAC_CSR0_CHIPSET FIELD32(0xffff0000)
413 413
414/* 414/*
415 * MAC_SYS_CTRL: 415 * MAC_SYS_CTRL:
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 9deae41cb784..18d4d8e4ae6b 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -37,9 +37,12 @@
37#include <linux/module.h> 37#include <linux/module.h>
38 38
39#include "rt2x00.h" 39#include "rt2x00.h"
40#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) 40#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
41#include "rt2x00usb.h" 41#include "rt2x00usb.h"
42#endif 42#endif
43#if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE)
44#include "rt2x00pci.h"
45#endif
43#include "rt2800lib.h" 46#include "rt2800lib.h"
44#include "rt2800.h" 47#include "rt2800.h"
45#include "rt2800usb.h" 48#include "rt2800usb.h"
@@ -89,7 +92,7 @@ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
89 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word); 92 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
90 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1); 93 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
91 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0); 94 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
92 if (rt2x00_intf_is_pci(rt2x00dev)) 95 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
93 rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 96 rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
94 97
95 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); 98 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
@@ -118,7 +121,7 @@ static void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev,
118 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word); 121 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
119 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1); 122 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
120 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1); 123 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
121 if (rt2x00_intf_is_pci(rt2x00dev)) 124 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
122 rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 125 rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
123 126
124 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); 127 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
@@ -218,10 +221,9 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
218 u32 reg; 221 u32 reg;
219 222
220 /* 223 /*
221 * RT2880 and RT3052 don't support MCU requests. 224 * SOC devices don't support MCU requests.
222 */ 225 */
223 if (rt2x00_rt(&rt2x00dev->chip, RT2880) || 226 if (rt2x00_is_soc(rt2x00dev))
224 rt2x00_rt(&rt2x00dev->chip, RT3052))
225 return; 227 return;
226 228
227 mutex_lock(&rt2x00dev->csr_mutex); 229 mutex_lock(&rt2x00dev->csr_mutex);
@@ -246,6 +248,25 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
246} 248}
247EXPORT_SYMBOL_GPL(rt2800_mcu_request); 249EXPORT_SYMBOL_GPL(rt2800_mcu_request);
248 250
251int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
252{
253 unsigned int i;
254 u32 reg;
255
256 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
257 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
258 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
259 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
260 return 0;
261
262 msleep(1);
263 }
264
265 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
266 return -EACCES;
267}
268EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
269
249#ifdef CONFIG_RT2X00_LIB_DEBUGFS 270#ifdef CONFIG_RT2X00_LIB_DEBUGFS
250const struct rt2x00debug rt2800_rt2x00debug = { 271const struct rt2x00debug rt2800_rt2x00debug = {
251 .owner = THIS_MODULE, 272 .owner = THIS_MODULE,
@@ -348,7 +369,7 @@ static int rt2800_blink_set(struct led_classdev *led_cdev,
348 return 0; 369 return 0;
349} 370}
350 371
351void rt2800_init_led(struct rt2x00_dev *rt2x00dev, 372static void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
352 struct rt2x00_led *led, enum led_type type) 373 struct rt2x00_led *led, enum led_type type)
353{ 374{
354 led->rt2x00dev = rt2x00dev; 375 led->rt2x00dev = rt2x00dev;
@@ -357,7 +378,6 @@ void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
357 led->led_dev.blink_set = rt2800_blink_set; 378 led->led_dev.blink_set = rt2800_blink_set;
358 led->flags = LED_INITIALIZED; 379 led->flags = LED_INITIALIZED;
359} 380}
360EXPORT_SYMBOL_GPL(rt2800_init_led);
361#endif /* CONFIG_RT2X00_LIB_LEDS */ 381#endif /* CONFIG_RT2X00_LIB_LEDS */
362 382
363/* 383/*
@@ -643,7 +663,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
643 switch ((int)ant->tx) { 663 switch ((int)ant->tx) {
644 case 1: 664 case 1:
645 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); 665 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
646 if (rt2x00_intf_is_pci(rt2x00dev)) 666 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
647 rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); 667 rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
648 break; 668 break;
649 case 2: 669 case 2:
@@ -806,12 +826,12 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
806 unsigned int tx_pin; 826 unsigned int tx_pin;
807 u8 bbp; 827 u8 bbp;
808 828
809 if ((rt2x00_rt(&rt2x00dev->chip, RT3070) || 829 if ((rt2x00_rt(rt2x00dev, RT3070) ||
810 rt2x00_rt(&rt2x00dev->chip, RT3090)) && 830 rt2x00_rt(rt2x00dev, RT3090)) &&
811 (rt2x00_rf(&rt2x00dev->chip, RF2020) || 831 (rt2x00_rf(rt2x00dev, RF2020) ||
812 rt2x00_rf(&rt2x00dev->chip, RF3020) || 832 rt2x00_rf(rt2x00dev, RF3020) ||
813 rt2x00_rf(&rt2x00dev->chip, RF3021) || 833 rt2x00_rf(rt2x00dev, RF3021) ||
814 rt2x00_rf(&rt2x00dev->chip, RF3022))) 834 rt2x00_rf(rt2x00dev, RF3022)))
815 rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info); 835 rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
816 else 836 else
817 rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info); 837 rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info);
@@ -878,7 +898,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
878 rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf)); 898 rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
879 rt2800_bbp_write(rt2x00dev, 3, bbp); 899 rt2800_bbp_write(rt2x00dev, 3, bbp);
880 900
881 if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) { 901 if (rt2x00_rt(rt2x00dev, RT2860) &&
902 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
882 if (conf_is_ht40(conf)) { 903 if (conf_is_ht40(conf)) {
883 rt2800_bbp_write(rt2x00dev, 69, 0x1a); 904 rt2800_bbp_write(rt2x00dev, 69, 0x1a);
884 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 905 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
@@ -1040,8 +1061,9 @@ EXPORT_SYMBOL_GPL(rt2800_link_stats);
1040static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) 1061static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
1041{ 1062{
1042 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { 1063 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
1043 if (rt2x00_intf_is_usb(rt2x00dev) && 1064 if (rt2x00_is_usb(rt2x00dev) &&
1044 rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) 1065 rt2x00_rt(rt2x00dev, RT3070) &&
1066 (rt2x00_rev(rt2x00dev) == RT3070_VERSION))
1045 return 0x1c + (2 * rt2x00dev->lna_gain); 1067 return 0x1c + (2 * rt2x00dev->lna_gain);
1046 else 1068 else
1047 return 0x2e + rt2x00dev->lna_gain; 1069 return 0x2e + rt2x00dev->lna_gain;
@@ -1072,7 +1094,8 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
1072void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, 1094void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
1073 const u32 count) 1095 const u32 count)
1074{ 1096{
1075 if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) 1097 if (rt2x00_rt(rt2x00dev, RT2860) &&
1098 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION))
1076 return; 1099 return;
1077 1100
1078 /* 1101 /*
@@ -1092,7 +1115,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1092 u32 reg; 1115 u32 reg;
1093 unsigned int i; 1116 unsigned int i;
1094 1117
1095 if (rt2x00_intf_is_usb(rt2x00dev)) { 1118 if (rt2x00_is_usb(rt2x00dev)) {
1096 /* 1119 /*
1097 * Wait until BBP and RF are ready. 1120 * Wait until BBP and RF are ready.
1098 */ 1121 */
@@ -1111,7 +1134,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1111 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg); 1134 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
1112 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 1135 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
1113 reg & ~0x00002000); 1136 reg & ~0x00002000);
1114 } else if (rt2x00_intf_is_pci(rt2x00dev)) 1137 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
1115 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); 1138 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
1116 1139
1117 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg); 1140 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
@@ -1119,9 +1142,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1119 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1); 1142 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
1120 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 1143 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
1121 1144
1122 if (rt2x00_intf_is_usb(rt2x00dev)) { 1145 if (rt2x00_is_usb(rt2x00dev)) {
1123 rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); 1146 rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
1124#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) 1147#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
1125 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, 1148 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
1126 USB_MODE_RESET, REGISTER_TIMEOUT); 1149 USB_MODE_RESET, REGISTER_TIMEOUT);
1127#endif 1150#endif
@@ -1157,8 +1180,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1157 rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0); 1180 rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
1158 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 1181 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
1159 1182
1160 if (rt2x00_intf_is_usb(rt2x00dev) && 1183 if (rt2x00_is_usb(rt2x00dev) &&
1161 rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) { 1184 rt2x00_rt(rt2x00dev, RT3070) &&
1185 (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
1162 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); 1186 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
1163 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); 1187 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
1164 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); 1188 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -1185,8 +1209,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1185 1209
1186 rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg); 1210 rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
1187 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); 1211 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
1188 if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION && 1212 if ((rt2x00_rt(rt2x00dev, RT2872) &&
1189 rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION) 1213 (rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
1214 rt2x00_rt(rt2x00dev, RT2880) ||
1215 rt2x00_rt(rt2x00dev, RT2883) ||
1216 rt2x00_rt(rt2x00dev, RT2890) ||
1217 rt2x00_rt(rt2x00dev, RT3052) ||
1218 (rt2x00_rt(rt2x00dev, RT3070) &&
1219 (rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
1190 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2); 1220 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
1191 else 1221 else
1192 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1); 1222 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
@@ -1276,7 +1306,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1276 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1); 1306 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
1277 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); 1307 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
1278 1308
1279 if (rt2x00_intf_is_usb(rt2x00dev)) { 1309 if (rt2x00_is_usb(rt2x00dev)) {
1280 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); 1310 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
1281 1311
1282 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 1312 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
@@ -1336,7 +1366,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1336 rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0); 1366 rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
1337 rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); 1367 rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
1338 1368
1339 if (rt2x00_intf_is_usb(rt2x00dev)) { 1369 if (rt2x00_is_usb(rt2x00dev)) {
1340 rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg); 1370 rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg);
1341 rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30); 1371 rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
1342 rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg); 1372 rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
@@ -1465,22 +1495,25 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
1465 rt2800_bbp_write(rt2x00dev, 103, 0x00); 1495 rt2800_bbp_write(rt2x00dev, 103, 0x00);
1466 rt2800_bbp_write(rt2x00dev, 105, 0x05); 1496 rt2800_bbp_write(rt2x00dev, 105, 0x05);
1467 1497
1468 if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) { 1498 if (rt2x00_rt(rt2x00dev, RT2860) &&
1499 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
1469 rt2800_bbp_write(rt2x00dev, 69, 0x16); 1500 rt2800_bbp_write(rt2x00dev, 69, 0x16);
1470 rt2800_bbp_write(rt2x00dev, 73, 0x12); 1501 rt2800_bbp_write(rt2x00dev, 73, 0x12);
1471 } 1502 }
1472 1503
1473 if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION) 1504 if (rt2x00_rt(rt2x00dev, RT2860) &&
1505 (rt2x00_rev(rt2x00dev) > RT2860D_VERSION))
1474 rt2800_bbp_write(rt2x00dev, 84, 0x19); 1506 rt2800_bbp_write(rt2x00dev, 84, 0x19);
1475 1507
1476 if (rt2x00_intf_is_usb(rt2x00dev) && 1508 if (rt2x00_is_usb(rt2x00dev) &&
1477 rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) { 1509 rt2x00_rt(rt2x00dev, RT3070) &&
1510 (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
1478 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 1511 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
1479 rt2800_bbp_write(rt2x00dev, 84, 0x99); 1512 rt2800_bbp_write(rt2x00dev, 84, 0x99);
1480 rt2800_bbp_write(rt2x00dev, 105, 0x05); 1513 rt2800_bbp_write(rt2x00dev, 105, 0x05);
1481 } 1514 }
1482 1515
1483 if (rt2x00_rt(&rt2x00dev->chip, RT3052)) { 1516 if (rt2x00_rt(rt2x00dev, RT3052)) {
1484 rt2800_bbp_write(rt2x00dev, 31, 0x08); 1517 rt2800_bbp_write(rt2x00dev, 31, 0x08);
1485 rt2800_bbp_write(rt2x00dev, 78, 0x0e); 1518 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
1486 rt2800_bbp_write(rt2x00dev, 80, 0x08); 1519 rt2800_bbp_write(rt2x00dev, 80, 0x08);
@@ -1565,14 +1598,15 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1565 u8 rfcsr; 1598 u8 rfcsr;
1566 u8 bbp; 1599 u8 bbp;
1567 1600
1568 if (rt2x00_intf_is_usb(rt2x00dev) && 1601 if (rt2x00_is_usb(rt2x00dev) &&
1569 rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION) 1602 rt2x00_rt(rt2x00dev, RT3070) &&
1603 (rt2x00_rev(rt2x00dev) != RT3070_VERSION))
1570 return 0; 1604 return 0;
1571 1605
1572 if (rt2x00_intf_is_pci(rt2x00dev)) { 1606 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
1573 if (!rt2x00_rf(&rt2x00dev->chip, RF3020) && 1607 if (!rt2x00_rf(rt2x00dev, RF3020) &&
1574 !rt2x00_rf(&rt2x00dev->chip, RF3021) && 1608 !rt2x00_rf(rt2x00dev, RF3021) &&
1575 !rt2x00_rf(&rt2x00dev->chip, RF3022)) 1609 !rt2x00_rf(rt2x00dev, RF3022))
1576 return 0; 1610 return 0;
1577 } 1611 }
1578 1612
@@ -1586,7 +1620,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1586 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); 1620 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
1587 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); 1621 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
1588 1622
1589 if (rt2x00_intf_is_usb(rt2x00dev)) { 1623 if (rt2x00_is_usb(rt2x00dev)) {
1590 rt2800_rfcsr_write(rt2x00dev, 4, 0x40); 1624 rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
1591 rt2800_rfcsr_write(rt2x00dev, 5, 0x03); 1625 rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
1592 rt2800_rfcsr_write(rt2x00dev, 6, 0x02); 1626 rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
@@ -1607,7 +1641,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1607 rt2800_rfcsr_write(rt2x00dev, 25, 0x01); 1641 rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
1608 rt2800_rfcsr_write(rt2x00dev, 27, 0x03); 1642 rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
1609 rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); 1643 rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
1610 } else if (rt2x00_intf_is_pci(rt2x00dev)) { 1644 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
1611 rt2800_rfcsr_write(rt2x00dev, 0, 0x50); 1645 rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
1612 rt2800_rfcsr_write(rt2x00dev, 1, 0x01); 1646 rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
1613 rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); 1647 rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
@@ -1737,7 +1771,12 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
1737 rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); 1771 rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
1738 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); 1772 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
1739 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); 1773 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
1740 } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) { 1774 } else if (rt2x00_rt(rt2x00dev, RT2860) ||
1775 rt2x00_rt(rt2x00dev, RT2870) ||
1776 rt2x00_rt(rt2x00dev, RT2872) ||
1777 rt2x00_rt(rt2x00dev, RT2880) ||
1778 (rt2x00_rt(rt2x00dev, RT2883) &&
1779 (rt2x00_rev(rt2x00dev) < RT2883_VERSION))) {
1741 /* 1780 /*
1742 * There is a max of 2 RX streams for RT28x0 series 1781 * There is a max of 2 RX streams for RT28x0 series
1743 */ 1782 */
@@ -1836,36 +1875,34 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
1836 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 1875 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
1837 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg); 1876 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
1838 1877
1839 rt2x00_set_chip_rf(rt2x00dev, value, reg); 1878 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
1840 1879 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
1841 if (rt2x00_intf_is_usb(rt2x00dev)) { 1880
1842 struct rt2x00_chip *chip = &rt2x00dev->chip; 1881 if (!rt2x00_rt(rt2x00dev, RT2860) &&
1843 1882 !rt2x00_rt(rt2x00dev, RT2870) &&
1844 /* 1883 !rt2x00_rt(rt2x00dev, RT2872) &&
1845 * The check for rt2860 is not a typo, some rt2870 hardware 1884 !rt2x00_rt(rt2x00dev, RT2880) &&
1846 * identifies itself as rt2860 in the CSR register. 1885 !rt2x00_rt(rt2x00dev, RT2883) &&
1847 */ 1886 !rt2x00_rt(rt2x00dev, RT2890) &&
1848 if (rt2x00_check_rev(chip, 0xfff00000, 0x28600000) || 1887 !rt2x00_rt(rt2x00dev, RT3052) &&
1849 rt2x00_check_rev(chip, 0xfff00000, 0x28700000) || 1888 !rt2x00_rt(rt2x00dev, RT3070) &&
1850 rt2x00_check_rev(chip, 0xfff00000, 0x28800000)) { 1889 !rt2x00_rt(rt2x00dev, RT3071) &&
1851 rt2x00_set_chip_rt(rt2x00dev, RT2870); 1890 !rt2x00_rt(rt2x00dev, RT3090) &&
1852 } else if (rt2x00_check_rev(chip, 0xffff0000, 0x30700000)) { 1891 !rt2x00_rt(rt2x00dev, RT3390) &&
1853 rt2x00_set_chip_rt(rt2x00dev, RT3070); 1892 !rt2x00_rt(rt2x00dev, RT3572)) {
1854 } else { 1893 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1855 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1894 return -ENODEV;
1856 return -ENODEV;
1857 }
1858 } 1895 }
1859 rt2x00_print_chip(rt2x00dev); 1896
1860 1897 if (!rt2x00_rf(rt2x00dev, RF2820) &&
1861 if (!rt2x00_rf(&rt2x00dev->chip, RF2820) && 1898 !rt2x00_rf(rt2x00dev, RF2850) &&
1862 !rt2x00_rf(&rt2x00dev->chip, RF2850) && 1899 !rt2x00_rf(rt2x00dev, RF2720) &&
1863 !rt2x00_rf(&rt2x00dev->chip, RF2720) && 1900 !rt2x00_rf(rt2x00dev, RF2750) &&
1864 !rt2x00_rf(&rt2x00dev->chip, RF2750) && 1901 !rt2x00_rf(rt2x00dev, RF3020) &&
1865 !rt2x00_rf(&rt2x00dev->chip, RF3020) && 1902 !rt2x00_rf(rt2x00dev, RF2020) &&
1866 !rt2x00_rf(&rt2x00dev->chip, RF2020) && 1903 !rt2x00_rf(rt2x00dev, RF3021) &&
1867 !rt2x00_rf(&rt2x00dev->chip, RF3021) && 1904 !rt2x00_rf(rt2x00dev, RF3022) &&
1868 !rt2x00_rf(&rt2x00dev->chip, RF3022)) { 1905 !rt2x00_rf(rt2x00dev, RF3052)) {
1869 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1906 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1870 return -ENODEV; 1907 return -ENODEV;
1871 } 1908 }
@@ -2013,7 +2050,6 @@ static const struct rf_channel rf_vals_302x[] = {
2013 2050
2014int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 2051int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2015{ 2052{
2016 struct rt2x00_chip *chip = &rt2x00dev->chip;
2017 struct hw_mode_spec *spec = &rt2x00dev->spec; 2053 struct hw_mode_spec *spec = &rt2x00dev->spec;
2018 struct channel_info *info; 2054 struct channel_info *info;
2019 char *tx_power1; 2055 char *tx_power1;
@@ -2024,7 +2060,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2024 /* 2060 /*
2025 * Disable powersaving as default on PCI devices. 2061 * Disable powersaving as default on PCI devices.
2026 */ 2062 */
2027 if (rt2x00_intf_is_pci(rt2x00dev)) 2063 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
2028 rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2064 rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2029 2065
2030 /* 2066 /*
@@ -2049,19 +2085,19 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2049 spec->supported_bands = SUPPORT_BAND_2GHZ; 2085 spec->supported_bands = SUPPORT_BAND_2GHZ;
2050 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 2086 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
2051 2087
2052 if (rt2x00_rf(chip, RF2820) || 2088 if (rt2x00_rf(rt2x00dev, RF2820) ||
2053 rt2x00_rf(chip, RF2720) || 2089 rt2x00_rf(rt2x00dev, RF2720) ||
2054 (rt2x00_intf_is_pci(rt2x00dev) && rt2x00_rf(chip, RF3052))) { 2090 rt2x00_rf(rt2x00dev, RF3052)) {
2055 spec->num_channels = 14; 2091 spec->num_channels = 14;
2056 spec->channels = rf_vals; 2092 spec->channels = rf_vals;
2057 } else if (rt2x00_rf(chip, RF2850) || rt2x00_rf(chip, RF2750)) { 2093 } else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) {
2058 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2094 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2059 spec->num_channels = ARRAY_SIZE(rf_vals); 2095 spec->num_channels = ARRAY_SIZE(rf_vals);
2060 spec->channels = rf_vals; 2096 spec->channels = rf_vals;
2061 } else if (rt2x00_rf(chip, RF3020) || 2097 } else if (rt2x00_rf(rt2x00dev, RF3020) ||
2062 rt2x00_rf(chip, RF2020) || 2098 rt2x00_rf(rt2x00dev, RF2020) ||
2063 rt2x00_rf(chip, RF3021) || 2099 rt2x00_rf(rt2x00dev, RF3021) ||
2064 rt2x00_rf(chip, RF3022)) { 2100 rt2x00_rf(rt2x00dev, RF3022)) {
2065 spec->num_channels = ARRAY_SIZE(rf_vals_302x); 2101 spec->num_channels = ARRAY_SIZE(rf_vals_302x);
2066 spec->channels = rf_vals_302x; 2102 spec->channels = rf_vals_302x;
2067 } 2103 }
@@ -2069,7 +2105,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2069 /* 2105 /*
2070 * Initialize HT information. 2106 * Initialize HT information.
2071 */ 2107 */
2072 if (!rt2x00_rf(chip, RF2020)) 2108 if (!rt2x00_rf(rt2x00dev, RF2020))
2073 spec->ht.ht_supported = true; 2109 spec->ht.ht_supported = true;
2074 else 2110 else
2075 spec->ht.ht_supported = false; 2111 spec->ht.ht_supported = false;
@@ -2282,7 +2318,6 @@ const struct ieee80211_ops rt2800_mac80211_ops = {
2282 .set_rts_threshold = rt2800_set_rts_threshold, 2318 .set_rts_threshold = rt2800_set_rts_threshold,
2283 .bss_info_changed = rt2x00mac_bss_info_changed, 2319 .bss_info_changed = rt2x00mac_bss_info_changed,
2284 .conf_tx = rt2800_conf_tx, 2320 .conf_tx = rt2800_conf_tx,
2285 .get_tx_stats = rt2x00mac_get_tx_stats,
2286 .get_tsf = rt2800_get_tsf, 2321 .get_tsf = rt2800_get_tsf,
2287 .rfkill_poll = rt2x00mac_rfkill_poll, 2322 .rfkill_poll = rt2x00mac_rfkill_poll,
2288}; 2323};
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 535ce22f2ac8..ebabeae62d1b 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -114,8 +114,6 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
114extern const struct rt2x00debug rt2800_rt2x00debug; 114extern const struct rt2x00debug rt2800_rt2x00debug;
115 115
116int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); 116int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
117void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
118 struct rt2x00_led *led, enum led_type type);
119int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, 117int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
120 struct rt2x00lib_crypto *crypto, 118 struct rt2x00lib_crypto *crypto,
121 struct ieee80211_key_conf *key); 119 struct ieee80211_key_conf *key);
@@ -139,6 +137,7 @@ void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
139int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); 137int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
140int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); 138int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
141int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); 139int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
140int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
142 141
143int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); 142int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
144void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); 143void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index dfc886fcb44d..0e4c41766edc 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -48,14 +48,6 @@
48#include "rt2800.h" 48#include "rt2800.h"
49#include "rt2800pci.h" 49#include "rt2800pci.h"
50 50
51#ifdef CONFIG_RT2800PCI_PCI_MODULE
52#define CONFIG_RT2800PCI_PCI
53#endif
54
55#ifdef CONFIG_RT2800PCI_WISOC_MODULE
56#define CONFIG_RT2800PCI_WISOC
57#endif
58
59/* 51/*
60 * Allow hardware encryption to be disabled. 52 * Allow hardware encryption to be disabled.
61 */ 53 */
@@ -87,7 +79,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
87 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 79 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
88} 80}
89 81
90#ifdef CONFIG_RT2800PCI_WISOC 82#ifdef CONFIG_RT2800PCI_SOC
91static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) 83static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
92{ 84{
93 u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */ 85 u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
@@ -98,7 +90,7 @@ static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
98static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) 90static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
99{ 91{
100} 92}
101#endif /* CONFIG_RT2800PCI_WISOC */ 93#endif /* CONFIG_RT2800PCI_SOC */
102 94
103#ifdef CONFIG_RT2800PCI_PCI 95#ifdef CONFIG_RT2800PCI_PCI
104static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 96static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -461,24 +453,6 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
461 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); 453 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
462} 454}
463 455
464static int rt2800pci_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
465{
466 unsigned int i;
467 u32 reg;
468
469 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
470 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
471 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
472 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
473 return 0;
474
475 msleep(1);
476 }
477
478 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
479 return -EACCES;
480}
481
482static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) 456static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
483{ 457{
484 u32 reg; 458 u32 reg;
@@ -487,10 +461,10 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
487 /* 461 /*
488 * Initialize all registers. 462 * Initialize all registers.
489 */ 463 */
490 if (unlikely(rt2800pci_wait_wpdma_ready(rt2x00dev) || 464 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
491 rt2800pci_init_queues(rt2x00dev) || 465 rt2800pci_init_queues(rt2x00dev) ||
492 rt2800_init_registers(rt2x00dev) || 466 rt2800_init_registers(rt2x00dev) ||
493 rt2800pci_wait_wpdma_ready(rt2x00dev) || 467 rt2800_wait_wpdma_ready(rt2x00dev) ||
494 rt2800_init_bbp(rt2x00dev) || 468 rt2800_init_bbp(rt2x00dev) ||
495 rt2800_init_rfcsr(rt2x00dev))) 469 rt2800_init_rfcsr(rt2x00dev)))
496 return -EIO; 470 return -EIO;
@@ -570,7 +544,7 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
570 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); 544 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
571 545
572 /* Wait for DMA, ignore error */ 546 /* Wait for DMA, ignore error */
573 rt2800pci_wait_wpdma_ready(rt2x00dev); 547 rt2800_wait_wpdma_ready(rt2x00dev);
574} 548}
575 549
576static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, 550static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -835,7 +809,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
835 struct rxdone_entry_desc *rxdesc) 809 struct rxdone_entry_desc *rxdesc)
836{ 810{
837 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 811 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
838 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
839 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 812 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
840 __le32 *rxd = entry_priv->desc; 813 __le32 *rxd = entry_priv->desc;
841 __le32 *rxwi = (__le32 *)entry->skb->data; 814 __le32 *rxwi = (__le32 *)entry->skb->data;
@@ -883,10 +856,8 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
883 if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS)) 856 if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS))
884 rxdesc->dev_flags |= RXDONE_MY_BSS; 857 rxdesc->dev_flags |= RXDONE_MY_BSS;
885 858
886 if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) { 859 if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD))
887 rxdesc->dev_flags |= RXDONE_L2PAD; 860 rxdesc->dev_flags |= RXDONE_L2PAD;
888 skbdesc->flags |= SKBDESC_L2_PADDED;
889 }
890 861
891 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) 862 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
892 rxdesc->flags |= RX_FLAG_SHORT_GI; 863 rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -927,7 +898,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
927 * Remove TXWI descriptor from start of buffer. 898 * Remove TXWI descriptor from start of buffer.
928 */ 899 */
929 skb_pull(entry->skb, RXWI_DESC_SIZE); 900 skb_pull(entry->skb, RXWI_DESC_SIZE);
930 skb_trim(entry->skb, rxdesc->size);
931} 901}
932 902
933/* 903/*
@@ -1071,18 +1041,12 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
1071 /* 1041 /*
1072 * Read EEPROM into buffer 1042 * Read EEPROM into buffer
1073 */ 1043 */
1074 switch (rt2x00dev->chip.rt) { 1044 if (rt2x00_is_soc(rt2x00dev))
1075 case RT2880:
1076 case RT3052:
1077 rt2800pci_read_eeprom_soc(rt2x00dev); 1045 rt2800pci_read_eeprom_soc(rt2x00dev);
1078 break; 1046 else if (rt2800pci_efuse_detect(rt2x00dev))
1079 default: 1047 rt2800pci_read_eeprom_efuse(rt2x00dev);
1080 if (rt2800pci_efuse_detect(rt2x00dev)) 1048 else
1081 rt2800pci_read_eeprom_efuse(rt2x00dev); 1049 rt2800pci_read_eeprom_pci(rt2x00dev);
1082 else
1083 rt2800pci_read_eeprom_pci(rt2x00dev);
1084 break;
1085 }
1086 1050
1087 return rt2800_validate_eeprom(rt2x00dev); 1051 return rt2800_validate_eeprom(rt2x00dev);
1088} 1052}
@@ -1133,8 +1097,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
1133 /* 1097 /*
1134 * This device requires firmware. 1098 * This device requires firmware.
1135 */ 1099 */
1136 if (!rt2x00_rt(&rt2x00dev->chip, RT2880) && 1100 if (!rt2x00_is_soc(rt2x00dev))
1137 !rt2x00_rt(&rt2x00dev->chip, RT3052))
1138 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 1101 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
1139 __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); 1102 __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
1140 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); 1103 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
@@ -1222,7 +1185,10 @@ static const struct rt2x00_ops rt2800pci_ops = {
1222 * RT2800pci module information. 1185 * RT2800pci module information.
1223 */ 1186 */
1224static struct pci_device_id rt2800pci_device_table[] = { 1187static struct pci_device_id rt2800pci_device_table[] = {
1225 { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1188 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
1189 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
1190 { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
1191 { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
1226 { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1192 { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
1227 { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1193 { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
1228 { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1194 { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1230,18 +1196,19 @@ static struct pci_device_id rt2800pci_device_table[] = {
1230 { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1196 { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
1231 { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1197 { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
1232 { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1198 { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
1233 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1199 { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
1234 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1200#ifdef CONFIG_RT2800PCI_RT30XX
1235 { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
1236 { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
1237 { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
1238 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
1239 { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1201 { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
1240 { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1202 { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
1241 { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1203 { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
1204 { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
1205#endif
1206#ifdef CONFIG_RT2800PCI_RT35XX
1207 { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
1208 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
1242 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1209 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
1243 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1210 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
1244 { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1211#endif
1245 { 0, } 1212 { 0, }
1246}; 1213};
1247 1214
@@ -1255,12 +1222,11 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
1255#endif /* CONFIG_RT2800PCI_PCI */ 1222#endif /* CONFIG_RT2800PCI_PCI */
1256MODULE_LICENSE("GPL"); 1223MODULE_LICENSE("GPL");
1257 1224
1258#ifdef CONFIG_RT2800PCI_WISOC 1225#ifdef CONFIG_RT2800PCI_SOC
1259#if defined(CONFIG_RALINK_RT288X) 1226static int rt2800soc_probe(struct platform_device *pdev)
1260__rt2x00soc_probe(RT2880, &rt2800pci_ops); 1227{
1261#elif defined(CONFIG_RALINK_RT305X) 1228 return rt2x00soc_probe(pdev, rt2800pci_ops);
1262__rt2x00soc_probe(RT3052, &rt2800pci_ops); 1229}
1263#endif
1264 1230
1265static struct platform_driver rt2800soc_driver = { 1231static struct platform_driver rt2800soc_driver = {
1266 .driver = { 1232 .driver = {
@@ -1268,12 +1234,12 @@ static struct platform_driver rt2800soc_driver = {
1268 .owner = THIS_MODULE, 1234 .owner = THIS_MODULE,
1269 .mod_name = KBUILD_MODNAME, 1235 .mod_name = KBUILD_MODNAME,
1270 }, 1236 },
1271 .probe = __rt2x00soc_probe, 1237 .probe = rt2800soc_probe,
1272 .remove = __devexit_p(rt2x00soc_remove), 1238 .remove = __devexit_p(rt2x00soc_remove),
1273 .suspend = rt2x00soc_suspend, 1239 .suspend = rt2x00soc_suspend,
1274 .resume = rt2x00soc_resume, 1240 .resume = rt2x00soc_resume,
1275}; 1241};
1276#endif /* CONFIG_RT2800PCI_WISOC */ 1242#endif /* CONFIG_RT2800PCI_SOC */
1277 1243
1278#ifdef CONFIG_RT2800PCI_PCI 1244#ifdef CONFIG_RT2800PCI_PCI
1279static struct pci_driver rt2800pci_driver = { 1245static struct pci_driver rt2800pci_driver = {
@@ -1290,7 +1256,7 @@ static int __init rt2800pci_init(void)
1290{ 1256{
1291 int ret = 0; 1257 int ret = 0;
1292 1258
1293#ifdef CONFIG_RT2800PCI_WISOC 1259#ifdef CONFIG_RT2800PCI_SOC
1294 ret = platform_driver_register(&rt2800soc_driver); 1260 ret = platform_driver_register(&rt2800soc_driver);
1295 if (ret) 1261 if (ret)
1296 return ret; 1262 return ret;
@@ -1298,7 +1264,7 @@ static int __init rt2800pci_init(void)
1298#ifdef CONFIG_RT2800PCI_PCI 1264#ifdef CONFIG_RT2800PCI_PCI
1299 ret = pci_register_driver(&rt2800pci_driver); 1265 ret = pci_register_driver(&rt2800pci_driver);
1300 if (ret) { 1266 if (ret) {
1301#ifdef CONFIG_RT2800PCI_WISOC 1267#ifdef CONFIG_RT2800PCI_SOC
1302 platform_driver_unregister(&rt2800soc_driver); 1268 platform_driver_unregister(&rt2800soc_driver);
1303#endif 1269#endif
1304 return ret; 1270 return ret;
@@ -1313,7 +1279,7 @@ static void __exit rt2800pci_exit(void)
1313#ifdef CONFIG_RT2800PCI_PCI 1279#ifdef CONFIG_RT2800PCI_PCI
1314 pci_unregister_driver(&rt2800pci_driver); 1280 pci_unregister_driver(&rt2800pci_driver);
1315#endif 1281#endif
1316#ifdef CONFIG_RT2800PCI_WISOC 1282#ifdef CONFIG_RT2800PCI_SOC
1317 platform_driver_unregister(&rt2800soc_driver); 1283 platform_driver_unregister(&rt2800soc_driver);
1318#endif 1284#endif
1319} 1285}
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ab95346cf6a3..5e4ee2023fcf 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -92,7 +92,6 @@ static bool rt2800usb_check_crc(const u8 *data, const size_t len)
92static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, 92static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
93 const u8 *data, const size_t len) 93 const u8 *data, const size_t len)
94{ 94{
95 u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
96 size_t offset = 0; 95 size_t offset = 0;
97 96
98 /* 97 /*
@@ -111,9 +110,9 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
111 * Check if we need the upper 4kb firmware data or not. 110 * Check if we need the upper 4kb firmware data or not.
112 */ 111 */
113 if ((len == 4096) && 112 if ((len == 4096) &&
114 (chipset != 0x2860) && 113 !rt2x00_rt(rt2x00dev, RT2860) &&
115 (chipset != 0x2872) && 114 !rt2x00_rt(rt2x00dev, RT2872) &&
116 (chipset != 0x3070)) 115 !rt2x00_rt(rt2x00dev, RT3070))
117 return FW_BAD_VERSION; 116 return FW_BAD_VERSION;
118 117
119 /* 118 /*
@@ -138,14 +137,13 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
138 u32 reg; 137 u32 reg;
139 u32 offset; 138 u32 offset;
140 u32 length; 139 u32 length;
141 u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
142 140
143 /* 141 /*
144 * Check which section of the firmware we need. 142 * Check which section of the firmware we need.
145 */ 143 */
146 if ((chipset == 0x2860) || 144 if (rt2x00_rt(rt2x00dev, RT2860) ||
147 (chipset == 0x2872) || 145 rt2x00_rt(rt2x00dev, RT2872) ||
148 (chipset == 0x3070)) { 146 rt2x00_rt(rt2x00dev, RT3070)) {
149 offset = 0; 147 offset = 0;
150 length = 4096; 148 length = 4096;
151 } else { 149 } else {
@@ -200,9 +198,9 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
200 */ 198 */
201 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); 199 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
202 200
203 if ((chipset == 0x3070) || 201 if (rt2x00_rt(rt2x00dev, RT3070) ||
204 (chipset == 0x3071) || 202 rt2x00_rt(rt2x00dev, RT3071) ||
205 (chipset == 0x3572)) { 203 rt2x00_rt(rt2x00dev, RT3572)) {
206 udelay(200); 204 udelay(200);
207 rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); 205 rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
208 udelay(10); 206 udelay(10);
@@ -248,24 +246,6 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
248 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 246 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
249} 247}
250 248
251static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
252{
253 unsigned int i;
254 u32 reg;
255
256 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
257 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
258 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
259 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
260 return 0;
261
262 msleep(1);
263 }
264
265 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
266 return -EACCES;
267}
268
269static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) 249static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
270{ 250{
271 u32 reg; 251 u32 reg;
@@ -274,7 +254,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
274 /* 254 /*
275 * Initialize all registers. 255 * Initialize all registers.
276 */ 256 */
277 if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) || 257 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
278 rt2800_init_registers(rt2x00dev) || 258 rt2800_init_registers(rt2x00dev) ||
279 rt2800_init_bbp(rt2x00dev) || 259 rt2800_init_bbp(rt2x00dev) ||
280 rt2800_init_rfcsr(rt2x00dev))) 260 rt2800_init_rfcsr(rt2x00dev)))
@@ -295,9 +275,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
295 275
296 rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg); 276 rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
297 rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0); 277 rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
298 /* Don't use bulk in aggregation when working with USB 1.1 */ 278 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
299 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
300 (rt2x00dev->rx->usb_maxpacket == 512));
301 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); 279 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
302 /* 280 /*
303 * Total room for RX frames in kilobytes, PBF might still exceed 281 * Total room for RX frames in kilobytes, PBF might still exceed
@@ -346,7 +324,7 @@ static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
346 rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); 324 rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
347 325
348 /* Wait for DMA, ignore error */ 326 /* Wait for DMA, ignore error */
349 rt2800usb_wait_wpdma_ready(rt2x00dev); 327 rt2800_wait_wpdma_ready(rt2x00dev);
350 328
351 rt2x00usb_disable_radio(rt2x00dev); 329 rt2x00usb_disable_radio(rt2x00dev);
352} 330}
@@ -573,41 +551,57 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
573{ 551{
574 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 552 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
575 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 553 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
576 __le32 *rxd = (__le32 *)entry->skb->data; 554 __le32 *rxi = (__le32 *)entry->skb->data;
577 __le32 *rxwi; 555 __le32 *rxwi;
578 u32 rxd0; 556 __le32 *rxd;
557 u32 rxi0;
579 u32 rxwi0; 558 u32 rxwi0;
580 u32 rxwi1; 559 u32 rxwi1;
581 u32 rxwi2; 560 u32 rxwi2;
582 u32 rxwi3; 561 u32 rxwi3;
562 u32 rxd0;
563 int rx_pkt_len;
564
565 /*
566 * RX frame format is :
567 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
568 * |<------------ rx_pkt_len -------------->|
569 */
570 rt2x00_desc_read(rxi, 0, &rxi0);
571 rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN);
572
573 rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE);
574
575 /*
576 * FIXME : we need to check for rx_pkt_len validity
577 */
578 rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len);
583 579
584 /* 580 /*
585 * Copy descriptor to the skbdesc->desc buffer, making it safe from 581 * Copy descriptor to the skbdesc->desc buffer, making it safe from
586 * moving of frame data in rt2x00usb. 582 * moving of frame data in rt2x00usb.
587 */ 583 */
588 memcpy(skbdesc->desc, rxd, skbdesc->desc_len); 584 memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
589 rxd = (__le32 *)skbdesc->desc;
590 rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)];
591 585
592 /* 586 /*
593 * It is now safe to read the descriptor on all architectures. 587 * It is now safe to read the descriptor on all architectures.
594 */ 588 */
595 rt2x00_desc_read(rxd, 0, &rxd0);
596 rt2x00_desc_read(rxwi, 0, &rxwi0); 589 rt2x00_desc_read(rxwi, 0, &rxwi0);
597 rt2x00_desc_read(rxwi, 1, &rxwi1); 590 rt2x00_desc_read(rxwi, 1, &rxwi1);
598 rt2x00_desc_read(rxwi, 2, &rxwi2); 591 rt2x00_desc_read(rxwi, 2, &rxwi2);
599 rt2x00_desc_read(rxwi, 3, &rxwi3); 592 rt2x00_desc_read(rxwi, 3, &rxwi3);
593 rt2x00_desc_read(rxd, 0, &rxd0);
600 594
601 if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR)) 595 if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
602 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 596 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
603 597
604 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 598 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
605 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); 599 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
606 rxdesc->cipher_status = 600 rxdesc->cipher_status =
607 rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR); 601 rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
608 } 602 }
609 603
610 if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) { 604 if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
611 /* 605 /*
612 * Hardware has stripped IV/EIV data from 802.11 frame during 606 * Hardware has stripped IV/EIV data from 802.11 frame during
613 * decryption. Unfortunately the descriptor doesn't contain 607 * decryption. Unfortunately the descriptor doesn't contain
@@ -622,13 +616,11 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
622 rxdesc->flags |= RX_FLAG_MMIC_ERROR; 616 rxdesc->flags |= RX_FLAG_MMIC_ERROR;
623 } 617 }
624 618
625 if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS)) 619 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
626 rxdesc->dev_flags |= RXDONE_MY_BSS; 620 rxdesc->dev_flags |= RXDONE_MY_BSS;
627 621
628 if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) { 622 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
629 rxdesc->dev_flags |= RXDONE_L2PAD; 623 rxdesc->dev_flags |= RXDONE_L2PAD;
630 skbdesc->flags |= SKBDESC_L2_PADDED;
631 }
632 624
633 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) 625 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
634 rxdesc->flags |= RX_FLAG_SHORT_GI; 626 rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -663,7 +655,6 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
663 * Remove RXWI descriptor from start of buffer. 655 * Remove RXWI descriptor from start of buffer.
664 */ 656 */
665 skb_pull(entry->skb, skbdesc->desc_len); 657 skb_pull(entry->skb, skbdesc->desc_len);
666 skb_trim(entry->skb, rxdesc->size);
667} 658}
668 659
669/* 660/*
@@ -814,51 +805,27 @@ static struct usb_device_id rt2800usb_device_table[] = {
814 /* Abocom */ 805 /* Abocom */
815 { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, 806 { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
816 { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, 807 { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
817 { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
818 { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
819 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
820 { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 808 { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
821 /* AirTies */
822 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
823 /* Amigo */
824 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
825 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
826 /* Amit */ 809 /* Amit */
827 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, 810 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
828 /* Askey */ 811 /* Askey */
829 { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) }, 812 { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) },
830 { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
831 { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
832 /* ASUS */ 813 /* ASUS */
833 { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, 814 { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
834 { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, 815 { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
835 { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, 816 { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
836 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
837 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
838 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
839 /* AzureWave */ 817 /* AzureWave */
840 { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, 818 { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
841 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
842 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
843 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
844 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
845 /* Belkin */ 819 /* Belkin */
846 { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, 820 { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
847 { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, 821 { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
848 { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) }, 822 { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
849 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
850 /* Buffalo */ 823 /* Buffalo */
851 { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, 824 { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
852 { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
853 /* Cisco */
854 { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
855 /* Conceptronic */ 825 /* Conceptronic */
856 { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, 826 { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
857 { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, 827 { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
858 { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
859 { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 828 { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
860 { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
861 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
862 { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, 829 { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
863 { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, 830 { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
864 { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, 831 { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -867,157 +834,257 @@ static struct usb_device_id rt2800usb_device_table[] = {
867 { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, 834 { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
868 { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, 835 { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
869 { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, 836 { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
870 { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
871 { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
872 { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
873 { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
874 /* D-Link */ 837 /* D-Link */
875 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 838 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
839 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
840 /* Edimax */
841 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
842 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
843 /* EnGenius */
844 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
845 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
846 /* Gigabyte */
847 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
848 /* Hawking */
849 { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
850 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
851 /* Linksys */
852 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
853 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
854 /* Logitec */
855 { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
856 { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
857 { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
858 /* Motorola */
859 { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
860 /* MSI */
861 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
862 /* Philips */
863 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
864 /* Planex */
865 { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
866 /* Ralink */
867 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
868 { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
869 /* Samsung */
870 { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
871 /* Siemens */
872 { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
873 /* Sitecom */
874 { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
875 { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
876 { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
877 { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
878 { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
879 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
880 /* SMC */
881 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
882 { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
883 { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
884 { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
885 { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
886 { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
887 /* Sparklan */
888 { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
889 /* Sweex */
890 { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
891 /* U-Media*/
892 { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
893 /* ZCOM */
894 { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
895 { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
896 /* Zinwell */
897 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
898 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
899 /* Zyxel */
900 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
901#ifdef CONFIG_RT2800USB_RT30XX
902 /* Abocom */
903 { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
904 { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
905 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
906 /* AirTies */
907 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
908 /* AzureWave */
909 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
910 /* Conceptronic */
911 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
912 /* Corega */
913 { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
914 /* D-Link */
876 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, 915 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
877 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
878 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, 916 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
879 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, 917 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
880 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, 918 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
881 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
882 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
883 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
884 /* Edimax */ 919 /* Edimax */
885 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, 920 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
886 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
887 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
888 /* Encore */ 921 /* Encore */
889 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, 922 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
890 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
891 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
892 /* EnGenius */ 923 /* EnGenius */
893 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
894 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
895 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, 924 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
896 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, 925 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
897 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, 926 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
927 /* Gigabyte */
928 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
929 /* I-O DATA */
930 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
931 /* MSI */
932 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
933 /* Pegatron */
934 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
935 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
936 /* Planex */
937 { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
938 /* Quanta */
939 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
940 /* Ralink */
941 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
942 { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
943 { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
944 { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
945 /* Sitecom */
946 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
947 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
948 /* SMC */
949 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
950 /* Zinwell */
951 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
952 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
953#endif
954#ifdef CONFIG_RT2800USB_RT35XX
955 /* Askey */
956 { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
957 /* Cisco */
958 { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
959 /* EnGenius */
960 { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
961 /* I-O DATA */
962 { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
963 /* Ralink */
964 { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
965 { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
966 { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
967 /* Sitecom */
968 { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
969 /* Zinwell */
970 { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
971#endif
972#ifdef CONFIG_RT2800USB_UNKNOWN
973 /*
974 * Unclear what kind of devices these are (they aren't supported by the
975 * vendor driver).
976 */
977 /* Allwin */
978 { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
979 { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
980 { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
981 { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
982 { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
983 { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
984 { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
985 /* Amigo */
986 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
987 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
988 /* Askey */
989 { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
990 /* ASUS */
991 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
992 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
993 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
994 { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
995 { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
996 /* AzureWave */
997 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
998 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
999 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
1000 /* Belkin */
1001 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
1002 /* Buffalo */
1003 { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
1004 { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) },
1005 { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) },
1006 { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) },
1007 /* Conceptronic */
1008 { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
1009 { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
1010 /* Corega */
1011 { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
1012 { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
1013 { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
1014 /* D-Link */
1015 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
1016 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
1017 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
1018 { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
1019 /* Encore */
1020 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
1021 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
1022 /* EnGenius */
898 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, 1023 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
899 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, 1024 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
900 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, 1025 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
901 { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
902 /* Gemtek */ 1026 /* Gemtek */
903 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, 1027 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
904 /* Gigabyte */ 1028 /* Gigabyte */
905 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
906 { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) }, 1029 { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
907 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
908 /* Hawking */ 1030 /* Hawking */
909 { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
910 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
911 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, 1031 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
912 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, 1032 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
913 /* I-O DATA */ 1033 /* I-O DATA */
914 { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
915 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
916 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, 1034 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
917 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, 1035 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
918 /* LevelOne */ 1036 /* LevelOne */
919 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, 1037 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
920 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, 1038 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
921 /* Linksys */ 1039 /* Linksys */
922 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
923 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
924 { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, 1040 { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
1041 { USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) },
925 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, 1042 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
926 /* Logitec */
927 { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
928 { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
929 { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
930 /* Motorola */ 1043 /* Motorola */
931 { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
932 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, 1044 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
933 /* MSI */ 1045 /* MSI */
934 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
935 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, 1046 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
1047 { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
936 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, 1048 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
937 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, 1049 { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
938 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1050 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
1051 { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
939 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1052 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
1053 { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
940 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1054 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
941 /* Ovislink */ 1055 /* Ovislink */
942 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 1056 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
943 /* Para */ 1057 /* Para */
944 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, 1058 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
945 /* Pegatron */ 1059 /* Pegatron */
1060 { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
946 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, 1061 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
947 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, 1062 { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
948 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
949 /* Philips */
950 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
951 /* Planex */ 1063 /* Planex */
952 { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
953 { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, 1064 { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
954 { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
955 /* Qcom */ 1065 /* Qcom */
956 { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) }, 1066 { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
957 /* Quanta */
958 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
959 /* Ralink */
960 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
961 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
962 { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
963 { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
964 { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
965 { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
966 { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
967 /* Samsung */
968 { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
969 /* Siemens */
970 { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
971 /* Sitecom */ 1067 /* Sitecom */
972 { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
973 { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
974 { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
975 { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
976 { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
977 { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, 1068 { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
978 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, 1069 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
979 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, 1070 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
980 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
981 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
982 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, 1071 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
983 { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
984 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
985 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, 1072 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
986 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, 1073 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
987 { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1074 { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) },
988 { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) }, 1075 { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) },
989 /* SMC */ 1076 /* SMC */
990 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
991 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
992 { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
993 { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
994 { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
995 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, 1077 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
996 { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
997 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, 1078 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
998 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, 1079 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
999 { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
1000 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, 1080 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
1001 /* Sparklan */ 1081 { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
1002 { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
1003 /* Sweex */ 1082 /* Sweex */
1004 { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, 1083 { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
1005 { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
1006 { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, 1084 { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
1007 /* U-Media*/
1008 { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
1009 /* ZCOM */
1010 { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
1011 { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
1012 /* Zinwell */
1013 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
1014 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
1015 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
1016 { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
1017 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
1018 /* Zyxel */ 1085 /* Zyxel */
1019 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
1020 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, 1086 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
1087#endif
1021 { 0, } 1088 { 0, }
1022}; 1089};
1023 1090
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 1e4340a182ef..d1d8ae94b4d4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -79,6 +79,8 @@
79 */ 79 */
80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
82#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
83#define RXD_DESC_SIZE ( 1 * sizeof(__le32) )
82 84
83/* 85/*
84 * TX Info structure 86 * TX Info structure
@@ -101,6 +103,54 @@
101#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000) 103#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000)
102 104
103/* 105/*
106 * RX Info structure
107 */
108
109/*
110 * Word 0
111 */
112
113#define RXINFO_W0_USB_DMA_RX_PKT_LEN FIELD32(0x0000ffff)
114
115/*
116 * RX WI structure
117 */
118
119/*
120 * Word0
121 */
122#define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff)
123#define RXWI_W0_KEY_INDEX FIELD32(0x00000300)
124#define RXWI_W0_BSSID FIELD32(0x00001c00)
125#define RXWI_W0_UDF FIELD32(0x0000e000)
126#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
127#define RXWI_W0_TID FIELD32(0xf0000000)
128
129/*
130 * Word1
131 */
132#define RXWI_W1_FRAG FIELD32(0x0000000f)
133#define RXWI_W1_SEQUENCE FIELD32(0x0000fff0)
134#define RXWI_W1_MCS FIELD32(0x007f0000)
135#define RXWI_W1_BW FIELD32(0x00800000)
136#define RXWI_W1_SHORT_GI FIELD32(0x01000000)
137#define RXWI_W1_STBC FIELD32(0x06000000)
138#define RXWI_W1_PHYMODE FIELD32(0xc0000000)
139
140/*
141 * Word2
142 */
143#define RXWI_W2_RSSI0 FIELD32(0x000000ff)
144#define RXWI_W2_RSSI1 FIELD32(0x0000ff00)
145#define RXWI_W2_RSSI2 FIELD32(0x00ff0000)
146
147/*
148 * Word3
149 */
150#define RXWI_W3_SNR0 FIELD32(0x000000ff)
151#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
152
153/*
104 * RX descriptor format for RX Ring. 154 * RX descriptor format for RX Ring.
105 */ 155 */
106 156
@@ -115,25 +165,25 @@
115 * AMSDU: rx with 802.3 header, not 802.11 header. 165 * AMSDU: rx with 802.3 header, not 802.11 header.
116 */ 166 */
117 167
118#define RXINFO_W0_BA FIELD32(0x00000001) 168#define RXD_W0_BA FIELD32(0x00000001)
119#define RXINFO_W0_DATA FIELD32(0x00000002) 169#define RXD_W0_DATA FIELD32(0x00000002)
120#define RXINFO_W0_NULLDATA FIELD32(0x00000004) 170#define RXD_W0_NULLDATA FIELD32(0x00000004)
121#define RXINFO_W0_FRAG FIELD32(0x00000008) 171#define RXD_W0_FRAG FIELD32(0x00000008)
122#define RXINFO_W0_UNICAST_TO_ME FIELD32(0x00000010) 172#define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010)
123#define RXINFO_W0_MULTICAST FIELD32(0x00000020) 173#define RXD_W0_MULTICAST FIELD32(0x00000020)
124#define RXINFO_W0_BROADCAST FIELD32(0x00000040) 174#define RXD_W0_BROADCAST FIELD32(0x00000040)
125#define RXINFO_W0_MY_BSS FIELD32(0x00000080) 175#define RXD_W0_MY_BSS FIELD32(0x00000080)
126#define RXINFO_W0_CRC_ERROR FIELD32(0x00000100) 176#define RXD_W0_CRC_ERROR FIELD32(0x00000100)
127#define RXINFO_W0_CIPHER_ERROR FIELD32(0x00000600) 177#define RXD_W0_CIPHER_ERROR FIELD32(0x00000600)
128#define RXINFO_W0_AMSDU FIELD32(0x00000800) 178#define RXD_W0_AMSDU FIELD32(0x00000800)
129#define RXINFO_W0_HTC FIELD32(0x00001000) 179#define RXD_W0_HTC FIELD32(0x00001000)
130#define RXINFO_W0_RSSI FIELD32(0x00002000) 180#define RXD_W0_RSSI FIELD32(0x00002000)
131#define RXINFO_W0_L2PAD FIELD32(0x00004000) 181#define RXD_W0_L2PAD FIELD32(0x00004000)
132#define RXINFO_W0_AMPDU FIELD32(0x00008000) 182#define RXD_W0_AMPDU FIELD32(0x00008000)
133#define RXINFO_W0_DECRYPTED FIELD32(0x00010000) 183#define RXD_W0_DECRYPTED FIELD32(0x00010000)
134#define RXINFO_W0_PLCP_RSSI FIELD32(0x00020000) 184#define RXD_W0_PLCP_RSSI FIELD32(0x00020000)
135#define RXINFO_W0_CIPHER_ALG FIELD32(0x00040000) 185#define RXD_W0_CIPHER_ALG FIELD32(0x00040000)
136#define RXINFO_W0_LAST_AMSDU FIELD32(0x00080000) 186#define RXD_W0_LAST_AMSDU FIELD32(0x00080000)
137#define RXINFO_W0_PLCP_SIGNAL FIELD32(0xfff00000) 187#define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000)
138 188
139#endif /* RT2800USB_H */ 189#endif /* RT2800USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index dcfc8c25d1a7..d9daa9c406fa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -104,6 +104,12 @@
104#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate)) 104#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
105 105
106/* 106/*
107 * Determine the number of L2 padding bytes required between the header and
108 * the payload.
109 */
110#define L2PAD_SIZE(__hdrlen) (-(__hdrlen) & 3)
111
112/*
107 * Determine the alignment requirement, 113 * Determine the alignment requirement,
108 * to make sure the 802.11 payload is padded to a 4-byte boundrary 114 * to make sure the 802.11 payload is padded to a 4-byte boundrary
109 * we must determine the address of the payload and calculate the 115 * we must determine the address of the payload and calculate the
@@ -154,6 +160,7 @@ struct avg_val {
154enum rt2x00_chip_intf { 160enum rt2x00_chip_intf {
155 RT2X00_CHIP_INTF_PCI, 161 RT2X00_CHIP_INTF_PCI,
156 RT2X00_CHIP_INTF_USB, 162 RT2X00_CHIP_INTF_USB,
163 RT2X00_CHIP_INTF_SOC,
157}; 164};
158 165
159/* 166/*
@@ -163,25 +170,26 @@ enum rt2x00_chip_intf {
163 */ 170 */
164struct rt2x00_chip { 171struct rt2x00_chip {
165 u16 rt; 172 u16 rt;
166#define RT2460 0x0101 173#define RT2460 0x2460
167#define RT2560 0x0201 174#define RT2560 0x2560
168#define RT2570 0x1201 175#define RT2570 0x2570
169#define RT2561s 0x0301 /* Turbo */ 176#define RT2661 0x2661
170#define RT2561 0x0302 177#define RT2573 0x2573
171#define RT2661 0x0401 178#define RT2860 0x2860 /* 2.4GHz PCI/CB */
172#define RT2571 0x1300 179#define RT2870 0x2870
173#define RT2860 0x0601 /* 2.4GHz PCI/CB */ 180#define RT2872 0x2872
174#define RT2860D 0x0681 /* 2.4GHz, 5GHz PCI/CB */
175#define RT2890 0x0701 /* 2.4GHz PCIe */
176#define RT2890D 0x0781 /* 2.4GHz, 5GHz PCIe */
177#define RT2880 0x2880 /* WSOC */ 181#define RT2880 0x2880 /* WSOC */
182#define RT2883 0x2883 /* WSOC */
183#define RT2890 0x2890 /* 2.4GHz PCIe */
178#define RT3052 0x3052 /* WSOC */ 184#define RT3052 0x3052 /* WSOC */
185#define RT3070 0x3070
186#define RT3071 0x3071
179#define RT3090 0x3090 /* 2.4GHz PCIe */ 187#define RT3090 0x3090 /* 2.4GHz PCIe */
180#define RT2870 0x1600 188#define RT3390 0x3390
181#define RT3070 0x1800 189#define RT3572 0x3572
182 190
183 u16 rf; 191 u16 rf;
184 u32 rev; 192 u16 rev;
185 193
186 enum rt2x00_chip_intf intf; 194 enum rt2x00_chip_intf intf;
187}; 195};
@@ -911,51 +919,30 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev,
911 * Chipset handlers 919 * Chipset handlers
912 */ 920 */
913static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, 921static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
914 const u16 rt, const u16 rf, const u32 rev) 922 const u16 rt, const u16 rf, const u16 rev)
915{ 923{
916 rt2x00dev->chip.rt = rt; 924 rt2x00dev->chip.rt = rt;
917 rt2x00dev->chip.rf = rf; 925 rt2x00dev->chip.rf = rf;
918 rt2x00dev->chip.rev = rev; 926 rt2x00dev->chip.rev = rev;
919}
920
921static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
922 const u16 rt)
923{
924 rt2x00dev->chip.rt = rt;
925}
926
927static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
928 const u16 rf, const u32 rev)
929{
930 rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
931}
932 927
933static inline void rt2x00_print_chip(struct rt2x00_dev *rt2x00dev)
934{
935 INFO(rt2x00dev, 928 INFO(rt2x00dev,
936 "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n", 929 "Chipset detected - rt: %04x, rf: %04x, rev: %04x.\n",
937 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); 930 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
938} 931}
939 932
940static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) 933static inline char rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
941{ 934{
942 return (chipset->rt == chip); 935 return (rt2x00dev->chip.rt == rt);
943} 936}
944 937
945static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip) 938static inline char rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
946{ 939{
947 return (chipset->rf == chip); 940 return (rt2x00dev->chip.rf == rf);
948} 941}
949 942
950static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset) 943static inline u16 rt2x00_rev(struct rt2x00_dev *rt2x00dev)
951{ 944{
952 return chipset->rev; 945 return rt2x00dev->chip.rev;
953}
954
955static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
956 const u32 mask, const u32 rev)
957{
958 return ((chipset->rev & mask) == rev);
959} 946}
960 947
961static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev, 948static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
@@ -964,20 +951,25 @@ static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
964 rt2x00dev->chip.intf = intf; 951 rt2x00dev->chip.intf = intf;
965} 952}
966 953
967static inline bool rt2x00_intf(const struct rt2x00_chip *chipset, 954static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev,
968 enum rt2x00_chip_intf intf) 955 enum rt2x00_chip_intf intf)
969{ 956{
970 return (chipset->intf == intf); 957 return (rt2x00dev->chip.intf == intf);
958}
959
960static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev)
961{
962 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
971} 963}
972 964
973static inline bool rt2x00_intf_is_pci(struct rt2x00_dev *rt2x00dev) 965static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev)
974{ 966{
975 return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_PCI); 967 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
976} 968}
977 969
978static inline bool rt2x00_intf_is_usb(struct rt2x00_dev *rt2x00dev) 970static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
979{ 971{
980 return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_USB); 972 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
981} 973}
982 974
983/** 975/**
@@ -1019,9 +1011,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
1019int rt2x00mac_start(struct ieee80211_hw *hw); 1011int rt2x00mac_start(struct ieee80211_hw *hw);
1020void rt2x00mac_stop(struct ieee80211_hw *hw); 1012void rt2x00mac_stop(struct ieee80211_hw *hw);
1021int rt2x00mac_add_interface(struct ieee80211_hw *hw, 1013int rt2x00mac_add_interface(struct ieee80211_hw *hw,
1022 struct ieee80211_if_init_conf *conf); 1014 struct ieee80211_vif *vif);
1023void rt2x00mac_remove_interface(struct ieee80211_hw *hw, 1015void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
1024 struct ieee80211_if_init_conf *conf); 1016 struct ieee80211_vif *vif);
1025int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed); 1017int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
1026void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 1018void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
1027 unsigned int changed_flags, 1019 unsigned int changed_flags,
@@ -1038,8 +1030,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1038#endif /* CONFIG_RT2X00_LIB_CRYPTO */ 1030#endif /* CONFIG_RT2X00_LIB_CRYPTO */
1039int rt2x00mac_get_stats(struct ieee80211_hw *hw, 1031int rt2x00mac_get_stats(struct ieee80211_hw *hw,
1040 struct ieee80211_low_level_stats *stats); 1032 struct ieee80211_low_level_stats *stats);
1041int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
1042 struct ieee80211_tx_queue_stats *stats);
1043void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, 1033void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
1044 struct ieee80211_vif *vif, 1034 struct ieee80211_vif *vif,
1045 struct ieee80211_bss_conf *bss_conf, 1035 struct ieee80211_bss_conf *bss_conf,
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 7d323a763b54..70c04c282efc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -184,7 +184,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
184 dump_hdr->data_length = cpu_to_le32(skb->len); 184 dump_hdr->data_length = cpu_to_le32(skb->len);
185 dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); 185 dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
186 dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); 186 dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
187 dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); 187 dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
188 dump_hdr->type = cpu_to_le16(type); 188 dump_hdr->type = cpu_to_le16(type);
189 dump_hdr->queue_index = desc->entry->queue->qid; 189 dump_hdr->queue_index = desc->entry->queue->qid;
190 dump_hdr->entry_index = desc->entry->entry_idx; 190 dump_hdr->entry_index = desc->entry->entry_idx;
@@ -573,7 +573,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
573 blob->data = data; 573 blob->data = data;
574 data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt); 574 data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
575 data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf); 575 data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
576 data += sprintf(data, "revision:\t%08x\n", intf->rt2x00dev->chip.rev); 576 data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
577 data += sprintf(data, "\n"); 577 data += sprintf(data, "\n");
578 data += sprintf(data, "register\tbase\twords\twordsize\n"); 578 data += sprintf(data, "register\tbase\twords\twordsize\n");
579 data += sprintf(data, "csr\t%d\t%d\t%d\n", 579 data += sprintf(data, "csr\t%d\t%d\t%d\n",
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 265e66dba552..b93731b79903 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -385,9 +385,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
385 memset(&rxdesc, 0, sizeof(rxdesc)); 385 memset(&rxdesc, 0, sizeof(rxdesc));
386 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 386 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
387 387
388 /* Trim buffer to correct size */
389 skb_trim(entry->skb, rxdesc.size);
390
391 /* 388 /*
392 * The data behind the ieee80211 header must be 389 * The data behind the ieee80211 header must be
393 * aligned on a 4 byte boundary. 390 * aligned on a 4 byte boundary.
@@ -404,11 +401,16 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
404 (rxdesc.flags & RX_FLAG_IV_STRIPPED)) 401 (rxdesc.flags & RX_FLAG_IV_STRIPPED))
405 rt2x00crypto_rx_insert_iv(entry->skb, header_length, 402 rt2x00crypto_rx_insert_iv(entry->skb, header_length,
406 &rxdesc); 403 &rxdesc);
407 else if (rxdesc.dev_flags & RXDONE_L2PAD) 404 else if (header_length &&
405 (rxdesc.size > header_length) &&
406 (rxdesc.dev_flags & RXDONE_L2PAD))
408 rt2x00queue_remove_l2pad(entry->skb, header_length); 407 rt2x00queue_remove_l2pad(entry->skb, header_length);
409 else 408 else
410 rt2x00queue_align_payload(entry->skb, header_length); 409 rt2x00queue_align_payload(entry->skb, header_length);
411 410
411 /* Trim buffer to correct size */
412 skb_trim(entry->skb, rxdesc.size);
413
412 /* 414 /*
413 * Check if the frame was received using HT. In that case, 415 * Check if the frame was received using HT. In that case,
414 * the rate is the MCS index and should be passed to mac80211 416 * the rate is the MCS index and should be passed to mac80211
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index de549c244ed8..abbd857ec759 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -187,10 +187,10 @@ void rt2x00mac_stop(struct ieee80211_hw *hw)
187EXPORT_SYMBOL_GPL(rt2x00mac_stop); 187EXPORT_SYMBOL_GPL(rt2x00mac_stop);
188 188
189int rt2x00mac_add_interface(struct ieee80211_hw *hw, 189int rt2x00mac_add_interface(struct ieee80211_hw *hw,
190 struct ieee80211_if_init_conf *conf) 190 struct ieee80211_vif *vif)
191{ 191{
192 struct rt2x00_dev *rt2x00dev = hw->priv; 192 struct rt2x00_dev *rt2x00dev = hw->priv;
193 struct rt2x00_intf *intf = vif_to_intf(conf->vif); 193 struct rt2x00_intf *intf = vif_to_intf(vif);
194 struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); 194 struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON);
195 struct queue_entry *entry = NULL; 195 struct queue_entry *entry = NULL;
196 unsigned int i; 196 unsigned int i;
@@ -203,7 +203,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
203 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) 203 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
204 return -ENODEV; 204 return -ENODEV;
205 205
206 switch (conf->type) { 206 switch (vif->type) {
207 case NL80211_IFTYPE_AP: 207 case NL80211_IFTYPE_AP:
208 /* 208 /*
209 * We don't support mixed combinations of 209 * We don't support mixed combinations of
@@ -263,7 +263,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
263 * increase interface count and start initialization. 263 * increase interface count and start initialization.
264 */ 264 */
265 265
266 if (conf->type == NL80211_IFTYPE_AP) 266 if (vif->type == NL80211_IFTYPE_AP)
267 rt2x00dev->intf_ap_count++; 267 rt2x00dev->intf_ap_count++;
268 else 268 else
269 rt2x00dev->intf_sta_count++; 269 rt2x00dev->intf_sta_count++;
@@ -273,16 +273,16 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
273 mutex_init(&intf->beacon_skb_mutex); 273 mutex_init(&intf->beacon_skb_mutex);
274 intf->beacon = entry; 274 intf->beacon = entry;
275 275
276 if (conf->type == NL80211_IFTYPE_AP) 276 if (vif->type == NL80211_IFTYPE_AP)
277 memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); 277 memcpy(&intf->bssid, vif->addr, ETH_ALEN);
278 memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); 278 memcpy(&intf->mac, vif->addr, ETH_ALEN);
279 279
280 /* 280 /*
281 * The MAC adddress must be configured after the device 281 * The MAC adddress must be configured after the device
282 * has been initialized. Otherwise the device can reset 282 * has been initialized. Otherwise the device can reset
283 * the MAC registers. 283 * the MAC registers.
284 */ 284 */
285 rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL); 285 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, intf->mac, NULL);
286 286
287 /* 287 /*
288 * Some filters depend on the current working mode. We can force 288 * Some filters depend on the current working mode. We can force
@@ -296,10 +296,10 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
296EXPORT_SYMBOL_GPL(rt2x00mac_add_interface); 296EXPORT_SYMBOL_GPL(rt2x00mac_add_interface);
297 297
298void rt2x00mac_remove_interface(struct ieee80211_hw *hw, 298void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
299 struct ieee80211_if_init_conf *conf) 299 struct ieee80211_vif *vif)
300{ 300{
301 struct rt2x00_dev *rt2x00dev = hw->priv; 301 struct rt2x00_dev *rt2x00dev = hw->priv;
302 struct rt2x00_intf *intf = vif_to_intf(conf->vif); 302 struct rt2x00_intf *intf = vif_to_intf(vif);
303 303
304 /* 304 /*
305 * Don't allow interfaces to be remove while 305 * Don't allow interfaces to be remove while
@@ -307,11 +307,11 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
307 * no interface is present. 307 * no interface is present.
308 */ 308 */
309 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || 309 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
310 (conf->type == NL80211_IFTYPE_AP && !rt2x00dev->intf_ap_count) || 310 (vif->type == NL80211_IFTYPE_AP && !rt2x00dev->intf_ap_count) ||
311 (conf->type != NL80211_IFTYPE_AP && !rt2x00dev->intf_sta_count)) 311 (vif->type != NL80211_IFTYPE_AP && !rt2x00dev->intf_sta_count))
312 return; 312 return;
313 313
314 if (conf->type == NL80211_IFTYPE_AP) 314 if (vif->type == NL80211_IFTYPE_AP)
315 rt2x00dev->intf_ap_count--; 315 rt2x00dev->intf_ap_count--;
316 else 316 else
317 rt2x00dev->intf_sta_count--; 317 rt2x00dev->intf_sta_count--;
@@ -555,22 +555,6 @@ int rt2x00mac_get_stats(struct ieee80211_hw *hw,
555} 555}
556EXPORT_SYMBOL_GPL(rt2x00mac_get_stats); 556EXPORT_SYMBOL_GPL(rt2x00mac_get_stats);
557 557
558int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
559 struct ieee80211_tx_queue_stats *stats)
560{
561 struct rt2x00_dev *rt2x00dev = hw->priv;
562 unsigned int i;
563
564 for (i = 0; i < rt2x00dev->ops->tx_queues; i++) {
565 stats[i].len = rt2x00dev->tx[i].length;
566 stats[i].limit = rt2x00dev->tx[i].limit;
567 stats[i].count = rt2x00dev->tx[i].count;
568 }
569
570 return 0;
571}
572EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
573
574void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, 558void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
575 struct ieee80211_vif *vif, 559 struct ieee80211_vif *vif,
576 struct ieee80211_bss_conf *bss_conf, 560 struct ieee80211_bss_conf *bss_conf,
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 0feb4d0e4668..047123b766fc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -41,6 +41,9 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
41{ 41{
42 unsigned int i; 42 unsigned int i;
43 43
44 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
45 return 0;
46
44 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 47 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
45 rt2x00pci_register_read(rt2x00dev, offset, reg); 48 rt2x00pci_register_read(rt2x00dev, offset, reg);
46 if (!rt2x00_get_field32(*reg, field)) 49 if (!rt2x00_get_field32(*reg, field))
@@ -269,7 +272,6 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
269 struct ieee80211_hw *hw; 272 struct ieee80211_hw *hw;
270 struct rt2x00_dev *rt2x00dev; 273 struct rt2x00_dev *rt2x00dev;
271 int retval; 274 int retval;
272 u16 chip;
273 275
274 retval = pci_request_regions(pci_dev, pci_name(pci_dev)); 276 retval = pci_request_regions(pci_dev, pci_name(pci_dev));
275 if (retval) { 277 if (retval) {
@@ -312,12 +314,6 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
312 314
313 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); 315 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
314 316
315 /*
316 * Determine RT chipset by reading PCI header.
317 */
318 pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
319 rt2x00_set_chip_rt(rt2x00dev, chip);
320
321 retval = rt2x00pci_alloc_reg(rt2x00dev); 317 retval = rt2x00pci_alloc_reg(rt2x00dev);
322 if (retval) 318 if (retval)
323 goto exit_free_device; 319 goto exit_free_device;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index d4f9449ab0a4..8149ff68410a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -27,6 +27,7 @@
27#define RT2X00PCI_H 27#define RT2X00PCI_H
28 28
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/pci.h>
30 31
31/* 32/*
32 * This variable should be used with the 33 * This variable should be used with the
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 9915a09141ef..0b4801a14601 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -177,55 +177,45 @@ void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
177 177
178void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) 178void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
179{ 179{
180 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 180 unsigned int payload_length = skb->len - header_length;
181 unsigned int frame_length = skb->len;
182 unsigned int header_align = ALIGN_SIZE(skb, 0); 181 unsigned int header_align = ALIGN_SIZE(skb, 0);
183 unsigned int payload_align = ALIGN_SIZE(skb, header_length); 182 unsigned int payload_align = ALIGN_SIZE(skb, header_length);
184 unsigned int l2pad = 4 - (payload_align - header_align); 183 unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
185 184
186 if (header_align == payload_align) { 185 /*
187 /* 186 * Adjust the header alignment if the payload needs to be moved more
188 * Both header and payload must be moved the same 187 * than the header.
189 * amount of bytes to align them properly. This means 188 */
190 * we don't use the L2 padding but just move the entire 189 if (payload_align > header_align)
191 * frame. 190 header_align += 4;
192 */ 191
193 rt2x00queue_align_frame(skb); 192 /* There is nothing to do if no alignment is needed */
194 } else if (!payload_align) { 193 if (!header_align)
195 /* 194 return;
196 * Simple L2 padding, only the header needs to be moved, 195
197 * the payload is already properly aligned. 196 /* Reserve the amount of space needed in front of the frame */
198 */ 197 skb_push(skb, header_align);
199 skb_push(skb, header_align); 198
200 memmove(skb->data, skb->data + header_align, frame_length); 199 /*
201 skbdesc->flags |= SKBDESC_L2_PADDED; 200 * Move the header.
202 } else { 201 */
203 /* 202 memmove(skb->data, skb->data + header_align, header_length);
204 *
205 * Complicated L2 padding, both header and payload need
206 * to be moved. By default we only move to the start
207 * of the buffer, so our header alignment needs to be
208 * increased if there is not enough room for the header
209 * to be moved.
210 */
211 if (payload_align > header_align)
212 header_align += 4;
213 203
214 skb_push(skb, header_align); 204 /* Move the payload, if present and if required */
215 memmove(skb->data, skb->data + header_align, header_length); 205 if (payload_length && payload_align)
216 memmove(skb->data + header_length + l2pad, 206 memmove(skb->data + header_length + l2pad,
217 skb->data + header_length + l2pad + payload_align, 207 skb->data + header_length + l2pad + payload_align,
218 frame_length - header_length); 208 payload_length);
219 skbdesc->flags |= SKBDESC_L2_PADDED; 209
220 } 210 /* Trim the skb to the correct size */
211 skb_trim(skb, header_length + l2pad + payload_length);
221} 212}
222 213
223void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) 214void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
224{ 215{
225 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 216 unsigned int l2pad = L2PAD_SIZE(header_length);
226 unsigned int l2pad = 4 - (header_length & 3);
227 217
228 if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED)) 218 if (!l2pad)
229 return; 219 return;
230 220
231 memmove(skb->data + l2pad, skb->data, header_length); 221 memmove(skb->data + l2pad, skb->data, header_length);
@@ -346,7 +336,9 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
346 * Header and alignment information. 336 * Header and alignment information.
347 */ 337 */
348 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 338 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
349 txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length); 339 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) &&
340 (entry->skb->len > txdesc->header_length))
341 txdesc->l2pad = L2PAD_SIZE(txdesc->header_length);
350 342
351 /* 343 /*
352 * Check whether this frame is to be acked. 344 * Check whether this frame is to be acked.
@@ -387,10 +379,13 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
387 379
388 /* 380 /*
389 * Beacons and probe responses require the tsf timestamp 381 * Beacons and probe responses require the tsf timestamp
390 * to be inserted into the frame. 382 * to be inserted into the frame, except for a frame that has been injected
383 * through a monitor interface. This latter is needed for testing a
384 * monitor interface.
391 */ 385 */
392 if (ieee80211_is_beacon(hdr->frame_control) || 386 if ((ieee80211_is_beacon(hdr->frame_control) ||
393 ieee80211_is_probe_resp(hdr->frame_control)) 387 ieee80211_is_probe_resp(hdr->frame_control)) &&
388 (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
394 __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); 389 __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
395 390
396 /* 391 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 70775e5ba1ac..c1e482bb37b3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -92,8 +92,6 @@ enum data_queue_qid {
92 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX 92 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
93 * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by 93 * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
94 * mac80211 but was stripped for processing by the driver. 94 * mac80211 but was stripped for processing by the driver.
95 * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
96 * the padded bytes are located between header and payload.
97 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211, 95 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
98 * don't try to pass it back. 96 * don't try to pass it back.
99 */ 97 */
@@ -101,8 +99,7 @@ enum skb_frame_desc_flags {
101 SKBDESC_DMA_MAPPED_RX = 1 << 0, 99 SKBDESC_DMA_MAPPED_RX = 1 << 0,
102 SKBDESC_DMA_MAPPED_TX = 1 << 1, 100 SKBDESC_DMA_MAPPED_TX = 1 << 1,
103 SKBDESC_IV_STRIPPED = 1 << 2, 101 SKBDESC_IV_STRIPPED = 1 << 2,
104 SKBDESC_L2_PADDED = 1 << 3, 102 SKBDESC_NOT_MAC80211 = 1 << 3,
105 SKBDESC_NOT_MAC80211 = 1 << 4,
106}; 103};
107 104
108/** 105/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c
index 19e684f8ffa1..4efdc96010f6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
@@ -71,9 +71,7 @@ exit:
71 return -ENOMEM; 71 return -ENOMEM;
72} 72}
73 73
74int rt2x00soc_probe(struct platform_device *pdev, 74int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops)
75 const unsigned short chipset,
76 const struct rt2x00_ops *ops)
77{ 75{
78 struct ieee80211_hw *hw; 76 struct ieee80211_hw *hw;
79 struct rt2x00_dev *rt2x00dev; 77 struct rt2x00_dev *rt2x00dev;
@@ -94,12 +92,7 @@ int rt2x00soc_probe(struct platform_device *pdev,
94 rt2x00dev->irq = platform_get_irq(pdev, 0); 92 rt2x00dev->irq = platform_get_irq(pdev, 0);
95 rt2x00dev->name = pdev->dev.driver->name; 93 rt2x00dev->name = pdev->dev.driver->name;
96 94
97 /* 95 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
98 * SoC devices mimic PCI behavior.
99 */
100 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
101
102 rt2x00_set_chip_rt(rt2x00dev, chipset);
103 96
104 retval = rt2x00soc_alloc_reg(rt2x00dev); 97 retval = rt2x00soc_alloc_reg(rt2x00dev);
105 if (retval) 98 if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h
index 8a3416624af5..4739edfe2f00 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.h
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.h
@@ -28,18 +28,10 @@
28 28
29#define KSEG1ADDR(__ptr) __ptr 29#define KSEG1ADDR(__ptr) __ptr
30 30
31#define __rt2x00soc_probe(__chipset, __ops) \
32static int __rt2x00soc_probe(struct platform_device *pdev) \
33{ \
34 return rt2x00soc_probe(pdev, (__chipset), (__ops)); \
35}
36
37/* 31/*
38 * SoC driver handlers. 32 * SoC driver handlers.
39 */ 33 */
40int rt2x00soc_probe(struct platform_device *pdev, 34int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops);
41 const unsigned short chipset,
42 const struct rt2x00_ops *ops);
43int rt2x00soc_remove(struct platform_device *pdev); 35int rt2x00soc_remove(struct platform_device *pdev);
44#ifdef CONFIG_PM 36#ifdef CONFIG_PM
45int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state); 37int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0ca589306d71..ee9c696fe1d4 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -637,8 +637,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
637 rt61pci_bbp_read(rt2x00dev, 4, &r4); 637 rt61pci_bbp_read(rt2x00dev, 4, &r4);
638 rt61pci_bbp_read(rt2x00dev, 77, &r77); 638 rt61pci_bbp_read(rt2x00dev, 77, &r77);
639 639
640 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 640 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF5325));
641 rt2x00_rf(&rt2x00dev->chip, RF5325));
642 641
643 /* 642 /*
644 * Configure the RX antenna. 643 * Configure the RX antenna.
@@ -684,8 +683,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
684 rt61pci_bbp_read(rt2x00dev, 4, &r4); 683 rt61pci_bbp_read(rt2x00dev, 4, &r4);
685 rt61pci_bbp_read(rt2x00dev, 77, &r77); 684 rt61pci_bbp_read(rt2x00dev, 77, &r77);
686 685
687 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 686 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529));
688 rt2x00_rf(&rt2x00dev->chip, RF2529));
689 rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 687 rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
690 !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); 688 !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
691 689
@@ -833,12 +831,11 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
833 831
834 rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); 832 rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
835 833
836 if (rt2x00_rf(&rt2x00dev->chip, RF5225) || 834 if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325))
837 rt2x00_rf(&rt2x00dev->chip, RF5325))
838 rt61pci_config_antenna_5x(rt2x00dev, ant); 835 rt61pci_config_antenna_5x(rt2x00dev, ant);
839 else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) 836 else if (rt2x00_rf(rt2x00dev, RF2527))
840 rt61pci_config_antenna_2x(rt2x00dev, ant); 837 rt61pci_config_antenna_2x(rt2x00dev, ant);
841 else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) { 838 else if (rt2x00_rf(rt2x00dev, RF2529)) {
842 if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) 839 if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
843 rt61pci_config_antenna_2x(rt2x00dev, ant); 840 rt61pci_config_antenna_2x(rt2x00dev, ant);
844 else 841 else
@@ -879,8 +876,7 @@ static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
879 rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); 876 rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
880 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); 877 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
881 878
882 smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) || 879 smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
883 rt2x00_rf(&rt2x00dev->chip, RF2527));
884 880
885 rt61pci_bbp_read(rt2x00dev, 3, &r3); 881 rt61pci_bbp_read(rt2x00dev, 3, &r3);
886 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart); 882 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
@@ -1135,16 +1131,18 @@ dynamic_cca_tune:
1135 */ 1131 */
1136static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) 1132static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
1137{ 1133{
1134 u16 chip;
1138 char *fw_name; 1135 char *fw_name;
1139 1136
1140 switch (rt2x00dev->chip.rt) { 1137 pci_read_config_word(to_pci_dev(rt2x00dev->dev), PCI_DEVICE_ID, &chip);
1141 case RT2561: 1138 switch (chip) {
1139 case RT2561_PCI_ID:
1142 fw_name = FIRMWARE_RT2561; 1140 fw_name = FIRMWARE_RT2561;
1143 break; 1141 break;
1144 case RT2561s: 1142 case RT2561s_PCI_ID:
1145 fw_name = FIRMWARE_RT2561s; 1143 fw_name = FIRMWARE_RT2561s;
1146 break; 1144 break;
1147 case RT2661: 1145 case RT2661_PCI_ID:
1148 fw_name = FIRMWARE_RT2661; 1146 fw_name = FIRMWARE_RT2661;
1149 break; 1147 break;
1150 default: 1148 default:
@@ -2299,13 +2297,13 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2299 */ 2297 */
2300 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 2298 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
2301 rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg); 2299 rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
2302 rt2x00_set_chip_rf(rt2x00dev, value, reg); 2300 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
2303 rt2x00_print_chip(rt2x00dev); 2301 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
2304 2302
2305 if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && 2303 if (!rt2x00_rf(rt2x00dev, RF5225) &&
2306 !rt2x00_rf(&rt2x00dev->chip, RF5325) && 2304 !rt2x00_rf(rt2x00dev, RF5325) &&
2307 !rt2x00_rf(&rt2x00dev->chip, RF2527) && 2305 !rt2x00_rf(rt2x00dev, RF2527) &&
2308 !rt2x00_rf(&rt2x00dev->chip, RF2529)) { 2306 !rt2x00_rf(rt2x00dev, RF2529)) {
2309 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 2307 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
2310 return -ENODEV; 2308 return -ENODEV;
2311 } 2309 }
@@ -2360,7 +2358,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2360 * the antenna settings should be gathered from the NIC 2358 * the antenna settings should be gathered from the NIC
2361 * eeprom word. 2359 * eeprom word.
2362 */ 2360 */
2363 if (rt2x00_rf(&rt2x00dev->chip, RF2529) && 2361 if (rt2x00_rf(rt2x00dev, RF2529) &&
2364 !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { 2362 !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
2365 rt2x00dev->default_ant.rx = 2363 rt2x00dev->default_ant.rx =
2366 ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); 2364 ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
@@ -2571,8 +2569,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2571 spec->channels = rf_vals_seq; 2569 spec->channels = rf_vals_seq;
2572 } 2570 }
2573 2571
2574 if (rt2x00_rf(&rt2x00dev->chip, RF5225) || 2572 if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) {
2575 rt2x00_rf(&rt2x00dev->chip, RF5325)) {
2576 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2573 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2577 spec->num_channels = ARRAY_SIZE(rf_vals_seq); 2574 spec->num_channels = ARRAY_SIZE(rf_vals_seq);
2578 } 2575 }
@@ -2735,7 +2732,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2735 .get_stats = rt2x00mac_get_stats, 2732 .get_stats = rt2x00mac_get_stats,
2736 .bss_info_changed = rt2x00mac_bss_info_changed, 2733 .bss_info_changed = rt2x00mac_bss_info_changed,
2737 .conf_tx = rt61pci_conf_tx, 2734 .conf_tx = rt61pci_conf_tx,
2738 .get_tx_stats = rt2x00mac_get_tx_stats,
2739 .get_tsf = rt61pci_get_tsf, 2735 .get_tsf = rt61pci_get_tsf,
2740 .rfkill_poll = rt2x00mac_rfkill_poll, 2736 .rfkill_poll = rt2x00mac_rfkill_poll,
2741}; 2737};
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6f33f7f5668c..ab20c7758824 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -28,6 +28,13 @@
28#define RT61PCI_H 28#define RT61PCI_H
29 29
30/* 30/*
31 * RT chip PCI IDs.
32 */
33#define RT2561s_PCI_ID 0x0301
34#define RT2561_PCI_ID 0x0302
35#define RT2661_PCI_ID 0x0401
36
37/*
31 * RF chip defines. 38 * RF chip defines.
32 */ 39 */
33#define RF5225 0x0001 40#define RF5225 0x0001
@@ -225,6 +232,8 @@ struct hw_pairwise_ta_entry {
225 * MAC_CSR0: ASIC revision number. 232 * MAC_CSR0: ASIC revision number.
226 */ 233 */
227#define MAC_CSR0 0x3000 234#define MAC_CSR0 0x3000
235#define MAC_CSR0_REVISION FIELD32(0x0000000f)
236#define MAC_CSR0_CHIPSET FIELD32(0x000ffff0)
228 237
229/* 238/*
230 * MAC_CSR1: System control register. 239 * MAC_CSR1: System control register.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ced3b6ab5e16..f39a8ed17841 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -136,8 +136,8 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
136 * all others contain 20 bits. 136 * all others contain 20 bits.
137 */ 137 */
138 rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS, 138 rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS,
139 20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) || 139 20 + (rt2x00_rf(rt2x00dev, RF5225) ||
140 rt2x00_rf(&rt2x00dev->chip, RF2527))); 140 rt2x00_rf(rt2x00dev, RF2527)));
141 rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0); 141 rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
142 rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1); 142 rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
143 143
@@ -741,11 +741,9 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
741 741
742 rt2x00usb_register_write(rt2x00dev, PHY_CSR0, reg); 742 rt2x00usb_register_write(rt2x00dev, PHY_CSR0, reg);
743 743
744 if (rt2x00_rf(&rt2x00dev->chip, RF5226) || 744 if (rt2x00_rf(rt2x00dev, RF5226) || rt2x00_rf(rt2x00dev, RF5225))
745 rt2x00_rf(&rt2x00dev->chip, RF5225))
746 rt73usb_config_antenna_5x(rt2x00dev, ant); 745 rt73usb_config_antenna_5x(rt2x00dev, ant);
747 else if (rt2x00_rf(&rt2x00dev->chip, RF2528) || 746 else if (rt2x00_rf(rt2x00dev, RF2528) || rt2x00_rf(rt2x00dev, RF2527))
748 rt2x00_rf(&rt2x00dev->chip, RF2527))
749 rt73usb_config_antenna_2x(rt2x00dev, ant); 747 rt73usb_config_antenna_2x(rt2x00dev, ant);
750} 748}
751 749
@@ -779,8 +777,7 @@ static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
779 rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); 777 rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
780 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); 778 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
781 779
782 smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) || 780 smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
783 rt2x00_rf(&rt2x00dev->chip, RF2527));
784 781
785 rt73usb_bbp_read(rt2x00dev, 3, &r3); 782 rt73usb_bbp_read(rt2x00dev, 3, &r3);
786 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart); 783 rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
@@ -1210,8 +1207,7 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
1210 rt2x00usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000); 1207 rt2x00usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
1211 1208
1212 reg = 0x000023b0; 1209 reg = 0x000023b0;
1213 if (rt2x00_rf(&rt2x00dev->chip, RF5225) || 1210 if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527))
1214 rt2x00_rf(&rt2x00dev->chip, RF2527))
1215 rt2x00_set_field32(&reg, PHY_CSR1_RF_RPI, 1); 1211 rt2x00_set_field32(&reg, PHY_CSR1_RF_RPI, 1);
1216 rt2x00usb_register_write(rt2x00dev, PHY_CSR1, reg); 1212 rt2x00usb_register_write(rt2x00dev, PHY_CSR1, reg);
1217 1213
@@ -1824,19 +1820,18 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1824 */ 1820 */
1825 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 1821 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
1826 rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg); 1822 rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
1827 rt2x00_set_chip(rt2x00dev, RT2571, value, reg); 1823 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
1828 rt2x00_print_chip(rt2x00dev); 1824 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
1829 1825
1830 if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) || 1826 if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) {
1831 rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
1832 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1827 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1833 return -ENODEV; 1828 return -ENODEV;
1834 } 1829 }
1835 1830
1836 if (!rt2x00_rf(&rt2x00dev->chip, RF5226) && 1831 if (!rt2x00_rf(rt2x00dev, RF5226) &&
1837 !rt2x00_rf(&rt2x00dev->chip, RF2528) && 1832 !rt2x00_rf(rt2x00dev, RF2528) &&
1838 !rt2x00_rf(&rt2x00dev->chip, RF5225) && 1833 !rt2x00_rf(rt2x00dev, RF5225) &&
1839 !rt2x00_rf(&rt2x00dev->chip, RF2527)) { 1834 !rt2x00_rf(rt2x00dev, RF2527)) {
1840 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1835 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1841 return -ENODEV; 1836 return -ENODEV;
1842 } 1837 }
@@ -2081,17 +2076,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2081 spec->supported_bands = SUPPORT_BAND_2GHZ; 2076 spec->supported_bands = SUPPORT_BAND_2GHZ;
2082 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 2077 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
2083 2078
2084 if (rt2x00_rf(&rt2x00dev->chip, RF2528)) { 2079 if (rt2x00_rf(rt2x00dev, RF2528)) {
2085 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); 2080 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
2086 spec->channels = rf_vals_bg_2528; 2081 spec->channels = rf_vals_bg_2528;
2087 } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { 2082 } else if (rt2x00_rf(rt2x00dev, RF5226)) {
2088 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2083 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2089 spec->num_channels = ARRAY_SIZE(rf_vals_5226); 2084 spec->num_channels = ARRAY_SIZE(rf_vals_5226);
2090 spec->channels = rf_vals_5226; 2085 spec->channels = rf_vals_5226;
2091 } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { 2086 } else if (rt2x00_rf(rt2x00dev, RF2527)) {
2092 spec->num_channels = 14; 2087 spec->num_channels = 14;
2093 spec->channels = rf_vals_5225_2527; 2088 spec->channels = rf_vals_5225_2527;
2094 } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { 2089 } else if (rt2x00_rf(rt2x00dev, RF5225)) {
2095 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2090 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2096 spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); 2091 spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
2097 spec->channels = rf_vals_5225_2527; 2092 spec->channels = rf_vals_5225_2527;
@@ -2249,7 +2244,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2249 .get_stats = rt2x00mac_get_stats, 2244 .get_stats = rt2x00mac_get_stats,
2250 .bss_info_changed = rt2x00mac_bss_info_changed, 2245 .bss_info_changed = rt2x00mac_bss_info_changed,
2251 .conf_tx = rt73usb_conf_tx, 2246 .conf_tx = rt73usb_conf_tx,
2252 .get_tx_stats = rt2x00mac_get_tx_stats,
2253 .get_tsf = rt73usb_get_tsf, 2247 .get_tsf = rt73usb_get_tsf,
2254 .rfkill_poll = rt2x00mac_rfkill_poll, 2248 .rfkill_poll = rt2x00mac_rfkill_poll,
2255}; 2249};
@@ -2354,6 +2348,7 @@ static struct usb_device_id rt73usb_device_table[] = {
2354 { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, 2348 { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
2355 /* Buffalo */ 2349 /* Buffalo */
2356 { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, 2350 { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
2351 { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) },
2357 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, 2352 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
2358 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, 2353 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
2359 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, 2354 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index e783a099a8f1..b4e3ddda06cf 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -142,6 +142,8 @@ struct hw_pairwise_ta_entry {
142 * MAC_CSR0: ASIC revision number. 142 * MAC_CSR0: ASIC revision number.
143 */ 143 */
144#define MAC_CSR0 0x3000 144#define MAC_CSR0 0x3000
145#define MAC_CSR0_REVISION FIELD32(0x0000000f)
146#define MAC_CSR0_CHIPSET FIELD32(0x000ffff0)
145 147
146/* 148/*
147 * MAC_CSR1: System control register. 149 * MAC_CSR1: System control register.
diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h
index 8721282a8185..de3844fe06d8 100644
--- a/drivers/net/wireless/rtl818x/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180.h
@@ -60,7 +60,6 @@ struct rtl8180_priv {
60 struct rtl818x_csr __iomem *map; 60 struct rtl818x_csr __iomem *map;
61 const struct rtl818x_rf_ops *rf; 61 const struct rtl818x_rf_ops *rf;
62 struct ieee80211_vif *vif; 62 struct ieee80211_vif *vif;
63 int mode;
64 63
65 /* rtl8180 driver specific */ 64 /* rtl8180 driver specific */
66 spinlock_t lock; 65 spinlock_t lock;
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 8a40a1439984..109ab1baf625 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -82,8 +82,6 @@ static const struct ieee80211_channel rtl818x_channels[] = {
82}; 82};
83 83
84 84
85
86
87void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) 85void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
88{ 86{
89 struct rtl8180_priv *priv = dev->priv; 87 struct rtl8180_priv *priv = dev->priv;
@@ -615,7 +613,6 @@ static int rtl8180_start(struct ieee80211_hw *dev)
615 reg |= RTL818X_CMD_TX_ENABLE; 613 reg |= RTL818X_CMD_TX_ENABLE;
616 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 614 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
617 615
618 priv->mode = NL80211_IFTYPE_MONITOR;
619 return 0; 616 return 0;
620 617
621 err_free_rings: 618 err_free_rings:
@@ -633,8 +630,6 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
633 u8 reg; 630 u8 reg;
634 int i; 631 int i;
635 632
636 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
637
638 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 633 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
639 634
640 reg = rtl818x_ioread8(priv, &priv->map->CMD); 635 reg = rtl818x_ioread8(priv, &priv->map->CMD);
@@ -657,38 +652,39 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
657} 652}
658 653
659static int rtl8180_add_interface(struct ieee80211_hw *dev, 654static int rtl8180_add_interface(struct ieee80211_hw *dev,
660 struct ieee80211_if_init_conf *conf) 655 struct ieee80211_vif *vif)
661{ 656{
662 struct rtl8180_priv *priv = dev->priv; 657 struct rtl8180_priv *priv = dev->priv;
663 658
664 if (priv->mode != NL80211_IFTYPE_MONITOR) 659 /*
665 return -EOPNOTSUPP; 660 * We only support one active interface at a time.
661 */
662 if (priv->vif)
663 return -EBUSY;
666 664
667 switch (conf->type) { 665 switch (vif->type) {
668 case NL80211_IFTYPE_STATION: 666 case NL80211_IFTYPE_STATION:
669 priv->mode = conf->type;
670 break; 667 break;
671 default: 668 default:
672 return -EOPNOTSUPP; 669 return -EOPNOTSUPP;
673 } 670 }
674 671
675 priv->vif = conf->vif; 672 priv->vif = vif;
676 673
677 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 674 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
678 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], 675 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
679 le32_to_cpu(*(__le32 *)conf->mac_addr)); 676 le32_to_cpu(*(__le32 *)vif->addr));
680 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], 677 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
681 le16_to_cpu(*(__le16 *)(conf->mac_addr + 4))); 678 le16_to_cpu(*(__le16 *)(vif->addr + 4)));
682 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 679 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
683 680
684 return 0; 681 return 0;
685} 682}
686 683
687static void rtl8180_remove_interface(struct ieee80211_hw *dev, 684static void rtl8180_remove_interface(struct ieee80211_hw *dev,
688 struct ieee80211_if_init_conf *conf) 685 struct ieee80211_vif *vif)
689{ 686{
690 struct rtl8180_priv *priv = dev->priv; 687 struct rtl8180_priv *priv = dev->priv;
691 priv->mode = NL80211_IFTYPE_MONITOR;
692 priv->vif = NULL; 688 priv->vif = NULL;
693} 689}
694 690
@@ -765,6 +761,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
765 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 761 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
766} 762}
767 763
764static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
765{
766 struct rtl8180_priv *priv = dev->priv;
767
768 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
769 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
770}
771
768static const struct ieee80211_ops rtl8180_ops = { 772static const struct ieee80211_ops rtl8180_ops = {
769 .tx = rtl8180_tx, 773 .tx = rtl8180_tx,
770 .start = rtl8180_start, 774 .start = rtl8180_start,
@@ -775,6 +779,7 @@ static const struct ieee80211_ops rtl8180_ops = {
775 .bss_info_changed = rtl8180_bss_info_changed, 779 .bss_info_changed = rtl8180_bss_info_changed,
776 .prepare_multicast = rtl8180_prepare_multicast, 780 .prepare_multicast = rtl8180_prepare_multicast,
777 .configure_filter = rtl8180_configure_filter, 781 .configure_filter = rtl8180_configure_filter,
782 .get_tsf = rtl8180_get_tsf,
778}; 783};
779 784
780static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) 785static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 6af0f3f71f3a..6bb32112e65c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -92,7 +92,7 @@ struct rtl8187_priv {
92 struct rtl818x_csr *map; 92 struct rtl818x_csr *map;
93 const struct rtl818x_rf_ops *rf; 93 const struct rtl818x_rf_ops *rf;
94 struct ieee80211_vif *vif; 94 struct ieee80211_vif *vif;
95 int mode; 95
96 /* The mutex protects the TX loopback state. 96 /* The mutex protects the TX loopback state.
97 * Any attempt to set channels concurrently locks the device. 97 * Any attempt to set channels concurrently locks the device.
98 */ 98 */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 7ba3052b0708..0fb850e0c656 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1019,31 +1019,30 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
1019} 1019}
1020 1020
1021static int rtl8187_add_interface(struct ieee80211_hw *dev, 1021static int rtl8187_add_interface(struct ieee80211_hw *dev,
1022 struct ieee80211_if_init_conf *conf) 1022 struct ieee80211_vif *vif)
1023{ 1023{
1024 struct rtl8187_priv *priv = dev->priv; 1024 struct rtl8187_priv *priv = dev->priv;
1025 int i; 1025 int i;
1026 int ret = -EOPNOTSUPP; 1026 int ret = -EOPNOTSUPP;
1027 1027
1028 mutex_lock(&priv->conf_mutex); 1028 mutex_lock(&priv->conf_mutex);
1029 if (priv->mode != NL80211_IFTYPE_MONITOR) 1029 if (priv->vif)
1030 goto exit; 1030 goto exit;
1031 1031
1032 switch (conf->type) { 1032 switch (vif->type) {
1033 case NL80211_IFTYPE_STATION: 1033 case NL80211_IFTYPE_STATION:
1034 priv->mode = conf->type;
1035 break; 1034 break;
1036 default: 1035 default:
1037 goto exit; 1036 goto exit;
1038 } 1037 }
1039 1038
1040 ret = 0; 1039 ret = 0;
1041 priv->vif = conf->vif; 1040 priv->vif = vif;
1042 1041
1043 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 1042 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1044 for (i = 0; i < ETH_ALEN; i++) 1043 for (i = 0; i < ETH_ALEN; i++)
1045 rtl818x_iowrite8(priv, &priv->map->MAC[i], 1044 rtl818x_iowrite8(priv, &priv->map->MAC[i],
1046 ((u8 *)conf->mac_addr)[i]); 1045 ((u8 *)vif->addr)[i]);
1047 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1046 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1048 1047
1049exit: 1048exit:
@@ -1052,11 +1051,10 @@ exit:
1052} 1051}
1053 1052
1054static void rtl8187_remove_interface(struct ieee80211_hw *dev, 1053static void rtl8187_remove_interface(struct ieee80211_hw *dev,
1055 struct ieee80211_if_init_conf *conf) 1054 struct ieee80211_vif *vif)
1056{ 1055{
1057 struct rtl8187_priv *priv = dev->priv; 1056 struct rtl8187_priv *priv = dev->priv;
1058 mutex_lock(&priv->conf_mutex); 1057 mutex_lock(&priv->conf_mutex);
1059 priv->mode = NL80211_IFTYPE_MONITOR;
1060 priv->vif = NULL; 1058 priv->vif = NULL;
1061 mutex_unlock(&priv->conf_mutex); 1059 mutex_unlock(&priv->conf_mutex);
1062} 1060}
@@ -1268,6 +1266,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
1268 return 0; 1266 return 0;
1269} 1267}
1270 1268
1269static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
1270{
1271 struct rtl8187_priv *priv = dev->priv;
1272
1273 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
1274 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
1275}
1276
1271static const struct ieee80211_ops rtl8187_ops = { 1277static const struct ieee80211_ops rtl8187_ops = {
1272 .tx = rtl8187_tx, 1278 .tx = rtl8187_tx,
1273 .start = rtl8187_start, 1279 .start = rtl8187_start,
@@ -1279,7 +1285,8 @@ static const struct ieee80211_ops rtl8187_ops = {
1279 .prepare_multicast = rtl8187_prepare_multicast, 1285 .prepare_multicast = rtl8187_prepare_multicast,
1280 .configure_filter = rtl8187_configure_filter, 1286 .configure_filter = rtl8187_configure_filter,
1281 .conf_tx = rtl8187_conf_tx, 1287 .conf_tx = rtl8187_conf_tx,
1282 .rfkill_poll = rtl8187_rfkill_poll 1288 .rfkill_poll = rtl8187_rfkill_poll,
1289 .get_tsf = rtl8187_get_tsf,
1283}; 1290};
1284 1291
1285static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 1292static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -1366,7 +1373,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1366 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 1373 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1367 1374
1368 1375
1369 priv->mode = NL80211_IFTYPE_MONITOR;
1370 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1376 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1371 IEEE80211_HW_SIGNAL_DBM | 1377 IEEE80211_HW_SIGNAL_DBM |
1372 IEEE80211_HW_RX_INCLUDES_FCS; 1378 IEEE80211_HW_RX_INCLUDES_FCS;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index ded44c045eb2..4637337d5ce6 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -33,7 +33,7 @@ static void led_turn_on(struct work_struct *work)
33 struct rtl8187_led *led = &priv->led_tx; 33 struct rtl8187_led *led = &priv->led_tx;
34 34
35 /* Don't change the LED, when the device is down. */ 35 /* Don't change the LED, when the device is down. */
36 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) 36 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
37 return ; 37 return ;
38 38
39 /* Skip if the LED is not registered. */ 39 /* Skip if the LED is not registered. */
@@ -71,7 +71,7 @@ static void led_turn_off(struct work_struct *work)
71 struct rtl8187_led *led = &priv->led_tx; 71 struct rtl8187_led *led = &priv->led_tx;
72 72
73 /* Don't change the LED, when the device is down. */ 73 /* Don't change the LED, when the device is down. */
74 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) 74 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
75 return ; 75 return ;
76 76
77 /* Skip if the LED is not registered. */ 77 /* Skip if the LED is not registered. */
@@ -241,5 +241,5 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
241 cancel_delayed_work_sync(&priv->led_off); 241 cancel_delayed_work_sync(&priv->led_off);
242 cancel_delayed_work_sync(&priv->led_on); 242 cancel_delayed_work_sync(&priv->led_on);
243} 243}
244#endif /* def CONFIG_RTL8187_LED */ 244#endif /* def CONFIG_RTL8187_LEDS */
245 245
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
index efe8041bdda4..d743c96d4a20 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.h
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h
@@ -54,6 +54,6 @@ struct rtl8187_led {
54void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); 54void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
55void rtl8187_leds_exit(struct ieee80211_hw *dev); 55void rtl8187_leds_exit(struct ieee80211_hw *dev);
56 56
57#endif /* def CONFIG_RTL8187_LED */ 57#endif /* def CONFIG_RTL8187_LEDS */
58 58
59#endif /* RTL8187_LED_H */ 59#endif /* RTL8187_LED_H */
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 62e37ad01cc0..f47ec94c16dc 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -10,5 +10,7 @@ obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
10wl1271-objs = wl1271_main.o wl1271_spi.o wl1271_cmd.o \ 10wl1271-objs = wl1271_main.o wl1271_spi.o wl1271_cmd.o \
11 wl1271_event.o wl1271_tx.o wl1271_rx.o \ 11 wl1271_event.o wl1271_tx.o wl1271_rx.o \
12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \ 12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \
13 wl1271_init.o wl1271_debugfs.o 13 wl1271_init.o wl1271_debugfs.o wl1271_io.o
14
15wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
14obj-$(CONFIG_WL1271) += wl1271.o 16obj-$(CONFIG_WL1271) += wl1271.o
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 054533f7a124..37c61c19cae5 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -247,6 +247,7 @@ struct wl1251_debugfs {
247 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; 247 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
248 248
249 struct dentry *tx_queue_len; 249 struct dentry *tx_queue_len;
250 struct dentry *tx_queue_status;
250 251
251 struct dentry *retry_count; 252 struct dentry *retry_count;
252 struct dentry *excessive_retries; 253 struct dentry *excessive_retries;
@@ -340,9 +341,6 @@ struct wl1251 {
340 /* Are we currently scanning */ 341 /* Are we currently scanning */
341 bool scanning; 342 bool scanning;
342 343
343 /* Our association ID */
344 u16 aid;
345
346 /* Default key (for WEP) */ 344 /* Default key (for WEP) */
347 u32 default_key; 345 u32 default_key;
348 346
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index acfa086dbfc5..beff084040b5 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -976,3 +976,72 @@ out:
976 kfree(acx); 976 kfree(acx);
977 return ret; 977 return ret;
978} 978}
979
980int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
981 u8 aifs, u16 txop)
982{
983 struct wl1251_acx_ac_cfg *acx;
984 int ret = 0;
985
986 wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
987 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
988
989 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
990
991 if (!acx) {
992 ret = -ENOMEM;
993 goto out;
994 }
995
996 acx->ac = ac;
997 acx->cw_min = cw_min;
998 acx->cw_max = cw_max;
999 acx->aifsn = aifs;
1000 acx->txop_limit = txop;
1001
1002 ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
1003 if (ret < 0) {
1004 wl1251_warning("acx ac cfg failed: %d", ret);
1005 goto out;
1006 }
1007
1008out:
1009 kfree(acx);
1010 return ret;
1011}
1012
1013int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1014 enum wl1251_acx_channel_type type,
1015 u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1016 enum wl1251_acx_ack_policy ack_policy)
1017{
1018 struct wl1251_acx_tid_cfg *acx;
1019 int ret = 0;
1020
1021 wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
1022 "ps_scheme %d ack_policy %d", queue, type, tsid,
1023 ps_scheme, ack_policy);
1024
1025 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1026
1027 if (!acx) {
1028 ret = -ENOMEM;
1029 goto out;
1030 }
1031
1032 acx->queue = queue;
1033 acx->type = type;
1034 acx->tsid = tsid;
1035 acx->ps_scheme = ps_scheme;
1036 acx->ack_policy = ack_policy;
1037
1038 ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
1039 if (ret < 0) {
1040 wl1251_warning("acx tid cfg failed: %d", ret);
1041 goto out;
1042 }
1043
1044out:
1045 kfree(acx);
1046 return ret;
1047}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
index 652371432cd8..26160c45784c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -1166,6 +1166,87 @@ struct wl1251_acx_wr_tbtt_and_dtim {
1166 u8 padding; 1166 u8 padding;
1167} __attribute__ ((packed)); 1167} __attribute__ ((packed));
1168 1168
1169struct wl1251_acx_ac_cfg {
1170 struct acx_header header;
1171
1172 /*
1173 * Access Category - The TX queue's access category
1174 * (refer to AccessCategory_enum)
1175 */
1176 u8 ac;
1177
1178 /*
1179 * The contention window minimum size (in slots) for
1180 * the access class.
1181 */
1182 u8 cw_min;
1183
1184 /*
1185 * The contention window maximum size (in slots) for
1186 * the access class.
1187 */
1188 u16 cw_max;
1189
1190 /* The AIF value (in slots) for the access class. */
1191 u8 aifsn;
1192
1193 u8 reserved;
1194
1195 /* The TX Op Limit (in microseconds) for the access class. */
1196 u16 txop_limit;
1197} __attribute__ ((packed));
1198
1199
1200enum wl1251_acx_channel_type {
1201 CHANNEL_TYPE_DCF = 0,
1202 CHANNEL_TYPE_EDCF = 1,
1203 CHANNEL_TYPE_HCCA = 2,
1204};
1205
1206enum wl1251_acx_ps_scheme {
1207 /* regular ps: simple sending of packets */
1208 WL1251_ACX_PS_SCHEME_LEGACY = 0,
1209
1210 /* sending a packet triggers a unscheduled apsd downstream */
1211 WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
1212
1213 /* a pspoll packet will be sent before every data packet */
1214 WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
1215
1216 /* scheduled apsd mode */
1217 WL1251_ACX_PS_SCHEME_SAPSD = 3,
1218};
1219
1220enum wl1251_acx_ack_policy {
1221 WL1251_ACX_ACK_POLICY_LEGACY = 0,
1222 WL1251_ACX_ACK_POLICY_NO_ACK = 1,
1223 WL1251_ACX_ACK_POLICY_BLOCK = 2,
1224};
1225
1226struct wl1251_acx_tid_cfg {
1227 struct acx_header header;
1228
1229 /* tx queue id number (0-7) */
1230 u8 queue;
1231
1232 /* channel access type for the queue, enum wl1251_acx_channel_type */
1233 u8 type;
1234
1235 /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
1236 u8 tsid;
1237
1238 /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
1239 u8 ps_scheme;
1240
1241 /* the tx queue ack policy, enum wl1251_acx_ack_policy */
1242 u8 ack_policy;
1243
1244 u8 padding[3];
1245
1246 /* not supported */
1247 u32 apsdconf[2];
1248} __attribute__ ((packed));
1249
1169/************************************************************************* 1250/*************************************************************************
1170 1251
1171 Host Interrupt Register (WiLink -> Host) 1252 Host Interrupt Register (WiLink -> Host)
@@ -1322,5 +1403,11 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
1322int wl1251_acx_rate_policies(struct wl1251 *wl); 1403int wl1251_acx_rate_policies(struct wl1251 *wl);
1323int wl1251_acx_mem_cfg(struct wl1251 *wl); 1404int wl1251_acx_mem_cfg(struct wl1251 *wl);
1324int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); 1405int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
1406int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1407 u8 aifs, u16 txop);
1408int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1409 enum wl1251_acx_channel_type type,
1410 u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1411 enum wl1251_acx_ack_policy ack_policy);
1325 1412
1326#endif /* __WL1251_ACX_H__ */ 1413#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index 770f260726bd..0320b478bb3f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -410,3 +410,86 @@ out:
410 kfree(cmd); 410 kfree(cmd);
411 return ret; 411 return ret;
412} 412}
413
414int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
415 struct ieee80211_channel *channels[],
416 unsigned int n_channels, unsigned int n_probes)
417{
418 struct wl1251_cmd_scan *cmd;
419 int i, ret = 0;
420
421 wl1251_debug(DEBUG_CMD, "cmd scan");
422
423 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
424 if (!cmd)
425 return -ENOMEM;
426
427 cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
428 cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
429 CFG_RX_MGMT_EN |
430 CFG_RX_BCN_EN);
431 cmd->params.scan_options = 0;
432 cmd->params.num_channels = n_channels;
433 cmd->params.num_probe_requests = n_probes;
434 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
435 cmd->params.tid_trigger = 0;
436
437 for (i = 0; i < n_channels; i++) {
438 cmd->channels[i].min_duration =
439 cpu_to_le32(WL1251_SCAN_MIN_DURATION);
440 cmd->channels[i].max_duration =
441 cpu_to_le32(WL1251_SCAN_MAX_DURATION);
442 memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
443 memset(&cmd->channels[i].bssid_msb, 0xff, 2);
444 cmd->channels[i].early_termination = 0;
445 cmd->channels[i].tx_power_att = 0;
446 cmd->channels[i].channel = channels[i]->hw_value;
447 }
448
449 cmd->params.ssid_len = ssid_len;
450 if (ssid)
451 memcpy(cmd->params.ssid, ssid, ssid_len);
452
453 ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
454 if (ret < 0) {
455 wl1251_error("cmd scan failed: %d", ret);
456 goto out;
457 }
458
459 wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
460
461 if (cmd->header.status != CMD_STATUS_SUCCESS) {
462 wl1251_error("cmd scan status wasn't success: %d",
463 cmd->header.status);
464 ret = -EIO;
465 goto out;
466 }
467
468out:
469 kfree(cmd);
470 return ret;
471}
472
473int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
474{
475 struct wl1251_cmd_trigger_scan_to *cmd;
476 int ret;
477
478 wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
479
480 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
481 if (!cmd)
482 return -ENOMEM;
483
484 cmd->timeout = timeout;
485
486 ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
487 if (ret < 0) {
488 wl1251_error("cmd trigger scan to failed: %d", ret);
489 goto out;
490 }
491
492out:
493 kfree(cmd);
494 return ret;
495}
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
index dff798ad0ef5..4ad67cae94d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h
@@ -27,6 +27,8 @@
27 27
28#include "wl1251.h" 28#include "wl1251.h"
29 29
30#include <net/cfg80211.h>
31
30struct acx_header; 32struct acx_header;
31 33
32int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len); 34int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
@@ -43,6 +45,10 @@ int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
43 size_t len); 45 size_t len);
44int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, 46int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
45 void *buf, size_t buf_len); 47 void *buf, size_t buf_len);
48int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
49 struct ieee80211_channel *channels[],
50 unsigned int n_channels, unsigned int n_probes);
51int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
46 52
47/* unit ms */ 53/* unit ms */
48#define WL1251_COMMAND_TIMEOUT 2000 54#define WL1251_COMMAND_TIMEOUT 2000
@@ -163,8 +169,12 @@ struct cmd_read_write_memory {
163#define CMDMBOX_HEADER_LEN 4 169#define CMDMBOX_HEADER_LEN 4
164#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 170#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
165 171
172#define WL1251_SCAN_MIN_DURATION 30000
173#define WL1251_SCAN_MAX_DURATION 60000
174
175#define WL1251_SCAN_NUM_PROBES 3
166 176
167struct basic_scan_parameters { 177struct wl1251_scan_parameters {
168 u32 rx_config_options; 178 u32 rx_config_options;
169 u32 rx_filter_options; 179 u32 rx_filter_options;
170 180
@@ -189,11 +199,11 @@ struct basic_scan_parameters {
189 199
190 u8 tid_trigger; 200 u8 tid_trigger;
191 u8 ssid_len; 201 u8 ssid_len;
192 u32 ssid[8]; 202 u8 ssid[32];
193 203
194} __attribute__ ((packed)); 204} __attribute__ ((packed));
195 205
196struct basic_scan_channel_parameters { 206struct wl1251_scan_ch_parameters {
197 u32 min_duration; /* in TU */ 207 u32 min_duration; /* in TU */
198 u32 max_duration; /* in TU */ 208 u32 max_duration; /* in TU */
199 u32 bssid_lsb; 209 u32 bssid_lsb;
@@ -213,11 +223,11 @@ struct basic_scan_channel_parameters {
213/* SCAN parameters */ 223/* SCAN parameters */
214#define SCAN_MAX_NUM_OF_CHANNELS 16 224#define SCAN_MAX_NUM_OF_CHANNELS 16
215 225
216struct cmd_scan { 226struct wl1251_cmd_scan {
217 struct wl1251_cmd_header header; 227 struct wl1251_cmd_header header;
218 228
219 struct basic_scan_parameters params; 229 struct wl1251_scan_parameters params;
220 struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; 230 struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
221} __attribute__ ((packed)); 231} __attribute__ ((packed));
222 232
223enum { 233enum {
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index a00723059f83..0ccba57fb9fb 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -237,6 +237,27 @@ static const struct file_operations tx_queue_len_ops = {
237 .open = wl1251_open_file_generic, 237 .open = wl1251_open_file_generic,
238}; 238};
239 239
240static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
241 size_t count, loff_t *ppos)
242{
243 struct wl1251 *wl = file->private_data;
244 char buf[3], status;
245 int len;
246
247 if (wl->tx_queue_stopped)
248 status = 's';
249 else
250 status = 'r';
251
252 len = scnprintf(buf, sizeof(buf), "%c\n", status);
253 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
254}
255
256static const struct file_operations tx_queue_status_ops = {
257 .read = tx_queue_status_read,
258 .open = wl1251_open_file_generic,
259};
260
240static void wl1251_debugfs_delete_files(struct wl1251 *wl) 261static void wl1251_debugfs_delete_files(struct wl1251 *wl)
241{ 262{
242 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); 263 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -331,6 +352,7 @@ static void wl1251_debugfs_delete_files(struct wl1251 *wl)
331 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); 352 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
332 353
333 DEBUGFS_DEL(tx_queue_len); 354 DEBUGFS_DEL(tx_queue_len);
355 DEBUGFS_DEL(tx_queue_status);
334 DEBUGFS_DEL(retry_count); 356 DEBUGFS_DEL(retry_count);
335 DEBUGFS_DEL(excessive_retries); 357 DEBUGFS_DEL(excessive_retries);
336} 358}
@@ -431,6 +453,7 @@ static int wl1251_debugfs_add_files(struct wl1251 *wl)
431 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); 453 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
432 454
433 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); 455 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
456 DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
434 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); 457 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
435 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); 458 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
436 459
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
index 5cb573383eeb..5aad56ea7153 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -294,6 +294,11 @@ static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
294 goto out; 294 goto out;
295 } 295 }
296 296
297 wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
298 wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
299 wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
300 wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
301
297out: 302out:
298 kfree(config); 303 kfree(config);
299 return ret; 304 return ret;
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
index b3b25ec885ea..269cefb3e7d4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl12xx/wl1251_init.h
@@ -26,6 +26,53 @@
26 26
27#include "wl1251.h" 27#include "wl1251.h"
28 28
29enum {
30 /* best effort/legacy */
31 AC_BE = 0,
32
33 /* background */
34 AC_BK = 1,
35
36 /* video */
37 AC_VI = 2,
38
39 /* voice */
40 AC_VO = 3,
41
42 /* broadcast dummy access category */
43 AC_BCAST = 4,
44
45 NUM_ACCESS_CATEGORIES = 4
46};
47
48/* following are defult values for the IE fields*/
49#define CWMIN_BK 15
50#define CWMIN_BE 15
51#define CWMIN_VI 7
52#define CWMIN_VO 3
53#define CWMAX_BK 1023
54#define CWMAX_BE 63
55#define CWMAX_VI 15
56#define CWMAX_VO 7
57
58/* slot number setting to start transmission at PIFS interval */
59#define AIFS_PIFS 1
60
61/*
62 * slot number setting to start transmission at DIFS interval - normal DCF
63 * access
64 */
65#define AIFS_DIFS 2
66
67#define AIFSN_BK 7
68#define AIFSN_BE 3
69#define AIFSN_VI AIFS_PIFS
70#define AIFSN_VO AIFS_PIFS
71#define TXOP_BK 0
72#define TXOP_BE 0
73#define TXOP_VI 3008
74#define TXOP_VO 1504
75
29int wl1251_hw_init_hwenc_config(struct wl1251 *wl); 76int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
30int wl1251_hw_init_templates_config(struct wl1251 *wl); 77int wl1251_hw_init_templates_config(struct wl1251 *wl);
31int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter); 78int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 2f50a256efa5..24ae6a360ac8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -395,6 +395,7 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
395 * the queue here, otherwise the queue will get too long. 395 * the queue here, otherwise the queue will get too long.
396 */ 396 */
397 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) { 397 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
398 wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
398 ieee80211_stop_queues(wl->hw); 399 ieee80211_stop_queues(wl->hw);
399 400
400 /* 401 /*
@@ -510,13 +511,13 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
510} 511}
511 512
512static int wl1251_op_add_interface(struct ieee80211_hw *hw, 513static int wl1251_op_add_interface(struct ieee80211_hw *hw,
513 struct ieee80211_if_init_conf *conf) 514 struct ieee80211_vif *vif)
514{ 515{
515 struct wl1251 *wl = hw->priv; 516 struct wl1251 *wl = hw->priv;
516 int ret = 0; 517 int ret = 0;
517 518
518 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 519 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
519 conf->type, conf->mac_addr); 520 vif->type, vif->addr);
520 521
521 mutex_lock(&wl->mutex); 522 mutex_lock(&wl->mutex);
522 if (wl->vif) { 523 if (wl->vif) {
@@ -524,9 +525,9 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
524 goto out; 525 goto out;
525 } 526 }
526 527
527 wl->vif = conf->vif; 528 wl->vif = vif;
528 529
529 switch (conf->type) { 530 switch (vif->type) {
530 case NL80211_IFTYPE_STATION: 531 case NL80211_IFTYPE_STATION:
531 wl->bss_type = BSS_TYPE_STA_BSS; 532 wl->bss_type = BSS_TYPE_STA_BSS;
532 break; 533 break;
@@ -538,8 +539,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
538 goto out; 539 goto out;
539 } 540 }
540 541
541 if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) { 542 if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
542 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 543 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
543 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); 544 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
544 ret = wl1251_acx_station_id(wl); 545 ret = wl1251_acx_station_id(wl);
545 if (ret < 0) 546 if (ret < 0)
@@ -552,7 +553,7 @@ out:
552} 553}
553 554
554static void wl1251_op_remove_interface(struct ieee80211_hw *hw, 555static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
555 struct ieee80211_if_init_conf *conf) 556 struct ieee80211_vif *vif)
556{ 557{
557 struct wl1251 *wl = hw->priv; 558 struct wl1251 *wl = hw->priv;
558 559
@@ -562,43 +563,25 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
562 mutex_unlock(&wl->mutex); 563 mutex_unlock(&wl->mutex);
563} 564}
564 565
565static int wl1251_build_null_data(struct wl1251 *wl) 566static int wl1251_build_qos_null_data(struct wl1251 *wl)
566{ 567{
567 struct wl12xx_null_data_template template; 568 struct ieee80211_qos_hdr template;
568 569
569 if (!is_zero_ether_addr(wl->bssid)) { 570 memset(&template, 0, sizeof(template));
570 memcpy(template.header.da, wl->bssid, ETH_ALEN);
571 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
572 } else {
573 memset(template.header.da, 0xff, ETH_ALEN);
574 memset(template.header.bssid, 0xff, ETH_ALEN);
575 }
576
577 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
578 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
579 IEEE80211_STYPE_NULLFUNC |
580 IEEE80211_FCTL_TODS);
581
582 return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
583 sizeof(template));
584
585}
586
587static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
588{
589 struct wl12xx_ps_poll_template template;
590 571
591 memcpy(template.bssid, wl->bssid, ETH_ALEN); 572 memcpy(template.addr1, wl->bssid, ETH_ALEN);
592 memcpy(template.ta, wl->mac_addr, ETH_ALEN); 573 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
574 memcpy(template.addr3, wl->bssid, ETH_ALEN);
593 575
594 /* aid in PS-Poll has its two MSBs each set to 1 */ 576 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
595 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid); 577 IEEE80211_STYPE_QOS_NULLFUNC |
578 IEEE80211_FCTL_TODS);
596 579
597 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 580 /* FIXME: not sure what priority to use here */
581 template.qos_ctrl = cpu_to_le16(0);
598 582
599 return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, 583 return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
600 sizeof(template)); 584 sizeof(template));
601
602} 585}
603 586
604static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) 587static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
@@ -634,26 +617,34 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
634 617
635 wl->psm_requested = true; 618 wl->psm_requested = true;
636 619
620 wl->dtim_period = conf->ps_dtim_period;
621
622 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
623 wl->dtim_period);
624
637 /* 625 /*
638 * We enter PSM only if we're already associated. 626 * mac80211 enables PSM only if we're already associated.
639 * If we're not, we'll enter it when joining an SSID,
640 * through the bss_info_changed() hook.
641 */ 627 */
642 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 628 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
629 if (ret < 0)
630 goto out_sleep;
643 } else if (!(conf->flags & IEEE80211_CONF_PS) && 631 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
644 wl->psm_requested) { 632 wl->psm_requested) {
645 wl1251_debug(DEBUG_PSM, "psm disabled"); 633 wl1251_debug(DEBUG_PSM, "psm disabled");
646 634
647 wl->psm_requested = false; 635 wl->psm_requested = false;
648 636
649 if (wl->psm) 637 if (wl->psm) {
650 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 638 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
639 if (ret < 0)
640 goto out_sleep;
641 }
651 } 642 }
652 643
653 if (conf->power_level != wl->power_level) { 644 if (conf->power_level != wl->power_level) {
654 ret = wl1251_acx_tx_power(wl, conf->power_level); 645 ret = wl1251_acx_tx_power(wl, conf->power_level);
655 if (ret < 0) 646 if (ret < 0)
656 goto out; 647 goto out_sleep;
657 648
658 wl->power_level = conf->power_level; 649 wl->power_level = conf->power_level;
659 } 650 }
@@ -864,199 +855,61 @@ out:
864 return ret; 855 return ret;
865} 856}
866 857
867static int wl1251_build_basic_rates(char *rates) 858static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
868{ 859 struct cfg80211_scan_request *req)
869 u8 index = 0;
870
871 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
872 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
873 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
874 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
875
876 return index;
877}
878
879static int wl1251_build_extended_rates(char *rates)
880{ 860{
881 u8 index = 0; 861 struct wl1251 *wl = hw->priv;
882 862 struct sk_buff *skb;
883 rates[index++] = IEEE80211_OFDM_RATE_6MB; 863 size_t ssid_len = 0;
884 rates[index++] = IEEE80211_OFDM_RATE_9MB; 864 u8 *ssid = NULL;
885 rates[index++] = IEEE80211_OFDM_RATE_12MB; 865 int ret;
886 rates[index++] = IEEE80211_OFDM_RATE_18MB;
887 rates[index++] = IEEE80211_OFDM_RATE_24MB;
888 rates[index++] = IEEE80211_OFDM_RATE_36MB;
889 rates[index++] = IEEE80211_OFDM_RATE_48MB;
890 rates[index++] = IEEE80211_OFDM_RATE_54MB;
891
892 return index;
893}
894
895 866
896static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len) 867 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
897{
898 struct wl12xx_probe_req_template template;
899 struct wl12xx_ie_rates *rates;
900 char *ptr;
901 u16 size;
902
903 ptr = (char *)&template;
904 size = sizeof(struct ieee80211_header);
905
906 memset(template.header.da, 0xff, ETH_ALEN);
907 memset(template.header.bssid, 0xff, ETH_ALEN);
908 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
909 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
910
911 /* IEs */
912 /* SSID */
913 template.ssid.header.id = WLAN_EID_SSID;
914 template.ssid.header.len = ssid_len;
915 if (ssid_len && ssid)
916 memcpy(template.ssid.ssid, ssid, ssid_len);
917 size += sizeof(struct wl12xx_ie_header) + ssid_len;
918 ptr += size;
919
920 /* Basic Rates */
921 rates = (struct wl12xx_ie_rates *)ptr;
922 rates->header.id = WLAN_EID_SUPP_RATES;
923 rates->header.len = wl1251_build_basic_rates(rates->rates);
924 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
925 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
926
927 /* Extended rates */
928 rates = (struct wl12xx_ie_rates *)ptr;
929 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
930 rates->header.len = wl1251_build_extended_rates(rates->rates);
931 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
932
933 wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
934
935 return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
936 size);
937}
938 868
939static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len, 869 if (req->n_ssids) {
940 u8 active_scan, u8 high_prio, u8 num_channels, 870 ssid = req->ssids[0].ssid;
941 u8 probe_requests) 871 ssid_len = req->ssids[0].ssid_len;
942{
943 struct wl1251_cmd_trigger_scan_to *trigger = NULL;
944 struct cmd_scan *params = NULL;
945 int i, ret;
946 u16 scan_options = 0;
947
948 if (wl->scanning)
949 return -EINVAL;
950
951 params = kzalloc(sizeof(*params), GFP_KERNEL);
952 if (!params)
953 return -ENOMEM;
954
955 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
956 params->params.rx_filter_options =
957 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
958
959 /* High priority scan */
960 if (!active_scan)
961 scan_options |= SCAN_PASSIVE;
962 if (high_prio)
963 scan_options |= SCAN_PRIORITY_HIGH;
964 params->params.scan_options = scan_options;
965
966 params->params.num_channels = num_channels;
967 params->params.num_probe_requests = probe_requests;
968 params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
969 params->params.tid_trigger = 0;
970
971 for (i = 0; i < num_channels; i++) {
972 params->channels[i].min_duration = cpu_to_le32(30000);
973 params->channels[i].max_duration = cpu_to_le32(60000);
974 memset(&params->channels[i].bssid_lsb, 0xff, 4);
975 memset(&params->channels[i].bssid_msb, 0xff, 2);
976 params->channels[i].early_termination = 0;
977 params->channels[i].tx_power_att = 0;
978 params->channels[i].channel = i + 1;
979 memset(params->channels[i].pad, 0, 3);
980 } 872 }
981 873
982 for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++) 874 mutex_lock(&wl->mutex);
983 memset(&params->channels[i], 0,
984 sizeof(struct basic_scan_channel_parameters));
985
986 if (len && ssid) {
987 params->params.ssid_len = len;
988 memcpy(params->params.ssid, ssid, len);
989 } else {
990 params->params.ssid_len = 0;
991 memset(params->params.ssid, 0, 32);
992 }
993 875
994 ret = wl1251_build_probe_req(wl, ssid, len); 876 if (wl->scanning) {
995 if (ret < 0) { 877 wl1251_debug(DEBUG_SCAN, "scan already in progress");
996 wl1251_error("PROBE request template failed"); 878 ret = -EINVAL;
997 goto out; 879 goto out;
998 } 880 }
999 881
1000 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); 882 ret = wl1251_ps_elp_wakeup(wl);
1001 if (!trigger) 883 if (ret < 0)
1002 goto out; 884 goto out;
1003 885
1004 trigger->timeout = 0; 886 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
1005 887 req->ie, req->ie_len);
1006 ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, 888 if (!skb) {
1007 sizeof(*trigger)); 889 ret = -ENOMEM;
1008 if (ret < 0) {
1009 wl1251_error("trigger scan to failed for hw scan");
1010 goto out; 890 goto out;
1011 } 891 }
1012 892
1013 wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 893 ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
1014 894 skb->len);
1015 wl->scanning = true; 895 dev_kfree_skb(skb);
896 if (ret < 0)
897 goto out_sleep;
1016 898
1017 ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params)); 899 ret = wl1251_cmd_trigger_scan_to(wl, 0);
1018 if (ret < 0) 900 if (ret < 0)
1019 wl1251_error("SCAN failed"); 901 goto out_sleep;
1020 902
1021 wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 903 wl->scanning = true;
1022 904
1023 if (params->header.status != CMD_STATUS_SUCCESS) { 905 ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
1024 wl1251_error("TEST command answer error: %d", 906 req->n_channels, WL1251_SCAN_NUM_PROBES);
1025 params->header.status); 907 if (ret < 0) {
1026 wl->scanning = false; 908 wl->scanning = false;
1027 ret = -EIO; 909 goto out_sleep;
1028 goto out;
1029 }
1030
1031out:
1032 kfree(params);
1033 return ret;
1034
1035}
1036
1037static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
1038 struct cfg80211_scan_request *req)
1039{
1040 struct wl1251 *wl = hw->priv;
1041 int ret;
1042 u8 *ssid = NULL;
1043 size_t ssid_len = 0;
1044
1045 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
1046
1047 if (req->n_ssids) {
1048 ssid = req->ssids[0].ssid;
1049 ssid_len = req->ssids[0].ssid_len;
1050 } 910 }
1051 911
1052 mutex_lock(&wl->mutex); 912out_sleep:
1053
1054 ret = wl1251_ps_elp_wakeup(wl);
1055 if (ret < 0)
1056 goto out;
1057
1058 ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
1059
1060 wl1251_ps_elp_sleep(wl); 913 wl1251_ps_elp_sleep(wl);
1061 914
1062out: 915out:
@@ -1093,9 +946,8 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1093 struct ieee80211_bss_conf *bss_conf, 946 struct ieee80211_bss_conf *bss_conf,
1094 u32 changed) 947 u32 changed)
1095{ 948{
1096 enum wl1251_cmd_ps_mode mode;
1097 struct wl1251 *wl = hw->priv; 949 struct wl1251 *wl = hw->priv;
1098 struct sk_buff *beacon; 950 struct sk_buff *beacon, *skb;
1099 int ret; 951 int ret;
1100 952
1101 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 953 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1109,7 +961,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1109 if (changed & BSS_CHANGED_BSSID) { 961 if (changed & BSS_CHANGED_BSSID) {
1110 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 962 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1111 963
1112 ret = wl1251_build_null_data(wl); 964 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
965 if (!skb)
966 goto out_sleep;
967
968 ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
969 skb->data, skb->len);
970 dev_kfree_skb(skb);
971 if (ret < 0)
972 goto out_sleep;
973
974 ret = wl1251_build_qos_null_data(wl);
1113 if (ret < 0) 975 if (ret < 0)
1114 goto out; 976 goto out;
1115 977
@@ -1124,27 +986,21 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1124 if (changed & BSS_CHANGED_ASSOC) { 986 if (changed & BSS_CHANGED_ASSOC) {
1125 if (bss_conf->assoc) { 987 if (bss_conf->assoc) {
1126 wl->beacon_int = bss_conf->beacon_int; 988 wl->beacon_int = bss_conf->beacon_int;
1127 wl->dtim_period = bss_conf->dtim_period;
1128 989
1129 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, 990 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
1130 wl->dtim_period); 991 if (!skb)
1131 wl->aid = bss_conf->aid; 992 goto out_sleep;
1132 993
1133 ret = wl1251_build_ps_poll(wl, wl->aid); 994 ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
995 skb->data,
996 skb->len);
997 dev_kfree_skb(skb);
1134 if (ret < 0) 998 if (ret < 0)
1135 goto out_sleep; 999 goto out_sleep;
1136 1000
1137 ret = wl1251_acx_aid(wl, wl->aid); 1001 ret = wl1251_acx_aid(wl, bss_conf->aid);
1138 if (ret < 0) 1002 if (ret < 0)
1139 goto out_sleep; 1003 goto out_sleep;
1140
1141 /* If we want to go in PSM but we're not there yet */
1142 if (wl->psm_requested && !wl->psm) {
1143 mode = STATION_POWER_SAVE_MODE;
1144 ret = wl1251_ps_set_mode(wl, mode);
1145 if (ret < 0)
1146 goto out_sleep;
1147 }
1148 } else { 1004 } else {
1149 /* use defaults when not associated */ 1005 /* use defaults when not associated */
1150 wl->beacon_int = WL1251_DEFAULT_BEACON_INT; 1006 wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
@@ -1176,7 +1032,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1176 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE); 1032 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
1177 if (ret < 0) { 1033 if (ret < 0) {
1178 wl1251_warning("Set ctsprotect failed %d", ret); 1034 wl1251_warning("Set ctsprotect failed %d", ret);
1179 goto out; 1035 goto out_sleep;
1180 } 1036 }
1181 } 1037 }
1182 1038
@@ -1187,7 +1043,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1187 1043
1188 if (ret < 0) { 1044 if (ret < 0) {
1189 dev_kfree_skb(beacon); 1045 dev_kfree_skb(beacon);
1190 goto out; 1046 goto out_sleep;
1191 } 1047 }
1192 1048
1193 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, 1049 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
@@ -1196,13 +1052,13 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1196 dev_kfree_skb(beacon); 1052 dev_kfree_skb(beacon);
1197 1053
1198 if (ret < 0) 1054 if (ret < 0)
1199 goto out; 1055 goto out_sleep;
1200 1056
1201 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, 1057 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
1202 wl->channel, wl->dtim_period); 1058 wl->channel, wl->dtim_period);
1203 1059
1204 if (ret < 0) 1060 if (ret < 0)
1205 goto out; 1061 goto out_sleep;
1206 } 1062 }
1207 1063
1208out_sleep: 1064out_sleep:
@@ -1273,6 +1129,49 @@ static struct ieee80211_channel wl1251_channels[] = {
1273 { .hw_value = 13, .center_freq = 2472}, 1129 { .hw_value = 13, .center_freq = 2472},
1274}; 1130};
1275 1131
1132static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1133 const struct ieee80211_tx_queue_params *params)
1134{
1135 enum wl1251_acx_ps_scheme ps_scheme;
1136 struct wl1251 *wl = hw->priv;
1137 int ret;
1138
1139 mutex_lock(&wl->mutex);
1140
1141 wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
1142
1143 ret = wl1251_ps_elp_wakeup(wl);
1144 if (ret < 0)
1145 goto out;
1146
1147 /* mac80211 uses units of 32 usec */
1148 ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
1149 params->cw_min, params->cw_max,
1150 params->aifs, params->txop * 32);
1151 if (ret < 0)
1152 goto out_sleep;
1153
1154 if (params->uapsd)
1155 ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
1156 else
1157 ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
1158
1159 ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
1160 CHANNEL_TYPE_EDCF,
1161 wl1251_tx_get_queue(queue), ps_scheme,
1162 WL1251_ACX_ACK_POLICY_LEGACY);
1163 if (ret < 0)
1164 goto out_sleep;
1165
1166out_sleep:
1167 wl1251_ps_elp_sleep(wl);
1168
1169out:
1170 mutex_unlock(&wl->mutex);
1171
1172 return ret;
1173}
1174
1276/* can't be const, mac80211 writes to this */ 1175/* can't be const, mac80211 writes to this */
1277static struct ieee80211_supported_band wl1251_band_2ghz = { 1176static struct ieee80211_supported_band wl1251_band_2ghz = {
1278 .channels = wl1251_channels, 1177 .channels = wl1251_channels,
@@ -1293,6 +1192,7 @@ static const struct ieee80211_ops wl1251_ops = {
1293 .hw_scan = wl1251_op_hw_scan, 1192 .hw_scan = wl1251_op_hw_scan,
1294 .bss_info_changed = wl1251_op_bss_info_changed, 1193 .bss_info_changed = wl1251_op_bss_info_changed,
1295 .set_rts_threshold = wl1251_op_set_rts_threshold, 1194 .set_rts_threshold = wl1251_op_set_rts_threshold,
1195 .conf_tx = wl1251_op_conf_tx,
1296}; 1196};
1297 1197
1298static int wl1251_register_hw(struct wl1251 *wl) 1198static int wl1251_register_hw(struct wl1251 *wl)
@@ -1332,12 +1232,15 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1332 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1232 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1333 IEEE80211_HW_NOISE_DBM | 1233 IEEE80211_HW_NOISE_DBM |
1334 IEEE80211_HW_SUPPORTS_PS | 1234 IEEE80211_HW_SUPPORTS_PS |
1335 IEEE80211_HW_BEACON_FILTER; 1235 IEEE80211_HW_BEACON_FILTER |
1236 IEEE80211_HW_SUPPORTS_UAPSD;
1336 1237
1337 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1238 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1338 wl->hw->wiphy->max_scan_ssids = 1; 1239 wl->hw->wiphy->max_scan_ssids = 1;
1339 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; 1240 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
1340 1241
1242 wl->hw->queues = 4;
1243
1341 ret = wl1251_register_hw(wl); 1244 ret = wl1251_register_hw(wl);
1342 if (ret) 1245 if (ret)
1343 goto out; 1246 goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 9931b197ff77..851dfb65e474 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -26,7 +26,8 @@
26#include "wl1251_cmd.h" 26#include "wl1251_cmd.h"
27#include "wl1251_io.h" 27#include "wl1251_io.h"
28 28
29#define WL1251_WAKEUP_TIMEOUT 2000 29/* in ms */
30#define WL1251_WAKEUP_TIMEOUT 100
30 31
31void wl1251_elp_work(struct work_struct *work) 32void wl1251_elp_work(struct work_struct *work)
32{ 33{
@@ -67,7 +68,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
67 68
68int wl1251_ps_elp_wakeup(struct wl1251 *wl) 69int wl1251_ps_elp_wakeup(struct wl1251 *wl)
69{ 70{
70 unsigned long timeout; 71 unsigned long timeout, start;
71 u32 elp_reg; 72 u32 elp_reg;
72 73
73 if (!wl->elp) 74 if (!wl->elp)
@@ -75,6 +76,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
75 76
76 wl1251_debug(DEBUG_PSM, "waking up chip from elp"); 77 wl1251_debug(DEBUG_PSM, "waking up chip from elp");
77 78
79 start = jiffies;
78 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); 80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
79 81
80 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 82 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
@@ -95,8 +97,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
95 } 97 }
96 98
97 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", 99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
98 jiffies_to_msecs(jiffies) - 100 jiffies_to_msecs(jiffies - start));
99 (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT));
100 101
101 wl->elp = false; 102 wl->elp = false;
102 103
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index f84cc89cbffc..b56732226cc0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -126,7 +126,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
126 if (wl->rx_current_buffer) 126 if (wl->rx_current_buffer)
127 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; 127 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
128 128
129 skb = dev_alloc_skb(length); 129 skb = __dev_alloc_skb(length, GFP_KERNEL);
130 if (!skb) { 130 if (!skb) {
131 wl1251_error("Couldn't allocate RX frame"); 131 wl1251_error("Couldn't allocate RX frame");
132 return; 132 return;
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index f85970615849..c8223185efd2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -167,8 +167,7 @@ static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
167 tx_hdr->expiry_time = cpu_to_le32(1 << 16); 167 tx_hdr->expiry_time = cpu_to_le32(1 << 16);
168 tx_hdr->id = id; 168 tx_hdr->id = id;
169 169
170 /* FIXME: how to get the correct queue id? */ 170 tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
171 tx_hdr->xmit_queue = 0;
172 171
173 wl1251_tx_control(tx_hdr, control, fc); 172 wl1251_tx_control(tx_hdr, control, fc);
174 wl1251_tx_frag_block_num(tx_hdr); 173 wl1251_tx_frag_block_num(tx_hdr);
@@ -220,6 +219,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
220 /* align the buffer on a 4-byte boundary */ 219 /* align the buffer on a 4-byte boundary */
221 skb_reserve(skb, offset); 220 skb_reserve(skb, offset);
222 memmove(skb->data, src, skb->len); 221 memmove(skb->data, src, skb->len);
222 tx_hdr = (struct tx_double_buffer_desc *) skb->data;
223 } else { 223 } else {
224 wl1251_info("No handler, fixme!"); 224 wl1251_info("No handler, fixme!");
225 return -EINVAL; 225 return -EINVAL;
@@ -237,8 +237,9 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
237 237
238 wl1251_mem_write(wl, addr, skb->data, len); 238 wl1251_mem_write(wl, addr, skb->data, len);
239 239
240 wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x", 240 wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
241 tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate); 241 "queue %d", tx_hdr->id, skb, tx_hdr->length,
242 tx_hdr->rate, tx_hdr->xmit_queue);
242 243
243 return 0; 244 return 0;
244} 245}
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
index 7c1c1665c810..55856c6bb97a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -26,6 +26,7 @@
26#define __WL1251_TX_H__ 26#define __WL1251_TX_H__
27 27
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include "wl1251_acx.h"
29 30
30/* 31/*
31 * 32 *
@@ -209,6 +210,22 @@ struct tx_result {
209 u8 done_2; 210 u8 done_2;
210} __attribute__ ((packed)); 211} __attribute__ ((packed));
211 212
213static inline int wl1251_tx_get_queue(int queue)
214{
215 switch (queue) {
216 case 0:
217 return QOS_AC_VO;
218 case 1:
219 return QOS_AC_VI;
220 case 2:
221 return QOS_AC_BE;
222 case 3:
223 return QOS_AC_BK;
224 default:
225 return QOS_AC_BE;
226 }
227}
228
212void wl1251_tx_work(struct work_struct *work); 229void wl1251_tx_work(struct work_struct *work);
213void wl1251_tx_complete(struct wl1251 *wl); 230void wl1251_tx_complete(struct wl1251 *wl);
214void wl1251_tx_flush(struct wl1251 *wl); 231void wl1251_tx_flush(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 94359b1a861f..97ea5096bc8c 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -43,7 +43,7 @@ enum {
43 DEBUG_SPI = BIT(1), 43 DEBUG_SPI = BIT(1),
44 DEBUG_BOOT = BIT(2), 44 DEBUG_BOOT = BIT(2),
45 DEBUG_MAILBOX = BIT(3), 45 DEBUG_MAILBOX = BIT(3),
46 DEBUG_NETLINK = BIT(4), 46 DEBUG_TESTMODE = BIT(4),
47 DEBUG_EVENT = BIT(5), 47 DEBUG_EVENT = BIT(5),
48 DEBUG_TX = BIT(6), 48 DEBUG_TX = BIT(6),
49 DEBUG_RX = BIT(7), 49 DEBUG_RX = BIT(7),
@@ -107,11 +107,36 @@ enum {
107 CFG_RX_CTL_EN | CFG_RX_BCN_EN | \ 107 CFG_RX_CTL_EN | CFG_RX_BCN_EN | \
108 CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) 108 CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
109 109
110#define WL1271_DEFAULT_BASIC_RATE_SET (CONF_TX_RATE_MASK_ALL)
111
112#define WL1271_FW_NAME "wl1271-fw.bin" 110#define WL1271_FW_NAME "wl1271-fw.bin"
113#define WL1271_NVS_NAME "wl1271-nvs.bin" 111#define WL1271_NVS_NAME "wl1271-nvs.bin"
114 112
113/* NVS data structure */
114#define WL1271_NVS_SECTION_SIZE 468
115
116#define WL1271_NVS_GENERAL_PARAMS_SIZE 57
117#define WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED \
118 (WL1271_NVS_GENERAL_PARAMS_SIZE + 1)
119#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE 17
120#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED \
121 (WL1271_NVS_STAT_RADIO_PARAMS_SIZE + 1)
122#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE 65
123#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED \
124 (WL1271_NVS_DYN_RADIO_PARAMS_SIZE + 1)
125#define WL1271_NVS_FEM_COUNT 2
126#define WL1271_NVS_INI_SPARE_SIZE 124
127
128struct wl1271_nvs_file {
129 /* NVS section */
130 u8 nvs[WL1271_NVS_SECTION_SIZE];
131
132 /* INI section */
133 u8 general_params[WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED];
134 u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED];
135 u8 dyn_radio_params[WL1271_NVS_FEM_COUNT]
136 [WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED];
137 u8 ini_spare[WL1271_NVS_INI_SPARE_SIZE];
138} __attribute__ ((packed));
139
115/* 140/*
116 * Enable/disable 802.11a support for WL1273 141 * Enable/disable 802.11a support for WL1273
117 */ 142 */
@@ -276,6 +301,7 @@ struct wl1271_debugfs {
276 301
277 struct dentry *retry_count; 302 struct dentry *retry_count;
278 struct dentry *excessive_retries; 303 struct dentry *excessive_retries;
304 struct dentry *gpio_power;
279}; 305};
280 306
281#define NUM_TX_QUEUES 4 307#define NUM_TX_QUEUES 4
@@ -322,6 +348,17 @@ struct wl1271 {
322 enum wl1271_state state; 348 enum wl1271_state state;
323 struct mutex mutex; 349 struct mutex mutex;
324 350
351#define WL1271_FLAG_STA_RATES_CHANGED (0)
352#define WL1271_FLAG_STA_ASSOCIATED (1)
353#define WL1271_FLAG_JOINED (2)
354#define WL1271_FLAG_GPIO_POWER (3)
355#define WL1271_FLAG_TX_QUEUE_STOPPED (4)
356#define WL1271_FLAG_SCANNING (5)
357#define WL1271_FLAG_IN_ELP (6)
358#define WL1271_FLAG_PSM (7)
359#define WL1271_FLAG_PSM_REQUESTED (8)
360 unsigned long flags;
361
325 struct wl1271_partition_set part; 362 struct wl1271_partition_set part;
326 363
327 struct wl1271_chip chip; 364 struct wl1271_chip chip;
@@ -331,8 +368,7 @@ struct wl1271 {
331 368
332 u8 *fw; 369 u8 *fw;
333 size_t fw_len; 370 size_t fw_len;
334 u8 *nvs; 371 struct wl1271_nvs_file *nvs;
335 size_t nvs_len;
336 372
337 u8 bssid[ETH_ALEN]; 373 u8 bssid[ETH_ALEN];
338 u8 mac_addr[ETH_ALEN]; 374 u8 mac_addr[ETH_ALEN];
@@ -359,7 +395,6 @@ struct wl1271 {
359 395
360 /* Frames scheduled for transmission, not handled yet */ 396 /* Frames scheduled for transmission, not handled yet */
361 struct sk_buff_head tx_queue; 397 struct sk_buff_head tx_queue;
362 bool tx_queue_stopped;
363 398
364 struct work_struct tx_work; 399 struct work_struct tx_work;
365 400
@@ -387,14 +422,15 @@ struct wl1271 {
387 u32 mbox_ptr[2]; 422 u32 mbox_ptr[2];
388 423
389 /* Are we currently scanning */ 424 /* Are we currently scanning */
390 bool scanning;
391 struct wl1271_scan scan; 425 struct wl1271_scan scan;
392 426
393 /* Our association ID */ 427 /* Our association ID */
394 u16 aid; 428 u16 aid;
395 429
396 /* currently configured rate set */ 430 /* currently configured rate set */
431 u32 sta_rate_set;
397 u32 basic_rate_set; 432 u32 basic_rate_set;
433 u32 rate_set;
398 434
399 /* The current band */ 435 /* The current band */
400 enum ieee80211_band band; 436 enum ieee80211_band band;
@@ -405,18 +441,9 @@ struct wl1271 {
405 unsigned int rx_config; 441 unsigned int rx_config;
406 unsigned int rx_filter; 442 unsigned int rx_filter;
407 443
408 /* is firmware in elp mode */
409 bool elp;
410
411 struct completion *elp_compl; 444 struct completion *elp_compl;
412 struct delayed_work elp_work; 445 struct delayed_work elp_work;
413 446
414 /* we can be in psm, but not in elp, we have to differentiate */
415 bool psm;
416
417 /* PSM mode requested */
418 bool psm_requested;
419
420 /* retry counter for PSM entries */ 447 /* retry counter for PSM entries */
421 u8 psm_entry_retry; 448 u8 psm_entry_retry;
422 449
@@ -435,9 +462,6 @@ struct wl1271 {
435 462
436 struct ieee80211_vif *vif; 463 struct ieee80211_vif *vif;
437 464
438 /* Used for a workaround to send disconnect before rejoining */
439 bool joined;
440
441 /* Current chipset configuration */ 465 /* Current chipset configuration */
442 struct conf_drv_settings conf; 466 struct conf_drv_settings conf;
443 467
@@ -455,11 +479,14 @@ int wl1271_plt_stop(struct wl1271 *wl);
455 479
456#define WL1271_TX_QUEUE_MAX_LENGTH 20 480#define WL1271_TX_QUEUE_MAX_LENGTH 20
457 481
458/* WL1271 needs a 200ms sleep after power on */ 482/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
483 on in case is has been shut down shortly before */
484#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
459#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ 485#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
460 486
461static inline bool wl1271_11a_enabled(void) 487static inline bool wl1271_11a_enabled(void)
462{ 488{
489 /* FIXME: this could be determined based on the NVS-INI file */
463#ifdef WL1271_80211A_ENABLED 490#ifdef WL1271_80211A_ENABLED
464 return true; 491 return true;
465#else 492#else
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 5cc89bbdac7a..60f10dce4800 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -390,6 +390,35 @@ out:
390 return ret; 390 return ret;
391} 391}
392 392
393int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
394{
395 struct acx_dco_itrim_params *dco;
396 struct conf_itrim_settings *c = &wl->conf.itrim;
397 int ret;
398
399 wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
400
401 dco = kzalloc(sizeof(*dco), GFP_KERNEL);
402 if (!dco) {
403 ret = -ENOMEM;
404 goto out;
405 }
406
407 dco->enable = c->enable;
408 dco->timeout = cpu_to_le32(c->timeout);
409
410 ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
411 dco, sizeof(*dco));
412 if (ret < 0) {
413 wl1271_warning("failed to set dco itrim parameters: %d", ret);
414 goto out;
415 }
416
417out:
418 kfree(dco);
419 return ret;
420}
421
393int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter) 422int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
394{ 423{
395 struct acx_beacon_filter_option *beacon_filter = NULL; 424 struct acx_beacon_filter_option *beacon_filter = NULL;
@@ -758,10 +787,11 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
758 return 0; 787 return 0;
759} 788}
760 789
761int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates) 790int wl1271_acx_rate_policies(struct wl1271 *wl)
762{ 791{
763 struct acx_rate_policy *acx; 792 struct acx_rate_policy *acx;
764 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; 793 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
794 int idx = 0;
765 int ret = 0; 795 int ret = 0;
766 796
767 wl1271_debug(DEBUG_ACX, "acx rate policies"); 797 wl1271_debug(DEBUG_ACX, "acx rate policies");
@@ -773,12 +803,21 @@ int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
773 goto out; 803 goto out;
774 } 804 }
775 805
776 /* configure one default (one-size-fits-all) rate class */ 806 /* configure one basic rate class */
777 acx->rate_class_cnt = cpu_to_le32(1); 807 idx = ACX_TX_BASIC_RATE;
778 acx->rate_class[0].enabled_rates = cpu_to_le32(enabled_rates); 808 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set);
779 acx->rate_class[0].short_retry_limit = c->short_retry_limit; 809 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
780 acx->rate_class[0].long_retry_limit = c->long_retry_limit; 810 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
781 acx->rate_class[0].aflags = c->aflags; 811 acx->rate_class[idx].aflags = c->aflags;
812
813 /* configure one AP supported rate class */
814 idx = ACX_TX_AP_FULL_RATE;
815 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
816 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
817 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
818 acx->rate_class[idx].aflags = c->aflags;
819
820 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
782 821
783 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 822 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
784 if (ret < 0) { 823 if (ret < 0) {
@@ -791,12 +830,14 @@ out:
791 return ret; 830 return ret;
792} 831}
793 832
794int wl1271_acx_ac_cfg(struct wl1271 *wl) 833int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
834 u8 aifsn, u16 txop)
795{ 835{
796 struct acx_ac_cfg *acx; 836 struct acx_ac_cfg *acx;
797 int i, ret = 0; 837 int ret = 0;
798 838
799 wl1271_debug(DEBUG_ACX, "acx access category config"); 839 wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
840 "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
800 841
801 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 842 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
802 843
@@ -805,21 +846,16 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl)
805 goto out; 846 goto out;
806 } 847 }
807 848
808 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 849 acx->ac = ac;
809 struct conf_tx_ac_category *c = &(wl->conf.tx.ac_conf[i]); 850 acx->cw_min = cw_min;
810 acx->ac = c->ac; 851 acx->cw_max = cpu_to_le16(cw_max);
811 acx->cw_min = c->cw_min; 852 acx->aifsn = aifsn;
812 acx->cw_max = cpu_to_le16(c->cw_max); 853 acx->tx_op_limit = cpu_to_le16(txop);
813 acx->aifsn = c->aifsn;
814 acx->reserved = 0;
815 acx->tx_op_limit = cpu_to_le16(c->tx_op_limit);
816 854
817 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); 855 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
818 if (ret < 0) { 856 if (ret < 0) {
819 wl1271_warning("Setting of access category " 857 wl1271_warning("acx ac cfg failed: %d", ret);
820 "config: %d", ret); 858 goto out;
821 goto out;
822 }
823 } 859 }
824 860
825out: 861out:
@@ -827,10 +863,12 @@ out:
827 return ret; 863 return ret;
828} 864}
829 865
830int wl1271_acx_tid_cfg(struct wl1271 *wl) 866int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
867 u8 tsid, u8 ps_scheme, u8 ack_policy,
868 u32 apsd_conf0, u32 apsd_conf1)
831{ 869{
832 struct acx_tid_config *acx; 870 struct acx_tid_config *acx;
833 int i, ret = 0; 871 int ret = 0;
834 872
835 wl1271_debug(DEBUG_ACX, "acx tid config"); 873 wl1271_debug(DEBUG_ACX, "acx tid config");
836 874
@@ -841,21 +879,18 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl)
841 goto out; 879 goto out;
842 } 880 }
843 881
844 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 882 acx->queue_id = queue_id;
845 struct conf_tx_tid *c = &(wl->conf.tx.tid_conf[i]); 883 acx->channel_type = channel_type;
846 acx->queue_id = c->queue_id; 884 acx->tsid = tsid;
847 acx->channel_type = c->channel_type; 885 acx->ps_scheme = ps_scheme;
848 acx->tsid = c->tsid; 886 acx->ack_policy = ack_policy;
849 acx->ps_scheme = c->ps_scheme; 887 acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
850 acx->ack_policy = c->ack_policy; 888 acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
851 acx->apsd_conf[0] = cpu_to_le32(c->apsd_conf[0]);
852 acx->apsd_conf[1] = cpu_to_le32(c->apsd_conf[1]);
853 889
854 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); 890 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
855 if (ret < 0) { 891 if (ret < 0) {
856 wl1271_warning("Setting of tid config failed: %d", ret); 892 wl1271_warning("Setting of tid config failed: %d", ret);
857 goto out; 893 goto out;
858 }
859 } 894 }
860 895
861out: 896out:
@@ -1012,59 +1047,6 @@ out:
1012 return ret; 1047 return ret;
1013} 1048}
1014 1049
1015int wl1271_acx_smart_reflex(struct wl1271 *wl)
1016{
1017 struct acx_smart_reflex_state *sr_state = NULL;
1018 struct acx_smart_reflex_config_params *sr_param = NULL;
1019 int i, ret;
1020
1021 wl1271_debug(DEBUG_ACX, "acx smart reflex");
1022
1023 sr_param = kzalloc(sizeof(*sr_param), GFP_KERNEL);
1024 if (!sr_param) {
1025 ret = -ENOMEM;
1026 goto out;
1027 }
1028
1029 for (i = 0; i < CONF_SR_ERR_TBL_COUNT; i++) {
1030 struct conf_mart_reflex_err_table *e =
1031 &(wl->conf.init.sr_err_tbl[i]);
1032
1033 sr_param->error_table[i].len = e->len;
1034 sr_param->error_table[i].upper_limit = e->upper_limit;
1035 memcpy(sr_param->error_table[i].values, e->values, e->len);
1036 }
1037
1038 ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_PARAMS,
1039 sr_param, sizeof(*sr_param));
1040 if (ret < 0) {
1041 wl1271_warning("failed to set smart reflex params: %d", ret);
1042 goto out;
1043 }
1044
1045 sr_state = kzalloc(sizeof(*sr_state), GFP_KERNEL);
1046 if (!sr_state) {
1047 ret = -ENOMEM;
1048 goto out;
1049 }
1050
1051 /* enable smart reflex */
1052 sr_state->enable = wl->conf.init.sr_enable;
1053
1054 ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_STATE,
1055 sr_state, sizeof(*sr_state));
1056 if (ret < 0) {
1057 wl1271_warning("failed to set smart reflex params: %d", ret);
1058 goto out;
1059 }
1060
1061out:
1062 kfree(sr_state);
1063 kfree(sr_param);
1064 return ret;
1065
1066}
1067
1068int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable) 1050int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
1069{ 1051{
1070 struct wl1271_acx_bet_enable *acx = NULL; 1052 struct wl1271_acx_bet_enable *acx = NULL;
@@ -1132,3 +1114,31 @@ out:
1132 kfree(acx); 1114 kfree(acx);
1133 return ret; 1115 return ret;
1134} 1116}
1117
1118int wl1271_acx_pm_config(struct wl1271 *wl)
1119{
1120 struct wl1271_acx_pm_config *acx = NULL;
1121 struct conf_pm_config_settings *c = &wl->conf.pm_config;
1122 int ret = 0;
1123
1124 wl1271_debug(DEBUG_ACX, "acx pm config");
1125
1126 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1127 if (!acx) {
1128 ret = -ENOMEM;
1129 goto out;
1130 }
1131
1132 acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
1133 acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
1134
1135 ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
1136 if (ret < 0) {
1137 wl1271_warning("acx pm config failed: %d", ret);
1138 goto out;
1139 }
1140
1141out:
1142 kfree(acx);
1143 return ret;
1144}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 2ce0a8128542..aeccc98581eb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -2,7 +2,7 @@
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. 4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation 5 * Copyright (C) 2008-2010 Nokia Corporation
6 * 6 *
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8 * 8 *
@@ -348,7 +348,7 @@ struct acx_beacon_filter_option {
348 * ACXBeaconFilterEntry (not 221) 348 * ACXBeaconFilterEntry (not 221)
349 * Byte Offset Size (Bytes) Definition 349 * Byte Offset Size (Bytes) Definition
350 * =========== ============ ========== 350 * =========== ============ ==========
351 * 0 1 IE identifier 351 * 0 1 IE identifier
352 * 1 1 Treatment bit mask 352 * 1 1 Treatment bit mask
353 * 353 *
354 * ACXBeaconFilterEntry (221) 354 * ACXBeaconFilterEntry (221)
@@ -381,8 +381,8 @@ struct acx_beacon_filter_ie_table {
381 struct acx_header header; 381 struct acx_header header;
382 382
383 u8 num_ie; 383 u8 num_ie;
384 u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
385 u8 pad[3]; 384 u8 pad[3];
385 u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
386} __attribute__ ((packed)); 386} __attribute__ ((packed));
387 387
388struct acx_conn_monit_params { 388struct acx_conn_monit_params {
@@ -415,23 +415,12 @@ struct acx_bt_wlan_coex {
415 u8 pad[3]; 415 u8 pad[3];
416} __attribute__ ((packed)); 416} __attribute__ ((packed));
417 417
418struct acx_smart_reflex_state { 418struct acx_dco_itrim_params {
419 struct acx_header header; 419 struct acx_header header;
420 420
421 u8 enable; 421 u8 enable;
422 u8 padding[3]; 422 u8 padding[3];
423} __attribute__ ((packed)); 423 __le32 timeout;
424
425struct smart_reflex_err_table {
426 u8 len;
427 s8 upper_limit;
428 s8 values[14];
429} __attribute__ ((packed));
430
431struct acx_smart_reflex_config_params {
432 struct acx_header header;
433
434 struct smart_reflex_err_table error_table[3];
435} __attribute__ ((packed)); 424} __attribute__ ((packed));
436 425
437#define PTA_ANTENNA_TYPE_DEF (0) 426#define PTA_ANTENNA_TYPE_DEF (0)
@@ -837,6 +826,9 @@ struct acx_rate_class {
837 u8 reserved; 826 u8 reserved;
838}; 827};
839 828
829#define ACX_TX_BASIC_RATE 0
830#define ACX_TX_AP_FULL_RATE 1
831#define ACX_TX_RATE_POLICY_CNT 2
840struct acx_rate_policy { 832struct acx_rate_policy {
841 struct acx_header header; 833 struct acx_header header;
842 834
@@ -877,8 +869,8 @@ struct acx_tx_config_options {
877 __le16 tx_compl_threshold; /* number of packets */ 869 __le16 tx_compl_threshold; /* number of packets */
878} __attribute__ ((packed)); 870} __attribute__ ((packed));
879 871
880#define ACX_RX_MEM_BLOCKS 64 872#define ACX_RX_MEM_BLOCKS 70
881#define ACX_TX_MIN_MEM_BLOCKS 64 873#define ACX_TX_MIN_MEM_BLOCKS 40
882#define ACX_TX_DESCRIPTORS 32 874#define ACX_TX_DESCRIPTORS 32
883#define ACX_NUM_SSID_PROFILES 1 875#define ACX_NUM_SSID_PROFILES 1
884 876
@@ -969,6 +961,13 @@ struct wl1271_acx_arp_filter {
969 used. */ 961 used. */
970} __attribute__((packed)); 962} __attribute__((packed));
971 963
964struct wl1271_acx_pm_config {
965 struct acx_header header;
966
967 __le32 host_clk_settling_time;
968 u8 host_fast_wakeup_support;
969 u8 padding[3];
970} __attribute__ ((packed));
972 971
973enum { 972enum {
974 ACX_WAKE_UP_CONDITIONS = 0x0002, 973 ACX_WAKE_UP_CONDITIONS = 0x0002,
@@ -1027,13 +1026,13 @@ enum {
1027 ACX_HT_BSS_OPERATION = 0x0058, 1026 ACX_HT_BSS_OPERATION = 0x0058,
1028 ACX_COEX_ACTIVITY = 0x0059, 1027 ACX_COEX_ACTIVITY = 0x0059,
1029 ACX_SET_SMART_REFLEX_DEBUG = 0x005A, 1028 ACX_SET_SMART_REFLEX_DEBUG = 0x005A,
1030 ACX_SET_SMART_REFLEX_STATE = 0x005B, 1029 ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
1031 ACX_SET_SMART_REFLEX_PARAMS = 0x005F,
1032 DOT11_RX_MSDU_LIFE_TIME = 0x1004, 1030 DOT11_RX_MSDU_LIFE_TIME = 0x1004,
1033 DOT11_CUR_TX_PWR = 0x100D, 1031 DOT11_CUR_TX_PWR = 0x100D,
1034 DOT11_RX_DOT11_MODE = 0x1012, 1032 DOT11_RX_DOT11_MODE = 0x1012,
1035 DOT11_RTS_THRESHOLD = 0x1013, 1033 DOT11_RTS_THRESHOLD = 0x1013,
1036 DOT11_GROUP_ADDRESS_TBL = 0x1014, 1034 DOT11_GROUP_ADDRESS_TBL = 0x1014,
1035 ACX_PM_CONFIG = 0x1016,
1037 1036
1038 MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, 1037 MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
1039 1038
@@ -1056,6 +1055,7 @@ int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
1056 void *mc_list, u32 mc_list_len); 1055 void *mc_list, u32 mc_list_len);
1057int wl1271_acx_service_period_timeout(struct wl1271 *wl); 1056int wl1271_acx_service_period_timeout(struct wl1271 *wl);
1058int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold); 1057int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
1058int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1059int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1059int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1060int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1060int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1061int wl1271_acx_conn_monit_params(struct wl1271 *wl); 1061int wl1271_acx_conn_monit_params(struct wl1271 *wl);
@@ -1069,9 +1069,12 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
1069int wl1271_acx_cts_protect(struct wl1271 *wl, 1069int wl1271_acx_cts_protect(struct wl1271 *wl,
1070 enum acx_ctsprotect_type ctsprotect); 1070 enum acx_ctsprotect_type ctsprotect);
1071int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); 1071int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
1072int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates); 1072int wl1271_acx_rate_policies(struct wl1271 *wl);
1073int wl1271_acx_ac_cfg(struct wl1271 *wl); 1073int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
1074int wl1271_acx_tid_cfg(struct wl1271 *wl); 1074 u8 aifsn, u16 txop);
1075int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
1076 u8 tsid, u8 ps_scheme, u8 ack_policy,
1077 u32 apsd_conf0, u32 apsd_conf1);
1075int wl1271_acx_frag_threshold(struct wl1271 *wl); 1078int wl1271_acx_frag_threshold(struct wl1271 *wl);
1076int wl1271_acx_tx_config_options(struct wl1271 *wl); 1079int wl1271_acx_tx_config_options(struct wl1271 *wl);
1077int wl1271_acx_mem_cfg(struct wl1271 *wl); 1080int wl1271_acx_mem_cfg(struct wl1271 *wl);
@@ -1081,5 +1084,6 @@ int wl1271_acx_smart_reflex(struct wl1271 *wl);
1081int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); 1084int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1082int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1085int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1083 u8 version); 1086 u8 version);
1087int wl1271_acx_pm_config(struct wl1271 *wl);
1084 1088
1085#endif /* __WL1271_ACX_H__ */ 1089#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index b7c96454cca3..2be76ee42bb9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -27,6 +27,7 @@
27#include "wl1271_reg.h" 27#include "wl1271_reg.h"
28#include "wl1271_boot.h" 28#include "wl1271_boot.h"
29#include "wl1271_spi.h" 29#include "wl1271_spi.h"
30#include "wl1271_io.h"
30#include "wl1271_event.h" 31#include "wl1271_event.h"
31 32
32static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { 33static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
@@ -93,19 +94,19 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
93 u32 cpu_ctrl; 94 u32 cpu_ctrl;
94 95
95 /* 10.5.0 run the firmware (I) */ 96 /* 10.5.0 run the firmware (I) */
96 cpu_ctrl = wl1271_spi_read32(wl, ACX_REG_ECPU_CONTROL); 97 cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
97 98
98 /* 10.5.1 run the firmware (II) */ 99 /* 10.5.1 run the firmware (II) */
99 cpu_ctrl |= flag; 100 cpu_ctrl |= flag;
100 wl1271_spi_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); 101 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
101} 102}
102 103
103static void wl1271_boot_fw_version(struct wl1271 *wl) 104static void wl1271_boot_fw_version(struct wl1271 *wl)
104{ 105{
105 struct wl1271_static_data static_data; 106 struct wl1271_static_data static_data;
106 107
107 wl1271_spi_read(wl, wl->cmd_box_addr, 108 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
108 &static_data, sizeof(static_data), false); 109 false);
109 110
110 strncpy(wl->chip.fw_ver, static_data.fw_version, 111 strncpy(wl->chip.fw_ver, static_data.fw_version,
111 sizeof(wl->chip.fw_ver)); 112 sizeof(wl->chip.fw_ver));
@@ -164,7 +165,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
164 memcpy(chunk, p, CHUNK_SIZE); 165 memcpy(chunk, p, CHUNK_SIZE);
165 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", 166 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
166 p, addr); 167 p, addr);
167 wl1271_spi_write(wl, addr, chunk, CHUNK_SIZE, false); 168 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
168 169
169 chunk_num++; 170 chunk_num++;
170 } 171 }
@@ -175,7 +176,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
175 memcpy(chunk, p, fw_data_len % CHUNK_SIZE); 176 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
176 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", 177 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
177 fw_data_len % CHUNK_SIZE, p, addr); 178 fw_data_len % CHUNK_SIZE, p, addr);
178 wl1271_spi_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); 179 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
179 180
180 kfree(chunk); 181 kfree(chunk);
181 return 0; 182 return 0;
@@ -219,23 +220,14 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
219 size_t nvs_len, burst_len; 220 size_t nvs_len, burst_len;
220 int i; 221 int i;
221 u32 dest_addr, val; 222 u32 dest_addr, val;
222 u8 *nvs_ptr, *nvs, *nvs_aligned; 223 u8 *nvs_ptr, *nvs_aligned;
223 224
224 nvs = wl->nvs; 225 if (wl->nvs == NULL)
225 if (nvs == NULL)
226 return -ENODEV; 226 return -ENODEV;
227 227
228 nvs_ptr = nvs; 228 /* only the first part of the NVS needs to be uploaded */
229 229 nvs_len = sizeof(wl->nvs->nvs);
230 nvs_len = wl->nvs_len; 230 nvs_ptr = (u8 *)wl->nvs->nvs;
231
232 /* Update the device MAC address into the nvs */
233 nvs[11] = wl->mac_addr[0];
234 nvs[10] = wl->mac_addr[1];
235 nvs[6] = wl->mac_addr[2];
236 nvs[5] = wl->mac_addr[3];
237 nvs[4] = wl->mac_addr[4];
238 nvs[3] = wl->mac_addr[5];
239 231
240 /* 232 /*
241 * Layout before the actual NVS tables: 233 * Layout before the actual NVS tables:
@@ -265,7 +257,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
265 wl1271_debug(DEBUG_BOOT, 257 wl1271_debug(DEBUG_BOOT,
266 "nvs burst write 0x%x: 0x%x", 258 "nvs burst write 0x%x: 0x%x",
267 dest_addr, val); 259 dest_addr, val);
268 wl1271_spi_write32(wl, dest_addr, val); 260 wl1271_write32(wl, dest_addr, val);
269 261
270 nvs_ptr += 4; 262 nvs_ptr += 4;
271 dest_addr += 4; 263 dest_addr += 4;
@@ -277,7 +269,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
277 * is 7 bytes further. 269 * is 7 bytes further.
278 */ 270 */
279 nvs_ptr += 7; 271 nvs_ptr += 7;
280 nvs_len -= nvs_ptr - nvs; 272 nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
281 nvs_len = ALIGN(nvs_len, 4); 273 nvs_len = ALIGN(nvs_len, 4);
282 274
283 /* FIXME: The driver sets the partition here, but this is not needed, 275 /* FIXME: The driver sets the partition here, but this is not needed,
@@ -286,15 +278,20 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
286 wl1271_set_partition(wl, &part_table[PART_WORK]); 278 wl1271_set_partition(wl, &part_table[PART_WORK]);
287 279
288 /* Copy the NVS tables to a new block to ensure alignment */ 280 /* Copy the NVS tables to a new block to ensure alignment */
289 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); 281 /* FIXME: We jump 3 more bytes before uploading the NVS. It seems
290 if (!nvs_aligned) 282 that our NVS files have three extra zeros here. I'm not sure whether
291 return -ENOMEM; 283 the problem is in our NVS generation or we should really jumpt these
284 3 bytes here */
285 nvs_ptr += 3;
286
287 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if
288 (!nvs_aligned) return -ENOMEM;
292 289
293 /* And finally we upload the NVS tables */ 290 /* And finally we upload the NVS tables */
294 /* FIXME: In wl1271, we upload everything at once. 291 /* FIXME: In wl1271, we upload everything at once.
295 No endianness handling needed here?! The ref driver doesn't do 292 No endianness handling needed here?! The ref driver doesn't do
296 anything about it at this point */ 293 anything about it at this point */
297 wl1271_spi_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); 294 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
298 295
299 kfree(nvs_aligned); 296 kfree(nvs_aligned);
300 return 0; 297 return 0;
@@ -303,9 +300,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
303static void wl1271_boot_enable_interrupts(struct wl1271 *wl) 300static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
304{ 301{
305 enable_irq(wl->irq); 302 enable_irq(wl->irq);
306 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, 303 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
307 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 304 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
308 wl1271_spi_write32(wl, HI_CFG, HI_CFG_DEF_VAL); 305 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
309} 306}
310 307
311static int wl1271_boot_soft_reset(struct wl1271 *wl) 308static int wl1271_boot_soft_reset(struct wl1271 *wl)
@@ -314,13 +311,12 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl)
314 u32 boot_data; 311 u32 boot_data;
315 312
316 /* perform soft reset */ 313 /* perform soft reset */
317 wl1271_spi_write32(wl, ACX_REG_SLV_SOFT_RESET, 314 wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
318 ACX_SLV_SOFT_RESET_BIT);
319 315
320 /* SOFT_RESET is self clearing */ 316 /* SOFT_RESET is self clearing */
321 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); 317 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
322 while (1) { 318 while (1) {
323 boot_data = wl1271_spi_read32(wl, ACX_REG_SLV_SOFT_RESET); 319 boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
324 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); 320 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
325 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) 321 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
326 break; 322 break;
@@ -336,10 +332,10 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl)
336 } 332 }
337 333
338 /* disable Rx/Tx */ 334 /* disable Rx/Tx */
339 wl1271_spi_write32(wl, ENABLE, 0x0); 335 wl1271_write32(wl, ENABLE, 0x0);
340 336
341 /* disable auto calibration on start*/ 337 /* disable auto calibration on start*/
342 wl1271_spi_write32(wl, SPARE_A2, 0xffff); 338 wl1271_write32(wl, SPARE_A2, 0xffff);
343 339
344 return 0; 340 return 0;
345} 341}
@@ -351,7 +347,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
351 347
352 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); 348 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
353 349
354 chip_id = wl1271_spi_read32(wl, CHIP_ID_B); 350 chip_id = wl1271_read32(wl, CHIP_ID_B);
355 351
356 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); 352 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
357 353
@@ -364,8 +360,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
364 loop = 0; 360 loop = 0;
365 while (loop++ < INIT_LOOP) { 361 while (loop++ < INIT_LOOP) {
366 udelay(INIT_LOOP_DELAY); 362 udelay(INIT_LOOP_DELAY);
367 interrupt = wl1271_spi_read32(wl, 363 interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
368 ACX_REG_INTERRUPT_NO_CLEAR);
369 364
370 if (interrupt == 0xffffffff) { 365 if (interrupt == 0xffffffff) {
371 wl1271_error("error reading hardware complete " 366 wl1271_error("error reading hardware complete "
@@ -374,8 +369,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
374 } 369 }
375 /* check that ACX_INTR_INIT_COMPLETE is enabled */ 370 /* check that ACX_INTR_INIT_COMPLETE is enabled */
376 else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) { 371 else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
377 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK, 372 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
378 WL1271_ACX_INTR_INIT_COMPLETE); 373 WL1271_ACX_INTR_INIT_COMPLETE);
379 break; 374 break;
380 } 375 }
381 } 376 }
@@ -387,10 +382,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
387 } 382 }
388 383
389 /* get hardware config command mail box */ 384 /* get hardware config command mail box */
390 wl->cmd_box_addr = wl1271_spi_read32(wl, REG_COMMAND_MAILBOX_PTR); 385 wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
391 386
392 /* get hardware config event mail box */ 387 /* get hardware config event mail box */
393 wl->event_box_addr = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR); 388 wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
394 389
395 /* set the working partition to its "running" mode offset */ 390 /* set the working partition to its "running" mode offset */
396 wl1271_set_partition(wl, &part_table[PART_WORK]); 391 wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -463,9 +458,9 @@ int wl1271_boot(struct wl1271 *wl)
463 wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); 458 wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
464 } 459 }
465 460
466 wl1271_spi_write32(wl, PLL_PARAMETERS, clk); 461 wl1271_write32(wl, PLL_PARAMETERS, clk);
467 462
468 pause = wl1271_spi_read32(wl, PLL_PARAMETERS); 463 pause = wl1271_read32(wl, PLL_PARAMETERS);
469 464
470 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); 465 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
471 466
@@ -474,10 +469,10 @@ int wl1271_boot(struct wl1271 *wl)
474 * 0x3ff (magic number ). How does 469 * 0x3ff (magic number ). How does
475 * this work?! */ 470 * this work?! */
476 pause |= WU_COUNTER_PAUSE_VAL; 471 pause |= WU_COUNTER_PAUSE_VAL;
477 wl1271_spi_write32(wl, WU_COUNTER_PAUSE, pause); 472 wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
478 473
479 /* Continue the ELP wake up sequence */ 474 /* Continue the ELP wake up sequence */
480 wl1271_spi_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); 475 wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
481 udelay(500); 476 udelay(500);
482 477
483 wl1271_set_partition(wl, &part_table[PART_DRPW]); 478 wl1271_set_partition(wl, &part_table[PART_DRPW]);
@@ -487,18 +482,18 @@ int wl1271_boot(struct wl1271 *wl)
487 before taking DRPw out of reset */ 482 before taking DRPw out of reset */
488 483
489 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); 484 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
490 clk = wl1271_spi_read32(wl, DRPW_SCRATCH_START); 485 clk = wl1271_read32(wl, DRPW_SCRATCH_START);
491 486
492 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); 487 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
493 488
494 /* 2 */ 489 /* 2 */
495 clk |= (REF_CLOCK << 1) << 4; 490 clk |= (REF_CLOCK << 1) << 4;
496 wl1271_spi_write32(wl, DRPW_SCRATCH_START, clk); 491 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
497 492
498 wl1271_set_partition(wl, &part_table[PART_WORK]); 493 wl1271_set_partition(wl, &part_table[PART_WORK]);
499 494
500 /* Disable interrupts */ 495 /* Disable interrupts */
501 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); 496 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
502 497
503 ret = wl1271_boot_soft_reset(wl); 498 ret = wl1271_boot_soft_reset(wl);
504 if (ret < 0) 499 if (ret < 0)
@@ -513,23 +508,22 @@ int wl1271_boot(struct wl1271 *wl)
513 * ACX_EEPROMLESS_IND_REG */ 508 * ACX_EEPROMLESS_IND_REG */
514 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); 509 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
515 510
516 wl1271_spi_write32(wl, ACX_EEPROMLESS_IND_REG, 511 wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
517 ACX_EEPROMLESS_IND_REG);
518 512
519 tmp = wl1271_spi_read32(wl, CHIP_ID_B); 513 tmp = wl1271_read32(wl, CHIP_ID_B);
520 514
521 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); 515 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
522 516
523 /* 6. read the EEPROM parameters */ 517 /* 6. read the EEPROM parameters */
524 tmp = wl1271_spi_read32(wl, SCR_PAD2); 518 tmp = wl1271_read32(wl, SCR_PAD2);
525 519
526 ret = wl1271_boot_write_irq_polarity(wl); 520 ret = wl1271_boot_write_irq_polarity(wl);
527 if (ret < 0) 521 if (ret < 0)
528 goto out; 522 goto out;
529 523
530 /* FIXME: Need to check whether this is really what we want */ 524 /* FIXME: Need to check whether this is really what we want */
531 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, 525 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
532 WL1271_ACX_ALL_EVENTS_VECTOR); 526 WL1271_ACX_ALL_EVENTS_VECTOR);
533 527
534 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly 528 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
535 * to upload_fw) */ 529 * to upload_fw) */
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index c3385b3d246c..36a64e06f290 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -30,6 +30,7 @@
30#include "wl1271.h" 30#include "wl1271.h"
31#include "wl1271_reg.h" 31#include "wl1271_reg.h"
32#include "wl1271_spi.h" 32#include "wl1271_spi.h"
33#include "wl1271_io.h"
33#include "wl1271_acx.h" 34#include "wl1271_acx.h"
34#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
35#include "wl1271_cmd.h" 36#include "wl1271_cmd.h"
@@ -57,13 +58,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
57 58
58 WARN_ON(len % 4 != 0); 59 WARN_ON(len % 4 != 0);
59 60
60 wl1271_spi_write(wl, wl->cmd_box_addr, buf, len, false); 61 wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
61 62
62 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 63 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
63 64
64 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 65 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
65 66
66 intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 67 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
67 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 68 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
68 if (time_after(jiffies, timeout)) { 69 if (time_after(jiffies, timeout)) {
69 wl1271_error("command complete timeout"); 70 wl1271_error("command complete timeout");
@@ -73,13 +74,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
73 74
74 msleep(1); 75 msleep(1);
75 76
76 intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 77 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
77 } 78 }
78 79
79 /* read back the status code of the command */ 80 /* read back the status code of the command */
80 if (res_len == 0) 81 if (res_len == 0)
81 res_len = sizeof(struct wl1271_cmd_header); 82 res_len = sizeof(struct wl1271_cmd_header);
82 wl1271_spi_read(wl, wl->cmd_box_addr, cmd, res_len, false); 83 wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false);
83 84
84 status = le16_to_cpu(cmd->status); 85 status = le16_to_cpu(cmd->status);
85 if (status != CMD_STATUS_SUCCESS) { 86 if (status != CMD_STATUS_SUCCESS) {
@@ -87,8 +88,8 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
87 ret = -EIO; 88 ret = -EIO;
88 } 89 }
89 90
90 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK, 91 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
91 WL1271_ACX_INTR_CMD_COMPLETE); 92 WL1271_ACX_INTR_CMD_COMPLETE);
92 93
93out: 94out:
94 return ret; 95 return ret;
@@ -191,23 +192,19 @@ static int wl1271_cmd_cal(struct wl1271 *wl)
191int wl1271_cmd_general_parms(struct wl1271 *wl) 192int wl1271_cmd_general_parms(struct wl1271 *wl)
192{ 193{
193 struct wl1271_general_parms_cmd *gen_parms; 194 struct wl1271_general_parms_cmd *gen_parms;
194 struct conf_general_parms *g = &wl->conf.init.genparam;
195 int ret; 195 int ret;
196 196
197 if (!wl->nvs)
198 return -ENODEV;
199
197 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); 200 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
198 if (!gen_parms) 201 if (!gen_parms)
199 return -ENOMEM; 202 return -ENOMEM;
200 203
201 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 204 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
202 205
203 gen_parms->ref_clk = g->ref_clk; 206 memcpy(gen_parms->params, wl->nvs->general_params,
204 gen_parms->settling_time = g->settling_time; 207 WL1271_NVS_GENERAL_PARAMS_SIZE);
205 gen_parms->clk_valid_on_wakeup = g->clk_valid_on_wakeup;
206 gen_parms->dc2dcmode = g->dc2dcmode;
207 gen_parms->single_dual_band = g->single_dual_band;
208 gen_parms->tx_bip_fem_autodetect = g->tx_bip_fem_autodetect;
209 gen_parms->tx_bip_fem_manufacturer = g->tx_bip_fem_manufacturer;
210 gen_parms->settings = g->settings;
211 208
212 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); 209 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
213 if (ret < 0) 210 if (ret < 0)
@@ -220,8 +217,11 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
220int wl1271_cmd_radio_parms(struct wl1271 *wl) 217int wl1271_cmd_radio_parms(struct wl1271 *wl)
221{ 218{
222 struct wl1271_radio_parms_cmd *radio_parms; 219 struct wl1271_radio_parms_cmd *radio_parms;
223 struct conf_radio_parms *r = &wl->conf.init.radioparam; 220 struct conf_radio_parms *rparam = &wl->conf.init.radioparam;
224 int i, ret; 221 int ret;
222
223 if (!wl->nvs)
224 return -ENODEV;
225 225
226 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); 226 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
227 if (!radio_parms) 227 if (!radio_parms)
@@ -229,60 +229,13 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
229 229
230 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 230 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
231 231
232 /* Static radio parameters */ 232 memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params,
233 radio_parms->rx_trace_loss = r->rx_trace_loss; 233 WL1271_NVS_STAT_RADIO_PARAMS_SIZE);
234 radio_parms->tx_trace_loss = r->tx_trace_loss; 234 memcpy(radio_parms->dyn_radio_params,
235 memcpy(radio_parms->rx_rssi_and_proc_compens, 235 wl->nvs->dyn_radio_params[rparam->fem],
236 r->rx_rssi_and_proc_compens, 236 WL1271_NVS_DYN_RADIO_PARAMS_SIZE);
237 CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE); 237
238 238 /* FIXME: current NVS is missing 5GHz parameters */
239 memcpy(radio_parms->rx_trace_loss_5, r->rx_trace_loss_5,
240 CONF_NUMBER_OF_SUB_BANDS_5);
241 memcpy(radio_parms->tx_trace_loss_5, r->tx_trace_loss_5,
242 CONF_NUMBER_OF_SUB_BANDS_5);
243 memcpy(radio_parms->rx_rssi_and_proc_compens_5,
244 r->rx_rssi_and_proc_compens_5,
245 CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE);
246
247 /* Dynamic radio parameters */
248 radio_parms->tx_ref_pd_voltage = cpu_to_le16(r->tx_ref_pd_voltage);
249 radio_parms->tx_ref_power = r->tx_ref_power;
250 radio_parms->tx_offset_db = r->tx_offset_db;
251
252 memcpy(radio_parms->tx_rate_limits_normal, r->tx_rate_limits_normal,
253 CONF_NUMBER_OF_RATE_GROUPS);
254 memcpy(radio_parms->tx_rate_limits_degraded, r->tx_rate_limits_degraded,
255 CONF_NUMBER_OF_RATE_GROUPS);
256
257 memcpy(radio_parms->tx_channel_limits_11b, r->tx_channel_limits_11b,
258 CONF_NUMBER_OF_CHANNELS_2_4);
259 memcpy(radio_parms->tx_channel_limits_ofdm, r->tx_channel_limits_ofdm,
260 CONF_NUMBER_OF_CHANNELS_2_4);
261 memcpy(radio_parms->tx_pdv_rate_offsets, r->tx_pdv_rate_offsets,
262 CONF_NUMBER_OF_RATE_GROUPS);
263 memcpy(radio_parms->tx_ibias, r->tx_ibias, CONF_NUMBER_OF_RATE_GROUPS);
264
265 radio_parms->rx_fem_insertion_loss = r->rx_fem_insertion_loss;
266
267 for (i = 0; i < CONF_NUMBER_OF_SUB_BANDS_5; i++)
268 radio_parms->tx_ref_pd_voltage_5[i] =
269 cpu_to_le16(r->tx_ref_pd_voltage_5[i]);
270 memcpy(radio_parms->tx_ref_power_5, r->tx_ref_power_5,
271 CONF_NUMBER_OF_SUB_BANDS_5);
272 memcpy(radio_parms->tx_offset_db_5, r->tx_offset_db_5,
273 CONF_NUMBER_OF_SUB_BANDS_5);
274 memcpy(radio_parms->tx_rate_limits_normal_5,
275 r->tx_rate_limits_normal_5, CONF_NUMBER_OF_RATE_GROUPS);
276 memcpy(radio_parms->tx_rate_limits_degraded_5,
277 r->tx_rate_limits_degraded_5, CONF_NUMBER_OF_RATE_GROUPS);
278 memcpy(radio_parms->tx_channel_limits_ofdm_5,
279 r->tx_channel_limits_ofdm_5, CONF_NUMBER_OF_CHANNELS_5);
280 memcpy(radio_parms->tx_pdv_rate_offsets_5, r->tx_pdv_rate_offsets_5,
281 CONF_NUMBER_OF_RATE_GROUPS);
282 memcpy(radio_parms->tx_ibias_5, r->tx_ibias_5,
283 CONF_NUMBER_OF_RATE_GROUPS);
284 memcpy(radio_parms->rx_fem_insertion_loss_5,
285 r->rx_fem_insertion_loss_5, CONF_NUMBER_OF_SUB_BANDS_5);
286 239
287 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 240 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
288 radio_parms, sizeof(*radio_parms)); 241 radio_parms, sizeof(*radio_parms));
@@ -311,19 +264,6 @@ int wl1271_cmd_join(struct wl1271 *wl)
311 do_cal = false; 264 do_cal = false;
312 } 265 }
313 266
314 /* FIXME: This is a workaround, because with the current stack, we
315 * cannot know when we have disassociated. So, if we have already
316 * joined, we disconnect before joining again. */
317 if (wl->joined) {
318 ret = wl1271_cmd_disconnect(wl);
319 if (ret < 0) {
320 wl1271_error("failed to disconnect before rejoining");
321 goto out;
322 }
323
324 wl->joined = false;
325 }
326
327 join = kzalloc(sizeof(*join), GFP_KERNEL); 267 join = kzalloc(sizeof(*join), GFP_KERNEL);
328 if (!join) { 268 if (!join) {
329 ret = -ENOMEM; 269 ret = -ENOMEM;
@@ -388,8 +328,6 @@ int wl1271_cmd_join(struct wl1271 *wl)
388 goto out_free; 328 goto out_free;
389 } 329 }
390 330
391 wl->joined = true;
392
393 /* 331 /*
394 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to 332 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
395 * simplify locking we just sleep instead, for now 333 * simplify locking we just sleep instead, for now
@@ -487,7 +425,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
487 return 0; 425 return 0;
488} 426}
489 427
490int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable) 428int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
491{ 429{
492 struct cmd_enabledisable_path *cmd; 430 struct cmd_enabledisable_path *cmd;
493 int ret; 431 int ret;
@@ -501,7 +439,8 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
501 goto out; 439 goto out;
502 } 440 }
503 441
504 cmd->channel = channel; 442 /* the channel here is only used for calibration, so hardcoded to 1 */
443 cmd->channel = 1;
505 444
506 if (enable) { 445 if (enable) {
507 cmd_rx = CMD_ENABLE_RX; 446 cmd_rx = CMD_ENABLE_RX;
@@ -514,29 +453,29 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
514 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0); 453 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
515 if (ret < 0) { 454 if (ret < 0) {
516 wl1271_error("rx %s cmd for channel %d failed", 455 wl1271_error("rx %s cmd for channel %d failed",
517 enable ? "start" : "stop", channel); 456 enable ? "start" : "stop", cmd->channel);
518 goto out; 457 goto out;
519 } 458 }
520 459
521 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", 460 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
522 enable ? "start" : "stop", channel); 461 enable ? "start" : "stop", cmd->channel);
523 462
524 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0); 463 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
525 if (ret < 0) { 464 if (ret < 0) {
526 wl1271_error("tx %s cmd for channel %d failed", 465 wl1271_error("tx %s cmd for channel %d failed",
527 enable ? "start" : "stop", channel); 466 enable ? "start" : "stop", cmd->channel);
528 return ret; 467 return ret;
529 } 468 }
530 469
531 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 470 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
532 enable ? "start" : "stop", channel); 471 enable ? "start" : "stop", cmd->channel);
533 472
534out: 473out:
535 kfree(cmd); 474 kfree(cmd);
536 return ret; 475 return ret;
537} 476}
538 477
539int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode) 478int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
540{ 479{
541 struct wl1271_cmd_ps_params *ps_params = NULL; 480 struct wl1271_cmd_ps_params *ps_params = NULL;
542 int ret = 0; 481 int ret = 0;
@@ -557,7 +496,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
557 } 496 }
558 497
559 ps_params->ps_mode = ps_mode; 498 ps_params->ps_mode = ps_mode;
560 ps_params->send_null_data = 1; 499 ps_params->send_null_data = send;
561 ps_params->retries = 5; 500 ps_params->retries = 5;
562 ps_params->hang_over_period = 128; 501 ps_params->hang_over_period = 128;
563 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */ 502 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
@@ -636,7 +575,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
636 channels = wl->hw->wiphy->bands[ieee_band]->channels; 575 channels = wl->hw->wiphy->bands[ieee_band]->channels;
637 n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels; 576 n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels;
638 577
639 if (wl->scanning) 578 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags))
640 return -EINVAL; 579 return -EINVAL;
641 580
642 params = kzalloc(sizeof(*params), GFP_KERNEL); 581 params = kzalloc(sizeof(*params), GFP_KERNEL);
@@ -711,7 +650,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
711 650
712 wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 651 wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
713 652
714 wl->scanning = true; 653 set_bit(WL1271_FLAG_SCANNING, &wl->flags);
715 if (wl1271_11a_enabled()) { 654 if (wl1271_11a_enabled()) {
716 wl->scan.state = band; 655 wl->scan.state = band;
717 if (band == WL1271_SCAN_BAND_DUAL) { 656 if (band == WL1271_SCAN_BAND_DUAL) {
@@ -729,7 +668,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
729 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0); 668 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
730 if (ret < 0) { 669 if (ret < 0) {
731 wl1271_error("SCAN failed"); 670 wl1271_error("SCAN failed");
732 wl->scanning = false; 671 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
733 goto out; 672 goto out;
734 } 673 }
735 674
@@ -1003,7 +942,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
1003 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 942 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
1004 if (ret < 0) { 943 if (ret < 0) {
1005 wl1271_warning("could not set keys"); 944 wl1271_warning("could not set keys");
1006 goto out; 945 goto out;
1007 } 946 }
1008 947
1009out: 948out:
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index b4fa4acb9229..2dc06c73532b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -37,8 +37,8 @@ int wl1271_cmd_join(struct wl1271 *wl);
37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
40int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable); 40int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode); 41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
@@ -428,67 +428,24 @@ struct wl1271_general_parms_cmd {
428 428
429 struct wl1271_cmd_test_header test; 429 struct wl1271_cmd_test_header test;
430 430
431 u8 ref_clk; 431 u8 params[WL1271_NVS_GENERAL_PARAMS_SIZE];
432 u8 settling_time; 432 s8 reserved[23];
433 u8 clk_valid_on_wakeup;
434 u8 dc2dcmode;
435 u8 single_dual_band;
436
437 u8 tx_bip_fem_autodetect;
438 u8 tx_bip_fem_manufacturer;
439 u8 settings;
440} __attribute__ ((packed)); 433} __attribute__ ((packed));
441 434
435#define WL1271_STAT_RADIO_PARAMS_5_SIZE 29
436#define WL1271_DYN_RADIO_PARAMS_5_SIZE 104
437
442struct wl1271_radio_parms_cmd { 438struct wl1271_radio_parms_cmd {
443 struct wl1271_cmd_header header; 439 struct wl1271_cmd_header header;
444 440
445 struct wl1271_cmd_test_header test; 441 struct wl1271_cmd_test_header test;
446 442
447 /* Static radio parameters */ 443 u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE];
448 /* 2.4GHz */ 444 u8 stat_radio_params_5[WL1271_STAT_RADIO_PARAMS_5_SIZE];
449 u8 rx_trace_loss;
450 u8 tx_trace_loss;
451 s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
452
453 /* 5GHz */
454 u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
455 u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
456 s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
457
458 /* Dynamic radio parameters */
459 /* 2.4GHz */
460 __le16 tx_ref_pd_voltage;
461 s8 tx_ref_power;
462 s8 tx_offset_db;
463
464 s8 tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
465 s8 tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
466
467 s8 tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
468 s8 tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
469 s8 tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
470
471 u8 tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
472 u8 rx_fem_insertion_loss;
473 445
474 u8 padding2; 446 u8 dyn_radio_params[WL1271_NVS_DYN_RADIO_PARAMS_SIZE];
475 447 u8 reserved;
476 /* 5GHz */ 448 u8 dyn_radio_params_5[WL1271_DYN_RADIO_PARAMS_5_SIZE];
477 __le16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];
478 s8 tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
479 s8 tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
480
481 s8 tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
482 s8 tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
483
484 s8 tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
485 s8 tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
486
487 /* FIXME: this is inconsistent with the types for 2.4GHz */
488 s8 tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
489 s8 rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
490
491 u8 padding3[2];
492} __attribute__ ((packed)); 449} __attribute__ ((packed));
493 450
494struct wl1271_cmd_cal_channel_tune { 451struct wl1271_cmd_cal_channel_tune {
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 565373ede265..6f9e75cc5640 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -258,7 +258,8 @@ struct conf_rx_settings {
258#define CONF_TX_MAX_RATE_CLASSES 8 258#define CONF_TX_MAX_RATE_CLASSES 8
259 259
260#define CONF_TX_RATE_MASK_UNSPECIFIED 0 260#define CONF_TX_RATE_MASK_UNSPECIFIED 0
261#define CONF_TX_RATE_MASK_ALL 0x1eff 261#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \
262 CONF_HW_BIT_RATE_2MBPS)
262#define CONF_TX_RATE_RETRY_LIMIT 10 263#define CONF_TX_RATE_RETRY_LIMIT 10
263 264
264struct conf_tx_rate_class { 265struct conf_tx_rate_class {
@@ -722,31 +723,6 @@ struct conf_conn_settings {
722 u8 psm_entry_retries; 723 u8 psm_entry_retries;
723}; 724};
724 725
725#define CONF_SR_ERR_TBL_MAX_VALUES 14
726
727struct conf_mart_reflex_err_table {
728 /*
729 * Length of the error table values table.
730 *
731 * Range: 0 - CONF_SR_ERR_TBL_MAX_VALUES
732 */
733 u8 len;
734
735 /*
736 * Smart Reflex error table upper limit.
737 *
738 * Range: s8
739 */
740 s8 upper_limit;
741
742 /*
743 * Smart Reflex error table values.
744 *
745 * Range: s8
746 */
747 s8 values[CONF_SR_ERR_TBL_MAX_VALUES];
748};
749
750enum { 726enum {
751 CONF_REF_CLK_19_2_E, 727 CONF_REF_CLK_19_2_E,
752 CONF_REF_CLK_26_E, 728 CONF_REF_CLK_26_E,
@@ -759,64 +735,6 @@ enum single_dual_band_enum {
759 CONF_DUAL_BAND 735 CONF_DUAL_BAND
760}; 736};
761 737
762struct conf_general_parms {
763 /*
764 * RF Reference Clock type / speed
765 *
766 * Range: CONF_REF_CLK_*
767 */
768 u8 ref_clk;
769
770 /*
771 * Settling time of the reference clock after boot.
772 *
773 * Range: u8
774 */
775 u8 settling_time;
776
777 /*
778 * Flag defining whether clock is valid on wakeup.
779 *
780 * Range: 0 - not valid on wakeup, 1 - valid on wakeup
781 */
782 u8 clk_valid_on_wakeup;
783
784 /*
785 * DC-to-DC mode.
786 *
787 * Range: Unknown
788 */
789 u8 dc2dcmode;
790
791 /*
792 * Flag defining whether used as single or dual-band.
793 *
794 * Range: CONF_SINGLE_BAND, CONF_DUAL_BAND
795 */
796 u8 single_dual_band;
797
798 /*
799 * TX bip fem autodetect flag.
800 *
801 * Range: Unknown
802 */
803 u8 tx_bip_fem_autodetect;
804
805 /*
806 * TX bip gem manufacturer.
807 *
808 * Range: Unknown
809 */
810 u8 tx_bip_fem_manufacturer;
811
812 /*
813 * Settings flags.
814 *
815 * Range: Unknown
816 */
817 u8 settings;
818};
819
820#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15 738#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15
821#define CONF_NUMBER_OF_SUB_BANDS_5 7 739#define CONF_NUMBER_OF_SUB_BANDS_5 7
822#define CONF_NUMBER_OF_RATE_GROUPS 6 740#define CONF_NUMBER_OF_RATE_GROUPS 6
@@ -825,87 +743,43 @@ struct conf_general_parms {
825 743
826struct conf_radio_parms { 744struct conf_radio_parms {
827 /* 745 /*
828 * Static radio parameters for 2.4GHz 746 * FEM parameter set to use
829 *
830 * Range: unknown
831 */
832 u8 rx_trace_loss;
833 u8 tx_trace_loss;
834 s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
835
836 /*
837 * Static radio parameters for 5GHz
838 *
839 * Range: unknown
840 */
841 u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
842 u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
843 s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
844
845 /*
846 * Dynamic radio parameters for 2.4GHz
847 * 747 *
848 * Range: unknown 748 * Range: 0 or 1
849 */ 749 */
850 s16 tx_ref_pd_voltage; 750 u8 fem;
851 s8 tx_ref_power; 751};
852 s8 tx_offset_db;
853
854 s8 tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
855 s8 tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
856
857 s8 tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
858 s8 tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
859 s8 tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
860
861 u8 tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
862 u8 rx_fem_insertion_loss;
863 752
753struct conf_init_settings {
864 /* 754 /*
865 * Dynamic radio parameters for 5GHz 755 * Configure radio parameters.
866 *
867 * Range: unknown
868 */ 756 */
869 s16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5]; 757 struct conf_radio_parms radioparam;
870 s8 tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
871 s8 tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
872
873 s8 tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
874 s8 tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
875
876 s8 tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
877 s8 tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
878 758
879 /* FIXME: this is inconsistent with the types for 2.4GHz */
880 s8 tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
881 s8 rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
882}; 759};
883 760
884#define CONF_SR_ERR_TBL_COUNT 3 761struct conf_itrim_settings {
762 /* enable dco itrim */
763 u8 enable;
885 764
886struct conf_init_settings { 765 /* moderation timeout in microsecs from the last TX */
887 /* 766 u32 timeout;
888 * Configure Smart Reflex error table values. 767};
889 */
890 struct conf_mart_reflex_err_table sr_err_tbl[CONF_SR_ERR_TBL_COUNT];
891 768
769struct conf_pm_config_settings {
892 /* 770 /*
893 * Smart Reflex enable flag. 771 * Host clock settling time
894 * 772 *
895 * Range: 1 - Smart Reflex enabled, 0 - Smart Reflex disabled 773 * Range: 0 - 30000 us
896 */
897 u8 sr_enable;
898
899 /*
900 * Configure general parameters.
901 */ 774 */
902 struct conf_general_parms genparam; 775 u32 host_clk_settling_time;
903 776
904 /* 777 /*
905 * Configure radio parameters. 778 * Host fast wakeup support
779 *
780 * Range: true, false
906 */ 781 */
907 struct conf_radio_parms radioparam; 782 bool host_fast_wakeup_support;
908
909}; 783};
910 784
911struct conf_drv_settings { 785struct conf_drv_settings {
@@ -914,6 +788,8 @@ struct conf_drv_settings {
914 struct conf_tx_settings tx; 788 struct conf_tx_settings tx;
915 struct conf_conn_settings conn; 789 struct conf_conn_settings conn;
916 struct conf_init_settings init; 790 struct conf_init_settings init;
791 struct conf_itrim_settings itrim;
792 struct conf_pm_config_settings pm_config;
917}; 793};
918 794
919#endif 795#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index c1805e5f8964..8d7588ca68fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -237,6 +237,64 @@ static const struct file_operations tx_queue_len_ops = {
237 .open = wl1271_open_file_generic, 237 .open = wl1271_open_file_generic,
238}; 238};
239 239
240static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
241 size_t count, loff_t *ppos)
242{
243 struct wl1271 *wl = file->private_data;
244 bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
245
246 int res;
247 char buf[10];
248
249 res = scnprintf(buf, sizeof(buf), "%d\n", state);
250
251 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
252}
253
254static ssize_t gpio_power_write(struct file *file,
255 const char __user *user_buf,
256 size_t count, loff_t *ppos)
257{
258 struct wl1271 *wl = file->private_data;
259 char buf[10];
260 size_t len;
261 unsigned long value;
262 int ret;
263
264 mutex_lock(&wl->mutex);
265
266 len = min(count, sizeof(buf) - 1);
267 if (copy_from_user(buf, user_buf, len)) {
268 ret = -EFAULT;
269 goto out;
270 }
271 buf[len] = '\0';
272
273 ret = strict_strtoul(buf, 0, &value);
274 if (ret < 0) {
275 wl1271_warning("illegal value in gpio_power");
276 goto out;
277 }
278
279 if (value) {
280 wl->set_power(true);
281 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
282 } else {
283 wl->set_power(false);
284 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
285 }
286
287out:
288 mutex_unlock(&wl->mutex);
289 return count;
290}
291
292static const struct file_operations gpio_power_ops = {
293 .read = gpio_power_read,
294 .write = gpio_power_write,
295 .open = wl1271_open_file_generic
296};
297
240static void wl1271_debugfs_delete_files(struct wl1271 *wl) 298static void wl1271_debugfs_delete_files(struct wl1271 *wl)
241{ 299{
242 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); 300 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -333,6 +391,8 @@ static void wl1271_debugfs_delete_files(struct wl1271 *wl)
333 DEBUGFS_DEL(tx_queue_len); 391 DEBUGFS_DEL(tx_queue_len);
334 DEBUGFS_DEL(retry_count); 392 DEBUGFS_DEL(retry_count);
335 DEBUGFS_DEL(excessive_retries); 393 DEBUGFS_DEL(excessive_retries);
394
395 DEBUGFS_DEL(gpio_power);
336} 396}
337 397
338static int wl1271_debugfs_add_files(struct wl1271 *wl) 398static int wl1271_debugfs_add_files(struct wl1271 *wl)
@@ -434,6 +494,8 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl)
434 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); 494 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
435 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); 495 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
436 496
497 DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir);
498
437out: 499out:
438 if (ret < 0) 500 if (ret < 0)
439 wl1271_debugfs_delete_files(wl); 501 wl1271_debugfs_delete_files(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index d13fdd99c85c..7468ef10194b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -24,6 +24,7 @@
24#include "wl1271.h" 24#include "wl1271.h"
25#include "wl1271_reg.h" 25#include "wl1271_reg.h"
26#include "wl1271_spi.h" 26#include "wl1271_spi.h"
27#include "wl1271_io.h"
27#include "wl1271_event.h" 28#include "wl1271_event.h"
28#include "wl1271_ps.h" 29#include "wl1271_ps.h"
29#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
@@ -35,7 +36,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
35 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 36 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
36 mbox->scheduled_scan_status); 37 mbox->scheduled_scan_status);
37 38
38 if (wl->scanning) { 39 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
39 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { 40 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
40 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 41 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
41 NULL, size); 42 NULL, size);
@@ -43,7 +44,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
43 * to the wl1271_cmd_scan function that we are not 44 * to the wl1271_cmd_scan function that we are not
44 * scanning as it checks that. 45 * scanning as it checks that.
45 */ 46 */
46 wl->scanning = false; 47 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
47 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 48 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
48 wl->scan.active, 49 wl->scan.active,
49 wl->scan.high_prio, 50 wl->scan.high_prio,
@@ -62,7 +63,7 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
62 mutex_unlock(&wl->mutex); 63 mutex_unlock(&wl->mutex);
63 ieee80211_scan_completed(wl->hw, false); 64 ieee80211_scan_completed(wl->hw, false);
64 mutex_lock(&wl->mutex); 65 mutex_lock(&wl->mutex);
65 wl->scanning = false; 66 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
66 } 67 }
67 } 68 }
68 return 0; 69 return 0;
@@ -78,25 +79,61 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
78 79
79 switch (mbox->ps_status) { 80 switch (mbox->ps_status) {
80 case EVENT_ENTER_POWER_SAVE_FAIL: 81 case EVENT_ENTER_POWER_SAVE_FAIL:
81 if (!wl->psm) { 82 wl1271_debug(DEBUG_PSM, "PSM entry failed");
83
84 if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
85 /* remain in active mode */
82 wl->psm_entry_retry = 0; 86 wl->psm_entry_retry = 0;
83 break; 87 break;
84 } 88 }
85 89
86 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { 90 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
87 wl->psm_entry_retry++; 91 wl->psm_entry_retry++;
88 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 92 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
93 true);
89 } else { 94 } else {
90 wl1271_error("PSM entry failed, giving up.\n"); 95 wl1271_error("PSM entry failed, giving up.\n");
96 /* FIXME: this may need to be reconsidered. for now it
97 is not possible to indicate to the mac80211
98 afterwards that PSM entry failed. To maximize
99 functionality (receiving data and remaining
100 associated) make sure that we are in sync with the
101 AP in regard of PSM mode. */
102 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
103 false);
91 wl->psm_entry_retry = 0; 104 wl->psm_entry_retry = 0;
92 *beacon_loss = true;
93 } 105 }
94 break; 106 break;
95 case EVENT_ENTER_POWER_SAVE_SUCCESS: 107 case EVENT_ENTER_POWER_SAVE_SUCCESS:
96 wl->psm_entry_retry = 0; 108 wl->psm_entry_retry = 0;
109
110 /* enable beacon filtering */
111 ret = wl1271_acx_beacon_filter_opt(wl, true);
112 if (ret < 0)
113 break;
114
115 /* enable beacon early termination */
116 ret = wl1271_acx_bet_enable(wl, true);
117 if (ret < 0)
118 break;
119
120 /* go to extremely low power mode */
121 wl1271_ps_elp_sleep(wl);
122 if (ret < 0)
123 break;
97 break; 124 break;
98 case EVENT_EXIT_POWER_SAVE_FAIL: 125 case EVENT_EXIT_POWER_SAVE_FAIL:
99 wl1271_info("PSM exit failed"); 126 wl1271_debug(DEBUG_PSM, "PSM exit failed");
127
128 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
129 wl->psm_entry_retry = 0;
130 break;
131 }
132
133 /* make sure the firmware goes to active mode - the frame to
134 be sent next will indicate to the AP, that we are active. */
135 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
136 false);
100 break; 137 break;
101 case EVENT_EXIT_POWER_SAVE_SUCCESS: 138 case EVENT_EXIT_POWER_SAVE_SUCCESS:
102 default: 139 default:
@@ -136,7 +173,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
136 * filtering) is enabled. Without PSM, the stack will receive all 173 * filtering) is enabled. Without PSM, the stack will receive all
137 * beacons and can detect beacon loss by itself. 174 * beacons and can detect beacon loss by itself.
138 */ 175 */
139 if (vector & BSS_LOSE_EVENT_ID && wl->psm) { 176 if (vector & BSS_LOSE_EVENT_ID &&
177 test_bit(WL1271_FLAG_PSM, &wl->flags)) {
140 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); 178 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
141 179
142 /* indicate to the stack, that beacons have been lost */ 180 /* indicate to the stack, that beacons have been lost */
@@ -150,7 +188,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
150 return ret; 188 return ret;
151 } 189 }
152 190
153 if (beacon_loss) { 191 if (wl->vif && beacon_loss) {
154 /* Obviously, it's dangerous to release the mutex while 192 /* Obviously, it's dangerous to release the mutex while
155 we are holding many of the variables in the wl struct. 193 we are holding many of the variables in the wl struct.
156 That's why it's done last in the function, and care must 194 That's why it's done last in the function, and care must
@@ -177,14 +215,14 @@ int wl1271_event_unmask(struct wl1271 *wl)
177 215
178void wl1271_event_mbox_config(struct wl1271 *wl) 216void wl1271_event_mbox_config(struct wl1271 *wl)
179{ 217{
180 wl->mbox_ptr[0] = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR); 218 wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
181 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); 219 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
182 220
183 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", 221 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
184 wl->mbox_ptr[0], wl->mbox_ptr[1]); 222 wl->mbox_ptr[0], wl->mbox_ptr[1]);
185} 223}
186 224
187int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack) 225int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
188{ 226{
189 struct event_mailbox mbox; 227 struct event_mailbox mbox;
190 int ret; 228 int ret;
@@ -195,8 +233,8 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
195 return -EINVAL; 233 return -EINVAL;
196 234
197 /* first we read the mbox descriptor */ 235 /* first we read the mbox descriptor */
198 wl1271_spi_read(wl, wl->mbox_ptr[mbox_num], &mbox, 236 wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox,
199 sizeof(struct event_mailbox), false); 237 sizeof(struct event_mailbox), false);
200 238
201 /* process the descriptor */ 239 /* process the descriptor */
202 ret = wl1271_event_process(wl, &mbox); 240 ret = wl1271_event_process(wl, &mbox);
@@ -204,9 +242,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
204 return ret; 242 return ret;
205 243
206 /* then we let the firmware know it can go on...*/ 244 /* then we let the firmware know it can go on...*/
207 if (do_ack) 245 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
208 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
209 INTR_TRIG_EVENT_ACK);
210 246
211 return 0; 247 return 0;
212} 248}
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 4e3f55ebb1a8..278f9206aa56 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -112,6 +112,6 @@ struct event_mailbox {
112 112
113int wl1271_event_unmask(struct wl1271 *wl); 113int wl1271_event_unmask(struct wl1271 *wl);
114void wl1271_event_mbox_config(struct wl1271 *wl); 114void wl1271_event_mbox_config(struct wl1271 *wl);
115int wl1271_event_handle(struct wl1271 *wl, u8 mbox, bool do_ack); 115int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
116 116
117#endif 117#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 11249b436cf1..86c30a86a456 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -49,7 +49,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
49 return 0; 49 return 0;
50} 50}
51 51
52static int wl1271_init_templates_config(struct wl1271 *wl) 52int wl1271_init_templates_config(struct wl1271 *wl)
53{ 53{
54 int ret; 54 int ret;
55 55
@@ -113,7 +113,7 @@ static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
113 return 0; 113 return 0;
114} 114}
115 115
116static int wl1271_init_phy_config(struct wl1271 *wl) 116int wl1271_init_phy_config(struct wl1271 *wl)
117{ 117{
118 int ret; 118 int ret;
119 119
@@ -156,7 +156,7 @@ static int wl1271_init_beacon_filter(struct wl1271 *wl)
156 return 0; 156 return 0;
157} 157}
158 158
159static int wl1271_init_pta(struct wl1271 *wl) 159int wl1271_init_pta(struct wl1271 *wl)
160{ 160{
161 int ret; 161 int ret;
162 162
@@ -171,7 +171,7 @@ static int wl1271_init_pta(struct wl1271 *wl)
171 return 0; 171 return 0;
172} 172}
173 173
174static int wl1271_init_energy_detection(struct wl1271 *wl) 174int wl1271_init_energy_detection(struct wl1271 *wl)
175{ 175{
176 int ret; 176 int ret;
177 177
@@ -195,7 +195,9 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
195 195
196int wl1271_hw_init(struct wl1271 *wl) 196int wl1271_hw_init(struct wl1271 *wl)
197{ 197{
198 int ret; 198 struct conf_tx_ac_category *conf_ac;
199 struct conf_tx_tid *conf_tid;
200 int ret, i;
199 201
200 ret = wl1271_cmd_general_parms(wl); 202 ret = wl1271_cmd_general_parms(wl);
201 if (ret < 0) 203 if (ret < 0)
@@ -229,6 +231,10 @@ int wl1271_hw_init(struct wl1271 *wl)
229 if (ret < 0) 231 if (ret < 0)
230 goto out_free_memmap; 232 goto out_free_memmap;
231 233
234 ret = wl1271_acx_dco_itrim_params(wl);
235 if (ret < 0)
236 goto out_free_memmap;
237
232 /* Initialize connection monitoring thresholds */ 238 /* Initialize connection monitoring thresholds */
233 ret = wl1271_acx_conn_monit_params(wl); 239 ret = wl1271_acx_conn_monit_params(wl);
234 if (ret < 0) 240 if (ret < 0)
@@ -270,22 +276,36 @@ int wl1271_hw_init(struct wl1271 *wl)
270 goto out_free_memmap; 276 goto out_free_memmap;
271 277
272 /* Default TID configuration */ 278 /* Default TID configuration */
273 ret = wl1271_acx_tid_cfg(wl); 279 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
274 if (ret < 0) 280 conf_tid = &wl->conf.tx.tid_conf[i];
275 goto out_free_memmap; 281 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
282 conf_tid->channel_type,
283 conf_tid->tsid,
284 conf_tid->ps_scheme,
285 conf_tid->ack_policy,
286 conf_tid->apsd_conf[0],
287 conf_tid->apsd_conf[1]);
288 if (ret < 0)
289 goto out_free_memmap;
290 }
276 291
277 /* Default AC configuration */ 292 /* Default AC configuration */
278 ret = wl1271_acx_ac_cfg(wl); 293 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
279 if (ret < 0) 294 conf_ac = &wl->conf.tx.ac_conf[i];
280 goto out_free_memmap; 295 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
296 conf_ac->cw_max, conf_ac->aifsn,
297 conf_ac->tx_op_limit);
298 if (ret < 0)
299 goto out_free_memmap;
300 }
281 301
282 /* Configure TX rate classes */ 302 /* Configure TX rate classes */
283 ret = wl1271_acx_rate_policies(wl, CONF_TX_RATE_MASK_ALL); 303 ret = wl1271_acx_rate_policies(wl);
284 if (ret < 0) 304 if (ret < 0)
285 goto out_free_memmap; 305 goto out_free_memmap;
286 306
287 /* Enable data path */ 307 /* Enable data path */
288 ret = wl1271_cmd_data_path(wl, wl->channel, 1); 308 ret = wl1271_cmd_data_path(wl, 1);
289 if (ret < 0) 309 if (ret < 0)
290 goto out_free_memmap; 310 goto out_free_memmap;
291 311
@@ -299,8 +319,8 @@ int wl1271_hw_init(struct wl1271 *wl)
299 if (ret < 0) 319 if (ret < 0)
300 goto out_free_memmap; 320 goto out_free_memmap;
301 321
302 /* Configure smart reflex */ 322 /* configure PM */
303 ret = wl1271_acx_smart_reflex(wl); 323 ret = wl1271_acx_pm_config(wl);
304 if (ret < 0) 324 if (ret < 0)
305 goto out_free_memmap; 325 goto out_free_memmap;
306 326
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/wl1271_init.h
index 930677fbe852..bc26f8c53b91 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.h
+++ b/drivers/net/wireless/wl12xx/wl1271_init.h
@@ -27,6 +27,10 @@
27#include "wl1271.h" 27#include "wl1271.h"
28 28
29int wl1271_hw_init_power_auth(struct wl1271 *wl); 29int wl1271_hw_init_power_auth(struct wl1271 *wl);
30int wl1271_init_templates_config(struct wl1271 *wl);
31int wl1271_init_phy_config(struct wl1271 *wl);
32int wl1271_init_pta(struct wl1271 *wl);
33int wl1271_init_energy_detection(struct wl1271 *wl);
30int wl1271_hw_init(struct wl1271 *wl); 34int wl1271_hw_init(struct wl1271 *wl);
31 35
32#endif 36#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c
new file mode 100644
index 000000000000..5cd94d5666c2
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_io.c
@@ -0,0 +1,213 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/crc7.h>
27#include <linux/spi/spi.h>
28
29#include "wl1271.h"
30#include "wl12xx_80211.h"
31#include "wl1271_spi.h"
32#include "wl1271_io.h"
33
34static int wl1271_translate_addr(struct wl1271 *wl, int addr)
35{
36 /*
37 * To translate, first check to which window of addresses the
38 * particular address belongs. Then subtract the starting address
39 * of that window from the address. Then, add offset of the
40 * translated region.
41 *
42 * The translated regions occur next to each other in physical device
43 * memory, so just add the sizes of the preceeding address regions to
44 * get the offset to the new region.
45 *
46 * Currently, only the two first regions are addressed, and the
47 * assumption is that all addresses will fall into either of those
48 * two.
49 */
50 if ((addr >= wl->part.reg.start) &&
51 (addr < wl->part.reg.start + wl->part.reg.size))
52 return addr - wl->part.reg.start + wl->part.mem.size;
53 else
54 return addr - wl->part.mem.start;
55}
56
57/* Set the SPI partitions to access the chip addresses
58 *
59 * To simplify driver code, a fixed (virtual) memory map is defined for
60 * register and memory addresses. Because in the chipset, in different stages
61 * of operation, those addresses will move around, an address translation
62 * mechanism is required.
63 *
64 * There are four partitions (three memory and one register partition),
65 * which are mapped to two different areas of the hardware memory.
66 *
67 * Virtual address
68 * space
69 *
70 * | |
71 * ...+----+--> mem.start
72 * Physical address ... | |
73 * space ... | | [PART_0]
74 * ... | |
75 * 00000000 <--+----+... ...+----+--> mem.start + mem.size
76 * | | ... | |
77 * |MEM | ... | |
78 * | | ... | |
79 * mem.size <--+----+... | | {unused area)
80 * | | ... | |
81 * |REG | ... | |
82 * mem.size | | ... | |
83 * + <--+----+... ...+----+--> reg.start
84 * reg.size | | ... | |
85 * |MEM2| ... | | [PART_1]
86 * | | ... | |
87 * ...+----+--> reg.start + reg.size
88 * | |
89 *
90 */
91int wl1271_set_partition(struct wl1271 *wl,
92 struct wl1271_partition_set *p)
93{
94 /* copy partition info */
95 memcpy(&wl->part, p, sizeof(*p));
96
97 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
98 p->mem.start, p->mem.size);
99 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
100 p->reg.start, p->reg.size);
101 wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
102 p->mem2.start, p->mem2.size);
103 wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
104 p->mem3.start, p->mem3.size);
105
106 /* write partition info to the chipset */
107 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
108 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
109 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
110 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
111 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
112 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
113 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
114
115 return 0;
116}
117
118void wl1271_io_reset(struct wl1271 *wl)
119{
120 wl1271_spi_reset(wl);
121}
122
123void wl1271_io_init(struct wl1271 *wl)
124{
125 wl1271_spi_init(wl);
126}
127
128void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
129 size_t len, bool fixed)
130{
131 wl1271_spi_raw_write(wl, addr, buf, len, fixed);
132}
133
134void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
135 size_t len, bool fixed)
136{
137 wl1271_spi_raw_read(wl, addr, buf, len, fixed);
138}
139
140void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
141 bool fixed)
142{
143 int physical;
144
145 physical = wl1271_translate_addr(wl, addr);
146
147 wl1271_spi_raw_read(wl, physical, buf, len, fixed);
148}
149
150void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
151 bool fixed)
152{
153 int physical;
154
155 physical = wl1271_translate_addr(wl, addr);
156
157 wl1271_spi_raw_write(wl, physical, buf, len, fixed);
158}
159
160u32 wl1271_read32(struct wl1271 *wl, int addr)
161{
162 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
163}
164
165void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
166{
167 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
168}
169
170void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
171{
172 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
173 addr = (addr >> 1) + 0x30000;
174 wl1271_write32(wl, OCP_POR_CTR, addr);
175
176 /* write value to OCP_POR_WDATA */
177 wl1271_write32(wl, OCP_DATA_WRITE, val);
178
179 /* write 1 to OCP_CMD */
180 wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);
181}
182
183u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
184{
185 u32 val;
186 int timeout = OCP_CMD_LOOP;
187
188 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
189 addr = (addr >> 1) + 0x30000;
190 wl1271_write32(wl, OCP_POR_CTR, addr);
191
192 /* write 2 to OCP_CMD */
193 wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);
194
195 /* poll for data ready */
196 do {
197 val = wl1271_read32(wl, OCP_DATA_READ);
198 } while (!(val & OCP_READY_MASK) && --timeout);
199
200 if (!timeout) {
201 wl1271_warning("Top register access timed out.");
202 return 0xffff;
203 }
204
205 /* check data status and return if OK */
206 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
207 return val & 0xffff;
208 else {
209 wl1271_warning("Top register access returned error.");
210 return 0xffff;
211 }
212}
213
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
new file mode 100644
index 000000000000..fa9a0b35788f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -0,0 +1,68 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL1271_IO_H__
26#define __WL1271_IO_H__
27
28struct wl1271;
29
30void wl1271_io_reset(struct wl1271 *wl);
31void wl1271_io_init(struct wl1271 *wl);
32
33/* Raw target IO, address is not translated */
34void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
35 size_t len, bool fixed);
36void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
37 size_t len, bool fixed);
38
39/* Translated target IO */
40void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
41 bool fixed);
42void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
43 bool fixed);
44u32 wl1271_read32(struct wl1271 *wl, int addr);
45void wl1271_write32(struct wl1271 *wl, int addr, u32 val);
46
47/* Top Register IO */
48void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
49u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
50
51int wl1271_set_partition(struct wl1271 *wl,
52 struct wl1271_partition_set *p);
53
54static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
55{
56 wl1271_raw_read(wl, addr, &wl->buffer_32,
57 sizeof(wl->buffer_32), false);
58
59 return wl->buffer_32;
60}
61
62static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
63{
64 wl->buffer_32 = val;
65 wl1271_raw_write(wl, addr, &wl->buffer_32,
66 sizeof(wl->buffer_32), false);
67}
68#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index b62c00ff42fe..2a864b24291d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2008-2009 Nokia Corporation 4 * Copyright (C) 2008-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -38,6 +38,7 @@
38#include "wl12xx_80211.h" 38#include "wl12xx_80211.h"
39#include "wl1271_reg.h" 39#include "wl1271_reg.h"
40#include "wl1271_spi.h" 40#include "wl1271_spi.h"
41#include "wl1271_io.h"
41#include "wl1271_event.h" 42#include "wl1271_event.h"
42#include "wl1271_tx.h" 43#include "wl1271_tx.h"
43#include "wl1271_rx.h" 44#include "wl1271_rx.h"
@@ -46,6 +47,9 @@
46#include "wl1271_debugfs.h" 47#include "wl1271_debugfs.h"
47#include "wl1271_cmd.h" 48#include "wl1271_cmd.h"
48#include "wl1271_boot.h" 49#include "wl1271_boot.h"
50#include "wl1271_testmode.h"
51
52#define WL1271_BOOT_RETRIES 3
49 53
50static struct conf_drv_settings default_conf = { 54static struct conf_drv_settings default_conf = {
51 .sg = { 55 .sg = {
@@ -67,16 +71,17 @@ static struct conf_drv_settings default_conf = {
67 .ps_poll_timeout = 15, 71 .ps_poll_timeout = 15,
68 .upsd_timeout = 15, 72 .upsd_timeout = 15,
69 .rts_threshold = 2347, 73 .rts_threshold = 2347,
70 .rx_cca_threshold = 0xFFEF, 74 .rx_cca_threshold = 0,
71 .irq_blk_threshold = 0, 75 .irq_blk_threshold = 0xFFFF,
72 .irq_pkt_threshold = USHORT_MAX, 76 .irq_pkt_threshold = 0,
73 .irq_timeout = 5, 77 .irq_timeout = 600,
74 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, 78 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
75 }, 79 },
76 .tx = { 80 .tx = {
77 .tx_energy_detection = 0, 81 .tx_energy_detection = 0,
78 .rc_conf = { 82 .rc_conf = {
79 .enabled_rates = CONF_TX_RATE_MASK_UNSPECIFIED, 83 .enabled_rates = CONF_HW_BIT_RATE_1MBPS |
84 CONF_HW_BIT_RATE_2MBPS,
80 .short_retry_limit = 10, 85 .short_retry_limit = 10,
81 .long_retry_limit = 10, 86 .long_retry_limit = 10,
82 .aflags = 0 87 .aflags = 0
@@ -172,8 +177,8 @@ static struct conf_drv_settings default_conf = {
172 } 177 }
173 }, 178 },
174 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 179 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
175 .tx_compl_timeout = 5, 180 .tx_compl_timeout = 700,
176 .tx_compl_threshold = 5 181 .tx_compl_threshold = 4
177 }, 182 },
178 .conn = { 183 .conn = {
179 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 184 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
@@ -186,12 +191,12 @@ static struct conf_drv_settings default_conf = {
186 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, 191 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
187 } 192 }
188 }, 193 },
189 .synch_fail_thold = 5, 194 .synch_fail_thold = 10,
190 .bss_lose_timeout = 100, 195 .bss_lose_timeout = 100,
191 .beacon_rx_timeout = 10000, 196 .beacon_rx_timeout = 10000,
192 .broadcast_timeout = 20000, 197 .broadcast_timeout = 20000,
193 .rx_broadcast_in_ps = 1, 198 .rx_broadcast_in_ps = 1,
194 .ps_poll_threshold = 4, 199 .ps_poll_threshold = 20,
195 .sig_trigger_count = 2, 200 .sig_trigger_count = 2,
196 .sig_trigger = { 201 .sig_trigger = {
197 [0] = { 202 [0] = {
@@ -226,97 +231,17 @@ static struct conf_drv_settings default_conf = {
226 .psm_entry_retries = 3 231 .psm_entry_retries = 3
227 }, 232 },
228 .init = { 233 .init = {
229 .sr_err_tbl = {
230 [0] = {
231 .len = 7,
232 .upper_limit = 0x03,
233 .values = {
234 0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
235 0x00 }
236 },
237 [1] = {
238 .len = 7,
239 .upper_limit = 0x03,
240 .values = {
241 0x18, 0x10, 0x05, 0xf6, 0xf0, 0xe8,
242 0x00 }
243 },
244 [2] = {
245 .len = 7,
246 .upper_limit = 0x03,
247 .values = {
248 0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
249 0x00 }
250 }
251 },
252 .sr_enable = 1,
253 .genparam = {
254 .ref_clk = CONF_REF_CLK_38_4_E,
255 .settling_time = 5,
256 .clk_valid_on_wakeup = 0,
257 .dc2dcmode = 0,
258 .single_dual_band = CONF_SINGLE_BAND,
259 .tx_bip_fem_autodetect = 0,
260 .tx_bip_fem_manufacturer = 1,
261 .settings = 1,
262 },
263 .radioparam = { 234 .radioparam = {
264 .rx_trace_loss = 10, 235 .fem = 1,
265 .tx_trace_loss = 10,
266 .rx_rssi_and_proc_compens = {
267 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8,
268 0xfc, 0x00, 0x08, 0x10, 0xf0, 0xf8,
269 0x00, 0x0a, 0x14 },
270 .rx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },
271 .tx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },
272 .rx_rssi_and_proc_compens_5 = {
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00 },
276 .tx_ref_pd_voltage = 0x24e,
277 .tx_ref_power = 0x78,
278 .tx_offset_db = 0x0,
279 .tx_rate_limits_normal = {
280 0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 },
281 .tx_rate_limits_degraded = {
282 0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 },
283 .tx_channel_limits_11b = {
284 0x22, 0x50, 0x50, 0x50, 0x50, 0x50,
285 0x50, 0x50, 0x50, 0x50, 0x22, 0x50,
286 0x22, 0x50 },
287 .tx_channel_limits_ofdm = {
288 0x20, 0x50, 0x50, 0x50, 0x50, 0x50,
289 0x50, 0x50, 0x50, 0x50, 0x20, 0x50,
290 0x20, 0x50 },
291 .tx_pdv_rate_offsets = {
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
293 .tx_ibias = {
294 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 },
295 .rx_fem_insertion_loss = 0x14,
296 .tx_ref_pd_voltage_5 = {
297 0x0190, 0x01a4, 0x01c3, 0x01d8,
298 0x020a, 0x021c },
299 .tx_ref_power_5 = {
300 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
301 .tx_offset_db_5 = {
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
303 .tx_rate_limits_normal_5 = {
304 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
305 .tx_rate_limits_degraded_5 = {
306 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
307 .tx_channel_limits_ofdm_5 = {
308 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
309 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
310 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
311 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
312 0x50, 0x50, 0x50 },
313 .tx_pdv_rate_offsets_5 = {
314 0x01, 0x02, 0x02, 0x02, 0x02, 0x00 },
315 .tx_ibias_5 = {
316 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
317 .rx_fem_insertion_loss_5 = {
318 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }
319 } 236 }
237 },
238 .itrim = {
239 .enable = false,
240 .timeout = 50000,
241 },
242 .pm_config = {
243 .host_clk_settling_time = 5000,
244 .host_fast_wakeup_support = false
320 } 245 }
321}; 246};
322 247
@@ -337,15 +262,14 @@ static void wl1271_conf_init(struct wl1271 *wl)
337 262
338 /* apply driver default configuration */ 263 /* apply driver default configuration */
339 memcpy(&wl->conf, &default_conf, sizeof(default_conf)); 264 memcpy(&wl->conf, &default_conf, sizeof(default_conf));
340
341 if (wl1271_11a_enabled())
342 wl->conf.init.genparam.single_dual_band = CONF_DUAL_BAND;
343} 265}
344 266
345 267
346static int wl1271_plt_init(struct wl1271 *wl) 268static int wl1271_plt_init(struct wl1271 *wl)
347{ 269{
348 int ret; 270 struct conf_tx_ac_category *conf_ac;
271 struct conf_tx_tid *conf_tid;
272 int ret, i;
349 273
350 ret = wl1271_cmd_general_parms(wl); 274 ret = wl1271_cmd_general_parms(wl);
351 if (ret < 0) 275 if (ret < 0)
@@ -355,15 +279,89 @@ static int wl1271_plt_init(struct wl1271 *wl)
355 if (ret < 0) 279 if (ret < 0)
356 return ret; 280 return ret;
357 281
358 ret = wl1271_acx_init_mem_config(wl); 282 ret = wl1271_init_templates_config(wl);
359 if (ret < 0) 283 if (ret < 0)
360 return ret; 284 return ret;
361 285
362 ret = wl1271_cmd_data_path(wl, wl->channel, 1); 286 ret = wl1271_acx_init_mem_config(wl);
363 if (ret < 0) 287 if (ret < 0)
364 return ret; 288 return ret;
365 289
290 /* PHY layer config */
291 ret = wl1271_init_phy_config(wl);
292 if (ret < 0)
293 goto out_free_memmap;
294
295 ret = wl1271_acx_dco_itrim_params(wl);
296 if (ret < 0)
297 goto out_free_memmap;
298
299 /* Initialize connection monitoring thresholds */
300 ret = wl1271_acx_conn_monit_params(wl);
301 if (ret < 0)
302 goto out_free_memmap;
303
304 /* Bluetooth WLAN coexistence */
305 ret = wl1271_init_pta(wl);
306 if (ret < 0)
307 goto out_free_memmap;
308
309 /* Energy detection */
310 ret = wl1271_init_energy_detection(wl);
311 if (ret < 0)
312 goto out_free_memmap;
313
314 /* Default fragmentation threshold */
315 ret = wl1271_acx_frag_threshold(wl);
316 if (ret < 0)
317 goto out_free_memmap;
318
319 /* Default TID configuration */
320 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
321 conf_tid = &wl->conf.tx.tid_conf[i];
322 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
323 conf_tid->channel_type,
324 conf_tid->tsid,
325 conf_tid->ps_scheme,
326 conf_tid->ack_policy,
327 conf_tid->apsd_conf[0],
328 conf_tid->apsd_conf[1]);
329 if (ret < 0)
330 goto out_free_memmap;
331 }
332
333 /* Default AC configuration */
334 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
335 conf_ac = &wl->conf.tx.ac_conf[i];
336 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
337 conf_ac->cw_max, conf_ac->aifsn,
338 conf_ac->tx_op_limit);
339 if (ret < 0)
340 goto out_free_memmap;
341 }
342
343 /* Enable data path */
344 ret = wl1271_cmd_data_path(wl, 1);
345 if (ret < 0)
346 goto out_free_memmap;
347
348 /* Configure for CAM power saving (ie. always active) */
349 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
350 if (ret < 0)
351 goto out_free_memmap;
352
353 /* configure PM */
354 ret = wl1271_acx_pm_config(wl);
355 if (ret < 0)
356 goto out_free_memmap;
357
366 return 0; 358 return 0;
359
360 out_free_memmap:
361 kfree(wl->target_mem_map);
362 wl->target_mem_map = NULL;
363
364 return ret;
367} 365}
368 366
369static void wl1271_disable_interrupts(struct wl1271 *wl) 367static void wl1271_disable_interrupts(struct wl1271 *wl)
@@ -374,11 +372,13 @@ static void wl1271_disable_interrupts(struct wl1271 *wl)
374static void wl1271_power_off(struct wl1271 *wl) 372static void wl1271_power_off(struct wl1271 *wl)
375{ 373{
376 wl->set_power(false); 374 wl->set_power(false);
375 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
377} 376}
378 377
379static void wl1271_power_on(struct wl1271 *wl) 378static void wl1271_power_on(struct wl1271 *wl)
380{ 379{
381 wl->set_power(true); 380 wl->set_power(true);
381 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
382} 382}
383 383
384static void wl1271_fw_status(struct wl1271 *wl, 384static void wl1271_fw_status(struct wl1271 *wl,
@@ -387,8 +387,7 @@ static void wl1271_fw_status(struct wl1271 *wl,
387 u32 total = 0; 387 u32 total = 0;
388 int i; 388 int i;
389 389
390 wl1271_spi_read(wl, FW_STATUS_ADDR, status, 390 wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
391 sizeof(*status), false);
392 391
393 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 392 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
394 "drv_rx_counter = %d, tx_results_counter = %d)", 393 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -435,7 +434,7 @@ static void wl1271_irq_work(struct work_struct *work)
435 if (ret < 0) 434 if (ret < 0)
436 goto out; 435 goto out;
437 436
438 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); 437 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
439 438
440 wl1271_fw_status(wl, wl->fw_status); 439 wl1271_fw_status(wl, wl->fw_status);
441 intr = le32_to_cpu(wl->fw_status->intr); 440 intr = le32_to_cpu(wl->fw_status->intr);
@@ -447,14 +446,13 @@ static void wl1271_irq_work(struct work_struct *work)
447 intr &= WL1271_INTR_MASK; 446 intr &= WL1271_INTR_MASK;
448 447
449 if (intr & WL1271_ACX_INTR_EVENT_A) { 448 if (intr & WL1271_ACX_INTR_EVENT_A) {
450 bool do_ack = (intr & WL1271_ACX_INTR_EVENT_B) ? false : true;
451 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); 449 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
452 wl1271_event_handle(wl, 0, do_ack); 450 wl1271_event_handle(wl, 0);
453 } 451 }
454 452
455 if (intr & WL1271_ACX_INTR_EVENT_B) { 453 if (intr & WL1271_ACX_INTR_EVENT_B) {
456 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); 454 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
457 wl1271_event_handle(wl, 1, true); 455 wl1271_event_handle(wl, 1);
458 } 456 }
459 457
460 if (intr & WL1271_ACX_INTR_INIT_COMPLETE) 458 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
@@ -478,8 +476,8 @@ static void wl1271_irq_work(struct work_struct *work)
478 } 476 }
479 477
480out_sleep: 478out_sleep:
481 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, 479 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
482 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 480 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
483 wl1271_ps_elp_sleep(wl); 481 wl1271_ps_elp_sleep(wl);
484 482
485out: 483out:
@@ -546,6 +544,40 @@ out:
546 return ret; 544 return ret;
547} 545}
548 546
547static int wl1271_update_mac_addr(struct wl1271 *wl)
548{
549 int ret = 0;
550 u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
551
552 /* get mac address from the NVS */
553 wl->mac_addr[0] = nvs_ptr[11];
554 wl->mac_addr[1] = nvs_ptr[10];
555 wl->mac_addr[2] = nvs_ptr[6];
556 wl->mac_addr[3] = nvs_ptr[5];
557 wl->mac_addr[4] = nvs_ptr[4];
558 wl->mac_addr[5] = nvs_ptr[3];
559
560 /* FIXME: if it is a zero-address, we should bail out. Now, instead,
561 we randomize an address */
562 if (is_zero_ether_addr(wl->mac_addr)) {
563 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
564 memcpy(wl->mac_addr, nokia_oui, 3);
565 get_random_bytes(wl->mac_addr + 3, 3);
566
567 /* update this address to the NVS */
568 nvs_ptr[11] = wl->mac_addr[0];
569 nvs_ptr[10] = wl->mac_addr[1];
570 nvs_ptr[6] = wl->mac_addr[2];
571 nvs_ptr[5] = wl->mac_addr[3];
572 nvs_ptr[4] = wl->mac_addr[4];
573 nvs_ptr[3] = wl->mac_addr[5];
574 }
575
576 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
577
578 return ret;
579}
580
549static int wl1271_fetch_nvs(struct wl1271 *wl) 581static int wl1271_fetch_nvs(struct wl1271 *wl)
550{ 582{
551 const struct firmware *fw; 583 const struct firmware *fw;
@@ -558,15 +590,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
558 return ret; 590 return ret;
559 } 591 }
560 592
561 if (fw->size % 4) { 593 if (fw->size != sizeof(struct wl1271_nvs_file)) {
562 wl1271_error("nvs size is not multiple of 32 bits: %zu", 594 wl1271_error("nvs size is not as expected: %zu != %zu",
563 fw->size); 595 fw->size, sizeof(struct wl1271_nvs_file));
564 ret = -EILSEQ; 596 ret = -EILSEQ;
565 goto out; 597 goto out;
566 } 598 }
567 599
568 wl->nvs_len = fw->size; 600 wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
569 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
570 601
571 if (!wl->nvs) { 602 if (!wl->nvs) {
572 wl1271_error("could not allocate memory for the nvs file"); 603 wl1271_error("could not allocate memory for the nvs file");
@@ -574,9 +605,9 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
574 goto out; 605 goto out;
575 } 606 }
576 607
577 memcpy(wl->nvs, fw->data, wl->nvs_len); 608 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));
578 609
579 ret = 0; 610 ret = wl1271_update_mac_addr(wl);
580 611
581out: 612out:
582 release_firmware(fw); 613 release_firmware(fw);
@@ -614,10 +645,11 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
614 struct wl1271_partition_set partition; 645 struct wl1271_partition_set partition;
615 int ret = 0; 646 int ret = 0;
616 647
648 msleep(WL1271_PRE_POWER_ON_SLEEP);
617 wl1271_power_on(wl); 649 wl1271_power_on(wl);
618 msleep(WL1271_POWER_ON_SLEEP); 650 msleep(WL1271_POWER_ON_SLEEP);
619 wl1271_spi_reset(wl); 651 wl1271_io_reset(wl);
620 wl1271_spi_init(wl); 652 wl1271_io_init(wl);
621 653
622 /* We don't need a real memory partition here, because we only want 654 /* We don't need a real memory partition here, because we only want
623 * to use the registers at this point. */ 655 * to use the registers at this point. */
@@ -632,7 +664,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
632 /* whal_FwCtrl_BootSm() */ 664 /* whal_FwCtrl_BootSm() */
633 665
634 /* 0. read chip id from CHIP_ID */ 666 /* 0. read chip id from CHIP_ID */
635 wl->chip.id = wl1271_spi_read32(wl, CHIP_ID_B); 667 wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
636 668
637 /* 1. check if chip id is valid */ 669 /* 1. check if chip id is valid */
638 670
@@ -643,7 +675,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
643 675
644 ret = wl1271_setup(wl); 676 ret = wl1271_setup(wl);
645 if (ret < 0) 677 if (ret < 0)
646 goto out_power_off; 678 goto out;
647 break; 679 break;
648 case CHIP_ID_1271_PG20: 680 case CHIP_ID_1271_PG20:
649 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", 681 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
@@ -651,38 +683,34 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
651 683
652 ret = wl1271_setup(wl); 684 ret = wl1271_setup(wl);
653 if (ret < 0) 685 if (ret < 0)
654 goto out_power_off; 686 goto out;
655 break; 687 break;
656 default: 688 default:
657 wl1271_error("unsupported chip id: 0x%x", wl->chip.id); 689 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
658 ret = -ENODEV; 690 ret = -ENODEV;
659 goto out_power_off; 691 goto out;
660 } 692 }
661 693
662 if (wl->fw == NULL) { 694 if (wl->fw == NULL) {
663 ret = wl1271_fetch_firmware(wl); 695 ret = wl1271_fetch_firmware(wl);
664 if (ret < 0) 696 if (ret < 0)
665 goto out_power_off; 697 goto out;
666 } 698 }
667 699
668 /* No NVS from netlink, try to get it from the filesystem */ 700 /* No NVS from netlink, try to get it from the filesystem */
669 if (wl->nvs == NULL) { 701 if (wl->nvs == NULL) {
670 ret = wl1271_fetch_nvs(wl); 702 ret = wl1271_fetch_nvs(wl);
671 if (ret < 0) 703 if (ret < 0)
672 goto out_power_off; 704 goto out;
673 } 705 }
674 706
675 goto out;
676
677out_power_off:
678 wl1271_power_off(wl);
679
680out: 707out:
681 return ret; 708 return ret;
682} 709}
683 710
684int wl1271_plt_start(struct wl1271 *wl) 711int wl1271_plt_start(struct wl1271 *wl)
685{ 712{
713 int retries = WL1271_BOOT_RETRIES;
686 int ret; 714 int ret;
687 715
688 mutex_lock(&wl->mutex); 716 mutex_lock(&wl->mutex);
@@ -696,35 +724,43 @@ int wl1271_plt_start(struct wl1271 *wl)
696 goto out; 724 goto out;
697 } 725 }
698 726
699 wl->state = WL1271_STATE_PLT; 727 while (retries) {
700 728 retries--;
701 ret = wl1271_chip_wakeup(wl); 729 ret = wl1271_chip_wakeup(wl);
702 if (ret < 0) 730 if (ret < 0)
703 goto out; 731 goto power_off;
704
705 ret = wl1271_boot(wl);
706 if (ret < 0)
707 goto out_power_off;
708
709 wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
710
711 ret = wl1271_plt_init(wl);
712 if (ret < 0)
713 goto out_irq_disable;
714 732
715 /* Make sure power saving is disabled */ 733 ret = wl1271_boot(wl);
716 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 734 if (ret < 0)
717 if (ret < 0) 735 goto power_off;
718 goto out_irq_disable;
719 736
720 goto out; 737 ret = wl1271_plt_init(wl);
738 if (ret < 0)
739 goto irq_disable;
721 740
722out_irq_disable: 741 wl->state = WL1271_STATE_PLT;
723 wl1271_disable_interrupts(wl); 742 wl1271_notice("firmware booted in PLT mode (%s)",
743 wl->chip.fw_ver);
744 goto out;
724 745
725out_power_off: 746irq_disable:
726 wl1271_power_off(wl); 747 wl1271_disable_interrupts(wl);
748 mutex_unlock(&wl->mutex);
749 /* Unlocking the mutex in the middle of handling is
750 inherently unsafe. In this case we deem it safe to do,
751 because we need to let any possibly pending IRQ out of
752 the system (and while we are WL1271_STATE_OFF the IRQ
753 work function will not do anything.) Also, any other
754 possible concurrent operations will fail due to the
755 current state, hence the wl1271 struct should be safe. */
756 cancel_work_sync(&wl->irq_work);
757 mutex_lock(&wl->mutex);
758power_off:
759 wl1271_power_off(wl);
760 }
727 761
762 wl1271_error("firmware boot in PLT mode failed despite %d retries",
763 WL1271_BOOT_RETRIES);
728out: 764out:
729 mutex_unlock(&wl->mutex); 765 mutex_unlock(&wl->mutex);
730 766
@@ -762,7 +798,20 @@ out:
762static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 798static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
763{ 799{
764 struct wl1271 *wl = hw->priv; 800 struct wl1271 *wl = hw->priv;
801 struct ieee80211_conf *conf = &hw->conf;
802 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
803 struct ieee80211_sta *sta = txinfo->control.sta;
804 unsigned long flags;
805
806 /* peek into the rates configured in the STA entry */
807 spin_lock_irqsave(&wl->wl_lock, flags);
808 if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
809 wl->sta_rate_set = sta->supp_rates[conf->channel->band];
810 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
811 }
812 spin_unlock_irqrestore(&wl->wl_lock, flags);
765 813
814 /* queue the packet */
766 skb_queue_tail(&wl->tx_queue, skb); 815 skb_queue_tail(&wl->tx_queue, skb);
767 816
768 /* 817 /*
@@ -784,7 +833,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
784 * protected. Maybe fix this by removing the stupid 833 * protected. Maybe fix this by removing the stupid
785 * variable altogether and checking the real queue state? 834 * variable altogether and checking the real queue state?
786 */ 835 */
787 wl->tx_queue_stopped = true; 836 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
788 } 837 }
789 838
790 return NETDEV_TX_OK; 839 return NETDEV_TX_OK;
@@ -880,6 +929,7 @@ static struct notifier_block wl1271_dev_notifier = {
880static int wl1271_op_start(struct ieee80211_hw *hw) 929static int wl1271_op_start(struct ieee80211_hw *hw)
881{ 930{
882 struct wl1271 *wl = hw->priv; 931 struct wl1271 *wl = hw->priv;
932 int retries = WL1271_BOOT_RETRIES;
883 int ret = 0; 933 int ret = 0;
884 934
885 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 935 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -893,30 +943,42 @@ static int wl1271_op_start(struct ieee80211_hw *hw)
893 goto out; 943 goto out;
894 } 944 }
895 945
896 ret = wl1271_chip_wakeup(wl); 946 while (retries) {
897 if (ret < 0) 947 retries--;
898 goto out; 948 ret = wl1271_chip_wakeup(wl);
899 949 if (ret < 0)
900 ret = wl1271_boot(wl); 950 goto power_off;
901 if (ret < 0)
902 goto out_power_off;
903
904 ret = wl1271_hw_init(wl);
905 if (ret < 0)
906 goto out_irq_disable;
907
908 wl->state = WL1271_STATE_ON;
909 951
910 wl1271_info("firmware booted (%s)", wl->chip.fw_ver); 952 ret = wl1271_boot(wl);
953 if (ret < 0)
954 goto power_off;
911 955
912 goto out; 956 ret = wl1271_hw_init(wl);
957 if (ret < 0)
958 goto irq_disable;
913 959
914out_irq_disable: 960 wl->state = WL1271_STATE_ON;
915 wl1271_disable_interrupts(wl); 961 wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
962 goto out;
916 963
917out_power_off: 964irq_disable:
918 wl1271_power_off(wl); 965 wl1271_disable_interrupts(wl);
966 mutex_unlock(&wl->mutex);
967 /* Unlocking the mutex in the middle of handling is
968 inherently unsafe. In this case we deem it safe to do,
969 because we need to let any possibly pending IRQ out of
970 the system (and while we are WL1271_STATE_OFF the IRQ
971 work function will not do anything.) Also, any other
972 possible concurrent operations will fail due to the
973 current state, hence the wl1271 struct should be safe. */
974 cancel_work_sync(&wl->irq_work);
975 mutex_lock(&wl->mutex);
976power_off:
977 wl1271_power_off(wl);
978 }
919 979
980 wl1271_error("firmware boot failed despite %d retries",
981 WL1271_BOOT_RETRIES);
920out: 982out:
921 mutex_unlock(&wl->mutex); 983 mutex_unlock(&wl->mutex);
922 984
@@ -944,11 +1006,10 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
944 1006
945 WARN_ON(wl->state != WL1271_STATE_ON); 1007 WARN_ON(wl->state != WL1271_STATE_ON);
946 1008
947 if (wl->scanning) { 1009 if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
948 mutex_unlock(&wl->mutex); 1010 mutex_unlock(&wl->mutex);
949 ieee80211_scan_completed(wl->hw, true); 1011 ieee80211_scan_completed(wl->hw, true);
950 mutex_lock(&wl->mutex); 1012 mutex_lock(&wl->mutex);
951 wl->scanning = false;
952 } 1013 }
953 1014
954 wl->state = WL1271_STATE_OFF; 1015 wl->state = WL1271_STATE_OFF;
@@ -973,10 +1034,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
973 wl->band = IEEE80211_BAND_2GHZ; 1034 wl->band = IEEE80211_BAND_2GHZ;
974 1035
975 wl->rx_counter = 0; 1036 wl->rx_counter = 0;
976 wl->elp = false;
977 wl->psm = 0;
978 wl->psm_entry_retry = 0; 1037 wl->psm_entry_retry = 0;
979 wl->tx_queue_stopped = false;
980 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 1038 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
981 wl->tx_blocks_available = 0; 1039 wl->tx_blocks_available = 0;
982 wl->tx_results_count = 0; 1040 wl->tx_results_count = 0;
@@ -986,7 +1044,9 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
986 wl->tx_security_seq_32 = 0; 1044 wl->tx_security_seq_32 = 0;
987 wl->time_offset = 0; 1045 wl->time_offset = 0;
988 wl->session_counter = 0; 1046 wl->session_counter = 0;
989 wl->joined = false; 1047 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1048 wl->sta_rate_set = 0;
1049 wl->flags = 0;
990 1050
991 for (i = 0; i < NUM_TX_QUEUES; i++) 1051 for (i = 0; i < NUM_TX_QUEUES; i++)
992 wl->tx_blocks_freed[i] = 0; 1052 wl->tx_blocks_freed[i] = 0;
@@ -996,13 +1056,13 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
996} 1056}
997 1057
998static int wl1271_op_add_interface(struct ieee80211_hw *hw, 1058static int wl1271_op_add_interface(struct ieee80211_hw *hw,
999 struct ieee80211_if_init_conf *conf) 1059 struct ieee80211_vif *vif)
1000{ 1060{
1001 struct wl1271 *wl = hw->priv; 1061 struct wl1271 *wl = hw->priv;
1002 int ret = 0; 1062 int ret = 0;
1003 1063
1004 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 1064 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
1005 conf->type, conf->mac_addr); 1065 vif->type, vif->addr);
1006 1066
1007 mutex_lock(&wl->mutex); 1067 mutex_lock(&wl->mutex);
1008 if (wl->vif) { 1068 if (wl->vif) {
@@ -1010,9 +1070,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
1010 goto out; 1070 goto out;
1011 } 1071 }
1012 1072
1013 wl->vif = conf->vif; 1073 wl->vif = vif;
1014 1074
1015 switch (conf->type) { 1075 switch (vif->type) {
1016 case NL80211_IFTYPE_STATION: 1076 case NL80211_IFTYPE_STATION:
1017 wl->bss_type = BSS_TYPE_STA_BSS; 1077 wl->bss_type = BSS_TYPE_STA_BSS;
1018 break; 1078 break;
@@ -1032,7 +1092,7 @@ out:
1032} 1092}
1033 1093
1034static void wl1271_op_remove_interface(struct ieee80211_hw *hw, 1094static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1035 struct ieee80211_if_init_conf *conf) 1095 struct ieee80211_vif *vif)
1036{ 1096{
1037 struct wl1271 *wl = hw->priv; 1097 struct wl1271 *wl = hw->priv;
1038 1098
@@ -1109,6 +1169,51 @@ out:
1109} 1169}
1110#endif 1170#endif
1111 1171
1172static int wl1271_join_channel(struct wl1271 *wl, int channel)
1173{
1174 int ret = 0;
1175 /* we need to use a dummy BSSID for now */
1176 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1177 0xad, 0xbe, 0xef };
1178
1179 /* the dummy join is not required for ad-hoc */
1180 if (wl->bss_type == BSS_TYPE_IBSS)
1181 goto out;
1182
1183 /* disable mac filter, so we hear everything */
1184 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1185
1186 wl->channel = channel;
1187 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1188
1189 ret = wl1271_cmd_join(wl);
1190 if (ret < 0)
1191 goto out;
1192
1193 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1194
1195out:
1196 return ret;
1197}
1198
1199static int wl1271_unjoin_channel(struct wl1271 *wl)
1200{
1201 int ret;
1202
1203 /* to stop listening to a channel, we disconnect */
1204 ret = wl1271_cmd_disconnect(wl);
1205 if (ret < 0)
1206 goto out;
1207
1208 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1209 wl->channel = 0;
1210 memset(wl->bssid, 0, ETH_ALEN);
1211 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1212
1213out:
1214 return ret;
1215}
1216
1112static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1217static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1113{ 1218{
1114 struct wl1271 *wl = hw->priv; 1219 struct wl1271 *wl = hw->priv;
@@ -1117,10 +1222,11 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1117 1222
1118 channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 1223 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
1119 1224
1120 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", 1225 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s",
1121 channel, 1226 channel,
1122 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 1227 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
1123 conf->power_level); 1228 conf->power_level,
1229 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use");
1124 1230
1125 mutex_lock(&wl->mutex); 1231 mutex_lock(&wl->mutex);
1126 1232
@@ -1130,35 +1236,55 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1130 if (ret < 0) 1236 if (ret < 0)
1131 goto out; 1237 goto out;
1132 1238
1133 if (channel != wl->channel) { 1239 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1134 /* 1240 if (conf->flags & IEEE80211_CONF_IDLE &&
1135 * We assume that the stack will configure the right channel 1241 test_bit(WL1271_FLAG_JOINED, &wl->flags))
1136 * before associating, so we don't need to send a join 1242 wl1271_unjoin_channel(wl);
1137 * command here. We will join the right channel when the 1243 else if (!(conf->flags & IEEE80211_CONF_IDLE))
1138 * BSSID changes 1244 wl1271_join_channel(wl, channel);
1139 */ 1245
1140 wl->channel = channel; 1246 if (conf->flags & IEEE80211_CONF_IDLE) {
1247 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1248 wl->sta_rate_set = 0;
1249 wl1271_acx_rate_policies(wl);
1250 }
1141 } 1251 }
1142 1252
1143 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { 1253 /* if the channel changes while joined, join again */
1144 wl1271_info("psm enabled"); 1254 if (channel != wl->channel &&
1255 test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1256 wl->channel = channel;
1257 /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
1258 ret = wl1271_cmd_join(wl);
1259 if (ret < 0)
1260 wl1271_warning("cmd join to update channel failed %d",
1261 ret);
1262 } else
1263 wl->channel = channel;
1145 1264
1146 wl->psm_requested = true; 1265 if (conf->flags & IEEE80211_CONF_PS &&
1266 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1267 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
1147 1268
1148 /* 1269 /*
1149 * We enter PSM only if we're already associated. 1270 * We enter PSM only if we're already associated.
1150 * If we're not, we'll enter it when joining an SSID, 1271 * If we're not, we'll enter it when joining an SSID,
1151 * through the bss_info_changed() hook. 1272 * through the bss_info_changed() hook.
1152 */ 1273 */
1153 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 1274 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1275 wl1271_info("psm enabled");
1276 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1277 true);
1278 }
1154 } else if (!(conf->flags & IEEE80211_CONF_PS) && 1279 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1155 wl->psm_requested) { 1280 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1156 wl1271_info("psm disabled"); 1281 wl1271_info("psm disabled");
1157 1282
1158 wl->psm_requested = false; 1283 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
1159 1284
1160 if (wl->psm) 1285 if (test_bit(WL1271_FLAG_PSM, &wl->flags))
1161 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE); 1286 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
1287 true);
1162 } 1288 }
1163 1289
1164 if (conf->power_level != wl->power_level) { 1290 if (conf->power_level != wl->power_level) {
@@ -1350,9 +1476,24 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1350 wl1271_error("Could not add or replace key"); 1476 wl1271_error("Could not add or replace key");
1351 goto out_sleep; 1477 goto out_sleep;
1352 } 1478 }
1479
1480 /* the default WEP key needs to be configured at least once */
1481 if (key_type == KEY_WEP) {
1482 ret = wl1271_cmd_set_default_wep_key(wl,
1483 wl->default_key);
1484 if (ret < 0)
1485 goto out_sleep;
1486 }
1353 break; 1487 break;
1354 1488
1355 case DISABLE_KEY: 1489 case DISABLE_KEY:
1490 /* The wl1271 does not allow to remove unicast keys - they
1491 will be cleared automatically on next CMD_JOIN. Ignore the
1492 request silently, as we dont want the mac80211 to emit
1493 an error message. */
1494 if (!is_broadcast_ether_addr(addr))
1495 break;
1496
1356 ret = wl1271_cmd_set_key(wl, KEY_REMOVE, 1497 ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
1357 key_conf->keyidx, key_type, 1498 key_conf->keyidx, key_type,
1358 key_conf->keylen, key_conf->key, 1499 key_conf->keylen, key_conf->key,
@@ -1440,20 +1581,21 @@ out:
1440 return ret; 1581 return ret;
1441} 1582}
1442 1583
1443static u32 wl1271_enabled_rates_get(struct wl1271 *wl, u64 basic_rate_set) 1584static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon)
1444{ 1585{
1445 struct ieee80211_supported_band *band; 1586 u8 *ptr = beacon->data +
1446 u32 enabled_rates = 0; 1587 offsetof(struct ieee80211_mgmt, u.beacon.variable);
1447 int bit; 1588
1448 1589 /* find the location of the ssid in the beacon */
1449 band = wl->hw->wiphy->bands[wl->band]; 1590 while (ptr < beacon->data + beacon->len) {
1450 for (bit = 0; bit < band->n_bitrates; bit++) { 1591 if (ptr[0] == WLAN_EID_SSID) {
1451 if (basic_rate_set & 0x1) 1592 wl->ssid_len = ptr[1];
1452 enabled_rates |= band->bitrates[bit].hw_value; 1593 memcpy(wl->ssid, ptr+2, wl->ssid_len);
1453 basic_rate_set >>= 1; 1594 return;
1595 }
1596 ptr += ptr[1];
1454 } 1597 }
1455 1598 wl1271_error("ad-hoc beacon template has no SSID!\n");
1456 return enabled_rates;
1457} 1599}
1458 1600
1459static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, 1601static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -1463,6 +1605,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1463{ 1605{
1464 enum wl1271_cmd_ps_mode mode; 1606 enum wl1271_cmd_ps_mode mode;
1465 struct wl1271 *wl = hw->priv; 1607 struct wl1271 *wl = hw->priv;
1608 bool do_join = false;
1466 int ret; 1609 int ret;
1467 1610
1468 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1611 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1473,9 +1616,67 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1473 if (ret < 0) 1616 if (ret < 0)
1474 goto out; 1617 goto out;
1475 1618
1619 if (wl->bss_type == BSS_TYPE_IBSS) {
1620 /* FIXME: This implements rudimentary ad-hoc support -
1621 proper templates are on the wish list and notification
1622 on when they change. This patch will update the templates
1623 on every call to this function. */
1624 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1625
1626 if (beacon) {
1627 struct ieee80211_hdr *hdr;
1628
1629 wl1271_ssid_set(wl, beacon);
1630 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1631 beacon->data,
1632 beacon->len);
1633
1634 if (ret < 0) {
1635 dev_kfree_skb(beacon);
1636 goto out_sleep;
1637 }
1638
1639 hdr = (struct ieee80211_hdr *) beacon->data;
1640 hdr->frame_control = cpu_to_le16(
1641 IEEE80211_FTYPE_MGMT |
1642 IEEE80211_STYPE_PROBE_RESP);
1643
1644 ret = wl1271_cmd_template_set(wl,
1645 CMD_TEMPL_PROBE_RESPONSE,
1646 beacon->data,
1647 beacon->len);
1648 dev_kfree_skb(beacon);
1649 if (ret < 0)
1650 goto out_sleep;
1651
1652 /* Need to update the SSID (for filtering etc) */
1653 do_join = true;
1654 }
1655 }
1656
1657 if ((changed & BSS_CHANGED_BSSID) &&
1658 /*
1659 * Now we know the correct bssid, so we send a new join command
1660 * and enable the BSSID filter
1661 */
1662 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1663 wl->rx_config |= CFG_BSSID_FILTER_EN;
1664 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1665 ret = wl1271_cmd_build_null_data(wl);
1666 if (ret < 0) {
1667 wl1271_warning("cmd buld null data failed %d",
1668 ret);
1669 goto out_sleep;
1670 }
1671
1672 /* Need to update the BSSID (for filtering etc) */
1673 do_join = true;
1674 }
1675
1476 if (changed & BSS_CHANGED_ASSOC) { 1676 if (changed & BSS_CHANGED_ASSOC) {
1477 if (bss_conf->assoc) { 1677 if (bss_conf->assoc) {
1478 wl->aid = bss_conf->aid; 1678 wl->aid = bss_conf->aid;
1679 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1479 1680
1480 /* 1681 /*
1481 * with wl1271, we don't need to update the 1682 * with wl1271, we don't need to update the
@@ -1492,15 +1693,16 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1492 goto out_sleep; 1693 goto out_sleep;
1493 1694
1494 /* If we want to go in PSM but we're not there yet */ 1695 /* If we want to go in PSM but we're not there yet */
1495 if (wl->psm_requested && !wl->psm) { 1696 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
1697 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
1496 mode = STATION_POWER_SAVE_MODE; 1698 mode = STATION_POWER_SAVE_MODE;
1497 ret = wl1271_ps_set_mode(wl, mode); 1699 ret = wl1271_ps_set_mode(wl, mode, true);
1498 if (ret < 0) 1700 if (ret < 0)
1499 goto out_sleep; 1701 goto out_sleep;
1500 } 1702 }
1501 } else { 1703 } else {
1502 /* use defaults when not associated */ 1704 /* use defaults when not associated */
1503 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET; 1705 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1504 wl->aid = 0; 1706 wl->aid = 0;
1505 } 1707 }
1506 1708
@@ -1535,15 +1737,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1535 } 1737 }
1536 } 1738 }
1537 1739
1538 if (changed & BSS_CHANGED_BASIC_RATES) { 1740 if (do_join) {
1539 wl->basic_rate_set = wl1271_enabled_rates_get( 1741 ret = wl1271_cmd_join(wl);
1540 wl, bss_conf->basic_rates);
1541
1542 ret = wl1271_acx_rate_policies(wl, wl->basic_rate_set);
1543 if (ret < 0) { 1742 if (ret < 0) {
1544 wl1271_warning("Set rate policies failed %d", ret); 1743 wl1271_warning("cmd join failed %d", ret);
1545 goto out_sleep; 1744 goto out_sleep;
1546 } 1745 }
1746 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1547 } 1747 }
1548 1748
1549out_sleep: 1749out_sleep:
@@ -1553,6 +1753,43 @@ out:
1553 mutex_unlock(&wl->mutex); 1753 mutex_unlock(&wl->mutex);
1554} 1754}
1555 1755
1756static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1757 const struct ieee80211_tx_queue_params *params)
1758{
1759 struct wl1271 *wl = hw->priv;
1760 int ret;
1761
1762 mutex_lock(&wl->mutex);
1763
1764 wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
1765
1766 ret = wl1271_ps_elp_wakeup(wl, false);
1767 if (ret < 0)
1768 goto out;
1769
1770 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
1771 params->cw_min, params->cw_max,
1772 params->aifs, params->txop);
1773 if (ret < 0)
1774 goto out_sleep;
1775
1776 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
1777 CONF_CHANNEL_TYPE_EDCF,
1778 wl1271_tx_get_queue(queue),
1779 CONF_PS_SCHEME_LEGACY_PSPOLL,
1780 CONF_ACK_POLICY_LEGACY, 0, 0);
1781 if (ret < 0)
1782 goto out_sleep;
1783
1784out_sleep:
1785 wl1271_ps_elp_sleep(wl);
1786
1787out:
1788 mutex_unlock(&wl->mutex);
1789
1790 return ret;
1791}
1792
1556 1793
1557/* can't be const, mac80211 writes to this */ 1794/* can't be const, mac80211 writes to this */
1558static struct ieee80211_rate wl1271_rates[] = { 1795static struct ieee80211_rate wl1271_rates[] = {
@@ -1599,19 +1836,19 @@ static struct ieee80211_rate wl1271_rates[] = {
1599 1836
1600/* can't be const, mac80211 writes to this */ 1837/* can't be const, mac80211 writes to this */
1601static struct ieee80211_channel wl1271_channels[] = { 1838static struct ieee80211_channel wl1271_channels[] = {
1602 { .hw_value = 1, .center_freq = 2412}, 1839 { .hw_value = 1, .center_freq = 2412, .max_power = 25 },
1603 { .hw_value = 2, .center_freq = 2417}, 1840 { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
1604 { .hw_value = 3, .center_freq = 2422}, 1841 { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
1605 { .hw_value = 4, .center_freq = 2427}, 1842 { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
1606 { .hw_value = 5, .center_freq = 2432}, 1843 { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
1607 { .hw_value = 6, .center_freq = 2437}, 1844 { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
1608 { .hw_value = 7, .center_freq = 2442}, 1845 { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
1609 { .hw_value = 8, .center_freq = 2447}, 1846 { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
1610 { .hw_value = 9, .center_freq = 2452}, 1847 { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
1611 { .hw_value = 10, .center_freq = 2457}, 1848 { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
1612 { .hw_value = 11, .center_freq = 2462}, 1849 { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
1613 { .hw_value = 12, .center_freq = 2467}, 1850 { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
1614 { .hw_value = 13, .center_freq = 2472}, 1851 { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
1615}; 1852};
1616 1853
1617/* can't be const, mac80211 writes to this */ 1854/* can't be const, mac80211 writes to this */
@@ -1718,6 +1955,8 @@ static const struct ieee80211_ops wl1271_ops = {
1718 .hw_scan = wl1271_op_hw_scan, 1955 .hw_scan = wl1271_op_hw_scan,
1719 .bss_info_changed = wl1271_op_bss_info_changed, 1956 .bss_info_changed = wl1271_op_bss_info_changed,
1720 .set_rts_threshold = wl1271_op_set_rts_threshold, 1957 .set_rts_threshold = wl1271_op_set_rts_threshold,
1958 .conf_tx = wl1271_op_conf_tx,
1959 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
1721}; 1960};
1722 1961
1723static int wl1271_register_hw(struct wl1271 *wl) 1962static int wl1271_register_hw(struct wl1271 *wl)
@@ -1757,7 +1996,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
1757 IEEE80211_HW_BEACON_FILTER | 1996 IEEE80211_HW_BEACON_FILTER |
1758 IEEE80211_HW_SUPPORTS_PS; 1997 IEEE80211_HW_SUPPORTS_PS;
1759 1998
1760 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1999 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2000 BIT(NL80211_IFTYPE_ADHOC);
1761 wl->hw->wiphy->max_scan_ssids = 1; 2001 wl->hw->wiphy->max_scan_ssids = 1;
1762 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; 2002 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
1763 2003
@@ -1785,24 +2025,17 @@ static struct platform_device wl1271_device = {
1785}; 2025};
1786 2026
1787#define WL1271_DEFAULT_CHANNEL 0 2027#define WL1271_DEFAULT_CHANNEL 0
1788static int __devinit wl1271_probe(struct spi_device *spi) 2028
2029static struct ieee80211_hw *wl1271_alloc_hw(void)
1789{ 2030{
1790 struct wl12xx_platform_data *pdata;
1791 struct ieee80211_hw *hw; 2031 struct ieee80211_hw *hw;
1792 struct wl1271 *wl; 2032 struct wl1271 *wl;
1793 int ret, i; 2033 int i;
1794 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
1795
1796 pdata = spi->dev.platform_data;
1797 if (!pdata) {
1798 wl1271_error("no platform data");
1799 return -ENODEV;
1800 }
1801 2034
1802 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2035 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
1803 if (!hw) { 2036 if (!hw) {
1804 wl1271_error("could not alloc ieee80211_hw"); 2037 wl1271_error("could not alloc ieee80211_hw");
1805 return -ENOMEM; 2038 return ERR_PTR(-ENOMEM);
1806 } 2039 }
1807 2040
1808 wl = hw->priv; 2041 wl = hw->priv;
@@ -1811,44 +2044,80 @@ static int __devinit wl1271_probe(struct spi_device *spi)
1811 INIT_LIST_HEAD(&wl->list); 2044 INIT_LIST_HEAD(&wl->list);
1812 2045
1813 wl->hw = hw; 2046 wl->hw = hw;
1814 dev_set_drvdata(&spi->dev, wl);
1815 wl->spi = spi;
1816 2047
1817 skb_queue_head_init(&wl->tx_queue); 2048 skb_queue_head_init(&wl->tx_queue);
1818 2049
1819 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2050 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
1820 wl->channel = WL1271_DEFAULT_CHANNEL; 2051 wl->channel = WL1271_DEFAULT_CHANNEL;
1821 wl->scanning = false;
1822 wl->default_key = 0; 2052 wl->default_key = 0;
1823 wl->rx_counter = 0; 2053 wl->rx_counter = 0;
1824 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 2054 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1825 wl->rx_filter = WL1271_DEFAULT_RX_FILTER; 2055 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1826 wl->elp = false;
1827 wl->psm = 0;
1828 wl->psm_requested = false;
1829 wl->psm_entry_retry = 0; 2056 wl->psm_entry_retry = 0;
1830 wl->tx_queue_stopped = false;
1831 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 2057 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1832 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET; 2058 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2059 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2060 wl->sta_rate_set = 0;
1833 wl->band = IEEE80211_BAND_2GHZ; 2061 wl->band = IEEE80211_BAND_2GHZ;
1834 wl->vif = NULL; 2062 wl->vif = NULL;
1835 wl->joined = false; 2063 wl->flags = 0;
1836 2064
1837 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 2065 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
1838 wl->tx_frames[i] = NULL; 2066 wl->tx_frames[i] = NULL;
1839 2067
1840 spin_lock_init(&wl->wl_lock); 2068 spin_lock_init(&wl->wl_lock);
1841 2069
1842 /*
1843 * In case our MAC address is not correctly set,
1844 * we use a random but Nokia MAC.
1845 */
1846 memcpy(wl->mac_addr, nokia_oui, 3);
1847 get_random_bytes(wl->mac_addr + 3, 3);
1848
1849 wl->state = WL1271_STATE_OFF; 2070 wl->state = WL1271_STATE_OFF;
1850 mutex_init(&wl->mutex); 2071 mutex_init(&wl->mutex);
1851 2072
2073 /* Apply default driver configuration. */
2074 wl1271_conf_init(wl);
2075
2076 return hw;
2077}
2078
2079int wl1271_free_hw(struct wl1271 *wl)
2080{
2081 ieee80211_unregister_hw(wl->hw);
2082
2083 wl1271_debugfs_exit(wl);
2084
2085 kfree(wl->target_mem_map);
2086 vfree(wl->fw);
2087 wl->fw = NULL;
2088 kfree(wl->nvs);
2089 wl->nvs = NULL;
2090
2091 kfree(wl->fw_status);
2092 kfree(wl->tx_res_if);
2093
2094 ieee80211_free_hw(wl->hw);
2095
2096 return 0;
2097}
2098
2099static int __devinit wl1271_probe(struct spi_device *spi)
2100{
2101 struct wl12xx_platform_data *pdata;
2102 struct ieee80211_hw *hw;
2103 struct wl1271 *wl;
2104 int ret;
2105
2106 pdata = spi->dev.platform_data;
2107 if (!pdata) {
2108 wl1271_error("no platform data");
2109 return -ENODEV;
2110 }
2111
2112 hw = wl1271_alloc_hw();
2113 if (IS_ERR(hw))
2114 return PTR_ERR(hw);
2115
2116 wl = hw->priv;
2117
2118 dev_set_drvdata(&spi->dev, wl);
2119 wl->spi = spi;
2120
1852 /* This is the only SPI value that we need to set here, the rest 2121 /* This is the only SPI value that we need to set here, the rest
1853 * comes from the board-peripherals file */ 2122 * comes from the board-peripherals file */
1854 spi->bits_per_word = 32; 2123 spi->bits_per_word = 32;
@@ -1890,9 +2159,6 @@ static int __devinit wl1271_probe(struct spi_device *spi)
1890 } 2159 }
1891 dev_set_drvdata(&wl1271_device.dev, wl); 2160 dev_set_drvdata(&wl1271_device.dev, wl);
1892 2161
1893 /* Apply default driver configuration. */
1894 wl1271_conf_init(wl);
1895
1896 ret = wl1271_init_ieee80211(wl); 2162 ret = wl1271_init_ieee80211(wl);
1897 if (ret) 2163 if (ret)
1898 goto out_platform; 2164 goto out_platform;
@@ -1923,21 +2189,10 @@ static int __devexit wl1271_remove(struct spi_device *spi)
1923{ 2189{
1924 struct wl1271 *wl = dev_get_drvdata(&spi->dev); 2190 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
1925 2191
1926 ieee80211_unregister_hw(wl->hw);
1927
1928 wl1271_debugfs_exit(wl);
1929 platform_device_unregister(&wl1271_device); 2192 platform_device_unregister(&wl1271_device);
1930 free_irq(wl->irq, wl); 2193 free_irq(wl->irq, wl);
1931 kfree(wl->target_mem_map);
1932 vfree(wl->fw);
1933 wl->fw = NULL;
1934 kfree(wl->nvs);
1935 wl->nvs = NULL;
1936 2194
1937 kfree(wl->fw_status); 2195 wl1271_free_hw(wl);
1938 kfree(wl->tx_res_if);
1939
1940 ieee80211_free_hw(wl->hw);
1941 2196
1942 return 0; 2197 return 0;
1943} 2198}
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index 507cd91d7eed..e2b1ebf096e8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -24,6 +24,7 @@
24#include "wl1271_reg.h" 24#include "wl1271_reg.h"
25#include "wl1271_ps.h" 25#include "wl1271_ps.h"
26#include "wl1271_spi.h" 26#include "wl1271_spi.h"
27#include "wl1271_io.h"
27 28
28#define WL1271_WAKEUP_TIMEOUT 500 29#define WL1271_WAKEUP_TIMEOUT 500
29 30
@@ -39,12 +40,13 @@ void wl1271_elp_work(struct work_struct *work)
39 40
40 mutex_lock(&wl->mutex); 41 mutex_lock(&wl->mutex);
41 42
42 if (wl->elp || !wl->psm) 43 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
44 !test_bit(WL1271_FLAG_PSM, &wl->flags))
43 goto out; 45 goto out;
44 46
45 wl1271_debug(DEBUG_PSM, "chip to elp"); 47 wl1271_debug(DEBUG_PSM, "chip to elp");
46 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 48 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
47 wl->elp = true; 49 set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
48 50
49out: 51out:
50 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
@@ -55,7 +57,7 @@ out:
55/* Routines to toggle sleep mode while in ELP */ 57/* Routines to toggle sleep mode while in ELP */
56void wl1271_ps_elp_sleep(struct wl1271 *wl) 58void wl1271_ps_elp_sleep(struct wl1271 *wl)
57{ 59{
58 if (wl->psm) { 60 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
59 cancel_delayed_work(&wl->elp_work); 61 cancel_delayed_work(&wl->elp_work);
60 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
61 msecs_to_jiffies(ELP_ENTRY_DELAY)); 63 msecs_to_jiffies(ELP_ENTRY_DELAY));
@@ -70,7 +72,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
70 u32 start_time = jiffies; 72 u32 start_time = jiffies;
71 bool pending = false; 73 bool pending = false;
72 74
73 if (!wl->elp) 75 if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
74 return 0; 76 return 0;
75 77
76 wl1271_debug(DEBUG_PSM, "waking up chip from elp"); 78 wl1271_debug(DEBUG_PSM, "waking up chip from elp");
@@ -101,7 +103,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
101 } 103 }
102 } 104 }
103 105
104 wl->elp = false; 106 clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
105 107
106 wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", 108 wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
107 jiffies_to_msecs(jiffies - start_time)); 109 jiffies_to_msecs(jiffies - start_time));
@@ -117,7 +119,8 @@ out:
117 return 0; 119 return 0;
118} 120}
119 121
120int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode) 122int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
123 bool send)
121{ 124{
122 int ret; 125 int ret;
123 126
@@ -125,25 +128,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
125 case STATION_POWER_SAVE_MODE: 128 case STATION_POWER_SAVE_MODE:
126 wl1271_debug(DEBUG_PSM, "entering psm"); 129 wl1271_debug(DEBUG_PSM, "entering psm");
127 130
128 /* enable beacon filtering */ 131 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);
129 ret = wl1271_acx_beacon_filter_opt(wl, true);
130 if (ret < 0) 132 if (ret < 0)
131 return ret; 133 return ret;
132 134
133 /* enable beacon early termination */ 135 set_bit(WL1271_FLAG_PSM, &wl->flags);
134 ret = wl1271_acx_bet_enable(wl, true);
135 if (ret < 0)
136 return ret;
137
138 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
139 if (ret < 0)
140 return ret;
141
142 wl1271_ps_elp_sleep(wl);
143 if (ret < 0)
144 return ret;
145
146 wl->psm = 1;
147 break; 136 break;
148 case STATION_ACTIVE_MODE: 137 case STATION_ACTIVE_MODE:
149 default: 138 default:
@@ -162,11 +151,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
162 if (ret < 0) 151 if (ret < 0)
163 return ret; 152 return ret;
164 153
165 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE); 154 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);
166 if (ret < 0) 155 if (ret < 0)
167 return ret; 156 return ret;
168 157
169 wl->psm = 0; 158 clear_bit(WL1271_FLAG_PSM, &wl->flags);
170 break; 159 break;
171 } 160 }
172 161
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index 779653d0ae85..940276f517a4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -27,7 +27,8 @@
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_acx.h" 28#include "wl1271_acx.h"
29 29
30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode); 30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
31 bool send);
31void wl1271_ps_elp_sleep(struct wl1271 *wl); 32void wl1271_ps_elp_sleep(struct wl1271 *wl);
32int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); 33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
33void wl1271_elp_work(struct work_struct *work); 34void wl1271_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h
index 1f237389d1c7..990960771528 100644
--- a/drivers/net/wireless/wl12xx/wl1271_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1271_reg.h
@@ -62,73 +62,10 @@
62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) 62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) 63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) 64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
65/*
66 * Interrupt registers.
67 * 64 bit interrupt sources registers ws ced.
68 * sme interupts were removed and new ones were added.
69 * Order was changed.
70 */
71#define FIQ_MASK (REGISTERS_BASE + 0x0400)
72#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
73#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
74#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
75#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
76#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
77#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
78#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
79#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
80#define IRQ_MASK (REGISTERS_BASE + 0x0418)
81#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
82#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
83#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
84#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
85#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
86#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
87#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
88#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
89#define ECPU_MASK (REGISTERS_BASE + 0x0448)
90#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
91#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
92#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
93#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
94#define INT_STS_ND (REGISTERS_BASE + 0x0464)
95#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
96#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
97#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
98#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
99#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
100#define INT_ACK (REGISTERS_BASE + 0x046C)
101#define INT_ACK_L (REGISTERS_BASE + 0x046C)
102#define INT_ACK_H (REGISTERS_BASE + 0x0470)
103#define INT_TRIG (REGISTERS_BASE + 0x0474)
104#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
105#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
106#define HOST_STS_L (REGISTERS_BASE + 0x045C)
107#define HOST_STS_H (REGISTERS_BASE + 0x0460)
108#define HOST_MASK (REGISTERS_BASE + 0x0430)
109#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
110#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
111#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
112#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
113#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
114#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
115#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
116#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
117 65
118#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) 66#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
119#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) 67#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
120 68
121/* Host Interrupts*/
122#define HINT_MASK (REGISTERS_BASE + 0x0494)
123#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
124#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
125#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
126/*1150 spec calls this HINT_STS_RAW*/
127#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
128#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
129#define HINT_ACK (REGISTERS_BASE + 0x04A8)
130#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
131
132/*============================================= 69/*=============================================
133 Host Interrupt Mask Register - 32bit (RW) 70 Host Interrupt Mask Register - 32bit (RW)
134 ------------------------------------------ 71 ------------------------------------------
@@ -433,16 +370,6 @@
433 370
434 371
435/*=============================================== 372/*===============================================
436 Phy regs
437 ===============================================*/
438#define ACX_PHY_ADDR_REG SBB_ADDR
439#define ACX_PHY_DATA_REG SBB_DATA
440#define ACX_PHY_CTRL_REG SBB_CTL
441#define ACX_PHY_REG_WR_MASK 0x00000001ul
442#define ACX_PHY_REG_RD_MASK 0x00000002ul
443
444
445/*===============================================
446 EEPROM Read/Write Request 32bit RW 373 EEPROM Read/Write Request 32bit RW
447 ------------------------------------------ 374 ------------------------------------------
448 1 EE_READ - EEPROM Read Request 1 - Setting this bit 375 1 EE_READ - EEPROM Read Request 1 - Setting this bit
@@ -511,28 +438,6 @@
511#define ACX_CONT_WIND_MIN_MASK 0x0000007f 438#define ACX_CONT_WIND_MIN_MASK 0x0000007f
512#define ACX_CONT_WIND_MAX 0x03ff0000 439#define ACX_CONT_WIND_MAX 0x03ff0000
513 440
514/*
515 * Indirect slave register/memory registers
516 * ----------------------------------------
517 */
518#define HW_SLAVE_REG_ADDR_REG 0x00000004
519#define HW_SLAVE_REG_DATA_REG 0x00000008
520#define HW_SLAVE_REG_CTRL_REG 0x0000000c
521
522#define SLAVE_AUTO_INC 0x00010000
523#define SLAVE_NO_AUTO_INC 0x00000000
524#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
525
526#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
527#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
528#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
529#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
530
531#define HW_FUNC_EVENT_INT_EN 0x8000
532#define HW_FUNC_EVENT_MASK_REG 0x00000034
533
534#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
535
536/*=============================================== 441/*===============================================
537 HI_CFG Interface Configuration Register Values 442 HI_CFG Interface Configuration Register Values
538 ------------------------------------------ 443 ------------------------------------------
@@ -647,10 +552,6 @@ b12-b0 - Supported Rate indicator bits as defined below.
647******************************************************************************/ 552******************************************************************************/
648 553
649 554
650#define TNETW1251_CHIP_ID_PG1_0 0x07010101
651#define TNETW1251_CHIP_ID_PG1_1 0x07020101
652#define TNETW1251_CHIP_ID_PG1_2 0x07030101
653
654/************************************************************************* 555/*************************************************************************
655 556
656 Interrupt Trigger Register (Host -> WiLink) 557 Interrupt Trigger Register (Host -> WiLink)
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index ca645f38109b..6730f5b96e76 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -26,6 +26,7 @@
26#include "wl1271_reg.h" 26#include "wl1271_reg.h"
27#include "wl1271_rx.h" 27#include "wl1271_rx.h"
28#include "wl1271_spi.h" 28#include "wl1271_spi.h"
29#include "wl1271_io.h"
29 30
30static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, 31static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
31 u32 drv_rx_counter) 32 u32 drv_rx_counter)
@@ -166,7 +167,7 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
166 } 167 }
167 168
168 buf = skb_put(skb, length); 169 buf = skb_put(skb, length);
169 wl1271_spi_read(wl, WL1271_SLV_MEM_DATA, buf, length, true); 170 wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
170 171
171 /* the data read starts with the descriptor */ 172 /* the data read starts with the descriptor */
172 desc = (struct wl1271_rx_descriptor *) buf; 173 desc = (struct wl1271_rx_descriptor *) buf;
@@ -210,15 +211,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
210 wl->rx_mem_pool_addr.addr + 4; 211 wl->rx_mem_pool_addr.addr + 4;
211 212
212 /* Choose the block we want to read */ 213 /* Choose the block we want to read */
213 wl1271_spi_write(wl, WL1271_SLV_REG_DATA, 214 wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
214 &wl->rx_mem_pool_addr, 215 sizeof(wl->rx_mem_pool_addr), false);
215 sizeof(wl->rx_mem_pool_addr), false);
216 216
217 wl1271_rx_handle_data(wl, buf_size); 217 wl1271_rx_handle_data(wl, buf_size);
218 218
219 wl->rx_counter++; 219 wl->rx_counter++;
220 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 220 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
221 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
221 } 222 }
222
223 wl1271_spi_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
224} 223}
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 02978a16e732..67a82934f36e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -30,28 +30,6 @@
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "wl1271_spi.h" 31#include "wl1271_spi.h"
32 32
33static int wl1271_translate_addr(struct wl1271 *wl, int addr)
34{
35 /*
36 * To translate, first check to which window of addresses the
37 * particular address belongs. Then subtract the starting address
38 * of that window from the address. Then, add offset of the
39 * translated region.
40 *
41 * The translated regions occur next to each other in physical device
42 * memory, so just add the sizes of the preceeding address regions to
43 * get the offset to the new region.
44 *
45 * Currently, only the two first regions are addressed, and the
46 * assumption is that all addresses will fall into either of those
47 * two.
48 */
49 if ((addr >= wl->part.reg.start) &&
50 (addr < wl->part.reg.start + wl->part.reg.size))
51 return addr - wl->part.reg.start + wl->part.mem.size;
52 else
53 return addr - wl->part.mem.start;
54}
55 33
56void wl1271_spi_reset(struct wl1271 *wl) 34void wl1271_spi_reset(struct wl1271 *wl)
57{ 35{
@@ -133,67 +111,6 @@ void wl1271_spi_init(struct wl1271 *wl)
133 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); 111 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
134} 112}
135 113
136/* Set the SPI partitions to access the chip addresses
137 *
138 * To simplify driver code, a fixed (virtual) memory map is defined for
139 * register and memory addresses. Because in the chipset, in different stages
140 * of operation, those addresses will move around, an address translation
141 * mechanism is required.
142 *
143 * There are four partitions (three memory and one register partition),
144 * which are mapped to two different areas of the hardware memory.
145 *
146 * Virtual address
147 * space
148 *
149 * | |
150 * ...+----+--> mem.start
151 * Physical address ... | |
152 * space ... | | [PART_0]
153 * ... | |
154 * 00000000 <--+----+... ...+----+--> mem.start + mem.size
155 * | | ... | |
156 * |MEM | ... | |
157 * | | ... | |
158 * mem.size <--+----+... | | {unused area)
159 * | | ... | |
160 * |REG | ... | |
161 * mem.size | | ... | |
162 * + <--+----+... ...+----+--> reg.start
163 * reg.size | | ... | |
164 * |MEM2| ... | | [PART_1]
165 * | | ... | |
166 * ...+----+--> reg.start + reg.size
167 * | |
168 *
169 */
170int wl1271_set_partition(struct wl1271 *wl,
171 struct wl1271_partition_set *p)
172{
173 /* copy partition info */
174 memcpy(&wl->part, p, sizeof(*p));
175
176 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
177 p->mem.start, p->mem.size);
178 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
179 p->reg.start, p->reg.size);
180 wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
181 p->mem2.start, p->mem2.size);
182 wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
183 p->mem3.start, p->mem3.size);
184
185 /* write partition info to the chipset */
186 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
187 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
188 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
189 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
190 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
191 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
192 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
193
194 return 0;
195}
196
197#define WL1271_BUSY_WORD_TIMEOUT 1000 114#define WL1271_BUSY_WORD_TIMEOUT 1000
198 115
199/* FIXME: Check busy words, removed due to SPI bug */ 116/* FIXME: Check busy words, removed due to SPI bug */
@@ -338,78 +255,3 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
338 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); 255 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
339 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); 256 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
340} 257}
341
342void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
343 bool fixed)
344{
345 int physical;
346
347 physical = wl1271_translate_addr(wl, addr);
348
349 wl1271_spi_raw_read(wl, physical, buf, len, fixed);
350}
351
352void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
353 bool fixed)
354{
355 int physical;
356
357 physical = wl1271_translate_addr(wl, addr);
358
359 wl1271_spi_raw_write(wl, physical, buf, len, fixed);
360}
361
362u32 wl1271_spi_read32(struct wl1271 *wl, int addr)
363{
364 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
365}
366
367void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val)
368{
369 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
370}
371
372void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
373{
374 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
375 addr = (addr >> 1) + 0x30000;
376 wl1271_spi_write32(wl, OCP_POR_CTR, addr);
377
378 /* write value to OCP_POR_WDATA */
379 wl1271_spi_write32(wl, OCP_DATA_WRITE, val);
380
381 /* write 1 to OCP_CMD */
382 wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_WRITE);
383}
384
385u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
386{
387 u32 val;
388 int timeout = OCP_CMD_LOOP;
389
390 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
391 addr = (addr >> 1) + 0x30000;
392 wl1271_spi_write32(wl, OCP_POR_CTR, addr);
393
394 /* write 2 to OCP_CMD */
395 wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_READ);
396
397 /* poll for data ready */
398 do {
399 val = wl1271_spi_read32(wl, OCP_DATA_READ);
400 timeout--;
401 } while (!(val & OCP_READY_MASK) && timeout);
402
403 if (!timeout) {
404 wl1271_warning("Top register access timed out.");
405 return 0xffff;
406 }
407
408 /* check data status and return if OK */
409 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
410 return val & 0xffff;
411 else {
412 wl1271_warning("Top register access returned error.");
413 return 0xffff;
414 }
415}
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
index cb7df1c56314..a803596dad4a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -90,37 +90,7 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
90void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 90void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
91 size_t len, bool fixed); 91 size_t len, bool fixed);
92 92
93/* Translated target IO */
94void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
95 bool fixed);
96void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
97 bool fixed);
98u32 wl1271_spi_read32(struct wl1271 *wl, int addr);
99void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val);
100
101/* Top Register IO */
102void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
103u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
104
105/* INIT and RESET words */ 93/* INIT and RESET words */
106void wl1271_spi_reset(struct wl1271 *wl); 94void wl1271_spi_reset(struct wl1271 *wl);
107void wl1271_spi_init(struct wl1271 *wl); 95void wl1271_spi_init(struct wl1271 *wl);
108int wl1271_set_partition(struct wl1271 *wl,
109 struct wl1271_partition_set *p);
110
111static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
112{
113 wl1271_spi_raw_read(wl, addr, &wl->buffer_32,
114 sizeof(wl->buffer_32), false);
115
116 return wl->buffer_32;
117}
118
119static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
120{
121 wl->buffer_32 = val;
122 wl1271_spi_raw_write(wl, addr, &wl->buffer_32,
123 sizeof(wl->buffer_32), false);
124}
125
126#endif /* __WL1271_SPI_H__ */ 96#endif /* __WL1271_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
new file mode 100644
index 000000000000..3919102e942e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -0,0 +1,283 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23#include "wl1271_testmode.h"
24
25#include <net/genetlink.h>
26
27#include "wl1271.h"
28#include "wl1271_spi.h"
29#include "wl1271_acx.h"
30
31#define WL1271_TM_MAX_DATA_LENGTH 1024
32
33enum wl1271_tm_commands {
34 WL1271_TM_CMD_UNSPEC,
35 WL1271_TM_CMD_TEST,
36 WL1271_TM_CMD_INTERROGATE,
37 WL1271_TM_CMD_CONFIGURE,
38 WL1271_TM_CMD_NVS_PUSH,
39 WL1271_TM_CMD_SET_PLT_MODE,
40
41 __WL1271_TM_CMD_AFTER_LAST
42};
43#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1)
44
45enum wl1271_tm_attrs {
46 WL1271_TM_ATTR_UNSPEC,
47 WL1271_TM_ATTR_CMD_ID,
48 WL1271_TM_ATTR_ANSWER,
49 WL1271_TM_ATTR_DATA,
50 WL1271_TM_ATTR_IE_ID,
51 WL1271_TM_ATTR_PLT_MODE,
52
53 __WL1271_TM_ATTR_AFTER_LAST
54};
55#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)
56
57static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = {
58 [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 },
59 [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 },
60 [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY,
61 .len = WL1271_TM_MAX_DATA_LENGTH },
62 [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 },
63 [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 },
64};
65
66
67static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
68{
69 int buf_len, ret, len;
70 struct sk_buff *skb;
71 void *buf;
72 u8 answer = 0;
73
74 wl1271_debug(DEBUG_TESTMODE, "testmode cmd test");
75
76 if (!tb[WL1271_TM_ATTR_DATA])
77 return -EINVAL;
78
79 buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
80 buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
81
82 if (tb[WL1271_TM_ATTR_ANSWER])
83 answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]);
84
85 if (buf_len > sizeof(struct wl1271_command))
86 return -EMSGSIZE;
87
88 mutex_lock(&wl->mutex);
89 ret = wl1271_cmd_test(wl, buf, buf_len, answer);
90 mutex_unlock(&wl->mutex);
91
92 if (ret < 0) {
93 wl1271_warning("testmode cmd test failed: %d", ret);
94 return ret;
95 }
96
97 if (answer) {
98 len = nla_total_size(buf_len);
99 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);
100 if (!skb)
101 return -ENOMEM;
102
103 NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
104 ret = cfg80211_testmode_reply(skb);
105 if (ret < 0)
106 return ret;
107 }
108
109 return 0;
110
111nla_put_failure:
112 kfree_skb(skb);
113 return -EMSGSIZE;
114}
115
116static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
117{
118 int ret;
119 struct wl1271_command *cmd;
120 struct sk_buff *skb;
121 u8 ie_id;
122
123 wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate");
124
125 if (!tb[WL1271_TM_ATTR_IE_ID])
126 return -EINVAL;
127
128 ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
129
130 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
131 if (!cmd)
132 return -ENOMEM;
133
134 mutex_lock(&wl->mutex);
135 ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd));
136 mutex_unlock(&wl->mutex);
137
138 if (ret < 0) {
139 wl1271_warning("testmode cmd interrogate failed: %d", ret);
140 return ret;
141 }
142
143 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));
144 if (!skb)
145 return -ENOMEM;
146
147 NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
148
149 return 0;
150
151nla_put_failure:
152 kfree_skb(skb);
153 return -EMSGSIZE;
154}
155
156static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])
157{
158 int buf_len, ret;
159 void *buf;
160 u8 ie_id;
161
162 wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure");
163
164 if (!tb[WL1271_TM_ATTR_DATA])
165 return -EINVAL;
166 if (!tb[WL1271_TM_ATTR_IE_ID])
167 return -EINVAL;
168
169 ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
170 buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
171 buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
172
173 if (buf_len > sizeof(struct wl1271_command))
174 return -EMSGSIZE;
175
176 mutex_lock(&wl->mutex);
177 ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len);
178 mutex_unlock(&wl->mutex);
179
180 if (ret < 0) {
181 wl1271_warning("testmode cmd configure failed: %d", ret);
182 return ret;
183 }
184
185 return 0;
186}
187
188static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
189{
190 int ret = 0;
191 size_t len;
192 void *buf;
193
194 wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");
195
196 if (!tb[WL1271_TM_ATTR_DATA])
197 return -EINVAL;
198
199 buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
200 len = nla_len(tb[WL1271_TM_ATTR_DATA]);
201
202 if (len != sizeof(struct wl1271_nvs_file)) {
203 wl1271_error("nvs size is not as expected: %zu != %zu",
204 len, sizeof(struct wl1271_nvs_file));
205 return -EMSGSIZE;
206 }
207
208 mutex_lock(&wl->mutex);
209
210 kfree(wl->nvs);
211
212 wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
213 if (!wl->nvs) {
214 wl1271_error("could not allocate memory for the nvs file");
215 ret = -ENOMEM;
216 goto out;
217 }
218
219 memcpy(wl->nvs, buf, len);
220
221 wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
222
223out:
224 mutex_unlock(&wl->mutex);
225
226 return ret;
227}
228
229static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
230{
231 u32 val;
232 int ret;
233
234 wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode");
235
236 if (!tb[WL1271_TM_ATTR_PLT_MODE])
237 return -EINVAL;
238
239 val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]);
240
241 switch (val) {
242 case 0:
243 ret = wl1271_plt_stop(wl);
244 break;
245 case 1:
246 ret = wl1271_plt_start(wl);
247 break;
248 default:
249 ret = -EINVAL;
250 break;
251 }
252
253 return ret;
254}
255
256int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
257{
258 struct wl1271 *wl = hw->priv;
259 struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
260 int err;
261
262 err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
263 if (err)
264 return err;
265
266 if (!tb[WL1271_TM_ATTR_CMD_ID])
267 return -EINVAL;
268
269 switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {
270 case WL1271_TM_CMD_TEST:
271 return wl1271_tm_cmd_test(wl, tb);
272 case WL1271_TM_CMD_INTERROGATE:
273 return wl1271_tm_cmd_interrogate(wl, tb);
274 case WL1271_TM_CMD_CONFIGURE:
275 return wl1271_tm_cmd_configure(wl, tb);
276 case WL1271_TM_CMD_NVS_PUSH:
277 return wl1271_tm_cmd_nvs_push(wl, tb);
278 case WL1271_TM_CMD_SET_PLT_MODE:
279 return wl1271_tm_cmd_set_plt_mode(wl, tb);
280 default:
281 return -EOPNOTSUPP;
282 }
283}
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.h b/drivers/net/wireless/wl12xx/wl1271_testmode.h
new file mode 100644
index 000000000000..c196d28f9d9d
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.h
@@ -0,0 +1,31 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __WL1271_TESTMODE_H__
25#define __WL1271_TESTMODE_H__
26
27#include <net/mac80211.h>
28
29int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len);
30
31#endif /* __WL1271_TESTMODE_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 00af065c77c2..811e739d05bf 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -26,6 +26,7 @@
26 26
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_spi.h" 28#include "wl1271_spi.h"
29#include "wl1271_io.h"
29#include "wl1271_reg.h" 30#include "wl1271_reg.h"
30#include "wl1271_ps.h" 31#include "wl1271_ps.h"
31#include "wl1271_tx.h" 32#include "wl1271_tx.h"
@@ -87,7 +88,7 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
87 u32 extra, struct ieee80211_tx_info *control) 88 u32 extra, struct ieee80211_tx_info *control)
88{ 89{
89 struct wl1271_tx_hw_descr *desc; 90 struct wl1271_tx_hw_descr *desc;
90 int pad; 91 int pad, ac;
91 u16 tx_attr; 92 u16 tx_attr;
92 93
93 desc = (struct wl1271_tx_hw_descr *) skb->data; 94 desc = (struct wl1271_tx_hw_descr *) skb->data;
@@ -107,9 +108,11 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
107 108
108 /* configure the tx attributes */ 109 /* configure the tx attributes */
109 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; 110 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
110 /* FIXME: do we know the packet priority? can we identify mgmt 111
111 packets, and use max prio for them at least? */ 112 /* queue */
112 desc->tid = 0; 113 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
114 desc->tid = wl1271_tx_ac_to_tid(ac);
115
113 desc->aid = TX_HW_DEFAULT_AID; 116 desc->aid = TX_HW_DEFAULT_AID;
114 desc->reserved = 0; 117 desc->reserved = 0;
115 118
@@ -121,6 +124,11 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
121 pad = pad - skb->len; 124 pad = pad - skb->len;
122 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; 125 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
123 126
127 /* if the packets are destined for AP (have a STA entry) send them
128 with AP rate policies, otherwise use default basic rates */
129 if (control->control.sta)
130 tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY;
131
124 desc->tx_attr = cpu_to_le16(tx_attr); 132 desc->tx_attr = cpu_to_le16(tx_attr);
125 133
126 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); 134 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
@@ -158,11 +166,11 @@ static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
158 len = WL1271_TX_ALIGN(skb->len); 166 len = WL1271_TX_ALIGN(skb->len);
159 167
160 /* perform a fixed address block write with the packet */ 168 /* perform a fixed address block write with the packet */
161 wl1271_spi_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true); 169 wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
162 170
163 /* write packet new counter into the write access register */ 171 /* write packet new counter into the write access register */
164 wl->tx_packets_count++; 172 wl->tx_packets_count++;
165 wl1271_spi_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); 173 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
166 174
167 desc = (struct wl1271_tx_hw_descr *) skb->data; 175 desc = (struct wl1271_tx_hw_descr *) skb->data;
168 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", 176 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
@@ -196,6 +204,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
196 ret = wl1271_cmd_set_default_wep_key(wl, idx); 204 ret = wl1271_cmd_set_default_wep_key(wl, idx);
197 if (ret < 0) 205 if (ret < 0)
198 return ret; 206 return ret;
207 wl->default_key = idx;
199 } 208 }
200 } 209 }
201 210
@@ -214,18 +223,50 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
214 return ret; 223 return ret;
215} 224}
216 225
226static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
227{
228 struct ieee80211_supported_band *band;
229 u32 enabled_rates = 0;
230 int bit;
231
232 band = wl->hw->wiphy->bands[wl->band];
233 for (bit = 0; bit < band->n_bitrates; bit++) {
234 if (rate_set & 0x1)
235 enabled_rates |= band->bitrates[bit].hw_value;
236 rate_set >>= 1;
237 }
238
239 return enabled_rates;
240}
241
217void wl1271_tx_work(struct work_struct *work) 242void wl1271_tx_work(struct work_struct *work)
218{ 243{
219 struct wl1271 *wl = container_of(work, struct wl1271, tx_work); 244 struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
220 struct sk_buff *skb; 245 struct sk_buff *skb;
221 bool woken_up = false; 246 bool woken_up = false;
247 u32 sta_rates = 0;
222 int ret; 248 int ret;
223 249
250 /* check if the rates supported by the AP have changed */
251 if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
252 &wl->flags))) {
253 unsigned long flags;
254 spin_lock_irqsave(&wl->wl_lock, flags);
255 sta_rates = wl->sta_rate_set;
256 spin_unlock_irqrestore(&wl->wl_lock, flags);
257 }
258
224 mutex_lock(&wl->mutex); 259 mutex_lock(&wl->mutex);
225 260
226 if (unlikely(wl->state == WL1271_STATE_OFF)) 261 if (unlikely(wl->state == WL1271_STATE_OFF))
227 goto out; 262 goto out;
228 263
264 /* if rates have changed, re-configure the rate policy */
265 if (unlikely(sta_rates)) {
266 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
267 wl1271_acx_rate_policies(wl);
268 }
269
229 while ((skb = skb_dequeue(&wl->tx_queue))) { 270 while ((skb = skb_dequeue(&wl->tx_queue))) {
230 if (!woken_up) { 271 if (!woken_up) {
231 ret = wl1271_ps_elp_wakeup(wl, false); 272 ret = wl1271_ps_elp_wakeup(wl, false);
@@ -240,18 +281,18 @@ void wl1271_tx_work(struct work_struct *work)
240 wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, " 281 wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
241 "stop queues"); 282 "stop queues");
242 ieee80211_stop_queues(wl->hw); 283 ieee80211_stop_queues(wl->hw);
243 wl->tx_queue_stopped = true; 284 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
244 skb_queue_head(&wl->tx_queue, skb); 285 skb_queue_head(&wl->tx_queue, skb);
245 goto out; 286 goto out;
246 } else if (ret < 0) { 287 } else if (ret < 0) {
247 dev_kfree_skb(skb); 288 dev_kfree_skb(skb);
248 goto out; 289 goto out;
249 } else if (wl->tx_queue_stopped) { 290 } else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED,
291 &wl->flags)) {
250 /* firmware buffer has space, restart queues */ 292 /* firmware buffer has space, restart queues */
251 wl1271_debug(DEBUG_TX, 293 wl1271_debug(DEBUG_TX,
252 "complete_packet: waking queues"); 294 "complete_packet: waking queues");
253 ieee80211_wake_queues(wl->hw); 295 ieee80211_wake_queues(wl->hw);
254 wl->tx_queue_stopped = false;
255 } 296 }
256 } 297 }
257 298
@@ -335,8 +376,8 @@ void wl1271_tx_complete(struct wl1271 *wl, u32 count)
335 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); 376 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
336 377
337 /* read the tx results from the chipset */ 378 /* read the tx results from the chipset */
338 wl1271_spi_read(wl, le32_to_cpu(memmap->tx_result), 379 wl1271_read(wl, le32_to_cpu(memmap->tx_result),
339 wl->tx_res_if, sizeof(*wl->tx_res_if), false); 380 wl->tx_res_if, sizeof(*wl->tx_res_if), false);
340 381
341 /* verify that the result buffer is not getting overrun */ 382 /* verify that the result buffer is not getting overrun */
342 if (count > TX_HW_RESULT_QUEUE_LEN) { 383 if (count > TX_HW_RESULT_QUEUE_LEN) {
@@ -357,10 +398,10 @@ void wl1271_tx_complete(struct wl1271 *wl, u32 count)
357 } 398 }
358 399
359 /* write host counter to chipset (to ack) */ 400 /* write host counter to chipset (to ack) */
360 wl1271_spi_write32(wl, le32_to_cpu(memmap->tx_result) + 401 wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
361 offsetof(struct wl1271_tx_hw_res_if, 402 offsetof(struct wl1271_tx_hw_res_if,
362 tx_result_host_counter), 403 tx_result_host_counter),
363 le32_to_cpu(wl->tx_res_if->tx_result_fw_counter)); 404 le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));
364} 405}
365 406
366/* caller must hold wl->mutex */ 407/* caller must hold wl->mutex */
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 416396caf0a0..17e405a09caa 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -123,6 +123,42 @@ struct wl1271_tx_hw_res_if {
123 struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; 123 struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
124} __attribute__ ((packed)); 124} __attribute__ ((packed));
125 125
126static inline int wl1271_tx_get_queue(int queue)
127{
128 /* FIXME: use best effort until WMM is enabled */
129 return CONF_TX_AC_BE;
130
131 switch (queue) {
132 case 0:
133 return CONF_TX_AC_VO;
134 case 1:
135 return CONF_TX_AC_VI;
136 case 2:
137 return CONF_TX_AC_BE;
138 case 3:
139 return CONF_TX_AC_BK;
140 default:
141 return CONF_TX_AC_BE;
142 }
143}
144
145/* wl1271 tx descriptor needs the tid and we need to convert it from ac */
146static inline int wl1271_tx_ac_to_tid(int ac)
147{
148 switch (ac) {
149 case 0:
150 return 0;
151 case 1:
152 return 2;
153 case 2:
154 return 4;
155 case 3:
156 return 6;
157 default:
158 return 0;
159 }
160}
161
126void wl1271_tx_work(struct work_struct *work); 162void wl1271_tx_work(struct work_struct *work);
127void wl1271_tx_complete(struct wl1271 *wl, u32 count); 163void wl1271_tx_complete(struct wl1271 *wl, u32 count);
128void wl1271_tx_flush(struct wl1271 *wl); 164void wl1271_tx_flush(struct wl1271 *wl);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 9d9b263733e6..d90f0a25b9cf 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -869,7 +869,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
869} 869}
870 870
871static int zd_op_add_interface(struct ieee80211_hw *hw, 871static int zd_op_add_interface(struct ieee80211_hw *hw,
872 struct ieee80211_if_init_conf *conf) 872 struct ieee80211_vif *vif)
873{ 873{
874 struct zd_mac *mac = zd_hw_mac(hw); 874 struct zd_mac *mac = zd_hw_mac(hw);
875 875
@@ -877,22 +877,22 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
877 if (mac->type != NL80211_IFTYPE_UNSPECIFIED) 877 if (mac->type != NL80211_IFTYPE_UNSPECIFIED)
878 return -EOPNOTSUPP; 878 return -EOPNOTSUPP;
879 879
880 switch (conf->type) { 880 switch (vif->type) {
881 case NL80211_IFTYPE_MONITOR: 881 case NL80211_IFTYPE_MONITOR:
882 case NL80211_IFTYPE_MESH_POINT: 882 case NL80211_IFTYPE_MESH_POINT:
883 case NL80211_IFTYPE_STATION: 883 case NL80211_IFTYPE_STATION:
884 case NL80211_IFTYPE_ADHOC: 884 case NL80211_IFTYPE_ADHOC:
885 mac->type = conf->type; 885 mac->type = vif->type;
886 break; 886 break;
887 default: 887 default:
888 return -EOPNOTSUPP; 888 return -EOPNOTSUPP;
889 } 889 }
890 890
891 return zd_write_mac_addr(&mac->chip, conf->mac_addr); 891 return zd_write_mac_addr(&mac->chip, vif->addr);
892} 892}
893 893
894static void zd_op_remove_interface(struct ieee80211_hw *hw, 894static void zd_op_remove_interface(struct ieee80211_hw *hw,
895 struct ieee80211_if_init_conf *conf) 895 struct ieee80211_vif *vif)
896{ 896{
897 struct zd_mac *mac = zd_hw_mac(hw); 897 struct zd_mac *mac = zd_hw_mac(hw);
898 mac->type = NL80211_IFTYPE_UNSPECIFIED; 898 mac->type = NL80211_IFTYPE_UNSPECIFIED;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 72d3e437e190..442fc1117326 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1079,11 +1079,15 @@ static int eject_installer(struct usb_interface *intf)
1079 int r; 1079 int r;
1080 1080
1081 /* Find bulk out endpoint */ 1081 /* Find bulk out endpoint */
1082 endpoint = &iface_desc->endpoint[1].desc; 1082 for (r = 1; r >= 0; r--) {
1083 if (usb_endpoint_dir_out(endpoint) && 1083 endpoint = &iface_desc->endpoint[r].desc;
1084 usb_endpoint_xfer_bulk(endpoint)) { 1084 if (usb_endpoint_dir_out(endpoint) &&
1085 bulk_out_ep = endpoint->bEndpointAddress; 1085 usb_endpoint_xfer_bulk(endpoint)) {
1086 } else { 1086 bulk_out_ep = endpoint->bEndpointAddress;
1087 break;
1088 }
1089 }
1090 if (r == -1) {
1087 dev_err(&udev->dev, 1091 dev_err(&udev->dev,
1088 "zd1211rw: Could not find bulk out endpoint\n"); 1092 "zd1211rw: Could not find bulk out endpoint\n");
1089 return -ENODEV; 1093 return -ENODEV;