aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
commit10be7eb36b93364b98688831ee7d26f58402bb96 (patch)
treeeb13ae80fcaa8baacd804a721c5a4962a501a2a4 /drivers/net
parent90c30335a70e96b8b8493b7deb15e6b30e6d9fce (diff)
parent5ffaf8a361b4c9025963959a744f21d8173c7669 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
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/airo.c34
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c22
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c39
-rw-r--r--drivers/net/wireless/ath/debug.h8
-rw-r--r--drivers/net/wireless/b43/main.c28
-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.c52
-rw-r--r--drivers/net/wireless/b43/phy_n.c1264
-rw-r--r--drivers/net/wireless/b43/phy_n.h7
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c167
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h27
-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.c78
-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.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c28
-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.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c149
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1267
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h46
-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.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-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.c104
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c192
-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.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c57
-rw-r--r--drivers/net/wireless/libertas/assoc.c78
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwl8k.c14
-rw-r--r--drivers/net/wireless/p54/p54pci.c74
-rw-r--r--drivers/net/wireless/p54/p54pci.h6
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c9
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c25
90 files changed, 3209 insertions, 1787 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 411e20703110..ef662e15c3d3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2368,20 +2368,6 @@ config GELIC_WIRELESS
2368 the driver automatically distinguishes the models, you can 2368 the driver automatically distinguishes the models, you can
2369 safely enable this option even if you have a wireless-less model. 2369 safely enable this option even if you have a wireless-less model.
2370 2370
2371config GELIC_WIRELESS_OLD_PSK_INTERFACE
2372 bool "PS3 Wireless private PSK interface (OBSOLETE)"
2373 depends on GELIC_WIRELESS
2374 select WEXT_PRIV
2375 help
2376 This option retains the obsolete private interface to pass
2377 the PSK from user space programs to the driver. The PSK
2378 stands for 'Pre Shared Key' and is used for WPA[2]-PSK
2379 (WPA-Personal) environment.
2380 If WPA[2]-PSK is used and you need to use old programs that
2381 support only this old interface, say Y. Otherwise N.
2382
2383 If unsure, say N.
2384
2385config FSL_PQ_MDIO 2371config FSL_PQ_MDIO
2386 tristate "Freescale PQ MDIO" 2372 tristate "Freescale PQ MDIO"
2387 depends on FSL_SOC 2373 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/airo.c b/drivers/net/wireless/airo.c
index 37e4ab737f2a..ef6b78da370f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5254 WepKeyRid wkr; 5254 WepKeyRid wkr;
5255 int rc; 5255 int rc;
5256 5256
5257 if (keylen == 0) { 5257 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 5258
5263 memset(&wkr, 0, sizeof(wkr)); 5259 memset(&wkr, 0, sizeof(wkr));
5264 wkr.len = cpu_to_le16(sizeof(wkr)); 5260 wkr.len = cpu_to_le16(sizeof(wkr));
@@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev,
6405 if (dwrq->length > MIN_KEY_SIZE) 6401 if (dwrq->length > MIN_KEY_SIZE)
6406 key.len = MAX_KEY_SIZE; 6402 key.len = MAX_KEY_SIZE;
6407 else 6403 else
6408 if (dwrq->length > 0) 6404 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 */ 6405 /* Check if the key is not marked as invalid */
6414 if(!(dwrq->flags & IW_ENCODE_NOKEY)) { 6406 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6415 /* Cleanup */ 6407 /* Cleanup */
@@ -6590,12 +6582,22 @@ static int airo_set_encodeext(struct net_device *dev,
6590 default: 6582 default:
6591 return -EINVAL; 6583 return -EINVAL;
6592 } 6584 }
6593 /* Send the key to the card */ 6585 if (key.len == 0) {
6594 rc = set_wep_key(local, idx, key.key, key.len, perm, 1); 6586 rc = set_wep_tx_idx(local, idx, perm, 1);
6595 if (rc < 0) { 6587 if (rc < 0) {
6596 airo_print_err(local->dev->name, "failed to set WEP key" 6588 airo_print_err(local->dev->name,
6597 " at index %d: %d.", idx, rc); 6589 "failed to set WEP transmit index to %d: %d.",
6598 return rc; 6590 idx, rc);
6591 return rc;
6592 }
6593 } else {
6594 rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6595 if (rc < 0) {
6596 airo_print_err(local->dev->name,
6597 "failed to set WEP key at index %d: %d.",
6598 idx, rc);
6599 return rc;
6600 }
6599 } 6601 }
6600 } 6602 }
6601 6603
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 66bcb506a112..ad4d446f0264 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -535,7 +535,7 @@ 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/*
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 5577bcc80eac..edb6c90e376f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1516,7 +1516,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1516 1516
1517 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); 1517 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
1518 if (ret) 1518 if (ret)
1519 return ret; 1519 goto err;
1520
1520 if (sc->opmode == NL80211_IFTYPE_AP || 1521 if (sc->opmode == NL80211_IFTYPE_AP ||
1521 sc->opmode == NL80211_IFTYPE_MESH_POINT) { 1522 sc->opmode == NL80211_IFTYPE_MESH_POINT) {
1522 /* 1523 /*
@@ -1543,10 +1544,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1543 if (ret) { 1544 if (ret) {
1544 ATH5K_ERR(sc, "%s: unable to update parameters for beacon " 1545 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1545 "hardware queue!\n", __func__); 1546 "hardware queue!\n", __func__);
1546 return ret; 1547 goto err;
1547 } 1548 }
1549 ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
1550 if (ret)
1551 goto err;
1548 1552
1549 return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; 1553 /* reconfigure cabq with ready time to 80% of beacon_interval */
1554 ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1555 if (ret)
1556 goto err;
1557
1558 qi.tqi_ready_time = (sc->bintval * 80) / 100;
1559 ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1560 if (ret)
1561 goto err;
1562
1563 ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
1564err:
1565 return ret;
1550} 1566}
1551 1567
1552static void 1568static void
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/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index abe36c0d139c..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) |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 6690923fd78c..a35a7db0fc4c 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1374,8 +1374,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1374 * Set clocks to 32KHz operation and use an 1374 * Set clocks to 32KHz operation and use an
1375 * external 32KHz crystal when sleeping if one 1375 * external 32KHz crystal when sleeping if one
1376 * exists */ 1376 * exists */
1377 if (ah->ah_version == AR5K_AR5212) 1377 if (ah->ah_version == AR5K_AR5212 &&
1378 ath5k_hw_set_sleep_clock(ah, true); 1378 ah->ah_op_mode != NL80211_IFTYPE_AP)
1379 ath5k_hw_set_sleep_clock(ah, true);
1379 1380
1380 /* 1381 /*
1381 * Disable beacons and reset the register 1382 * Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9e62a569e816..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
@@ -164,12 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
164 if (hw) { 156 if (hw) {
165 struct ath_wiphy *aphy = hw->priv; 157 struct ath_wiphy *aphy = hw->priv;
166 struct ath_softc *sc = aphy->sc; 158 struct ath_softc *sc = aphy->sc;
167 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 159 void __iomem *mem = sc->mem;
168 160
169 ath9k_deinit_device(sc); 161 ath9k_deinit_device(sc);
170 free_irq(sc->irq, sc); 162 free_irq(sc->irq, sc);
171 ieee80211_free_hw(sc->hw); 163 ieee80211_free_hw(sc->hw);
172 ath_bus_cleanup(common); 164 iounmap(mem);
173 platform_set_drvdata(pdev, NULL); 165 platform_set_drvdata(pdev, NULL);
174 } 166 }
175 167
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index bf3d4c4bfa52..0ea340fd071c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -364,6 +364,7 @@ struct ath_btcoex {
364 int bt_stomp_type; /* Types of BT stomping */ 364 int bt_stomp_type; /* Types of BT stomping */
365 u32 btcoex_no_stomp; /* in usec */ 365 u32 btcoex_no_stomp; /* in usec */
366 u32 btcoex_period; /* in usec */ 366 u32 btcoex_period; /* in usec */
367 u32 btscan_no_stomp; /* in usec */
367 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 368 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
368}; 369};
369 370
@@ -429,6 +430,7 @@ void ath_deinit_leds(struct ath_softc *sc);
429#define SC_OP_SCANNING BIT(10) 430#define SC_OP_SCANNING BIT(10)
430#define SC_OP_TSF_RESET BIT(11) 431#define SC_OP_TSF_RESET BIT(11)
431#define SC_OP_BT_PRIORITY_DETECTED BIT(12) 432#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
433#define SC_OP_BT_SCAN BIT(13)
432 434
433/* Powersave flags */ 435/* Powersave flags */
434#define PS_WAIT_FOR_BEACON BIT(0) 436#define PS_WAIT_FOR_BEACON BIT(0)
@@ -478,6 +480,7 @@ struct ath_softc {
478 u8 nbcnvifs; 480 u8 nbcnvifs;
479 u16 nvifs; 481 u16 nvifs;
480 bool ps_enabled; 482 bool ps_enabled;
483 bool ps_idle;
481 unsigned long ps_usecount; 484 unsigned long ps_usecount;
482 enum ath9k_int imask; 485 enum ath9k_int imask;
483 486
@@ -535,11 +538,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
535 common->bus_ops->read_cachesize(common, csz); 538 common->bus_ops->read_cachesize(common, csz);
536} 539}
537 540
538static inline void ath_bus_cleanup(struct ath_common *common)
539{
540 common->bus_ops->cleanup(common);
541}
542
543extern struct ieee80211_ops ath9k_ops; 541extern struct ieee80211_ops ath9k_ops;
544extern int modparam_nohwcrypt; 542extern int modparam_nohwcrypt;
545 543
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 9489b6b25b5f..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 = {
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index e204bd25ff65..deab8beb0680 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -230,12 +230,17 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
230 230
231 if (time_after(jiffies, btcoex->bt_priority_time + 231 if (time_after(jiffies, btcoex->bt_priority_time +
232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { 232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
233 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_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) {
234 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, 241 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
235 "BT priority traffic detected"); 242 "BT priority traffic detected");
236 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; 243 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
237 } else {
238 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
239 } 244 }
240 245
241 btcoex->bt_priority_cnt = 0; 246 btcoex->bt_priority_cnt = 0;
@@ -316,12 +321,17 @@ static void ath_btcoex_period_timer(unsigned long data)
316 struct ath_softc *sc = (struct ath_softc *) data; 321 struct ath_softc *sc = (struct ath_softc *) data;
317 struct ath_hw *ah = sc->sc_ah; 322 struct ath_hw *ah = sc->sc_ah;
318 struct ath_btcoex *btcoex = &sc->btcoex; 323 struct ath_btcoex *btcoex = &sc->btcoex;
324 u32 timer_period;
325 bool is_btscan;
319 326
320 ath_detect_bt_priority(sc); 327 ath_detect_bt_priority(sc);
321 328
329 is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
330
322 spin_lock_bh(&btcoex->btcoex_lock); 331 spin_lock_bh(&btcoex->btcoex_lock);
323 332
324 ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); 333 ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
334 btcoex->bt_stomp_type);
325 335
326 spin_unlock_bh(&btcoex->btcoex_lock); 336 spin_unlock_bh(&btcoex->btcoex_lock);
327 337
@@ -329,11 +339,12 @@ static void ath_btcoex_period_timer(unsigned long data)
329 if (btcoex->hw_timer_enabled) 339 if (btcoex->hw_timer_enabled)
330 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); 340 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
331 341
342 timer_period = is_btscan ? btcoex->btscan_no_stomp :
343 btcoex->btcoex_no_stomp;
332 ath9k_gen_timer_start(ah, 344 ath9k_gen_timer_start(ah,
333 btcoex->no_stomp_timer, 345 btcoex->no_stomp_timer,
334 (ath9k_hw_gettsf32(ah) + 346 (ath9k_hw_gettsf32(ah) +
335 btcoex->btcoex_no_stomp), 347 timer_period), timer_period * 10);
336 btcoex->btcoex_no_stomp * 10);
337 btcoex->hw_timer_enabled = true; 348 btcoex->hw_timer_enabled = true;
338 } 349 }
339 350
@@ -350,13 +361,14 @@ static void ath_btcoex_no_stomp_timer(void *arg)
350 struct ath_softc *sc = (struct ath_softc *)arg; 361 struct ath_softc *sc = (struct ath_softc *)arg;
351 struct ath_hw *ah = sc->sc_ah; 362 struct ath_hw *ah = sc->sc_ah;
352 struct ath_btcoex *btcoex = &sc->btcoex; 363 struct ath_btcoex *btcoex = &sc->btcoex;
364 bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
353 365
354 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, 366 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
355 "no stomp timer running \n"); 367 "no stomp timer running \n");
356 368
357 spin_lock_bh(&btcoex->btcoex_lock); 369 spin_lock_bh(&btcoex->btcoex_lock);
358 370
359 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) 371 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
360 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); 372 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
361 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) 373 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
362 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); 374 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
@@ -371,6 +383,8 @@ int ath_init_btcoex_timer(struct ath_softc *sc)
371 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; 383 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
372 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 384 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
373 btcoex->btcoex_period / 100; 385 btcoex->btcoex_period / 100;
386 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
387 btcoex->btcoex_period / 100;
374 388
375 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 389 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
376 (unsigned long) sc); 390 (unsigned long) sc);
@@ -405,7 +419,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
405 419
406 btcoex->bt_priority_cnt = 0; 420 btcoex->bt_priority_cnt = 0;
407 btcoex->bt_priority_time = jiffies; 421 btcoex->bt_priority_time = jiffies;
408 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; 422 sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
409 423
410 mod_timer(&btcoex->period_timer, jiffies); 424 mod_timer(&btcoex->period_timer, jiffies);
411} 425}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1a27f39c1adc..f15fee76a4e2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -334,7 +334,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
334 ah->config.pcie_clock_req = 0; 334 ah->config.pcie_clock_req = 0;
335 ah->config.pcie_waen = 0; 335 ah->config.pcie_waen = 0;
336 ah->config.analog_shiftreg = 1; 336 ah->config.analog_shiftreg = 1;
337 ah->config.ht_enable = 1;
338 ah->config.ofdm_trig_low = 200; 337 ah->config.ofdm_trig_low = 200;
339 ah->config.ofdm_trig_high = 500; 338 ah->config.ofdm_trig_high = 500;
340 ah->config.cck_trig_high = 200; 339 ah->config.cck_trig_high = 200;
@@ -346,6 +345,11 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
346 ah->config.spurchans[i][1] = AR_NO_SPUR; 345 ah->config.spurchans[i][1] = AR_NO_SPUR;
347 } 346 }
348 347
348 if (ah->hw_version.devid != AR2427_DEVID_PCIE)
349 ah->config.ht_enable = 1;
350 else
351 ah->config.ht_enable = 0;
352
349 ah->config.rx_intr_mitigation = true; 353 ah->config.rx_intr_mitigation = true;
350 354
351 /* 355 /*
@@ -542,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid)
542 case AR5416_DEVID_AR9287_PCI: 546 case AR5416_DEVID_AR9287_PCI:
543 case AR5416_DEVID_AR9287_PCIE: 547 case AR5416_DEVID_AR9287_PCIE:
544 case AR9271_USB: 548 case AR9271_USB:
549 case AR2427_DEVID_PCIE:
545 return true; 550 return true;
546 default: 551 default:
547 break; 552 break;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ab1f1981d857..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
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 5f78d7a5ff22..4b5e54848683 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -620,11 +620,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
622 IEEE80211_HW_SIGNAL_DBM | 622 IEEE80211_HW_SIGNAL_DBM |
623 IEEE80211_HW_AMPDU_AGGREGATION |
624 IEEE80211_HW_SUPPORTS_PS | 623 IEEE80211_HW_SUPPORTS_PS |
625 IEEE80211_HW_PS_NULLFUNC_STACK | 624 IEEE80211_HW_PS_NULLFUNC_STACK |
626 IEEE80211_HW_SPECTRUM_MGMT; 625 IEEE80211_HW_SPECTRUM_MGMT;
627 626
627 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
628 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
629
628 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) 630 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
629 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 631 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
630 632
@@ -640,8 +642,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
640 hw->max_rates = 4; 642 hw->max_rates = 4;
641 hw->channel_change_time = 5000; 643 hw->channel_change_time = 5000;
642 hw->max_listen_interval = 10; 644 hw->max_listen_interval = 10;
643 /* Hardware supports 10 but we use 4 */ 645 hw->max_rate_tries = 10;
644 hw->max_rate_tries = 4;
645 hw->sta_data_size = sizeof(struct ath_node); 646 hw->sta_data_size = sizeof(struct ath_node);
646 hw->vif_data_size = sizeof(struct ath_vif); 647 hw->vif_data_size = sizeof(struct ath_vif);
647 648
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6aaca0026da8..6796d5cdc293 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -143,8 +143,10 @@ void ath9k_ps_restore(struct ath_softc *sc)
143 if (--sc->ps_usecount != 0) 143 if (--sc->ps_usecount != 0)
144 goto unlock; 144 goto unlock;
145 145
146 if (sc->ps_enabled && 146 if (sc->ps_idle)
147 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 147 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
148 else if (sc->ps_enabled &&
149 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
148 PS_WAIT_FOR_CAB | 150 PS_WAIT_FOR_CAB |
149 PS_WAIT_FOR_PSPOLL_DATA | 151 PS_WAIT_FOR_PSPOLL_DATA |
150 PS_WAIT_FOR_TX_ACK))) 152 PS_WAIT_FOR_TX_ACK)))
@@ -204,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
204 r = ath9k_hw_reset(ah, hchan, fastcc); 206 r = ath9k_hw_reset(ah, hchan, fastcc);
205 if (r) { 207 if (r) {
206 ath_print(common, ATH_DBG_FATAL, 208 ath_print(common, ATH_DBG_FATAL,
207 "Unable to reset channel (%u Mhz) " 209 "Unable to reset channel (%u MHz), "
208 "reset status %d\n", 210 "reset status %d\n",
209 channel->center_freq, r); 211 channel->center_freq, r);
210 spin_unlock_bh(&sc->sc_resetlock); 212 spin_unlock_bh(&sc->sc_resetlock);
@@ -867,7 +869,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
867 r = ath9k_hw_reset(ah, ah->curchan, false); 869 r = ath9k_hw_reset(ah, ah->curchan, false);
868 if (r) { 870 if (r) {
869 ath_print(common, ATH_DBG_FATAL, 871 ath_print(common, ATH_DBG_FATAL,
870 "Unable to reset channel %u (%uMhz) ", 872 "Unable to reset channel (%u MHz), "
871 "reset status %d\n", 873 "reset status %d\n",
872 channel->center_freq, r); 874 channel->center_freq, r);
873 } 875 }
@@ -922,7 +924,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
922 r = ath9k_hw_reset(ah, ah->curchan, false); 924 r = ath9k_hw_reset(ah, ah->curchan, false);
923 if (r) { 925 if (r) {
924 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 926 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
925 "Unable to reset channel %u (%uMhz) " 927 "Unable to reset channel (%u MHz), "
926 "reset status %d\n", 928 "reset status %d\n",
927 channel->center_freq, r); 929 channel->center_freq, r);
928 } 930 }
@@ -1528,6 +1530,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1528 spin_unlock_bh(&sc->wiphy_lock); 1530 spin_unlock_bh(&sc->wiphy_lock);
1529 1531
1530 if (enable_radio) { 1532 if (enable_radio) {
1533 sc->ps_idle = false;
1531 ath_radio_enable(sc, hw); 1534 ath_radio_enable(sc, hw);
1532 ath_print(common, ATH_DBG_CONFIG, 1535 ath_print(common, ATH_DBG_CONFIG,
1533 "not-idle: enabling radio\n"); 1536 "not-idle: enabling radio\n");
@@ -1624,8 +1627,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1624 } 1627 }
1625 1628
1626skip_chan_change: 1629skip_chan_change:
1627 if (changed & IEEE80211_CONF_CHANGE_POWER) 1630 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1628 sc->config.txpowlimit = 2 * conf->power_level; 1631 sc->config.txpowlimit = 2 * conf->power_level;
1632 ath_update_txpow(sc);
1633 }
1629 1634
1630 spin_lock_bh(&sc->wiphy_lock); 1635 spin_lock_bh(&sc->wiphy_lock);
1631 disable_radio = ath9k_all_wiphys_idle(sc); 1636 disable_radio = ath9k_all_wiphys_idle(sc);
@@ -1633,6 +1638,7 @@ skip_chan_change:
1633 1638
1634 if (disable_radio) { 1639 if (disable_radio) {
1635 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); 1640 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1641 sc->ps_idle = true;
1636 ath_radio_disable(sc, hw); 1642 ath_radio_disable(sc, hw);
1637 } 1643 }
1638 1644
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index fe2c3a644a6e..9441c6718a30 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -25,6 +25,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
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};
@@ -245,12 +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;
248 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 238 void __iomem *mem = sc->mem;
249 239
250 ath9k_deinit_device(sc); 240 ath9k_deinit_device(sc);
251 free_irq(sc->irq, sc); 241 free_irq(sc->irq, sc);
252 ieee80211_free_hw(sc->hw); 242 ieee80211_free_hw(sc->hw);
253 ath_bus_cleanup(common); 243
244 pci_iounmap(pdev, mem);
245 pci_disable_device(pdev);
246 pci_release_region(pdev, 0);
254} 247}
255 248
256#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 70fdb9d8db82..11968843c773 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -678,13 +678,13 @@ 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);
@@ -714,7 +714,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
714 for ( ; i < 4; i++) { 714 for ( ; i < 4; i++) {
715 /* Use twice the number of tries for the last MRR segment. */ 715 /* Use twice the number of tries for the last MRR segment. */
716 if (i + 1 == 4) 716 if (i + 1 == 4)
717 try_per_rate = 4; 717 try_per_rate = 8;
718 718
719 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 719 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
720 /* All other rates in the series have RTS enabled */ 720 /* All other rates in the series have RTS enabled */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 40b5d05edcce..1ca42e5148c8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -429,7 +429,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
429 sc->ps_flags &= ~PS_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->ps_flags & (PS_WAIT_FOR_BEACON | 433 sc->ps_flags & (PS_WAIT_FOR_BEACON |
434 PS_WAIT_FOR_CAB | 434 PS_WAIT_FOR_CAB |
435 PS_WAIT_FOR_PSPOLL_DATA | 435 PS_WAIT_FOR_PSPOLL_DATA |
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/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index a821bb687b3b..3c790a4f38f7 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,
@@ -1862,7 +1857,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1862 sc->ps_flags &= ~PS_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->ps_flags & (PS_WAIT_FOR_BEACON | 1861 sc->ps_flags & (PS_WAIT_FOR_BEACON |
1867 PS_WAIT_FOR_CAB | 1862 PS_WAIT_FOR_CAB |
1868 PS_WAIT_FOR_PSPOLL_DATA | 1863 PS_WAIT_FOR_PSPOLL_DATA |
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/b43/main.c b/drivers/net/wireless/b43/main.c
index 9c5c7c9ad530..316a913860d7 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -844,8 +844,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
844} 844}
845 845
846static void b43_op_update_tkip_key(struct ieee80211_hw *hw, 846static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
847 struct ieee80211_key_conf *keyconf, const u8 *addr, 847 struct ieee80211_vif *vif,
848 u32 iv32, u16 *phase1key) 848 struct ieee80211_key_conf *keyconf,
849 struct ieee80211_sta *sta,
850 u32 iv32, u16 *phase1key)
849{ 851{
850 struct b43_wl *wl = hw_to_b43_wl(hw); 852 struct b43_wl *wl = hw_to_b43_wl(hw);
851 struct b43_wldev *dev; 853 struct b43_wldev *dev;
@@ -854,19 +856,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
854 if (B43_WARN_ON(!modparam_hwtkip)) 856 if (B43_WARN_ON(!modparam_hwtkip))
855 return; 857 return;
856 858
857 mutex_lock(&wl->mutex); 859 /* This is only called from the RX path through mac80211, where
858 860 * our mutex is already locked. */
861 B43_WARN_ON(!mutex_is_locked(&wl->mutex));
859 dev = wl->current_dev; 862 dev = wl->current_dev;
860 if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) 863 B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
861 goto out_unlock;
862 864
863 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ 865 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
864 866
865 rx_tkip_phase1_write(dev, index, iv32, phase1key); 867 rx_tkip_phase1_write(dev, index, iv32, phase1key);
866 keymac_write(dev, index, addr); 868 /* only pairwise TKIP keys are supported right now */
867 869 if (WARN_ON(!sta))
868out_unlock: 870 return;
869 mutex_unlock(&wl->mutex); 871 keymac_write(dev, index, sta->addr);
870} 872}
871 873
872static void do_key_write(struct b43_wldev *dev, 874static void do_key_write(struct b43_wldev *dev,
@@ -3571,6 +3573,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3571 dev = wl->current_dev; 3573 dev = wl->current_dev;
3572 phy = &dev->phy; 3574 phy = &dev->phy;
3573 3575
3576 if (conf_is_ht(conf))
3577 phy->is_40mhz =
3578 (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
3579 else
3580 phy->is_40mhz = false;
3581
3574 b43_mac_suspend(dev); 3582 b43_mac_suspend(dev);
3575 3583
3576 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) 3584 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
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 b58d6cf26580..185219e0a552 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1767,47 +1767,6 @@ out:
1767 return ret; 1767 return ret;
1768} 1768}
1769 1769
1770/* Complex number using 2 32-bit signed integers */
1771typedef struct {s32 i, q;} lpphy_c32;
1772
1773static lpphy_c32 lpphy_cordic(int theta)
1774{
1775 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
1776 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
1777 229, 115, 57, 29, };
1778 int i, tmp, signx = 1, angle = 0;
1779 lpphy_c32 ret = { .i = 39797, .q = 0, };
1780
1781 theta = clamp_t(int, theta, -180, 180);
1782
1783 if (theta > 90) {
1784 theta -= 180;
1785 signx = -1;
1786 } else if (theta < -90) {
1787 theta += 180;
1788 signx = -1;
1789 }
1790
1791 for (i = 0; i <= 17; i++) {
1792 if (theta > angle) {
1793 tmp = ret.i - (ret.q >> i);
1794 ret.q += ret.i >> i;
1795 ret.i = tmp;
1796 angle += arctg[i];
1797 } else {
1798 tmp = ret.i + (ret.q >> i);
1799 ret.q -= ret.i >> i;
1800 ret.i = tmp;
1801 angle -= arctg[i];
1802 }
1803 }
1804
1805 ret.i *= signx;
1806 ret.q *= signx;
1807
1808 return ret;
1809}
1810
1811static 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,
1812 u16 wait) 1771 u16 wait)
1813{ 1772{
@@ -1825,8 +1784,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1825{ 1784{
1826 struct b43_phy_lp *lpphy = dev->phy.lp; 1785 struct b43_phy_lp *lpphy = dev->phy.lp;
1827 u16 buf[64]; 1786 u16 buf[64];
1828 int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; 1787 int i, samples = 0, angle = 0;
1829 lpphy_c32 sample; 1788 int rotation = (((36 * freq) / 20) << 16) / 100;
1789 struct b43_c32 sample;
1830 1790
1831 lpphy->tx_tone_freq = freq; 1791 lpphy->tx_tone_freq = freq;
1832 1792
@@ -1842,10 +1802,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1842 } 1802 }
1843 1803
1844 for (i = 0; i < samples; i++) { 1804 for (i = 0; i < samples; i++) {
1845 sample = lpphy_cordic(angle); 1805 sample = b43_cordic(angle);
1846 angle += rotation; 1806 angle += rotation;
1847 buf[i] = ((sample.i * max) & 0xFF) << 8; 1807 buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
1848 buf[i] |= (sample.q * max) & 0xFF; 1808 buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
1849 } 1809 }
1850 1810
1851 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 4a817e3da163..6392da25efed 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -55,6 +55,20 @@ struct nphy_iq_est {
55 u32 q1_pwr; 55 u32 q1_pwr;
56}; 56};
57 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);
71
58void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 72void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
59{//TODO 73{//TODO
60} 74}
@@ -234,110 +248,6 @@ static void b43_nphy_tables_init(struct b43_wldev *dev)
234 b43_nphy_rev3plus_tables_init(dev); 248 b43_nphy_rev3plus_tables_init(dev);
235} 249}
236 250
237static void b43_nphy_workarounds(struct b43_wldev *dev)
238{
239 struct b43_phy *phy = &dev->phy;
240 unsigned int i;
241
242 b43_phy_set(dev, B43_NPHY_IQFLIP,
243 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
244 if (1 /* FIXME band is 2.4GHz */) {
245 b43_phy_set(dev, B43_NPHY_CLASSCTL,
246 B43_NPHY_CLASSCTL_CCKEN);
247 } else {
248 b43_phy_mask(dev, B43_NPHY_CLASSCTL,
249 ~B43_NPHY_CLASSCTL_CCKEN);
250 }
251 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
252 b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8);
253
254 /* Fixup some tables */
255 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA);
256 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA);
257 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
258 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
259 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0);
260 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0);
261 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
262 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
263 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800);
264 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800);
265
266 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
267 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
268 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
269 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
270
271 //TODO set RF sequence
272
273 /* Set narrowband clip threshold */
274 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66);
275 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66);
276
277 /* Set wideband clip 2 threshold */
278 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
279 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
280 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT);
281 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
282 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
283 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT);
284
285 /* Set Clip 2 detect */
286 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
287 B43_NPHY_C1_CGAINI_CL2DETECT);
288 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
289 B43_NPHY_C2_CGAINI_CL2DETECT);
290
291 if (0 /*FIXME*/) {
292 /* Set dwell lengths */
293 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43);
294 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43);
295 b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9);
296 b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9);
297
298 /* Set gain backoff */
299 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
300 ~B43_NPHY_C1_CGAINI_GAINBKOFF,
301 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT);
302 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
303 ~B43_NPHY_C2_CGAINI_GAINBKOFF,
304 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT);
305
306 /* Set HPVGA2 index */
307 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
308 ~B43_NPHY_C1_INITGAIN_HPVGA2,
309 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
310 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
311 ~B43_NPHY_C2_INITGAIN_HPVGA2,
312 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
313
314 //FIXME verify that the specs really mean to use autoinc here.
315 for (i = 0; i < 3; i++)
316 b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673);
317 }
318
319 /* Set minimum gain value */
320 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN,
321 ~B43_NPHY_C1_MINGAIN,
322 23 << B43_NPHY_C1_MINGAIN_SHIFT);
323 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN,
324 ~B43_NPHY_C2_MINGAIN,
325 23 << B43_NPHY_C2_MINGAIN_SHIFT);
326
327 if (phy->rev < 2) {
328 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
329 ~B43_NPHY_SCRAM_SIGCTL_SCM);
330 }
331
332 /* Set phase track alpha and beta */
333 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
334 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
335 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
336 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
337 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
338 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
339}
340
341/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ 251/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
342static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) 252static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
343{ 253{
@@ -421,7 +331,49 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev)
421 udelay(1); 331 udelay(1);
422 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); 332 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
423 b43_nphy_bmac_clock_fgc(dev, 0); 333 b43_nphy_bmac_clock_fgc(dev, 0);
424 /* TODO: N PHY Force RF Seq with argument 2 */ 334 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
335}
336
337/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
338static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
339{
340 u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
341
342 mimocfg |= B43_NPHY_MIMOCFG_AUTO;
343 if (preamble == 1)
344 mimocfg |= B43_NPHY_MIMOCFG_GFMIX;
345 else
346 mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX;
347
348 b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
349}
350
351/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
352static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
353{
354 struct b43_phy_n *nphy = dev->phy.n;
355
356 bool override = false;
357 u16 chain = 0x33;
358
359 if (nphy->txrx_chain == 0) {
360 chain = 0x11;
361 override = true;
362 } else if (nphy->txrx_chain == 1) {
363 chain = 0x22;
364 override = true;
365 }
366
367 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
368 ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
369 chain);
370
371 if (override)
372 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
373 B43_NPHY_RFSEQMODE_CAOVER);
374 else
375 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
376 ~B43_NPHY_RFSEQMODE_CAOVER);
425} 377}
426 378
427/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ 379/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
@@ -480,6 +432,88 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
480 } 432 }
481} 433}
482 434
435/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
436static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
437{
438 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
439
440 b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]);
441 if (core == 0) {
442 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]);
443 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
444 } else {
445 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
446 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
447 }
448 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]);
449 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]);
450 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]);
451 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]);
452 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]);
453 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]);
454 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
455 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
456}
457
458/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
459static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
460{
461 u8 rxval, txval;
462 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
463
464 regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
465 if (core == 0) {
466 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
467 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
468 } else {
469 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
470 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
471 }
472 regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
473 regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
474 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
475 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
476 regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1);
477 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
478 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
479 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
480
481 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
482 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
483
484 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS,
485 ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
486 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
487 ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT));
488 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
489 (core << B43_NPHY_RFSEQCA_RXEN_SHIFT));
490 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS,
491 (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT));
492
493 if (core == 0) {
494 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007);
495 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007);
496 } else {
497 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007);
498 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
499 }
500
501 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */
502 /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */
503 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
504
505 if (core == 0) {
506 rxval = 1;
507 txval = 8;
508 } else {
509 rxval = 4;
510 txval = 2;
511 }
512
513 /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */
514 /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */
515}
516
483/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ 517/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
484static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) 518static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
485{ 519{
@@ -653,6 +687,386 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
653 } 687 }
654} 688}
655 689
690/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
691static void b43_nphy_stop_playback(struct b43_wldev *dev)
692{
693 struct b43_phy_n *nphy = dev->phy.n;
694 u16 tmp;
695
696 if (nphy->hang_avoid)
697 b43_nphy_stay_in_carrier_search(dev, 1);
698
699 tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
700 if (tmp & 0x1)
701 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
702 else if (tmp & 0x2)
703 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000);
704
705 b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
706
707 if (nphy->bb_mult_save & 0x80000000) {
708 tmp = nphy->bb_mult_save & 0xFFFF;
709 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
710 nphy->bb_mult_save = 0;
711 }
712
713 if (nphy->hang_avoid)
714 b43_nphy_stay_in_carrier_search(dev, 0);
715}
716
717/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
718static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
719{
720 struct b43_phy_n *nphy = dev->phy.n;
721 u8 i, j;
722 u8 code;
723
724 /* TODO: for PHY >= 3
725 s8 *lna1_gain, *lna2_gain;
726 u8 *gain_db, *gain_bits;
727 u16 *rfseq_init;
728 u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
729 u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
730 */
731
732 u8 rfseq_events[3] = { 6, 8, 7 };
733 u8 rfseq_delays[3] = { 10, 30, 1 };
734
735 if (dev->phy.rev >= 3) {
736 /* TODO */
737 } else {
738 /* Set Clip 2 detect */
739 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
740 B43_NPHY_C1_CGAINI_CL2DETECT);
741 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
742 B43_NPHY_C2_CGAINI_CL2DETECT);
743
744 /* Set narrowband clip threshold */
745 b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
746 b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
747
748 if (!dev->phy.is_40mhz) {
749 /* Set dwell lengths */
750 b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
751 b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
752 b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
753 b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
754 }
755
756 /* Set wideband clip 2 threshold */
757 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
758 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
759 21);
760 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
761 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
762 21);
763
764 if (!dev->phy.is_40mhz) {
765 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
766 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
767 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
768 ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1);
769 b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI,
770 ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1);
771 b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI,
772 ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
773 }
774
775 b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
776
777 if (nphy->gain_boost) {
778 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
779 dev->phy.is_40mhz)
780 code = 4;
781 else
782 code = 5;
783 } else {
784 code = dev->phy.is_40mhz ? 6 : 7;
785 }
786
787 /* Set HPVGA2 index */
788 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
789 ~B43_NPHY_C1_INITGAIN_HPVGA2,
790 code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
791 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
792 ~B43_NPHY_C2_INITGAIN_HPVGA2,
793 code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
794
795 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
796 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
797 (code << 8 | 0x7C));
798 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
799 (code << 8 | 0x7C));
800
801 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */
802
803 if (nphy->elna_gain_config) {
804 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
805 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
806 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
807 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
808 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
809
810 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08);
811 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
812 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
813 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
814 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
815
816 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
817 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
818 (code << 8 | 0x74));
819 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
820 (code << 8 | 0x74));
821 }
822
823 if (dev->phy.rev == 2) {
824 for (i = 0; i < 4; i++) {
825 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
826 (0x0400 * i) + 0x0020);
827 for (j = 0; j < 21; j++)
828 b43_phy_write(dev,
829 B43_NPHY_TABLE_DATALO, 3 * j);
830 }
831
832 b43_nphy_set_rf_sequence(dev, 5,
833 rfseq_events, rfseq_delays, 3);
834 b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
835 (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV,
836 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
837
838 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
839 b43_phy_maskset(dev, B43_PHY_N(0xC5D),
840 0xFF80, 4);
841 }
842 }
843}
844
845/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
846static void b43_nphy_workarounds(struct b43_wldev *dev)
847{
848 struct ssb_bus *bus = dev->dev->bus;
849 struct b43_phy *phy = &dev->phy;
850 struct b43_phy_n *nphy = phy->n;
851
852 u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 };
853 u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 };
854
855 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
856 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
857
858 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
859 b43_nphy_classifier(dev, 1, 0);
860 else
861 b43_nphy_classifier(dev, 1, 1);
862
863 if (nphy->hang_avoid)
864 b43_nphy_stay_in_carrier_search(dev, 1);
865
866 b43_phy_set(dev, B43_NPHY_IQFLIP,
867 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
868
869 if (dev->phy.rev >= 3) {
870 /* TODO */
871 } else {
872 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
873 nphy->band5g_pwrgain) {
874 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
875 b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
876 } else {
877 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
878 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
879 }
880
881 /* TODO: convert to b43_ntab_write? */
882 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
883 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
884 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
885 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
886 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
887 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
888 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
889 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
890
891 if (dev->phy.rev < 2) {
892 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
893 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
894 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
895 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
896 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
897 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
898 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
899 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
900 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
901 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
902 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
903 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
904 }
905
906 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
907 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
908 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
909 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
910
911 if (bus->sprom.boardflags2_lo & 0x100 &&
912 bus->boardinfo.type == 0x8B) {
913 delays1[0] = 0x1;
914 delays1[5] = 0x14;
915 }
916 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
917 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
918
919 b43_nphy_gain_crtl_workarounds(dev);
920
921 if (dev->phy.rev < 2) {
922 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
923 ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
924 } else if (dev->phy.rev == 2) {
925 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
926 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
927 }
928
929 if (dev->phy.rev < 2)
930 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
931 ~B43_NPHY_SCRAM_SIGCTL_SCM);
932
933 /* Set phase track alpha and beta */
934 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
935 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
936 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
937 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
938 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
939 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
940
941 b43_phy_mask(dev, B43_NPHY_PIL_DW1,
942 (u16)~B43_NPHY_PIL_DW_64QAM);
943 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
944 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
945 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
946
947 if (dev->phy.rev == 2)
948 b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
949 B43_NPHY_FINERX2_CGC_DECGC);
950 }
951
952 if (nphy->hang_avoid)
953 b43_nphy_stay_in_carrier_search(dev, 0);
954}
955
956/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
957static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
958 bool test)
959{
960 int i;
961 u16 bw, len, rot, angle;
962 struct b43_c32 *samples;
963
964
965 bw = (dev->phy.is_40mhz) ? 40 : 20;
966 len = bw << 3;
967
968 if (test) {
969 if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX)
970 bw = 82;
971 else
972 bw = 80;
973
974 if (dev->phy.is_40mhz)
975 bw <<= 1;
976
977 len = bw << 1;
978 }
979
980 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
981 rot = (((freq * 36) / bw) << 16) / 100;
982 angle = 0;
983
984 for (i = 0; i < len; i++) {
985 samples[i] = b43_cordic(angle);
986 angle += rot;
987 samples[i].q = CORDIC_CONVERT(samples[i].q * max);
988 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
989 }
990
991 /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */
992 kfree(samples);
993 return len;
994}
995
996/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
997static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
998 u16 wait, bool iqmode, bool dac_test)
999{
1000 struct b43_phy_n *nphy = dev->phy.n;
1001 int i;
1002 u16 seq_mode;
1003 u32 tmp;
1004
1005 if (nphy->hang_avoid)
1006 b43_nphy_stay_in_carrier_search(dev, true);
1007
1008 if ((nphy->bb_mult_save & 0x80000000) == 0) {
1009 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1010 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1011 }
1012
1013 if (!dev->phy.is_40mhz)
1014 tmp = 0x6464;
1015 else
1016 tmp = 0x4747;
1017 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1018
1019 if (nphy->hang_avoid)
1020 b43_nphy_stay_in_carrier_search(dev, false);
1021
1022 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1023
1024 if (loops != 0xFFFF)
1025 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1));
1026 else
1027 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops);
1028
1029 b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait);
1030
1031 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
1032
1033 b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER);
1034 if (iqmode) {
1035 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1036 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1037 } else {
1038 if (dac_test)
1039 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1040 else
1041 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1042 }
1043 for (i = 0; i < 100; i++) {
1044 if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) {
1045 i = 0;
1046 break;
1047 }
1048 udelay(10);
1049 }
1050 if (i)
1051 b43err(dev->wl, "run samples timeout\n");
1052
1053 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
1054}
1055
1056/*
1057 * Transmits a known value for LO calibration
1058 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1059 */
1060static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1061 bool iqmode, bool dac_test)
1062{
1063 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1064 if (samp == 0)
1065 return -1;
1066 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1067 return 0;
1068}
1069
656/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ 1070/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
657static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) 1071static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
658{ 1072{
@@ -666,8 +1080,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
666 if (nphy->hang_avoid) 1080 if (nphy->hang_avoid)
667 b43_nphy_stay_in_carrier_search(dev, true); 1081 b43_nphy_stay_in_carrier_search(dev, true);
668 1082
669 /* TODO: Read an N PHY Table with ID 15, length 7, offset 80, 1083 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
670 width 16, and data pointer buffer */
671 1084
672 for (i = 0; i < 2; i++) { 1085 for (i = 0; i < 2; i++) {
673 tmp = ((buffer[i * 2] & 0x3FF) << 10) | 1086 tmp = ((buffer[i * 2] & 0x3FF) << 10) |
@@ -720,15 +1133,32 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
720 b43_nphy_stay_in_carrier_search(dev, false); 1133 b43_nphy_stay_in_carrier_search(dev, false);
721} 1134}
722 1135
723enum b43_nphy_rf_sequence { 1136/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
724 B43_RFSEQ_RX2TX, 1137static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
725 B43_RFSEQ_TX2RX, 1138 u8 *events, u8 *delays, u8 length)
726 B43_RFSEQ_RESET2RX, 1139{
727 B43_RFSEQ_UPDATE_GAINH, 1140 struct b43_phy_n *nphy = dev->phy.n;
728 B43_RFSEQ_UPDATE_GAINL, 1141 u8 i;
729 B43_RFSEQ_UPDATE_GAINU, 1142 u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F;
730}; 1143 u16 offset1 = cmd << 4;
1144 u16 offset2 = offset1 + 0x80;
731 1145
1146 if (nphy->hang_avoid)
1147 b43_nphy_stay_in_carrier_search(dev, true);
1148
1149 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events);
1150 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays);
1151
1152 for (i = length; i < 16; i++) {
1153 b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end);
1154 b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1);
1155 }
1156
1157 if (nphy->hang_avoid)
1158 b43_nphy_stay_in_carrier_search(dev, false);
1159}
1160
1161/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
732static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 1162static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
733 enum b43_nphy_rf_sequence seq) 1163 enum b43_nphy_rf_sequence seq)
734{ 1164{
@@ -741,6 +1171,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
741 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, 1171 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU,
742 }; 1172 };
743 int i; 1173 int i;
1174 u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
744 1175
745 B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); 1176 B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
746 1177
@@ -754,8 +1185,83 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
754 } 1185 }
755 b43err(dev->wl, "RF sequence status timeout\n"); 1186 b43err(dev->wl, "RF sequence status timeout\n");
756ok: 1187ok:
757 b43_phy_mask(dev, B43_NPHY_RFSEQMODE, 1188 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
758 ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); 1189}
1190
1191/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
1192static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
1193 u16 value, u8 core, bool off)
1194{
1195 int i;
1196 u8 index = fls(field);
1197 u8 addr, en_addr, val_addr;
1198 /* we expect only one bit set */
1199 B43_WARN_ON(field & (~(1 << (index - 1))));
1200
1201 if (dev->phy.rev >= 3) {
1202 const struct nphy_rf_control_override_rev3 *rf_ctrl;
1203 for (i = 0; i < 2; i++) {
1204 if (index == 0 || index == 16) {
1205 b43err(dev->wl,
1206 "Unsupported RF Ctrl Override call\n");
1207 return;
1208 }
1209
1210 rf_ctrl = &tbl_rf_control_override_rev3[index - 1];
1211 en_addr = B43_PHY_N((i == 0) ?
1212 rf_ctrl->en_addr0 : rf_ctrl->en_addr1);
1213 val_addr = B43_PHY_N((i == 0) ?
1214 rf_ctrl->val_addr0 : rf_ctrl->val_addr1);
1215
1216 if (off) {
1217 b43_phy_mask(dev, en_addr, ~(field));
1218 b43_phy_mask(dev, val_addr,
1219 ~(rf_ctrl->val_mask));
1220 } else {
1221 if (core == 0 || ((1 << core) & i) != 0) {
1222 b43_phy_set(dev, en_addr, field);
1223 b43_phy_maskset(dev, val_addr,
1224 ~(rf_ctrl->val_mask),
1225 (value << rf_ctrl->val_shift));
1226 }
1227 }
1228 }
1229 } else {
1230 const struct nphy_rf_control_override_rev2 *rf_ctrl;
1231 if (off) {
1232 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field));
1233 value = 0;
1234 } else {
1235 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field);
1236 }
1237
1238 for (i = 0; i < 2; i++) {
1239 if (index <= 1 || index == 16) {
1240 b43err(dev->wl,
1241 "Unsupported RF Ctrl Override call\n");
1242 return;
1243 }
1244
1245 if (index == 2 || index == 10 ||
1246 (index >= 13 && index <= 15)) {
1247 core = 1;
1248 }
1249
1250 rf_ctrl = &tbl_rf_control_override_rev2[index - 2];
1251 addr = B43_PHY_N((i == 0) ?
1252 rf_ctrl->addr0 : rf_ctrl->addr1);
1253
1254 if ((core & (1 << i)) != 0)
1255 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
1256 (value << rf_ctrl->shift));
1257
1258 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
1259 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1260 B43_NPHY_RFCTL_CMD_START);
1261 udelay(1);
1262 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE);
1263 }
1264 }
759} 1265}
760 1266
761static void b43_nphy_bphy_init(struct b43_wldev *dev) 1267static void b43_nphy_bphy_init(struct b43_wldev *dev)
@@ -837,66 +1343,151 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
837 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); 1343 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
838} 1344}
839 1345
840/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ 1346static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
841static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
842{ 1347{
843 u16 val; 1348 u16 val;
844 1349
845 if (dev->phy.rev >= 3) { 1350 if (type < 3)
846 /* TODO */ 1351 val = 0;
847 } else { 1352 else if (type == 6)
848 if (type < 3) 1353 val = 1;
849 val = 0; 1354 else if (type == 3)
850 else if (type == 6) 1355 val = 2;
851 val = 1; 1356 else
852 else if (type == 3) 1357 val = 3;
853 val = 2;
854 else
855 val = 3;
856 1358
857 val = (val << 12) | (val << 14); 1359 val = (val << 12) | (val << 14);
858 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); 1360 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
859 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); 1361 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
860 1362
1363 if (type < 3) {
1364 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
1365 (type + 1) << 4);
1366 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
1367 (type + 1) << 4);
1368 }
1369
1370 /* TODO use some definitions */
1371 if (code == 0) {
1372 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
1373 if (type < 3) {
1374 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
1375 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
1376 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
1377 udelay(20);
1378 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
1379 }
1380 } else {
1381 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
1382 0x3000);
861 if (type < 3) { 1383 if (type < 3) {
862 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, 1384 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
863 (type + 1) << 4); 1385 0xFEC7, 0x0180);
864 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, 1386 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
865 (type + 1) << 4); 1387 0xEFDC, (code << 1 | 0x1021));
1388 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
1389 udelay(20);
1390 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
866 } 1391 }
1392 }
1393}
1394
1395static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1396{
1397 struct b43_phy_n *nphy = dev->phy.n;
1398 u8 i;
1399 u16 reg, val;
1400
1401 if (code == 0) {
1402 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF);
1403 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF);
1404 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF);
1405 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF);
1406 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF);
1407 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF);
1408 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3);
1409 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3);
1410 } else {
1411 for (i = 0; i < 2; i++) {
1412 if ((code == 1 && i == 1) || (code == 2 && !i))
1413 continue;
1414
1415 reg = (i == 0) ?
1416 B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER;
1417 b43_phy_maskset(dev, reg, 0xFDFF, 0x0200);
867 1418
868 /* TODO use some definitions */
869 if (code == 0) {
870 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
871 if (type < 3) {
872 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
873 0xFEC7, 0);
874 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
875 0xEFDC, 0);
876 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
877 0xFFFE, 0);
878 udelay(20);
879 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
880 0xFFFE, 0);
881 }
882 } else {
883 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
884 0x3000);
885 if (type < 3) { 1419 if (type < 3) {
886 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 1420 reg = (i == 0) ?
887 0xFEC7, 0x0180); 1421 B43_NPHY_AFECTL_C1 :
888 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 1422 B43_NPHY_AFECTL_C2;
889 0xEFDC, (code << 1 | 0x1021)); 1423 b43_phy_maskset(dev, reg, 0xFCFF, 0);
890 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 1424
891 0xFFFE, 0x0001); 1425 reg = (i == 0) ?
892 udelay(20); 1426 B43_NPHY_RFCTL_LUT_TRSW_UP1 :
893 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 1427 B43_NPHY_RFCTL_LUT_TRSW_UP2;
894 0xFFFE, 0); 1428 b43_phy_maskset(dev, reg, 0xFFC3, 0);
1429
1430 if (type == 0)
1431 val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8;
1432 else if (type == 1)
1433 val = 16;
1434 else
1435 val = 32;
1436 b43_phy_set(dev, reg, val);
1437
1438 reg = (i == 0) ?
1439 B43_NPHY_TXF_40CO_B1S0 :
1440 B43_NPHY_TXF_40CO_B32S1;
1441 b43_phy_set(dev, reg, 0x0020);
1442 } else {
1443 if (type == 6)
1444 val = 0x0100;
1445 else if (type == 3)
1446 val = 0x0200;
1447 else
1448 val = 0x0300;
1449
1450 reg = (i == 0) ?
1451 B43_NPHY_AFECTL_C1 :
1452 B43_NPHY_AFECTL_C2;
1453
1454 b43_phy_maskset(dev, reg, 0xFCFF, val);
1455 b43_phy_maskset(dev, reg, 0xF3FF, val << 2);
1456
1457 if (type != 3 && type != 6) {
1458 enum ieee80211_band band =
1459 b43_current_band(dev->wl);
1460
1461 if ((nphy->ipa2g_on &&
1462 band == IEEE80211_BAND_2GHZ) ||
1463 (nphy->ipa5g_on &&
1464 band == IEEE80211_BAND_5GHZ))
1465 val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1466 else
1467 val = 0x11;
1468 reg = (i == 0) ? 0x2000 : 0x3000;
1469 reg |= B2055_PADDRV;
1470 b43_radio_write16(dev, reg, val);
1471
1472 reg = (i == 0) ?
1473 B43_NPHY_AFECTL_OVER1 :
1474 B43_NPHY_AFECTL_OVER;
1475 b43_phy_set(dev, reg, 0x0200);
1476 }
895 } 1477 }
896 } 1478 }
897 } 1479 }
898} 1480}
899 1481
1482/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
1483static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1484{
1485 if (dev->phy.rev >= 3)
1486 b43_nphy_rev3_rssi_select(dev, code, type);
1487 else
1488 b43_nphy_rev2_rssi_select(dev, code, type);
1489}
1490
900/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ 1491/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
901static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) 1492static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
902{ 1493{
@@ -1239,9 +1830,60 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
1239{ 1830{
1240 struct b43_phy_n *nphy = dev->phy.n; 1831 struct b43_phy_n *nphy = dev->phy.n;
1241 u16 *save = nphy->tx_rx_cal_radio_saveregs; 1832 u16 *save = nphy->tx_rx_cal_radio_saveregs;
1833 u16 tmp;
1834 u8 offset, i;
1242 1835
1243 if (dev->phy.rev >= 3) { 1836 if (dev->phy.rev >= 3) {
1244 /* TODO */ 1837 for (i = 0; i < 2; i++) {
1838 tmp = (i == 0) ? 0x2000 : 0x3000;
1839 offset = i * 11;
1840
1841 save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL);
1842 save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL);
1843 save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS);
1844 save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS);
1845 save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS);
1846 save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV);
1847 save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1);
1848 save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2);
1849 save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL);
1850 save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC);
1851 save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1);
1852
1853 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1854 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A);
1855 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
1856 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
1857 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
1858 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
1859 if (nphy->ipa5g_on) {
1860 b43_radio_write16(dev, tmp | B2055_PADDRV, 4);
1861 b43_radio_write16(dev, tmp | B2055_XOCTL1, 1);
1862 } else {
1863 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
1864 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F);
1865 }
1866 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
1867 } else {
1868 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06);
1869 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
1870 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
1871 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
1872 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
1873 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0);
1874 if (nphy->ipa2g_on) {
1875 b43_radio_write16(dev, tmp | B2055_PADDRV, 6);
1876 b43_radio_write16(dev, tmp | B2055_XOCTL2,
1877 (dev->phy.rev < 5) ? 0x11 : 0x01);
1878 } else {
1879 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
1880 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
1881 }
1882 }
1883 b43_radio_write16(dev, tmp | B2055_XOREGUL, 0);
1884 b43_radio_write16(dev, tmp | B2055_XOMISC, 0);
1885 b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0);
1886 }
1245 } else { 1887 } else {
1246 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); 1888 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1);
1247 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); 1889 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
@@ -1330,16 +1972,51 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
1330 for (i = 0; i < 18; i++) { 1972 for (i = 0; i < 18; i++) {
1331 scale = (ladder_lo[i].percent * tmp) / 100; 1973 scale = (ladder_lo[i].percent * tmp) / 100;
1332 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; 1974 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
1333 /* TODO: Write an N PHY Table with ID 15, length 1, 1975 b43_ntab_write(dev, B43_NTAB16(15, i), entry);
1334 offset i, width 16, and data entry */
1335 1976
1336 scale = (ladder_iq[i].percent * tmp) / 100; 1977 scale = (ladder_iq[i].percent * tmp) / 100;
1337 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; 1978 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
1338 /* TODO: Write an N PHY Table with ID 15, length 1, 1979 b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry);
1339 offset i + 32, width 16, and data entry */
1340 } 1980 }
1341} 1981}
1342 1982
1983/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
1984static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
1985{
1986 int i;
1987 for (i = 0; i < 15; i++)
1988 b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
1989 tbl_tx_filter_coef_rev4[2][i]);
1990}
1991
1992/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
1993static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
1994{
1995 int i, j;
1996 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
1997 u16 offset[] = { 0x186, 0x195, 0x2C5 };
1998
1999 for (i = 0; i < 3; i++)
2000 for (j = 0; j < 15; j++)
2001 b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2002 tbl_tx_filter_coef_rev4[i][j]);
2003
2004 if (dev->phy.is_40mhz) {
2005 for (j = 0; j < 15; j++)
2006 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2007 tbl_tx_filter_coef_rev4[3][j]);
2008 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2009 for (j = 0; j < 15; j++)
2010 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2011 tbl_tx_filter_coef_rev4[5][j]);
2012 }
2013
2014 if (dev->phy.channel == 14)
2015 for (j = 0; j < 15; j++)
2016 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2017 tbl_tx_filter_coef_rev4[6][j]);
2018}
2019
1343/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ 2020/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
1344static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) 2021static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1345{ 2022{
@@ -1354,8 +2031,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1354 2031
1355 if (nphy->hang_avoid) 2032 if (nphy->hang_avoid)
1356 b43_nphy_stay_in_carrier_search(dev, true); 2033 b43_nphy_stay_in_carrier_search(dev, true);
1357 /* TODO: Read an N PHY Table with ID 7, length 2, 2034 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain);
1358 offset 0x110, width 16, and curr_gain */
1359 if (nphy->hang_avoid) 2035 if (nphy->hang_avoid)
1360 b43_nphy_stay_in_carrier_search(dev, false); 2036 b43_nphy_stay_in_carrier_search(dev, false);
1361 2037
@@ -1423,6 +2099,101 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1423 return target; 2099 return target;
1424} 2100}
1425 2101
2102/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
2103static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
2104{
2105 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2106
2107 if (dev->phy.rev >= 3) {
2108 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]);
2109 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
2110 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
2111 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]);
2112 b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]);
2113 b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]);
2114 b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]);
2115 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]);
2116 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]);
2117 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
2118 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
2119 b43_nphy_reset_cca(dev);
2120 } else {
2121 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]);
2122 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]);
2123 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
2124 b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]);
2125 b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]);
2126 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]);
2127 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]);
2128 }
2129}
2130
2131/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2132static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2133{
2134 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2135 u16 tmp;
2136
2137 regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2138 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2139 if (dev->phy.rev >= 3) {
2140 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00);
2141 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00);
2142
2143 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
2144 regs[2] = tmp;
2145 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600);
2146
2147 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2148 regs[3] = tmp;
2149 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600);
2150
2151 regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG);
2152 b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX);
2153
2154 tmp = b43_ntab_read(dev, B43_NTAB16(8, 3));
2155 regs[5] = tmp;
2156 b43_ntab_write(dev, B43_NTAB16(8, 3), 0);
2157
2158 tmp = b43_ntab_read(dev, B43_NTAB16(8, 19));
2159 regs[6] = tmp;
2160 b43_ntab_write(dev, B43_NTAB16(8, 19), 0);
2161 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2162 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2163
2164 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */
2165 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */
2166 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */
2167
2168 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
2169 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2170 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2171 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2172 } else {
2173 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2174 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2175 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2176 regs[2] = tmp;
2177 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000);
2178 tmp = b43_ntab_read(dev, B43_NTAB16(8, 2));
2179 regs[3] = tmp;
2180 tmp |= 0x2000;
2181 b43_ntab_write(dev, B43_NTAB16(8, 2), tmp);
2182 tmp = b43_ntab_read(dev, B43_NTAB16(8, 18));
2183 regs[4] = tmp;
2184 tmp |= 0x2000;
2185 b43_ntab_write(dev, B43_NTAB16(8, 18), tmp);
2186 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2187 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2188 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2189 tmp = 0x0180;
2190 else
2191 tmp = 0x0120;
2192 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
2193 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
2194 }
2195}
2196
1426/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ 2197/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
1427static void b43_nphy_restore_cal(struct b43_wldev *dev) 2198static void b43_nphy_restore_cal(struct b43_wldev *dev)
1428{ 2199{
@@ -1448,8 +2219,7 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
1448 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2219 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
1449 } 2220 }
1450 2221
1451 /* TODO: Write an N PHY table with ID 15, length 4, offset 80, 2222 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table);
1452 width 16, and data from table */
1453 2223
1454 for (i = 0; i < 4; i++) { 2224 for (i = 0; i < 4; i++) {
1455 if (dev->phy.rev >= 3) 2225 if (dev->phy.rev >= 3)
@@ -1458,12 +2228,9 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
1458 coef[i] = 0; 2228 coef[i] = 0;
1459 } 2229 }
1460 2230
1461 /* TODO: Write an N PHY table with ID 15, length 4, offset 88, 2231 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef);
1462 width 16, and data from coef */ 2232 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft);
1463 /* TODO: Write an N PHY table with ID 15, length 2, offset 85, 2233 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft);
1464 width 16 and data from loft */
1465 /* TODO: Write an N PHY table with ID 15, length 2, offset 93,
1466 width 16 and data from loft */
1467 2234
1468 if (dev->phy.rev < 2) 2235 if (dev->phy.rev < 2)
1469 b43_nphy_tx_iq_workaround(dev); 2236 b43_nphy_tx_iq_workaround(dev);
@@ -1524,39 +2291,47 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1524 nphy->hang_avoid = 0; 2291 nphy->hang_avoid = 0;
1525 } 2292 }
1526 2293
1527 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, 2294 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
1528 width 16, and data pointer save */
1529 2295
1530 for (i = 0; i < 2; i++) { 2296 for (i = 0; i < 2; i++) {
1531 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]); 2297 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
1532 gain[i] = params[i].cal_gain; 2298 gain[i] = params[i].cal_gain;
1533 } 2299 }
1534 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2300
1535 width 16, and data pointer gain */ 2301 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain);
1536 2302
1537 b43_nphy_tx_cal_radio_setup(dev); 2303 b43_nphy_tx_cal_radio_setup(dev);
1538 /* TODO: Call N PHY TX Cal PHY Setup */ 2304 b43_nphy_tx_cal_phy_setup(dev);
1539 2305
1540 phy6or5x = dev->phy.rev >= 6 || 2306 phy6or5x = dev->phy.rev >= 6 ||
1541 (dev->phy.rev == 5 && nphy->ipa2g_on && 2307 (dev->phy.rev == 5 && nphy->ipa2g_on &&
1542 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); 2308 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
1543 if (phy6or5x) { 2309 if (phy6or5x) {
1544 /* TODO */ 2310 if (dev->phy.is_40mhz) {
2311 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2312 tbl_tx_iqlo_cal_loft_ladder_40);
2313 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2314 tbl_tx_iqlo_cal_iqimb_ladder_40);
2315 } else {
2316 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2317 tbl_tx_iqlo_cal_loft_ladder_20);
2318 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2319 tbl_tx_iqlo_cal_iqimb_ladder_20);
2320 }
1545 } 2321 }
1546 2322
1547 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); 2323 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
1548 2324
1549 if (1 /* FIXME: the band width is 20 MHz */) 2325 if (!dev->phy.is_40mhz)
1550 freq = 2500; 2326 freq = 2500;
1551 else 2327 else
1552 freq = 5000; 2328 freq = 5000;
1553 2329
1554 if (nphy->mphase_cal_phase_id > 2) 2330 if (nphy->mphase_cal_phase_id > 2)
1555 ;/* TODO: Call N PHY Run Samples with (band width * 8), 2331 b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
1556 0xFFFF, 0, 1, 0 as arguments */ 2332 0xFFFF, 0, true, false);
1557 else 2333 else
1558 ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments 2334 error = b43_nphy_tx_tone(dev, freq, 250, true, false);
1559 and save result as error */
1560 2335
1561 if (error == 0) { 2336 if (error == 0) {
1562 if (nphy->mphase_cal_phase_id > 2) { 2337 if (nphy->mphase_cal_phase_id > 2) {
@@ -1582,8 +2357,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1582 } 2357 }
1583 } 2358 }
1584 2359
1585 /* TODO: Write an N PHY Table with ID 15, length from above, 2360 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table);
1586 offset 64, width 16, and the data pointer from above */
1587 2361
1588 if (full) { 2362 if (full) {
1589 if (dev->phy.rev >= 3) 2363 if (dev->phy.rev >= 3)
@@ -1631,14 +2405,12 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1631 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); 2405 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
1632 2406
1633 if (type == 1 || type == 3 || type == 4) { 2407 if (type == 1 || type == 3 || type == 4) {
1634 /* TODO: Read an N PHY Table with ID 15, 2408 buffer[0] = b43_ntab_read(dev,
1635 length 1, offset 69 + core, 2409 B43_NTAB16(15, 69 + core));
1636 width 16, and data pointer buffer */
1637 diq_start = buffer[0]; 2410 diq_start = buffer[0];
1638 buffer[0] = 0; 2411 buffer[0] = 0;
1639 /* TODO: Write an N PHY Table with ID 15, 2412 b43_ntab_write(dev, B43_NTAB16(15, 69 + core),
1640 length 1, offset 69 + core, width 16, 2413 0);
1641 and data of 0 */
1642 } 2414 }
1643 2415
1644 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); 2416 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
@@ -1649,12 +2421,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1649 udelay(10); 2421 udelay(10);
1650 } 2422 }
1651 2423
1652 /* TODO: Read an N PHY Table with ID 15, 2424 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1653 length table_length, offset 96, width 16, 2425 buffer);
1654 and data pointer buffer */ 2426 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length,
1655 /* TODO: Write an N PHY Table with ID 15, 2427 buffer);
1656 length table_length, offset 64, width 16,
1657 and data pointer buffer */
1658 2428
1659 if (type == 1 || type == 3 || type == 4) 2429 if (type == 1 || type == 3 || type == 4)
1660 buffer[0] = diq_start; 2430 buffer[0] = diq_start;
@@ -1666,30 +2436,27 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1666 last = (dev->phy.rev < 3) ? 6 : 7; 2436 last = (dev->phy.rev < 3) ? 6 : 7;
1667 2437
1668 if (!mphase || nphy->mphase_cal_phase_id == last) { 2438 if (!mphase || nphy->mphase_cal_phase_id == last) {
1669 /* TODO: Write an N PHY Table with ID 15, length 4, 2439 b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer);
1670 offset 96, width 16, and data pointer buffer */ 2440 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer);
1671 /* TODO: Read an N PHY Table with ID 15, length 4,
1672 offset 80, width 16, and data pointer buffer */
1673 if (dev->phy.rev < 3) { 2441 if (dev->phy.rev < 3) {
1674 buffer[0] = 0; 2442 buffer[0] = 0;
1675 buffer[1] = 0; 2443 buffer[1] = 0;
1676 buffer[2] = 0; 2444 buffer[2] = 0;
1677 buffer[3] = 0; 2445 buffer[3] = 0;
1678 } 2446 }
1679 /* TODO: Write an N PHY Table with ID 15, length 4, 2447 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
1680 offset 88, width 16, and data pointer buffer */ 2448 buffer);
1681 /* TODO: Read an N PHY Table with ID 15, length 2, 2449 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2,
1682 offset 101, width 16, and data pointer buffer*/ 2450 buffer);
1683 /* TODO: Write an N PHY Table with ID 15, length 2, 2451 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
1684 offset 85, width 16, and data pointer buffer */ 2452 buffer);
1685 /* TODO: Write an N PHY Table with ID 15, length 2, 2453 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
1686 offset 93, width 16, and data pointer buffer */ 2454 buffer);
1687 length = 11; 2455 length = 11;
1688 if (dev->phy.rev < 3) 2456 if (dev->phy.rev < 3)
1689 length -= 2; 2457 length -= 2;
1690 /* TODO: Read an N PHY Table with ID 15, length length, 2458 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1691 offset 96, width 16, and data pointer 2459 nphy->txiqlocal_bestc);
1692 nphy->txiqlocal_bestc */
1693 nphy->txiqlocal_coeffsvalid = true; 2460 nphy->txiqlocal_coeffsvalid = true;
1694 /* TODO: Set nphy->txiqlocal_chanspec to 2461 /* TODO: Set nphy->txiqlocal_chanspec to
1695 the current channel */ 2462 the current channel */
@@ -1697,18 +2464,16 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1697 length = 11; 2464 length = 11;
1698 if (dev->phy.rev < 3) 2465 if (dev->phy.rev < 3)
1699 length -= 2; 2466 length -= 2;
1700 /* TODO: Read an N PHY Table with ID 5, length length, 2467 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1701 offset 96, width 16, and data pointer 2468 nphy->mphase_txcal_bestcoeffs);
1702 nphy->mphase_txcal_bestcoeffs */
1703 } 2469 }
1704 2470
1705 /* TODO: Call N PHY Stop Playback */ 2471 b43_nphy_stop_playback(dev);
1706 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); 2472 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
1707 } 2473 }
1708 2474
1709 /* TODO: Call N PHY TX Cal PHY Cleanup */ 2475 b43_nphy_tx_cal_phy_cleanup(dev);
1710 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2476 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
1711 width 16, and data from save */
1712 2477
1713 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) 2478 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
1714 b43_nphy_tx_iq_workaround(dev); 2479 b43_nphy_tx_iq_workaround(dev);
@@ -1739,7 +2504,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1739 u16 lna[3] = { 3, 3, 1 }; 2504 u16 lna[3] = { 3, 3, 1 };
1740 u16 hpf1[3] = { 7, 2, 0 }; 2505 u16 hpf1[3] = { 7, 2, 0 };
1741 u16 hpf2[3] = { 2, 0, 0 }; 2506 u16 hpf2[3] = { 2, 0, 0 };
1742 u32 power[3]; 2507 u32 power[3] = { };
1743 u16 gain_save[2]; 2508 u16 gain_save[2];
1744 u16 cal_gain[2]; 2509 u16 cal_gain[2];
1745 struct nphy_iqcal_params cal_params[2]; 2510 struct nphy_iqcal_params cal_params[2];
@@ -1752,14 +2517,12 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1752 2517
1753 if (dev->phy.rev < 2) 2518 if (dev->phy.rev < 2)
1754 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ 2519 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */
1755 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, 2520 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
1756 width 16, and data gain_save */
1757 for (i = 0; i < 2; i++) { 2521 for (i = 0; i < 2; i++) {
1758 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); 2522 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
1759 cal_gain[i] = cal_params[i].cal_gain; 2523 cal_gain[i] = cal_params[i].cal_gain;
1760 } 2524 }
1761 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2525 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain);
1762 width 16, and data from cal_gain */
1763 2526
1764 for (i = 0; i < 2; i++) { 2527 for (i = 0; i < 2; i++) {
1765 if (i == 0) { 2528 if (i == 0) {
@@ -1846,19 +2609,19 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1846 2609
1847 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | 2610 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
1848 (cur_lna << 2)); 2611 (cur_lna << 2));
1849 /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], 2612 b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3,
1850 3, 0 as arguments */ 2613 false);
1851 /* TODO: Call N PHY Force RF Seq with 2 as argument */ 2614 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1852 /* TODO: Call N PHT Stop Playback */ 2615 b43_nphy_stop_playback(dev);
1853 2616
1854 if (playtone) { 2617 if (playtone) {
1855 /* TODO: Call N PHY TX Tone with 4000, 2618 ret = b43_nphy_tx_tone(dev, 4000,
1856 (nphy_rxcalparams & 0xffff), 0, 0 2619 (nphy->rxcalparams & 0xFFFF),
1857 as arguments and save result as ret */ 2620 false, false);
1858 playtone = false; 2621 playtone = false;
1859 } else { 2622 } else {
1860 /* TODO: Call N PHY Run Samples with 160, 2623 b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
1861 0xFFFF, 0, 0, 0 as arguments */ 2624 false, false);
1862 } 2625 }
1863 2626
1864 if (ret == 0) { 2627 if (ret == 0) {
@@ -1876,7 +2639,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1876 } else { 2639 } else {
1877 b43_nphy_calc_rx_iq_comp(dev, 1 << i); 2640 b43_nphy_calc_rx_iq_comp(dev, 1 << i);
1878 } 2641 }
1879 /* TODO: Call N PHY Stop Playback */ 2642 b43_nphy_stop_playback(dev);
1880 } 2643 }
1881 2644
1882 if (ret != 0) 2645 if (ret != 0)
@@ -1895,10 +2658,9 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1895 break; 2658 break;
1896 } 2659 }
1897 2660
1898 /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ 2661 b43_nphy_rf_control_override(dev, 0x400, 0, 3, true);
1899 /* TODO: Call N PHY Force RF Seq with 2 as argument */ 2662 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1900 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2663 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
1901 width 16, and data from gain_save */
1902 2664
1903 b43_nphy_stay_in_carrier_search(dev, 0); 2665 b43_nphy_stay_in_carrier_search(dev, 0);
1904 2666
@@ -1990,8 +2752,8 @@ int b43_phy_initn(struct b43_wldev *dev)
1990 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); 2752 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
1991 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); 2753 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
1992 2754
1993 /* TODO MIMO-Config */ 2755 b43_nphy_update_mimo_config(dev, nphy->preamble_override);
1994 /* TODO Update TX/RX chain */ 2756 b43_nphy_update_txrx_chain(dev);
1995 2757
1996 if (phy->rev < 2) { 2758 if (phy->rev < 2) {
1997 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); 2759 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
@@ -2007,9 +2769,9 @@ int b43_phy_initn(struct b43_wldev *dev)
2007 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); 2769 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
2008 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, 2770 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
2009 nphy->papd_epsilon_offset[1] << 7); 2771 nphy->papd_epsilon_offset[1] << 7);
2010 /* TODO N PHY IPA Set TX Dig Filters */ 2772 b43_nphy_int_pa_set_tx_dig_filters(dev);
2011 } else if (phy->rev >= 5) { 2773 } else if (phy->rev >= 5) {
2012 /* TODO N PHY Ext PA Set TX Dig Filters */ 2774 b43_nphy_ext_pa_set_tx_dig_filters(dev);
2013 } 2775 }
2014 2776
2015 b43_nphy_workarounds(dev); 2777 b43_nphy_workarounds(dev);
@@ -2040,8 +2802,10 @@ int b43_phy_initn(struct b43_wldev *dev)
2040 if (phy->rev >= 3) { 2802 if (phy->rev >= 3) {
2041 /* TODO */ 2803 /* TODO */
2042 } else { 2804 } else {
2043 /* TODO Write an N PHY table with ID 26, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ 2805 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128,
2044 /* TODO Write an N PHY table with ID 27, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ 2806 b43_ntab_tx_gain_rev0_1_2);
2807 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128,
2808 b43_ntab_tx_gain_rev0_1_2);
2045 } 2809 }
2046 2810
2047 if (nphy->phyrxchain != 3) 2811 if (nphy->phyrxchain != 3)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 4572866756fc..ae82f0fc2096 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -973,6 +973,12 @@ struct b43_phy_n {
973 bool hang_avoid; 973 bool hang_avoid;
974 bool mute; 974 bool mute;
975 u16 papd_epsilon_offset[2]; 975 u16 papd_epsilon_offset[2];
976 s32 preamble_override;
977 u32 bb_mult_save;
978
979 bool gain_boost;
980 bool elna_gain_config;
981 bool band5g_pwrgain;
976 982
977 u8 mphase_cal_phase_id; 983 u8 mphase_cal_phase_id;
978 u16 mphase_txcal_cmdidx; 984 u16 mphase_txcal_cmdidx;
@@ -985,6 +991,7 @@ struct b43_phy_n {
985 bool txiqlocal_coeffsvalid; 991 bool txiqlocal_coeffsvalid;
986 struct b43_phy_n_txpwrindex txpwrindex[2]; 992 struct b43_phy_n_txpwrindex txpwrindex[2];
987 993
994 u8 txrx_chain;
988 u16 tx_rx_cal_phy_saveregs[11]; 995 u16 tx_rx_cal_phy_saveregs[11];
989 u16 tx_rx_cal_radio_saveregs[22]; 996 u16 tx_rx_cal_radio_saveregs[22];
990 997
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 7dff853ab962..a00d509150f7 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2883,6 +2883,67 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
2883 0x9084, 0x9267, 0x9056, 0x9234 2883 0x9084, 0x9267, 0x9056, 0x9234
2884}; 2884};
2885 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
2886static inline void assert_ntab_array_sizes(void) 2947static inline void assert_ntab_array_sizes(void)
2887{ 2948{
2888#undef check 2949#undef check
@@ -2919,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void)
2919#undef check 2980#undef check
2920} 2981}
2921 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
2922void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) 3049void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2923{ 3050{
2924 u32 type; 3051 u32 type;
@@ -2952,6 +3079,46 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2952 assert_ntab_array_sizes(); 3079 assert_ntab_array_sizes();
2953} 3080}
2954 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
2955#define ntab_upload(dev, offset, data) do { \ 3122#define ntab_upload(dev, offset, data) do { \
2956 unsigned int i; \ 3123 unsigned int i; \
2957 for (i = 0; i < (offset##_SIZE); i++) \ 3124 for (i = 0; i < (offset##_SIZE); i++) \
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 51636d02f8b1..9c1c6ecd3672 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -51,6 +51,22 @@ struct nphy_txiqcal_ladder {
51 u8 g_env; 51 u8 g_env;
52}; 52};
53 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
54/* Upload the default register value table. 70/* Upload the default register value table.
55 * 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
56 * 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
@@ -142,7 +158,12 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
142#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 158#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10
143#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 159#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12
144 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);
145void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); 164void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
165void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
166 unsigned int nr_elements, const void *_data);
146 167
147void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); 168void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
148void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); 169void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
@@ -172,5 +193,11 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
172extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; 193extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
173extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; 194extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
174extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; 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[];
175 202
176#endif /* B43_TABLES_NPHY_H_ */ 203#endif /* B43_TABLES_NPHY_H_ */
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 0db1fda94a65..9d1820676f30 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,
@@ -106,6 +176,7 @@ static struct iwl_lib_ops iwl1000_lib = {
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,
108 .dump_csr = iwl_dump_csr, 178 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh,
109 .init_alive_start = iwl5000_init_alive_start, 180 .init_alive_start = iwl5000_init_alive_start,
110 .alive_notify = iwl5000_alive_notify, 181 .alive_notify = iwl5000_alive_notify,
111 .send_tx_power = iwl5000_send_tx_power, 182 .send_tx_power = iwl5000_send_tx_power,
@@ -139,6 +210,7 @@ static struct iwl_lib_ops iwl1000_lib = {
139 .temperature = iwl5000_temperature, 210 .temperature = iwl5000_temperature,
140 .set_ct_kill = iwl1000_set_ct_threshold, 211 .set_ct_kill = iwl1000_set_ct_threshold,
141 }, 212 },
213 .add_bcast_station = iwl_add_bcast_station,
142}; 214};
143 215
144static const struct iwl_ops iwl1000_ops = { 216static const struct iwl_ops iwl1000_ops = {
@@ -174,6 +246,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
174 .use_rts_for_ht = true, /* use rts/cts protection */ 246 .use_rts_for_ht = true, /* use rts/cts protection */
175 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
176 .support_ct_kill_exit = true, 248 .support_ct_kill_exit = true,
249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
177}; 250};
178 251
179struct iwl_cfg iwl1000_bg_cfg = { 252struct iwl_cfg iwl1000_bg_cfg = {
@@ -200,6 +273,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
200 .led_compensation = 51, 273 .led_compensation = 51,
201 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 274 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
202 .support_ct_kill_exit = true, 275 .support_ct_kill_exit = true,
276 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
203}; 277};
204 278
205MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 279MODULE_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 6cde661ce0bc..6940f086823c 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
@@ -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 */
@@ -2796,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2796 .post_associate = iwl3945_post_associate, 2792 .post_associate = iwl3945_post_associate,
2797 .isr = iwl_isr_legacy, 2793 .isr = iwl_isr_legacy,
2798 .config_ap = iwl3945_config_ap, 2794 .config_ap = iwl3945_config_ap,
2795 .add_bcast_station = iwl3945_add_bcast_station,
2799}; 2796};
2800 2797
2801static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2798static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2830,6 +2827,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2830 .ht_greenfield_support = false, 2827 .ht_greenfield_support = false,
2831 .led_compensation = 64, 2828 .led_compensation = 64,
2832 .broken_powersave = true, 2829 .broken_powersave = true,
2830 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2833}; 2831};
2834 2832
2835static struct iwl_cfg iwl3945_abg_cfg = { 2833static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,6 +2845,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2847 .ht_greenfield_support = false, 2845 .ht_greenfield_support = false,
2848 .led_compensation = 64, 2846 .led_compensation = 64,
2849 .broken_powersave = true, 2847 .broken_powersave = true,
2848 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2850}; 2849};
2851 2850
2852DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2851DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bc532ff4f883..8f553f36d270 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
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 6a004abb5973..aebe8c51d3e1 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
@@ -2206,6 +2206,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2206 .temperature = iwl4965_temperature_calib, 2206 .temperature = iwl4965_temperature_calib,
2207 .set_ct_kill = iwl4965_set_ct_threshold, 2207 .set_ct_kill = iwl4965_set_ct_threshold,
2208 }, 2208 },
2209 .add_bcast_station = iwl_add_bcast_station,
2209}; 2210};
2210 2211
2211static const struct iwl_ops iwl4965_ops = { 2212static const struct iwl_ops iwl4965_ops = {
@@ -2239,6 +2240,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2240 .broken_powersave = true,
2240 .led_compensation = 61, 2241 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2242 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2243 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2242}; 2244};
2243 2245
2244/* Module firmware */ 2246/* 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 c6120f0b8f98..6d5988901341 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
@@ -263,8 +263,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
263 263
264 .auto_corr_max_ofdm = 120, 264 .auto_corr_max_ofdm = 120,
265 .auto_corr_max_ofdm_mrc = 210, 265 .auto_corr_max_ofdm_mrc = 210,
266 .auto_corr_max_ofdm_x1 = 155, 266 .auto_corr_max_ofdm_x1 = 120,
267 .auto_corr_max_ofdm_mrc_x1 = 290, 267 .auto_corr_max_ofdm_mrc_x1 = 240,
268 268
269 .auto_corr_min_cck = 125, 269 .auto_corr_min_cck = 125,
270 .auto_corr_max_cck = 200, 270 .auto_corr_max_cck = 200,
@@ -412,12 +412,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
412/* 412/*
413 * ucode 413 * ucode
414 */ 414 */
415static int iwl5000_load_section(struct iwl_priv *priv, 415static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
416 struct fw_desc *image, 416 struct fw_desc *image, u32 dst_addr)
417 u32 dst_addr)
418{ 417{
419 dma_addr_t phy_addr = image->p_addr; 418 dma_addr_t phy_addr = image->p_addr;
420 u32 byte_cnt = image->len; 419 u32 byte_cnt = image->len;
420 int ret;
421
422 priv->ucode_write_complete = 0;
421 423
422 iwl_write_direct32(priv, 424 iwl_write_direct32(priv,
423 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 425 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +449,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
447 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 449 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
448 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 450 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
449 451
450 return 0; 452 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, 453 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
466 priv->ucode_write_complete, 5 * HZ); 454 priv->ucode_write_complete, 5 * HZ);
467 if (ret == -ERESTARTSYS) { 455 if (ret == -ERESTARTSYS) {
468 IWL_ERR(priv, "Could not load the INST uCode section due " 456 IWL_ERR(priv, "Could not load the %s uCode section due "
469 "to interrupt\n"); 457 "to interrupt\n", name);
470 return ret; 458 return ret;
471 } 459 }
472 if (!ret) { 460 if (!ret) {
473 IWL_ERR(priv, "Could not load the INST uCode section\n"); 461 IWL_ERR(priv, "Could not load the %s uCode section\n",
462 name);
474 return -ETIMEDOUT; 463 return -ETIMEDOUT;
475 } 464 }
476 465
477 priv->ucode_write_complete = 0; 466 return 0;
478 467}
479 ret = iwl5000_load_section(
480 priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
481 if (ret)
482 return ret;
483 468
484 IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); 469static int iwl5000_load_given_ucode(struct iwl_priv *priv,
470 struct fw_desc *inst_image,
471 struct fw_desc *data_image)
472{
473 int ret = 0;
485 474
486 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 475 ret = iwl5000_load_section(priv, "INST", inst_image,
487 priv->ucode_write_complete, 5 * HZ); 476 IWL50_RTC_INST_LOWER_BOUND);
488 if (ret == -ERESTARTSYS) { 477 if (ret)
489 IWL_ERR(priv, "Could not load the INST uCode section due "
490 "to interrupt\n");
491 return ret; 478 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
498 priv->ucode_write_complete = 0;
499 479
500 return ret; 480 return iwl5000_load_section(priv, "DATA", data_image,
481 IWL50_RTC_DATA_LOWER_BOUND);
501} 482}
502 483
503int iwl5000_load_ucode(struct iwl_priv *priv) 484int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -1467,6 +1448,7 @@ struct iwl_lib_ops iwl5000_lib = {
1467 .dump_nic_event_log = iwl_dump_nic_event_log, 1448 .dump_nic_event_log = iwl_dump_nic_event_log,
1468 .dump_nic_error_log = iwl_dump_nic_error_log, 1449 .dump_nic_error_log = iwl_dump_nic_error_log,
1469 .dump_csr = iwl_dump_csr, 1450 .dump_csr = iwl_dump_csr,
1451 .dump_fh = iwl_dump_fh,
1470 .load_ucode = iwl5000_load_ucode, 1452 .load_ucode = iwl5000_load_ucode,
1471 .init_alive_start = iwl5000_init_alive_start, 1453 .init_alive_start = iwl5000_init_alive_start,
1472 .alive_notify = iwl5000_alive_notify, 1454 .alive_notify = iwl5000_alive_notify,
@@ -1502,6 +1484,7 @@ struct iwl_lib_ops iwl5000_lib = {
1502 .temperature = iwl5000_temperature, 1484 .temperature = iwl5000_temperature,
1503 .set_ct_kill = iwl5000_set_ct_threshold, 1485 .set_ct_kill = iwl5000_set_ct_threshold,
1504 }, 1486 },
1487 .add_bcast_station = iwl_add_bcast_station,
1505}; 1488};
1506 1489
1507static struct iwl_lib_ops iwl5150_lib = { 1490static struct iwl_lib_ops iwl5150_lib = {
@@ -1555,6 +1538,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1555 .temperature = iwl5150_temperature, 1538 .temperature = iwl5150_temperature,
1556 .set_ct_kill = iwl5150_set_ct_threshold, 1539 .set_ct_kill = iwl5150_set_ct_threshold,
1557 }, 1540 },
1541 .add_bcast_station = iwl_add_bcast_station,
1558}; 1542};
1559 1543
1560static const struct iwl_ops iwl5000_ops = { 1544static const struct iwl_ops iwl5000_ops = {
@@ -1602,6 +1586,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
1602 .led_compensation = 51, 1586 .led_compensation = 51,
1603 .use_rts_for_ht = true, /* use rts/cts protection */ 1587 .use_rts_for_ht = true, /* use rts/cts protection */
1604 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1588 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1589 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605}; 1590};
1606 1591
1607struct iwl_cfg iwl5100_bgn_cfg = { 1592struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1626,6 +1611,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1626 .led_compensation = 51, 1611 .led_compensation = 51,
1627 .use_rts_for_ht = true, /* use rts/cts protection */ 1612 .use_rts_for_ht = true, /* use rts/cts protection */
1628 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1613 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1614 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1629}; 1615};
1630 1616
1631struct iwl_cfg iwl5100_abg_cfg = { 1617struct iwl_cfg iwl5100_abg_cfg = {
@@ -1648,6 +1634,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
1648 .use_bsm = false, 1634 .use_bsm = false,
1649 .led_compensation = 51, 1635 .led_compensation = 51,
1650 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1636 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1637 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1651}; 1638};
1652 1639
1653struct iwl_cfg iwl5100_agn_cfg = { 1640struct iwl_cfg iwl5100_agn_cfg = {
@@ -1672,6 +1659,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
1672 .led_compensation = 51, 1659 .led_compensation = 51,
1673 .use_rts_for_ht = true, /* use rts/cts protection */ 1660 .use_rts_for_ht = true, /* use rts/cts protection */
1674 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1661 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1662 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1675}; 1663};
1676 1664
1677struct iwl_cfg iwl5350_agn_cfg = { 1665struct iwl_cfg iwl5350_agn_cfg = {
@@ -1696,6 +1684,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
1696 .led_compensation = 51, 1684 .led_compensation = 51,
1697 .use_rts_for_ht = true, /* use rts/cts protection */ 1685 .use_rts_for_ht = true, /* use rts/cts protection */
1698 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1686 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1699}; 1688};
1700 1689
1701struct iwl_cfg iwl5150_agn_cfg = { 1690struct iwl_cfg iwl5150_agn_cfg = {
@@ -1720,6 +1709,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1720 .led_compensation = 51, 1709 .led_compensation = 51,
1721 .use_rts_for_ht = true, /* use rts/cts protection */ 1710 .use_rts_for_ht = true, /* use rts/cts protection */
1722 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1711 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1712 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1723}; 1713};
1724 1714
1725struct iwl_cfg iwl5150_abg_cfg = { 1715struct iwl_cfg iwl5150_abg_cfg = {
@@ -1742,6 +1732,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
1742 .use_bsm = false, 1732 .use_bsm = false,
1743 .led_compensation = 51, 1733 .led_compensation = 51,
1744 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1734 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1735 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1745}; 1736};
1746 1737
1747MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1738MODULE_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 a5a0ed4817a4..a9f8551e0e40 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
@@ -108,7 +108,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
108 108
109 .auto_corr_max_ofdm = 145, 109 .auto_corr_max_ofdm = 145,
110 .auto_corr_max_ofdm_mrc = 232, 110 .auto_corr_max_ofdm_mrc = 232,
111 .auto_corr_max_ofdm_x1 = 145, 111 .auto_corr_max_ofdm_x1 = 110,
112 .auto_corr_max_ofdm_mrc_x1 = 232, 112 .auto_corr_max_ofdm_mrc_x1 = 232,
113 113
114 .auto_corr_min_cck = 125, 114 .auto_corr_min_cck = 125,
@@ -158,11 +158,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
158 /* Set initial sensitivity parameters */ 158 /* Set initial sensitivity parameters */
159 /* Set initial calibration set */ 159 /* Set initial calibration set */
160 priv->hw_params.sens = &iwl6000_sensitivity; 160 priv->hw_params.sens = &iwl6000_sensitivity;
161 priv->hw_params.calib_init_cfg = 161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
162 case CSR_HW_REV_TYPE_6x50:
163 priv->hw_params.calib_init_cfg =
162 BIT(IWL_CALIB_XTAL) | 164 BIT(IWL_CALIB_XTAL) |
165 BIT(IWL_CALIB_DC) |
163 BIT(IWL_CALIB_LO) | 166 BIT(IWL_CALIB_LO) |
164 BIT(IWL_CALIB_TX_IQ) | 167 BIT(IWL_CALIB_TX_IQ) |
165 BIT(IWL_CALIB_BASE_BAND); 168 BIT(IWL_CALIB_BASE_BAND);
169
170 break;
171 default:
172 priv->hw_params.calib_init_cfg =
173 BIT(IWL_CALIB_XTAL) |
174 BIT(IWL_CALIB_LO) |
175 BIT(IWL_CALIB_TX_IQ) |
176 BIT(IWL_CALIB_BASE_BAND);
177 break;
178 }
179
166 return 0; 180 return 0;
167} 181}
168 182
@@ -216,6 +230,7 @@ static struct iwl_lib_ops iwl6000_lib = {
216 .dump_nic_event_log = iwl_dump_nic_event_log, 230 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 231 .dump_nic_error_log = iwl_dump_nic_error_log,
218 .dump_csr = iwl_dump_csr, 232 .dump_csr = iwl_dump_csr,
233 .dump_fh = iwl_dump_fh,
219 .init_alive_start = iwl5000_init_alive_start, 234 .init_alive_start = iwl5000_init_alive_start,
220 .alive_notify = iwl5000_alive_notify, 235 .alive_notify = iwl5000_alive_notify,
221 .send_tx_power = iwl5000_send_tx_power, 236 .send_tx_power = iwl5000_send_tx_power,
@@ -251,6 +266,7 @@ static struct iwl_lib_ops iwl6000_lib = {
251 .temperature = iwl5000_temperature, 266 .temperature = iwl5000_temperature,
252 .set_ct_kill = iwl6000_set_ct_threshold, 267 .set_ct_kill = iwl6000_set_ct_threshold,
253 }, 268 },
269 .add_bcast_station = iwl_add_bcast_station,
254}; 270};
255 271
256static const struct iwl_ops iwl6000_ops = { 272static const struct iwl_ops iwl6000_ops = {
@@ -307,6 +323,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
307 .supports_idle = true, 323 .supports_idle = true,
308 .adv_thermal_throttle = true, 324 .adv_thermal_throttle = true,
309 .support_ct_kill_exit = true, 325 .support_ct_kill_exit = true,
326 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
310}; 327};
311 328
312struct iwl_cfg iwl6000i_2abg_cfg = { 329struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -336,6 +353,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
336 .supports_idle = true, 353 .supports_idle = true,
337 .adv_thermal_throttle = true, 354 .adv_thermal_throttle = true,
338 .support_ct_kill_exit = true, 355 .support_ct_kill_exit = true,
356 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
339}; 357};
340 358
341struct iwl_cfg iwl6000i_2bg_cfg = { 359struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -365,6 +383,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
365 .supports_idle = true, 383 .supports_idle = true,
366 .adv_thermal_throttle = true, 384 .adv_thermal_throttle = true,
367 .support_ct_kill_exit = true, 385 .support_ct_kill_exit = true,
386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
368}; 387};
369 388
370struct iwl_cfg iwl6050_2agn_cfg = { 389struct iwl_cfg iwl6050_2agn_cfg = {
@@ -395,6 +414,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 414 .supports_idle = true,
396 .adv_thermal_throttle = true, 415 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 416 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
398}; 418};
399 419
400struct iwl_cfg iwl6050_2abg_cfg = { 420struct iwl_cfg iwl6050_2abg_cfg = {
@@ -424,6 +444,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
424 .supports_idle = true, 444 .supports_idle = true,
425 .adv_thermal_throttle = true, 445 .adv_thermal_throttle = true,
426 .support_ct_kill_exit = true, 446 .support_ct_kill_exit = true,
447 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
427}; 448};
428 449
429struct iwl_cfg iwl6000_3agn_cfg = { 450struct iwl_cfg iwl6000_3agn_cfg = {
@@ -454,6 +475,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
454 .supports_idle = true, 475 .supports_idle = true,
455 .adv_thermal_throttle = true, 476 .adv_thermal_throttle = true,
456 .support_ct_kill_exit = true, 477 .support_ct_kill_exit = true,
478 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
457}; 479};
458 480
459MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 481MODULE_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..6aebcedaca8d 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
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 344e99de4cab..d0268280d679 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 */
@@ -704,7 +699,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
704 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 699 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
705} 700}
706 701
707void iwl_continuous_event_trace(struct iwl_priv *priv) 702static void iwl_continuous_event_trace(struct iwl_priv *priv)
708{ 703{
709 u32 capacity; /* event log capacity in # entries */ 704 u32 capacity; /* event log capacity in # entries */
710 u32 base; /* SRAM byte address of event log header */ 705 u32 base; /* SRAM byte address of event log header */
@@ -888,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
888 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 883 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
889 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 884 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
890 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;
891 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 888 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
892 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 889 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
893 iwl_rx_pm_debug_statistics_notif; 890 iwl_rx_pm_debug_statistics_notif;
@@ -901,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
901 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; 898 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
902 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 899 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
903 900
904 iwl_setup_spectrum_handlers(priv);
905 iwl_setup_rx_scan_handlers(priv); 901 iwl_setup_rx_scan_handlers(priv);
906 902
907 /* status change handler */ 903 /* status change handler */
@@ -1761,7 +1757,7 @@ static const char *desc_lookup_text[] = {
1761 "DEBUG_1", 1757 "DEBUG_1",
1762 "DEBUG_2", 1758 "DEBUG_2",
1763 "DEBUG_3", 1759 "DEBUG_3",
1764 "UNKNOWN" 1760 "ADVANCED SYSASSERT"
1765}; 1761};
1766 1762
1767static const char *desc_lookup(int i) 1763static const char *desc_lookup(int i)
@@ -1965,7 +1961,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1965 IWL_ERR(priv, 1961 IWL_ERR(priv,
1966 "Invalid event log pointer 0x%08X for %s uCode\n", 1962 "Invalid event log pointer 0x%08X for %s uCode\n",
1967 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1963 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1968 return pos; 1964 return -EINVAL;
1969 } 1965 }
1970 1966
1971 /* event log header */ 1967 /* event log header */
@@ -2013,7 +2009,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2013 bufsz = size * 48; 2009 bufsz = size * 48;
2014 *buf = kmalloc(bufsz, GFP_KERNEL); 2010 *buf = kmalloc(bufsz, GFP_KERNEL);
2015 if (!*buf) 2011 if (!*buf)
2016 return pos; 2012 return -ENOMEM;
2017 } 2013 }
2018 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) {
2019 /* 2015 /*
@@ -2443,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2443 return; 2439 return;
2444} 2440}
2445 2441
2446static void iwl_bg_up(struct work_struct *data)
2447{
2448 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
2449
2450 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2451 return;
2452
2453 mutex_lock(&priv->mutex);
2454 __iwl_up(priv);
2455 mutex_unlock(&priv->mutex);
2456}
2457
2458static void iwl_bg_restart(struct work_struct *data) 2442static void iwl_bg_restart(struct work_struct *data)
2459{ 2443{
2460 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 2444 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2471,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data)
2471 ieee80211_restart_hw(priv->hw); 2455 ieee80211_restart_hw(priv->hw);
2472 } else { 2456 } else {
2473 iwl_down(priv); 2457 iwl_down(priv);
2474 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);
2475 } 2465 }
2476} 2466}
2477 2467
@@ -2607,7 +2597,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2607 * 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
2608 * other mac80211 functions grouped here. 2598 * other mac80211 functions grouped here.
2609 */ 2599 */
2610static int iwl_setup_mac(struct iwl_priv *priv) 2600static int iwl_mac_setup_register(struct iwl_priv *priv)
2611{ 2601{
2612 int ret; 2602 int ret;
2613 struct ieee80211_hw *hw = priv->hw; 2603 struct ieee80211_hw *hw = priv->hw;
@@ -2839,14 +2829,18 @@ void iwl_config_ap(struct iwl_priv *priv)
2839} 2829}
2840 2830
2841static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, 2831static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2842 struct ieee80211_key_conf *keyconf, const u8 *addr, 2832 struct ieee80211_vif *vif,
2843 u32 iv32, u16 *phase1key) 2833 struct ieee80211_key_conf *keyconf,
2834 struct ieee80211_sta *sta,
2835 u32 iv32, u16 *phase1key)
2844{ 2836{
2845 2837
2846 struct iwl_priv *priv = hw->priv; 2838 struct iwl_priv *priv = hw->priv;
2847 IWL_DEBUG_MAC80211(priv, "enter\n"); 2839 IWL_DEBUG_MAC80211(priv, "enter\n");
2848 2840
2849 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);
2850 2844
2851 IWL_DEBUG_MAC80211(priv, "leave\n"); 2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2852} 2846}
@@ -3007,6 +3001,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3007 break; 3001 break;
3008 case STA_NOTIFY_AWAKE: 3002 case STA_NOTIFY_AWAKE:
3009 WARN_ON(!sta_priv->client); 3003 WARN_ON(!sta_priv->client);
3004 if (!sta_priv->asleep)
3005 break;
3010 sta_priv->asleep = false; 3006 sta_priv->asleep = false;
3011 sta_id = iwl_find_station(priv, sta->addr); 3007 sta_id = iwl_find_station(priv, sta->addr);
3012 if (sta_id != IWL_INVALID_STATION) 3008 if (sta_id != IWL_INVALID_STATION)
@@ -3283,7 +3279,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3283 3279
3284 init_waitqueue_head(&priv->wait_command_queue); 3280 init_waitqueue_head(&priv->wait_command_queue);
3285 3281
3286 INIT_WORK(&priv->up, iwl_bg_up);
3287 INIT_WORK(&priv->restart, iwl_bg_restart); 3282 INIT_WORK(&priv->restart, iwl_bg_restart);
3288 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3283 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3289 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3284 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
@@ -3368,6 +3363,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3368 3363
3369 priv->iw_mode = NL80211_IFTYPE_STATION; 3364 priv->iw_mode = NL80211_IFTYPE_STATION;
3370 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 3365 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3366 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3371 3367
3372 /* Choose which receivers/antennas to use */ 3368 /* Choose which receivers/antennas to use */
3373 if (priv->cfg->ops->hcmd->set_rxon_chain) 3369 if (priv->cfg->ops->hcmd->set_rxon_chain)
@@ -3619,9 +3615,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3619 iwl_setup_deferred_work(priv); 3615 iwl_setup_deferred_work(priv);
3620 iwl_setup_rx_handlers(priv); 3616 iwl_setup_rx_handlers(priv);
3621 3617
3622 /********************************** 3618 /*********************************************
3623 * 8. Setup and register mac80211 3619 * 8. Enable interrupts and read RFKILL state
3624 **********************************/ 3620 *********************************************/
3625 3621
3626 /* enable interrupts if needed: hw bug w/a */ 3622 /* enable interrupts if needed: hw bug w/a */
3627 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); 3623 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
@@ -3632,14 +3628,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3632 3628
3633 iwl_enable_interrupts(priv); 3629 iwl_enable_interrupts(priv);
3634 3630
3635 err = iwl_setup_mac(priv);
3636 if (err)
3637 goto out_remove_sysfs;
3638
3639 err = iwl_dbgfs_register(priv, DRV_NAME);
3640 if (err)
3641 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3642
3643 /* If platform's RF_KILL switch is NOT set to KILL */ 3631 /* If platform's RF_KILL switch is NOT set to KILL */
3644 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) 3632 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
3645 clear_bit(STATUS_RF_KILL_HW, &priv->status); 3633 clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -3651,6 +3639,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3651 3639
3652 iwl_power_initialize(priv); 3640 iwl_power_initialize(priv);
3653 iwl_tt_initialize(priv); 3641 iwl_tt_initialize(priv);
3642
3643 /**************************************************
3644 * 9. Setup and register with mac80211 and debugfs
3645 **************************************************/
3646 err = iwl_mac_setup_register(priv);
3647 if (err)
3648 goto out_remove_sysfs;
3649
3650 err = iwl_dbgfs_register(priv, DRV_NAME);
3651 if (err)
3652 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3653
3654 return 0; 3654 return 0;
3655 3655
3656 out_remove_sysfs: 3656 out_remove_sysfs:
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index dc61906290e8..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
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 3320cce3d57b..c2f31eb26bef 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
@@ -2247,10 +2247,22 @@ struct iwl_link_quality_cmd {
2247 __le32 reserved2; 2247 __le32 reserved2;
2248} __attribute__ ((packed)); 2248} __attribute__ ((packed));
2249 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
2250#define BT_COEX_DISABLE (0x0) 2264#define BT_COEX_DISABLE (0x0)
2251#define BT_COEX_MODE_2W (0x1) 2265#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
2252#define BT_COEX_MODE_3W (0x2)
2253#define BT_COEX_MODE_4W (0x3)
2254 2266
2255#define BT_LEAD_TIME_MIN (0x0) 2267#define BT_LEAD_TIME_MIN (0x0)
2256#define BT_LEAD_TIME_DEF (0x1E) 2268#define BT_LEAD_TIME_DEF (0x1E)
@@ -3095,7 +3107,12 @@ struct statistics_general {
3095 __le32 ttl_timestamp; 3107 __le32 ttl_timestamp;
3096 struct statistics_div div; 3108 struct statistics_div div;
3097 __le32 rx_enable_counter; 3109 __le32 rx_enable_counter;
3098 __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;
3099 __le32 reserved2; 3116 __le32 reserved2;
3100 __le32 reserved3; 3117 __le32 reserved3;
3101} __attribute__ ((packed)); 3118} __attribute__ ((packed));
@@ -3160,13 +3177,30 @@ struct iwl_notif_statistics {
3160 3177
3161/* 3178/*
3162 * 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 *
3163 */ 3196 */
3164/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, 3197
3165 * then this notification will be sent. */ 3198#define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
3166#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
3167 3201
3168struct iwl_missed_beacon_notif { 3202struct iwl_missed_beacon_notif {
3169 __le32 consequtive_missed_beacons; 3203 __le32 consecutive_missed_beacons;
3170 __le32 total_missed_becons; 3204 __le32 total_missed_becons;
3171 __le32 num_expected_beacons; 3205 __le32 num_expected_beacons;
3172 __le32 num_recvd_beacons; 3206 __le32 num_recvd_beacons;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5b56307a3812..02bf17ecaf54 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
@@ -1353,6 +1373,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1353 priv->cfg->ops->lib->dump_nic_error_log(priv); 1373 priv->cfg->ops->lib->dump_nic_error_log(priv);
1354 if (priv->cfg->ops->lib->dump_csr) 1374 if (priv->cfg->ops->lib->dump_csr)
1355 priv->cfg->ops->lib->dump_csr(priv); 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);
1356 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); 1378 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1357#ifdef CONFIG_IWLWIFI_DEBUG 1379#ifdef CONFIG_IWLWIFI_DEBUG
1358 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1380 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
@@ -1803,6 +1825,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1803 if (val == 0xffffffff) 1825 if (val == 0xffffffff)
1804 val = 0; 1826 val = 0;
1805 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
1806 inta = (0xff & val) | ((0xff00 & val) << 16); 1838 inta = (0xff & val) | ((0xff00 & val) << 16);
1807 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",
1808 inta, inta_mask, val); 1840 inta, inta_mask, val);
@@ -1965,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
1965int iwl_send_bt_config(struct iwl_priv *priv) 1997int iwl_send_bt_config(struct iwl_priv *priv)
1966{ 1998{
1967 struct iwl_bt_cmd bt_cmd = { 1999 struct iwl_bt_cmd bt_cmd = {
1968 .flags = BT_COEX_MODE_4W,
1969 .lead_time = BT_LEAD_TIME_DEF, 2000 .lead_time = BT_LEAD_TIME_DEF,
1970 .max_kill = BT_MAX_KILL_DEF, 2001 .max_kill = BT_MAX_KILL_DEF,
1971 .kill_ack_mask = 0, 2002 .kill_ack_mask = 0,
1972 .kill_cts_mask = 0, 2003 .kill_cts_mask = 0,
1973 }; 2004 };
1974 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
1975 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, 2014 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
1976 sizeof(struct iwl_bt_cmd), &bt_cmd); 2015 sizeof(struct iwl_bt_cmd), &bt_cmd);
1977} 2016}
@@ -2592,23 +2631,21 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2592 struct ieee80211_vif *vif) 2631 struct ieee80211_vif *vif)
2593{ 2632{
2594 struct iwl_priv *priv = hw->priv; 2633 struct iwl_priv *priv = hw->priv;
2595 unsigned long flags; 2634 int err = 0;
2596 2635
2597 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type); 2636 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
2598 2637
2638 mutex_lock(&priv->mutex);
2639
2599 if (priv->vif) { 2640 if (priv->vif) {
2600 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2641 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2601 return -EOPNOTSUPP; 2642 err = -EOPNOTSUPP;
2643 goto out;
2602 } 2644 }
2603 2645
2604 spin_lock_irqsave(&priv->lock, flags);
2605 priv->vif = vif; 2646 priv->vif = vif;
2606 priv->iw_mode = vif->type; 2647 priv->iw_mode = vif->type;
2607 2648
2608 spin_unlock_irqrestore(&priv->lock, flags);
2609
2610 mutex_lock(&priv->mutex);
2611
2612 if (vif->addr) { 2649 if (vif->addr) {
2613 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); 2650 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2614 memcpy(priv->mac_addr, vif->addr, ETH_ALEN); 2651 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
@@ -2618,10 +2655,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2618 /* we are not ready, will run again when ready */ 2655 /* we are not ready, will run again when ready */
2619 set_bit(STATUS_MODE_PENDING, &priv->status); 2656 set_bit(STATUS_MODE_PENDING, &priv->status);
2620 2657
2658 out:
2621 mutex_unlock(&priv->mutex); 2659 mutex_unlock(&priv->mutex);
2622 2660
2623 IWL_DEBUG_MAC80211(priv, "leave\n"); 2661 IWL_DEBUG_MAC80211(priv, "leave\n");
2624 return 0; 2662 return err;
2625} 2663}
2626EXPORT_SYMBOL(iwl_mac_add_interface); 2664EXPORT_SYMBOL(iwl_mac_add_interface);
2627 2665
@@ -3268,6 +3306,93 @@ void iwl_dump_csr(struct iwl_priv *priv)
3268} 3306}
3269EXPORT_SYMBOL(iwl_dump_csr); 3307EXPORT_SYMBOL(iwl_dump_csr);
3270 3308
3309const static char *get_fh_string(int cmd)
3310{
3311 switch (cmd) {
3312 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
3313 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
3314 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
3315 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
3316 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
3317 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
3318 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
3319 IWL_CMD(FH_TSSR_TX_STATUS_REG);
3320 IWL_CMD(FH_TSSR_TX_ERROR_REG);
3321 default:
3322 return "UNKNOWN";
3323
3324 }
3325}
3326
3327int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
3328{
3329 int i;
3330#ifdef CONFIG_IWLWIFI_DEBUG
3331 int pos = 0;
3332 size_t bufsz = 0;
3333#endif
3334 u32 fh_tbl[] = {
3335 FH_RSCSR_CHNL0_STTS_WPTR_REG,
3336 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
3337 FH_RSCSR_CHNL0_WPTR,
3338 FH_MEM_RCSR_CHNL0_CONFIG_REG,
3339 FH_MEM_RSSR_SHARED_CTRL_REG,
3340 FH_MEM_RSSR_RX_STATUS_REG,
3341 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
3342 FH_TSSR_TX_STATUS_REG,
3343 FH_TSSR_TX_ERROR_REG
3344 };
3345#ifdef CONFIG_IWLWIFI_DEBUG
3346 if (display) {
3347 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
3348 *buf = kmalloc(bufsz, GFP_KERNEL);
3349 if (!*buf)
3350 return -ENOMEM;
3351 pos += scnprintf(*buf + pos, bufsz - pos,
3352 "FH register values:\n");
3353 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3354 pos += scnprintf(*buf + pos, bufsz - pos,
3355 " %34s: 0X%08x\n",
3356 get_fh_string(fh_tbl[i]),
3357 iwl_read_direct32(priv, fh_tbl[i]));
3358 }
3359 return pos;
3360 }
3361#endif
3362 IWL_ERR(priv, "FH register values:\n");
3363 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3364 IWL_ERR(priv, " %34s: 0X%08x\n",
3365 get_fh_string(fh_tbl[i]),
3366 iwl_read_direct32(priv, fh_tbl[i]));
3367 }
3368 return 0;
3369}
3370EXPORT_SYMBOL(iwl_dump_fh);
3371
3372void iwl_force_rf_reset(struct iwl_priv *priv)
3373{
3374 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3375 return;
3376
3377 if (!iwl_is_associated(priv)) {
3378 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
3379 return;
3380 }
3381 /*
3382 * There is no easy and better way to force reset the radio,
3383 * the only known method is switching channel which will force to
3384 * reset and tune the radio.
3385 * Use internal short scan (single channel) operation to should
3386 * achieve this objective.
3387 * Driver should reset the radio when number of consecutive missed
3388 * beacon, or any other uCode error condition detected.
3389 */
3390 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
3391 iwl_internal_short_hw_scan(priv);
3392 return;
3393}
3394EXPORT_SYMBOL(iwl_force_rf_reset);
3395
3271#ifdef CONFIG_PM 3396#ifdef CONFIG_PM
3272 3397
3273int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3398int 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 8deb83bfe182..ec1fe1d7cc9a 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
@@ -71,7 +71,7 @@ struct iwl_cmd;
71 71
72 72
73#define IWLWIFI_VERSION "in-tree:" 73#define IWLWIFI_VERSION "in-tree:"
74#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
75#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
76 76
77#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 77#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -171,6 +171,7 @@ struct iwl_lib_ops {
171 bool full_log, char **buf, bool display); 171 bool full_log, char **buf, bool display);
172 void (*dump_nic_error_log)(struct iwl_priv *priv); 172 void (*dump_nic_error_log)(struct iwl_priv *priv);
173 void (*dump_csr)(struct iwl_priv *priv); 173 void (*dump_csr)(struct iwl_priv *priv);
174 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 175 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 176 /* power management */
176 struct iwl_apm_ops apm_ops; 177 struct iwl_apm_ops apm_ops;
@@ -187,6 +188,8 @@ struct iwl_lib_ops {
187 188
188 /* temperature */ 189 /* temperature */
189 struct iwl_temp_ops temp_ops; 190 struct iwl_temp_ops temp_ops;
191 /* station management */
192 void (*add_bcast_station)(struct iwl_priv *priv);
190}; 193};
191 194
192struct iwl_led_ops { 195struct iwl_led_ops {
@@ -231,6 +234,8 @@ struct iwl_mod_params {
231 * @adv_thermal_throttle: support advance thermal throttle 234 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 235 * @support_ct_kill_exit: support ct kill exit condition
233 * @support_wimax_coexist: support wimax/wifi co-exist 236 * @support_wimax_coexist: support wimax/wifi co-exist
237 * @plcp_delta_threshold: plcp error rate threshold used to trigger
238 * radio tuning when there is a high receiving plcp error rate
234 * 239 *
235 * We enable the driver to be backward compatible wrt API version. The 240 * We enable the driver to be backward compatible wrt API version. The
236 * driver specifies which APIs it supports (with @ucode_api_max being the 241 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -287,6 +292,7 @@ struct iwl_cfg {
287 bool adv_thermal_throttle; 292 bool adv_thermal_throttle;
288 bool support_ct_kill_exit; 293 bool support_ct_kill_exit;
289 const bool support_wimax_coexist; 294 const bool support_wimax_coexist;
295 u8 plcp_delta_threshold;
290}; 296};
291 297
292/*************************** 298/***************************
@@ -423,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
423/* Handlers */ 429/* Handlers */
424void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 430void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
425 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);
426void iwl_rx_statistics(struct iwl_priv *priv, 434void iwl_rx_statistics(struct iwl_priv *priv,
427 struct iwl_rx_mem_buffer *rxb); 435 struct iwl_rx_mem_buffer *rxb);
428void iwl_reply_statistics(struct iwl_priv *priv, 436void iwl_reply_statistics(struct iwl_priv *priv,
@@ -493,6 +501,8 @@ void iwl_init_scan_params(struct iwl_priv *priv);
493int iwl_scan_cancel(struct iwl_priv *priv); 501int iwl_scan_cancel(struct iwl_priv *priv);
494int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 502int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
495int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 503int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
504int iwl_internal_short_hw_scan(struct iwl_priv *priv);
505void iwl_force_rf_reset(struct iwl_priv *priv);
496u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 506u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
497 const u8 *ie, int ie_len, int left); 507 const u8 *ie, int ie_len, int left);
498void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 508void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@ -523,14 +533,6 @@ int iwl_send_calib_results(struct iwl_priv *priv);
523int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); 533int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
524void iwl_calib_free_results(struct iwl_priv *priv); 534void iwl_calib_free_results(struct iwl_priv *priv);
525 535
526/*******************************************************************************
527 * Spectrum Measureemtns in iwl-spectrum.c
528 ******************************************************************************/
529#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
530void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
531#else
532static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
533#endif
534/***************************************************** 536/*****************************************************
535 * S e n d i n g H o s t C o m m a n d s * 537 * S e n d i n g H o s t C o m m a n d s *
536 *****************************************************/ 538 *****************************************************/
@@ -582,6 +584,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv);
582int iwl_dump_nic_event_log(struct iwl_priv *priv, 584int iwl_dump_nic_event_log(struct iwl_priv *priv,
583 bool full_log, char **buf, bool display); 585 bool full_log, char **buf, bool display);
584void iwl_dump_csr(struct iwl_priv *priv); 586void iwl_dump_csr(struct iwl_priv *priv);
587int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
585#ifdef CONFIG_IWLWIFI_DEBUG 588#ifdef CONFIG_IWLWIFI_DEBUG
586void iwl_print_rx_config_cmd(struct iwl_priv *priv); 589void iwl_print_rx_config_cmd(struct iwl_priv *priv);
587#else 590#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 1ec8cb4d5eae..1e00720bf8b1 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 58e0462cafa3..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,59 +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 struct dentry *file_csr;
113 struct dentry *file_ucode_tracing;
114 } dbgfs_debug_files;
115 u32 sram_offset;
116 u32 sram_len;
117};
118
119int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
120void iwl_dbgfs_unregister(struct iwl_priv *priv);
121#endif
122
123#else 70#else
124#define IWL_DEBUG(__priv, level, fmt, args...) 71#define IWL_DEBUG(__priv, level, fmt, args...)
125#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) 72#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
@@ -128,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
128{} 75{}
129#endif /* CONFIG_IWLWIFI_DEBUG */ 76#endif /* CONFIG_IWLWIFI_DEBUG */
130 77
131 78#ifdef CONFIG_IWLWIFI_DEBUGFS
132 79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
133#ifndef CONFIG_IWLWIFI_DEBUGFS 80void iwl_dbgfs_unregister(struct iwl_priv *priv);
81#else
134static 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)
135{ 83{
136 return 0; 84 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 4a2ac9311ba8..d134301b553c 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, \
@@ -236,24 +221,24 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
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;
@@ -429,8 +414,9 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file,
429 int pos = 0; 414 int pos = 0;
430 ssize_t ret = -ENOMEM; 415 ssize_t ret = -ENOMEM;
431 416
432 pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true); 417 ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
433 if (pos && buf) { 418 priv, true, &buf, true);
419 if (buf) {
434 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 420 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
435 kfree(buf); 421 kfree(buf);
436 } 422 }
@@ -829,7 +815,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
829 815
830 priv->power_data.debug_sleep_level_override = value; 816 priv->power_data.debug_sleep_level_override = value;
831 817
818 mutex_lock(&priv->mutex);
832 iwl_power_update_mode(priv, true); 819 iwl_power_update_mode(priv, true);
820 mutex_unlock(&priv->mutex);
833 821
834 return count; 822 return count;
835} 823}
@@ -1081,6 +1069,12 @@ static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1081 return p; 1069 return p;
1082} 1070}
1083 1071
1072static const char ucode_stats_header[] =
1073 "%-32s current acumulative delta max\n";
1074static const char ucode_stats_short_format[] =
1075 " %-30s %10u\n";
1076static const char ucode_stats_format[] =
1077 " %-30s %10u %10u %10u %10u\n";
1084 1078
1085static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1079static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1086 char __user *user_buf, 1080 char __user *user_buf,
@@ -1089,28 +1083,19 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1089 struct iwl_priv *priv = file->private_data; 1083 struct iwl_priv *priv = file->private_data;
1090 int pos = 0; 1084 int pos = 0;
1091 char *buf; 1085 char *buf;
1092 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1086 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1093 sizeof(struct statistics_rx_non_phy) * 20 + 1087 sizeof(struct statistics_rx_non_phy) * 40 +
1094 sizeof(struct statistics_rx_ht_phy) * 20 + 400; 1088 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1095 ssize_t ret; 1089 ssize_t ret;
1096 struct statistics_rx_phy *ofdm, *accum_ofdm; 1090 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1097 struct statistics_rx_phy *cck, *accum_cck; 1091 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1098 struct statistics_rx_non_phy *general, *accum_general; 1092 struct statistics_rx_non_phy *general, *accum_general;
1099 struct statistics_rx_ht_phy *ht, *accum_ht; 1093 struct statistics_rx_non_phy *delta_general, *max_general;
1094 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1100 1095
1101 if (!iwl_is_alive(priv)) 1096 if (!iwl_is_alive(priv))
1102 return -EAGAIN; 1097 return -EAGAIN;
1103 1098
1104 /* make request to uCode to retrieve statistics information */
1105 mutex_lock(&priv->mutex);
1106 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1107 mutex_unlock(&priv->mutex);
1108
1109 if (ret) {
1110 IWL_ERR(priv,
1111 "Error sending statistics request: %zd\n", ret);
1112 return -EAGAIN;
1113 }
1114 buf = kzalloc(bufsz, GFP_KERNEL); 1099 buf = kzalloc(bufsz, GFP_KERNEL);
1115 if (!buf) { 1100 if (!buf) {
1116 IWL_ERR(priv, "Can not allocate Buffer\n"); 1101 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1129,267 +1114,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1129 accum_cck = &priv->accum_statistics.rx.cck; 1114 accum_cck = &priv->accum_statistics.rx.cck;
1130 accum_general = &priv->accum_statistics.rx.general; 1115 accum_general = &priv->accum_statistics.rx.general;
1131 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 1116 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1117 delta_ofdm = &priv->delta_statistics.rx.ofdm;
1118 delta_cck = &priv->delta_statistics.rx.cck;
1119 delta_general = &priv->delta_statistics.rx.general;
1120 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1121 max_ofdm = &priv->max_delta.rx.ofdm;
1122 max_cck = &priv->max_delta.rx.cck;
1123 max_general = &priv->max_delta.rx.general;
1124 max_ht = &priv->max_delta.rx.ofdm_ht;
1125
1132 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1126 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1133 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); 1127 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1134 pos += scnprintf(buf + pos, bufsz - pos, 1128 "Statistics_Rx - OFDM:");
1135 "\t\t\tcurrent\t\t\taccumulative\n"); 1129 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1136 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1130 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1137 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); 1131 accum_ofdm->ina_cnt,
1138 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1132 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1139 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); 1133 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1140 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1134 "fina_cnt:",
1141 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); 1135 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1142 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1136 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1143 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); 1137 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1144 pos += scnprintf(buf + pos, bufsz - pos, 1138 "plcp_err:",
1145 "overrun_err:\t\t%u\t\t\t%u\n", 1139 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1140 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1141 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1142 "crc32_err:",
1143 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1144 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1145 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1146 "overrun_err:",
1146 le32_to_cpu(ofdm->overrun_err), 1147 le32_to_cpu(ofdm->overrun_err),
1147 accum_ofdm->overrun_err); 1148 accum_ofdm->overrun_err,
1148 pos += scnprintf(buf + pos, bufsz - pos, 1149 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1149 "early_overrun_err:\t%u\t\t\t%u\n", 1150 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1151 "early_overrun_err:",
1150 le32_to_cpu(ofdm->early_overrun_err), 1152 le32_to_cpu(ofdm->early_overrun_err),
1151 accum_ofdm->early_overrun_err); 1153 accum_ofdm->early_overrun_err,
1152 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1154 delta_ofdm->early_overrun_err,
1155 max_ofdm->early_overrun_err);
1156 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1157 "crc32_good:",
1153 le32_to_cpu(ofdm->crc32_good), 1158 le32_to_cpu(ofdm->crc32_good),
1154 accum_ofdm->crc32_good); 1159 accum_ofdm->crc32_good,
1155 pos += scnprintf(buf + pos, bufsz - pos, 1160 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1156 "false_alarm_cnt:\t%u\t\t\t%u\n", 1161 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1162 "false_alarm_cnt:",
1157 le32_to_cpu(ofdm->false_alarm_cnt), 1163 le32_to_cpu(ofdm->false_alarm_cnt),
1158 accum_ofdm->false_alarm_cnt); 1164 accum_ofdm->false_alarm_cnt,
1159 pos += scnprintf(buf + pos, bufsz - pos, 1165 delta_ofdm->false_alarm_cnt,
1160 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1166 max_ofdm->false_alarm_cnt);
1167 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1168 "fina_sync_err_cnt:",
1161 le32_to_cpu(ofdm->fina_sync_err_cnt), 1169 le32_to_cpu(ofdm->fina_sync_err_cnt),
1162 accum_ofdm->fina_sync_err_cnt); 1170 accum_ofdm->fina_sync_err_cnt,
1163 pos += scnprintf(buf + pos, bufsz - pos, 1171 delta_ofdm->fina_sync_err_cnt,
1164 "sfd_timeout:\t\t%u\t\t\t%u\n", 1172 max_ofdm->fina_sync_err_cnt);
1173 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1174 "sfd_timeout:",
1165 le32_to_cpu(ofdm->sfd_timeout), 1175 le32_to_cpu(ofdm->sfd_timeout),
1166 accum_ofdm->sfd_timeout); 1176 accum_ofdm->sfd_timeout,
1167 pos += scnprintf(buf + pos, bufsz - pos, 1177 delta_ofdm->sfd_timeout,
1168 "fina_timeout:\t\t%u\t\t\t%u\n", 1178 max_ofdm->sfd_timeout);
1179 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1180 "fina_timeout:",
1169 le32_to_cpu(ofdm->fina_timeout), 1181 le32_to_cpu(ofdm->fina_timeout),
1170 accum_ofdm->fina_timeout); 1182 accum_ofdm->fina_timeout,
1171 pos += scnprintf(buf + pos, bufsz - pos, 1183 delta_ofdm->fina_timeout,
1172 "unresponded_rts:\t%u\t\t\t%u\n", 1184 max_ofdm->fina_timeout);
1185 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1186 "unresponded_rts:",
1173 le32_to_cpu(ofdm->unresponded_rts), 1187 le32_to_cpu(ofdm->unresponded_rts),
1174 accum_ofdm->unresponded_rts); 1188 accum_ofdm->unresponded_rts,
1175 pos += scnprintf(buf + pos, bufsz - pos, 1189 delta_ofdm->unresponded_rts,
1176 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1190 max_ofdm->unresponded_rts);
1191 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1192 "rxe_frame_lmt_ovrun:",
1177 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1193 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1178 accum_ofdm->rxe_frame_limit_overrun); 1194 accum_ofdm->rxe_frame_limit_overrun,
1179 pos += scnprintf(buf + pos, bufsz - pos, 1195 delta_ofdm->rxe_frame_limit_overrun,
1180 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1196 max_ofdm->rxe_frame_limit_overrun);
1197 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1198 "sent_ack_cnt:",
1181 le32_to_cpu(ofdm->sent_ack_cnt), 1199 le32_to_cpu(ofdm->sent_ack_cnt),
1182 accum_ofdm->sent_ack_cnt); 1200 accum_ofdm->sent_ack_cnt,
1183 pos += scnprintf(buf + pos, bufsz - pos, 1201 delta_ofdm->sent_ack_cnt,
1184 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1202 max_ofdm->sent_ack_cnt);
1203 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1204 "sent_cts_cnt:",
1185 le32_to_cpu(ofdm->sent_cts_cnt), 1205 le32_to_cpu(ofdm->sent_cts_cnt),
1186 accum_ofdm->sent_cts_cnt); 1206 accum_ofdm->sent_cts_cnt,
1187 pos += scnprintf(buf + pos, bufsz - pos, 1207 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1188 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1208 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209 "sent_ba_rsp_cnt:",
1189 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1210 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1190 accum_ofdm->sent_ba_rsp_cnt); 1211 accum_ofdm->sent_ba_rsp_cnt,
1191 pos += scnprintf(buf + pos, bufsz - pos, 1212 delta_ofdm->sent_ba_rsp_cnt,
1192 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1213 max_ofdm->sent_ba_rsp_cnt);
1214 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1215 "dsp_self_kill:",
1193 le32_to_cpu(ofdm->dsp_self_kill), 1216 le32_to_cpu(ofdm->dsp_self_kill),
1194 accum_ofdm->dsp_self_kill); 1217 accum_ofdm->dsp_self_kill,
1195 pos += scnprintf(buf + pos, bufsz - pos, 1218 delta_ofdm->dsp_self_kill,
1196 "mh_format_err:\t\t%u\t\t\t%u\n", 1219 max_ofdm->dsp_self_kill);
1220 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1221 "mh_format_err:",
1197 le32_to_cpu(ofdm->mh_format_err), 1222 le32_to_cpu(ofdm->mh_format_err),
1198 accum_ofdm->mh_format_err); 1223 accum_ofdm->mh_format_err,
1199 pos += scnprintf(buf + pos, bufsz - pos, 1224 delta_ofdm->mh_format_err,
1200 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1225 max_ofdm->mh_format_err);
1226 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1227 "re_acq_main_rssi_sum:",
1201 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1228 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1202 accum_ofdm->re_acq_main_rssi_sum); 1229 accum_ofdm->re_acq_main_rssi_sum,
1203 1230 delta_ofdm->re_acq_main_rssi_sum,
1204 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); 1231 max_ofdm->re_acq_main_rssi_sum);
1205 pos += scnprintf(buf + pos, bufsz - pos, 1232
1206 "\t\t\tcurrent\t\t\taccumulative\n"); 1233 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1207 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1234 "Statistics_Rx - CCK:");
1208 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); 1235 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1236 "ina_cnt:",
1210 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); 1237 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1211 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1238 delta_cck->ina_cnt, max_cck->ina_cnt);
1212 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); 1239 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1213 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1240 "fina_cnt:",
1214 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); 1241 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1215 pos += scnprintf(buf + pos, bufsz - pos, 1242 delta_cck->fina_cnt, max_cck->fina_cnt);
1216 "overrun_err:\t\t%u\t\t\t%u\n", 1243 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1244 "plcp_err:",
1245 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1246 delta_cck->plcp_err, max_cck->plcp_err);
1247 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1248 "crc32_err:",
1249 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1250 delta_cck->crc32_err, max_cck->crc32_err);
1251 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1252 "overrun_err:",
1217 le32_to_cpu(cck->overrun_err), 1253 le32_to_cpu(cck->overrun_err),
1218 accum_cck->overrun_err); 1254 accum_cck->overrun_err,
1219 pos += scnprintf(buf + pos, bufsz - pos, 1255 delta_cck->overrun_err, max_cck->overrun_err);
1220 "early_overrun_err:\t%u\t\t\t%u\n", 1256 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1257 "early_overrun_err:",
1221 le32_to_cpu(cck->early_overrun_err), 1258 le32_to_cpu(cck->early_overrun_err),
1222 accum_cck->early_overrun_err); 1259 accum_cck->early_overrun_err,
1223 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1260 delta_cck->early_overrun_err,
1224 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); 1261 max_cck->early_overrun_err);
1225 pos += scnprintf(buf + pos, bufsz - pos, 1262 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1226 "false_alarm_cnt:\t%u\t\t\t%u\n", 1263 "crc32_good:",
1264 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1265 delta_cck->crc32_good,
1266 max_cck->crc32_good);
1267 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1268 "false_alarm_cnt:",
1227 le32_to_cpu(cck->false_alarm_cnt), 1269 le32_to_cpu(cck->false_alarm_cnt),
1228 accum_cck->false_alarm_cnt); 1270 accum_cck->false_alarm_cnt,
1229 pos += scnprintf(buf + pos, bufsz - pos, 1271 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1230 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1272 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1273 "fina_sync_err_cnt:",
1231 le32_to_cpu(cck->fina_sync_err_cnt), 1274 le32_to_cpu(cck->fina_sync_err_cnt),
1232 accum_cck->fina_sync_err_cnt); 1275 accum_cck->fina_sync_err_cnt,
1233 pos += scnprintf(buf + pos, bufsz - pos, 1276 delta_cck->fina_sync_err_cnt,
1234 "sfd_timeout:\t\t%u\t\t\t%u\n", 1277 max_cck->fina_sync_err_cnt);
1278 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1279 "sfd_timeout:",
1235 le32_to_cpu(cck->sfd_timeout), 1280 le32_to_cpu(cck->sfd_timeout),
1236 accum_cck->sfd_timeout); 1281 accum_cck->sfd_timeout,
1237 pos += scnprintf(buf + pos, bufsz - pos, 1282 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1238 "fina_timeout:\t\t%u\t\t\t%u\n", 1283 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1284 "fina_timeout:",
1239 le32_to_cpu(cck->fina_timeout), 1285 le32_to_cpu(cck->fina_timeout),
1240 accum_cck->fina_timeout); 1286 accum_cck->fina_timeout,
1241 pos += scnprintf(buf + pos, bufsz - pos, 1287 delta_cck->fina_timeout, max_cck->fina_timeout);
1242 "unresponded_rts:\t%u\t\t\t%u\n", 1288 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1289 "unresponded_rts:",
1243 le32_to_cpu(cck->unresponded_rts), 1290 le32_to_cpu(cck->unresponded_rts),
1244 accum_cck->unresponded_rts); 1291 accum_cck->unresponded_rts,
1245 pos += scnprintf(buf + pos, bufsz - pos, 1292 delta_cck->unresponded_rts,
1246 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1293 max_cck->unresponded_rts);
1294 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1295 "rxe_frame_lmt_ovrun:",
1247 le32_to_cpu(cck->rxe_frame_limit_overrun), 1296 le32_to_cpu(cck->rxe_frame_limit_overrun),
1248 accum_cck->rxe_frame_limit_overrun); 1297 accum_cck->rxe_frame_limit_overrun,
1249 pos += scnprintf(buf + pos, bufsz - pos, 1298 delta_cck->rxe_frame_limit_overrun,
1250 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1299 max_cck->rxe_frame_limit_overrun);
1300 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1301 "sent_ack_cnt:",
1251 le32_to_cpu(cck->sent_ack_cnt), 1302 le32_to_cpu(cck->sent_ack_cnt),
1252 accum_cck->sent_ack_cnt); 1303 accum_cck->sent_ack_cnt,
1253 pos += scnprintf(buf + pos, bufsz - pos, 1304 delta_cck->sent_ack_cnt,
1254 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1305 max_cck->sent_ack_cnt);
1306 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1307 "sent_cts_cnt:",
1255 le32_to_cpu(cck->sent_cts_cnt), 1308 le32_to_cpu(cck->sent_cts_cnt),
1256 accum_cck->sent_cts_cnt); 1309 accum_cck->sent_cts_cnt,
1257 pos += scnprintf(buf + pos, bufsz - pos, 1310 delta_cck->sent_cts_cnt,
1258 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1311 max_cck->sent_cts_cnt);
1312 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1313 "sent_ba_rsp_cnt:",
1259 le32_to_cpu(cck->sent_ba_rsp_cnt), 1314 le32_to_cpu(cck->sent_ba_rsp_cnt),
1260 accum_cck->sent_ba_rsp_cnt); 1315 accum_cck->sent_ba_rsp_cnt,
1261 pos += scnprintf(buf + pos, bufsz - pos, 1316 delta_cck->sent_ba_rsp_cnt,
1262 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1317 max_cck->sent_ba_rsp_cnt);
1318 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1319 "dsp_self_kill:",
1263 le32_to_cpu(cck->dsp_self_kill), 1320 le32_to_cpu(cck->dsp_self_kill),
1264 accum_cck->dsp_self_kill); 1321 accum_cck->dsp_self_kill,
1265 pos += scnprintf(buf + pos, bufsz - pos, 1322 delta_cck->dsp_self_kill,
1266 "mh_format_err:\t\t%u\t\t\t%u\n", 1323 max_cck->dsp_self_kill);
1324 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1325 "mh_format_err:",
1267 le32_to_cpu(cck->mh_format_err), 1326 le32_to_cpu(cck->mh_format_err),
1268 accum_cck->mh_format_err); 1327 accum_cck->mh_format_err,
1269 pos += scnprintf(buf + pos, bufsz - pos, 1328 delta_cck->mh_format_err, max_cck->mh_format_err);
1270 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1329 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1330 "re_acq_main_rssi_sum:",
1271 le32_to_cpu(cck->re_acq_main_rssi_sum), 1331 le32_to_cpu(cck->re_acq_main_rssi_sum),
1272 accum_cck->re_acq_main_rssi_sum); 1332 accum_cck->re_acq_main_rssi_sum,
1273 1333 delta_cck->re_acq_main_rssi_sum,
1274 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); 1334 max_cck->re_acq_main_rssi_sum);
1275 pos += scnprintf(buf + pos, bufsz - pos, 1335
1276 "\t\t\tcurrent\t\t\taccumulative\n"); 1336 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1277 pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", 1337 "Statistics_Rx - GENERAL:");
1338 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1339 "bogus_cts:",
1278 le32_to_cpu(general->bogus_cts), 1340 le32_to_cpu(general->bogus_cts),
1279 accum_general->bogus_cts); 1341 accum_general->bogus_cts,
1280 pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", 1342 delta_general->bogus_cts, max_general->bogus_cts);
1343 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1344 "bogus_ack:",
1281 le32_to_cpu(general->bogus_ack), 1345 le32_to_cpu(general->bogus_ack),
1282 accum_general->bogus_ack); 1346 accum_general->bogus_ack,
1283 pos += scnprintf(buf + pos, bufsz - pos, 1347 delta_general->bogus_ack, max_general->bogus_ack);
1284 "non_bssid_frames:\t%u\t\t\t%u\n", 1348 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1349 "non_bssid_frames:",
1285 le32_to_cpu(general->non_bssid_frames), 1350 le32_to_cpu(general->non_bssid_frames),
1286 accum_general->non_bssid_frames); 1351 accum_general->non_bssid_frames,
1287 pos += scnprintf(buf + pos, bufsz - pos, 1352 delta_general->non_bssid_frames,
1288 "filtered_frames:\t%u\t\t\t%u\n", 1353 max_general->non_bssid_frames);
1354 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1355 "filtered_frames:",
1289 le32_to_cpu(general->filtered_frames), 1356 le32_to_cpu(general->filtered_frames),
1290 accum_general->filtered_frames); 1357 accum_general->filtered_frames,
1291 pos += scnprintf(buf + pos, bufsz - pos, 1358 delta_general->filtered_frames,
1292 "non_channel_beacons:\t%u\t\t\t%u\n", 1359 max_general->filtered_frames);
1360 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1361 "non_channel_beacons:",
1293 le32_to_cpu(general->non_channel_beacons), 1362 le32_to_cpu(general->non_channel_beacons),
1294 accum_general->non_channel_beacons); 1363 accum_general->non_channel_beacons,
1295 pos += scnprintf(buf + pos, bufsz - pos, 1364 delta_general->non_channel_beacons,
1296 "channel_beacons:\t%u\t\t\t%u\n", 1365 max_general->non_channel_beacons);
1366 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1367 "channel_beacons:",
1297 le32_to_cpu(general->channel_beacons), 1368 le32_to_cpu(general->channel_beacons),
1298 accum_general->channel_beacons); 1369 accum_general->channel_beacons,
1299 pos += scnprintf(buf + pos, bufsz - pos, 1370 delta_general->channel_beacons,
1300 "num_missed_bcon:\t%u\t\t\t%u\n", 1371 max_general->channel_beacons);
1372 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1373 "num_missed_bcon:",
1301 le32_to_cpu(general->num_missed_bcon), 1374 le32_to_cpu(general->num_missed_bcon),
1302 accum_general->num_missed_bcon); 1375 accum_general->num_missed_bcon,
1303 pos += scnprintf(buf + pos, bufsz - pos, 1376 delta_general->num_missed_bcon,
1304 "adc_rx_saturation_time:\t%u\t\t\t%u\n", 1377 max_general->num_missed_bcon);
1378 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1379 "adc_rx_saturation_time:",
1305 le32_to_cpu(general->adc_rx_saturation_time), 1380 le32_to_cpu(general->adc_rx_saturation_time),
1306 accum_general->adc_rx_saturation_time); 1381 accum_general->adc_rx_saturation_time,
1307 pos += scnprintf(buf + pos, bufsz - pos, 1382 delta_general->adc_rx_saturation_time,
1308 "ina_detect_search_tm:\t%u\t\t\t%u\n", 1383 max_general->adc_rx_saturation_time);
1384 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1385 "ina_detect_search_tm:",
1309 le32_to_cpu(general->ina_detection_search_time), 1386 le32_to_cpu(general->ina_detection_search_time),
1310 accum_general->ina_detection_search_time); 1387 accum_general->ina_detection_search_time,
1311 pos += scnprintf(buf + pos, bufsz - pos, 1388 delta_general->ina_detection_search_time,
1312 "beacon_silence_rssi_a:\t%u\t\t\t%u\n", 1389 max_general->ina_detection_search_time);
1390 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1391 "beacon_silence_rssi_a:",
1313 le32_to_cpu(general->beacon_silence_rssi_a), 1392 le32_to_cpu(general->beacon_silence_rssi_a),
1314 accum_general->beacon_silence_rssi_a); 1393 accum_general->beacon_silence_rssi_a,
1315 pos += scnprintf(buf + pos, bufsz - pos, 1394 delta_general->beacon_silence_rssi_a,
1316 "beacon_silence_rssi_b:\t%u\t\t\t%u\n", 1395 max_general->beacon_silence_rssi_a);
1396 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1397 "beacon_silence_rssi_b:",
1317 le32_to_cpu(general->beacon_silence_rssi_b), 1398 le32_to_cpu(general->beacon_silence_rssi_b),
1318 accum_general->beacon_silence_rssi_b); 1399 accum_general->beacon_silence_rssi_b,
1319 pos += scnprintf(buf + pos, bufsz - pos, 1400 delta_general->beacon_silence_rssi_b,
1320 "beacon_silence_rssi_c:\t%u\t\t\t%u\n", 1401 max_general->beacon_silence_rssi_b);
1402 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1403 "beacon_silence_rssi_c:",
1321 le32_to_cpu(general->beacon_silence_rssi_c), 1404 le32_to_cpu(general->beacon_silence_rssi_c),
1322 accum_general->beacon_silence_rssi_c); 1405 accum_general->beacon_silence_rssi_c,
1323 pos += scnprintf(buf + pos, bufsz - pos, 1406 delta_general->beacon_silence_rssi_c,
1324 "interference_data_flag:\t%u\t\t\t%u\n", 1407 max_general->beacon_silence_rssi_c);
1408 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1409 "interference_data_flag:",
1325 le32_to_cpu(general->interference_data_flag), 1410 le32_to_cpu(general->interference_data_flag),
1326 accum_general->interference_data_flag); 1411 accum_general->interference_data_flag,
1327 pos += scnprintf(buf + pos, bufsz - pos, 1412 delta_general->interference_data_flag,
1328 "channel_load:\t\t%u\t\t\t%u\n", 1413 max_general->interference_data_flag);
1414 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1415 "channel_load:",
1329 le32_to_cpu(general->channel_load), 1416 le32_to_cpu(general->channel_load),
1330 accum_general->channel_load); 1417 accum_general->channel_load,
1331 pos += scnprintf(buf + pos, bufsz - pos, 1418 delta_general->channel_load,
1332 "dsp_false_alarms:\t%u\t\t\t%u\n", 1419 max_general->channel_load);
1420 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1421 "dsp_false_alarms:",
1333 le32_to_cpu(general->dsp_false_alarms), 1422 le32_to_cpu(general->dsp_false_alarms),
1334 accum_general->dsp_false_alarms); 1423 accum_general->dsp_false_alarms,
1335 pos += scnprintf(buf + pos, bufsz - pos, 1424 delta_general->dsp_false_alarms,
1336 "beacon_rssi_a:\t\t%u\t\t\t%u\n", 1425 max_general->dsp_false_alarms);
1426 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1427 "beacon_rssi_a:",
1337 le32_to_cpu(general->beacon_rssi_a), 1428 le32_to_cpu(general->beacon_rssi_a),
1338 accum_general->beacon_rssi_a); 1429 accum_general->beacon_rssi_a,
1339 pos += scnprintf(buf + pos, bufsz - pos, 1430 delta_general->beacon_rssi_a,
1340 "beacon_rssi_b:\t\t%u\t\t\t%u\n", 1431 max_general->beacon_rssi_a);
1432 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1433 "beacon_rssi_b:",
1341 le32_to_cpu(general->beacon_rssi_b), 1434 le32_to_cpu(general->beacon_rssi_b),
1342 accum_general->beacon_rssi_b); 1435 accum_general->beacon_rssi_b,
1343 pos += scnprintf(buf + pos, bufsz - pos, 1436 delta_general->beacon_rssi_b,
1344 "beacon_rssi_c:\t\t%u\t\t\t%u\n", 1437 max_general->beacon_rssi_b);
1438 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 "beacon_rssi_c:",
1345 le32_to_cpu(general->beacon_rssi_c), 1440 le32_to_cpu(general->beacon_rssi_c),
1346 accum_general->beacon_rssi_c); 1441 accum_general->beacon_rssi_c,
1347 pos += scnprintf(buf + pos, bufsz - pos, 1442 delta_general->beacon_rssi_c,
1348 "beacon_energy_a:\t%u\t\t\t%u\n", 1443 max_general->beacon_rssi_c);
1444 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1445 "beacon_energy_a:",
1349 le32_to_cpu(general->beacon_energy_a), 1446 le32_to_cpu(general->beacon_energy_a),
1350 accum_general->beacon_energy_a); 1447 accum_general->beacon_energy_a,
1351 pos += scnprintf(buf + pos, bufsz - pos, 1448 delta_general->beacon_energy_a,
1352 "beacon_energy_b:\t%u\t\t\t%u\n", 1449 max_general->beacon_energy_a);
1450 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1451 "beacon_energy_b:",
1353 le32_to_cpu(general->beacon_energy_b), 1452 le32_to_cpu(general->beacon_energy_b),
1354 accum_general->beacon_energy_b); 1453 accum_general->beacon_energy_b,
1355 pos += scnprintf(buf + pos, bufsz - pos, 1454 delta_general->beacon_energy_b,
1356 "beacon_energy_c:\t%u\t\t\t%u\n", 1455 max_general->beacon_energy_b);
1456 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1457 "beacon_energy_c:",
1357 le32_to_cpu(general->beacon_energy_c), 1458 le32_to_cpu(general->beacon_energy_c),
1358 accum_general->beacon_energy_c); 1459 accum_general->beacon_energy_c,
1460 delta_general->beacon_energy_c,
1461 max_general->beacon_energy_c);
1359 1462
1360 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); 1463 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1361 pos += scnprintf(buf + pos, bufsz - pos, 1464 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1362 "\t\t\tcurrent\t\t\taccumulative\n"); 1465 "Statistics_Rx - OFDM_HT:");
1363 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1466 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1364 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); 1467 "plcp_err:",
1365 pos += scnprintf(buf + pos, bufsz - pos, 1468 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1366 "overrun_err:\t\t%u\t\t\t%u\n", 1469 delta_ht->plcp_err, max_ht->plcp_err);
1367 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); 1470 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1368 pos += scnprintf(buf + pos, bufsz - pos, 1471 "overrun_err:",
1369 "early_overrun_err:\t%u\t\t\t%u\n", 1472 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1473 delta_ht->overrun_err, max_ht->overrun_err);
1474 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1475 "early_overrun_err:",
1370 le32_to_cpu(ht->early_overrun_err), 1476 le32_to_cpu(ht->early_overrun_err),
1371 accum_ht->early_overrun_err); 1477 accum_ht->early_overrun_err,
1372 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1478 delta_ht->early_overrun_err,
1373 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); 1479 max_ht->early_overrun_err);
1374 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1480 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1375 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); 1481 "crc32_good:",
1376 pos += scnprintf(buf + pos, bufsz - pos, 1482 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1377 "mh_format_err:\t\t%u\t\t\t%u\n", 1483 delta_ht->crc32_good, max_ht->crc32_good);
1484 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1485 "crc32_err:",
1486 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1487 delta_ht->crc32_err, max_ht->crc32_err);
1488 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1489 "mh_format_err:",
1378 le32_to_cpu(ht->mh_format_err), 1490 le32_to_cpu(ht->mh_format_err),
1379 accum_ht->mh_format_err); 1491 accum_ht->mh_format_err,
1380 pos += scnprintf(buf + pos, bufsz - pos, 1492 delta_ht->mh_format_err, max_ht->mh_format_err);
1381 "agg_crc32_good:\t\t%u\t\t\t%u\n", 1493 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1494 "agg_crc32_good:",
1382 le32_to_cpu(ht->agg_crc32_good), 1495 le32_to_cpu(ht->agg_crc32_good),
1383 accum_ht->agg_crc32_good); 1496 accum_ht->agg_crc32_good,
1384 pos += scnprintf(buf + pos, bufsz - pos, 1497 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1385 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", 1498 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1499 "agg_mpdu_cnt:",
1386 le32_to_cpu(ht->agg_mpdu_cnt), 1500 le32_to_cpu(ht->agg_mpdu_cnt),
1387 accum_ht->agg_mpdu_cnt); 1501 accum_ht->agg_mpdu_cnt,
1388 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1502 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1389 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1503 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1390 pos += scnprintf(buf + pos, bufsz - pos, "unsupport_mcs:\t\t%u\t\t\t%u\n", 1504 "agg_cnt:",
1505 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1506 delta_ht->agg_cnt, max_ht->agg_cnt);
1507 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1508 "unsupport_mcs:",
1391 le32_to_cpu(ht->unsupport_mcs), 1509 le32_to_cpu(ht->unsupport_mcs),
1392 accum_ht->unsupport_mcs); 1510 accum_ht->unsupport_mcs,
1511 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1393 1512
1394 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1513 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1395 kfree(buf); 1514 kfree(buf);
@@ -1403,23 +1522,13 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1403 struct iwl_priv *priv = file->private_data; 1522 struct iwl_priv *priv = file->private_data;
1404 int pos = 0; 1523 int pos = 0;
1405 char *buf; 1524 char *buf;
1406 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1525 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1407 ssize_t ret; 1526 ssize_t ret;
1408 struct statistics_tx *tx, *accum_tx; 1527 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1409 1528
1410 if (!iwl_is_alive(priv)) 1529 if (!iwl_is_alive(priv))
1411 return -EAGAIN; 1530 return -EAGAIN;
1412 1531
1413 /* make request to uCode to retrieve statistics information */
1414 mutex_lock(&priv->mutex);
1415 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1416 mutex_unlock(&priv->mutex);
1417
1418 if (ret) {
1419 IWL_ERR(priv,
1420 "Error sending statistics request: %zd\n", ret);
1421 return -EAGAIN;
1422 }
1423 buf = kzalloc(bufsz, GFP_KERNEL); 1532 buf = kzalloc(bufsz, GFP_KERNEL);
1424 if (!buf) { 1533 if (!buf) {
1425 IWL_ERR(priv, "Can not allocate Buffer\n"); 1534 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1432,106 +1541,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1432 */ 1541 */
1433 tx = &priv->statistics.tx; 1542 tx = &priv->statistics.tx;
1434 accum_tx = &priv->accum_statistics.tx; 1543 accum_tx = &priv->accum_statistics.tx;
1544 delta_tx = &priv->delta_statistics.tx;
1545 max_tx = &priv->max_delta.tx;
1435 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1436 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); 1547 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1437 pos += scnprintf(buf + pos, bufsz - pos, 1548 "Statistics_Tx:");
1438 "\t\t\tcurrent\t\t\taccumulative\n"); 1549 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", 1550 "preamble:",
1440 le32_to_cpu(tx->preamble_cnt), 1551 le32_to_cpu(tx->preamble_cnt),
1441 accum_tx->preamble_cnt); 1552 accum_tx->preamble_cnt,
1442 pos += scnprintf(buf + pos, bufsz - pos, 1553 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1443 "rx_detected_cnt:\t\t%u\t\t\t%u\n", 1554 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1555 "rx_detected_cnt:",
1444 le32_to_cpu(tx->rx_detected_cnt), 1556 le32_to_cpu(tx->rx_detected_cnt),
1445 accum_tx->rx_detected_cnt); 1557 accum_tx->rx_detected_cnt,
1446 pos += scnprintf(buf + pos, bufsz - pos, 1558 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1447 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", 1559 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1560 "bt_prio_defer_cnt:",
1448 le32_to_cpu(tx->bt_prio_defer_cnt), 1561 le32_to_cpu(tx->bt_prio_defer_cnt),
1449 accum_tx->bt_prio_defer_cnt); 1562 accum_tx->bt_prio_defer_cnt,
1450 pos += scnprintf(buf + pos, bufsz - pos, 1563 delta_tx->bt_prio_defer_cnt,
1451 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", 1564 max_tx->bt_prio_defer_cnt);
1565 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1566 "bt_prio_kill_cnt:",
1452 le32_to_cpu(tx->bt_prio_kill_cnt), 1567 le32_to_cpu(tx->bt_prio_kill_cnt),
1453 accum_tx->bt_prio_kill_cnt); 1568 accum_tx->bt_prio_kill_cnt,
1454 pos += scnprintf(buf + pos, bufsz - pos, 1569 delta_tx->bt_prio_kill_cnt,
1455 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", 1570 max_tx->bt_prio_kill_cnt);
1571 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1572 "few_bytes_cnt:",
1456 le32_to_cpu(tx->few_bytes_cnt), 1573 le32_to_cpu(tx->few_bytes_cnt),
1457 accum_tx->few_bytes_cnt); 1574 accum_tx->few_bytes_cnt,
1458 pos += scnprintf(buf + pos, bufsz - pos, 1575 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1459 "cts_timeout:\t\t\t%u\t\t\t%u\n", 1576 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1460 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); 1577 "cts_timeout:",
1461 pos += scnprintf(buf + pos, bufsz - pos, 1578 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1462 "ack_timeout:\t\t\t%u\t\t\t%u\n", 1579 delta_tx->cts_timeout, max_tx->cts_timeout);
1580 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1581 "ack_timeout:",
1463 le32_to_cpu(tx->ack_timeout), 1582 le32_to_cpu(tx->ack_timeout),
1464 accum_tx->ack_timeout); 1583 accum_tx->ack_timeout,
1465 pos += scnprintf(buf + pos, bufsz - pos, 1584 delta_tx->ack_timeout, max_tx->ack_timeout);
1466 "expected_ack_cnt:\t\t%u\t\t\t%u\n", 1585 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1586 "expected_ack_cnt:",
1467 le32_to_cpu(tx->expected_ack_cnt), 1587 le32_to_cpu(tx->expected_ack_cnt),
1468 accum_tx->expected_ack_cnt); 1588 accum_tx->expected_ack_cnt,
1469 pos += scnprintf(buf + pos, bufsz - pos, 1589 delta_tx->expected_ack_cnt,
1470 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", 1590 max_tx->expected_ack_cnt);
1591 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592 "actual_ack_cnt:",
1471 le32_to_cpu(tx->actual_ack_cnt), 1593 le32_to_cpu(tx->actual_ack_cnt),
1472 accum_tx->actual_ack_cnt); 1594 accum_tx->actual_ack_cnt,
1473 pos += scnprintf(buf + pos, bufsz - pos, 1595 delta_tx->actual_ack_cnt,
1474 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", 1596 max_tx->actual_ack_cnt);
1597 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1598 "dump_msdu_cnt:",
1475 le32_to_cpu(tx->dump_msdu_cnt), 1599 le32_to_cpu(tx->dump_msdu_cnt),
1476 accum_tx->dump_msdu_cnt); 1600 accum_tx->dump_msdu_cnt,
1477 pos += scnprintf(buf + pos, bufsz - pos, 1601 delta_tx->dump_msdu_cnt,
1478 "abort_nxt_frame_mismatch:" 1602 max_tx->dump_msdu_cnt);
1479 "\t%u\t\t\t%u\n", 1603 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1604 "abort_nxt_frame_mismatch:",
1480 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1605 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1481 accum_tx->burst_abort_next_frame_mismatch_cnt); 1606 accum_tx->burst_abort_next_frame_mismatch_cnt,
1482 pos += scnprintf(buf + pos, bufsz - pos, 1607 delta_tx->burst_abort_next_frame_mismatch_cnt,
1483 "abort_missing_nxt_frame:" 1608 max_tx->burst_abort_next_frame_mismatch_cnt);
1484 "\t%u\t\t\t%u\n", 1609 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1610 "abort_missing_nxt_frame:",
1485 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1611 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1486 accum_tx->burst_abort_missing_next_frame_cnt); 1612 accum_tx->burst_abort_missing_next_frame_cnt,
1487 pos += scnprintf(buf + pos, bufsz - pos, 1613 delta_tx->burst_abort_missing_next_frame_cnt,
1488 "cts_timeout_collision:\t\t%u\t\t\t%u\n", 1614 max_tx->burst_abort_missing_next_frame_cnt);
1615 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1616 "cts_timeout_collision:",
1489 le32_to_cpu(tx->cts_timeout_collision), 1617 le32_to_cpu(tx->cts_timeout_collision),
1490 accum_tx->cts_timeout_collision); 1618 accum_tx->cts_timeout_collision,
1491 pos += scnprintf(buf + pos, bufsz - pos, 1619 delta_tx->cts_timeout_collision,
1492 "ack_ba_timeout_collision:\t%u\t\t\t%u\n", 1620 max_tx->cts_timeout_collision);
1621 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622 "ack_ba_timeout_collision:",
1493 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1623 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1494 accum_tx->ack_or_ba_timeout_collision); 1624 accum_tx->ack_or_ba_timeout_collision,
1495 pos += scnprintf(buf + pos, bufsz - pos, 1625 delta_tx->ack_or_ba_timeout_collision,
1496 "agg ba_timeout:\t\t\t%u\t\t\t%u\n", 1626 max_tx->ack_or_ba_timeout_collision);
1627 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1628 "agg ba_timeout:",
1497 le32_to_cpu(tx->agg.ba_timeout), 1629 le32_to_cpu(tx->agg.ba_timeout),
1498 accum_tx->agg.ba_timeout); 1630 accum_tx->agg.ba_timeout,
1499 pos += scnprintf(buf + pos, bufsz - pos, 1631 delta_tx->agg.ba_timeout,
1500 "agg ba_resched_frames:\t\t%u\t\t\t%u\n", 1632 max_tx->agg.ba_timeout);
1633 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1634 "agg ba_resched_frames:",
1501 le32_to_cpu(tx->agg.ba_reschedule_frames), 1635 le32_to_cpu(tx->agg.ba_reschedule_frames),
1502 accum_tx->agg.ba_reschedule_frames); 1636 accum_tx->agg.ba_reschedule_frames,
1503 pos += scnprintf(buf + pos, bufsz - pos, 1637 delta_tx->agg.ba_reschedule_frames,
1504 "agg scd_query_agg_frame:\t%u\t\t\t%u\n", 1638 max_tx->agg.ba_reschedule_frames);
1639 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1640 "agg scd_query_agg_frame:",
1505 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1641 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1506 accum_tx->agg.scd_query_agg_frame_cnt); 1642 accum_tx->agg.scd_query_agg_frame_cnt,
1507 pos += scnprintf(buf + pos, bufsz - pos, 1643 delta_tx->agg.scd_query_agg_frame_cnt,
1508 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", 1644 max_tx->agg.scd_query_agg_frame_cnt);
1645 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1646 "agg scd_query_no_agg:",
1509 le32_to_cpu(tx->agg.scd_query_no_agg), 1647 le32_to_cpu(tx->agg.scd_query_no_agg),
1510 accum_tx->agg.scd_query_no_agg); 1648 accum_tx->agg.scd_query_no_agg,
1511 pos += scnprintf(buf + pos, bufsz - pos, 1649 delta_tx->agg.scd_query_no_agg,
1512 "agg scd_query_agg:\t\t%u\t\t\t%u\n", 1650 max_tx->agg.scd_query_no_agg);
1651 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1652 "agg scd_query_agg:",
1513 le32_to_cpu(tx->agg.scd_query_agg), 1653 le32_to_cpu(tx->agg.scd_query_agg),
1514 accum_tx->agg.scd_query_agg); 1654 accum_tx->agg.scd_query_agg,
1515 pos += scnprintf(buf + pos, bufsz - pos, 1655 delta_tx->agg.scd_query_agg,
1516 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", 1656 max_tx->agg.scd_query_agg);
1657 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1658 "agg scd_query_mismatch:",
1517 le32_to_cpu(tx->agg.scd_query_mismatch), 1659 le32_to_cpu(tx->agg.scd_query_mismatch),
1518 accum_tx->agg.scd_query_mismatch); 1660 accum_tx->agg.scd_query_mismatch,
1519 pos += scnprintf(buf + pos, bufsz - pos, 1661 delta_tx->agg.scd_query_mismatch,
1520 "agg frame_not_ready:\t\t%u\t\t\t%u\n", 1662 max_tx->agg.scd_query_mismatch);
1663 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1664 "agg frame_not_ready:",
1521 le32_to_cpu(tx->agg.frame_not_ready), 1665 le32_to_cpu(tx->agg.frame_not_ready),
1522 accum_tx->agg.frame_not_ready); 1666 accum_tx->agg.frame_not_ready,
1523 pos += scnprintf(buf + pos, bufsz - pos, 1667 delta_tx->agg.frame_not_ready,
1524 "agg underrun:\t\t\t%u\t\t\t%u\n", 1668 max_tx->agg.frame_not_ready);
1669 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1670 "agg underrun:",
1525 le32_to_cpu(tx->agg.underrun), 1671 le32_to_cpu(tx->agg.underrun),
1526 accum_tx->agg.underrun); 1672 accum_tx->agg.underrun,
1527 pos += scnprintf(buf + pos, bufsz - pos, 1673 delta_tx->agg.underrun, max_tx->agg.underrun);
1528 "agg bt_prio_kill:\t\t%u\t\t\t%u\n", 1674 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1675 "agg bt_prio_kill:",
1529 le32_to_cpu(tx->agg.bt_prio_kill), 1676 le32_to_cpu(tx->agg.bt_prio_kill),
1530 accum_tx->agg.bt_prio_kill); 1677 accum_tx->agg.bt_prio_kill,
1531 pos += scnprintf(buf + pos, bufsz - pos, 1678 delta_tx->agg.bt_prio_kill,
1532 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", 1679 max_tx->agg.bt_prio_kill);
1680 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1681 "agg rx_ba_rsp_cnt:",
1533 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1682 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1534 accum_tx->agg.rx_ba_rsp_cnt); 1683 accum_tx->agg.rx_ba_rsp_cnt,
1684 delta_tx->agg.rx_ba_rsp_cnt,
1685 max_tx->agg.rx_ba_rsp_cnt);
1535 1686
1536 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1687 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1537 kfree(buf); 1688 kfree(buf);
@@ -1545,25 +1696,16 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1545 struct iwl_priv *priv = file->private_data; 1696 struct iwl_priv *priv = file->private_data;
1546 int pos = 0; 1697 int pos = 0;
1547 char *buf; 1698 char *buf;
1548 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1699 int bufsz = sizeof(struct statistics_general) * 10 + 300;
1549 ssize_t ret; 1700 ssize_t ret;
1550 struct statistics_general *general, *accum_general; 1701 struct statistics_general *general, *accum_general;
1551 struct statistics_dbg *dbg, *accum_dbg; 1702 struct statistics_general *delta_general, *max_general;
1552 struct statistics_div *div, *accum_div; 1703 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1704 struct statistics_div *div, *accum_div, *delta_div, *max_div;
1553 1705
1554 if (!iwl_is_alive(priv)) 1706 if (!iwl_is_alive(priv))
1555 return -EAGAIN; 1707 return -EAGAIN;
1556 1708
1557 /* make request to uCode to retrieve statistics information */
1558 mutex_lock(&priv->mutex);
1559 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1560 mutex_unlock(&priv->mutex);
1561
1562 if (ret) {
1563 IWL_ERR(priv,
1564 "Error sending statistics request: %zd\n", ret);
1565 return -EAGAIN;
1566 }
1567 buf = kzalloc(bufsz, GFP_KERNEL); 1709 buf = kzalloc(bufsz, GFP_KERNEL);
1568 if (!buf) { 1710 if (!buf) {
1569 IWL_ERR(priv, "Can not allocate Buffer\n"); 1711 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1578,52 +1720,78 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1578 dbg = &priv->statistics.general.dbg; 1720 dbg = &priv->statistics.general.dbg;
1579 div = &priv->statistics.general.div; 1721 div = &priv->statistics.general.div;
1580 accum_general = &priv->accum_statistics.general; 1722 accum_general = &priv->accum_statistics.general;
1723 delta_general = &priv->delta_statistics.general;
1724 max_general = &priv->max_delta.general;
1581 accum_dbg = &priv->accum_statistics.general.dbg; 1725 accum_dbg = &priv->accum_statistics.general.dbg;
1726 delta_dbg = &priv->delta_statistics.general.dbg;
1727 max_dbg = &priv->max_delta.general.dbg;
1582 accum_div = &priv->accum_statistics.general.div; 1728 accum_div = &priv->accum_statistics.general.div;
1729 delta_div = &priv->delta_statistics.general.div;
1730 max_div = &priv->max_delta.general.div;
1583 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1731 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1584 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); 1732 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1585 pos += scnprintf(buf + pos, bufsz - pos, 1733 "Statistics_General:");
1586 "\t\t\tcurrent\t\t\taccumulative\n"); 1734 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1587 pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", 1735 "temperature:",
1588 le32_to_cpu(general->temperature)); 1736 le32_to_cpu(general->temperature));
1589 pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", 1737 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1738 "temperature_m:",
1590 le32_to_cpu(general->temperature_m)); 1739 le32_to_cpu(general->temperature_m));
1591 pos += scnprintf(buf + pos, bufsz - pos, 1740 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592 "burst_check:\t\t\t%u\t\t\t%u\n", 1741 "burst_check:",
1593 le32_to_cpu(dbg->burst_check), 1742 le32_to_cpu(dbg->burst_check),
1594 accum_dbg->burst_check); 1743 accum_dbg->burst_check,
1595 pos += scnprintf(buf + pos, bufsz - pos, 1744 delta_dbg->burst_check, max_dbg->burst_check);
1596 "burst_count:\t\t\t%u\t\t\t%u\n", 1745 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1746 "burst_count:",
1597 le32_to_cpu(dbg->burst_count), 1747 le32_to_cpu(dbg->burst_count),
1598 accum_dbg->burst_count); 1748 accum_dbg->burst_count,
1599 pos += scnprintf(buf + pos, bufsz - pos, 1749 delta_dbg->burst_count, max_dbg->burst_count);
1600 "sleep_time:\t\t\t%u\t\t\t%u\n", 1750 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1751 "sleep_time:",
1601 le32_to_cpu(general->sleep_time), 1752 le32_to_cpu(general->sleep_time),
1602 accum_general->sleep_time); 1753 accum_general->sleep_time,
1603 pos += scnprintf(buf + pos, bufsz - pos, 1754 delta_general->sleep_time, max_general->sleep_time);
1604 "slots_out:\t\t\t%u\t\t\t%u\n", 1755 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1756 "slots_out:",
1605 le32_to_cpu(general->slots_out), 1757 le32_to_cpu(general->slots_out),
1606 accum_general->slots_out); 1758 accum_general->slots_out,
1607 pos += scnprintf(buf + pos, bufsz - pos, 1759 delta_general->slots_out, max_general->slots_out);
1608 "slots_idle:\t\t\t%u\t\t\t%u\n", 1760 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1761 "slots_idle:",
1609 le32_to_cpu(general->slots_idle), 1762 le32_to_cpu(general->slots_idle),
1610 accum_general->slots_idle); 1763 accum_general->slots_idle,
1764 delta_general->slots_idle, max_general->slots_idle);
1611 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", 1765 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1612 le32_to_cpu(general->ttl_timestamp)); 1766 le32_to_cpu(general->ttl_timestamp));
1613 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", 1767 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1614 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); 1768 "tx_on_a:",
1615 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", 1769 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1616 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); 1770 delta_div->tx_on_a, max_div->tx_on_a);
1617 pos += scnprintf(buf + pos, bufsz - pos, 1771 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1618 "exec_time:\t\t\t%u\t\t\t%u\n", 1772 "tx_on_b:",
1619 le32_to_cpu(div->exec_time), accum_div->exec_time); 1773 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1620 pos += scnprintf(buf + pos, bufsz - pos, 1774 delta_div->tx_on_b, max_div->tx_on_b);
1621 "probe_time:\t\t\t%u\t\t\t%u\n", 1775 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622 le32_to_cpu(div->probe_time), accum_div->probe_time); 1776 "exec_time:",
1623 pos += scnprintf(buf + pos, bufsz - pos, 1777 le32_to_cpu(div->exec_time), accum_div->exec_time,
1624 "rx_enable_counter:\t\t%u\t\t\t%u\n", 1778 delta_div->exec_time, max_div->exec_time);
1779 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1780 "probe_time:",
1781 le32_to_cpu(div->probe_time), accum_div->probe_time,
1782 delta_div->probe_time, max_div->probe_time);
1783 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1784 "rx_enable_counter:",
1625 le32_to_cpu(general->rx_enable_counter), 1785 le32_to_cpu(general->rx_enable_counter),
1626 accum_general->rx_enable_counter); 1786 accum_general->rx_enable_counter,
1787 delta_general->rx_enable_counter,
1788 max_general->rx_enable_counter);
1789 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1790 "num_of_sos_states:",
1791 le32_to_cpu(general->num_of_sos_states),
1792 accum_general->num_of_sos_states,
1793 delta_general->num_of_sos_states,
1794 max_general->num_of_sos_states);
1627 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1795 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1628 kfree(buf); 1796 kfree(buf);
1629 return ret; 1797 return ret;
@@ -1775,23 +1943,12 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1775 struct iwl_priv *priv = file->private_data; 1943 struct iwl_priv *priv = file->private_data;
1776 char buf[128]; 1944 char buf[128];
1777 int pos = 0; 1945 int pos = 0;
1778 ssize_t ret;
1779 const size_t bufsz = sizeof(buf); 1946 const size_t bufsz = sizeof(buf);
1780 struct statistics_tx *tx; 1947 struct statistics_tx *tx;
1781 1948
1782 if (!iwl_is_alive(priv)) 1949 if (!iwl_is_alive(priv))
1783 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1950 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1784 else { 1951 else {
1785 /* make request to uCode to retrieve statistics information */
1786 mutex_lock(&priv->mutex);
1787 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1788 mutex_unlock(&priv->mutex);
1789
1790 if (ret) {
1791 IWL_ERR(priv, "Error sending statistics request: %zd\n",
1792 ret);
1793 return -EAGAIN;
1794 }
1795 tx = &priv->statistics.tx; 1952 tx = &priv->statistics.tx;
1796 if (tx->tx_power.ant_a || 1953 if (tx->tx_power.ant_a ||
1797 tx->tx_power.ant_b || 1954 tx->tx_power.ant_b ||
@@ -1940,6 +2097,132 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1940 return count; 2097 return count;
1941} 2098}
1942 2099
2100static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2101 char __user *user_buf,
2102 size_t count, loff_t *ppos)
2103{
2104 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2105 char *buf;
2106 int pos = 0;
2107 ssize_t ret = -EFAULT;
2108
2109 if (priv->cfg->ops->lib->dump_fh) {
2110 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
2111 if (buf) {
2112 ret = simple_read_from_buffer(user_buf,
2113 count, ppos, buf, pos);
2114 kfree(buf);
2115 }
2116 }
2117
2118 return ret;
2119}
2120
2121static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2122 char __user *user_buf,
2123 size_t count, loff_t *ppos) {
2124
2125 struct iwl_priv *priv = file->private_data;
2126 int pos = 0;
2127 char buf[12];
2128 const size_t bufsz = sizeof(buf);
2129 ssize_t ret;
2130
2131 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2132 priv->missed_beacon_threshold);
2133
2134 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2135 return ret;
2136}
2137
2138static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2139 const char __user *user_buf,
2140 size_t count, loff_t *ppos)
2141{
2142 struct iwl_priv *priv = file->private_data;
2143 char buf[8];
2144 int buf_size;
2145 int missed;
2146
2147 memset(buf, 0, sizeof(buf));
2148 buf_size = min(count, sizeof(buf) - 1);
2149 if (copy_from_user(buf, user_buf, buf_size))
2150 return -EFAULT;
2151 if (sscanf(buf, "%d", &missed) != 1)
2152 return -EINVAL;
2153
2154 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2155 missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2156 priv->missed_beacon_threshold =
2157 IWL_MISSED_BEACON_THRESHOLD_DEF;
2158 else
2159 priv->missed_beacon_threshold = missed;
2160
2161 return count;
2162}
2163
2164static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2165 const char __user *user_buf,
2166 size_t count, loff_t *ppos)
2167{
2168 struct iwl_priv *priv = file->private_data;
2169 char buf[8];
2170 int buf_size;
2171 int scan;
2172
2173 memset(buf, 0, sizeof(buf));
2174 buf_size = min(count, sizeof(buf) - 1);
2175 if (copy_from_user(buf, user_buf, buf_size))
2176 return -EFAULT;
2177 if (sscanf(buf, "%d", &scan) != 1)
2178 return -EINVAL;
2179
2180 iwl_internal_short_hw_scan(priv);
2181
2182 return count;
2183}
2184
2185static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2186 char __user *user_buf,
2187 size_t count, loff_t *ppos) {
2188
2189 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2190 int pos = 0;
2191 char buf[12];
2192 const size_t bufsz = sizeof(buf);
2193 ssize_t ret;
2194
2195 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2196 priv->cfg->plcp_delta_threshold);
2197
2198 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2199 return ret;
2200}
2201
2202static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2203 const char __user *user_buf,
2204 size_t count, loff_t *ppos) {
2205
2206 struct iwl_priv *priv = file->private_data;
2207 char buf[8];
2208 int buf_size;
2209 int plcp;
2210
2211 memset(buf, 0, sizeof(buf));
2212 buf_size = min(count, sizeof(buf) - 1);
2213 if (copy_from_user(buf, user_buf, buf_size))
2214 return -EFAULT;
2215 if (sscanf(buf, "%d", &plcp) != 1)
2216 return -EINVAL;
2217 if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2218 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2219 priv->cfg->plcp_delta_threshold =
2220 IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
2221 else
2222 priv->cfg->plcp_delta_threshold = plcp;
2223 return count;
2224}
2225
1943DEBUGFS_READ_FILE_OPS(rx_statistics); 2226DEBUGFS_READ_FILE_OPS(rx_statistics);
1944DEBUGFS_READ_FILE_OPS(tx_statistics); 2227DEBUGFS_READ_FILE_OPS(tx_statistics);
1945DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2228DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1956,6 +2239,10 @@ DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1956DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 2239DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1957DEBUGFS_WRITE_FILE_OPS(csr); 2240DEBUGFS_WRITE_FILE_OPS(csr);
1958DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 2241DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2242DEBUGFS_READ_FILE_OPS(fh_reg);
2243DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2244DEBUGFS_WRITE_FILE_OPS(internal_scan);
2245DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1959 2246
1960/* 2247/*
1961 * Create the debugfs files and directories 2248 * Create the debugfs files and directories
@@ -1963,71 +2250,73 @@ DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1963 */ 2250 */
1964int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 2251int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1965{ 2252{
1966 struct iwl_debugfs *dbgfs;
1967 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 2253 struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1968 int ret = 0; 2254 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1969 2255
1970 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 2256 dir_drv = debugfs_create_dir(name, phyd);
1971 if (!dbgfs) { 2257 if (!dir_drv)
1972 ret = -ENOMEM; 2258 return -ENOMEM;
1973 goto err;
1974 }
1975 2259
1976 priv->dbgfs = dbgfs; 2260 priv->debugfs_dir = dir_drv;
1977 dbgfs->name = name; 2261
1978 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 2262 dir_data = debugfs_create_dir("data", dir_drv);
1979 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 2263 if (!dir_data)
1980 ret = -ENOENT; 2264 goto err;
2265 dir_rf = debugfs_create_dir("rf", dir_drv);
2266 if (!dir_rf)
2267 goto err;
2268 dir_debug = debugfs_create_dir("debug", dir_drv);
2269 if (!dir_debug)
1981 goto err; 2270 goto err;
1982 }
1983 2271
1984 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 2272 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1985 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 2273 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1986 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 2274 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
1987 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 2275 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1988 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 2276 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1989 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR); 2277 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1990 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 2278 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1991 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 2279 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1992 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 2280 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1993 DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); 2281 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
1994 DEBUGFS_ADD_FILE(qos, data, S_IRUSR); 2282 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1995 DEBUGFS_ADD_FILE(led, data, S_IRUSR); 2283 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
1996 DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); 2284 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1997 DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); 2285 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1998 DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); 2286 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1999 DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); 2287 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
2000 DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); 2288 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
2001 DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); 2289 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
2002 DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); 2290 DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
2003 DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); 2291 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
2004 DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); 2292 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
2005 DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); 2293 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
2006 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2294 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
2007 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2295 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
2008 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2296 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2009 DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); 2297 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2298 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2010 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2299 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2011 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2300 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2012 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2301 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2013 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2302 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
2014 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2303 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
2015 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2304 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2016 DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR); 2305 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2017 } 2306 }
2018 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2307 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
2019 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2308 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2020 &priv->disable_chain_noise_cal); 2309 &priv->disable_chain_noise_cal);
2021 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 2310 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
2022 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 2311 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
2023 DEBUGFS_ADD_BOOL(disable_tx_power, rf, 2312 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
2024 &priv->disable_tx_power_cal); 2313 &priv->disable_tx_power_cal);
2025 return 0; 2314 return 0;
2026 2315
2027err: 2316err:
2028 IWL_ERR(priv, "Can't open the debugfs directory\n"); 2317 IWL_ERR(priv, "Can't create the debugfs directory\n");
2029 iwl_dbgfs_unregister(priv); 2318 iwl_dbgfs_unregister(priv);
2030 return ret; 2319 return -ENOMEM;
2031} 2320}
2032EXPORT_SYMBOL(iwl_dbgfs_register); 2321EXPORT_SYMBOL(iwl_dbgfs_register);
2033 2322
@@ -2037,59 +2326,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
2037 */ 2326 */
2038void iwl_dbgfs_unregister(struct iwl_priv *priv) 2327void iwl_dbgfs_unregister(struct iwl_priv *priv)
2039{ 2328{
2040 if (!priv->dbgfs) 2329 if (!priv->debugfs_dir)
2041 return; 2330 return;
2042 2331
2043 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); 2332 debugfs_remove_recursive(priv->debugfs_dir);
2044 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); 2333 priv->debugfs_dir = NULL;
2045 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
2046 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
2047 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
2048 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
2049 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
2050 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
2051 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
2052 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
2053 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
2054 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
2055 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
2056 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
2057 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
2058 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
2059 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
2060 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
2061 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
2062 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
2063 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
2064 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2065 file_clear_ucode_statistics);
2066 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2067 file_clear_traffic_statistics);
2068 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr);
2069 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2070 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2071 file_ucode_rx_stats);
2072 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2073 file_ucode_tx_stats);
2074 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2075 file_ucode_general_stats);
2076 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2077 file_sensitivity);
2078 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2079 file_chain_noise);
2080 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2081 file_ucode_tracing);
2082 }
2083 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
2084 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
2085 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
2086 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
2087 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
2088 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
2089 DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
2090 DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
2091 kfree(priv->dbgfs);
2092 priv->dbgfs = NULL;
2093} 2334}
2094EXPORT_SYMBOL(iwl_dbgfs_unregister); 2335EXPORT_SYMBOL(iwl_dbgfs_unregister);
2095 2336
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 70f0e79c8e4a..55dc5a866542 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
@@ -1011,6 +1011,30 @@ struct iwl_event_log {
1011 int wraps_more_count; 1011 int wraps_more_count;
1012}; 1012};
1013 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_THRESHOLD_MAX (255)
1037
1014struct iwl_priv { 1038struct iwl_priv {
1015 1039
1016 /* ieee device used by generic ieee processing code */ 1040 /* ieee device used by generic ieee processing code */
@@ -1031,13 +1055,16 @@ struct iwl_priv {
1031 1055
1032 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 1056 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
1033 1057
1034#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
1035 /* spectrum measurement report caching */ 1058 /* spectrum measurement report caching */
1036 struct iwl_spectrum_notification measure_report; 1059 struct iwl_spectrum_notification measure_report;
1037 u8 measurement_status; 1060 u8 measurement_status;
1038#endif 1061
1039 /* ucode beacon time */ 1062 /* ucode beacon time */
1040 u32 ucode_beacon_time; 1063 u32 ucode_beacon_time;
1064 int missed_beacon_threshold;
1065
1066 /* storing the jiffies when the plcp error rate is received */
1067 unsigned long plcp_jiffies;
1041 1068
1042 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1069 /* we allocate array of iwl4965_channel_info for NIC's valid channels.
1043 * Access via channel # using indirect index array */ 1070 * Access via channel # using indirect index array */
@@ -1056,14 +1083,15 @@ struct iwl_priv {
1056 struct iwl_calib_result calib_results[IWL_CALIB_MAX]; 1083 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
1057 1084
1058 /* Scan related variables */ 1085 /* Scan related variables */
1059 unsigned long last_scan_jiffies;
1060 unsigned long next_scan_jiffies; 1086 unsigned long next_scan_jiffies;
1061 unsigned long scan_start; 1087 unsigned long scan_start;
1062 unsigned long scan_pass_start; 1088 unsigned long scan_pass_start;
1063 unsigned long scan_start_tsf; 1089 unsigned long scan_start_tsf;
1090 unsigned long last_internal_scan_jiffies;
1064 void *scan; 1091 void *scan;
1065 int scan_bands; 1092 int scan_bands;
1066 struct cfg80211_scan_request *scan_request; 1093 struct cfg80211_scan_request *scan_request;
1094 bool is_internal_short_scan;
1067 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1095 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
1068 u8 mgmt_tx_ant; 1096 u8 mgmt_tx_ant;
1069 1097
@@ -1162,6 +1190,8 @@ struct iwl_priv {
1162 struct iwl_notif_statistics statistics; 1190 struct iwl_notif_statistics statistics;
1163#ifdef CONFIG_IWLWIFI_DEBUG 1191#ifdef CONFIG_IWLWIFI_DEBUG
1164 struct iwl_notif_statistics accum_statistics; 1192 struct iwl_notif_statistics accum_statistics;
1193 struct iwl_notif_statistics delta_statistics;
1194 struct iwl_notif_statistics max_delta;
1165#endif 1195#endif
1166 1196
1167 /* context information */ 1197 /* context information */
@@ -1234,15 +1264,10 @@ struct iwl_priv {
1234 1264
1235 struct workqueue_struct *workqueue; 1265 struct workqueue_struct *workqueue;
1236 1266
1237 struct work_struct up;
1238 struct work_struct restart; 1267 struct work_struct restart;
1239 struct work_struct calibrated_work;
1240 struct work_struct scan_completed; 1268 struct work_struct scan_completed;
1241 struct work_struct rx_replenish; 1269 struct work_struct rx_replenish;
1242 struct work_struct abort_scan; 1270 struct work_struct abort_scan;
1243 struct work_struct update_link_led;
1244 struct work_struct auth_work;
1245 struct work_struct report_work;
1246 struct work_struct request_scan; 1271 struct work_struct request_scan;
1247 struct work_struct beacon_update; 1272 struct work_struct beacon_update;
1248 struct work_struct tt_work; 1273 struct work_struct tt_work;
@@ -1278,7 +1303,8 @@ struct iwl_priv {
1278 u16 rx_traffic_idx; 1303 u16 rx_traffic_idx;
1279 u8 *tx_traffic; 1304 u8 *tx_traffic;
1280 u8 *rx_traffic; 1305 u8 *rx_traffic;
1281 struct iwl_debugfs *dbgfs; 1306 struct dentry *debugfs_dir;
1307 u32 dbgfs_sram_offset, dbgfs_sram_len;
1282#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1308#endif /* CONFIG_IWLWIFI_DEBUGFS */
1283#endif /* CONFIG_IWLWIFI_DEBUG */ 1309#endif /* CONFIG_IWLWIFI_DEBUG */
1284 1310
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 87d684efe110..86783c27d97c 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index bd0b12efb5c7..45af5bbc1c56 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.
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 6f36b6e79f5e..5df66382d922 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.
@@ -473,8 +473,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)| 473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); 474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
475 475
476 /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ 476 /* Set interrupt coalescing timer to default (2048 usecs) */
477 iwl_write8(priv, CSR_INT_COALESCING, 0x40); 477 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
478 478
479 return 0; 479 return 0;
480} 480}
@@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
499 struct iwl_missed_beacon_notif *missed_beacon; 499 struct iwl_missed_beacon_notif *missed_beacon;
500 500
501 missed_beacon = &pkt->u.missed_beacon; 501 missed_beacon = &pkt->u.missed_beacon;
502 if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { 502 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
503 priv->missed_beacon_threshold) {
503 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 504 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
504 le32_to_cpu(missed_beacon->consequtive_missed_beacons), 505 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
505 le32_to_cpu(missed_beacon->total_missed_becons), 506 le32_to_cpu(missed_beacon->total_missed_becons),
506 le32_to_cpu(missed_beacon->num_recvd_beacons), 507 le32_to_cpu(missed_beacon->num_recvd_beacons),
507 le32_to_cpu(missed_beacon->num_expected_beacons)); 508 le32_to_cpu(missed_beacon->num_expected_beacons));
@@ -511,6 +512,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
511} 512}
512EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 513EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
513 514
515void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
516 struct iwl_rx_mem_buffer *rxb)
517{
518 struct iwl_rx_packet *pkt = rxb_addr(rxb);
519 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
520
521 if (!report->state) {
522 IWL_DEBUG_11H(priv,
523 "Spectrum Measure Notification: Start\n");
524 return;
525 }
526
527 memcpy(&priv->measure_report, report, sizeof(*report));
528 priv->measurement_status |= MEASUREMENT_READY;
529}
530EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
531
532
514 533
515/* Calculate noise level, based on measurements during network silence just 534/* Calculate noise level, based on measurements during network silence just
516 * before arriving beacon. This measurement can be done only if we know 535 * before arriving beacon. This measurement can be done only if we know
@@ -564,15 +583,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
564 int i; 583 int i;
565 __le32 *prev_stats; 584 __le32 *prev_stats;
566 u32 *accum_stats; 585 u32 *accum_stats;
586 u32 *delta, *max_delta;
567 587
568 prev_stats = (__le32 *)&priv->statistics; 588 prev_stats = (__le32 *)&priv->statistics;
569 accum_stats = (u32 *)&priv->accum_statistics; 589 accum_stats = (u32 *)&priv->accum_statistics;
590 delta = (u32 *)&priv->delta_statistics;
591 max_delta = (u32 *)&priv->max_delta;
570 592
571 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 593 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
572 i += sizeof(__le32), stats++, prev_stats++, accum_stats++) 594 i += sizeof(__le32), stats++, prev_stats++, delta++,
573 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) 595 max_delta++, accum_stats++) {
574 *accum_stats += (le32_to_cpu(*stats) - 596 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
597 *delta = (le32_to_cpu(*stats) -
575 le32_to_cpu(*prev_stats)); 598 le32_to_cpu(*prev_stats));
599 *accum_stats += *delta;
600 if (*delta > *max_delta)
601 *max_delta = *delta;
602 }
603 }
576 604
577 /* reset accumulative statistics for "no-counter" type statistics */ 605 /* reset accumulative statistics for "no-counter" type statistics */
578 priv->accum_statistics.general.temperature = 606 priv->accum_statistics.general.temperature =
@@ -592,11 +620,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
592 620
593#define REG_RECALIB_PERIOD (60) 621#define REG_RECALIB_PERIOD (60)
594 622
623#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
595void iwl_rx_statistics(struct iwl_priv *priv, 624void iwl_rx_statistics(struct iwl_priv *priv,
596 struct iwl_rx_mem_buffer *rxb) 625 struct iwl_rx_mem_buffer *rxb)
597{ 626{
598 int change; 627 int change;
599 struct iwl_rx_packet *pkt = rxb_addr(rxb); 628 struct iwl_rx_packet *pkt = rxb_addr(rxb);
629 int combined_plcp_delta;
630 unsigned int plcp_msec;
631 unsigned long plcp_received_jiffies;
600 632
601 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 633 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
602 (int)sizeof(priv->statistics), 634 (int)sizeof(priv->statistics),
@@ -611,6 +643,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
611#ifdef CONFIG_IWLWIFI_DEBUG 643#ifdef CONFIG_IWLWIFI_DEBUG
612 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 644 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
613#endif 645#endif
646 /*
647 * check for plcp_err and trigger radio reset if it exceeds
648 * the plcp error threshold plcp_delta.
649 */
650 plcp_received_jiffies = jiffies;
651 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
652 (long) priv->plcp_jiffies);
653 priv->plcp_jiffies = plcp_received_jiffies;
654 /*
655 * check to make sure plcp_msec is not 0 to prevent division
656 * by zero.
657 */
658 if (plcp_msec) {
659 combined_plcp_delta =
660 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
661 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
662 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
663 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
664
665 if ((combined_plcp_delta > 0) &&
666 ((combined_plcp_delta * 100) / plcp_msec) >
667 priv->cfg->plcp_delta_threshold) {
668 /*
669 * if plcp_err exceed the threshold, the following
670 * data is printed in csv format:
671 * Text: plcp_err exceeded %d,
672 * Received ofdm.plcp_err,
673 * Current ofdm.plcp_err,
674 * Received ofdm_ht.plcp_err,
675 * Current ofdm_ht.plcp_err,
676 * combined_plcp_delta,
677 * plcp_msec
678 */
679 IWL_DEBUG_RADIO(priv, PLCP_MSG,
680 priv->cfg->plcp_delta_threshold,
681 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
682 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
683 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
684 le32_to_cpu(
685 priv->statistics.rx.ofdm_ht.plcp_err),
686 combined_plcp_delta, plcp_msec);
687
688 /*
689 * Reset the RF radio due to the high plcp
690 * error rate
691 */
692 iwl_force_rf_reset(priv);
693 }
694 }
695
614 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 696 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
615 697
616 set_bit(STATUS_STATISTICS, &priv->status); 698 set_bit(STATUS_STATISTICS, &priv->status);
@@ -638,11 +720,13 @@ void iwl_reply_statistics(struct iwl_priv *priv,
638 struct iwl_rx_packet *pkt = rxb_addr(rxb); 720 struct iwl_rx_packet *pkt = rxb_addr(rxb);
639 721
640 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 722 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 723#ifdef CONFIG_IWLWIFI_DEBUG
644 memset(&priv->accum_statistics, 0, 724 memset(&priv->accum_statistics, 0,
645 sizeof(struct iwl_notif_statistics)); 725 sizeof(struct iwl_notif_statistics));
726 memset(&priv->delta_statistics, 0,
727 sizeof(struct iwl_notif_statistics));
728 memset(&priv->max_delta, 0,
729 sizeof(struct iwl_notif_statistics));
646#endif 730#endif
647 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 731 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
648 } 732 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index fa1c89ba6459..08faafae8497 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,11 @@ 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 else
254 priv->last_internal_scan_jiffies = jiffies;
255
255 IWL_DEBUG_INFO(priv, "Setting scan to off\n"); 256 IWL_DEBUG_INFO(priv, "Setting scan to off\n");
256 257
257 clear_bit(STATUS_SCANNING, &priv->status); 258 clear_bit(STATUS_SCANNING, &priv->status);
@@ -314,6 +315,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
314} 315}
315EXPORT_SYMBOL(iwl_get_passive_dwell_time); 316EXPORT_SYMBOL(iwl_get_passive_dwell_time);
316 317
318static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
319 enum ieee80211_band band,
320 struct iwl_scan_channel *scan_ch)
321{
322 const struct ieee80211_supported_band *sband;
323 const struct iwl_channel_info *ch_info;
324 u16 passive_dwell = 0;
325 u16 active_dwell = 0;
326 int i, added = 0;
327 u16 channel = 0;
328
329 sband = iwl_get_hw_mode(priv, band);
330 if (!sband) {
331 IWL_ERR(priv, "invalid band\n");
332 return added;
333 }
334
335 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
336 passive_dwell = iwl_get_passive_dwell_time(priv, band);
337
338 if (passive_dwell <= active_dwell)
339 passive_dwell = active_dwell + 1;
340
341 /* only scan single channel, good enough to reset the RF */
342 /* pick the first valid not in-use channel */
343 if (band == IEEE80211_BAND_5GHZ) {
344 for (i = 14; i < priv->channel_count; i++) {
345 if (priv->channel_info[i].channel !=
346 le16_to_cpu(priv->staging_rxon.channel)) {
347 channel = priv->channel_info[i].channel;
348 ch_info = iwl_get_channel_info(priv,
349 band, channel);
350 if (is_channel_valid(ch_info))
351 break;
352 }
353 }
354 } else {
355 for (i = 0; i < 14; i++) {
356 if (priv->channel_info[i].channel !=
357 le16_to_cpu(priv->staging_rxon.channel)) {
358 channel =
359 priv->channel_info[i].channel;
360 ch_info = iwl_get_channel_info(priv,
361 band, channel);
362 if (is_channel_valid(ch_info))
363 break;
364 }
365 }
366 }
367 if (channel) {
368 scan_ch->channel = cpu_to_le16(channel);
369 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
370 scan_ch->active_dwell = cpu_to_le16(active_dwell);
371 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
372 /* Set txpower levels to defaults */
373 scan_ch->dsp_atten = 110;
374 if (band == IEEE80211_BAND_5GHZ)
375 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
376 else
377 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
378 added++;
379 } else
380 IWL_ERR(priv, "no valid channel found\n");
381 return added;
382}
383
317static int iwl_get_channels_for_scan(struct iwl_priv *priv, 384static int iwl_get_channels_for_scan(struct iwl_priv *priv,
318 enum ieee80211_band band, 385 enum ieee80211_band band,
319 u8 is_active, u8 n_probes, 386 u8 is_active, u8 n_probes,
@@ -421,6 +488,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
421 488
422 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 489 IWL_DEBUG_INFO(priv, "Starting scan...\n");
423 set_bit(STATUS_SCANNING, &priv->status); 490 set_bit(STATUS_SCANNING, &priv->status);
491 priv->is_internal_short_scan = false;
424 priv->scan_start = jiffies; 492 priv->scan_start = jiffies;
425 priv->scan_pass_start = priv->scan_start; 493 priv->scan_pass_start = priv->scan_start;
426 494
@@ -461,15 +529,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
461 goto out_unlock; 529 goto out_unlock;
462 } 530 }
463 531
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; 532 priv->scan_bands = 0;
474 for (i = 0; i < req->n_channels; i++) 533 for (i = 0; i < req->n_channels; i++)
475 priv->scan_bands |= BIT(req->channels[i]->band); 534 priv->scan_bands |= BIT(req->channels[i]->band);
@@ -488,6 +547,54 @@ out_unlock:
488} 547}
489EXPORT_SYMBOL(iwl_mac_hw_scan); 548EXPORT_SYMBOL(iwl_mac_hw_scan);
490 549
550/*
551 * internal short scan, this function should only been called while associated.
552 * It will reset and tune the radio to prevent possible RF related problem
553 */
554#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1)
555
556int iwl_internal_short_hw_scan(struct iwl_priv *priv)
557{
558 int ret = 0;
559
560 if (!iwl_is_ready_rf(priv)) {
561 ret = -EIO;
562 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
563 goto out;
564 }
565 if (test_bit(STATUS_SCANNING, &priv->status)) {
566 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
567 ret = -EAGAIN;
568 goto out;
569 }
570 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
571 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
572 ret = -EAGAIN;
573 goto out;
574 }
575 if (priv->last_internal_scan_jiffies &&
576 time_after(priv->last_internal_scan_jiffies +
577 IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) {
578 IWL_DEBUG_SCAN(priv, "internal scan rejected\n");
579 goto out;
580 }
581
582 priv->scan_bands = 0;
583 if (priv->band == IEEE80211_BAND_5GHZ)
584 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
585 else
586 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
587
588 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
589 set_bit(STATUS_SCANNING, &priv->status);
590 priv->is_internal_short_scan = true;
591 queue_work(priv->workqueue, &priv->request_scan);
592
593out:
594 return ret;
595}
596EXPORT_SYMBOL(iwl_internal_short_hw_scan);
597
491#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 598#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
492 599
493void iwl_bg_scan_check(struct work_struct *data) 600void iwl_bg_scan_check(struct work_struct *data)
@@ -551,7 +658,8 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
551 if (WARN_ON(left < ie_len)) 658 if (WARN_ON(left < ie_len))
552 return len; 659 return len;
553 660
554 memcpy(pos, ies, ie_len); 661 if (ies)
662 memcpy(pos, ies, ie_len);
555 len += ie_len; 663 len += ie_len;
556 left -= ie_len; 664 left -= ie_len;
557 665
@@ -654,7 +762,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
654 unsigned long flags; 762 unsigned long flags;
655 763
656 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 764 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
657
658 spin_lock_irqsave(&priv->lock, flags); 765 spin_lock_irqsave(&priv->lock, flags);
659 interval = priv->beacon_int; 766 interval = priv->beacon_int;
660 spin_unlock_irqrestore(&priv->lock, flags); 767 spin_unlock_irqrestore(&priv->lock, flags);
@@ -672,7 +779,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
672 scan_suspend_time, interval); 779 scan_suspend_time, interval);
673 } 780 }
674 781
675 if (priv->scan_request->n_ssids) { 782 if (priv->is_internal_short_scan) {
783 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
784 } else if (priv->scan_request->n_ssids) {
676 int i, p = 0; 785 int i, p = 0;
677 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 786 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
678 for (i = 0; i < priv->scan_request->n_ssids; i++) { 787 for (i = 0; i < priv->scan_request->n_ssids; i++) {
@@ -753,24 +862,38 @@ static void iwl_bg_request_scan(struct work_struct *data)
753 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 862 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
754 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 863 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
755 scan->rx_chain = cpu_to_le16(rx_chain); 864 scan->rx_chain = cpu_to_le16(rx_chain);
756 cmd_len = iwl_fill_probe_req(priv, 865 if (!priv->is_internal_short_scan) {
757 (struct ieee80211_mgmt *)scan->data, 866 cmd_len = iwl_fill_probe_req(priv,
758 priv->scan_request->ie, 867 (struct ieee80211_mgmt *)scan->data,
759 priv->scan_request->ie_len, 868 priv->scan_request->ie,
760 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 869 priv->scan_request->ie_len,
870 IWL_MAX_SCAN_SIZE - sizeof(*scan));
871 } else {
872 cmd_len = iwl_fill_probe_req(priv,
873 (struct ieee80211_mgmt *)scan->data,
874 NULL, 0,
875 IWL_MAX_SCAN_SIZE - sizeof(*scan));
761 876
877 }
762 scan->tx_cmd.len = cpu_to_le16(cmd_len); 878 scan->tx_cmd.len = cpu_to_le16(cmd_len);
763
764 if (iwl_is_monitor_mode(priv)) 879 if (iwl_is_monitor_mode(priv))
765 scan->filter_flags = RXON_FILTER_PROMISC_MSK; 880 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
766 881
767 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | 882 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
768 RXON_FILTER_BCON_AWARE_MSK); 883 RXON_FILTER_BCON_AWARE_MSK);
769 884
770 scan->channel_count = 885 if (priv->is_internal_short_scan) {
771 iwl_get_channels_for_scan(priv, band, is_active, n_probes, 886 scan->channel_count =
772 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 887 iwl_get_single_channel_for_scan(priv, band,
773 888 (void *)&scan->data[le16_to_cpu(
889 scan->tx_cmd.len)]);
890 } else {
891 scan->channel_count =
892 iwl_get_channels_for_scan(priv, band,
893 is_active, n_probes,
894 (void *)&scan->data[le16_to_cpu(
895 scan->tx_cmd.len)]);
896 }
774 if (scan->channel_count == 0) { 897 if (scan->channel_count == 0) {
775 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 898 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
776 goto done; 899 goto done;
@@ -831,7 +954,12 @@ void iwl_bg_scan_completed(struct work_struct *work)
831 954
832 cancel_delayed_work(&priv->scan_check); 955 cancel_delayed_work(&priv->scan_check);
833 956
834 ieee80211_scan_completed(priv->hw, false); 957 if (!priv->is_internal_short_scan)
958 ieee80211_scan_completed(priv->hw, false);
959 else {
960 priv->is_internal_short_scan = false;
961 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
962 }
835 963
836 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 964 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
837 return; 965 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 87ce2bd292c7..d365d13e3291 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 10b0aa8024c4..119da54116de 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.
@@ -56,6 +56,7 @@
56#include "iwl-helpers.h" 56#include "iwl-helpers.h"
57#include "iwl-core.h" 57#include "iwl-core.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);
@@ -689,10 +689,6 @@ drop:
689 return -1; 689 return -1;
690} 690}
691 691
692#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
693
694#include "iwl-spectrum.h"
695
696#define BEACON_TIME_MASK_LOW 0x00FFFFFF 692#define BEACON_TIME_MASK_LOW 0x00FFFFFF
697#define BEACON_TIME_MASK_HIGH 0xFF000000 693#define BEACON_TIME_MASK_HIGH 0xFF000000
698#define TIME_UNIT 1024 694#define TIME_UNIT 1024
@@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
819 815
820 return rc; 816 return rc;
821} 817}
822#endif
823 818
824static void iwl3945_rx_reply_alive(struct iwl_priv *priv, 819static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
825 struct iwl_rx_mem_buffer *rxb) 820 struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
962 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; 957 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
963 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 958 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
964 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 959 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
960 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
961 iwl_rx_spectrum_measure_notif;
965 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 962 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
966 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 963 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
967 iwl_rx_pm_debug_statistics_notif; 964 iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
975 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 972 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
976 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 973 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
977 974
978 iwl_setup_spectrum_handlers(priv);
979 iwl_setup_rx_scan_handlers(priv); 975 iwl_setup_rx_scan_handlers(priv);
980 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 976 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
981 977
@@ -1644,7 +1640,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1644 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1640 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1645 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1641 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1646 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1642 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1647 return pos; 1643 return -EINVAL;
1648 } 1644 }
1649 1645
1650 /* event log header */ 1646 /* event log header */
@@ -1693,7 +1689,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1693 bufsz = size * 48; 1689 bufsz = size * 48;
1694 *buf = kmalloc(bufsz, GFP_KERNEL); 1690 *buf = kmalloc(bufsz, GFP_KERNEL);
1695 if (!*buf) 1691 if (!*buf)
1696 return pos; 1692 return -ENOMEM;
1697 } 1693 }
1698 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1694 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1699 /* if uCode has wrapped back to top of log, 1695 /* if uCode has wrapped back to top of log,
@@ -3037,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
3037 mutex_unlock(&priv->mutex); 3033 mutex_unlock(&priv->mutex);
3038} 3034}
3039 3035
3040static void iwl3945_bg_up(struct work_struct *data)
3041{
3042 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
3043
3044 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3045 return;
3046
3047 mutex_lock(&priv->mutex);
3048 __iwl3945_up(priv);
3049 mutex_unlock(&priv->mutex);
3050}
3051
3052static void iwl3945_bg_restart(struct work_struct *data) 3036static void iwl3945_bg_restart(struct work_struct *data)
3053{ 3037{
3054 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3038 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3065,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
3065 ieee80211_restart_hw(priv->hw); 3049 ieee80211_restart_hw(priv->hw);
3066 } else { 3050 } else {
3067 iwl3945_down(priv); 3051 iwl3945_down(priv);
3068 queue_work(priv->workqueue, &priv->up); 3052
3053 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3054 return;
3055
3056 mutex_lock(&priv->mutex);
3057 __iwl3945_up(priv);
3058 mutex_unlock(&priv->mutex);
3069 } 3059 }
3070} 3060}
3071 3061
@@ -3569,8 +3559,6 @@ static ssize_t store_filter_flags(struct device *d,
3569static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3559static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3570 store_filter_flags); 3560 store_filter_flags);
3571 3561
3572#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3573
3574static ssize_t show_measurement(struct device *d, 3562static ssize_t show_measurement(struct device *d,
3575 struct device_attribute *attr, char *buf) 3563 struct device_attribute *attr, char *buf)
3576{ 3564{
@@ -3640,7 +3628,6 @@ static ssize_t store_measurement(struct device *d,
3640 3628
3641static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, 3629static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3642 show_measurement, store_measurement); 3630 show_measurement, store_measurement);
3643#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
3644 3631
3645static ssize_t store_retry_rate(struct device *d, 3632static ssize_t store_retry_rate(struct device *d,
3646 struct device_attribute *attr, 3633 struct device_attribute *attr,
@@ -3789,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3789 3776
3790 init_waitqueue_head(&priv->wait_command_queue); 3777 init_waitqueue_head(&priv->wait_command_queue);
3791 3778
3792 INIT_WORK(&priv->up, iwl3945_bg_up);
3793 INIT_WORK(&priv->restart, iwl3945_bg_restart); 3779 INIT_WORK(&priv->restart, iwl3945_bg_restart);
3794 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); 3780 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
3795 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3781 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
@@ -3823,9 +3809,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3823 &dev_attr_dump_errors.attr, 3809 &dev_attr_dump_errors.attr,
3824 &dev_attr_flags.attr, 3810 &dev_attr_flags.attr,
3825 &dev_attr_filter_flags.attr, 3811 &dev_attr_filter_flags.attr,
3826#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3827 &dev_attr_measurement.attr, 3812 &dev_attr_measurement.attr,
3828#endif
3829 &dev_attr_retry_rate.attr, 3813 &dev_attr_retry_rate.attr,
3830 &dev_attr_statistics.attr, 3814 &dev_attr_statistics.attr,
3831 &dev_attr_status.attr, 3815 &dev_attr_status.attr,
@@ -3881,6 +3865,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3881 priv->band = IEEE80211_BAND_2GHZ; 3865 priv->band = IEEE80211_BAND_2GHZ;
3882 3866
3883 priv->iw_mode = NL80211_IFTYPE_STATION; 3867 priv->iw_mode = NL80211_IFTYPE_STATION;
3868 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3884 3869
3885 iwl_reset_qos(priv); 3870 iwl_reset_qos(priv);
3886 3871
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 5e650f358415..f03d5e4e59c3 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -1160,11 +1160,11 @@ int lbs_adhoc_stop(struct lbs_private *priv)
1160static 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,
1161 struct bss_descriptor *match_bss) 1161 struct bss_descriptor *match_bss)
1162{ 1162{
1163 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1163 if (!secinfo->wep_enabled &&
1164 && !secinfo->WPA2enabled 1164 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1165 && match_bss->wpa_ie[0] != WLAN_EID_GENERIC 1165 match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
1166 && match_bss->rsn_ie[0] != WLAN_EID_RSN 1166 match_bss->rsn_ie[0] != WLAN_EID_RSN &&
1167 && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1167 !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1168 return 1; 1168 return 1;
1169 else 1169 else
1170 return 0; 1170 return 0;
@@ -1173,9 +1173,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1173static 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,
1174 struct bss_descriptor *match_bss) 1174 struct bss_descriptor *match_bss)
1175{ 1175{
1176 if (secinfo->wep_enabled && !secinfo->WPAenabled 1176 if (secinfo->wep_enabled &&
1177 && !secinfo->WPA2enabled 1177 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1178 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1178 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1179 return 1; 1179 return 1;
1180 else 1180 else
1181 return 0; 1181 return 0;
@@ -1184,8 +1184,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1184static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, 1184static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
1185 struct bss_descriptor *match_bss) 1185 struct bss_descriptor *match_bss)
1186{ 1186{
1187 if (!secinfo->wep_enabled && secinfo->WPAenabled 1187 if (!secinfo->wep_enabled && secinfo->WPAenabled &&
1188 && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) 1188 (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
1189 /* 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
1190 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ 1190 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
1191 ) 1191 )
@@ -1210,11 +1210,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
1210static 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,
1211 struct bss_descriptor *match_bss) 1211 struct bss_descriptor *match_bss)
1212{ 1212{
1213 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1213 if (!secinfo->wep_enabled &&
1214 && !secinfo->WPA2enabled 1214 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1215 && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) 1215 (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
1216 && (match_bss->rsn_ie[0] != WLAN_EID_RSN) 1216 (match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
1217 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1217 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1218 return 1; 1218 return 1;
1219 else 1219 else
1220 return 0; 1220 return 0;
@@ -1525,8 +1525,8 @@ static int assoc_helper_associate(struct lbs_private *priv,
1525 /* 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 */
1526 1526
1527 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1527 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1528 if (compare_ether_addr(bssid_any, assoc_req->bssid) 1528 if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
1529 && compare_ether_addr(bssid_off, assoc_req->bssid)) { 1529 compare_ether_addr(bssid_off, assoc_req->bssid)) {
1530 ret = assoc_helper_bssid(priv, assoc_req); 1530 ret = assoc_helper_bssid(priv, assoc_req);
1531 done = 1; 1531 done = 1;
1532 } 1532 }
@@ -1612,11 +1612,9 @@ static int assoc_helper_channel(struct lbs_private *priv,
1612 goto restore_mesh; 1612 goto restore_mesh;
1613 } 1613 }
1614 1614
1615 if ( assoc_req->secinfo.wep_enabled 1615 if (assoc_req->secinfo.wep_enabled &&
1616 && (assoc_req->wep_keys[0].len 1616 (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
1617 || assoc_req->wep_keys[1].len 1617 assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
1618 || assoc_req->wep_keys[2].len
1619 || assoc_req->wep_keys[3].len)) {
1620 /* Make sure WEP keys are re-sent to firmware */ 1618 /* Make sure WEP keys are re-sent to firmware */
1621 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1619 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1622 } 1620 }
@@ -1983,14 +1981,14 @@ void lbs_association_worker(struct work_struct *work)
1983 assoc_req->secinfo.auth_mode); 1981 assoc_req->secinfo.auth_mode);
1984 1982
1985 /* If 'any' SSID was specified, find an SSID to associate with */ 1983 /* If 'any' SSID was specified, find an SSID to associate with */
1986 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) 1984 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
1987 && !assoc_req->ssid_len) 1985 !assoc_req->ssid_len)
1988 find_any_ssid = 1; 1986 find_any_ssid = 1;
1989 1987
1990 /* 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 */
1991 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1989 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1992 if (compare_ether_addr(assoc_req->bssid, bssid_any) 1990 if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
1993 && compare_ether_addr(assoc_req->bssid, bssid_off)) 1991 compare_ether_addr(assoc_req->bssid, bssid_off))
1994 find_any_ssid = 0; 1992 find_any_ssid = 0;
1995 } 1993 }
1996 1994
@@ -2052,13 +2050,6 @@ void lbs_association_worker(struct work_struct *work)
2052 goto out; 2050 goto out;
2053 } 2051 }
2054 2052
2055 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
2056 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2057 ret = assoc_helper_wep_keys(priv, assoc_req);
2058 if (ret)
2059 goto out;
2060 }
2061
2062 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 2053 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
2063 ret = assoc_helper_secinfo(priv, assoc_req); 2054 ret = assoc_helper_secinfo(priv, assoc_req);
2064 if (ret) 2055 if (ret)
@@ -2071,18 +2062,31 @@ void lbs_association_worker(struct work_struct *work)
2071 goto out; 2062 goto out;
2072 } 2063 }
2073 2064
2074 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) 2065 /*
2075 || 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)) {
2076 ret = assoc_helper_wpa_keys(priv, assoc_req); 2072 ret = assoc_helper_wpa_keys(priv, assoc_req);
2077 if (ret) 2073 if (ret)
2078 goto out; 2074 goto out;
2079 } 2075 }
2080 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
2081 /* SSID/BSSID should be the _last_ config option set, because they 2085 /* SSID/BSSID should be the _last_ config option set, because they
2082 * trigger the association attempt. 2086 * trigger the association attempt.
2083 */ 2087 */
2084 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) 2088 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
2085 || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 2089 test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
2086 int success = 1; 2090 int success = 1;
2087 2091
2088 ret = assoc_helper_associate(priv, assoc_req); 2092 ret = assoc_helper_associate(priv, assoc_req);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 84df3fcf37b3..0dbda8dfbd99 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -281,6 +281,8 @@ struct mac80211_hwsim_data {
281 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; 281 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
282 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 282 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
283 283
284 struct mac_address addresses[2];
285
284 struct ieee80211_channel *channel; 286 struct ieee80211_channel *channel;
285 unsigned long beacon_int; /* in jiffies unit */ 287 unsigned long beacon_int; /* in jiffies unit */
286 unsigned int rx_filter; 288 unsigned int rx_filter;
@@ -1154,7 +1156,11 @@ static int __init init_mac80211_hwsim(void)
1154 SET_IEEE80211_DEV(hw, data->dev); 1156 SET_IEEE80211_DEV(hw, data->dev);
1155 addr[3] = i >> 8; 1157 addr[3] = i >> 8;
1156 addr[4] = i; 1158 addr[4] = i;
1157 SET_IEEE80211_PERM_ADDR(hw, addr); 1159 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
1160 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
1161 data->addresses[1].addr[0] |= 0x40;
1162 hw->wiphy->n_addresses = 2;
1163 hw->wiphy->addresses = data->addresses;
1158 1164
1159 hw->channel_change_time = 1; 1165 hw->channel_change_time = 1;
1160 hw->queues = 4; 1166 hw->queues = 4;
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 68546ca0ba37..f0f08f3919cc 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
3881 struct mwl8k_priv *priv = 3881 struct mwl8k_priv *priv =
3882 container_of(work, struct mwl8k_priv, finalize_join_worker); 3882 container_of(work, struct mwl8k_priv, finalize_join_worker);
3883 struct sk_buff *skb = priv->beacon_skb; 3883 struct sk_buff *skb = priv->beacon_skb;
3884 struct mwl8k_vif *mwl8k_vif; 3884 struct ieee80211_mgmt *mgmt = (void *)skb->data;
3885 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
3886 const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
3887 mgmt->u.beacon.variable, len);
3888 int dtim_period = 1;
3889
3890 if (tim && tim[1] >= 2)
3891 dtim_period = tim[3];
3885 3892
3886 mwl8k_vif = mwl8k_first_vif(priv); 3893 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
3887 if (mwl8k_vif != NULL)
3888 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
3889 mwl8k_vif->vif->bss_conf.dtim_period);
3890 3894
3891 dev_kfree_skb(skb); 3895 dev_kfree_skb(skb);
3892 priv->beacon_skb = NULL; 3896 priv->beacon_skb = NULL;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 57c646598062..ed4bdffdd63e 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/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index b9192bfcc557..2b928ecf47bd 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -761,6 +761,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
761 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 761 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
762} 762}
763 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
764static const struct ieee80211_ops rtl8180_ops = { 772static const struct ieee80211_ops rtl8180_ops = {
765 .tx = rtl8180_tx, 773 .tx = rtl8180_tx,
766 .start = rtl8180_start, 774 .start = rtl8180_start,
@@ -771,6 +779,7 @@ static const struct ieee80211_ops rtl8180_ops = {
771 .bss_info_changed = rtl8180_bss_info_changed, 779 .bss_info_changed = rtl8180_bss_info_changed,
772 .prepare_multicast = rtl8180_prepare_multicast, 780 .prepare_multicast = rtl8180_prepare_multicast,
773 .configure_filter = rtl8180_configure_filter, 781 .configure_filter = rtl8180_configure_filter,
782 .get_tsf = rtl8180_get_tsf,
774}; 783};
775 784
776static 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_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index f336c63053c1..a05382557789 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1265,6 +1265,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
1265 return 0; 1265 return 0;
1266} 1266}
1267 1267
1268static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
1269{
1270 struct rtl8187_priv *priv = dev->priv;
1271
1272 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
1273 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
1274}
1275
1268static const struct ieee80211_ops rtl8187_ops = { 1276static const struct ieee80211_ops rtl8187_ops = {
1269 .tx = rtl8187_tx, 1277 .tx = rtl8187_tx,
1270 .start = rtl8187_start, 1278 .start = rtl8187_start,
@@ -1276,7 +1284,8 @@ static const struct ieee80211_ops rtl8187_ops = {
1276 .prepare_multicast = rtl8187_prepare_multicast, 1284 .prepare_multicast = rtl8187_prepare_multicast,
1277 .configure_filter = rtl8187_configure_filter, 1285 .configure_filter = rtl8187_configure_filter,
1278 .conf_tx = rtl8187_conf_tx, 1286 .conf_tx = rtl8187_conf_tx,
1279 .rfkill_poll = rtl8187_rfkill_poll 1287 .rfkill_poll = rtl8187_rfkill_poll,
1288 .get_tsf = rtl8187_get_tsf,
1280}; 1289};
1281 1290
1282static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 1291static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 6301578d1565..37c61c19cae5 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -341,9 +341,6 @@ struct wl1251 {
341 /* Are we currently scanning */ 341 /* Are we currently scanning */
342 bool scanning; 342 bool scanning;
343 343
344 /* Our association ID */
345 u16 aid;
346
347 /* Default key (for WEP) */ 344 /* Default key (for WEP) */
348 u32 default_key; 345 u32 default_key;
349 346
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 595f0f94d16e..a717dde4822e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
617 617
618 wl->psm_requested = true; 618 wl->psm_requested = true;
619 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
620 /* 625 /*
621 * We enter PSM only if we're already associated. 626 * mac80211 enables PSM only if we're already associated.
622 * If we're not, we'll enter it when joining an SSID,
623 * through the bss_info_changed() hook.
624 */ 627 */
625 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 628 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
626 if (ret < 0) 629 if (ret < 0)
@@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
943 struct ieee80211_bss_conf *bss_conf, 946 struct ieee80211_bss_conf *bss_conf,
944 u32 changed) 947 u32 changed)
945{ 948{
946 enum wl1251_cmd_ps_mode mode;
947 struct wl1251 *wl = hw->priv; 949 struct wl1251 *wl = hw->priv;
948 struct sk_buff *beacon, *skb; 950 struct sk_buff *beacon, *skb;
949 int ret; 951 int ret;
@@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
984 if (changed & BSS_CHANGED_ASSOC) { 986 if (changed & BSS_CHANGED_ASSOC) {
985 if (bss_conf->assoc) { 987 if (bss_conf->assoc) {
986 wl->beacon_int = bss_conf->beacon_int; 988 wl->beacon_int = bss_conf->beacon_int;
987 wl->dtim_period = bss_conf->dtim_period;
988
989 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
990 wl->dtim_period);
991 wl->aid = bss_conf->aid;
992 989
993 skb = ieee80211_pspoll_get(wl->hw, wl->vif); 990 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
994 if (!skb) 991 if (!skb)
@@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1001 if (ret < 0) 998 if (ret < 0)
1002 goto out_sleep; 999 goto out_sleep;
1003 1000
1004 ret = wl1251_acx_aid(wl, wl->aid); 1001 ret = wl1251_acx_aid(wl, bss_conf->aid);
1005 if (ret < 0) 1002 if (ret < 0)
1006 goto out_sleep; 1003 goto out_sleep;
1007
1008 /* If we want to go in PSM but we're not there yet */
1009 if (wl->psm_requested && !wl->psm) {
1010 mode = STATION_POWER_SAVE_MODE;
1011 ret = wl1251_ps_set_mode(wl, mode);
1012 if (ret < 0)
1013 goto out_sleep;
1014 }
1015 } else { 1004 } else {
1016 /* use defaults when not associated */ 1005 /* use defaults when not associated */
1017 wl->beacon_int = WL1251_DEFAULT_BEACON_INT; 1006 wl->beacon_int = WL1251_DEFAULT_BEACON_INT;