Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6

Conflicts:
drivers/net/wireless/libertas/host.h

+3633 -7660
+72 -36
drivers/net/wireless/at76c50x-usb.c
··· 7 7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> 8 8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org> 9 9 * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi> 10 + * Copyright (c) 2010 Sebastian Smolorz <sesmo@gmx.net> 10 11 * 11 12 * This program is free software; you can redistribute it and/or 12 13 * modify it under the terms of the GNU General Public License as ··· 1650 1649 return NULL; 1651 1650 } 1652 1651 1652 + static int at76_join(struct at76_priv *priv) 1653 + { 1654 + struct at76_req_join join; 1655 + int ret; 1656 + 1657 + memset(&join, 0, sizeof(struct at76_req_join)); 1658 + memcpy(join.essid, priv->essid, priv->essid_size); 1659 + join.essid_size = priv->essid_size; 1660 + memcpy(join.bssid, priv->bssid, ETH_ALEN); 1661 + join.bss_type = INFRASTRUCTURE_MODE; 1662 + join.channel = priv->channel; 1663 + join.timeout = cpu_to_le16(2000); 1664 + 1665 + at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); 1666 + ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, 1667 + sizeof(struct at76_req_join)); 1668 + 1669 + if (ret < 0) { 1670 + printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", 1671 + wiphy_name(priv->hw->wiphy), ret); 1672 + return 0; 1673 + } 1674 + 1675 + ret = at76_wait_completion(priv, CMD_JOIN); 1676 + at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); 1677 + if (ret != CMD_STATUS_COMPLETE) { 1678 + printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", 1679 + wiphy_name(priv->hw->wiphy), ret); 1680 + return 0; 1681 + } 1682 + 1683 + at76_set_pm_mode(priv); 1684 + 1685 + return 0; 1686 + } 1687 + 1688 + static void at76_work_join_bssid(struct work_struct *work) 1689 + { 1690 + struct at76_priv *priv = container_of(work, struct at76_priv, 1691 + work_join_bssid); 1692 + 1693 + if (priv->device_unplugged) 1694 + return; 1695 + 1696 + mutex_lock(&priv->mtx); 1697 + 1698 + if (is_valid_ether_addr(priv->bssid)) 1699 + at76_join(priv); 1700 + 1701 + mutex_unlock(&priv->mtx); 1702 + } 1703 + 1653 1704 static void at76_mac80211_tx_callback(struct urb *urb) 1654 1705 { 1655 1706 struct at76_priv *priv = urb->context; ··· 1739 1686 struct at76_priv *priv = hw->priv; 1740 1687 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; 1741 1688 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1689 + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1742 1690 int padding, submit_len, ret; 1743 1691 1744 1692 at76_dbg(DBG_MAC80211, "%s()", __func__); ··· 1748 1694 printk(KERN_ERR "%s: %s called while tx urb is pending\n", 1749 1695 wiphy_name(priv->hw->wiphy), __func__); 1750 1696 return NETDEV_TX_BUSY; 1697 + } 1698 + 1699 + /* The following code lines are important when the device is going to 1700 + * authenticate with a new bssid. The driver must send CMD_JOIN before 1701 + * an authentication frame is transmitted. For this to succeed, the 1702 + * correct bssid of the AP must be known. As mac80211 does not inform 1703 + * drivers about the bssid prior to the authentication process the 1704 + * following workaround is necessary. If the TX frame is an 1705 + * authentication frame extract the bssid and send the CMD_JOIN. */ 1706 + if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { 1707 + if (compare_ether_addr(priv->bssid, mgmt->bssid)) { 1708 + memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); 1709 + ieee80211_queue_work(hw, &priv->work_join_bssid); 1710 + return NETDEV_TX_BUSY; 1711 + } 1751 1712 } 1752 1713 1753 1714 ieee80211_stop_queues(hw); ··· 1839 1770 at76_dbg(DBG_MAC80211, "%s()", __func__); 1840 1771 1841 1772 cancel_delayed_work(&priv->dwork_hw_scan); 1773 + cancel_work_sync(&priv->work_join_bssid); 1842 1774 cancel_work_sync(&priv->work_set_promisc); 1843 1775 1844 1776 mutex_lock(&priv->mtx); ··· 1886 1816 struct ieee80211_vif *vif) 1887 1817 { 1888 1818 at76_dbg(DBG_MAC80211, "%s()", __func__); 1889 - } 1890 - 1891 - static int at76_join(struct at76_priv *priv) 1892 - { 1893 - struct at76_req_join join; 1894 - int ret; 1895 - 1896 - memset(&join, 0, sizeof(struct at76_req_join)); 1897 - memcpy(join.essid, priv->essid, priv->essid_size); 1898 - join.essid_size = priv->essid_size; 1899 - memcpy(join.bssid, priv->bssid, ETH_ALEN); 1900 - join.bss_type = INFRASTRUCTURE_MODE; 1901 - join.channel = priv->channel; 1902 - join.timeout = cpu_to_le16(2000); 1903 - 1904 - at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); 1905 - ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, 1906 - sizeof(struct at76_req_join)); 1907 - 1908 - if (ret < 0) { 1909 - printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", 1910 - wiphy_name(priv->hw->wiphy), ret); 1911 - return 0; 1912 - } 1913 - 1914 - ret = at76_wait_completion(priv, CMD_JOIN); 1915 - at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); 1916 - if (ret != CMD_STATUS_COMPLETE) { 1917 - printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", 1918 - wiphy_name(priv->hw->wiphy), ret); 1919 - return 0; 1920 - } 1921 - 1922 - at76_set_pm_mode(priv); 1923 - 1924 - return 0; 1925 1819 } 1926 1820 1927 1821 static void at76_dwork_hw_scan(struct work_struct *work) ··· 2141 2107 mutex_init(&priv->mtx); 2142 2108 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); 2143 2109 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); 2110 + INIT_WORK(&priv->work_join_bssid, at76_work_join_bssid); 2144 2111 INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); 2145 2112 2146 2113 tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0); ··· 2543 2508 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); 2544 2509 MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>"); 2545 2510 MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>"); 2511 + MODULE_AUTHOR("Sebastian Smolorz <sesmo@gmx.net>"); 2546 2512 MODULE_DESCRIPTION(DRIVER_DESC); 2547 2513 MODULE_LICENSE("GPL");
+1
drivers/net/wireless/at76c50x-usb.h
··· 387 387 /* work queues */ 388 388 struct work_struct work_set_promisc; 389 389 struct work_struct work_submit_rx; 390 + struct work_struct work_join_bssid; 390 391 struct delayed_work dwork_hw_scan; 391 392 392 393 struct tasklet_struct rx_tasklet;
+1 -1
drivers/net/wireless/ath/ath5k/phy.c
··· 1768 1768 1769 1769 if (enable) { 1770 1770 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, 1771 - AR5K_PHY_RESTART_DIV_GC, 1); 1771 + AR5K_PHY_RESTART_DIV_GC, 4); 1772 1772 1773 1773 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, 1774 1774 AR5K_PHY_FAST_ANT_DIV_EN);
+20
drivers/net/wireless/ath/ath9k/ar9003_hw.c
··· 295 295 /* Several PCIe massages to ensure proper behaviour */ 296 296 if (ah->config.pcie_waen) 297 297 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 298 + else 299 + REG_WRITE(ah, AR_WA, ah->WARegVal); 300 + } 301 + 302 + /* 303 + * Configire PCIE after Ini init. SERDES values now come from ini file 304 + * This enables PCIe low power mode. 305 + */ 306 + if (ah->config.pcieSerDesWrite) { 307 + unsigned int i; 308 + struct ar5416IniArray *array; 309 + 310 + array = power_off ? &ah->iniPcieSerdes : 311 + &ah->iniPcieSerdesLowPower; 312 + 313 + for (i = 0; i < array->ia_rows; i++) { 314 + REG_WRITE(ah, 315 + INI_RA(array, i, 0), 316 + INI_RA(array, i, 1)); 317 + } 298 318 } 299 319 } 300 320
+5 -1
drivers/net/wireless/ath/ath9k/ath9k.h
··· 226 226 int bfs_retries; 227 227 u8 bf_type; 228 228 u8 bfs_paprd; 229 + unsigned long bfs_paprd_timestamp; 229 230 u32 bfs_keyix; 230 231 enum ath9k_key_type bfs_keytype; 231 232 }; ··· 426 425 #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 427 426 #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 428 427 428 + #define ATH_PAPRD_TIMEOUT 100 /* msecs */ 429 + 429 430 void ath_paprd_calibrate(struct work_struct *work); 430 431 void ath_ani_calibrate(unsigned long data); 431 432 ··· 519 516 #define SC_OP_TSF_RESET BIT(11) 520 517 #define SC_OP_BT_PRIORITY_DETECTED BIT(12) 521 518 #define SC_OP_BT_SCAN BIT(13) 519 + #define SC_OP_ANI_RUN BIT(14) 522 520 523 521 /* Powersave flags */ 524 522 #define PS_WAIT_FOR_BEACON BIT(0) ··· 563 559 struct mutex mutex; 564 560 struct work_struct paprd_work; 565 561 struct completion paprd_complete; 566 - int paprd_txok; 567 562 568 563 u32 intrstatus; 569 564 u32 sc_flags; /* SC_OP_* */ ··· 631 628 632 629 extern struct ieee80211_ops ath9k_ops; 633 630 extern int modparam_nohwcrypt; 631 + extern int led_blink; 634 632 635 633 irqreturn_t ath_isr(int irq, void *dev); 636 634 int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+6 -3
drivers/net/wireless/ath/ath9k/gpio.c
··· 76 76 case LED_FULL: 77 77 if (led->led_type == ATH_LED_ASSOC) { 78 78 sc->sc_flags |= SC_OP_LED_ASSOCIATED; 79 - ieee80211_queue_delayed_work(sc->hw, 79 + if (led_blink) 80 + ieee80211_queue_delayed_work(sc->hw, 80 81 &sc->ath_led_blink_work, 0); 81 82 } else if (led->led_type == ATH_LED_RADIO) { 82 83 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); ··· 144 143 /* LED off, active low */ 145 144 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 146 145 147 - INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); 146 + if (led_blink) 147 + INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); 148 148 149 149 trigger = ieee80211_get_radio_led_name(sc->hw); 150 150 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), ··· 182 180 return; 183 181 184 182 fail: 185 - cancel_delayed_work_sync(&sc->ath_led_blink_work); 183 + if (led_blink) 184 + cancel_delayed_work_sync(&sc->ath_led_blink_work); 186 185 ath_deinit_leds(sc); 187 186 } 188 187
+24 -9
drivers/net/wireless/ath/ath9k/hif_usb.c
··· 16 16 17 17 #include "htc.h" 18 18 19 + /* identify firmware images */ 20 + #define FIRMWARE_AR7010 "ar7010.fw" 21 + #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" 22 + #define FIRMWARE_AR9271 "ar9271.fw" 23 + 24 + MODULE_FIRMWARE(FIRMWARE_AR7010); 25 + MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); 26 + MODULE_FIRMWARE(FIRMWARE_AR9271); 27 + 19 28 static struct usb_device_id ath9k_hif_usb_ids[] = { 20 - { USB_DEVICE(0x0cf3, 0x9271) }, 21 - { USB_DEVICE(0x0cf3, 0x1006) }, 22 - { USB_DEVICE(0x0cf3, 0x7010) }, 29 + { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ 30 + { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */ 31 + { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */ 32 + { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */ 33 + { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */ 34 + { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */ 35 + { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ 36 + { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ 37 + { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ 38 + { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ 39 + { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ 23 40 { }, 24 41 }; 25 42 ··· 896 879 /* Find out which firmware to load */ 897 880 898 881 switch(hif_dev->device_id) { 899 - case 0x9271: 900 - case 0x1006: 901 - hif_dev->fw_name = "ar9271.fw"; 902 - break; 903 882 case 0x7010: 883 + case 0x9018: 904 884 if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) 905 - hif_dev->fw_name = "ar7010_1_1.fw"; 885 + hif_dev->fw_name = FIRMWARE_AR7010_1_1; 906 886 else 907 - hif_dev->fw_name = "ar7010.fw"; 887 + hif_dev->fw_name = FIRMWARE_AR7010; 908 888 break; 909 889 default: 890 + hif_dev->fw_name = FIRMWARE_AR9271; 910 891 break; 911 892 } 912 893
+1
drivers/net/wireless/ath/ath9k/htc.h
··· 287 287 #define ATH_LED_PIN_DEF 1 288 288 #define ATH_LED_PIN_9287 8 289 289 #define ATH_LED_PIN_9271 15 290 + #define ATH_LED_PIN_7010 12 290 291 #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ 291 292 #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ 292 293
+2 -7
drivers/net/wireless/ath/ath9k/htc_drv_init.c
··· 244 244 */ 245 245 246 246 switch(devid) { 247 - case 0x9271: 248 - case 0x1006: 249 - priv->htc->credits = 33; 250 - break; 251 247 case 0x7010: 248 + case 0x9018: 252 249 priv->htc->credits = 45; 253 250 break; 254 251 default: 255 - dev_err(priv->dev, "ath9k_htc: Unsupported device id: 0x%x\n", 256 - devid); 257 - goto err; 252 + priv->htc->credits = 33; 258 253 } 259 254 260 255 ret = htc_init(priv->htc);
+2
drivers/net/wireless/ath/ath9k/htc_drv_main.c
··· 931 931 priv->ah->led_pin = ATH_LED_PIN_9287; 932 932 else if (AR_SREV_9271(priv->ah)) 933 933 priv->ah->led_pin = ATH_LED_PIN_9271; 934 + else if (AR_DEVID_7010(priv->ah)) 935 + priv->ah->led_pin = ATH_LED_PIN_7010; 934 936 else 935 937 priv->ah->led_pin = ATH_LED_PIN_DEF; 936 938
+83 -36
drivers/net/wireless/ath/ath9k/hw.c
··· 388 388 ah->config.ht_enable = 0; 389 389 390 390 ah->config.rx_intr_mitigation = true; 391 + ah->config.pcieSerDesWrite = true; 391 392 392 393 /* 393 394 * We need this for PCI devices only (Cardbus, PCI, miniPCI) ··· 572 571 ath9k_hw_init_mode_regs(ah); 573 572 574 573 /* 575 - * Configire PCIE after Ini init. SERDES values now come from ini file 576 - * This enables PCIe low power mode. 574 + * Read back AR_WA into a permanent copy and set bits 14 and 17. 575 + * We need to do this to avoid RMW of this register. We cannot 576 + * read the reg when chip is asleep. 577 577 */ 578 - if (AR_SREV_9300_20_OR_LATER(ah)) { 579 - u32 regval; 580 - unsigned int i; 581 - 582 - /* Set Bits 16 and 17 in the AR_WA register. */ 583 - regval = REG_READ(ah, AR_WA); 584 - regval |= 0x00030000; 585 - REG_WRITE(ah, AR_WA, regval); 586 - 587 - for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { 588 - REG_WRITE(ah, 589 - INI_RA(&ah->iniPcieSerdesLowPower, i, 0), 590 - INI_RA(&ah->iniPcieSerdesLowPower, i, 1)); 591 - } 592 - } 578 + ah->WARegVal = REG_READ(ah, AR_WA); 579 + ah->WARegVal |= (AR_WA_D3_L1_DISABLE | 580 + AR_WA_ASPM_TIMER_BASED_DISABLE); 593 581 594 582 if (ah->is_pciexpress) 595 583 ath9k_hw_configpcipowersave(ah, 0, 0); ··· 999 1009 1000 1010 ENABLE_REGWRITE_BUFFER(ah); 1001 1011 1012 + if (AR_SREV_9300_20_OR_LATER(ah)) { 1013 + REG_WRITE(ah, AR_WA, ah->WARegVal); 1014 + udelay(10); 1015 + } 1016 + 1002 1017 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1003 1018 AR_RTC_FORCE_WAKE_ON_INT); 1004 1019 ··· 1058 1063 { 1059 1064 ENABLE_REGWRITE_BUFFER(ah); 1060 1065 1066 + if (AR_SREV_9300_20_OR_LATER(ah)) { 1067 + REG_WRITE(ah, AR_WA, ah->WARegVal); 1068 + udelay(10); 1069 + } 1070 + 1061 1071 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1062 1072 AR_RTC_FORCE_WAKE_ON_INT); 1063 1073 ··· 1070 1070 REG_WRITE(ah, AR_RC, AR_RC_AHB); 1071 1071 1072 1072 REG_WRITE(ah, AR_RTC_RESET, 0); 1073 + udelay(2); 1073 1074 1074 1075 REGWRITE_BUFFER_FLUSH(ah); 1075 1076 DISABLE_REGWRITE_BUFFER(ah); ··· 1100 1099 1101 1100 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) 1102 1101 { 1102 + if (AR_SREV_9300_20_OR_LATER(ah)) { 1103 + REG_WRITE(ah, AR_WA, ah->WARegVal); 1104 + udelay(10); 1105 + } 1106 + 1103 1107 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1104 1108 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1105 1109 ··· 1268 1262 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1269 1263 1270 1264 /* For chips on which RTC reset is done, save TSF before it gets cleared */ 1271 - if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) 1265 + if (AR_SREV_9100(ah) || 1266 + (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 1272 1267 tsf = ath9k_hw_gettsf64(ah); 1273 1268 1274 1269 saveLedState = REG_READ(ah, AR_CFG_LED) & ··· 1301 1294 } 1302 1295 1303 1296 /* Restore TSF */ 1304 - if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) 1297 + if (tsf) 1305 1298 ath9k_hw_settsf64(ah, tsf); 1306 1299 1307 1300 if (AR_SREV_9280_10_OR_LATER(ah)) ··· 1313 1306 r = ath9k_hw_process_ini(ah, chan); 1314 1307 if (r) 1315 1308 return r; 1309 + 1310 + /* 1311 + * Some AR91xx SoC devices frequently fail to accept TSF writes 1312 + * right after the chip reset. When that happens, write a new 1313 + * value after the initvals have been applied, with an offset 1314 + * based on measured time difference 1315 + */ 1316 + if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { 1317 + tsf += 1500; 1318 + ath9k_hw_settsf64(ah, tsf); 1319 + } 1316 1320 1317 1321 /* Setup MFP options for CCMP */ 1318 1322 if (AR_SREV_9280_20_OR_LATER(ah)) { ··· 1510 1492 } 1511 1493 EXPORT_SYMBOL(ath9k_hw_keyreset); 1512 1494 1513 - bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) 1495 + static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) 1514 1496 { 1515 1497 u32 macHi, macLo; 1516 1498 u32 unicast_flag = AR_KEYTABLE_VALID; ··· 1548 1530 1549 1531 return true; 1550 1532 } 1551 - EXPORT_SYMBOL(ath9k_hw_keysetmac); 1552 1533 1553 1534 bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, 1554 1535 const struct ath9k_keyval *k, ··· 1748 1731 } 1749 1732 EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); 1750 1733 1751 - bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) 1752 - { 1753 - if (entry < ah->caps.keycache_size) { 1754 - u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 1755 - if (val & AR_KEYTABLE_VALID) 1756 - return true; 1757 - } 1758 - return false; 1759 - } 1760 - EXPORT_SYMBOL(ath9k_hw_keyisvalid); 1761 - 1762 1734 /******************************/ 1763 1735 /* Power Management (Chipset) */ 1764 1736 /******************************/ ··· 1774 1768 REG_CLR_BIT(ah, (AR_RTC_RESET), 1775 1769 AR_RTC_RESET_EN); 1776 1770 } 1771 + 1772 + /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ 1773 + if (AR_SREV_9300_20_OR_LATER(ah)) 1774 + REG_WRITE(ah, AR_WA, 1775 + ah->WARegVal & ~AR_WA_D3_L1_DISABLE); 1777 1776 } 1778 1777 1779 1778 /* ··· 1805 1794 AR_RTC_FORCE_WAKE_EN); 1806 1795 } 1807 1796 } 1797 + 1798 + /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ 1799 + if (AR_SREV_9300_20_OR_LATER(ah)) 1800 + REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); 1808 1801 } 1809 1802 1810 1803 static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) 1811 1804 { 1812 1805 u32 val; 1813 1806 int i; 1807 + 1808 + /* Set Bits 14 and 17 of AR_WA before powering on the chip. */ 1809 + if (AR_SREV_9300_20_OR_LATER(ah)) { 1810 + REG_WRITE(ah, AR_WA, ah->WARegVal); 1811 + udelay(10); 1812 + } 1814 1813 1815 1814 if (setChip) { 1816 1815 if ((REG_READ(ah, AR_RTC_STATUS) & ··· 2176 2155 2177 2156 if (AR_SREV_9271(ah)) 2178 2157 pCap->num_gpio_pins = AR9271_NUM_GPIO; 2158 + else if (AR_DEVID_7010(ah)) 2159 + pCap->num_gpio_pins = AR7010_NUM_GPIO; 2179 2160 else if (AR_SREV_9285_10_OR_LATER(ah)) 2180 2161 pCap->num_gpio_pins = AR9285_NUM_GPIO; 2181 2162 else if (AR_SREV_9280_10_OR_LATER(ah)) ··· 2318 2295 2319 2296 BUG_ON(gpio >= ah->caps.num_gpio_pins); 2320 2297 2321 - gpio_shift = gpio << 1; 2298 + if (AR_DEVID_7010(ah)) { 2299 + gpio_shift = gpio; 2300 + REG_RMW(ah, AR7010_GPIO_OE, 2301 + (AR7010_GPIO_OE_AS_INPUT << gpio_shift), 2302 + (AR7010_GPIO_OE_MASK << gpio_shift)); 2303 + return; 2304 + } 2322 2305 2306 + gpio_shift = gpio << 1; 2323 2307 REG_RMW(ah, 2324 2308 AR_GPIO_OE_OUT, 2325 2309 (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), ··· 2342 2312 if (gpio >= ah->caps.num_gpio_pins) 2343 2313 return 0xffffffff; 2344 2314 2345 - if (AR_SREV_9300_20_OR_LATER(ah)) 2315 + if (AR_DEVID_7010(ah)) { 2316 + u32 val; 2317 + val = REG_READ(ah, AR7010_GPIO_IN); 2318 + return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; 2319 + } else if (AR_SREV_9300_20_OR_LATER(ah)) 2346 2320 return MS_REG_READ(AR9300, gpio) != 0; 2347 2321 else if (AR_SREV_9271(ah)) 2348 2322 return MS_REG_READ(AR9271, gpio) != 0; ··· 2366 2332 { 2367 2333 u32 gpio_shift; 2368 2334 2335 + if (AR_DEVID_7010(ah)) { 2336 + gpio_shift = gpio; 2337 + REG_RMW(ah, AR7010_GPIO_OE, 2338 + (AR7010_GPIO_OE_AS_OUTPUT << gpio_shift), 2339 + (AR7010_GPIO_OE_MASK << gpio_shift)); 2340 + return; 2341 + } 2342 + 2369 2343 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 2370 - 2371 2344 gpio_shift = 2 * gpio; 2372 - 2373 2345 REG_RMW(ah, 2374 2346 AR_GPIO_OE_OUT, 2375 2347 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), ··· 2385 2345 2386 2346 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 2387 2347 { 2348 + if (AR_DEVID_7010(ah)) { 2349 + val = val ? 0 : 1; 2350 + REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio), 2351 + AR_GPIO_BIT(gpio)); 2352 + return; 2353 + } 2354 + 2388 2355 if (AR_SREV_9271(ah)) 2389 2356 val = ~val; 2390 2357
+7 -2
drivers/net/wireless/ath/ath9k/hw.h
··· 235 235 int ack_6mb; 236 236 u32 cwm_ignore_extcca; 237 237 u8 pcie_powersave_enable; 238 + bool pcieSerDesWrite; 238 239 u8 pcie_clock_req; 239 240 u32 pcie_waen; 240 241 u8 analog_shiftreg; ··· 820 819 821 820 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; 822 821 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; 822 + /* 823 + * Store the permanent value of Reg 0x4004in WARegVal 824 + * so we dont have to R/M/W. We should not be reading 825 + * this register when in sleep states. 826 + */ 827 + u32 WARegVal; 823 828 }; 824 829 825 830 static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) ··· 859 852 860 853 /* Key Cache Management */ 861 854 bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); 862 - bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac); 863 855 bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, 864 856 const struct ath9k_keyval *k, 865 857 const u8 *mac); 866 - bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry); 867 858 868 859 /* GPIO / RFKILL / Antennae */ 869 860 void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+4
drivers/net/wireless/ath/ath9k/init.c
··· 33 33 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 34 34 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); 35 35 36 + int led_blink = 1; 37 + module_param_named(blink, led_blink, int, 0444); 38 + MODULE_PARM_DESC(blink, "Enable LED blink on activity"); 39 + 36 40 /* We use the hw_value as an index into our private channel structure */ 37 41 38 42 #define CHAN2G(_freq, _idx) { \
+17 -5
drivers/net/wireless/ath/ath9k/main.c
··· 268 268 int time_left; 269 269 int i; 270 270 271 - ath9k_ps_wakeup(sc); 272 271 skb = alloc_skb(len, GFP_KERNEL); 273 272 if (!skb) 274 273 return; ··· 288 289 qnum = sc->tx.hwq_map[WME_AC_BE]; 289 290 txctl.txq = &sc->tx.txq[qnum]; 290 291 292 + ath9k_ps_wakeup(sc); 291 293 ar9003_paprd_init_table(ah); 292 294 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 293 295 if (!(ah->caps.tx_chainmask & BIT(chain))) ··· 310 310 break; 311 311 312 312 time_left = wait_for_completion_timeout(&sc->paprd_complete, 313 - 100); 313 + msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); 314 314 if (!time_left) { 315 315 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, 316 316 "Timeout waiting for paprd training on " 317 317 "TX chain %d\n", 318 318 chain); 319 - break; 319 + goto fail_paprd; 320 320 } 321 321 322 322 if (!ar9003_paprd_is_done(ah)) ··· 334 334 ath_paprd_activate(sc); 335 335 } 336 336 337 + fail_paprd: 337 338 ath9k_ps_restore(sc); 338 339 } 339 340 ··· 452 451 { 453 452 struct ath_hw *ah = common->ah; 454 453 unsigned long timestamp = jiffies_to_msecs(jiffies); 454 + struct ath_softc *sc = (struct ath_softc *) common->priv; 455 + 456 + if (!(sc->sc_flags & SC_OP_ANI_RUN)) 457 + return; 455 458 456 459 common->ani.longcal_timer = timestamp; 457 460 common->ani.shortcal_timer = timestamp; ··· 771 766 /* Reset rssi stats */ 772 767 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; 773 768 769 + sc->sc_flags |= SC_OP_ANI_RUN; 774 770 ath_start_ani(common); 775 771 } else { 776 772 ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); 777 773 common->curaid = 0; 778 774 /* Stop ANI */ 775 + sc->sc_flags &= ~SC_OP_ANI_RUN; 779 776 del_timer_sync(&common->ani.timer); 780 777 } 781 778 } ··· 1248 1241 1249 1242 aphy->state = ATH_WIPHY_INACTIVE; 1250 1243 1251 - cancel_delayed_work_sync(&sc->ath_led_blink_work); 1244 + if (led_blink) 1245 + cancel_delayed_work_sync(&sc->ath_led_blink_work); 1246 + 1252 1247 cancel_delayed_work_sync(&sc->tx_complete_work); 1253 1248 cancel_work_sync(&sc->paprd_work); 1254 1249 ··· 1383 1374 1384 1375 if (vif->type == NL80211_IFTYPE_AP || 1385 1376 vif->type == NL80211_IFTYPE_ADHOC || 1386 - vif->type == NL80211_IFTYPE_MONITOR) 1377 + vif->type == NL80211_IFTYPE_MONITOR) { 1378 + sc->sc_flags |= SC_OP_ANI_RUN; 1387 1379 ath_start_ani(common); 1380 + } 1388 1381 1389 1382 out: 1390 1383 mutex_unlock(&sc->mutex); ··· 1407 1396 mutex_lock(&sc->mutex); 1408 1397 1409 1398 /* Stop ANI */ 1399 + sc->sc_flags &= ~SC_OP_ANI_RUN; 1410 1400 del_timer_sync(&common->ani.timer); 1411 1401 1412 1402 /* Reclaim beacon resources */
+28
drivers/net/wireless/ath/ath9k/reg.h
··· 704 704 #define AR_WA_BIT7 (1 << 7) 705 705 #define AR_WA_BIT23 (1 << 23) 706 706 #define AR_WA_D3_L1_DISABLE (1 << 14) 707 + #define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16) 708 + #define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17) 709 + #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ 710 + #define AR_WA_ANALOG_SHIFT (1 << 20) 711 + #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ 707 712 #define AR9285_WA_DEFAULT 0x004a050b 708 713 #define AR9280_WA_DEFAULT 0x0040073b 709 714 #define AR_WA_DEFAULT 0x0000073f ··· 882 877 #define AR_SREV_9271_11(_ah) \ 883 878 (AR_SREV_9271(_ah) && \ 884 879 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) 880 + 885 881 #define AR_SREV_9300(_ah) \ 886 882 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) 887 883 #define AR_SREV_9300_20(_ah) \ ··· 896 890 #define AR_SREV_9285E_20(_ah) \ 897 891 (AR_SREV_9285_12_OR_LATER(_ah) && \ 898 892 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) 893 + 894 + #define AR_DEVID_7010(_ah) \ 895 + (((_ah)->hw_version.devid == 0x7010) || \ 896 + ((_ah)->hw_version.devid == 0x9018)) 899 897 900 898 #define AR_RADIO_SREV_MAJOR 0xf0 901 899 #define AR_RAD5133_SREV_MAJOR 0xc0 ··· 998 988 #define AR9287_NUM_GPIO 11 999 989 #define AR9271_NUM_GPIO 16 1000 990 #define AR9300_NUM_GPIO 17 991 + #define AR7010_NUM_GPIO 16 1001 992 1002 993 #define AR_GPIO_IN_OUT 0x4048 1003 994 #define AR_GPIO_IN_VAL 0x0FFFC000 ··· 1013 1002 #define AR9271_GPIO_IN_VAL_S 16 1014 1003 #define AR9300_GPIO_IN_VAL 0x0001FFFF 1015 1004 #define AR9300_GPIO_IN_VAL_S 0 1005 + #define AR7010_GPIO_IN_VAL 0x0000FFFF 1006 + #define AR7010_GPIO_IN_VAL_S 0 1016 1007 1017 1008 #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) 1018 1009 #define AR_GPIO_OE_OUT_DRV 0x3 ··· 1022 1009 #define AR_GPIO_OE_OUT_DRV_LOW 0x1 1023 1010 #define AR_GPIO_OE_OUT_DRV_HI 0x2 1024 1011 #define AR_GPIO_OE_OUT_DRV_ALL 0x3 1012 + 1013 + #define AR7010_GPIO_OE 0x52000 1014 + #define AR7010_GPIO_OE_MASK 0x1 1015 + #define AR7010_GPIO_OE_AS_OUTPUT 0x0 1016 + #define AR7010_GPIO_OE_AS_INPUT 0x1 1017 + #define AR7010_GPIO_IN 0x52004 1018 + #define AR7010_GPIO_OUT 0x52008 1019 + #define AR7010_GPIO_SET 0x5200C 1020 + #define AR7010_GPIO_CLEAR 0x52010 1021 + #define AR7010_GPIO_INT 0x52014 1022 + #define AR7010_GPIO_INT_TYPE 0x52018 1023 + #define AR7010_GPIO_INT_POLARITY 0x5201C 1024 + #define AR7010_GPIO_PENDING 0x52020 1025 + #define AR7010_GPIO_INT_MASK 0x52024 1026 + #define AR7010_GPIO_FUNCTION 0x52028 1025 1027 1026 1028 #define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) 1027 1029 #define AR_GPIO_INTR_POL_VAL 0x0001FFFF
+16 -5
drivers/net/wireless/ath/ath9k/xmit.c
··· 328 328 u32 ba[WME_BA_BMP_SIZE >> 5]; 329 329 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; 330 330 bool rc_update = true; 331 + struct ieee80211_tx_rate rates[4]; 331 332 332 333 skb = bf->bf_mpdu; 333 334 hdr = (struct ieee80211_hdr *)skb->data; 334 335 335 336 tx_info = IEEE80211_SKB_CB(skb); 336 337 hw = bf->aphy->hw; 338 + 339 + memcpy(rates, tx_info->control.rates, sizeof(rates)); 337 340 338 341 rcu_read_lock(); 339 342 ··· 377 374 while (bf) { 378 375 txfail = txpending = 0; 379 376 bf_next = bf->bf_next; 377 + 378 + skb = bf->bf_mpdu; 379 + tx_info = IEEE80211_SKB_CB(skb); 380 380 381 381 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { 382 382 /* transmit completion, subframe is ··· 434 428 spin_unlock_bh(&txq->axq_lock); 435 429 436 430 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 431 + memcpy(tx_info->control.rates, rates, sizeof(rates)); 437 432 ath_tx_rc_status(bf, ts, nbad, txok, true); 438 433 rc_update = false; 439 434 } else { ··· 1651 1644 } 1652 1645 1653 1646 bf->bf_state.bfs_paprd = txctl->paprd; 1647 + if (txctl->paprd) 1648 + bf->bf_state.bfs_paprd_timestamp = jiffies; 1654 1649 bf->bf_flags = setup_tx_flags(skb, use_ldpc); 1655 1650 1656 1651 bf->bf_keytype = get_hw_crypto_keytype(skb); ··· 1953 1944 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1954 1945 1955 1946 if (bf->bf_state.bfs_paprd) { 1956 - sc->paprd_txok = txok; 1957 - complete(&sc->paprd_complete); 1947 + if (time_after(jiffies, 1948 + bf->bf_state.bfs_paprd_timestamp + 1949 + msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) 1950 + dev_kfree_skb_any(skb); 1951 + else 1952 + complete(&sc->paprd_complete); 1958 1953 } else { 1959 1954 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1960 1955 ath_debug_stat_tx(sc, txq, bf, ts); ··· 2040 2027 tx_info->status.rates[i].idx = -1; 2041 2028 } 2042 2029 2043 - tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; 2030 + tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; 2044 2031 } 2045 2032 2046 2033 static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) ··· 2151 2138 * This frame is sent out as a single frame. 2152 2139 * Use hardware retry status for this frame. 2153 2140 */ 2154 - bf->bf_retries = ts.ts_longretry; 2155 2141 if (ts.ts_status & ATH9K_TXERR_XRETRY) 2156 2142 bf->bf_state.bf_type |= BUF_XRETRY; 2157 2143 ath_tx_rc_status(bf, &ts, 0, txok, true); ··· 2280 2268 } 2281 2269 2282 2270 if (!bf_isampdu(bf)) { 2283 - bf->bf_retries = txs.ts_longretry; 2284 2271 if (txs.ts_status & ATH9K_TXERR_XRETRY) 2285 2272 bf->bf_state.bf_type |= BUF_XRETRY; 2286 2273 ath_tx_rc_status(bf, &txs, 0, txok, true);
+1 -1
drivers/net/wireless/b43/main.c
··· 1804 1804 dma_reason[2], dma_reason[3], 1805 1805 dma_reason[4], dma_reason[5]); 1806 1806 b43err(dev->wl, "This device does not support DMA " 1807 - "on your system. Please use PIO instead.\n"); 1807 + "on your system. It will now be switched to PIO.\n"); 1808 1808 /* Fall back to PIO transfers if we get fatal DMA errors! */ 1809 1809 dev->use_pio = 1; 1810 1810 b43_controller_restart(dev, "DMA error");
+1
drivers/net/wireless/b43/sdio.c
··· 182 182 183 183 static const struct sdio_device_id b43_sdio_ids[] = { 184 184 { SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */ 185 + { SDIO_DEVICE(0x0092, 0x0004) }, /* C-guys, Inc. EW-CG1102GC */ 185 186 { }, 186 187 }; 187 188
+1 -2
drivers/net/wireless/hostap/hostap_ap.c
··· 688 688 struct ap_data *ap = data; 689 689 struct net_device *dev = ap->local->dev; 690 690 struct ieee80211_hdr *hdr; 691 - u16 fc, status; 691 + u16 status; 692 692 __le16 *pos; 693 693 struct sta_info *sta = NULL; 694 694 char *txt = NULL; ··· 699 699 } 700 700 701 701 hdr = (struct ieee80211_hdr *) skb->data; 702 - fc = le16_to_cpu(hdr->frame_control); 703 702 if ((!ieee80211_is_assoc_resp(hdr->frame_control) && 704 703 !ieee80211_is_reassoc_resp(hdr->frame_control)) || 705 704 skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
-2
drivers/net/wireless/hostap/hostap_main.c
··· 741 741 local_info_t *local = 742 742 container_of(work, local_info_t, set_multicast_list_queue); 743 743 struct net_device *dev = local->dev; 744 - struct hostap_interface *iface; 745 744 746 - iface = netdev_priv(dev); 747 745 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, 748 746 local->is_promisc)) { 749 747 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
+2 -2
drivers/net/wireless/iwlwifi/Makefile
··· 1 1 obj-$(CONFIG_IWLWIFI) += iwlcore.o 2 2 iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 3 - iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3 + iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o 4 4 iwlcore-objs += iwl-scan.o iwl-led.o 5 5 iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 6 6 iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o ··· 11 11 obj-$(CONFIG_IWLAGN) += iwlagn.o 12 12 iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o 13 13 iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o 14 - iwlagn-objs += iwl-agn-lib.o 14 + iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o 15 15 iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o 16 16 17 17 iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
+3
drivers/net/wireless/iwlwifi/iwl-1000.c
··· 157 157 BIT(IWL_CALIB_TX_IQ) | 158 158 BIT(IWL_CALIB_TX_IQ_PERD) | 159 159 BIT(IWL_CALIB_BASE_BAND); 160 + if (priv->cfg->need_dc_calib) 161 + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); 160 162 161 163 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 162 164 ··· 217 215 .set_ct_kill = iwl1000_set_ct_threshold, 218 216 }, 219 217 .manage_ibss_station = iwlagn_manage_ibss_station, 218 + .update_bcast_station = iwl_update_bcast_station, 220 219 .debugfs_ops = { 221 220 .rx_stats_read = iwl_ucode_rx_stats_read, 222 221 .tx_stats_read = iwl_ucode_tx_stats_read,
+5
drivers/net/wireless/iwlwifi/iwl-3945.c
··· 406 406 unsigned int plcp_msec; 407 407 unsigned long plcp_received_jiffies; 408 408 409 + if (priv->cfg->plcp_delta_threshold == 410 + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { 411 + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); 412 + return rc; 413 + } 409 414 memcpy(&current_stat, pkt->u.raw, sizeof(struct 410 415 iwl3945_notif_statistics)); 411 416 /*
+9 -4
drivers/net/wireless/iwlwifi/iwl-4965.c
··· 1580 1580 u32 R4; 1581 1581 1582 1582 if (test_bit(STATUS_TEMPERATURE, &priv->status) && 1583 - (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { 1583 + (priv->_agn.statistics.flag & 1584 + STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { 1584 1585 IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); 1585 1586 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); 1586 1587 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); ··· 1605 1604 if (!test_bit(STATUS_TEMPERATURE, &priv->status)) 1606 1605 vt = sign_extend(R4, 23); 1607 1606 else 1608 - vt = sign_extend( 1609 - le32_to_cpu(priv->statistics.general.temperature), 23); 1607 + vt = sign_extend(le32_to_cpu( 1608 + priv->_agn.statistics.general.temperature), 23); 1610 1609 1611 1610 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); 1612 1611 ··· 1786 1785 { 1787 1786 unsigned long flags; 1788 1787 u16 ra_tid; 1788 + int ret; 1789 1789 1790 1790 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1791 1791 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues ··· 1802 1800 ra_tid = BUILD_RAxTID(sta_id, tid); 1803 1801 1804 1802 /* Modify device's station table to Tx this TID */ 1805 - iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 1803 + ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 1804 + if (ret) 1805 + return ret; 1806 1806 1807 1807 spin_lock_irqsave(&priv->lock, flags); 1808 1808 ··· 2280 2276 .set_ct_kill = iwl4965_set_ct_threshold, 2281 2277 }, 2282 2278 .manage_ibss_station = iwlagn_manage_ibss_station, 2279 + .update_bcast_station = iwl_update_bcast_station, 2283 2280 .debugfs_ops = { 2284 2281 .rx_stats_read = iwl_ucode_rx_stats_read, 2285 2282 .tx_stats_read = iwl_ucode_tx_stats_read,
+7 -2
drivers/net/wireless/iwlwifi/iwl-5000.c
··· 249 249 /* Set initial calibration set */ 250 250 priv->hw_params.sens = &iwl5150_sensitivity; 251 251 priv->hw_params.calib_init_cfg = 252 - BIT(IWL_CALIB_DC) | 253 252 BIT(IWL_CALIB_LO) | 254 253 BIT(IWL_CALIB_TX_IQ) | 255 254 BIT(IWL_CALIB_BASE_BAND); 255 + if (priv->cfg->need_dc_calib) 256 + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); 256 257 257 258 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 258 259 ··· 265 264 u32 vt = 0; 266 265 s32 offset = iwl_temp_calib_to_offset(priv); 267 266 268 - vt = le32_to_cpu(priv->statistics.general.temperature); 267 + vt = le32_to_cpu(priv->_agn.statistics.general.temperature); 269 268 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 270 269 /* now vt hold the temperature in Kelvin */ 271 270 priv->temperature = KELVIN_TO_CELSIUS(vt); ··· 393 392 .set_ct_kill = iwl5000_set_ct_threshold, 394 393 }, 395 394 .manage_ibss_station = iwlagn_manage_ibss_station, 395 + .update_bcast_station = iwl_update_bcast_station, 396 396 .debugfs_ops = { 397 397 .rx_stats_read = iwl_ucode_rx_stats_read, 398 398 .tx_stats_read = iwl_ucode_tx_stats_read, ··· 456 454 .set_ct_kill = iwl5150_set_ct_threshold, 457 455 }, 458 456 .manage_ibss_station = iwlagn_manage_ibss_station, 457 + .update_bcast_station = iwl_update_bcast_station, 459 458 .debugfs_ops = { 460 459 .rx_stats_read = iwl_ucode_rx_stats_read, 461 460 .tx_stats_read = iwl_ucode_tx_stats_read, ··· 663 660 .ucode_tracing = true, 664 661 .sensitivity_calib_by_driver = true, 665 662 .chain_noise_calib_by_driver = true, 663 + .need_dc_calib = true, 666 664 }; 667 665 668 666 struct iwl_cfg iwl5150_abg_cfg = { ··· 693 689 .ucode_tracing = true, 694 690 .sensitivity_calib_by_driver = true, 695 691 .chain_noise_calib_by_driver = true, 692 + .need_dc_calib = true, 696 693 }; 697 694 698 695 MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
+36 -124
drivers/net/wireless/iwlwifi/iwl-6000.c
··· 84 84 } 85 85 86 86 /* Indicate calibration version to uCode. */ 87 - static void iwl6050_set_calib_version(struct iwl_priv *priv) 87 + static void iwl6000_set_calib_version(struct iwl_priv *priv) 88 88 { 89 - if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) 89 + if (priv->cfg->need_dc_calib && 90 + (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)) 90 91 iwl_set_bit(priv, CSR_GP_DRIVER_REG, 91 92 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); 92 93 } ··· 187 186 BIT(IWL_CALIB_LO) | 188 187 BIT(IWL_CALIB_TX_IQ) | 189 188 BIT(IWL_CALIB_BASE_BAND); 190 - 191 - priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 192 - 193 - return 0; 194 - } 195 - 196 - static int iwl6050_hw_set_hw_params(struct iwl_priv *priv) 197 - { 198 - if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 199 - priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) 200 - priv->cfg->num_of_queues = 201 - priv->cfg->mod_params->num_of_queues; 202 - 203 - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 204 - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 205 - priv->hw_params.scd_bc_tbls_size = 206 - priv->cfg->num_of_queues * 207 - sizeof(struct iwlagn_scd_bc_tbl); 208 - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 209 - priv->hw_params.max_stations = IWL5000_STATION_COUNT; 210 - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 211 - 212 - priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 213 - priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 214 - 215 - priv->hw_params.max_bsm_size = 0; 216 - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 217 - BIT(IEEE80211_BAND_5GHZ); 218 - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 219 - 220 - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 221 - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 222 - priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 223 - priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 224 - 225 - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 226 - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); 227 - 228 - /* Set initial sensitivity parameters */ 229 - /* Set initial calibration set */ 230 - priv->hw_params.sens = &iwl6000_sensitivity; 231 - priv->hw_params.calib_init_cfg = 232 - BIT(IWL_CALIB_XTAL) | 233 - BIT(IWL_CALIB_DC) | 234 - BIT(IWL_CALIB_LO) | 235 - BIT(IWL_CALIB_TX_IQ) | 236 - BIT(IWL_CALIB_BASE_BAND); 189 + if (priv->cfg->need_dc_calib) 190 + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); 237 191 238 192 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 239 193 ··· 315 359 .temp_ops = { 316 360 .temperature = iwlagn_temperature, 317 361 .set_ct_kill = iwl6000_set_ct_threshold, 362 + .set_calib_version = iwl6000_set_calib_version, 318 363 }, 319 364 .manage_ibss_station = iwlagn_manage_ibss_station, 365 + .update_bcast_station = iwl_update_bcast_station, 320 366 .debugfs_ops = { 321 367 .rx_stats_read = iwl_ucode_rx_stats_read, 322 368 .tx_stats_read = iwl_ucode_tx_stats_read, ··· 355 397 .led = &iwlagn_led_ops, 356 398 }; 357 399 358 - static struct iwl_lib_ops iwl6050_lib = { 359 - .set_hw_params = iwl6050_hw_set_hw_params, 360 - .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 361 - .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 362 - .txq_set_sched = iwlagn_txq_set_sched, 363 - .txq_agg_enable = iwlagn_txq_agg_enable, 364 - .txq_agg_disable = iwlagn_txq_agg_disable, 365 - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 366 - .txq_free_tfd = iwl_hw_txq_free_tfd, 367 - .txq_init = iwl_hw_tx_queue_init, 368 - .rx_handler_setup = iwlagn_rx_handler_setup, 369 - .setup_deferred_work = iwlagn_setup_deferred_work, 370 - .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 371 - .load_ucode = iwlagn_load_ucode, 372 - .dump_nic_event_log = iwl_dump_nic_event_log, 373 - .dump_nic_error_log = iwl_dump_nic_error_log, 374 - .dump_csr = iwl_dump_csr, 375 - .dump_fh = iwl_dump_fh, 376 - .init_alive_start = iwlagn_init_alive_start, 377 - .alive_notify = iwlagn_alive_notify, 378 - .send_tx_power = iwlagn_send_tx_power, 379 - .update_chain_flags = iwl_update_chain_flags, 380 - .set_channel_switch = iwl6000_hw_channel_switch, 381 - .apm_ops = { 382 - .init = iwl_apm_init, 383 - .stop = iwl_apm_stop, 384 - .config = iwl6000_nic_config, 385 - .set_pwr_src = iwl_set_pwr_src, 386 - }, 387 - .eeprom_ops = { 388 - .regulatory_bands = { 389 - EEPROM_REG_BAND_1_CHANNELS, 390 - EEPROM_REG_BAND_2_CHANNELS, 391 - EEPROM_REG_BAND_3_CHANNELS, 392 - EEPROM_REG_BAND_4_CHANNELS, 393 - EEPROM_REG_BAND_5_CHANNELS, 394 - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, 395 - EEPROM_REG_BAND_52_HT40_CHANNELS 396 - }, 397 - .verify_signature = iwlcore_eeprom_verify_signature, 398 - .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 399 - .release_semaphore = iwlcore_eeprom_release_semaphore, 400 - .calib_version = iwlagn_eeprom_calib_version, 401 - .query_addr = iwlagn_eeprom_query_addr, 402 - .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 403 - }, 404 - .post_associate = iwl_post_associate, 405 - .isr = iwl_isr_ict, 406 - .config_ap = iwl_config_ap, 407 - .temp_ops = { 408 - .temperature = iwlagn_temperature, 409 - .set_ct_kill = iwl6000_set_ct_threshold, 410 - .set_calib_version = iwl6050_set_calib_version, 411 - }, 412 - .manage_ibss_station = iwlagn_manage_ibss_station, 413 - .debugfs_ops = { 414 - .rx_stats_read = iwl_ucode_rx_stats_read, 415 - .tx_stats_read = iwl_ucode_tx_stats_read, 416 - .general_stats_read = iwl_ucode_general_stats_read, 417 - }, 418 - .recover_from_tx_stall = iwl_bg_monitor_recover, 419 - .check_plcp_health = iwl_good_plcp_health, 420 - .check_ack_health = iwl_good_ack_health, 421 - }; 422 - 423 - static const struct iwl_ops iwl6050_ops = { 424 - .lib = &iwl6050_lib, 425 - .hcmd = &iwlagn_hcmd, 426 - .utils = &iwlagn_hcmd_utils, 427 - .led = &iwlagn_led_ops, 428 - }; 429 - 430 - 431 400 struct iwl_cfg iwl6000g2a_2agn_cfg = { 432 401 .name = "6000 Series 2x2 AGN Gen2a", 433 402 .fw_name_pre = IWL6000G2A_FW_PRE, ··· 390 505 .ucode_tracing = true, 391 506 .sensitivity_calib_by_driver = true, 392 507 .chain_noise_calib_by_driver = true, 508 + .need_dc_calib = true, 393 509 }; 394 510 395 511 struct iwl_cfg iwl6000g2a_2abg_cfg = { ··· 423 537 .chain_noise_scale = 1000, 424 538 .monitor_recover_period = IWL_MONITORING_PERIOD, 425 539 .max_event_log_size = 512, 540 + .sensitivity_calib_by_driver = true, 541 + .chain_noise_calib_by_driver = true, 542 + .need_dc_calib = true, 426 543 }; 427 544 428 545 struct iwl_cfg iwl6000g2a_2bg_cfg = { ··· 458 569 .chain_noise_scale = 1000, 459 570 .monitor_recover_period = IWL_MONITORING_PERIOD, 460 571 .max_event_log_size = 512, 572 + .sensitivity_calib_by_driver = true, 573 + .chain_noise_calib_by_driver = true, 574 + .need_dc_calib = true, 461 575 }; 462 576 463 577 struct iwl_cfg iwl6000g2b_2agn_cfg = { ··· 495 603 .chain_noise_scale = 1000, 496 604 .monitor_recover_period = IWL_MONITORING_PERIOD, 497 605 .max_event_log_size = 512, 606 + .sensitivity_calib_by_driver = true, 607 + .chain_noise_calib_by_driver = true, 608 + .need_dc_calib = true, 498 609 }; 499 610 500 611 struct iwl_cfg iwl6000g2b_2abg_cfg = { ··· 530 635 .chain_noise_scale = 1000, 531 636 .monitor_recover_period = IWL_MONITORING_PERIOD, 532 637 .max_event_log_size = 512, 638 + .sensitivity_calib_by_driver = true, 639 + .chain_noise_calib_by_driver = true, 640 + .need_dc_calib = true, 533 641 }; 534 642 535 643 struct iwl_cfg iwl6000g2b_2bgn_cfg = { ··· 567 669 .chain_noise_scale = 1000, 568 670 .monitor_recover_period = IWL_MONITORING_PERIOD, 569 671 .max_event_log_size = 512, 672 + .sensitivity_calib_by_driver = true, 673 + .chain_noise_calib_by_driver = true, 674 + .need_dc_calib = true, 570 675 }; 571 676 572 677 struct iwl_cfg iwl6000g2b_2bg_cfg = { ··· 602 701 .chain_noise_scale = 1000, 603 702 .monitor_recover_period = IWL_MONITORING_PERIOD, 604 703 .max_event_log_size = 512, 704 + .sensitivity_calib_by_driver = true, 705 + .chain_noise_calib_by_driver = true, 706 + .need_dc_calib = true, 605 707 }; 606 708 607 709 struct iwl_cfg iwl6000g2b_bgn_cfg = { ··· 639 735 .chain_noise_scale = 1000, 640 736 .monitor_recover_period = IWL_MONITORING_PERIOD, 641 737 .max_event_log_size = 512, 738 + .sensitivity_calib_by_driver = true, 739 + .chain_noise_calib_by_driver = true, 740 + .need_dc_calib = true, 642 741 }; 643 742 644 743 struct iwl_cfg iwl6000g2b_bg_cfg = { ··· 674 767 .chain_noise_scale = 1000, 675 768 .monitor_recover_period = IWL_MONITORING_PERIOD, 676 769 .max_event_log_size = 512, 770 + .sensitivity_calib_by_driver = true, 771 + .chain_noise_calib_by_driver = true, 772 + .need_dc_calib = true, 677 773 }; 678 774 679 775 /* ··· 795 885 .ucode_api_max = IWL6050_UCODE_API_MAX, 796 886 .ucode_api_min = IWL6050_UCODE_API_MIN, 797 887 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 798 - .ops = &iwl6050_ops, 888 + .ops = &iwl6000_ops, 799 889 .eeprom_size = OTP_LOW_IMAGE_SIZE, 800 890 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 801 891 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, ··· 824 914 .ucode_tracing = true, 825 915 .sensitivity_calib_by_driver = true, 826 916 .chain_noise_calib_by_driver = true, 917 + .need_dc_calib = true, 827 918 }; 828 919 829 920 struct iwl_cfg iwl6050_2abg_cfg = { ··· 833 922 .ucode_api_max = IWL6050_UCODE_API_MAX, 834 923 .ucode_api_min = IWL6050_UCODE_API_MIN, 835 924 .sku = IWL_SKU_A|IWL_SKU_G, 836 - .ops = &iwl6050_ops, 925 + .ops = &iwl6000_ops, 837 926 .eeprom_size = OTP_LOW_IMAGE_SIZE, 838 927 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 839 928 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, ··· 860 949 .ucode_tracing = true, 861 950 .sensitivity_calib_by_driver = true, 862 951 .chain_noise_calib_by_driver = true, 952 + .need_dc_calib = true, 863 953 }; 864 954 865 955 struct iwl_cfg iwl6000_3agn_cfg = {
+36 -36
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
··· 33 33 int p = 0; 34 34 35 35 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", 36 - le32_to_cpu(priv->statistics.flag)); 37 - if (le32_to_cpu(priv->statistics.flag) & 36 + le32_to_cpu(priv->_agn.statistics.flag)); 37 + if (le32_to_cpu(priv->_agn.statistics.flag) & 38 38 UCODE_STATISTICS_CLEAR_MSK) 39 39 p += scnprintf(buf + p, bufsz - p, 40 40 "\tStatistics have been cleared\n"); 41 41 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", 42 - (le32_to_cpu(priv->statistics.flag) & 42 + (le32_to_cpu(priv->_agn.statistics.flag) & 43 43 UCODE_STATISTICS_FREQUENCY_MSK) 44 44 ? "2.4 GHz" : "5.2 GHz"); 45 45 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", 46 - (le32_to_cpu(priv->statistics.flag) & 46 + (le32_to_cpu(priv->_agn.statistics.flag) & 47 47 UCODE_STATISTICS_NARROW_BAND_MSK) 48 48 ? "enabled" : "disabled"); 49 49 return p; ··· 79 79 * the last statistics notification from uCode 80 80 * might not reflect the current uCode activity 81 81 */ 82 - ofdm = &priv->statistics.rx.ofdm; 83 - cck = &priv->statistics.rx.cck; 84 - general = &priv->statistics.rx.general; 85 - ht = &priv->statistics.rx.ofdm_ht; 86 - accum_ofdm = &priv->accum_statistics.rx.ofdm; 87 - accum_cck = &priv->accum_statistics.rx.cck; 88 - accum_general = &priv->accum_statistics.rx.general; 89 - accum_ht = &priv->accum_statistics.rx.ofdm_ht; 90 - delta_ofdm = &priv->delta_statistics.rx.ofdm; 91 - delta_cck = &priv->delta_statistics.rx.cck; 92 - delta_general = &priv->delta_statistics.rx.general; 93 - delta_ht = &priv->delta_statistics.rx.ofdm_ht; 94 - max_ofdm = &priv->max_delta.rx.ofdm; 95 - max_cck = &priv->max_delta.rx.cck; 96 - max_general = &priv->max_delta.rx.general; 97 - max_ht = &priv->max_delta.rx.ofdm_ht; 82 + ofdm = &priv->_agn.statistics.rx.ofdm; 83 + cck = &priv->_agn.statistics.rx.cck; 84 + general = &priv->_agn.statistics.rx.general; 85 + ht = &priv->_agn.statistics.rx.ofdm_ht; 86 + accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; 87 + accum_cck = &priv->_agn.accum_statistics.rx.cck; 88 + accum_general = &priv->_agn.accum_statistics.rx.general; 89 + accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; 90 + delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; 91 + delta_cck = &priv->_agn.delta_statistics.rx.cck; 92 + delta_general = &priv->_agn.delta_statistics.rx.general; 93 + delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; 94 + max_ofdm = &priv->_agn.max_delta.rx.ofdm; 95 + max_cck = &priv->_agn.max_delta.rx.cck; 96 + max_general = &priv->_agn.max_delta.rx.general; 97 + max_ht = &priv->_agn.max_delta.rx.ofdm_ht; 98 98 99 99 pos += iwl_statistics_flag(priv, buf, bufsz); 100 100 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" ··· 560 560 * the last statistics notification from uCode 561 561 * might not reflect the current uCode activity 562 562 */ 563 - tx = &priv->statistics.tx; 564 - accum_tx = &priv->accum_statistics.tx; 565 - delta_tx = &priv->delta_statistics.tx; 566 - max_tx = &priv->max_delta.tx; 563 + tx = &priv->_agn.statistics.tx; 564 + accum_tx = &priv->_agn.accum_statistics.tx; 565 + delta_tx = &priv->_agn.delta_statistics.tx; 566 + max_tx = &priv->_agn.max_delta.tx; 567 567 pos += iwl_statistics_flag(priv, buf, bufsz); 568 568 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 569 569 "acumulative delta max\n", ··· 777 777 * the last statistics notification from uCode 778 778 * might not reflect the current uCode activity 779 779 */ 780 - general = &priv->statistics.general; 781 - dbg = &priv->statistics.general.dbg; 782 - div = &priv->statistics.general.div; 783 - accum_general = &priv->accum_statistics.general; 784 - delta_general = &priv->delta_statistics.general; 785 - max_general = &priv->max_delta.general; 786 - accum_dbg = &priv->accum_statistics.general.dbg; 787 - delta_dbg = &priv->delta_statistics.general.dbg; 788 - max_dbg = &priv->max_delta.general.dbg; 789 - accum_div = &priv->accum_statistics.general.div; 790 - delta_div = &priv->delta_statistics.general.div; 791 - max_div = &priv->max_delta.general.div; 780 + general = &priv->_agn.statistics.general; 781 + dbg = &priv->_agn.statistics.general.dbg; 782 + div = &priv->_agn.statistics.general.div; 783 + accum_general = &priv->_agn.accum_statistics.general; 784 + delta_general = &priv->_agn.delta_statistics.general; 785 + max_general = &priv->_agn.max_delta.general; 786 + accum_dbg = &priv->_agn.accum_statistics.general.dbg; 787 + delta_dbg = &priv->_agn.delta_statistics.general.dbg; 788 + max_dbg = &priv->_agn.max_delta.general.dbg; 789 + accum_div = &priv->_agn.accum_statistics.general.div; 790 + delta_div = &priv->_agn.delta_statistics.general.div; 791 + max_div = &priv->_agn.max_delta.general.div; 792 792 pos += iwl_statistics_flag(priv, buf, bufsz); 793 793 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 794 794 "acumulative delta max\n",
+1 -5
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
··· 214 214 static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 215 215 __le32 *tx_flags) 216 216 { 217 - if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || 218 - (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) 219 - *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; 220 - else 221 - *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; 217 + *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; 222 218 } 223 219 224 220 /* Calc max signal level (dBm) among 3 possible receivers */
+2 -1
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
··· 361 361 void iwlagn_temperature(struct iwl_priv *priv) 362 362 { 363 363 /* store temperature from statistics (in Celsius) */ 364 - priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 364 + priv->temperature = 365 + le32_to_cpu(priv->_agn.statistics.general.temperature); 365 366 iwl_tt_handler(priv); 366 367 } 367 368
+5 -12
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
··· 324 324 struct iwl_lq_sta *lq_data, 325 325 struct ieee80211_sta *sta) 326 326 { 327 - if ((tid < TID_MAX_LOAD_COUNT) && 328 - !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) { 329 - if (priv->cfg->use_rts_for_ht) { 330 - /* 331 - * switch to RTS/CTS if it is the prefer protection 332 - * method for HT traffic 333 - */ 334 - IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n"); 335 - priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; 336 - iwlcore_commit_rxon(priv); 337 - } 338 - } 327 + if (tid < TID_MAX_LOAD_COUNT) 328 + rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); 329 + else 330 + IWL_ERR(priv, "tid exceeds max load count: %d/%d\n", 331 + tid, TID_MAX_LOAD_COUNT); 339 332 } 340 333 341 334 static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
+284
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
··· 1 + /****************************************************************************** 2 + * 3 + * GPL LICENSE SUMMARY 4 + * 5 + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 6 + * 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 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, but 12 + * WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 19 + * USA 20 + * 21 + * The full GNU General Public License is included in this distribution 22 + * in the file called LICENSE.GPL. 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/sched.h> 34 + 35 + #include "iwl-dev.h" 36 + #include "iwl-core.h" 37 + #include "iwl-calib.h" 38 + #include "iwl-sta.h" 39 + #include "iwl-io.h" 40 + #include "iwl-helpers.h" 41 + #include "iwl-agn-hw.h" 42 + #include "iwl-agn.h" 43 + 44 + void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 45 + struct iwl_rx_mem_buffer *rxb) 46 + 47 + { 48 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 49 + struct iwl_missed_beacon_notif *missed_beacon; 50 + 51 + missed_beacon = &pkt->u.missed_beacon; 52 + if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > 53 + priv->missed_beacon_threshold) { 54 + IWL_DEBUG_CALIB(priv, 55 + "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 56 + le32_to_cpu(missed_beacon->consecutive_missed_beacons), 57 + le32_to_cpu(missed_beacon->total_missed_becons), 58 + le32_to_cpu(missed_beacon->num_recvd_beacons), 59 + le32_to_cpu(missed_beacon->num_expected_beacons)); 60 + if (!test_bit(STATUS_SCANNING, &priv->status)) 61 + iwl_init_sensitivity(priv); 62 + } 63 + } 64 + 65 + /* Calculate noise level, based on measurements during network silence just 66 + * before arriving beacon. This measurement can be done only if we know 67 + * exactly when to expect beacons, therefore only when we're associated. */ 68 + static void iwl_rx_calc_noise(struct iwl_priv *priv) 69 + { 70 + struct statistics_rx_non_phy *rx_info 71 + = &(priv->_agn.statistics.rx.general); 72 + int num_active_rx = 0; 73 + int total_silence = 0; 74 + int bcn_silence_a = 75 + le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; 76 + int bcn_silence_b = 77 + le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; 78 + int bcn_silence_c = 79 + le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; 80 + int last_rx_noise; 81 + 82 + if (bcn_silence_a) { 83 + total_silence += bcn_silence_a; 84 + num_active_rx++; 85 + } 86 + if (bcn_silence_b) { 87 + total_silence += bcn_silence_b; 88 + num_active_rx++; 89 + } 90 + if (bcn_silence_c) { 91 + total_silence += bcn_silence_c; 92 + num_active_rx++; 93 + } 94 + 95 + /* Average among active antennas */ 96 + if (num_active_rx) 97 + last_rx_noise = (total_silence / num_active_rx) - 107; 98 + else 99 + last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 100 + 101 + IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", 102 + bcn_silence_a, bcn_silence_b, bcn_silence_c, 103 + last_rx_noise); 104 + } 105 + 106 + #ifdef CONFIG_IWLWIFI_DEBUGFS 107 + /* 108 + * based on the assumption of all statistics counter are in DWORD 109 + * FIXME: This function is for debugging, do not deal with 110 + * the case of counters roll-over. 111 + */ 112 + static void iwl_accumulative_statistics(struct iwl_priv *priv, 113 + __le32 *stats) 114 + { 115 + int i; 116 + __le32 *prev_stats; 117 + u32 *accum_stats; 118 + u32 *delta, *max_delta; 119 + 120 + prev_stats = (__le32 *)&priv->_agn.statistics; 121 + accum_stats = (u32 *)&priv->_agn.accum_statistics; 122 + delta = (u32 *)&priv->_agn.delta_statistics; 123 + max_delta = (u32 *)&priv->_agn.max_delta; 124 + 125 + for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 126 + i += sizeof(__le32), stats++, prev_stats++, delta++, 127 + max_delta++, accum_stats++) { 128 + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { 129 + *delta = (le32_to_cpu(*stats) - 130 + le32_to_cpu(*prev_stats)); 131 + *accum_stats += *delta; 132 + if (*delta > *max_delta) 133 + *max_delta = *delta; 134 + } 135 + } 136 + 137 + /* reset accumulative statistics for "no-counter" type statistics */ 138 + priv->_agn.accum_statistics.general.temperature = 139 + priv->_agn.statistics.general.temperature; 140 + priv->_agn.accum_statistics.general.temperature_m = 141 + priv->_agn.statistics.general.temperature_m; 142 + priv->_agn.accum_statistics.general.ttl_timestamp = 143 + priv->_agn.statistics.general.ttl_timestamp; 144 + priv->_agn.accum_statistics.tx.tx_power.ant_a = 145 + priv->_agn.statistics.tx.tx_power.ant_a; 146 + priv->_agn.accum_statistics.tx.tx_power.ant_b = 147 + priv->_agn.statistics.tx.tx_power.ant_b; 148 + priv->_agn.accum_statistics.tx.tx_power.ant_c = 149 + priv->_agn.statistics.tx.tx_power.ant_c; 150 + } 151 + #endif 152 + 153 + #define REG_RECALIB_PERIOD (60) 154 + 155 + /** 156 + * iwl_good_plcp_health - checks for plcp error. 157 + * 158 + * When the plcp error is exceeding the thresholds, reset the radio 159 + * to improve the throughput. 160 + */ 161 + bool iwl_good_plcp_health(struct iwl_priv *priv, 162 + struct iwl_rx_packet *pkt) 163 + { 164 + bool rc = true; 165 + int combined_plcp_delta; 166 + unsigned int plcp_msec; 167 + unsigned long plcp_received_jiffies; 168 + 169 + if (priv->cfg->plcp_delta_threshold == 170 + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { 171 + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); 172 + return rc; 173 + } 174 + 175 + /* 176 + * check for plcp_err and trigger radio reset if it exceeds 177 + * the plcp error threshold plcp_delta. 178 + */ 179 + plcp_received_jiffies = jiffies; 180 + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - 181 + (long) priv->plcp_jiffies); 182 + priv->plcp_jiffies = plcp_received_jiffies; 183 + /* 184 + * check to make sure plcp_msec is not 0 to prevent division 185 + * by zero. 186 + */ 187 + if (plcp_msec) { 188 + combined_plcp_delta = 189 + (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - 190 + le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) + 191 + (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - 192 + le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err)); 193 + 194 + if ((combined_plcp_delta > 0) && 195 + ((combined_plcp_delta * 100) / plcp_msec) > 196 + priv->cfg->plcp_delta_threshold) { 197 + /* 198 + * if plcp_err exceed the threshold, 199 + * the following data is printed in csv format: 200 + * Text: plcp_err exceeded %d, 201 + * Received ofdm.plcp_err, 202 + * Current ofdm.plcp_err, 203 + * Received ofdm_ht.plcp_err, 204 + * Current ofdm_ht.plcp_err, 205 + * combined_plcp_delta, 206 + * plcp_msec 207 + */ 208 + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 209 + "%u, %u, %u, %u, %d, %u mSecs\n", 210 + priv->cfg->plcp_delta_threshold, 211 + le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 212 + le32_to_cpu( 213 + priv->_agn.statistics.rx.ofdm.plcp_err), 214 + le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 215 + le32_to_cpu( 216 + priv->_agn.statistics.rx.ofdm_ht.plcp_err), 217 + combined_plcp_delta, plcp_msec); 218 + rc = false; 219 + } 220 + } 221 + return rc; 222 + } 223 + 224 + void iwl_rx_statistics(struct iwl_priv *priv, 225 + struct iwl_rx_mem_buffer *rxb) 226 + { 227 + int change; 228 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 229 + 230 + 231 + IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 232 + (int)sizeof(priv->_agn.statistics), 233 + le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 234 + 235 + change = ((priv->_agn.statistics.general.temperature != 236 + pkt->u.stats.general.temperature) || 237 + ((priv->_agn.statistics.flag & 238 + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 239 + (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 240 + 241 + #ifdef CONFIG_IWLWIFI_DEBUGFS 242 + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 243 + #endif 244 + iwl_recover_from_statistics(priv, pkt); 245 + 246 + memcpy(&priv->_agn.statistics, &pkt->u.stats, 247 + sizeof(priv->_agn.statistics)); 248 + 249 + set_bit(STATUS_STATISTICS, &priv->status); 250 + 251 + /* Reschedule the statistics timer to occur in 252 + * REG_RECALIB_PERIOD seconds to ensure we get a 253 + * thermal update even if the uCode doesn't give 254 + * us one */ 255 + mod_timer(&priv->statistics_periodic, jiffies + 256 + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); 257 + 258 + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && 259 + (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { 260 + iwl_rx_calc_noise(priv); 261 + queue_work(priv->workqueue, &priv->run_time_calib_work); 262 + } 263 + if (priv->cfg->ops->lib->temp_ops.temperature && change) 264 + priv->cfg->ops->lib->temp_ops.temperature(priv); 265 + } 266 + 267 + void iwl_reply_statistics(struct iwl_priv *priv, 268 + struct iwl_rx_mem_buffer *rxb) 269 + { 270 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 271 + 272 + if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 273 + #ifdef CONFIG_IWLWIFI_DEBUGFS 274 + memset(&priv->_agn.accum_statistics, 0, 275 + sizeof(struct iwl_notif_statistics)); 276 + memset(&priv->_agn.delta_statistics, 0, 277 + sizeof(struct iwl_notif_statistics)); 278 + memset(&priv->_agn.max_delta, 0, 279 + sizeof(struct iwl_notif_statistics)); 280 + #endif 281 + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 282 + } 283 + iwl_rx_statistics(priv, rxb); 284 + }
+4 -1
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
··· 233 233 { 234 234 unsigned long flags; 235 235 u16 ra_tid; 236 + int ret; 236 237 237 238 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 238 239 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues ··· 249 248 ra_tid = BUILD_RAxTID(sta_id, tid); 250 249 251 250 /* Modify device's station table to Tx this TID */ 252 - iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 251 + ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 252 + if (ret) 253 + return ret; 253 254 254 255 spin_lock_irqsave(&priv->lock, flags); 255 256
+49 -24
drivers/net/wireless/iwlwifi/iwl-agn.c
··· 1461 1461 1462 1462 actual_ack_cnt_delta = 1463 1463 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - 1464 - le32_to_cpu(priv->statistics.tx.actual_ack_cnt); 1464 + le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt); 1465 1465 expected_ack_cnt_delta = 1466 1466 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - 1467 - le32_to_cpu(priv->statistics.tx.expected_ack_cnt); 1467 + le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt); 1468 1468 ba_timeout_delta = 1469 1469 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - 1470 - le32_to_cpu(priv->statistics.tx.agg.ba_timeout); 1470 + le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout); 1471 1471 if ((priv->_agn.agg_tids_count > 0) && 1472 1472 (expected_ack_cnt_delta > 0) && 1473 1473 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) ··· 1484 1484 * DEBUG is not, these will just compile out. 1485 1485 */ 1486 1486 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", 1487 - priv->delta_statistics.tx.rx_detected_cnt); 1487 + priv->_agn.delta_statistics.tx.rx_detected_cnt); 1488 1488 IWL_DEBUG_RADIO(priv, 1489 1489 "ack_or_ba_timeout_collision delta = %d\n", 1490 - priv->delta_statistics.tx. 1490 + priv->_agn.delta_statistics.tx. 1491 1491 ack_or_ba_timeout_collision); 1492 1492 #endif 1493 1493 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", ··· 2310 2310 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, 2311 2311 blink1, blink2, ilink1, ilink2); 2312 2312 2313 - IWL_ERR(priv, "Desc Time " 2313 + IWL_ERR(priv, "Desc Time " 2314 2314 "data1 data2 line\n"); 2315 - IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", 2315 + IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", 2316 2316 desc_lookup(desc), desc, time, data1, data2, line); 2317 2317 IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); 2318 2318 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", ··· 2935 2935 } 2936 2936 2937 2937 if (priv->start_calib) { 2938 - iwl_chain_noise_calibration(priv, &priv->statistics); 2938 + iwl_chain_noise_calibration(priv, &priv->_agn.statistics); 2939 2939 2940 - iwl_sensitivity_calibration(priv, &priv->statistics); 2940 + iwl_sensitivity_calibration(priv, &priv->_agn.statistics); 2941 2941 } 2942 2942 2943 2943 mutex_unlock(&priv->mutex); ··· 3368 3368 return ret; 3369 3369 } 3370 3370 3371 + /* 3372 + * switch to RTS/CTS for TX 3373 + */ 3374 + static void iwl_enable_rts_cts(struct iwl_priv *priv) 3375 + { 3376 + 3377 + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3378 + return; 3379 + 3380 + priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; 3381 + if (!test_bit(STATUS_SCANNING, &priv->status)) { 3382 + IWL_DEBUG_INFO(priv, "use RTS/CTS protection\n"); 3383 + iwlcore_commit_rxon(priv); 3384 + } else { 3385 + /* scanning, defer the request until scan completed */ 3386 + IWL_DEBUG_INFO(priv, "defer setting RTS/CTS protection\n"); 3387 + } 3388 + } 3389 + 3371 3390 static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 3372 3391 struct ieee80211_vif *vif, 3373 3392 enum ieee80211_ampdu_mlme_action action, 3374 3393 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3375 3394 { 3376 3395 struct iwl_priv *priv = hw->priv; 3377 - int ret; 3396 + int ret = -EINVAL; 3378 3397 3379 3398 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", 3380 3399 sta->addr, tid); ··· 3401 3382 if (!(priv->cfg->sku & IWL_SKU_N)) 3402 3383 return -EACCES; 3403 3384 3385 + mutex_lock(&priv->mutex); 3386 + 3404 3387 switch (action) { 3405 3388 case IEEE80211_AMPDU_RX_START: 3406 3389 IWL_DEBUG_HT(priv, "start Rx\n"); 3407 - return iwl_sta_rx_agg_start(priv, sta, tid, *ssn); 3390 + ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); 3391 + break; 3408 3392 case IEEE80211_AMPDU_RX_STOP: 3409 3393 IWL_DEBUG_HT(priv, "stop Rx\n"); 3410 3394 ret = iwl_sta_rx_agg_stop(priv, sta, tid); 3411 3395 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3412 - return 0; 3413 - else 3414 - return ret; 3396 + ret = 0; 3397 + break; 3415 3398 case IEEE80211_AMPDU_TX_START: 3416 3399 IWL_DEBUG_HT(priv, "start Tx\n"); 3417 3400 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); ··· 3422 3401 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n", 3423 3402 priv->_agn.agg_tids_count); 3424 3403 } 3425 - return ret; 3404 + break; 3426 3405 case IEEE80211_AMPDU_TX_STOP: 3427 3406 IWL_DEBUG_HT(priv, "stop Tx\n"); 3428 3407 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); ··· 3432 3411 priv->_agn.agg_tids_count); 3433 3412 } 3434 3413 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3435 - return 0; 3436 - else 3437 - return ret; 3414 + ret = 0; 3415 + break; 3438 3416 case IEEE80211_AMPDU_TX_OPERATIONAL: 3439 - /* do nothing */ 3440 - return -EOPNOTSUPP; 3441 - default: 3442 - IWL_DEBUG_HT(priv, "unknown\n"); 3443 - return -EINVAL; 3417 + if (priv->cfg->use_rts_for_ht) { 3418 + /* 3419 + * switch to RTS/CTS if it is the prefer protection 3420 + * method for HT traffic 3421 + */ 3422 + iwl_enable_rts_cts(priv); 3423 + } 3424 + ret = 0; 3444 3425 break; 3445 3426 } 3446 - return 0; 3427 + mutex_unlock(&priv->mutex); 3428 + 3429 + return ret; 3447 3430 } 3448 3431 3449 3432 static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
+10
drivers/net/wireless/iwlwifi/iwl-agn.h
··· 201 201 (status == TX_STATUS_DIRECT_DONE); 202 202 } 203 203 204 + /* rx */ 205 + void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 206 + struct iwl_rx_mem_buffer *rxb); 207 + bool iwl_good_plcp_health(struct iwl_priv *priv, 208 + struct iwl_rx_packet *pkt); 209 + void iwl_rx_statistics(struct iwl_priv *priv, 210 + struct iwl_rx_mem_buffer *rxb); 211 + void iwl_reply_statistics(struct iwl_priv *priv, 212 + struct iwl_rx_mem_buffer *rxb); 213 + 204 214 /* scan */ 205 215 void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 206 216
+9 -18
drivers/net/wireless/iwlwifi/iwl-calib.c drivers/net/wireless/iwlwifi/iwl-agn-calib.c
··· 96 96 hcmd.len = priv->calib_results[i].buf_len; 97 97 hcmd.data = priv->calib_results[i].buf; 98 98 ret = iwl_send_cmd_sync(priv, &hcmd); 99 - if (ret) 100 - goto err; 99 + if (ret) { 100 + IWL_ERR(priv, "Error %d iteration %d\n", 101 + ret, i); 102 + break; 103 + } 101 104 } 102 105 } 103 106 104 - return 0; 105 - err: 106 - IWL_ERR(priv, "Error %d iteration %d\n", ret, i); 107 107 return ret; 108 108 } 109 - EXPORT_SYMBOL(iwl_send_calib_results); 110 109 111 110 int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) 112 111 { ··· 120 121 memcpy(res->buf, buf, len); 121 122 return 0; 122 123 } 123 - EXPORT_SYMBOL(iwl_calib_set); 124 124 125 125 void iwl_calib_free_results(struct iwl_priv *priv) 126 126 { ··· 131 133 priv->calib_results[i].buf_len = 0; 132 134 } 133 135 } 134 - EXPORT_SYMBOL(iwl_calib_free_results); 135 136 136 137 /***************************************************************************** 137 138 * RUNTIME calibrations framework ··· 530 533 ret |= iwl_sensitivity_write(priv); 531 534 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); 532 535 } 533 - EXPORT_SYMBOL(iwl_init_sensitivity); 534 536 535 537 void iwl_sensitivity_calibration(struct iwl_priv *priv, 536 538 struct iwl_notif_statistics *resp) ··· 635 639 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); 636 640 iwl_sensitivity_write(priv); 637 641 } 638 - EXPORT_SYMBOL(iwl_sensitivity_calibration); 639 642 640 643 static inline u8 find_first_chain(u8 mask) 641 644 { ··· 843 848 844 849 if (active_chains != priv->hw_params.valid_rx_ant && 845 850 active_chains != priv->chain_noise_data.active_chains) 846 - IWL_WARN(priv, 847 - "Detected that not all antennas are connected! " 848 - "Connected: %#x, valid: %#x.\n", 849 - active_chains, priv->hw_params.valid_rx_ant); 851 + IWL_DEBUG_CALIB(priv, 852 + "Detected that not all antennas are connected! " 853 + "Connected: %#x, valid: %#x.\n", 854 + active_chains, priv->hw_params.valid_rx_ant); 850 855 851 856 /* Save for use within RXON, TX, SCAN commands, etc. */ 852 857 priv->chain_noise_data.active_chains = active_chains; ··· 892 897 data->state = IWL_CHAIN_NOISE_DONE; 893 898 iwl_power_update_mode(priv, false); 894 899 } 895 - EXPORT_SYMBOL(iwl_chain_noise_calibration); 896 - 897 900 898 901 void iwl_reset_run_time_calib(struct iwl_priv *priv) 899 902 { ··· 908 915 * periodically after association */ 909 916 iwl_send_statistics_request(priv, CMD_ASYNC, true); 910 917 } 911 - EXPORT_SYMBOL(iwl_reset_run_time_calib); 912 -
+21 -9
drivers/net/wireless/iwlwifi/iwl-commands.h
··· 1399 1399 1400 1400 /* REPLY_TX Tx flags field */ 1401 1401 1402 - /* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it 1402 + /* 1403 + * 1: Use RTS/CTS protocol or CTS-to-self if spec allows it 1403 1404 * before this frame. if CTS-to-self required check 1404 - * RXON_FLG_SELF_CTS_EN status. */ 1405 - #define TX_CMD_FLG_RTS_CTS_MSK cpu_to_le32(1 << 0) 1405 + * RXON_FLG_SELF_CTS_EN status. 1406 + * unused in 3945/4965, used in 5000 series and after 1407 + */ 1408 + #define TX_CMD_FLG_PROT_REQUIRE_MSK cpu_to_le32(1 << 0) 1406 1409 1407 - /* 1: Use Request-To-Send protocol before this frame. 1408 - * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ 1410 + /* 1411 + * 1: Use Request-To-Send protocol before this frame. 1412 + * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. 1413 + * used in 3945/4965, unused in 5000 series and after 1414 + */ 1409 1415 #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) 1410 1416 1411 - /* 1: Transmit Clear-To-Send to self before this frame. 1417 + /* 1418 + * 1: Transmit Clear-To-Send to self before this frame. 1412 1419 * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. 1413 - * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ 1420 + * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. 1421 + * used in 3945/4965, unused in 5000 series and after 1422 + */ 1414 1423 #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) 1415 1424 1416 1425 /* 1: Expect ACK from receiving station ··· 1439 1430 * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ 1440 1431 #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) 1441 1432 1442 - /* 1: Frame requires full Tx-Op protection. 1443 - * Set this if either RTS or CTS Tx Flag gets set. */ 1433 + /* 1434 + * 1: Frame requires full Tx-Op protection. 1435 + * Set this if either RTS or CTS Tx Flag gets set. 1436 + * used in 3945/4965, unused in 5000 series and after 1437 + */ 1444 1438 #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) 1445 1439 1446 1440 /* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
+21 -1
drivers/net/wireless/iwlwifi/iwl-core.c
··· 1331 1331 changed_flags, *total_flags); 1332 1332 1333 1333 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); 1334 - CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK); 1335 1334 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); 1336 1335 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); 1337 1336 ··· 1345 1346 1346 1347 mutex_unlock(&priv->mutex); 1347 1348 1349 + /* 1350 + * Receiving all multicast frames is always enabled by the 1351 + * default flags setup in iwl_connection_init_rx_config() 1352 + * since we currently do not support programming multicast 1353 + * filters into the device. 1354 + */ 1348 1355 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | 1349 1356 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 1350 1357 } ··· 2110 2105 iwl_set_flags_for_band(priv, conf->channel->band, priv->vif); 2111 2106 spin_unlock_irqrestore(&priv->lock, flags); 2112 2107 2108 + if (priv->cfg->ops->lib->update_bcast_station) 2109 + ret = priv->cfg->ops->lib->update_bcast_station(priv); 2110 + 2113 2111 set_ch_out: 2114 2112 /* The list of supported rates and rate mask can be different 2115 2113 * for each band; since the band may have changed, reset ··· 2845 2837 { 2846 2838 struct iwl_priv *priv = pci_get_drvdata(pdev); 2847 2839 int ret; 2840 + bool hw_rfkill = false; 2848 2841 2849 2842 /* 2850 2843 * We disable the RETRY_TIMEOUT register (0x41) to keep ··· 2859 2850 return ret; 2860 2851 pci_restore_state(pdev); 2861 2852 iwl_enable_interrupts(priv); 2853 + 2854 + if (!(iwl_read32(priv, CSR_GP_CNTRL) & 2855 + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) 2856 + hw_rfkill = true; 2857 + 2858 + if (hw_rfkill) 2859 + set_bit(STATUS_RF_KILL_HW, &priv->status); 2860 + else 2861 + clear_bit(STATUS_RF_KILL_HW, &priv->status); 2862 + 2863 + wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rfkill); 2862 2864 2863 2865 return 0; 2864 2866 }
+2 -10
drivers/net/wireless/iwlwifi/iwl-core.h
··· 196 196 /* station management */ 197 197 int (*manage_ibss_station)(struct iwl_priv *priv, 198 198 struct ieee80211_vif *vif, bool add); 199 + int (*update_bcast_station)(struct iwl_priv *priv); 199 200 /* recover from tx queue stall */ 200 201 void (*recover_from_tx_stall)(unsigned long data); 201 202 /* check for plcp health */ ··· 331 330 const bool chain_noise_calib_by_driver; 332 331 u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; 333 332 u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; 333 + const bool need_dc_calib; 334 334 }; 335 335 336 336 /*************************** ··· 457 455 int iwl_rx_queue_space(const struct iwl_rx_queue *q); 458 456 void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 459 457 /* Handlers */ 460 - void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 461 - struct iwl_rx_mem_buffer *rxb); 462 458 void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 463 459 struct iwl_rx_mem_buffer *rxb); 464 - bool iwl_good_plcp_health(struct iwl_priv *priv, 465 - struct iwl_rx_packet *pkt); 466 - bool iwl_good_ack_health(struct iwl_priv *priv, 467 - struct iwl_rx_packet *pkt); 468 460 void iwl_recover_from_statistics(struct iwl_priv *priv, 469 461 struct iwl_rx_packet *pkt); 470 - void iwl_rx_statistics(struct iwl_priv *priv, 471 - struct iwl_rx_mem_buffer *rxb); 472 - void iwl_reply_statistics(struct iwl_priv *priv, 473 - struct iwl_rx_mem_buffer *rxb); 474 462 void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); 475 463 void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 476 464
+2 -2
drivers/net/wireless/iwlwifi/iwl-debugfs.c
··· 1430 1430 return -EFAULT; 1431 1431 if (sscanf(buf, "%d", &plcp) != 1) 1432 1432 return -EINVAL; 1433 - if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 1433 + if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 1434 1434 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 1435 1435 priv->cfg->plcp_delta_threshold = 1436 - IWL_MAX_PLCP_ERR_THRESHOLD_DEF; 1436 + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 1437 1437 else 1438 1438 priv->cfg->plcp_delta_threshold = plcp; 1439 1439 return count;
+9 -8
drivers/net/wireless/iwlwifi/iwl-dev.h
··· 1036 1036 * This is the threshold value of plcp error rate per 100mSecs. It is 1037 1037 * used to set and check for the validity of plcp_delta. 1038 1038 */ 1039 - #define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0) 1039 + #define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) 1040 1040 #define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) 1041 1041 #define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) 1042 1042 #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) 1043 1043 #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) 1044 + #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) 1044 1045 1045 1046 #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) 1046 1047 #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) ··· 1225 1224 struct iwl_power_mgr power_data; 1226 1225 struct iwl_tt_mgmt thermal_throttle; 1227 1226 1228 - struct iwl_notif_statistics statistics; 1229 - #ifdef CONFIG_IWLWIFI_DEBUGFS 1230 - struct iwl_notif_statistics accum_statistics; 1231 - struct iwl_notif_statistics delta_statistics; 1232 - struct iwl_notif_statistics max_delta; 1233 - #endif 1234 - 1235 1227 /* context information */ 1236 1228 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ 1237 1229 ··· 1317 1323 1318 1324 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; 1319 1325 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; 1326 + 1327 + struct iwl_notif_statistics statistics; 1328 + #ifdef CONFIG_IWLWIFI_DEBUGFS 1329 + struct iwl_notif_statistics accum_statistics; 1330 + struct iwl_notif_statistics delta_statistics; 1331 + struct iwl_notif_statistics max_delta; 1332 + #endif 1320 1333 } _agn; 1321 1334 #endif 1322 1335 };
+3
drivers/net/wireless/iwlwifi/iwl-eeprom.c
··· 629 629 calib_ver < priv->cfg->eeprom_calib_ver) 630 630 goto err; 631 631 632 + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", 633 + eeprom_ver, calib_ver); 634 + 632 635 return 0; 633 636 err: 634 637 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
-238
drivers/net/wireless/iwlwifi/iwl-rx.c
··· 205 205 } 206 206 EXPORT_SYMBOL(iwl_rx_queue_alloc); 207 207 208 - void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 209 - struct iwl_rx_mem_buffer *rxb) 210 - 211 - { 212 - struct iwl_rx_packet *pkt = rxb_addr(rxb); 213 - struct iwl_missed_beacon_notif *missed_beacon; 214 - 215 - missed_beacon = &pkt->u.missed_beacon; 216 - if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > 217 - priv->missed_beacon_threshold) { 218 - IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 219 - le32_to_cpu(missed_beacon->consecutive_missed_beacons), 220 - le32_to_cpu(missed_beacon->total_missed_becons), 221 - le32_to_cpu(missed_beacon->num_recvd_beacons), 222 - le32_to_cpu(missed_beacon->num_expected_beacons)); 223 - if (!test_bit(STATUS_SCANNING, &priv->status)) 224 - iwl_init_sensitivity(priv); 225 - } 226 - } 227 - EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 228 208 229 209 void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 230 210 struct iwl_rx_mem_buffer *rxb) ··· 222 242 priv->measurement_status |= MEASUREMENT_READY; 223 243 } 224 244 EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); 225 - 226 - 227 - 228 - /* Calculate noise level, based on measurements during network silence just 229 - * before arriving beacon. This measurement can be done only if we know 230 - * exactly when to expect beacons, therefore only when we're associated. */ 231 - static void iwl_rx_calc_noise(struct iwl_priv *priv) 232 - { 233 - struct statistics_rx_non_phy *rx_info 234 - = &(priv->statistics.rx.general); 235 - int num_active_rx = 0; 236 - int total_silence = 0; 237 - int bcn_silence_a = 238 - le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; 239 - int bcn_silence_b = 240 - le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; 241 - int bcn_silence_c = 242 - le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; 243 - int last_rx_noise; 244 - 245 - if (bcn_silence_a) { 246 - total_silence += bcn_silence_a; 247 - num_active_rx++; 248 - } 249 - if (bcn_silence_b) { 250 - total_silence += bcn_silence_b; 251 - num_active_rx++; 252 - } 253 - if (bcn_silence_c) { 254 - total_silence += bcn_silence_c; 255 - num_active_rx++; 256 - } 257 - 258 - /* Average among active antennas */ 259 - if (num_active_rx) 260 - last_rx_noise = (total_silence / num_active_rx) - 107; 261 - else 262 - last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 263 - 264 - IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", 265 - bcn_silence_a, bcn_silence_b, bcn_silence_c, 266 - last_rx_noise); 267 - } 268 - 269 - #ifdef CONFIG_IWLWIFI_DEBUGFS 270 - /* 271 - * based on the assumption of all statistics counter are in DWORD 272 - * FIXME: This function is for debugging, do not deal with 273 - * the case of counters roll-over. 274 - */ 275 - static void iwl_accumulative_statistics(struct iwl_priv *priv, 276 - __le32 *stats) 277 - { 278 - int i; 279 - __le32 *prev_stats; 280 - u32 *accum_stats; 281 - u32 *delta, *max_delta; 282 - 283 - prev_stats = (__le32 *)&priv->statistics; 284 - accum_stats = (u32 *)&priv->accum_statistics; 285 - delta = (u32 *)&priv->delta_statistics; 286 - max_delta = (u32 *)&priv->max_delta; 287 - 288 - for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 289 - i += sizeof(__le32), stats++, prev_stats++, delta++, 290 - max_delta++, accum_stats++) { 291 - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { 292 - *delta = (le32_to_cpu(*stats) - 293 - le32_to_cpu(*prev_stats)); 294 - *accum_stats += *delta; 295 - if (*delta > *max_delta) 296 - *max_delta = *delta; 297 - } 298 - } 299 - 300 - /* reset accumulative statistics for "no-counter" type statistics */ 301 - priv->accum_statistics.general.temperature = 302 - priv->statistics.general.temperature; 303 - priv->accum_statistics.general.temperature_m = 304 - priv->statistics.general.temperature_m; 305 - priv->accum_statistics.general.ttl_timestamp = 306 - priv->statistics.general.ttl_timestamp; 307 - priv->accum_statistics.tx.tx_power.ant_a = 308 - priv->statistics.tx.tx_power.ant_a; 309 - priv->accum_statistics.tx.tx_power.ant_b = 310 - priv->statistics.tx.tx_power.ant_b; 311 - priv->accum_statistics.tx.tx_power.ant_c = 312 - priv->statistics.tx.tx_power.ant_c; 313 - } 314 - #endif 315 - 316 - #define REG_RECALIB_PERIOD (60) 317 - 318 - /** 319 - * iwl_good_plcp_health - checks for plcp error. 320 - * 321 - * When the plcp error is exceeding the thresholds, reset the radio 322 - * to improve the throughput. 323 - */ 324 - bool iwl_good_plcp_health(struct iwl_priv *priv, 325 - struct iwl_rx_packet *pkt) 326 - { 327 - bool rc = true; 328 - int combined_plcp_delta; 329 - unsigned int plcp_msec; 330 - unsigned long plcp_received_jiffies; 331 - 332 - /* 333 - * check for plcp_err and trigger radio reset if it exceeds 334 - * the plcp error threshold plcp_delta. 335 - */ 336 - plcp_received_jiffies = jiffies; 337 - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - 338 - (long) priv->plcp_jiffies); 339 - priv->plcp_jiffies = plcp_received_jiffies; 340 - /* 341 - * check to make sure plcp_msec is not 0 to prevent division 342 - * by zero. 343 - */ 344 - if (plcp_msec) { 345 - combined_plcp_delta = 346 - (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - 347 - le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) + 348 - (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - 349 - le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); 350 - 351 - if ((combined_plcp_delta > 0) && 352 - ((combined_plcp_delta * 100) / plcp_msec) > 353 - priv->cfg->plcp_delta_threshold) { 354 - /* 355 - * if plcp_err exceed the threshold, 356 - * the following data is printed in csv format: 357 - * Text: plcp_err exceeded %d, 358 - * Received ofdm.plcp_err, 359 - * Current ofdm.plcp_err, 360 - * Received ofdm_ht.plcp_err, 361 - * Current ofdm_ht.plcp_err, 362 - * combined_plcp_delta, 363 - * plcp_msec 364 - */ 365 - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 366 - "%u, %u, %u, %u, %d, %u mSecs\n", 367 - priv->cfg->plcp_delta_threshold, 368 - le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 369 - le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), 370 - le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 371 - le32_to_cpu( 372 - priv->statistics.rx.ofdm_ht.plcp_err), 373 - combined_plcp_delta, plcp_msec); 374 - rc = false; 375 - } 376 - } 377 - return rc; 378 - } 379 - EXPORT_SYMBOL(iwl_good_plcp_health); 380 245 381 246 void iwl_recover_from_statistics(struct iwl_priv *priv, 382 247 struct iwl_rx_packet *pkt) ··· 255 430 } 256 431 } 257 432 EXPORT_SYMBOL(iwl_recover_from_statistics); 258 - 259 - void iwl_rx_statistics(struct iwl_priv *priv, 260 - struct iwl_rx_mem_buffer *rxb) 261 - { 262 - int change; 263 - struct iwl_rx_packet *pkt = rxb_addr(rxb); 264 - 265 - 266 - IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 267 - (int)sizeof(priv->statistics), 268 - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 269 - 270 - change = ((priv->statistics.general.temperature != 271 - pkt->u.stats.general.temperature) || 272 - ((priv->statistics.flag & 273 - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 274 - (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 275 - 276 - #ifdef CONFIG_IWLWIFI_DEBUGFS 277 - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 278 - #endif 279 - iwl_recover_from_statistics(priv, pkt); 280 - 281 - memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 282 - 283 - set_bit(STATUS_STATISTICS, &priv->status); 284 - 285 - /* Reschedule the statistics timer to occur in 286 - * REG_RECALIB_PERIOD seconds to ensure we get a 287 - * thermal update even if the uCode doesn't give 288 - * us one */ 289 - mod_timer(&priv->statistics_periodic, jiffies + 290 - msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); 291 - 292 - if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && 293 - (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { 294 - iwl_rx_calc_noise(priv); 295 - queue_work(priv->workqueue, &priv->run_time_calib_work); 296 - } 297 - if (priv->cfg->ops->lib->temp_ops.temperature && change) 298 - priv->cfg->ops->lib->temp_ops.temperature(priv); 299 - } 300 - EXPORT_SYMBOL(iwl_rx_statistics); 301 - 302 - void iwl_reply_statistics(struct iwl_priv *priv, 303 - struct iwl_rx_mem_buffer *rxb) 304 - { 305 - struct iwl_rx_packet *pkt = rxb_addr(rxb); 306 - 307 - if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 308 - #ifdef CONFIG_IWLWIFI_DEBUGFS 309 - memset(&priv->accum_statistics, 0, 310 - sizeof(struct iwl_notif_statistics)); 311 - memset(&priv->delta_statistics, 0, 312 - sizeof(struct iwl_notif_statistics)); 313 - memset(&priv->max_delta, 0, 314 - sizeof(struct iwl_notif_statistics)); 315 - #endif 316 - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 317 - } 318 - iwl_rx_statistics(priv, rxb); 319 - } 320 - EXPORT_SYMBOL(iwl_reply_statistics); 321 433 322 434 /* 323 435 * returns non-zero if packet should be dropped
+9
drivers/net/wireless/iwlwifi/iwl-scan.c
··· 537 537 /* Since setting the TXPOWER may have been deferred while 538 538 * performing the scan, fire one off */ 539 539 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); 540 + 541 + /* 542 + * Since setting the RXON may have been deferred while 543 + * performing the scan, fire one off if needed 544 + */ 545 + if (memcmp(&priv->active_rxon, 546 + &priv->staging_rxon, sizeof(priv->staging_rxon))) 547 + iwlcore_commit_rxon(priv); 548 + 540 549 out: 541 550 mutex_unlock(&priv->mutex); 542 551
+80 -26
drivers/net/wireless/iwlwifi/iwl-sta.c
··· 30 30 #include <net/mac80211.h> 31 31 #include <linux/etherdevice.h> 32 32 #include <linux/sched.h> 33 + #include <linux/lockdep.h> 33 34 34 35 #include "iwl-dev.h" 35 36 #include "iwl-core.h" ··· 55 54 } 56 55 } 57 56 58 - static void iwl_process_add_sta_resp(struct iwl_priv *priv, 59 - struct iwl_addsta_cmd *addsta, 60 - struct iwl_rx_packet *pkt, 61 - bool sync) 57 + static int iwl_process_add_sta_resp(struct iwl_priv *priv, 58 + struct iwl_addsta_cmd *addsta, 59 + struct iwl_rx_packet *pkt, 60 + bool sync) 62 61 { 63 62 u8 sta_id = addsta->sta.sta_id; 64 63 unsigned long flags; 64 + int ret = -EIO; 65 65 66 66 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 67 67 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 68 68 pkt->hdr.flags); 69 - return; 69 + return ret; 70 70 } 71 71 72 72 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", ··· 79 77 case ADD_STA_SUCCESS_MSK: 80 78 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); 81 79 iwl_sta_ucode_activate(priv, sta_id); 80 + ret = 0; 82 81 break; 83 82 case ADD_STA_NO_ROOM_IN_TABLE: 84 83 IWL_ERR(priv, "Adding station %d failed, no room in table.\n", ··· 117 114 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 118 115 addsta->sta.addr); 119 116 spin_unlock_irqrestore(&priv->sta_lock, flags); 117 + 118 + return ret; 120 119 } 121 120 122 121 static void iwl_add_sta_callback(struct iwl_priv *priv, ··· 150 145 151 146 if (flags & CMD_ASYNC) 152 147 cmd.callback = iwl_add_sta_callback; 153 - else 148 + else { 154 149 cmd.flags |= CMD_WANT_SKB; 150 + might_sleep(); 151 + } 155 152 156 153 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); 157 154 ret = iwl_send_cmd(priv, &cmd); ··· 163 156 164 157 if (ret == 0) { 165 158 pkt = (struct iwl_rx_packet *)cmd.reply_page; 166 - iwl_process_add_sta_resp(priv, sta, pkt, true); 159 + ret = iwl_process_add_sta_resp(priv, sta, pkt, true); 167 160 } 168 161 iwl_free_pages(priv, cmd.reply_page); 169 162 ··· 838 831 { 839 832 unsigned long flags; 840 833 __le16 key_flags = 0; 841 - int ret; 834 + struct iwl_addsta_cmd sta_cmd; 835 + 836 + lockdep_assert_held(&priv->mutex); 842 837 843 838 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; 844 839 ··· 880 871 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 881 872 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 882 873 883 - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 884 - 874 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 885 875 spin_unlock_irqrestore(&priv->sta_lock, flags); 886 876 887 - return ret; 877 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 888 878 } 889 879 890 880 static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, ··· 892 884 { 893 885 unsigned long flags; 894 886 __le16 key_flags = 0; 895 - int ret; 887 + struct iwl_addsta_cmd sta_cmd; 888 + 889 + lockdep_assert_held(&priv->mutex); 896 890 897 891 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 898 892 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); ··· 929 919 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 930 920 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 931 921 932 - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 933 - 922 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 934 923 spin_unlock_irqrestore(&priv->sta_lock, flags); 935 924 936 - return ret; 925 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 937 926 } 938 927 939 928 static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, ··· 1022 1013 u8 sta_id) 1023 1014 { 1024 1015 unsigned long flags; 1025 - int ret = 0; 1026 1016 u16 key_flags; 1027 1017 u8 keyidx; 1018 + struct iwl_addsta_cmd sta_cmd; 1019 + 1020 + lockdep_assert_held(&priv->mutex); 1028 1021 1029 1022 priv->key_mapping_key--; 1030 1023 ··· 1073 1062 spin_unlock_irqrestore(&priv->sta_lock, flags); 1074 1063 return 0; 1075 1064 } 1076 - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1065 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1077 1066 spin_unlock_irqrestore(&priv->sta_lock, flags); 1078 - return ret; 1067 + 1068 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 1079 1069 } 1080 1070 EXPORT_SYMBOL(iwl_remove_dynamic_key); 1081 1071 ··· 1084 1072 struct ieee80211_key_conf *keyconf, u8 sta_id) 1085 1073 { 1086 1074 int ret; 1075 + 1076 + lockdep_assert_held(&priv->mutex); 1087 1077 1088 1078 priv->key_mapping_key++; 1089 1079 keyconf->hw_key_idx = HW_KEY_DYNAMIC; ··· 1259 1245 } 1260 1246 EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); 1261 1247 1248 + /** 1249 + * iwl_update_bcast_station - update broadcast station's LQ command 1250 + * 1251 + * Only used by iwlagn. Placed here to have all bcast station management 1252 + * code together. 1253 + */ 1254 + int iwl_update_bcast_station(struct iwl_priv *priv) 1255 + { 1256 + unsigned long flags; 1257 + struct iwl_link_quality_cmd *link_cmd; 1258 + u8 sta_id = priv->hw_params.bcast_sta_id; 1259 + 1260 + link_cmd = iwl_sta_alloc_lq(priv, sta_id); 1261 + if (!link_cmd) { 1262 + IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); 1263 + return -ENOMEM; 1264 + } 1265 + 1266 + spin_lock_irqsave(&priv->sta_lock, flags); 1267 + if (priv->stations[sta_id].lq) 1268 + kfree(priv->stations[sta_id].lq); 1269 + else 1270 + IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); 1271 + priv->stations[sta_id].lq = link_cmd; 1272 + spin_unlock_irqrestore(&priv->sta_lock, flags); 1273 + 1274 + return 0; 1275 + } 1276 + EXPORT_SYMBOL_GPL(iwl_update_bcast_station); 1277 + 1262 1278 void iwl_dealloc_bcast_station(struct iwl_priv *priv) 1263 1279 { 1264 1280 unsigned long flags; ··· 1312 1268 /** 1313 1269 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table 1314 1270 */ 1315 - void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) 1271 + int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) 1316 1272 { 1317 1273 unsigned long flags; 1274 + struct iwl_addsta_cmd sta_cmd; 1275 + 1276 + lockdep_assert_held(&priv->mutex); 1318 1277 1319 1278 /* Remove "disable" flag, to enable Tx for this TID */ 1320 1279 spin_lock_irqsave(&priv->sta_lock, flags); 1321 1280 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; 1322 1281 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); 1323 1282 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1324 - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1283 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1325 1284 spin_unlock_irqrestore(&priv->sta_lock, flags); 1285 + 1286 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 1326 1287 } 1327 1288 EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1328 1289 ··· 1336 1287 { 1337 1288 unsigned long flags; 1338 1289 int sta_id; 1290 + struct iwl_addsta_cmd sta_cmd; 1291 + 1292 + lockdep_assert_held(&priv->mutex); 1339 1293 1340 1294 sta_id = iwl_sta_id(sta); 1341 1295 if (sta_id == IWL_INVALID_STATION) ··· 1350 1298 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; 1351 1299 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); 1352 1300 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1301 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1353 1302 spin_unlock_irqrestore(&priv->sta_lock, flags); 1354 1303 1355 - return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1356 - CMD_ASYNC); 1304 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 1357 1305 } 1358 1306 EXPORT_SYMBOL(iwl_sta_rx_agg_start); 1359 1307 ··· 1361 1309 int tid) 1362 1310 { 1363 1311 unsigned long flags; 1364 - int sta_id, ret; 1312 + int sta_id; 1313 + struct iwl_addsta_cmd sta_cmd; 1314 + 1315 + lockdep_assert_held(&priv->mutex); 1365 1316 1366 1317 sta_id = iwl_sta_id(sta); 1367 1318 if (sta_id == IWL_INVALID_STATION) { ··· 1377 1322 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 1378 1323 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1379 1324 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1380 - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1325 + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1381 1326 spin_unlock_irqrestore(&priv->sta_lock, flags); 1382 1327 1383 - return ret; 1384 - 1328 + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 1385 1329 } 1386 1330 EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1387 1331
+2 -1
drivers/net/wireless/iwlwifi/iwl-sta.h
··· 60 60 void iwl_clear_ucode_stations(struct iwl_priv *priv); 61 61 int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); 62 62 void iwl_dealloc_bcast_station(struct iwl_priv *priv); 63 + int iwl_update_bcast_station(struct iwl_priv *priv); 63 64 int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 64 65 int iwl_send_add_sta(struct iwl_priv *priv, 65 66 struct iwl_addsta_cmd *sta, u8 flags); ··· 74 73 const u8 *addr); 75 74 int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 76 75 struct ieee80211_sta *sta); 77 - void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76 + int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 78 77 int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, 79 78 int tid, u16 ssn); 80 79 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+1 -1
drivers/net/wireless/iwlwifi/iwl3945-base.c
··· 1424 1424 iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); 1425 1425 1426 1426 IWL_ERR(priv, 1427 - "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", 1427 + "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", 1428 1428 desc_lookup(desc), desc, time, blink1, blink2, 1429 1429 ilink1, ilink2, data1); 1430 1430 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0,
+8 -4
drivers/net/wireless/iwmc3200wifi/cfg80211.c
··· 670 670 } 671 671 672 672 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, 673 - enum tx_power_setting type, int dbm) 673 + enum nl80211_tx_power_setting type, int mbm) 674 674 { 675 675 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 676 676 int ret; 677 677 678 678 switch (type) { 679 - case TX_POWER_AUTOMATIC: 679 + case NL80211_TX_POWER_AUTOMATIC: 680 680 return 0; 681 - case TX_POWER_FIXED: 681 + case NL80211_TX_POWER_FIXED: 682 + if (mbm < 0 || (mbm % 100)) 683 + return -EOPNOTSUPP; 684 + 682 685 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 683 686 return 0; 684 687 685 688 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, 686 - CFG_TX_PWR_LIMIT_USR, dbm * 2); 689 + CFG_TX_PWR_LIMIT_USR, 690 + MBM_TO_DBM(mbm) * 2); 687 691 if (ret < 0) 688 692 return ret; 689 693
-3
drivers/net/wireless/libertas/Makefile
··· 1 - libertas-y += assoc.o 2 1 libertas-y += cfg.o 3 2 libertas-y += cmd.o 4 3 libertas-y += cmdresp.o ··· 5 6 libertas-y += ethtool.o 6 7 libertas-y += main.o 7 8 libertas-y += rx.o 8 - libertas-y += scan.o 9 9 libertas-y += tx.o 10 - libertas-y += wext.o 11 10 libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o 12 11 13 12 usb8xxx-objs += if_usb.o
-2264
drivers/net/wireless/libertas/assoc.c
··· 1 - /* Copyright (C) 2006, Red Hat, Inc. */ 2 - 3 - #include <linux/types.h> 4 - #include <linux/etherdevice.h> 5 - #include <linux/ieee80211.h> 6 - #include <linux/if_arp.h> 7 - #include <linux/slab.h> 8 - #include <net/lib80211.h> 9 - 10 - #include "assoc.h" 11 - #include "decl.h" 12 - #include "host.h" 13 - #include "scan.h" 14 - #include "cmd.h" 15 - 16 - static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = 17 - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 18 - static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = 19 - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 20 - 21 - /* The firmware needs the following bits masked out of the beacon-derived 22 - * capability field when associating/joining to a BSS: 23 - * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) 24 - */ 25 - #define CAPINFO_MASK (~(0xda00)) 26 - 27 - /** 28 - * 802.11b/g supported bitrates (in 500Kb/s units) 29 - */ 30 - u8 lbs_bg_rates[MAX_RATES] = 31 - { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 32 - 0x00, 0x00 }; 33 - 34 - 35 - static int assoc_helper_wep_keys(struct lbs_private *priv, 36 - struct assoc_request *assoc_req); 37 - 38 - /** 39 - * @brief This function finds common rates between rates and card rates. 40 - * 41 - * It will fill common rates in rates as output if found. 42 - * 43 - * NOTE: Setting the MSB of the basic rates need to be taken 44 - * care, either before or after calling this function 45 - * 46 - * @param priv A pointer to struct lbs_private structure 47 - * @param rates the buffer which keeps input and output 48 - * @param rates_size the size of rates buffer; new size of buffer on return, 49 - * which will be less than or equal to original rates_size 50 - * 51 - * @return 0 on success, or -1 on error 52 - */ 53 - static int get_common_rates(struct lbs_private *priv, 54 - u8 *rates, 55 - u16 *rates_size) 56 - { 57 - int i, j; 58 - u8 intersection[MAX_RATES]; 59 - u16 intersection_size; 60 - u16 num_rates = 0; 61 - 62 - intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection)); 63 - 64 - /* Allow each rate from 'rates' that is supported by the hardware */ 65 - for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) { 66 - for (j = 0; j < intersection_size && rates[j]; j++) { 67 - if (rates[j] == lbs_bg_rates[i]) 68 - intersection[num_rates++] = rates[j]; 69 - } 70 - } 71 - 72 - lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); 73 - lbs_deb_hex(LBS_DEB_JOIN, "card rates ", lbs_bg_rates, 74 - ARRAY_SIZE(lbs_bg_rates)); 75 - lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates); 76 - lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); 77 - 78 - if (!priv->enablehwauto) { 79 - for (i = 0; i < num_rates; i++) { 80 - if (intersection[i] == priv->cur_rate) 81 - goto done; 82 - } 83 - lbs_pr_alert("Previously set fixed data rate %#x isn't " 84 - "compatible with the network.\n", priv->cur_rate); 85 - return -1; 86 - } 87 - 88 - done: 89 - memset(rates, 0, *rates_size); 90 - *rates_size = num_rates; 91 - memcpy(rates, intersection, num_rates); 92 - return 0; 93 - } 94 - 95 - 96 - /** 97 - * @brief Sets the MSB on basic rates as the firmware requires 98 - * 99 - * Scan through an array and set the MSB for basic data rates. 100 - * 101 - * @param rates buffer of data rates 102 - * @param len size of buffer 103 - */ 104 - static void lbs_set_basic_rate_flags(u8 *rates, size_t len) 105 - { 106 - int i; 107 - 108 - for (i = 0; i < len; i++) { 109 - if (rates[i] == 0x02 || rates[i] == 0x04 || 110 - rates[i] == 0x0b || rates[i] == 0x16) 111 - rates[i] |= 0x80; 112 - } 113 - } 114 - 115 - 116 - static u8 iw_auth_to_ieee_auth(u8 auth) 117 - { 118 - if (auth == IW_AUTH_ALG_OPEN_SYSTEM) 119 - return 0x00; 120 - else if (auth == IW_AUTH_ALG_SHARED_KEY) 121 - return 0x01; 122 - else if (auth == IW_AUTH_ALG_LEAP) 123 - return 0x80; 124 - 125 - lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth); 126 - return 0; 127 - } 128 - 129 - /** 130 - * @brief This function prepares the authenticate command. AUTHENTICATE only 131 - * sets the authentication suite for future associations, as the firmware 132 - * handles authentication internally during the ASSOCIATE command. 133 - * 134 - * @param priv A pointer to struct lbs_private structure 135 - * @param bssid The peer BSSID with which to authenticate 136 - * @param auth The authentication mode to use (from wireless.h) 137 - * 138 - * @return 0 or -1 139 - */ 140 - static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth) 141 - { 142 - struct cmd_ds_802_11_authenticate cmd; 143 - int ret = -1; 144 - 145 - lbs_deb_enter(LBS_DEB_JOIN); 146 - 147 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 148 - memcpy(cmd.bssid, bssid, ETH_ALEN); 149 - 150 - cmd.authtype = iw_auth_to_ieee_auth(auth); 151 - 152 - lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", bssid, cmd.authtype); 153 - 154 - ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); 155 - 156 - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); 157 - return ret; 158 - } 159 - 160 - 161 - int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, 162 - struct assoc_request *assoc) 163 - { 164 - struct cmd_ds_802_11_set_wep cmd; 165 - int ret = 0; 166 - 167 - lbs_deb_enter(LBS_DEB_CMD); 168 - 169 - memset(&cmd, 0, sizeof(cmd)); 170 - cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP); 171 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 172 - 173 - cmd.action = cpu_to_le16(cmd_action); 174 - 175 - if (cmd_action == CMD_ACT_ADD) { 176 - int i; 177 - 178 - /* default tx key index */ 179 - cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx & 180 - CMD_WEP_KEY_INDEX_MASK); 181 - 182 - /* Copy key types and material to host command structure */ 183 - for (i = 0; i < 4; i++) { 184 - struct enc_key *pkey = &assoc->wep_keys[i]; 185 - 186 - switch (pkey->len) { 187 - case KEY_LEN_WEP_40: 188 - cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; 189 - memmove(cmd.keymaterial[i], pkey->key, pkey->len); 190 - lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); 191 - break; 192 - case KEY_LEN_WEP_104: 193 - cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; 194 - memmove(cmd.keymaterial[i], pkey->key, pkey->len); 195 - lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); 196 - break; 197 - case 0: 198 - break; 199 - default: 200 - lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", 201 - i, pkey->len); 202 - ret = -1; 203 - goto done; 204 - break; 205 - } 206 - } 207 - } else if (cmd_action == CMD_ACT_REMOVE) { 208 - /* ACT_REMOVE clears _all_ WEP keys */ 209 - 210 - /* default tx key index */ 211 - cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx & 212 - CMD_WEP_KEY_INDEX_MASK); 213 - lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx); 214 - } 215 - 216 - ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); 217 - done: 218 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 219 - return ret; 220 - } 221 - 222 - int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, 223 - uint16_t *enable) 224 - { 225 - struct cmd_ds_802_11_enable_rsn cmd; 226 - int ret; 227 - 228 - lbs_deb_enter(LBS_DEB_CMD); 229 - 230 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 231 - cmd.action = cpu_to_le16(cmd_action); 232 - 233 - if (cmd_action == CMD_ACT_GET) 234 - cmd.enable = 0; 235 - else { 236 - if (*enable) 237 - cmd.enable = cpu_to_le16(CMD_ENABLE_RSN); 238 - else 239 - cmd.enable = cpu_to_le16(CMD_DISABLE_RSN); 240 - lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); 241 - } 242 - 243 - ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); 244 - if (!ret && cmd_action == CMD_ACT_GET) 245 - *enable = le16_to_cpu(cmd.enable); 246 - 247 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 248 - return ret; 249 - } 250 - 251 - static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, 252 - struct enc_key *key) 253 - { 254 - lbs_deb_enter(LBS_DEB_CMD); 255 - 256 - if (key->flags & KEY_INFO_WPA_ENABLED) 257 - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); 258 - if (key->flags & KEY_INFO_WPA_UNICAST) 259 - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); 260 - if (key->flags & KEY_INFO_WPA_MCAST) 261 - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); 262 - 263 - keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); 264 - keyparam->keytypeid = cpu_to_le16(key->type); 265 - keyparam->keylen = cpu_to_le16(key->len); 266 - memcpy(keyparam->key, key->key, key->len); 267 - 268 - /* Length field doesn't include the {type,length} header */ 269 - keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); 270 - lbs_deb_leave(LBS_DEB_CMD); 271 - } 272 - 273 - int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, 274 - struct assoc_request *assoc) 275 - { 276 - struct cmd_ds_802_11_key_material cmd; 277 - int ret = 0; 278 - int index = 0; 279 - 280 - lbs_deb_enter(LBS_DEB_CMD); 281 - 282 - cmd.action = cpu_to_le16(cmd_action); 283 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 284 - 285 - if (cmd_action == CMD_ACT_GET) { 286 - cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2); 287 - } else { 288 - memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); 289 - 290 - if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { 291 - set_one_wpa_key(&cmd.keyParamSet[index], 292 - &assoc->wpa_unicast_key); 293 - index++; 294 - } 295 - 296 - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { 297 - set_one_wpa_key(&cmd.keyParamSet[index], 298 - &assoc->wpa_mcast_key); 299 - index++; 300 - } 301 - 302 - /* The common header and as many keys as we included */ 303 - cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), 304 - keyParamSet[index])); 305 - } 306 - ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); 307 - /* Copy the returned key to driver private data */ 308 - if (!ret && cmd_action == CMD_ACT_GET) { 309 - void *buf_ptr = cmd.keyParamSet; 310 - void *resp_end = &(&cmd)[1]; 311 - 312 - while (buf_ptr < resp_end) { 313 - struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; 314 - struct enc_key *key; 315 - uint16_t param_set_len = le16_to_cpu(keyparam->length); 316 - uint16_t key_len = le16_to_cpu(keyparam->keylen); 317 - uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); 318 - uint16_t key_type = le16_to_cpu(keyparam->keytypeid); 319 - void *end; 320 - 321 - end = (void *)keyparam + sizeof(keyparam->type) 322 - + sizeof(keyparam->length) + param_set_len; 323 - 324 - /* Make sure we don't access past the end of the IEs */ 325 - if (end > resp_end) 326 - break; 327 - 328 - if (key_flags & KEY_INFO_WPA_UNICAST) 329 - key = &priv->wpa_unicast_key; 330 - else if (key_flags & KEY_INFO_WPA_MCAST) 331 - key = &priv->wpa_mcast_key; 332 - else 333 - break; 334 - 335 - /* Copy returned key into driver */ 336 - memset(key, 0, sizeof(struct enc_key)); 337 - if (key_len > sizeof(key->key)) 338 - break; 339 - key->type = key_type; 340 - key->flags = key_flags; 341 - key->len = key_len; 342 - memcpy(key->key, keyparam->key, key->len); 343 - 344 - buf_ptr = end + 1; 345 - } 346 - } 347 - 348 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 349 - return ret; 350 - } 351 - 352 - static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok) 353 - { 354 - /* Bit Rate 355 - * 15:13 Reserved 356 - * 12 54 Mbps 357 - * 11 48 Mbps 358 - * 10 36 Mbps 359 - * 9 24 Mbps 360 - * 8 18 Mbps 361 - * 7 12 Mbps 362 - * 6 9 Mbps 363 - * 5 6 Mbps 364 - * 4 Reserved 365 - * 3 11 Mbps 366 - * 2 5.5 Mbps 367 - * 1 2 Mbps 368 - * 0 1 Mbps 369 - **/ 370 - 371 - uint16_t ratemask; 372 - int i = lbs_data_rate_to_fw_index(rate); 373 - if (lower_rates_ok) 374 - ratemask = (0x1fef >> (12 - i)); 375 - else 376 - ratemask = (1 << i); 377 - return cpu_to_le16(ratemask); 378 - } 379 - 380 - int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, 381 - uint16_t cmd_action) 382 - { 383 - struct cmd_ds_802_11_rate_adapt_rateset cmd; 384 - int ret; 385 - 386 - lbs_deb_enter(LBS_DEB_CMD); 387 - 388 - if (!priv->cur_rate && !priv->enablehwauto) 389 - return -EINVAL; 390 - 391 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 392 - 393 - cmd.action = cpu_to_le16(cmd_action); 394 - cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); 395 - cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); 396 - ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); 397 - if (!ret && cmd_action == CMD_ACT_GET) 398 - priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); 399 - 400 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 401 - return ret; 402 - } 403 - 404 - /** 405 - * @brief Set the data rate 406 - * 407 - * @param priv A pointer to struct lbs_private structure 408 - * @param rate The desired data rate, or 0 to clear a locked rate 409 - * 410 - * @return 0 on success, error on failure 411 - */ 412 - int lbs_set_data_rate(struct lbs_private *priv, u8 rate) 413 - { 414 - struct cmd_ds_802_11_data_rate cmd; 415 - int ret = 0; 416 - 417 - lbs_deb_enter(LBS_DEB_CMD); 418 - 419 - memset(&cmd, 0, sizeof(cmd)); 420 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 421 - 422 - if (rate > 0) { 423 - cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE); 424 - cmd.rates[0] = lbs_data_rate_to_fw_index(rate); 425 - if (cmd.rates[0] == 0) { 426 - lbs_deb_cmd("DATA_RATE: invalid requested rate of" 427 - " 0x%02X\n", rate); 428 - ret = 0; 429 - goto out; 430 - } 431 - lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]); 432 - } else { 433 - cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO); 434 - lbs_deb_cmd("DATA_RATE: setting auto\n"); 435 - } 436 - 437 - ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); 438 - if (ret) 439 - goto out; 440 - 441 - lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd)); 442 - 443 - /* FIXME: get actual rates FW can do if this command actually returns 444 - * all data rates supported. 445 - */ 446 - priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]); 447 - lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate); 448 - 449 - out: 450 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 451 - return ret; 452 - } 453 - 454 - 455 - int lbs_cmd_802_11_rssi(struct lbs_private *priv, 456 - struct cmd_ds_command *cmd) 457 - { 458 - 459 - lbs_deb_enter(LBS_DEB_CMD); 460 - cmd->command = cpu_to_le16(CMD_802_11_RSSI); 461 - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + 462 - sizeof(struct cmd_header)); 463 - cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); 464 - 465 - /* reset Beacon SNR/NF/RSSI values */ 466 - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; 467 - priv->SNR[TYPE_BEACON][TYPE_AVG] = 0; 468 - priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0; 469 - priv->NF[TYPE_BEACON][TYPE_AVG] = 0; 470 - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0; 471 - priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0; 472 - 473 - lbs_deb_leave(LBS_DEB_CMD); 474 - return 0; 475 - } 476 - 477 - int lbs_ret_802_11_rssi(struct lbs_private *priv, 478 - struct cmd_ds_command *resp) 479 - { 480 - struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; 481 - 482 - lbs_deb_enter(LBS_DEB_CMD); 483 - 484 - /* store the non average value */ 485 - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); 486 - priv->NF[TYPE_BEACON][TYPE_NOAVG] = 487 - get_unaligned_le16(&rssirsp->noisefloor); 488 - 489 - priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); 490 - priv->NF[TYPE_BEACON][TYPE_AVG] = 491 - get_unaligned_le16(&rssirsp->avgnoisefloor); 492 - 493 - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 494 - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], 495 - priv->NF[TYPE_BEACON][TYPE_NOAVG]); 496 - 497 - priv->RSSI[TYPE_BEACON][TYPE_AVG] = 498 - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, 499 - priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); 500 - 501 - lbs_deb_cmd("RSSI: beacon %d, avg %d\n", 502 - priv->RSSI[TYPE_BEACON][TYPE_NOAVG], 503 - priv->RSSI[TYPE_BEACON][TYPE_AVG]); 504 - 505 - lbs_deb_leave(LBS_DEB_CMD); 506 - return 0; 507 - } 508 - 509 - 510 - int lbs_cmd_bcn_ctrl(struct lbs_private *priv, 511 - struct cmd_ds_command *cmd, 512 - u16 cmd_action) 513 - { 514 - struct cmd_ds_802_11_beacon_control 515 - *bcn_ctrl = &cmd->params.bcn_ctrl; 516 - 517 - lbs_deb_enter(LBS_DEB_CMD); 518 - cmd->size = 519 - cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control) 520 - + sizeof(struct cmd_header)); 521 - cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL); 522 - 523 - bcn_ctrl->action = cpu_to_le16(cmd_action); 524 - bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable); 525 - bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period); 526 - 527 - lbs_deb_leave(LBS_DEB_CMD); 528 - return 0; 529 - } 530 - 531 - int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, 532 - struct cmd_ds_command *resp) 533 - { 534 - struct cmd_ds_802_11_beacon_control *bcn_ctrl = 535 - &resp->params.bcn_ctrl; 536 - 537 - lbs_deb_enter(LBS_DEB_CMD); 538 - 539 - if (bcn_ctrl->action == CMD_ACT_GET) { 540 - priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); 541 - priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); 542 - } 543 - 544 - lbs_deb_enter(LBS_DEB_CMD); 545 - return 0; 546 - } 547 - 548 - 549 - 550 - static int lbs_assoc_post(struct lbs_private *priv, 551 - struct cmd_ds_802_11_associate_response *resp) 552 - { 553 - int ret = 0; 554 - union iwreq_data wrqu; 555 - struct bss_descriptor *bss; 556 - u16 status_code; 557 - 558 - lbs_deb_enter(LBS_DEB_ASSOC); 559 - 560 - if (!priv->in_progress_assoc_req) { 561 - lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n"); 562 - ret = -1; 563 - goto done; 564 - } 565 - bss = &priv->in_progress_assoc_req->bss; 566 - 567 - /* 568 - * Older FW versions map the IEEE 802.11 Status Code in the association 569 - * response to the following values returned in resp->statuscode: 570 - * 571 - * IEEE Status Code Marvell Status Code 572 - * 0 -> 0x0000 ASSOC_RESULT_SUCCESS 573 - * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED 574 - * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED 575 - * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED 576 - * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED 577 - * others -> 0x0003 ASSOC_RESULT_REFUSED 578 - * 579 - * Other response codes: 580 - * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) 581 - * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for 582 - * association response from the AP) 583 - */ 584 - 585 - status_code = le16_to_cpu(resp->statuscode); 586 - if (priv->fwrelease < 0x09000000) { 587 - switch (status_code) { 588 - case 0x00: 589 - break; 590 - case 0x01: 591 - lbs_deb_assoc("ASSOC_RESP: invalid parameters\n"); 592 - break; 593 - case 0x02: 594 - lbs_deb_assoc("ASSOC_RESP: internal timer " 595 - "expired while waiting for the AP\n"); 596 - break; 597 - case 0x03: 598 - lbs_deb_assoc("ASSOC_RESP: association " 599 - "refused by AP\n"); 600 - break; 601 - case 0x04: 602 - lbs_deb_assoc("ASSOC_RESP: authentication " 603 - "refused by AP\n"); 604 - break; 605 - default: 606 - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x " 607 - " unknown\n", status_code); 608 - break; 609 - } 610 - } else { 611 - /* v9+ returns the AP's association response */ 612 - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code); 613 - } 614 - 615 - if (status_code) { 616 - lbs_mac_event_disconnected(priv); 617 - ret = status_code; 618 - goto done; 619 - } 620 - 621 - lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", 622 - (void *) (resp + sizeof (resp->hdr)), 623 - le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr)); 624 - 625 - /* Send a Media Connected event, according to the Spec */ 626 - priv->connect_status = LBS_CONNECTED; 627 - 628 - /* Update current SSID and BSSID */ 629 - memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); 630 - priv->curbssparams.ssid_len = bss->ssid_len; 631 - memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); 632 - 633 - priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; 634 - priv->NF[TYPE_RXPD][TYPE_AVG] = 0; 635 - 636 - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); 637 - memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); 638 - priv->nextSNRNF = 0; 639 - priv->numSNRNF = 0; 640 - 641 - netif_carrier_on(priv->dev); 642 - if (!priv->tx_pending_len) 643 - netif_wake_queue(priv->dev); 644 - 645 - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); 646 - wrqu.ap_addr.sa_family = ARPHRD_ETHER; 647 - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 648 - 649 - done: 650 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 651 - return ret; 652 - } 653 - 654 - /** 655 - * @brief This function prepares an association-class command. 656 - * 657 - * @param priv A pointer to struct lbs_private structure 658 - * @param assoc_req The association request describing the BSS to associate 659 - * or reassociate with 660 - * @param command The actual command, either CMD_802_11_ASSOCIATE or 661 - * CMD_802_11_REASSOCIATE 662 - * 663 - * @return 0 or -1 664 - */ 665 - static int lbs_associate(struct lbs_private *priv, 666 - struct assoc_request *assoc_req, 667 - u16 command) 668 - { 669 - struct cmd_ds_802_11_associate cmd; 670 - int ret = 0; 671 - struct bss_descriptor *bss = &assoc_req->bss; 672 - u8 *pos = &(cmd.iebuf[0]); 673 - u16 tmpcap, tmplen, tmpauth; 674 - struct mrvl_ie_ssid_param_set *ssid; 675 - struct mrvl_ie_ds_param_set *ds; 676 - struct mrvl_ie_cf_param_set *cf; 677 - struct mrvl_ie_rates_param_set *rates; 678 - struct mrvl_ie_rsn_param_set *rsn; 679 - struct mrvl_ie_auth_type *auth; 680 - 681 - lbs_deb_enter(LBS_DEB_ASSOC); 682 - 683 - BUG_ON((command != CMD_802_11_ASSOCIATE) && 684 - (command != CMD_802_11_REASSOCIATE)); 685 - 686 - memset(&cmd, 0, sizeof(cmd)); 687 - cmd.hdr.command = cpu_to_le16(command); 688 - 689 - /* Fill in static fields */ 690 - memcpy(cmd.bssid, bss->bssid, ETH_ALEN); 691 - cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); 692 - 693 - /* Capability info */ 694 - tmpcap = (bss->capability & CAPINFO_MASK); 695 - if (bss->mode == IW_MODE_INFRA) 696 - tmpcap |= WLAN_CAPABILITY_ESS; 697 - cmd.capability = cpu_to_le16(tmpcap); 698 - lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap); 699 - 700 - /* SSID */ 701 - ssid = (struct mrvl_ie_ssid_param_set *) pos; 702 - ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); 703 - tmplen = bss->ssid_len; 704 - ssid->header.len = cpu_to_le16(tmplen); 705 - memcpy(ssid->ssid, bss->ssid, tmplen); 706 - pos += sizeof(ssid->header) + tmplen; 707 - 708 - ds = (struct mrvl_ie_ds_param_set *) pos; 709 - ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); 710 - ds->header.len = cpu_to_le16(1); 711 - ds->channel = bss->phy.ds.channel; 712 - pos += sizeof(ds->header) + 1; 713 - 714 - cf = (struct mrvl_ie_cf_param_set *) pos; 715 - cf->header.type = cpu_to_le16(TLV_TYPE_CF); 716 - tmplen = sizeof(*cf) - sizeof (cf->header); 717 - cf->header.len = cpu_to_le16(tmplen); 718 - /* IE payload should be zeroed, firmware fills it in for us */ 719 - pos += sizeof(*cf); 720 - 721 - rates = (struct mrvl_ie_rates_param_set *) pos; 722 - rates->header.type = cpu_to_le16(TLV_TYPE_RATES); 723 - tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES); 724 - memcpy(&rates->rates, &bss->rates, tmplen); 725 - if (get_common_rates(priv, rates->rates, &tmplen)) { 726 - ret = -1; 727 - goto done; 728 - } 729 - pos += sizeof(rates->header) + tmplen; 730 - rates->header.len = cpu_to_le16(tmplen); 731 - lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen); 732 - 733 - /* Copy the infra. association rates into Current BSS state structure */ 734 - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); 735 - memcpy(&priv->curbssparams.rates, &rates->rates, tmplen); 736 - 737 - /* Set MSB on basic rates as the firmware requires, but _after_ 738 - * copying to current bss rates. 739 - */ 740 - lbs_set_basic_rate_flags(rates->rates, tmplen); 741 - 742 - /* Firmware v9+ indicate authentication suites as a TLV */ 743 - if (priv->fwrelease >= 0x09000000) { 744 - auth = (struct mrvl_ie_auth_type *) pos; 745 - auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); 746 - auth->header.len = cpu_to_le16(2); 747 - tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode); 748 - auth->auth = cpu_to_le16(tmpauth); 749 - pos += sizeof(auth->header) + 2; 750 - 751 - lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", 752 - bss->bssid, priv->secinfo.auth_mode); 753 - } 754 - 755 - /* WPA/WPA2 IEs */ 756 - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { 757 - rsn = (struct mrvl_ie_rsn_param_set *) pos; 758 - /* WPA_IE or WPA2_IE */ 759 - rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]); 760 - tmplen = (u16) assoc_req->wpa_ie[1]; 761 - rsn->header.len = cpu_to_le16(tmplen); 762 - memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen); 763 - lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn, 764 - sizeof(rsn->header) + tmplen); 765 - pos += sizeof(rsn->header) + tmplen; 766 - } 767 - 768 - cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) + 769 - (u16)(pos - (u8 *) &cmd.iebuf)); 770 - 771 - /* update curbssparams */ 772 - priv->channel = bss->phy.ds.channel; 773 - 774 - ret = lbs_cmd_with_response(priv, command, &cmd); 775 - if (ret == 0) { 776 - ret = lbs_assoc_post(priv, 777 - (struct cmd_ds_802_11_associate_response *) &cmd); 778 - } 779 - 780 - done: 781 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 782 - return ret; 783 - } 784 - 785 - /** 786 - * @brief Associate to a specific BSS discovered in a scan 787 - * 788 - * @param priv A pointer to struct lbs_private structure 789 - * @param assoc_req The association request describing the BSS to associate with 790 - * 791 - * @return 0-success, otherwise fail 792 - */ 793 - static int lbs_try_associate(struct lbs_private *priv, 794 - struct assoc_request *assoc_req) 795 - { 796 - int ret; 797 - u8 preamble = RADIO_PREAMBLE_LONG; 798 - 799 - lbs_deb_enter(LBS_DEB_ASSOC); 800 - 801 - /* FW v9 and higher indicate authentication suites as a TLV in the 802 - * association command, not as a separate authentication command. 803 - */ 804 - if (priv->fwrelease < 0x09000000) { 805 - ret = lbs_set_authentication(priv, assoc_req->bss.bssid, 806 - priv->secinfo.auth_mode); 807 - if (ret) 808 - goto out; 809 - } 810 - 811 - /* Use short preamble only when both the BSS and firmware support it */ 812 - if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 813 - preamble = RADIO_PREAMBLE_SHORT; 814 - 815 - ret = lbs_set_radio(priv, preamble, 1); 816 - if (ret) 817 - goto out; 818 - 819 - ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); 820 - /* If the association fails with current auth mode, let's 821 - * try by changing the auth mode 822 - */ 823 - if ((priv->authtype_auto) && 824 - (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) && 825 - (assoc_req->secinfo.wep_enabled) && 826 - (priv->connect_status != LBS_CONNECTED)) { 827 - if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM) 828 - priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 829 - else 830 - priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 831 - if (!assoc_helper_wep_keys(priv, assoc_req)) 832 - ret = lbs_associate(priv, assoc_req, 833 - CMD_802_11_ASSOCIATE); 834 - } 835 - 836 - if (ret) 837 - ret = -1; 838 - out: 839 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 840 - return ret; 841 - } 842 - 843 - static int lbs_adhoc_post(struct lbs_private *priv, 844 - struct cmd_ds_802_11_ad_hoc_result *resp) 845 - { 846 - int ret = 0; 847 - u16 command = le16_to_cpu(resp->hdr.command); 848 - u16 result = le16_to_cpu(resp->hdr.result); 849 - union iwreq_data wrqu; 850 - struct bss_descriptor *bss; 851 - DECLARE_SSID_BUF(ssid); 852 - 853 - lbs_deb_enter(LBS_DEB_JOIN); 854 - 855 - if (!priv->in_progress_assoc_req) { 856 - lbs_deb_join("ADHOC_RESP: no in-progress association " 857 - "request\n"); 858 - ret = -1; 859 - goto done; 860 - } 861 - bss = &priv->in_progress_assoc_req->bss; 862 - 863 - /* 864 - * Join result code 0 --> SUCCESS 865 - */ 866 - if (result) { 867 - lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result); 868 - if (priv->connect_status == LBS_CONNECTED) 869 - lbs_mac_event_disconnected(priv); 870 - ret = -1; 871 - goto done; 872 - } 873 - 874 - /* Send a Media Connected event, according to the Spec */ 875 - priv->connect_status = LBS_CONNECTED; 876 - 877 - if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { 878 - /* Update the created network descriptor with the new BSSID */ 879 - memcpy(bss->bssid, resp->bssid, ETH_ALEN); 880 - } 881 - 882 - /* Set the BSSID from the joined/started descriptor */ 883 - memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); 884 - 885 - /* Set the new SSID to current SSID */ 886 - memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); 887 - priv->curbssparams.ssid_len = bss->ssid_len; 888 - 889 - netif_carrier_on(priv->dev); 890 - if (!priv->tx_pending_len) 891 - netif_wake_queue(priv->dev); 892 - 893 - memset(&wrqu, 0, sizeof(wrqu)); 894 - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); 895 - wrqu.ap_addr.sa_family = ARPHRD_ETHER; 896 - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 897 - 898 - lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", 899 - print_ssid(ssid, bss->ssid, bss->ssid_len), 900 - priv->curbssparams.bssid, 901 - priv->channel); 902 - 903 - done: 904 - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); 905 - return ret; 906 - } 907 - 908 - /** 909 - * @brief Join an adhoc network found in a previous scan 910 - * 911 - * @param priv A pointer to struct lbs_private structure 912 - * @param assoc_req The association request describing the BSS to join 913 - * 914 - * @return 0 on success, error on failure 915 - */ 916 - static int lbs_adhoc_join(struct lbs_private *priv, 917 - struct assoc_request *assoc_req) 918 - { 919 - struct cmd_ds_802_11_ad_hoc_join cmd; 920 - struct bss_descriptor *bss = &assoc_req->bss; 921 - u8 preamble = RADIO_PREAMBLE_LONG; 922 - DECLARE_SSID_BUF(ssid); 923 - u16 ratesize = 0; 924 - int ret = 0; 925 - 926 - lbs_deb_enter(LBS_DEB_ASSOC); 927 - 928 - lbs_deb_join("current SSID '%s', ssid length %u\n", 929 - print_ssid(ssid, priv->curbssparams.ssid, 930 - priv->curbssparams.ssid_len), 931 - priv->curbssparams.ssid_len); 932 - lbs_deb_join("requested ssid '%s', ssid length %u\n", 933 - print_ssid(ssid, bss->ssid, bss->ssid_len), 934 - bss->ssid_len); 935 - 936 - /* check if the requested SSID is already joined */ 937 - if (priv->curbssparams.ssid_len && 938 - !lbs_ssid_cmp(priv->curbssparams.ssid, 939 - priv->curbssparams.ssid_len, 940 - bss->ssid, bss->ssid_len) && 941 - (priv->mode == IW_MODE_ADHOC) && 942 - (priv->connect_status == LBS_CONNECTED)) { 943 - union iwreq_data wrqu; 944 - 945 - lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as " 946 - "current, not attempting to re-join"); 947 - 948 - /* Send the re-association event though, because the association 949 - * request really was successful, even if just a null-op. 950 - */ 951 - memset(&wrqu, 0, sizeof(wrqu)); 952 - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, 953 - ETH_ALEN); 954 - wrqu.ap_addr.sa_family = ARPHRD_ETHER; 955 - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 956 - goto out; 957 - } 958 - 959 - /* Use short preamble only when both the BSS and firmware support it */ 960 - if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { 961 - lbs_deb_join("AdhocJoin: Short preamble\n"); 962 - preamble = RADIO_PREAMBLE_SHORT; 963 - } 964 - 965 - ret = lbs_set_radio(priv, preamble, 1); 966 - if (ret) 967 - goto out; 968 - 969 - lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); 970 - lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); 971 - 972 - priv->adhoccreate = 0; 973 - priv->channel = bss->channel; 974 - 975 - /* Build the join command */ 976 - memset(&cmd, 0, sizeof(cmd)); 977 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 978 - 979 - cmd.bss.type = CMD_BSS_TYPE_IBSS; 980 - cmd.bss.beaconperiod = cpu_to_le16(bss->beaconperiod); 981 - 982 - memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN); 983 - memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len); 984 - 985 - memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set)); 986 - 987 - memcpy(&cmd.bss.ibss, &bss->ss.ibss, 988 - sizeof(struct ieee_ie_ibss_param_set)); 989 - 990 - cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); 991 - lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", 992 - bss->capability, CAPINFO_MASK); 993 - 994 - /* information on BSSID descriptor passed to FW */ 995 - lbs_deb_join("ADHOC_J_CMD: BSSID = %pM, SSID = '%s'\n", 996 - cmd.bss.bssid, cmd.bss.ssid); 997 - 998 - /* Only v8 and below support setting these */ 999 - if (priv->fwrelease < 0x09000000) { 1000 - /* failtimeout */ 1001 - cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); 1002 - /* probedelay */ 1003 - cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1004 - } 1005 - 1006 - /* Copy Data rates from the rates recorded in scan response */ 1007 - memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates)); 1008 - ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates)); 1009 - memcpy(cmd.bss.rates, bss->rates, ratesize); 1010 - if (get_common_rates(priv, cmd.bss.rates, &ratesize)) { 1011 - lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n"); 1012 - ret = -1; 1013 - goto out; 1014 - } 1015 - 1016 - /* Copy the ad-hoc creation rates into Current BSS state structure */ 1017 - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); 1018 - memcpy(&priv->curbssparams.rates, cmd.bss.rates, ratesize); 1019 - 1020 - /* Set MSB on basic rates as the firmware requires, but _after_ 1021 - * copying to current bss rates. 1022 - */ 1023 - lbs_set_basic_rate_flags(cmd.bss.rates, ratesize); 1024 - 1025 - cmd.bss.ibss.atimwindow = bss->atimwindow; 1026 - 1027 - if (assoc_req->secinfo.wep_enabled) { 1028 - u16 tmp = le16_to_cpu(cmd.bss.capability); 1029 - tmp |= WLAN_CAPABILITY_PRIVACY; 1030 - cmd.bss.capability = cpu_to_le16(tmp); 1031 - } 1032 - 1033 - if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { 1034 - __le32 local_ps_mode = cpu_to_le32(LBS802_11POWERMODECAM); 1035 - 1036 - /* wake up first */ 1037 - ret = lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, 1038 - CMD_ACT_SET, 0, 0, 1039 - &local_ps_mode); 1040 - if (ret) { 1041 - ret = -1; 1042 - goto out; 1043 - } 1044 - } 1045 - 1046 - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); 1047 - if (ret == 0) { 1048 - ret = lbs_adhoc_post(priv, 1049 - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); 1050 - } 1051 - 1052 - out: 1053 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1054 - return ret; 1055 - } 1056 - 1057 - /** 1058 - * @brief Start an Adhoc Network 1059 - * 1060 - * @param priv A pointer to struct lbs_private structure 1061 - * @param assoc_req The association request describing the BSS to start 1062 - * 1063 - * @return 0 on success, error on failure 1064 - */ 1065 - static int lbs_adhoc_start(struct lbs_private *priv, 1066 - struct assoc_request *assoc_req) 1067 - { 1068 - struct cmd_ds_802_11_ad_hoc_start cmd; 1069 - u8 preamble = RADIO_PREAMBLE_SHORT; 1070 - size_t ratesize = 0; 1071 - u16 tmpcap = 0; 1072 - int ret = 0; 1073 - DECLARE_SSID_BUF(ssid); 1074 - 1075 - lbs_deb_enter(LBS_DEB_ASSOC); 1076 - 1077 - ret = lbs_set_radio(priv, preamble, 1); 1078 - if (ret) 1079 - goto out; 1080 - 1081 - /* Build the start command */ 1082 - memset(&cmd, 0, sizeof(cmd)); 1083 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1084 - 1085 - memcpy(cmd.ssid, assoc_req->ssid, assoc_req->ssid_len); 1086 - 1087 - lbs_deb_join("ADHOC_START: SSID '%s', ssid length %u\n", 1088 - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len), 1089 - assoc_req->ssid_len); 1090 - 1091 - cmd.bsstype = CMD_BSS_TYPE_IBSS; 1092 - 1093 - if (priv->beacon_period == 0) 1094 - priv->beacon_period = MRVDRV_BEACON_INTERVAL; 1095 - cmd.beaconperiod = cpu_to_le16(priv->beacon_period); 1096 - 1097 - WARN_ON(!assoc_req->channel); 1098 - 1099 - /* set Physical parameter set */ 1100 - cmd.ds.header.id = WLAN_EID_DS_PARAMS; 1101 - cmd.ds.header.len = 1; 1102 - cmd.ds.channel = assoc_req->channel; 1103 - 1104 - /* set IBSS parameter set */ 1105 - cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1106 - cmd.ibss.header.len = 2; 1107 - cmd.ibss.atimwindow = cpu_to_le16(0); 1108 - 1109 - /* set capability info */ 1110 - tmpcap = WLAN_CAPABILITY_IBSS; 1111 - if (assoc_req->secinfo.wep_enabled || 1112 - assoc_req->secinfo.WPAenabled || 1113 - assoc_req->secinfo.WPA2enabled) { 1114 - lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n"); 1115 - tmpcap |= WLAN_CAPABILITY_PRIVACY; 1116 - } else 1117 - lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n"); 1118 - 1119 - cmd.capability = cpu_to_le16(tmpcap); 1120 - 1121 - /* Only v8 and below support setting probe delay */ 1122 - if (priv->fwrelease < 0x09000000) 1123 - cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1124 - 1125 - ratesize = min(sizeof(cmd.rates), sizeof(lbs_bg_rates)); 1126 - memcpy(cmd.rates, lbs_bg_rates, ratesize); 1127 - 1128 - /* Copy the ad-hoc creating rates into Current BSS state structure */ 1129 - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); 1130 - memcpy(&priv->curbssparams.rates, &cmd.rates, ratesize); 1131 - 1132 - /* Set MSB on basic rates as the firmware requires, but _after_ 1133 - * copying to current bss rates. 1134 - */ 1135 - lbs_set_basic_rate_flags(cmd.rates, ratesize); 1136 - 1137 - lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", 1138 - cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); 1139 - 1140 - lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n", 1141 - assoc_req->channel, assoc_req->band); 1142 - 1143 - priv->adhoccreate = 1; 1144 - priv->mode = IW_MODE_ADHOC; 1145 - 1146 - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); 1147 - if (ret == 0) 1148 - ret = lbs_adhoc_post(priv, 1149 - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); 1150 - 1151 - out: 1152 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1153 - return ret; 1154 - } 1155 - 1156 - /** 1157 - * @brief Stop and Ad-Hoc network and exit Ad-Hoc mode 1158 - * 1159 - * @param priv A pointer to struct lbs_private structure 1160 - * @return 0 on success, or an error 1161 - */ 1162 - int lbs_adhoc_stop(struct lbs_private *priv) 1163 - { 1164 - struct cmd_ds_802_11_ad_hoc_stop cmd; 1165 - int ret; 1166 - 1167 - lbs_deb_enter(LBS_DEB_JOIN); 1168 - 1169 - memset(&cmd, 0, sizeof (cmd)); 1170 - cmd.hdr.size = cpu_to_le16 (sizeof (cmd)); 1171 - 1172 - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd); 1173 - 1174 - /* Clean up everything even if there was an error */ 1175 - lbs_mac_event_disconnected(priv); 1176 - 1177 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1178 - return ret; 1179 - } 1180 - 1181 - static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, 1182 - struct bss_descriptor *match_bss) 1183 - { 1184 - if (!secinfo->wep_enabled && 1185 - !secinfo->WPAenabled && !secinfo->WPA2enabled && 1186 - match_bss->wpa_ie[0] != WLAN_EID_GENERIC && 1187 - match_bss->rsn_ie[0] != WLAN_EID_RSN && 1188 - !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1189 - return 1; 1190 - else 1191 - return 0; 1192 - } 1193 - 1194 - static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, 1195 - struct bss_descriptor *match_bss) 1196 - { 1197 - if (secinfo->wep_enabled && 1198 - !secinfo->WPAenabled && !secinfo->WPA2enabled && 1199 - (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1200 - return 1; 1201 - else 1202 - return 0; 1203 - } 1204 - 1205 - static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, 1206 - struct bss_descriptor *match_bss) 1207 - { 1208 - if (!secinfo->wep_enabled && secinfo->WPAenabled && 1209 - (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) 1210 - /* privacy bit may NOT be set in some APs like LinkSys WRT54G 1211 - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ 1212 - ) 1213 - return 1; 1214 - else 1215 - return 0; 1216 - } 1217 - 1218 - static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, 1219 - struct bss_descriptor *match_bss) 1220 - { 1221 - if (!secinfo->wep_enabled && secinfo->WPA2enabled && 1222 - (match_bss->rsn_ie[0] == WLAN_EID_RSN) 1223 - /* privacy bit may NOT be set in some APs like LinkSys WRT54G 1224 - (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ 1225 - ) 1226 - return 1; 1227 - else 1228 - return 0; 1229 - } 1230 - 1231 - static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, 1232 - struct bss_descriptor *match_bss) 1233 - { 1234 - if (!secinfo->wep_enabled && 1235 - !secinfo->WPAenabled && !secinfo->WPA2enabled && 1236 - (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) && 1237 - (match_bss->rsn_ie[0] != WLAN_EID_RSN) && 1238 - (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1239 - return 1; 1240 - else 1241 - return 0; 1242 - } 1243 - 1244 - /** 1245 - * @brief Check if a scanned network compatible with the driver settings 1246 - * 1247 - * WEP WPA WPA2 ad-hoc encrypt Network 1248 - * enabled enabled enabled AES mode privacy WPA WPA2 Compatible 1249 - * 0 0 0 0 NONE 0 0 0 yes No security 1250 - * 1 0 0 0 NONE 1 0 0 yes Static WEP 1251 - * 0 1 0 0 x 1x 1 x yes WPA 1252 - * 0 0 1 0 x 1x x 1 yes WPA2 1253 - * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES 1254 - * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP 1255 - * 1256 - * 1257 - * @param priv A pointer to struct lbs_private 1258 - * @param index Index in scantable to check against current driver settings 1259 - * @param mode Network mode: Infrastructure or IBSS 1260 - * 1261 - * @return Index in scantable, or error code if negative 1262 - */ 1263 - static int is_network_compatible(struct lbs_private *priv, 1264 - struct bss_descriptor *bss, uint8_t mode) 1265 - { 1266 - int matched = 0; 1267 - 1268 - lbs_deb_enter(LBS_DEB_SCAN); 1269 - 1270 - if (bss->mode != mode) 1271 - goto done; 1272 - 1273 - matched = match_bss_no_security(&priv->secinfo, bss); 1274 - if (matched) 1275 - goto done; 1276 - matched = match_bss_static_wep(&priv->secinfo, bss); 1277 - if (matched) 1278 - goto done; 1279 - matched = match_bss_wpa(&priv->secinfo, bss); 1280 - if (matched) { 1281 - lbs_deb_scan("is_network_compatible() WPA: wpa_ie 0x%x " 1282 - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " 1283 - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], 1284 - priv->secinfo.wep_enabled ? "e" : "d", 1285 - priv->secinfo.WPAenabled ? "e" : "d", 1286 - priv->secinfo.WPA2enabled ? "e" : "d", 1287 - (bss->capability & WLAN_CAPABILITY_PRIVACY)); 1288 - goto done; 1289 - } 1290 - matched = match_bss_wpa2(&priv->secinfo, bss); 1291 - if (matched) { 1292 - lbs_deb_scan("is_network_compatible() WPA2: wpa_ie 0x%x " 1293 - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " 1294 - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], 1295 - priv->secinfo.wep_enabled ? "e" : "d", 1296 - priv->secinfo.WPAenabled ? "e" : "d", 1297 - priv->secinfo.WPA2enabled ? "e" : "d", 1298 - (bss->capability & WLAN_CAPABILITY_PRIVACY)); 1299 - goto done; 1300 - } 1301 - matched = match_bss_dynamic_wep(&priv->secinfo, bss); 1302 - if (matched) { 1303 - lbs_deb_scan("is_network_compatible() dynamic WEP: " 1304 - "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n", 1305 - bss->wpa_ie[0], bss->rsn_ie[0], 1306 - (bss->capability & WLAN_CAPABILITY_PRIVACY)); 1307 - goto done; 1308 - } 1309 - 1310 - /* bss security settings don't match those configured on card */ 1311 - lbs_deb_scan("is_network_compatible() FAILED: wpa_ie 0x%x " 1312 - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n", 1313 - bss->wpa_ie[0], bss->rsn_ie[0], 1314 - priv->secinfo.wep_enabled ? "e" : "d", 1315 - priv->secinfo.WPAenabled ? "e" : "d", 1316 - priv->secinfo.WPA2enabled ? "e" : "d", 1317 - (bss->capability & WLAN_CAPABILITY_PRIVACY)); 1318 - 1319 - done: 1320 - lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched); 1321 - return matched; 1322 - } 1323 - 1324 - /** 1325 - * @brief This function finds a specific compatible BSSID in the scan list 1326 - * 1327 - * Used in association code 1328 - * 1329 - * @param priv A pointer to struct lbs_private 1330 - * @param bssid BSSID to find in the scan list 1331 - * @param mode Network mode: Infrastructure or IBSS 1332 - * 1333 - * @return index in BSSID list, or error return code (< 0) 1334 - */ 1335 - static struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv, 1336 - uint8_t *bssid, uint8_t mode) 1337 - { 1338 - struct bss_descriptor *iter_bss; 1339 - struct bss_descriptor *found_bss = NULL; 1340 - 1341 - lbs_deb_enter(LBS_DEB_SCAN); 1342 - 1343 - if (!bssid) 1344 - goto out; 1345 - 1346 - lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN); 1347 - 1348 - /* Look through the scan table for a compatible match. The loop will 1349 - * continue past a matched bssid that is not compatible in case there 1350 - * is an AP with multiple SSIDs assigned to the same BSSID 1351 - */ 1352 - mutex_lock(&priv->lock); 1353 - list_for_each_entry(iter_bss, &priv->network_list, list) { 1354 - if (compare_ether_addr(iter_bss->bssid, bssid)) 1355 - continue; /* bssid doesn't match */ 1356 - switch (mode) { 1357 - case IW_MODE_INFRA: 1358 - case IW_MODE_ADHOC: 1359 - if (!is_network_compatible(priv, iter_bss, mode)) 1360 - break; 1361 - found_bss = iter_bss; 1362 - break; 1363 - default: 1364 - found_bss = iter_bss; 1365 - break; 1366 - } 1367 - } 1368 - mutex_unlock(&priv->lock); 1369 - 1370 - out: 1371 - lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); 1372 - return found_bss; 1373 - } 1374 - 1375 - /** 1376 - * @brief This function finds ssid in ssid list. 1377 - * 1378 - * Used in association code 1379 - * 1380 - * @param priv A pointer to struct lbs_private 1381 - * @param ssid SSID to find in the list 1382 - * @param bssid BSSID to qualify the SSID selection (if provided) 1383 - * @param mode Network mode: Infrastructure or IBSS 1384 - * 1385 - * @return index in BSSID list 1386 - */ 1387 - static struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv, 1388 - uint8_t *ssid, uint8_t ssid_len, 1389 - uint8_t *bssid, uint8_t mode, 1390 - int channel) 1391 - { 1392 - u32 bestrssi = 0; 1393 - struct bss_descriptor *iter_bss = NULL; 1394 - struct bss_descriptor *found_bss = NULL; 1395 - struct bss_descriptor *tmp_oldest = NULL; 1396 - 1397 - lbs_deb_enter(LBS_DEB_SCAN); 1398 - 1399 - mutex_lock(&priv->lock); 1400 - 1401 - list_for_each_entry(iter_bss, &priv->network_list, list) { 1402 - if (!tmp_oldest || 1403 - (iter_bss->last_scanned < tmp_oldest->last_scanned)) 1404 - tmp_oldest = iter_bss; 1405 - 1406 - if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, 1407 - ssid, ssid_len) != 0) 1408 - continue; /* ssid doesn't match */ 1409 - if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) 1410 - continue; /* bssid doesn't match */ 1411 - if ((channel > 0) && (iter_bss->channel != channel)) 1412 - continue; /* channel doesn't match */ 1413 - 1414 - switch (mode) { 1415 - case IW_MODE_INFRA: 1416 - case IW_MODE_ADHOC: 1417 - if (!is_network_compatible(priv, iter_bss, mode)) 1418 - break; 1419 - 1420 - if (bssid) { 1421 - /* Found requested BSSID */ 1422 - found_bss = iter_bss; 1423 - goto out; 1424 - } 1425 - 1426 - if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { 1427 - bestrssi = SCAN_RSSI(iter_bss->rssi); 1428 - found_bss = iter_bss; 1429 - } 1430 - break; 1431 - case IW_MODE_AUTO: 1432 - default: 1433 - if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { 1434 - bestrssi = SCAN_RSSI(iter_bss->rssi); 1435 - found_bss = iter_bss; 1436 - } 1437 - break; 1438 - } 1439 - } 1440 - 1441 - out: 1442 - mutex_unlock(&priv->lock); 1443 - lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); 1444 - return found_bss; 1445 - } 1446 - 1447 - static int assoc_helper_essid(struct lbs_private *priv, 1448 - struct assoc_request * assoc_req) 1449 - { 1450 - int ret = 0; 1451 - struct bss_descriptor * bss; 1452 - int channel = -1; 1453 - DECLARE_SSID_BUF(ssid); 1454 - 1455 - lbs_deb_enter(LBS_DEB_ASSOC); 1456 - 1457 - /* FIXME: take channel into account when picking SSIDs if a channel 1458 - * is set. 1459 - */ 1460 - 1461 - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) 1462 - channel = assoc_req->channel; 1463 - 1464 - lbs_deb_assoc("SSID '%s' requested\n", 1465 - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len)); 1466 - if (assoc_req->mode == IW_MODE_INFRA) { 1467 - lbs_send_specific_ssid_scan(priv, assoc_req->ssid, 1468 - assoc_req->ssid_len); 1469 - 1470 - bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, 1471 - assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); 1472 - if (bss != NULL) { 1473 - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1474 - ret = lbs_try_associate(priv, assoc_req); 1475 - } else { 1476 - lbs_deb_assoc("SSID not found; cannot associate\n"); 1477 - } 1478 - } else if (assoc_req->mode == IW_MODE_ADHOC) { 1479 - /* Scan for the network, do not save previous results. Stale 1480 - * scan data will cause us to join a non-existant adhoc network 1481 - */ 1482 - lbs_send_specific_ssid_scan(priv, assoc_req->ssid, 1483 - assoc_req->ssid_len); 1484 - 1485 - /* Search for the requested SSID in the scan table */ 1486 - bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, 1487 - assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel); 1488 - if (bss != NULL) { 1489 - lbs_deb_assoc("SSID found, will join\n"); 1490 - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1491 - lbs_adhoc_join(priv, assoc_req); 1492 - } else { 1493 - /* else send START command */ 1494 - lbs_deb_assoc("SSID not found, creating adhoc network\n"); 1495 - memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, 1496 - IEEE80211_MAX_SSID_LEN); 1497 - assoc_req->bss.ssid_len = assoc_req->ssid_len; 1498 - lbs_adhoc_start(priv, assoc_req); 1499 - } 1500 - } 1501 - 1502 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1503 - return ret; 1504 - } 1505 - 1506 - 1507 - static int assoc_helper_bssid(struct lbs_private *priv, 1508 - struct assoc_request * assoc_req) 1509 - { 1510 - int ret = 0; 1511 - struct bss_descriptor * bss; 1512 - 1513 - lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %pM", assoc_req->bssid); 1514 - 1515 - /* Search for index position in list for requested MAC */ 1516 - bss = lbs_find_bssid_in_list(priv, assoc_req->bssid, 1517 - assoc_req->mode); 1518 - if (bss == NULL) { 1519 - lbs_deb_assoc("ASSOC: WAP: BSSID %pM not found, " 1520 - "cannot associate.\n", assoc_req->bssid); 1521 - goto out; 1522 - } 1523 - 1524 - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1525 - if (assoc_req->mode == IW_MODE_INFRA) { 1526 - ret = lbs_try_associate(priv, assoc_req); 1527 - lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n", 1528 - ret); 1529 - } else if (assoc_req->mode == IW_MODE_ADHOC) { 1530 - lbs_adhoc_join(priv, assoc_req); 1531 - } 1532 - 1533 - out: 1534 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1535 - return ret; 1536 - } 1537 - 1538 - 1539 - static int assoc_helper_associate(struct lbs_private *priv, 1540 - struct assoc_request * assoc_req) 1541 - { 1542 - int ret = 0, done = 0; 1543 - 1544 - lbs_deb_enter(LBS_DEB_ASSOC); 1545 - 1546 - /* If we're given and 'any' BSSID, try associating based on SSID */ 1547 - 1548 - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1549 - if (compare_ether_addr(bssid_any, assoc_req->bssid) && 1550 - compare_ether_addr(bssid_off, assoc_req->bssid)) { 1551 - ret = assoc_helper_bssid(priv, assoc_req); 1552 - done = 1; 1553 - } 1554 - } 1555 - 1556 - if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 1557 - ret = assoc_helper_essid(priv, assoc_req); 1558 - } 1559 - 1560 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1561 - return ret; 1562 - } 1563 - 1564 - 1565 - static int assoc_helper_mode(struct lbs_private *priv, 1566 - struct assoc_request * assoc_req) 1567 - { 1568 - int ret = 0; 1569 - 1570 - lbs_deb_enter(LBS_DEB_ASSOC); 1571 - 1572 - if (assoc_req->mode == priv->mode) 1573 - goto done; 1574 - 1575 - if (assoc_req->mode == IW_MODE_INFRA) { 1576 - if (priv->psstate != PS_STATE_FULL_POWER) 1577 - lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 1578 - priv->psmode = LBS802_11POWERMODECAM; 1579 - } 1580 - 1581 - priv->mode = assoc_req->mode; 1582 - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1583 - assoc_req->mode == IW_MODE_ADHOC ? 2 : 1); 1584 - 1585 - done: 1586 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1587 - return ret; 1588 - } 1589 - 1590 - static int assoc_helper_channel(struct lbs_private *priv, 1591 - struct assoc_request * assoc_req) 1592 - { 1593 - int ret = 0; 1594 - 1595 - lbs_deb_enter(LBS_DEB_ASSOC); 1596 - 1597 - ret = lbs_update_channel(priv); 1598 - if (ret) { 1599 - lbs_deb_assoc("ASSOC: channel: error getting channel.\n"); 1600 - goto done; 1601 - } 1602 - 1603 - if (assoc_req->channel == priv->channel) 1604 - goto done; 1605 - 1606 - if (priv->mesh_dev) { 1607 - /* Change mesh channel first; 21.p21 firmware won't let 1608 - you change channel otherwise (even though it'll return 1609 - an error to this */ 1610 - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1611 - assoc_req->channel); 1612 - } 1613 - 1614 - lbs_deb_assoc("ASSOC: channel: %d -> %d\n", 1615 - priv->channel, assoc_req->channel); 1616 - 1617 - ret = lbs_set_channel(priv, assoc_req->channel); 1618 - if (ret < 0) 1619 - lbs_deb_assoc("ASSOC: channel: error setting channel.\n"); 1620 - 1621 - /* FIXME: shouldn't need to grab the channel _again_ after setting 1622 - * it since the firmware is supposed to return the new channel, but 1623 - * whatever... */ 1624 - ret = lbs_update_channel(priv); 1625 - if (ret) { 1626 - lbs_deb_assoc("ASSOC: channel: error getting channel.\n"); 1627 - goto done; 1628 - } 1629 - 1630 - if (assoc_req->channel != priv->channel) { 1631 - lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", 1632 - assoc_req->channel); 1633 - goto restore_mesh; 1634 - } 1635 - 1636 - if (assoc_req->secinfo.wep_enabled && 1637 - (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || 1638 - assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) { 1639 - /* Make sure WEP keys are re-sent to firmware */ 1640 - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1641 - } 1642 - 1643 - /* Must restart/rejoin adhoc networks after channel change */ 1644 - set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); 1645 - 1646 - restore_mesh: 1647 - if (priv->mesh_dev) 1648 - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1649 - priv->channel); 1650 - 1651 - done: 1652 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1653 - return ret; 1654 - } 1655 - 1656 - 1657 - static int assoc_helper_wep_keys(struct lbs_private *priv, 1658 - struct assoc_request *assoc_req) 1659 - { 1660 - int i; 1661 - int ret = 0; 1662 - 1663 - lbs_deb_enter(LBS_DEB_ASSOC); 1664 - 1665 - /* Set or remove WEP keys */ 1666 - if (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || 1667 - assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len) 1668 - ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_ADD, assoc_req); 1669 - else 1670 - ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_REMOVE, assoc_req); 1671 - 1672 - if (ret) 1673 - goto out; 1674 - 1675 - /* enable/disable the MAC's WEP packet filter */ 1676 - if (assoc_req->secinfo.wep_enabled) 1677 - priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; 1678 - else 1679 - priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; 1680 - 1681 - lbs_set_mac_control(priv); 1682 - 1683 - mutex_lock(&priv->lock); 1684 - 1685 - /* Copy WEP keys into priv wep key fields */ 1686 - for (i = 0; i < 4; i++) { 1687 - memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i], 1688 - sizeof(struct enc_key)); 1689 - } 1690 - priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx; 1691 - 1692 - mutex_unlock(&priv->lock); 1693 - 1694 - out: 1695 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1696 - return ret; 1697 - } 1698 - 1699 - static int assoc_helper_secinfo(struct lbs_private *priv, 1700 - struct assoc_request * assoc_req) 1701 - { 1702 - int ret = 0; 1703 - uint16_t do_wpa; 1704 - uint16_t rsn = 0; 1705 - 1706 - lbs_deb_enter(LBS_DEB_ASSOC); 1707 - 1708 - memcpy(&priv->secinfo, &assoc_req->secinfo, 1709 - sizeof(struct lbs_802_11_security)); 1710 - 1711 - lbs_set_mac_control(priv); 1712 - 1713 - /* If RSN is already enabled, don't try to enable it again, since 1714 - * ENABLE_RSN resets internal state machines and will clobber the 1715 - * 4-way WPA handshake. 1716 - */ 1717 - 1718 - /* Get RSN enabled/disabled */ 1719 - ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_GET, &rsn); 1720 - if (ret) { 1721 - lbs_deb_assoc("Failed to get RSN status: %d\n", ret); 1722 - goto out; 1723 - } 1724 - 1725 - /* Don't re-enable RSN if it's already enabled */ 1726 - do_wpa = assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled; 1727 - if (do_wpa == rsn) 1728 - goto out; 1729 - 1730 - /* Set RSN enabled/disabled */ 1731 - ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_SET, &do_wpa); 1732 - 1733 - out: 1734 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1735 - return ret; 1736 - } 1737 - 1738 - 1739 - static int assoc_helper_wpa_keys(struct lbs_private *priv, 1740 - struct assoc_request * assoc_req) 1741 - { 1742 - int ret = 0; 1743 - unsigned int flags = assoc_req->flags; 1744 - 1745 - lbs_deb_enter(LBS_DEB_ASSOC); 1746 - 1747 - /* Work around older firmware bug where WPA unicast and multicast 1748 - * keys must be set independently. Seen in SDIO parts with firmware 1749 - * version 5.0.11p0. 1750 - */ 1751 - 1752 - if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 1753 - clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); 1754 - ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); 1755 - assoc_req->flags = flags; 1756 - } 1757 - 1758 - if (ret) 1759 - goto out; 1760 - 1761 - memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key, 1762 - sizeof(struct enc_key)); 1763 - 1764 - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 1765 - clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); 1766 - 1767 - ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); 1768 - assoc_req->flags = flags; 1769 - 1770 - memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key, 1771 - sizeof(struct enc_key)); 1772 - } 1773 - 1774 - out: 1775 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1776 - return ret; 1777 - } 1778 - 1779 - 1780 - static int assoc_helper_wpa_ie(struct lbs_private *priv, 1781 - struct assoc_request * assoc_req) 1782 - { 1783 - int ret = 0; 1784 - 1785 - lbs_deb_enter(LBS_DEB_ASSOC); 1786 - 1787 - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { 1788 - memcpy(&priv->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); 1789 - priv->wpa_ie_len = assoc_req->wpa_ie_len; 1790 - } else { 1791 - memset(&priv->wpa_ie, 0, MAX_WPA_IE_LEN); 1792 - priv->wpa_ie_len = 0; 1793 - } 1794 - 1795 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1796 - return ret; 1797 - } 1798 - 1799 - 1800 - static int should_deauth_infrastructure(struct lbs_private *priv, 1801 - struct assoc_request * assoc_req) 1802 - { 1803 - int ret = 0; 1804 - 1805 - if (priv->connect_status != LBS_CONNECTED) 1806 - return 0; 1807 - 1808 - lbs_deb_enter(LBS_DEB_ASSOC); 1809 - if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 1810 - lbs_deb_assoc("Deauthenticating due to new SSID\n"); 1811 - ret = 1; 1812 - goto out; 1813 - } 1814 - 1815 - if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 1816 - if (priv->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { 1817 - lbs_deb_assoc("Deauthenticating due to new security\n"); 1818 - ret = 1; 1819 - goto out; 1820 - } 1821 - } 1822 - 1823 - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1824 - lbs_deb_assoc("Deauthenticating due to new BSSID\n"); 1825 - ret = 1; 1826 - goto out; 1827 - } 1828 - 1829 - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { 1830 - lbs_deb_assoc("Deauthenticating due to channel switch\n"); 1831 - ret = 1; 1832 - goto out; 1833 - } 1834 - 1835 - /* FIXME: deal with 'auto' mode somehow */ 1836 - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { 1837 - if (assoc_req->mode != IW_MODE_INFRA) { 1838 - lbs_deb_assoc("Deauthenticating due to leaving " 1839 - "infra mode\n"); 1840 - ret = 1; 1841 - goto out; 1842 - } 1843 - } 1844 - 1845 - out: 1846 - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 1847 - return ret; 1848 - } 1849 - 1850 - 1851 - static int should_stop_adhoc(struct lbs_private *priv, 1852 - struct assoc_request * assoc_req) 1853 - { 1854 - lbs_deb_enter(LBS_DEB_ASSOC); 1855 - 1856 - if (priv->connect_status != LBS_CONNECTED) 1857 - return 0; 1858 - 1859 - if (lbs_ssid_cmp(priv->curbssparams.ssid, 1860 - priv->curbssparams.ssid_len, 1861 - assoc_req->ssid, assoc_req->ssid_len) != 0) 1862 - return 1; 1863 - 1864 - /* FIXME: deal with 'auto' mode somehow */ 1865 - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { 1866 - if (assoc_req->mode != IW_MODE_ADHOC) 1867 - return 1; 1868 - } 1869 - 1870 - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { 1871 - if (assoc_req->channel != priv->channel) 1872 - return 1; 1873 - } 1874 - 1875 - lbs_deb_leave(LBS_DEB_ASSOC); 1876 - return 0; 1877 - } 1878 - 1879 - 1880 - /** 1881 - * @brief This function finds the best SSID in the Scan List 1882 - * 1883 - * Search the scan table for the best SSID that also matches the current 1884 - * adapter network preference (infrastructure or adhoc) 1885 - * 1886 - * @param priv A pointer to struct lbs_private 1887 - * 1888 - * @return index in BSSID list 1889 - */ 1890 - static struct bss_descriptor *lbs_find_best_ssid_in_list( 1891 - struct lbs_private *priv, uint8_t mode) 1892 - { 1893 - uint8_t bestrssi = 0; 1894 - struct bss_descriptor *iter_bss; 1895 - struct bss_descriptor *best_bss = NULL; 1896 - 1897 - lbs_deb_enter(LBS_DEB_SCAN); 1898 - 1899 - mutex_lock(&priv->lock); 1900 - 1901 - list_for_each_entry(iter_bss, &priv->network_list, list) { 1902 - switch (mode) { 1903 - case IW_MODE_INFRA: 1904 - case IW_MODE_ADHOC: 1905 - if (!is_network_compatible(priv, iter_bss, mode)) 1906 - break; 1907 - if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) 1908 - break; 1909 - bestrssi = SCAN_RSSI(iter_bss->rssi); 1910 - best_bss = iter_bss; 1911 - break; 1912 - case IW_MODE_AUTO: 1913 - default: 1914 - if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) 1915 - break; 1916 - bestrssi = SCAN_RSSI(iter_bss->rssi); 1917 - best_bss = iter_bss; 1918 - break; 1919 - } 1920 - } 1921 - 1922 - mutex_unlock(&priv->lock); 1923 - lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss); 1924 - return best_bss; 1925 - } 1926 - 1927 - /** 1928 - * @brief Find the best AP 1929 - * 1930 - * Used from association worker. 1931 - * 1932 - * @param priv A pointer to struct lbs_private structure 1933 - * @param pSSID A pointer to AP's ssid 1934 - * 1935 - * @return 0--success, otherwise--fail 1936 - */ 1937 - static int lbs_find_best_network_ssid(struct lbs_private *priv, 1938 - uint8_t *out_ssid, uint8_t *out_ssid_len, uint8_t preferred_mode, 1939 - uint8_t *out_mode) 1940 - { 1941 - int ret = -1; 1942 - struct bss_descriptor *found; 1943 - 1944 - lbs_deb_enter(LBS_DEB_SCAN); 1945 - 1946 - priv->scan_ssid_len = 0; 1947 - lbs_scan_networks(priv, 1); 1948 - if (priv->surpriseremoved) 1949 - goto out; 1950 - 1951 - found = lbs_find_best_ssid_in_list(priv, preferred_mode); 1952 - if (found && (found->ssid_len > 0)) { 1953 - memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN); 1954 - *out_ssid_len = found->ssid_len; 1955 - *out_mode = found->mode; 1956 - ret = 0; 1957 - } 1958 - 1959 - out: 1960 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 1961 - return ret; 1962 - } 1963 - 1964 - 1965 - void lbs_association_worker(struct work_struct *work) 1966 - { 1967 - struct lbs_private *priv = container_of(work, struct lbs_private, 1968 - assoc_work.work); 1969 - struct assoc_request * assoc_req = NULL; 1970 - int ret = 0; 1971 - int find_any_ssid = 0; 1972 - DECLARE_SSID_BUF(ssid); 1973 - 1974 - lbs_deb_enter(LBS_DEB_ASSOC); 1975 - 1976 - mutex_lock(&priv->lock); 1977 - assoc_req = priv->pending_assoc_req; 1978 - priv->pending_assoc_req = NULL; 1979 - priv->in_progress_assoc_req = assoc_req; 1980 - mutex_unlock(&priv->lock); 1981 - 1982 - if (!assoc_req) 1983 - goto done; 1984 - 1985 - lbs_deb_assoc( 1986 - "Association Request:\n" 1987 - " flags: 0x%08lx\n" 1988 - " SSID: '%s'\n" 1989 - " chann: %d\n" 1990 - " band: %d\n" 1991 - " mode: %d\n" 1992 - " BSSID: %pM\n" 1993 - " secinfo: %s%s%s\n" 1994 - " auth_mode: %d\n", 1995 - assoc_req->flags, 1996 - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len), 1997 - assoc_req->channel, assoc_req->band, assoc_req->mode, 1998 - assoc_req->bssid, 1999 - assoc_req->secinfo.WPAenabled ? " WPA" : "", 2000 - assoc_req->secinfo.WPA2enabled ? " WPA2" : "", 2001 - assoc_req->secinfo.wep_enabled ? " WEP" : "", 2002 - assoc_req->secinfo.auth_mode); 2003 - 2004 - /* If 'any' SSID was specified, find an SSID to associate with */ 2005 - if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) && 2006 - !assoc_req->ssid_len) 2007 - find_any_ssid = 1; 2008 - 2009 - /* But don't use 'any' SSID if there's a valid locked BSSID to use */ 2010 - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 2011 - if (compare_ether_addr(assoc_req->bssid, bssid_any) && 2012 - compare_ether_addr(assoc_req->bssid, bssid_off)) 2013 - find_any_ssid = 0; 2014 - } 2015 - 2016 - if (find_any_ssid) { 2017 - u8 new_mode = assoc_req->mode; 2018 - 2019 - ret = lbs_find_best_network_ssid(priv, assoc_req->ssid, 2020 - &assoc_req->ssid_len, assoc_req->mode, &new_mode); 2021 - if (ret) { 2022 - lbs_deb_assoc("Could not find best network\n"); 2023 - ret = -ENETUNREACH; 2024 - goto out; 2025 - } 2026 - 2027 - /* Ensure we switch to the mode of the AP */ 2028 - if (assoc_req->mode == IW_MODE_AUTO) { 2029 - set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); 2030 - assoc_req->mode = new_mode; 2031 - } 2032 - } 2033 - 2034 - /* 2035 - * Check if the attributes being changing require deauthentication 2036 - * from the currently associated infrastructure access point. 2037 - */ 2038 - if (priv->mode == IW_MODE_INFRA) { 2039 - if (should_deauth_infrastructure(priv, assoc_req)) { 2040 - ret = lbs_cmd_80211_deauthenticate(priv, 2041 - priv->curbssparams.bssid, 2042 - WLAN_REASON_DEAUTH_LEAVING); 2043 - if (ret) { 2044 - lbs_deb_assoc("Deauthentication due to new " 2045 - "configuration request failed: %d\n", 2046 - ret); 2047 - } 2048 - } 2049 - } else if (priv->mode == IW_MODE_ADHOC) { 2050 - if (should_stop_adhoc(priv, assoc_req)) { 2051 - ret = lbs_adhoc_stop(priv); 2052 - if (ret) { 2053 - lbs_deb_assoc("Teardown of AdHoc network due to " 2054 - "new configuration request failed: %d\n", 2055 - ret); 2056 - } 2057 - 2058 - } 2059 - } 2060 - 2061 - /* Send the various configuration bits to the firmware */ 2062 - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { 2063 - ret = assoc_helper_mode(priv, assoc_req); 2064 - if (ret) 2065 - goto out; 2066 - } 2067 - 2068 - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { 2069 - ret = assoc_helper_channel(priv, assoc_req); 2070 - if (ret) 2071 - goto out; 2072 - } 2073 - 2074 - if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 2075 - ret = assoc_helper_secinfo(priv, assoc_req); 2076 - if (ret) 2077 - goto out; 2078 - } 2079 - 2080 - if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { 2081 - ret = assoc_helper_wpa_ie(priv, assoc_req); 2082 - if (ret) 2083 - goto out; 2084 - } 2085 - 2086 - /* 2087 - * v10 FW wants WPA keys to be set/cleared before WEP key operations, 2088 - * otherwise it will fail to correctly associate to WEP networks. 2089 - * Other firmware versions don't appear to care. 2090 - */ 2091 - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || 2092 - test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 2093 - ret = assoc_helper_wpa_keys(priv, assoc_req); 2094 - if (ret) 2095 - goto out; 2096 - } 2097 - 2098 - if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || 2099 - test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { 2100 - ret = assoc_helper_wep_keys(priv, assoc_req); 2101 - if (ret) 2102 - goto out; 2103 - } 2104 - 2105 - 2106 - /* SSID/BSSID should be the _last_ config option set, because they 2107 - * trigger the association attempt. 2108 - */ 2109 - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) || 2110 - test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 2111 - int success = 1; 2112 - 2113 - ret = assoc_helper_associate(priv, assoc_req); 2114 - if (ret) { 2115 - lbs_deb_assoc("ASSOC: association unsuccessful: %d\n", 2116 - ret); 2117 - success = 0; 2118 - } 2119 - 2120 - if (priv->connect_status != LBS_CONNECTED) { 2121 - lbs_deb_assoc("ASSOC: association unsuccessful, " 2122 - "not connected\n"); 2123 - success = 0; 2124 - } 2125 - 2126 - if (success) { 2127 - lbs_deb_assoc("associated to %pM\n", 2128 - priv->curbssparams.bssid); 2129 - lbs_prepare_and_send_command(priv, 2130 - CMD_802_11_RSSI, 2131 - 0, CMD_OPTION_WAITFORRSP, 0, NULL); 2132 - } else { 2133 - ret = -1; 2134 - } 2135 - } 2136 - 2137 - out: 2138 - if (ret) { 2139 - lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", 2140 - ret); 2141 - } 2142 - 2143 - mutex_lock(&priv->lock); 2144 - priv->in_progress_assoc_req = NULL; 2145 - mutex_unlock(&priv->lock); 2146 - kfree(assoc_req); 2147 - 2148 - done: 2149 - lbs_deb_leave(LBS_DEB_ASSOC); 2150 - } 2151 - 2152 - 2153 - /* 2154 - * Caller MUST hold any necessary locks 2155 - */ 2156 - struct assoc_request *lbs_get_association_request(struct lbs_private *priv) 2157 - { 2158 - struct assoc_request * assoc_req; 2159 - 2160 - lbs_deb_enter(LBS_DEB_ASSOC); 2161 - if (!priv->pending_assoc_req) { 2162 - priv->pending_assoc_req = kzalloc(sizeof(struct assoc_request), 2163 - GFP_KERNEL); 2164 - if (!priv->pending_assoc_req) { 2165 - lbs_pr_info("Not enough memory to allocate association" 2166 - " request!\n"); 2167 - return NULL; 2168 - } 2169 - } 2170 - 2171 - /* Copy current configuration attributes to the association request, 2172 - * but don't overwrite any that are already set. 2173 - */ 2174 - assoc_req = priv->pending_assoc_req; 2175 - if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 2176 - memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, 2177 - IEEE80211_MAX_SSID_LEN); 2178 - assoc_req->ssid_len = priv->curbssparams.ssid_len; 2179 - } 2180 - 2181 - if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) 2182 - assoc_req->channel = priv->channel; 2183 - 2184 - if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) 2185 - assoc_req->band = priv->curbssparams.band; 2186 - 2187 - if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) 2188 - assoc_req->mode = priv->mode; 2189 - 2190 - if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 2191 - memcpy(&assoc_req->bssid, priv->curbssparams.bssid, 2192 - ETH_ALEN); 2193 - } 2194 - 2195 - if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) { 2196 - int i; 2197 - for (i = 0; i < 4; i++) { 2198 - memcpy(&assoc_req->wep_keys[i], &priv->wep_keys[i], 2199 - sizeof(struct enc_key)); 2200 - } 2201 - } 2202 - 2203 - if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) 2204 - assoc_req->wep_tx_keyidx = priv->wep_tx_keyidx; 2205 - 2206 - if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 2207 - memcpy(&assoc_req->wpa_mcast_key, &priv->wpa_mcast_key, 2208 - sizeof(struct enc_key)); 2209 - } 2210 - 2211 - if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 2212 - memcpy(&assoc_req->wpa_unicast_key, &priv->wpa_unicast_key, 2213 - sizeof(struct enc_key)); 2214 - } 2215 - 2216 - if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 2217 - memcpy(&assoc_req->secinfo, &priv->secinfo, 2218 - sizeof(struct lbs_802_11_security)); 2219 - } 2220 - 2221 - if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { 2222 - memcpy(&assoc_req->wpa_ie, &priv->wpa_ie, 2223 - MAX_WPA_IE_LEN); 2224 - assoc_req->wpa_ie_len = priv->wpa_ie_len; 2225 - } 2226 - 2227 - lbs_deb_leave(LBS_DEB_ASSOC); 2228 - return assoc_req; 2229 - } 2230 - 2231 - 2232 - /** 2233 - * @brief Deauthenticate from a specific BSS 2234 - * 2235 - * @param priv A pointer to struct lbs_private structure 2236 - * @param bssid The specific BSS to deauthenticate from 2237 - * @param reason The 802.11 sec. 7.3.1.7 Reason Code for deauthenticating 2238 - * 2239 - * @return 0 on success, error on failure 2240 - */ 2241 - int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN], 2242 - u16 reason) 2243 - { 2244 - struct cmd_ds_802_11_deauthenticate cmd; 2245 - int ret; 2246 - 2247 - lbs_deb_enter(LBS_DEB_JOIN); 2248 - 2249 - memset(&cmd, 0, sizeof(cmd)); 2250 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 2251 - memcpy(cmd.macaddr, &bssid[0], ETH_ALEN); 2252 - cmd.reasoncode = cpu_to_le16(reason); 2253 - 2254 - ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd); 2255 - 2256 - /* Clean up everything even if there was an error; can't assume that 2257 - * we're still authenticated to the AP after trying to deauth. 2258 - */ 2259 - lbs_mac_event_disconnected(priv); 2260 - 2261 - lbs_deb_leave(LBS_DEB_JOIN); 2262 - return ret; 2263 - } 2264 -
-155
drivers/net/wireless/libertas/assoc.h
··· 1 - /* Copyright (C) 2006, Red Hat, Inc. */ 2 - 3 - #ifndef _LBS_ASSOC_H_ 4 - #define _LBS_ASSOC_H_ 5 - 6 - 7 - #include "defs.h" 8 - #include "host.h" 9 - 10 - 11 - struct lbs_private; 12 - 13 - /* 14 - * In theory, the IE is limited to the IE length, 255, 15 - * but in practice 64 bytes are enough. 16 - */ 17 - #define MAX_WPA_IE_LEN 64 18 - 19 - 20 - 21 - struct lbs_802_11_security { 22 - u8 WPAenabled; 23 - u8 WPA2enabled; 24 - u8 wep_enabled; 25 - u8 auth_mode; 26 - u32 key_mgmt; 27 - }; 28 - 29 - /** Current Basic Service Set State Structure */ 30 - struct current_bss_params { 31 - /** bssid */ 32 - u8 bssid[ETH_ALEN]; 33 - /** ssid */ 34 - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 35 - u8 ssid_len; 36 - 37 - /** band */ 38 - u8 band; 39 - /** channel is directly in priv->channel */ 40 - /** zero-terminated array of supported data rates */ 41 - u8 rates[MAX_RATES + 1]; 42 - }; 43 - 44 - /** 45 - * @brief Structure used to store information for each beacon/probe response 46 - */ 47 - struct bss_descriptor { 48 - u8 bssid[ETH_ALEN]; 49 - 50 - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 51 - u8 ssid_len; 52 - 53 - u16 capability; 54 - u32 rssi; 55 - u32 channel; 56 - u16 beaconperiod; 57 - __le16 atimwindow; 58 - 59 - /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ 60 - u8 mode; 61 - 62 - /* zero-terminated array of supported data rates */ 63 - u8 rates[MAX_RATES + 1]; 64 - 65 - unsigned long last_scanned; 66 - 67 - union ieee_phy_param_set phy; 68 - union ieee_ss_param_set ss; 69 - 70 - u8 wpa_ie[MAX_WPA_IE_LEN]; 71 - size_t wpa_ie_len; 72 - u8 rsn_ie[MAX_WPA_IE_LEN]; 73 - size_t rsn_ie_len; 74 - 75 - u8 mesh; 76 - 77 - struct list_head list; 78 - }; 79 - 80 - /** Association request 81 - * 82 - * Encapsulates all the options that describe a specific assocation request 83 - * or configuration of the wireless card's radio, mode, and security settings. 84 - */ 85 - struct assoc_request { 86 - #define ASSOC_FLAG_SSID 1 87 - #define ASSOC_FLAG_CHANNEL 2 88 - #define ASSOC_FLAG_BAND 3 89 - #define ASSOC_FLAG_MODE 4 90 - #define ASSOC_FLAG_BSSID 5 91 - #define ASSOC_FLAG_WEP_KEYS 6 92 - #define ASSOC_FLAG_WEP_TX_KEYIDX 7 93 - #define ASSOC_FLAG_WPA_MCAST_KEY 8 94 - #define ASSOC_FLAG_WPA_UCAST_KEY 9 95 - #define ASSOC_FLAG_SECINFO 10 96 - #define ASSOC_FLAG_WPA_IE 11 97 - unsigned long flags; 98 - 99 - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 100 - u8 ssid_len; 101 - u8 channel; 102 - u8 band; 103 - u8 mode; 104 - u8 bssid[ETH_ALEN] __attribute__ ((aligned (2))); 105 - 106 - /** WEP keys */ 107 - struct enc_key wep_keys[4]; 108 - u16 wep_tx_keyidx; 109 - 110 - /** WPA keys */ 111 - struct enc_key wpa_mcast_key; 112 - struct enc_key wpa_unicast_key; 113 - 114 - struct lbs_802_11_security secinfo; 115 - 116 - /** WPA Information Elements*/ 117 - u8 wpa_ie[MAX_WPA_IE_LEN]; 118 - u8 wpa_ie_len; 119 - 120 - /* BSS to associate with for infrastructure of Ad-Hoc join */ 121 - struct bss_descriptor bss; 122 - }; 123 - 124 - 125 - extern u8 lbs_bg_rates[MAX_RATES]; 126 - 127 - void lbs_association_worker(struct work_struct *work); 128 - struct assoc_request *lbs_get_association_request(struct lbs_private *priv); 129 - 130 - int lbs_adhoc_stop(struct lbs_private *priv); 131 - 132 - int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 133 - u8 bssid[ETH_ALEN], u16 reason); 134 - 135 - int lbs_cmd_802_11_rssi(struct lbs_private *priv, 136 - struct cmd_ds_command *cmd); 137 - int lbs_ret_802_11_rssi(struct lbs_private *priv, 138 - struct cmd_ds_command *resp); 139 - 140 - int lbs_cmd_bcn_ctrl(struct lbs_private *priv, 141 - struct cmd_ds_command *cmd, 142 - u16 cmd_action); 143 - int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, 144 - struct cmd_ds_command *resp); 145 - 146 - int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, 147 - struct assoc_request *assoc); 148 - 149 - int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, 150 - uint16_t *enable); 151 - 152 - int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, 153 - struct assoc_request *assoc); 154 - 155 - #endif /* _LBS_ASSOC_H */
+2016 -22
drivers/net/wireless/libertas/cfg.c
··· 7 7 */ 8 8 9 9 #include <linux/slab.h> 10 + #include <linux/if_arp.h> 11 + #include <linux/ieee80211.h> 10 12 #include <net/cfg80211.h> 13 + #include <asm/unaligned.h> 11 14 15 + #include "decl.h" 12 16 #include "cfg.h" 13 17 #include "cmd.h" 14 18 ··· 43 39 CHAN2G(14, 2484, 0), 44 40 }; 45 41 46 - #define RATETAB_ENT(_rate, _rateid, _flags) { \ 47 - .bitrate = (_rate), \ 48 - .hw_value = (_rateid), \ 49 - .flags = (_flags), \ 42 + #define RATETAB_ENT(_rate, _hw_value, _flags) { \ 43 + .bitrate = (_rate), \ 44 + .hw_value = (_hw_value), \ 45 + .flags = (_flags), \ 50 46 } 51 47 52 48 49 + /* Table 6 in section 3.2.1.1 */ 53 50 static struct ieee80211_rate lbs_rates[] = { 54 - RATETAB_ENT(10, 0x1, 0), 55 - RATETAB_ENT(20, 0x2, 0), 56 - RATETAB_ENT(55, 0x4, 0), 57 - RATETAB_ENT(110, 0x8, 0), 58 - RATETAB_ENT(60, 0x10, 0), 59 - RATETAB_ENT(90, 0x20, 0), 60 - RATETAB_ENT(120, 0x40, 0), 61 - RATETAB_ENT(180, 0x80, 0), 62 - RATETAB_ENT(240, 0x100, 0), 63 - RATETAB_ENT(360, 0x200, 0), 64 - RATETAB_ENT(480, 0x400, 0), 65 - RATETAB_ENT(540, 0x800, 0), 51 + RATETAB_ENT(10, 0, 0), 52 + RATETAB_ENT(20, 1, 0), 53 + RATETAB_ENT(55, 2, 0), 54 + RATETAB_ENT(110, 3, 0), 55 + RATETAB_ENT(60, 9, 0), 56 + RATETAB_ENT(90, 6, 0), 57 + RATETAB_ENT(120, 7, 0), 58 + RATETAB_ENT(180, 8, 0), 59 + RATETAB_ENT(240, 9, 0), 60 + RATETAB_ENT(360, 10, 0), 61 + RATETAB_ENT(480, 11, 0), 62 + RATETAB_ENT(540, 12, 0), 66 63 }; 67 64 68 65 static struct ieee80211_supported_band lbs_band_2ghz = { ··· 81 76 WLAN_CIPHER_SUITE_CCMP, 82 77 }; 83 78 79 + /* Time to stay on the channel */ 80 + #define LBS_DWELL_PASSIVE 100 81 + #define LBS_DWELL_ACTIVE 40 84 82 83 + 84 + /*************************************************************************** 85 + * Misc utility functions 86 + * 87 + * TLVs are Marvell specific. They are very similar to IEs, they have the 88 + * same structure: type, length, data*. The only difference: for IEs, the 89 + * type and length are u8, but for TLVs they're __le16. 90 + */ 91 + 92 + /* 93 + * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1 94 + * in the firmware spec 95 + */ 96 + static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) 97 + { 98 + int ret = -ENOTSUPP; 99 + 100 + switch (auth_type) { 101 + case NL80211_AUTHTYPE_OPEN_SYSTEM: 102 + case NL80211_AUTHTYPE_SHARED_KEY: 103 + ret = auth_type; 104 + break; 105 + case NL80211_AUTHTYPE_AUTOMATIC: 106 + ret = NL80211_AUTHTYPE_OPEN_SYSTEM; 107 + break; 108 + case NL80211_AUTHTYPE_NETWORK_EAP: 109 + ret = 0x80; 110 + break; 111 + default: 112 + /* silence compiler */ 113 + break; 114 + } 115 + return ret; 116 + } 117 + 118 + 119 + /* Various firmware commands need the list of supported rates, but with 120 + the hight-bit set for basic rates */ 121 + static int lbs_add_rates(u8 *rates) 122 + { 123 + size_t i; 124 + 125 + for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { 126 + u8 rate = lbs_rates[i].bitrate / 5; 127 + if (rate == 0x02 || rate == 0x04 || 128 + rate == 0x0b || rate == 0x16) 129 + rate |= 0x80; 130 + rates[i] = rate; 131 + } 132 + return ARRAY_SIZE(lbs_rates); 133 + } 134 + 135 + 136 + /*************************************************************************** 137 + * TLV utility functions 138 + * 139 + * TLVs are Marvell specific. They are very similar to IEs, they have the 140 + * same structure: type, length, data*. The only difference: for IEs, the 141 + * type and length are u8, but for TLVs they're __le16. 142 + */ 143 + 144 + 145 + /* 146 + * Add ssid TLV 147 + */ 148 + #define LBS_MAX_SSID_TLV_SIZE \ 149 + (sizeof(struct mrvl_ie_header) \ 150 + + IEEE80211_MAX_SSID_LEN) 151 + 152 + static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len) 153 + { 154 + struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; 155 + 156 + /* 157 + * TLV-ID SSID 00 00 158 + * length 06 00 159 + * ssid 4d 4e 54 45 53 54 160 + */ 161 + ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 162 + ssid_tlv->header.len = cpu_to_le16(ssid_len); 163 + memcpy(ssid_tlv->ssid, ssid, ssid_len); 164 + return sizeof(ssid_tlv->header) + ssid_len; 165 + } 166 + 167 + 168 + /* 169 + * Add channel list TLV (section 8.4.2) 170 + * 171 + * Actual channel data comes from priv->wdev->wiphy->channels. 172 + */ 173 + #define LBS_MAX_CHANNEL_LIST_TLV_SIZE \ 174 + (sizeof(struct mrvl_ie_header) \ 175 + + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset))) 176 + 177 + static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv, 178 + int last_channel, int active_scan) 179 + { 180 + int chanscanparamsize = sizeof(struct chanscanparamset) * 181 + (last_channel - priv->scan_channel); 182 + 183 + struct mrvl_ie_header *header = (void *) tlv; 184 + 185 + /* 186 + * TLV-ID CHANLIST 01 01 187 + * length 0e 00 188 + * channel 00 01 00 00 00 64 00 189 + * radio type 00 190 + * channel 01 191 + * scan type 00 192 + * min scan time 00 00 193 + * max scan time 64 00 194 + * channel 2 00 02 00 00 00 64 00 195 + * 196 + */ 197 + 198 + header->type = cpu_to_le16(TLV_TYPE_CHANLIST); 199 + header->len = cpu_to_le16(chanscanparamsize); 200 + tlv += sizeof(struct mrvl_ie_header); 201 + 202 + /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel, 203 + last_channel); */ 204 + memset(tlv, 0, chanscanparamsize); 205 + 206 + while (priv->scan_channel < last_channel) { 207 + struct chanscanparamset *param = (void *) tlv; 208 + 209 + param->radiotype = CMD_SCAN_RADIO_TYPE_BG; 210 + param->channumber = 211 + priv->scan_req->channels[priv->scan_channel]->hw_value; 212 + if (active_scan) { 213 + param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE); 214 + } else { 215 + param->chanscanmode.passivescan = 1; 216 + param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE); 217 + } 218 + tlv += sizeof(struct chanscanparamset); 219 + priv->scan_channel++; 220 + } 221 + return sizeof(struct mrvl_ie_header) + chanscanparamsize; 222 + } 223 + 224 + 225 + /* 226 + * Add rates TLV 227 + * 228 + * The rates are in lbs_bg_rates[], but for the 802.11b 229 + * rates the high bit is set. We add this TLV only because 230 + * there's a firmware which otherwise doesn't report all 231 + * APs in range. 232 + */ 233 + #define LBS_MAX_RATES_TLV_SIZE \ 234 + (sizeof(struct mrvl_ie_header) \ 235 + + (ARRAY_SIZE(lbs_rates))) 236 + 237 + /* Adds a TLV with all rates the hardware supports */ 238 + static int lbs_add_supported_rates_tlv(u8 *tlv) 239 + { 240 + size_t i; 241 + struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; 242 + 243 + /* 244 + * TLV-ID RATES 01 00 245 + * length 0e 00 246 + * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 247 + */ 248 + rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 249 + tlv += sizeof(rate_tlv->header); 250 + i = lbs_add_rates(tlv); 251 + tlv += i; 252 + rate_tlv->header.len = cpu_to_le16(i); 253 + return sizeof(rate_tlv->header) + i; 254 + } 255 + 256 + 257 + /* 258 + * Adds a TLV with all rates the hardware *and* BSS supports. 259 + */ 260 + static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) 261 + { 262 + struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; 263 + const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); 264 + int n; 265 + 266 + /* 267 + * 01 00 TLV_TYPE_RATES 268 + * 04 00 len 269 + * 82 84 8b 96 rates 270 + */ 271 + rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 272 + tlv += sizeof(rate_tlv->header); 273 + 274 + if (!rates_eid) { 275 + /* Fallback: add basic 802.11b rates */ 276 + *tlv++ = 0x82; 277 + *tlv++ = 0x84; 278 + *tlv++ = 0x8b; 279 + *tlv++ = 0x96; 280 + n = 4; 281 + } else { 282 + int hw, ap; 283 + u8 ap_max = rates_eid[1]; 284 + n = 0; 285 + for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { 286 + u8 hw_rate = lbs_rates[hw].bitrate / 5; 287 + for (ap = 0; ap < ap_max; ap++) { 288 + if (hw_rate == (rates_eid[ap+2] & 0x7f)) { 289 + *tlv++ = rates_eid[ap+2]; 290 + n++; 291 + } 292 + } 293 + } 294 + } 295 + 296 + rate_tlv->header.len = cpu_to_le16(n); 297 + return sizeof(rate_tlv->header) + n; 298 + } 299 + 300 + 301 + /* 302 + * Add auth type TLV. 303 + * 304 + * This is only needed for newer firmware (V9 and up). 305 + */ 306 + #define LBS_MAX_AUTH_TYPE_TLV_SIZE \ 307 + sizeof(struct mrvl_ie_auth_type) 308 + 309 + static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type) 310 + { 311 + struct mrvl_ie_auth_type *auth = (void *) tlv; 312 + 313 + /* 314 + * 1f 01 TLV_TYPE_AUTH_TYPE 315 + * 01 00 len 316 + * 01 auth type 317 + */ 318 + auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); 319 + auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header)); 320 + auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type)); 321 + return sizeof(*auth); 322 + } 323 + 324 + 325 + /* 326 + * Add channel (phy ds) TLV 327 + */ 328 + #define LBS_MAX_CHANNEL_TLV_SIZE \ 329 + sizeof(struct mrvl_ie_header) 330 + 331 + static int lbs_add_channel_tlv(u8 *tlv, u8 channel) 332 + { 333 + struct mrvl_ie_ds_param_set *ds = (void *) tlv; 334 + 335 + /* 336 + * 03 00 TLV_TYPE_PHY_DS 337 + * 01 00 len 338 + * 06 channel 339 + */ 340 + ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); 341 + ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header)); 342 + ds->channel = channel; 343 + return sizeof(*ds); 344 + } 345 + 346 + 347 + /* 348 + * Add (empty) CF param TLV of the form: 349 + */ 350 + #define LBS_MAX_CF_PARAM_TLV_SIZE \ 351 + sizeof(struct mrvl_ie_header) 352 + 353 + static int lbs_add_cf_param_tlv(u8 *tlv) 354 + { 355 + struct mrvl_ie_cf_param_set *cf = (void *)tlv; 356 + 357 + /* 358 + * 04 00 TLV_TYPE_CF 359 + * 06 00 len 360 + * 00 cfpcnt 361 + * 00 cfpperiod 362 + * 00 00 cfpmaxduration 363 + * 00 00 cfpdurationremaining 364 + */ 365 + cf->header.type = cpu_to_le16(TLV_TYPE_CF); 366 + cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header)); 367 + return sizeof(*cf); 368 + } 369 + 370 + /* 371 + * Add WPA TLV 372 + */ 373 + #define LBS_MAX_WPA_TLV_SIZE \ 374 + (sizeof(struct mrvl_ie_header) \ 375 + + 128 /* TODO: I guessed the size */) 376 + 377 + static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) 378 + { 379 + size_t tlv_len; 380 + 381 + /* 382 + * We need just convert an IE to an TLV. IEs use u8 for the header, 383 + * u8 type 384 + * u8 len 385 + * u8[] data 386 + * but TLVs use __le16 instead: 387 + * __le16 type 388 + * __le16 len 389 + * u8[] data 390 + */ 391 + *tlv++ = *ie++; 392 + *tlv++ = 0; 393 + tlv_len = *tlv++ = *ie++; 394 + *tlv++ = 0; 395 + while (tlv_len--) 396 + *tlv++ = *ie++; 397 + /* the TLV is two bytes larger than the IE */ 398 + return ie_len + 2; 399 + } 400 + 401 + /*************************************************************************** 402 + * Set Channel 403 + */ 85 404 86 405 static int lbs_cfg_set_channel(struct wiphy *wiphy, 87 406 struct net_device *netdev, 88 - struct ieee80211_channel *chan, 407 + struct ieee80211_channel *channel, 89 408 enum nl80211_channel_type channel_type) 90 409 { 91 410 struct lbs_private *priv = wiphy_priv(wiphy); 92 411 int ret = -ENOTSUPP; 93 412 94 - lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", chan->center_freq, channel_type); 413 + lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", 414 + channel->center_freq, channel_type); 95 415 96 416 if (channel_type != NL80211_CHAN_NO_HT) 97 417 goto out; 98 418 99 - ret = lbs_set_channel(priv, chan->hw_value); 419 + ret = lbs_set_channel(priv, channel->hw_value); 420 + 421 + out: 422 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 423 + return ret; 424 + } 425 + 426 + 427 + 428 + /*************************************************************************** 429 + * Scanning 430 + */ 431 + 432 + /* 433 + * When scanning, the firmware doesn't send a nul packet with the power-safe 434 + * bit to the AP. So we cannot stay away from our current channel too long, 435 + * otherwise we loose data. So take a "nap" while scanning every other 436 + * while. 437 + */ 438 + #define LBS_SCAN_BEFORE_NAP 4 439 + 440 + 441 + /* 442 + * When the firmware reports back a scan-result, it gives us an "u8 rssi", 443 + * which isn't really an RSSI, as it becomes larger when moving away from 444 + * the AP. Anyway, we need to convert that into mBm. 445 + */ 446 + #define LBS_SCAN_RSSI_TO_MBM(rssi) \ 447 + ((-(int)rssi + 3)*100) 448 + 449 + static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, 450 + struct cmd_header *resp) 451 + { 452 + struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; 453 + int bsssize; 454 + const u8 *pos; 455 + u16 nr_sets; 456 + const u8 *tsfdesc; 457 + int tsfsize; 458 + int i; 459 + int ret = -EILSEQ; 460 + 461 + lbs_deb_enter(LBS_DEB_CFG80211); 462 + 463 + bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); 464 + nr_sets = le16_to_cpu(resp->size); 465 + 466 + /* 467 + * The general layout of the scan response is described in chapter 468 + * 5.7.1. Basically we have a common part, then any number of BSS 469 + * descriptor sections. Finally we have section with the same number 470 + * of TSFs. 471 + * 472 + * cmd_ds_802_11_scan_rsp 473 + * cmd_header 474 + * pos_size 475 + * nr_sets 476 + * bssdesc 1 477 + * bssid 478 + * rssi 479 + * timestamp 480 + * intvl 481 + * capa 482 + * IEs 483 + * bssdesc 2 484 + * bssdesc n 485 + * MrvlIEtypes_TsfFimestamp_t 486 + * TSF for BSS 1 487 + * TSF for BSS 2 488 + * TSF for BSS n 489 + */ 490 + 491 + pos = scanresp->bssdesc_and_tlvbuffer; 492 + 493 + tsfdesc = pos + bsssize; 494 + tsfsize = 4 + 8 * scanresp->nr_sets; 495 + 496 + /* Validity check: we expect a Marvell-Local TLV */ 497 + i = get_unaligned_le16(tsfdesc); 498 + tsfdesc += 2; 499 + if (i != TLV_TYPE_TSFTIMESTAMP) 500 + goto done; 501 + /* Validity check: the TLV holds TSF values with 8 bytes each, so 502 + * the size in the TLV must match the nr_sets value */ 503 + i = get_unaligned_le16(tsfdesc); 504 + tsfdesc += 2; 505 + if (i / 8 != scanresp->nr_sets) 506 + goto done; 507 + 508 + for (i = 0; i < scanresp->nr_sets; i++) { 509 + const u8 *bssid; 510 + const u8 *ie; 511 + int left; 512 + int ielen; 513 + int rssi; 514 + u16 intvl; 515 + u16 capa; 516 + int chan_no = -1; 517 + const u8 *ssid = NULL; 518 + u8 ssid_len = 0; 519 + DECLARE_SSID_BUF(ssid_buf); 520 + 521 + int len = get_unaligned_le16(pos); 522 + pos += 2; 523 + 524 + /* BSSID */ 525 + bssid = pos; 526 + pos += ETH_ALEN; 527 + /* RSSI */ 528 + rssi = *pos++; 529 + /* Packet time stamp */ 530 + pos += 8; 531 + /* Beacon interval */ 532 + intvl = get_unaligned_le16(pos); 533 + pos += 2; 534 + /* Capabilities */ 535 + capa = get_unaligned_le16(pos); 536 + pos += 2; 537 + 538 + /* To find out the channel, we must parse the IEs */ 539 + ie = pos; 540 + /* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon 541 + interval, capabilities */ 542 + ielen = left = len - (6 + 1 + 8 + 2 + 2); 543 + while (left >= 2) { 544 + u8 id, elen; 545 + id = *pos++; 546 + elen = *pos++; 547 + left -= 2; 548 + if (elen > left || elen == 0) 549 + goto done; 550 + if (id == WLAN_EID_DS_PARAMS) 551 + chan_no = *pos; 552 + if (id == WLAN_EID_SSID) { 553 + ssid = pos; 554 + ssid_len = elen; 555 + } 556 + left -= elen; 557 + pos += elen; 558 + } 559 + 560 + /* No channel, no luck */ 561 + if (chan_no != -1) { 562 + struct wiphy *wiphy = priv->wdev->wiphy; 563 + int freq = ieee80211_channel_to_frequency(chan_no); 564 + struct ieee80211_channel *channel = 565 + ieee80211_get_channel(wiphy, freq); 566 + 567 + lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, " 568 + "%d dBm\n", 569 + bssid, capa, chan_no, 570 + print_ssid(ssid_buf, ssid, ssid_len), 571 + LBS_SCAN_RSSI_TO_MBM(rssi)/100); 572 + 573 + if (channel || 574 + !(channel->flags & IEEE80211_CHAN_DISABLED)) 575 + cfg80211_inform_bss(wiphy, channel, 576 + bssid, le64_to_cpu(*(__le64 *)tsfdesc), 577 + capa, intvl, ie, ielen, 578 + LBS_SCAN_RSSI_TO_MBM(rssi), 579 + GFP_KERNEL); 580 + } 581 + tsfdesc += 8; 582 + } 583 + ret = 0; 584 + 585 + done: 586 + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 587 + return ret; 588 + } 589 + 590 + 591 + /* 592 + * Our scan command contains a TLV, consting of a SSID TLV, a channel list 593 + * TLV and a rates TLV. Determine the maximum size of them: 594 + */ 595 + #define LBS_SCAN_MAX_CMD_SIZE \ 596 + (sizeof(struct cmd_ds_802_11_scan) \ 597 + + LBS_MAX_SSID_TLV_SIZE \ 598 + + LBS_MAX_CHANNEL_LIST_TLV_SIZE \ 599 + + LBS_MAX_RATES_TLV_SIZE) 600 + 601 + /* 602 + * Assumes priv->scan_req is initialized and valid 603 + * Assumes priv->scan_channel is initialized 604 + */ 605 + static void lbs_scan_worker(struct work_struct *work) 606 + { 607 + struct lbs_private *priv = 608 + container_of(work, struct lbs_private, scan_work.work); 609 + struct cmd_ds_802_11_scan *scan_cmd; 610 + u8 *tlv; /* pointer into our current, growing TLV storage area */ 611 + int last_channel; 612 + int running, carrier; 613 + 614 + lbs_deb_enter(LBS_DEB_SCAN); 615 + 616 + scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL); 617 + if (scan_cmd == NULL) 618 + goto out_no_scan_cmd; 619 + 620 + /* prepare fixed part of scan command */ 621 + scan_cmd->bsstype = CMD_BSS_TYPE_ANY; 622 + 623 + /* stop network while we're away from our main channel */ 624 + running = !netif_queue_stopped(priv->dev); 625 + carrier = netif_carrier_ok(priv->dev); 626 + if (running) 627 + netif_stop_queue(priv->dev); 628 + if (carrier) 629 + netif_carrier_off(priv->dev); 630 + 631 + /* prepare fixed part of scan command */ 632 + tlv = scan_cmd->tlvbuffer; 633 + 634 + /* add SSID TLV */ 635 + if (priv->scan_req->n_ssids) 636 + tlv += lbs_add_ssid_tlv(tlv, 637 + priv->scan_req->ssids[0].ssid, 638 + priv->scan_req->ssids[0].ssid_len); 639 + 640 + /* add channel TLVs */ 641 + last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP; 642 + if (last_channel > priv->scan_req->n_channels) 643 + last_channel = priv->scan_req->n_channels; 644 + tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel, 645 + priv->scan_req->n_ssids); 646 + 647 + /* add rates TLV */ 648 + tlv += lbs_add_supported_rates_tlv(tlv); 649 + 650 + if (priv->scan_channel < priv->scan_req->n_channels) { 651 + cancel_delayed_work(&priv->scan_work); 652 + queue_delayed_work(priv->work_thread, &priv->scan_work, 653 + msecs_to_jiffies(300)); 654 + } 655 + 656 + /* This is the final data we are about to send */ 657 + scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd); 658 + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 659 + sizeof(*scan_cmd)); 660 + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, 661 + tlv - scan_cmd->tlvbuffer); 662 + 663 + __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, 664 + le16_to_cpu(scan_cmd->hdr.size), 665 + lbs_ret_scan, 0); 666 + 667 + if (priv->scan_channel >= priv->scan_req->n_channels) { 668 + /* Mark scan done */ 669 + cfg80211_scan_done(priv->scan_req, false); 670 + priv->scan_req = NULL; 671 + } 672 + 673 + /* Restart network */ 674 + if (carrier) 675 + netif_carrier_on(priv->dev); 676 + if (running && !priv->tx_pending_len) 677 + netif_wake_queue(priv->dev); 678 + 679 + kfree(scan_cmd); 680 + 681 + out_no_scan_cmd: 682 + lbs_deb_leave(LBS_DEB_SCAN); 683 + } 684 + 685 + 686 + static int lbs_cfg_scan(struct wiphy *wiphy, 687 + struct net_device *dev, 688 + struct cfg80211_scan_request *request) 689 + { 690 + struct lbs_private *priv = wiphy_priv(wiphy); 691 + int ret = 0; 692 + 693 + lbs_deb_enter(LBS_DEB_CFG80211); 694 + 695 + if (priv->scan_req || delayed_work_pending(&priv->scan_work)) { 696 + /* old scan request not yet processed */ 697 + ret = -EAGAIN; 698 + goto out; 699 + } 700 + 701 + lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n", 702 + request->n_ssids, request->n_channels, request->ie_len); 703 + 704 + priv->scan_channel = 0; 705 + queue_delayed_work(priv->work_thread, &priv->scan_work, 706 + msecs_to_jiffies(50)); 707 + 708 + if (priv->surpriseremoved) 709 + ret = -EIO; 710 + 711 + priv->scan_req = request; 100 712 101 713 out: 102 714 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); ··· 723 101 724 102 725 103 104 + /*************************************************************************** 105 + * Events 106 + */ 107 + 108 + void lbs_send_disconnect_notification(struct lbs_private *priv) 109 + { 110 + lbs_deb_enter(LBS_DEB_CFG80211); 111 + 112 + cfg80211_disconnected(priv->dev, 113 + 0, 114 + NULL, 0, 115 + GFP_KERNEL); 116 + 117 + lbs_deb_leave(LBS_DEB_CFG80211); 118 + } 119 + 120 + void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) 121 + { 122 + lbs_deb_enter(LBS_DEB_CFG80211); 123 + 124 + cfg80211_michael_mic_failure(priv->dev, 125 + priv->assoc_bss, 126 + event == MACREG_INT_CODE_MIC_ERR_MULTICAST ? 127 + NL80211_KEYTYPE_GROUP : 128 + NL80211_KEYTYPE_PAIRWISE, 129 + -1, 130 + NULL, 131 + GFP_KERNEL); 132 + 133 + lbs_deb_leave(LBS_DEB_CFG80211); 134 + } 135 + 136 + 137 + 138 + 139 + /*************************************************************************** 140 + * Connect/disconnect 141 + */ 142 + 143 + 144 + /* 145 + * This removes all WEP keys 146 + */ 147 + static int lbs_remove_wep_keys(struct lbs_private *priv) 148 + { 149 + struct cmd_ds_802_11_set_wep cmd; 150 + int ret; 151 + 152 + lbs_deb_enter(LBS_DEB_CFG80211); 153 + 154 + memset(&cmd, 0, sizeof(cmd)); 155 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 156 + cmd.keyindex = cpu_to_le16(priv->wep_tx_key); 157 + cmd.action = cpu_to_le16(CMD_ACT_REMOVE); 158 + 159 + ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); 160 + 161 + lbs_deb_leave(LBS_DEB_CFG80211); 162 + return ret; 163 + } 164 + 165 + /* 166 + * Set WEP keys 167 + */ 168 + static int lbs_set_wep_keys(struct lbs_private *priv) 169 + { 170 + struct cmd_ds_802_11_set_wep cmd; 171 + int i; 172 + int ret; 173 + 174 + lbs_deb_enter(LBS_DEB_CFG80211); 175 + 176 + /* 177 + * command 13 00 178 + * size 50 00 179 + * sequence xx xx 180 + * result 00 00 181 + * action 02 00 ACT_ADD 182 + * transmit key 00 00 183 + * type for key 1 01 WEP40 184 + * type for key 2 00 185 + * type for key 3 00 186 + * type for key 4 00 187 + * key 1 39 39 39 39 39 00 00 00 188 + * 00 00 00 00 00 00 00 00 189 + * key 2 00 00 00 00 00 00 00 00 190 + * 00 00 00 00 00 00 00 00 191 + * key 3 00 00 00 00 00 00 00 00 192 + * 00 00 00 00 00 00 00 00 193 + * key 4 00 00 00 00 00 00 00 00 194 + */ 195 + if (priv->wep_key_len[0] || priv->wep_key_len[1] || 196 + priv->wep_key_len[2] || priv->wep_key_len[3]) { 197 + /* Only set wep keys if we have at least one of them */ 198 + memset(&cmd, 0, sizeof(cmd)); 199 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 200 + cmd.keyindex = cpu_to_le16(priv->wep_tx_key); 201 + cmd.action = cpu_to_le16(CMD_ACT_ADD); 202 + 203 + for (i = 0; i < 4; i++) { 204 + switch (priv->wep_key_len[i]) { 205 + case WLAN_KEY_LEN_WEP40: 206 + cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; 207 + break; 208 + case WLAN_KEY_LEN_WEP104: 209 + cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; 210 + break; 211 + default: 212 + cmd.keytype[i] = 0; 213 + break; 214 + } 215 + memcpy(cmd.keymaterial[i], priv->wep_key[i], 216 + priv->wep_key_len[i]); 217 + } 218 + 219 + ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); 220 + } else { 221 + /* Otherwise remove all wep keys */ 222 + ret = lbs_remove_wep_keys(priv); 223 + } 224 + 225 + lbs_deb_leave(LBS_DEB_CFG80211); 226 + return ret; 227 + } 228 + 229 + 230 + /* 231 + * Enable/Disable RSN status 232 + */ 233 + static int lbs_enable_rsn(struct lbs_private *priv, int enable) 234 + { 235 + struct cmd_ds_802_11_enable_rsn cmd; 236 + int ret; 237 + 238 + lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable); 239 + 240 + /* 241 + * cmd 2f 00 242 + * size 0c 00 243 + * sequence xx xx 244 + * result 00 00 245 + * action 01 00 ACT_SET 246 + * enable 01 00 247 + */ 248 + memset(&cmd, 0, sizeof(cmd)); 249 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 250 + cmd.action = cpu_to_le16(CMD_ACT_SET); 251 + cmd.enable = cpu_to_le16(enable); 252 + 253 + ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); 254 + 255 + lbs_deb_leave(LBS_DEB_CFG80211); 256 + return ret; 257 + } 258 + 259 + 260 + /* 261 + * Set WPA/WPA key material 262 + */ 263 + 264 + /* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we 265 + * get rid of WEXT, this should go into host.h */ 266 + 267 + struct cmd_key_material { 268 + struct cmd_header hdr; 269 + 270 + __le16 action; 271 + struct MrvlIEtype_keyParamSet param; 272 + } __attribute__ ((packed)); 273 + 274 + static int lbs_set_key_material(struct lbs_private *priv, 275 + int key_type, 276 + int key_info, 277 + u8 *key, u16 key_len) 278 + { 279 + struct cmd_key_material cmd; 280 + int ret; 281 + 282 + lbs_deb_enter(LBS_DEB_CFG80211); 283 + 284 + /* 285 + * Example for WPA (TKIP): 286 + * 287 + * cmd 5e 00 288 + * size 34 00 289 + * sequence xx xx 290 + * result 00 00 291 + * action 01 00 292 + * TLV type 00 01 key param 293 + * length 00 26 294 + * key type 01 00 TKIP 295 + * key info 06 00 UNICAST | ENABLED 296 + * key len 20 00 297 + * key 32 bytes 298 + */ 299 + memset(&cmd, 0, sizeof(cmd)); 300 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 301 + cmd.action = cpu_to_le16(CMD_ACT_SET); 302 + cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); 303 + cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4); 304 + cmd.param.keytypeid = cpu_to_le16(key_type); 305 + cmd.param.keyinfo = cpu_to_le16(key_info); 306 + cmd.param.keylen = cpu_to_le16(key_len); 307 + if (key && key_len) 308 + memcpy(cmd.param.key, key, key_len); 309 + 310 + ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); 311 + 312 + lbs_deb_leave(LBS_DEB_CFG80211); 313 + return ret; 314 + } 315 + 316 + 317 + /* 318 + * Sets the auth type (open, shared, etc) in the firmware. That 319 + * we use CMD_802_11_AUTHENTICATE is misleading, this firmware 320 + * command doesn't send an authentication frame at all, it just 321 + * stores the auth_type. 322 + */ 323 + static int lbs_set_authtype(struct lbs_private *priv, 324 + struct cfg80211_connect_params *sme) 325 + { 326 + struct cmd_ds_802_11_authenticate cmd; 327 + int ret; 328 + 329 + lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type); 330 + 331 + /* 332 + * cmd 11 00 333 + * size 19 00 334 + * sequence xx xx 335 + * result 00 00 336 + * BSS id 00 13 19 80 da 30 337 + * auth type 00 338 + * reserved 00 00 00 00 00 00 00 00 00 00 339 + */ 340 + memset(&cmd, 0, sizeof(cmd)); 341 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 342 + if (sme->bssid) 343 + memcpy(cmd.bssid, sme->bssid, ETH_ALEN); 344 + /* convert auth_type */ 345 + ret = lbs_auth_to_authtype(sme->auth_type); 346 + if (ret < 0) 347 + goto done; 348 + 349 + cmd.authtype = ret; 350 + ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); 351 + 352 + done: 353 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 354 + return ret; 355 + } 356 + 357 + 358 + /* 359 + * Create association request 360 + */ 361 + #define LBS_ASSOC_MAX_CMD_SIZE \ 362 + (sizeof(struct cmd_ds_802_11_associate) \ 363 + - 512 /* cmd_ds_802_11_associate.iebuf */ \ 364 + + LBS_MAX_SSID_TLV_SIZE \ 365 + + LBS_MAX_CHANNEL_TLV_SIZE \ 366 + + LBS_MAX_CF_PARAM_TLV_SIZE \ 367 + + LBS_MAX_AUTH_TYPE_TLV_SIZE \ 368 + + LBS_MAX_WPA_TLV_SIZE) 369 + 370 + static int lbs_associate(struct lbs_private *priv, 371 + struct cfg80211_bss *bss, 372 + struct cfg80211_connect_params *sme) 373 + { 374 + struct cmd_ds_802_11_associate_response *resp; 375 + struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE, 376 + GFP_KERNEL); 377 + const u8 *ssid_eid; 378 + size_t len, resp_ie_len; 379 + int status; 380 + int ret; 381 + u8 *pos = &(cmd->iebuf[0]); 382 + 383 + lbs_deb_enter(LBS_DEB_CFG80211); 384 + 385 + if (!cmd) { 386 + ret = -ENOMEM; 387 + goto done; 388 + } 389 + 390 + /* 391 + * cmd 50 00 392 + * length 34 00 393 + * sequence xx xx 394 + * result 00 00 395 + * BSS id 00 13 19 80 da 30 396 + * capabilities 11 00 397 + * listen interval 0a 00 398 + * beacon interval 00 00 399 + * DTIM period 00 400 + * TLVs xx (up to 512 bytes) 401 + */ 402 + cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE); 403 + 404 + /* Fill in static fields */ 405 + memcpy(cmd->bssid, bss->bssid, ETH_ALEN); 406 + cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); 407 + cmd->capability = cpu_to_le16(bss->capability); 408 + 409 + /* add SSID TLV */ 410 + ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); 411 + if (ssid_eid) 412 + pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]); 413 + else 414 + lbs_deb_assoc("no SSID\n"); 415 + 416 + /* add DS param TLV */ 417 + if (bss->channel) 418 + pos += lbs_add_channel_tlv(pos, bss->channel->hw_value); 419 + else 420 + lbs_deb_assoc("no channel\n"); 421 + 422 + /* add (empty) CF param TLV */ 423 + pos += lbs_add_cf_param_tlv(pos); 424 + 425 + /* add rates TLV */ 426 + pos += lbs_add_common_rates_tlv(pos, bss); 427 + 428 + /* add auth type TLV */ 429 + if (priv->fwrelease >= 0x09000000) 430 + pos += lbs_add_auth_type_tlv(pos, sme->auth_type); 431 + 432 + /* add WPA/WPA2 TLV */ 433 + if (sme->ie && sme->ie_len) 434 + pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len); 435 + 436 + len = (sizeof(*cmd) - sizeof(cmd->iebuf)) + 437 + (u16)(pos - (u8 *) &cmd->iebuf); 438 + cmd->hdr.size = cpu_to_le16(len); 439 + 440 + /* store for later use */ 441 + memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); 442 + 443 + ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd); 444 + if (ret) 445 + goto done; 446 + 447 + 448 + /* generate connect message to cfg80211 */ 449 + 450 + resp = (void *) cmd; /* recast for easier field access */ 451 + status = le16_to_cpu(resp->statuscode); 452 + 453 + /* Convert statis code of old firmware */ 454 + if (priv->fwrelease < 0x09000000) 455 + switch (status) { 456 + case 0: 457 + break; 458 + case 1: 459 + lbs_deb_assoc("invalid association parameters\n"); 460 + status = WLAN_STATUS_CAPS_UNSUPPORTED; 461 + break; 462 + case 2: 463 + lbs_deb_assoc("timer expired while waiting for AP\n"); 464 + status = WLAN_STATUS_AUTH_TIMEOUT; 465 + break; 466 + case 3: 467 + lbs_deb_assoc("association refused by AP\n"); 468 + status = WLAN_STATUS_ASSOC_DENIED_UNSPEC; 469 + break; 470 + case 4: 471 + lbs_deb_assoc("authentication refused by AP\n"); 472 + status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 473 + break; 474 + default: 475 + lbs_deb_assoc("association failure %d\n", status); 476 + status = WLAN_STATUS_UNSPECIFIED_FAILURE; 477 + } 478 + 479 + lbs_deb_assoc("status %d, capability 0x%04x\n", status, 480 + le16_to_cpu(resp->capability)); 481 + 482 + resp_ie_len = le16_to_cpu(resp->hdr.size) 483 + - sizeof(resp->hdr) 484 + - 6; 485 + cfg80211_connect_result(priv->dev, 486 + priv->assoc_bss, 487 + sme->ie, sme->ie_len, 488 + resp->iebuf, resp_ie_len, 489 + status, 490 + GFP_KERNEL); 491 + 492 + if (status == 0) { 493 + /* TODO: get rid of priv->connect_status */ 494 + priv->connect_status = LBS_CONNECTED; 495 + netif_carrier_on(priv->dev); 496 + if (!priv->tx_pending_len) 497 + netif_tx_wake_all_queues(priv->dev); 498 + } 499 + 500 + 501 + done: 502 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 503 + return ret; 504 + } 505 + 506 + 507 + 508 + static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, 509 + struct cfg80211_connect_params *sme) 510 + { 511 + struct lbs_private *priv = wiphy_priv(wiphy); 512 + struct cfg80211_bss *bss = NULL; 513 + int ret = 0; 514 + u8 preamble = RADIO_PREAMBLE_SHORT; 515 + 516 + lbs_deb_enter(LBS_DEB_CFG80211); 517 + 518 + if (sme->bssid) { 519 + bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 520 + sme->ssid, sme->ssid_len, 521 + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 522 + } else { 523 + /* 524 + * Here we have an impedance mismatch. The firmware command 525 + * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot 526 + * connect otherwise. However, for the connect-API of 527 + * cfg80211 the bssid is purely optional. We don't get one, 528 + * except the user specifies one on the "iw" command line. 529 + * 530 + * If we don't got one, we could initiate a scan and look 531 + * for the best matching cfg80211_bss entry. 532 + * 533 + * Or, better yet, net/wireless/sme.c get's rewritten into 534 + * something more generally useful. 535 + */ 536 + lbs_pr_err("TODO: no BSS specified\n"); 537 + ret = -ENOTSUPP; 538 + goto done; 539 + } 540 + 541 + 542 + if (!bss) { 543 + lbs_pr_err("assicate: bss %pM not in scan results\n", 544 + sme->bssid); 545 + ret = -ENOENT; 546 + goto done; 547 + } 548 + lbs_deb_assoc("trying %pM", sme->bssid); 549 + lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n", 550 + sme->crypto.cipher_group, 551 + sme->key_idx, sme->key_len); 552 + 553 + /* As this is a new connection, clear locally stored WEP keys */ 554 + priv->wep_tx_key = 0; 555 + memset(priv->wep_key, 0, sizeof(priv->wep_key)); 556 + memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); 557 + 558 + /* set/remove WEP keys */ 559 + switch (sme->crypto.cipher_group) { 560 + case WLAN_CIPHER_SUITE_WEP40: 561 + case WLAN_CIPHER_SUITE_WEP104: 562 + /* Store provided WEP keys in priv-> */ 563 + priv->wep_tx_key = sme->key_idx; 564 + priv->wep_key_len[sme->key_idx] = sme->key_len; 565 + memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len); 566 + /* Set WEP keys and WEP mode */ 567 + lbs_set_wep_keys(priv); 568 + priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; 569 + lbs_set_mac_control(priv); 570 + /* No RSN mode for WEP */ 571 + lbs_enable_rsn(priv, 0); 572 + break; 573 + case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */ 574 + /* 575 + * If we don't have no WEP, no WPA and no WPA2, 576 + * we remove all keys like in the WPA/WPA2 setup, 577 + * we just don't set RSN. 578 + * 579 + * Therefore: fall-throught 580 + */ 581 + case WLAN_CIPHER_SUITE_TKIP: 582 + case WLAN_CIPHER_SUITE_CCMP: 583 + /* Remove WEP keys and WEP mode */ 584 + lbs_remove_wep_keys(priv); 585 + priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; 586 + lbs_set_mac_control(priv); 587 + 588 + /* clear the WPA/WPA2 keys */ 589 + lbs_set_key_material(priv, 590 + KEY_TYPE_ID_WEP, /* doesn't matter */ 591 + KEY_INFO_WPA_UNICAST, 592 + NULL, 0); 593 + lbs_set_key_material(priv, 594 + KEY_TYPE_ID_WEP, /* doesn't matter */ 595 + KEY_INFO_WPA_MCAST, 596 + NULL, 0); 597 + /* RSN mode for WPA/WPA2 */ 598 + lbs_enable_rsn(priv, sme->crypto.cipher_group != 0); 599 + break; 600 + default: 601 + lbs_pr_err("unsupported cipher group 0x%x\n", 602 + sme->crypto.cipher_group); 603 + ret = -ENOTSUPP; 604 + goto done; 605 + } 606 + 607 + lbs_set_authtype(priv, sme); 608 + lbs_set_radio(priv, preamble, 1); 609 + 610 + /* Do the actual association */ 611 + lbs_associate(priv, bss, sme); 612 + 613 + done: 614 + if (bss) 615 + cfg80211_put_bss(bss); 616 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 617 + return ret; 618 + } 619 + 620 + static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev, 621 + u16 reason_code) 622 + { 623 + struct lbs_private *priv = wiphy_priv(wiphy); 624 + struct cmd_ds_802_11_deauthenticate cmd; 625 + 626 + lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code); 627 + 628 + /* store for lbs_cfg_ret_disconnect() */ 629 + priv->disassoc_reason = reason_code; 630 + 631 + memset(&cmd, 0, sizeof(cmd)); 632 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 633 + /* Mildly ugly to use a locally store my own BSSID ... */ 634 + memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN); 635 + cmd.reasoncode = cpu_to_le16(reason_code); 636 + 637 + if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd)) 638 + return -EFAULT; 639 + 640 + cfg80211_disconnected(priv->dev, 641 + priv->disassoc_reason, 642 + NULL, 0, 643 + GFP_KERNEL); 644 + priv->connect_status = LBS_DISCONNECTED; 645 + 646 + return 0; 647 + } 648 + 649 + 650 + static int lbs_cfg_set_default_key(struct wiphy *wiphy, 651 + struct net_device *netdev, 652 + u8 key_index) 653 + { 654 + struct lbs_private *priv = wiphy_priv(wiphy); 655 + 656 + lbs_deb_enter(LBS_DEB_CFG80211); 657 + 658 + if (key_index != priv->wep_tx_key) { 659 + lbs_deb_assoc("set_default_key: to %d\n", key_index); 660 + priv->wep_tx_key = key_index; 661 + lbs_set_wep_keys(priv); 662 + } 663 + 664 + return 0; 665 + } 666 + 667 + 668 + static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, 669 + u8 idx, const u8 *mac_addr, 670 + struct key_params *params) 671 + { 672 + struct lbs_private *priv = wiphy_priv(wiphy); 673 + u16 key_info; 674 + u16 key_type; 675 + int ret = 0; 676 + 677 + lbs_deb_enter(LBS_DEB_CFG80211); 678 + 679 + lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n", 680 + params->cipher, mac_addr); 681 + lbs_deb_assoc("add_key: key index %d, key len %d\n", 682 + idx, params->key_len); 683 + if (params->key_len) 684 + lbs_deb_hex(LBS_DEB_CFG80211, "KEY", 685 + params->key, params->key_len); 686 + 687 + lbs_deb_assoc("add_key: seq len %d\n", params->seq_len); 688 + if (params->seq_len) 689 + lbs_deb_hex(LBS_DEB_CFG80211, "SEQ", 690 + params->seq, params->seq_len); 691 + 692 + switch (params->cipher) { 693 + case WLAN_CIPHER_SUITE_WEP40: 694 + case WLAN_CIPHER_SUITE_WEP104: 695 + /* actually compare if something has changed ... */ 696 + if ((priv->wep_key_len[idx] != params->key_len) || 697 + memcmp(priv->wep_key[idx], 698 + params->key, params->key_len) != 0) { 699 + priv->wep_key_len[idx] = params->key_len; 700 + memcpy(priv->wep_key[idx], 701 + params->key, params->key_len); 702 + lbs_set_wep_keys(priv); 703 + } 704 + break; 705 + case WLAN_CIPHER_SUITE_TKIP: 706 + case WLAN_CIPHER_SUITE_CCMP: 707 + key_info = KEY_INFO_WPA_ENABLED | ((idx == 0) 708 + ? KEY_INFO_WPA_UNICAST 709 + : KEY_INFO_WPA_MCAST); 710 + key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP) 711 + ? KEY_TYPE_ID_TKIP 712 + : KEY_TYPE_ID_AES; 713 + lbs_set_key_material(priv, 714 + key_type, 715 + key_info, 716 + params->key, params->key_len); 717 + break; 718 + default: 719 + lbs_pr_err("unhandled cipher 0x%x\n", params->cipher); 720 + ret = -ENOTSUPP; 721 + break; 722 + } 723 + 724 + return ret; 725 + } 726 + 727 + 728 + static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, 729 + u8 key_index, const u8 *mac_addr) 730 + { 731 + 732 + lbs_deb_enter(LBS_DEB_CFG80211); 733 + 734 + lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n", 735 + key_index, mac_addr); 736 + 737 + #ifdef TODO 738 + struct lbs_private *priv = wiphy_priv(wiphy); 739 + /* 740 + * I think can keep this a NO-OP, because: 741 + 742 + * - we clear all keys whenever we do lbs_cfg_connect() anyway 743 + * - neither "iw" nor "wpa_supplicant" won't call this during 744 + * an ongoing connection 745 + * - TODO: but I have to check if this is still true when 746 + * I set the AP to periodic re-keying 747 + * - we've not kzallec() something when we've added a key at 748 + * lbs_cfg_connect() or lbs_cfg_add_key(). 749 + * 750 + * This causes lbs_cfg_del_key() only called at disconnect time, 751 + * where we'd just waste time deleting a key that is not going 752 + * to be used anyway. 753 + */ 754 + if (key_index < 3 && priv->wep_key_len[key_index]) { 755 + priv->wep_key_len[key_index] = 0; 756 + lbs_set_wep_keys(priv); 757 + } 758 + #endif 759 + 760 + return 0; 761 + } 762 + 763 + 764 + 765 + /*************************************************************************** 766 + * Monitor mode 767 + */ 768 + 769 + /* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we 770 + * get rid of WEXT, this should go into host.h */ 771 + struct cmd_monitor_mode { 772 + struct cmd_header hdr; 773 + 774 + __le16 action; 775 + __le16 mode; 776 + } __attribute__ ((packed)); 777 + 778 + static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode) 779 + { 780 + struct cmd_monitor_mode cmd; 781 + int ret; 782 + 783 + lbs_deb_enter(LBS_DEB_CFG80211); 784 + 785 + /* 786 + * cmd 98 00 787 + * size 0c 00 788 + * sequence xx xx 789 + * result 00 00 790 + * action 01 00 ACT_SET 791 + * enable 01 00 792 + */ 793 + memset(&cmd, 0, sizeof(cmd)); 794 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 795 + cmd.action = cpu_to_le16(CMD_ACT_SET); 796 + cmd.mode = cpu_to_le16(mode); 797 + 798 + ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); 799 + 800 + if (ret == 0) 801 + priv->dev->type = ARPHRD_IEEE80211_RADIOTAP; 802 + else 803 + priv->dev->type = ARPHRD_ETHER; 804 + 805 + lbs_deb_leave(LBS_DEB_CFG80211); 806 + return ret; 807 + } 808 + 809 + 810 + 811 + 812 + 813 + 814 + /*************************************************************************** 815 + * Get station 816 + */ 817 + 818 + /* 819 + * Returns the signal or 0 in case of an error. 820 + */ 821 + 822 + /* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid 823 + * of WEXT, this should go into host.h */ 824 + struct cmd_rssi { 825 + struct cmd_header hdr; 826 + 827 + __le16 n_or_snr; 828 + __le16 nf; 829 + __le16 avg_snr; 830 + __le16 avg_nf; 831 + } __attribute__ ((packed)); 832 + 833 + static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise) 834 + { 835 + struct cmd_rssi cmd; 836 + int ret; 837 + 838 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 839 + cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); 840 + ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); 841 + 842 + if (ret == 0) { 843 + *signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), 844 + le16_to_cpu(cmd.nf)); 845 + *noise = CAL_NF(le16_to_cpu(cmd.nf)); 846 + } 847 + return ret; 848 + } 849 + 850 + 851 + static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, 852 + u8 *mac, struct station_info *sinfo) 853 + { 854 + struct lbs_private *priv = wiphy_priv(wiphy); 855 + s8 signal, noise; 856 + int ret; 857 + size_t i; 858 + 859 + lbs_deb_enter(LBS_DEB_CFG80211); 860 + 861 + sinfo->filled |= STATION_INFO_TX_BYTES | 862 + STATION_INFO_TX_PACKETS | 863 + STATION_INFO_RX_BYTES | 864 + STATION_INFO_RX_PACKETS; 865 + sinfo->tx_bytes = priv->dev->stats.tx_bytes; 866 + sinfo->tx_packets = priv->dev->stats.tx_packets; 867 + sinfo->rx_bytes = priv->dev->stats.rx_bytes; 868 + sinfo->rx_packets = priv->dev->stats.rx_packets; 869 + 870 + /* Get current RSSI */ 871 + ret = lbs_get_signal(priv, &signal, &noise); 872 + if (ret == 0) { 873 + sinfo->signal = signal; 874 + sinfo->filled |= STATION_INFO_SIGNAL; 875 + } 876 + 877 + /* Convert priv->cur_rate from hw_value to NL80211 value */ 878 + for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { 879 + if (priv->cur_rate == lbs_rates[i].hw_value) { 880 + sinfo->txrate.legacy = lbs_rates[i].bitrate; 881 + sinfo->filled |= STATION_INFO_TX_BITRATE; 882 + break; 883 + } 884 + } 885 + 886 + return 0; 887 + } 888 + 889 + 890 + 891 + 892 + /*************************************************************************** 893 + * "Site survey", here just current channel and noise level 894 + */ 895 + 896 + static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, 897 + int idx, struct survey_info *survey) 898 + { 899 + struct lbs_private *priv = wiphy_priv(wiphy); 900 + s8 signal, noise; 901 + int ret; 902 + 903 + if (idx != 0) 904 + ret = -ENOENT; 905 + 906 + lbs_deb_enter(LBS_DEB_CFG80211); 907 + 908 + survey->channel = ieee80211_get_channel(wiphy, 909 + ieee80211_channel_to_frequency(priv->channel)); 910 + 911 + ret = lbs_get_signal(priv, &signal, &noise); 912 + if (ret == 0) { 913 + survey->filled = SURVEY_INFO_NOISE_DBM; 914 + survey->noise = noise; 915 + } 916 + 917 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 918 + return ret; 919 + } 920 + 921 + 922 + 923 + 924 + /*************************************************************************** 925 + * Change interface 926 + */ 927 + 928 + static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, 929 + enum nl80211_iftype type, u32 *flags, 930 + struct vif_params *params) 931 + { 932 + struct lbs_private *priv = wiphy_priv(wiphy); 933 + int ret = 0; 934 + 935 + lbs_deb_enter(LBS_DEB_CFG80211); 936 + 937 + switch (type) { 938 + case NL80211_IFTYPE_MONITOR: 939 + ret = lbs_enable_monitor_mode(priv, 1); 940 + break; 941 + case NL80211_IFTYPE_STATION: 942 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) 943 + ret = lbs_enable_monitor_mode(priv, 0); 944 + if (!ret) 945 + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); 946 + break; 947 + case NL80211_IFTYPE_ADHOC: 948 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) 949 + ret = lbs_enable_monitor_mode(priv, 0); 950 + if (!ret) 951 + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); 952 + break; 953 + default: 954 + ret = -ENOTSUPP; 955 + } 956 + 957 + if (!ret) 958 + priv->wdev->iftype = type; 959 + 960 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 961 + return ret; 962 + } 963 + 964 + 965 + 966 + /*************************************************************************** 967 + * IBSS (Ad-Hoc) 968 + */ 969 + 970 + /* The firmware needs the following bits masked out of the beacon-derived 971 + * capability field when associating/joining to a BSS: 972 + * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) 973 + */ 974 + #define CAPINFO_MASK (~(0xda00)) 975 + 976 + 977 + static void lbs_join_post(struct lbs_private *priv, 978 + struct cfg80211_ibss_params *params, 979 + u8 *bssid, u16 capability) 980 + { 981 + u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */ 982 + 2 + 4 + /* basic rates */ 983 + 2 + 1 + /* DS parameter */ 984 + 2 + 2 + /* atim */ 985 + 2 + 8]; /* extended rates */ 986 + u8 *fake = fake_ie; 987 + 988 + lbs_deb_enter(LBS_DEB_CFG80211); 989 + 990 + /* 991 + * For cfg80211_inform_bss, we'll need a fake IE, as we can't get 992 + * the real IE from the firmware. So we fabricate a fake IE based on 993 + * what the firmware actually sends (sniffed with wireshark). 994 + */ 995 + /* Fake SSID IE */ 996 + *fake++ = WLAN_EID_SSID; 997 + *fake++ = params->ssid_len; 998 + memcpy(fake, params->ssid, params->ssid_len); 999 + fake += params->ssid_len; 1000 + /* Fake supported basic rates IE */ 1001 + *fake++ = WLAN_EID_SUPP_RATES; 1002 + *fake++ = 4; 1003 + *fake++ = 0x82; 1004 + *fake++ = 0x84; 1005 + *fake++ = 0x8b; 1006 + *fake++ = 0x96; 1007 + /* Fake DS channel IE */ 1008 + *fake++ = WLAN_EID_DS_PARAMS; 1009 + *fake++ = 1; 1010 + *fake++ = params->channel->hw_value; 1011 + /* Fake IBSS params IE */ 1012 + *fake++ = WLAN_EID_IBSS_PARAMS; 1013 + *fake++ = 2; 1014 + *fake++ = 0; /* ATIM=0 */ 1015 + *fake++ = 0; 1016 + /* Fake extended rates IE, TODO: don't add this for 802.11b only, 1017 + * but I don't know how this could be checked */ 1018 + *fake++ = WLAN_EID_EXT_SUPP_RATES; 1019 + *fake++ = 8; 1020 + *fake++ = 0x0c; 1021 + *fake++ = 0x12; 1022 + *fake++ = 0x18; 1023 + *fake++ = 0x24; 1024 + *fake++ = 0x30; 1025 + *fake++ = 0x48; 1026 + *fake++ = 0x60; 1027 + *fake++ = 0x6c; 1028 + lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); 1029 + 1030 + cfg80211_inform_bss(priv->wdev->wiphy, 1031 + params->channel, 1032 + bssid, 1033 + 0, 1034 + capability, 1035 + params->beacon_interval, 1036 + fake_ie, fake - fake_ie, 1037 + 0, GFP_KERNEL); 1038 + 1039 + memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); 1040 + priv->wdev->ssid_len = params->ssid_len; 1041 + 1042 + cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); 1043 + 1044 + /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ 1045 + priv->connect_status = LBS_CONNECTED; 1046 + netif_carrier_on(priv->dev); 1047 + if (!priv->tx_pending_len) 1048 + netif_wake_queue(priv->dev); 1049 + 1050 + lbs_deb_leave(LBS_DEB_CFG80211); 1051 + } 1052 + 1053 + static int lbs_ibss_join_existing(struct lbs_private *priv, 1054 + struct cfg80211_ibss_params *params, 1055 + struct cfg80211_bss *bss) 1056 + { 1057 + const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); 1058 + struct cmd_ds_802_11_ad_hoc_join cmd; 1059 + u8 preamble = RADIO_PREAMBLE_SHORT; 1060 + int ret = 0; 1061 + 1062 + lbs_deb_enter(LBS_DEB_CFG80211); 1063 + 1064 + /* TODO: set preamble based on scan result */ 1065 + ret = lbs_set_radio(priv, preamble, 1); 1066 + if (ret) 1067 + goto out; 1068 + 1069 + /* 1070 + * Example CMD_802_11_AD_HOC_JOIN command: 1071 + * 1072 + * command 2c 00 CMD_802_11_AD_HOC_JOIN 1073 + * size 65 00 1074 + * sequence xx xx 1075 + * result 00 00 1076 + * bssid 02 27 27 97 2f 96 1077 + * ssid 49 42 53 53 00 00 00 00 1078 + * 00 00 00 00 00 00 00 00 1079 + * 00 00 00 00 00 00 00 00 1080 + * 00 00 00 00 00 00 00 00 1081 + * type 02 CMD_BSS_TYPE_IBSS 1082 + * beacon period 64 00 1083 + * dtim period 00 1084 + * timestamp 00 00 00 00 00 00 00 00 1085 + * localtime 00 00 00 00 00 00 00 00 1086 + * IE DS 03 1087 + * IE DS len 01 1088 + * IE DS channel 01 1089 + * reserveed 00 00 00 00 1090 + * IE IBSS 06 1091 + * IE IBSS len 02 1092 + * IE IBSS atim 00 00 1093 + * reserved 00 00 00 00 1094 + * capability 02 00 1095 + * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 00 1096 + * fail timeout ff 00 1097 + * probe delay 00 00 1098 + */ 1099 + memset(&cmd, 0, sizeof(cmd)); 1100 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1101 + 1102 + memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN); 1103 + memcpy(cmd.bss.ssid, params->ssid, params->ssid_len); 1104 + cmd.bss.type = CMD_BSS_TYPE_IBSS; 1105 + cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); 1106 + cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; 1107 + cmd.bss.ds.header.len = 1; 1108 + cmd.bss.ds.channel = params->channel->hw_value; 1109 + cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1110 + cmd.bss.ibss.header.len = 2; 1111 + cmd.bss.ibss.atimwindow = 0; 1112 + cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); 1113 + 1114 + /* set rates to the intersection of our rates and the rates in the 1115 + bss */ 1116 + if (!rates_eid) { 1117 + lbs_add_rates(cmd.bss.rates); 1118 + } else { 1119 + int hw, i; 1120 + u8 rates_max = rates_eid[1]; 1121 + u8 *rates = cmd.bss.rates; 1122 + for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { 1123 + u8 hw_rate = lbs_rates[hw].bitrate / 5; 1124 + for (i = 0; i < rates_max; i++) { 1125 + if (hw_rate == (rates_eid[i+2] & 0x7f)) { 1126 + u8 rate = rates_eid[i+2]; 1127 + if (rate == 0x02 || rate == 0x04 || 1128 + rate == 0x0b || rate == 0x16) 1129 + rate |= 0x80; 1130 + *rates++ = rate; 1131 + } 1132 + } 1133 + } 1134 + } 1135 + 1136 + /* Only v8 and below support setting this */ 1137 + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { 1138 + cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); 1139 + cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1140 + } 1141 + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); 1142 + if (ret) 1143 + goto out; 1144 + 1145 + /* 1146 + * This is a sample response to CMD_802_11_AD_HOC_JOIN: 1147 + * 1148 + * response 2c 80 1149 + * size 09 00 1150 + * sequence xx xx 1151 + * result 00 00 1152 + * reserved 00 1153 + */ 1154 + lbs_join_post(priv, params, bss->bssid, bss->capability); 1155 + 1156 + out: 1157 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1158 + return ret; 1159 + } 1160 + 1161 + 1162 + 1163 + static int lbs_ibss_start_new(struct lbs_private *priv, 1164 + struct cfg80211_ibss_params *params) 1165 + { 1166 + struct cmd_ds_802_11_ad_hoc_start cmd; 1167 + struct cmd_ds_802_11_ad_hoc_result *resp = 1168 + (struct cmd_ds_802_11_ad_hoc_result *) &cmd; 1169 + u8 preamble = RADIO_PREAMBLE_SHORT; 1170 + int ret = 0; 1171 + u16 capability; 1172 + 1173 + lbs_deb_enter(LBS_DEB_CFG80211); 1174 + 1175 + ret = lbs_set_radio(priv, preamble, 1); 1176 + if (ret) 1177 + goto out; 1178 + 1179 + /* 1180 + * Example CMD_802_11_AD_HOC_START command: 1181 + * 1182 + * command 2b 00 CMD_802_11_AD_HOC_START 1183 + * size b1 00 1184 + * sequence xx xx 1185 + * result 00 00 1186 + * ssid 54 45 53 54 00 00 00 00 1187 + * 00 00 00 00 00 00 00 00 1188 + * 00 00 00 00 00 00 00 00 1189 + * 00 00 00 00 00 00 00 00 1190 + * bss type 02 1191 + * beacon period 64 00 1192 + * dtim period 00 1193 + * IE IBSS 06 1194 + * IE IBSS len 02 1195 + * IE IBSS atim 00 00 1196 + * reserved 00 00 00 00 1197 + * IE DS 03 1198 + * IE DS len 01 1199 + * IE DS channel 01 1200 + * reserved 00 00 00 00 1201 + * probe delay 00 00 1202 + * capability 02 00 1203 + * rates 82 84 8b 96 (basic rates with have bit 7 set) 1204 + * 0c 12 18 24 30 48 60 6c 1205 + * padding 100 bytes 1206 + */ 1207 + memset(&cmd, 0, sizeof(cmd)); 1208 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1209 + memcpy(cmd.ssid, params->ssid, params->ssid_len); 1210 + cmd.bsstype = CMD_BSS_TYPE_IBSS; 1211 + cmd.beaconperiod = cpu_to_le16(params->beacon_interval); 1212 + cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1213 + cmd.ibss.header.len = 2; 1214 + cmd.ibss.atimwindow = 0; 1215 + cmd.ds.header.id = WLAN_EID_DS_PARAMS; 1216 + cmd.ds.header.len = 1; 1217 + cmd.ds.channel = params->channel->hw_value; 1218 + /* Only v8 and below support setting probe delay */ 1219 + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) 1220 + cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1221 + /* TODO: mix in WLAN_CAPABILITY_PRIVACY */ 1222 + capability = WLAN_CAPABILITY_IBSS; 1223 + cmd.capability = cpu_to_le16(capability); 1224 + lbs_add_rates(cmd.rates); 1225 + 1226 + 1227 + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); 1228 + if (ret) 1229 + goto out; 1230 + 1231 + /* 1232 + * This is a sample response to CMD_802_11_AD_HOC_JOIN: 1233 + * 1234 + * response 2b 80 1235 + * size 14 00 1236 + * sequence xx xx 1237 + * result 00 00 1238 + * reserved 00 1239 + * bssid 02 2b 7b 0f 86 0e 1240 + */ 1241 + lbs_join_post(priv, params, resp->bssid, capability); 1242 + 1243 + out: 1244 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1245 + return ret; 1246 + } 1247 + 1248 + 1249 + static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1250 + struct cfg80211_ibss_params *params) 1251 + { 1252 + struct lbs_private *priv = wiphy_priv(wiphy); 1253 + int ret = 0; 1254 + struct cfg80211_bss *bss; 1255 + DECLARE_SSID_BUF(ssid_buf); 1256 + 1257 + lbs_deb_enter(LBS_DEB_CFG80211); 1258 + 1259 + if (!params->channel) { 1260 + ret = -ENOTSUPP; 1261 + goto out; 1262 + } 1263 + 1264 + ret = lbs_set_channel(priv, params->channel->hw_value); 1265 + if (ret) 1266 + goto out; 1267 + 1268 + /* Search if someone is beaconing. This assumes that the 1269 + * bss list is populated already */ 1270 + bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, 1271 + params->ssid, params->ssid_len, 1272 + WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 1273 + 1274 + if (bss) { 1275 + ret = lbs_ibss_join_existing(priv, params, bss); 1276 + cfg80211_put_bss(bss); 1277 + } else 1278 + ret = lbs_ibss_start_new(priv, params); 1279 + 1280 + 1281 + out: 1282 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1283 + return ret; 1284 + } 1285 + 1286 + 1287 + static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) 1288 + { 1289 + struct lbs_private *priv = wiphy_priv(wiphy); 1290 + struct cmd_ds_802_11_ad_hoc_stop cmd; 1291 + int ret = 0; 1292 + 1293 + lbs_deb_enter(LBS_DEB_CFG80211); 1294 + 1295 + memset(&cmd, 0, sizeof(cmd)); 1296 + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1297 + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd); 1298 + 1299 + /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */ 1300 + lbs_mac_event_disconnected(priv); 1301 + 1302 + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1303 + return ret; 1304 + } 1305 + 1306 + 1307 + 1308 + 1309 + /*************************************************************************** 1310 + * Initialization 1311 + */ 1312 + 726 1313 static struct cfg80211_ops lbs_cfg80211_ops = { 727 1314 .set_channel = lbs_cfg_set_channel, 1315 + .scan = lbs_cfg_scan, 1316 + .connect = lbs_cfg_connect, 1317 + .disconnect = lbs_cfg_disconnect, 1318 + .add_key = lbs_cfg_add_key, 1319 + .del_key = lbs_cfg_del_key, 1320 + .set_default_key = lbs_cfg_set_default_key, 1321 + .get_station = lbs_cfg_get_station, 1322 + .dump_survey = lbs_get_survey, 1323 + .change_virtual_intf = lbs_change_intf, 1324 + .join_ibss = lbs_join_ibss, 1325 + .leave_ibss = lbs_leave_ibss, 728 1326 }; 729 1327 730 1328 ··· 1984 142 } 1985 143 1986 144 145 + static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv) 146 + { 147 + struct region_code_mapping { 148 + const char *cn; 149 + int code; 150 + }; 151 + 152 + /* Section 5.17.2 */ 153 + static struct region_code_mapping regmap[] = { 154 + {"US ", 0x10}, /* US FCC */ 155 + {"CA ", 0x20}, /* Canada */ 156 + {"EU ", 0x30}, /* ETSI */ 157 + {"ES ", 0x31}, /* Spain */ 158 + {"FR ", 0x32}, /* France */ 159 + {"JP ", 0x40}, /* Japan */ 160 + }; 161 + size_t i; 162 + 163 + lbs_deb_enter(LBS_DEB_CFG80211); 164 + 165 + for (i = 0; i < ARRAY_SIZE(regmap); i++) 166 + if (regmap[i].code == priv->regioncode) { 167 + regulatory_hint(priv->wdev->wiphy, regmap[i].cn); 168 + break; 169 + } 170 + 171 + lbs_deb_leave(LBS_DEB_CFG80211); 172 + } 173 + 174 + 1987 175 /* 1988 176 * This function get's called after lbs_setup_firmware() determined the 1989 177 * firmware capabities. So we can setup the wiphy according to our ··· 2029 157 wdev->wiphy->max_scan_ssids = 1; 2030 158 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 2031 159 2032 - /* TODO: BIT(NL80211_IFTYPE_ADHOC); */ 2033 - wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 160 + wdev->wiphy->interface_modes = 161 + BIT(NL80211_IFTYPE_STATION) | 162 + BIT(NL80211_IFTYPE_ADHOC); 163 + if (lbs_rtap_supported(priv)) 164 + wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 2034 165 2035 - /* TODO: honor priv->regioncode */ 2036 166 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz; 2037 167 2038 168 /* ··· 2043 169 */ 2044 170 wdev->wiphy->cipher_suites = cipher_suites; 2045 171 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 172 + wdev->wiphy->reg_notifier = lbs_reg_notifier; 2046 173 2047 174 ret = wiphy_register(wdev->wiphy); 2048 175 if (ret < 0) ··· 2055 180 if (ret) 2056 181 lbs_pr_err("cannot register network device\n"); 2057 182 183 + INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 184 + 185 + lbs_cfg_set_regulatory_hint(priv); 186 + 2058 187 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 2059 188 return ret; 189 + } 190 + 191 + /** 192 + * @brief This function sets DOMAIN INFO to FW 193 + * @param priv pointer to struct lbs_private 194 + * @return 0; -1 195 + */ 196 + static int lbs_11d_set_domain_info(struct lbs_private *priv) 197 + { 198 + int ret; 199 + 200 + ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, 201 + CMD_ACT_SET, 202 + CMD_OPTION_WAITFORRSP, 0, NULL); 203 + if (ret) 204 + lbs_deb_11d("fail to dnld domain info\n"); 205 + 206 + return ret; 207 + } 208 + 209 + static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy, 210 + struct regulatory_request *request) 211 + { 212 + u8 no_of_triplet = 0; 213 + u8 no_of_parsed_chan = 0; 214 + u8 first_channel = 0, next_chan = 0, max_pwr = 0; 215 + u8 i, flag = 0; 216 + enum ieee80211_band band; 217 + struct ieee80211_supported_band *sband; 218 + struct ieee80211_channel *ch; 219 + struct lbs_private *priv = wiphy_priv(wiphy); 220 + struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg; 221 + int ret = 0; 222 + 223 + lbs_deb_enter(LBS_DEB_CFG80211); 224 + 225 + /* Set country code */ 226 + domain_info->country_code[0] = request->alpha2[0]; 227 + domain_info->country_code[1] = request->alpha2[1]; 228 + domain_info->country_code[2] = ' '; 229 + 230 + for (band = 0; band < IEEE80211_NUM_BANDS ; band++) { 231 + 232 + if (!wiphy->bands[band]) 233 + continue; 234 + 235 + sband = wiphy->bands[band]; 236 + 237 + for (i = 0; i < sband->n_channels ; i++) { 238 + ch = &sband->channels[i]; 239 + if (ch->flags & IEEE80211_CHAN_DISABLED) 240 + continue; 241 + 242 + if (!flag) { 243 + flag = 1; 244 + next_chan = first_channel = (u32) ch->hw_value; 245 + max_pwr = ch->max_power; 246 + no_of_parsed_chan = 1; 247 + continue; 248 + } 249 + 250 + if (ch->hw_value == next_chan + 1 && 251 + ch->max_power == max_pwr) { 252 + next_chan++; 253 + no_of_parsed_chan++; 254 + } else { 255 + domain_info->triplet[no_of_triplet] 256 + .chans.first_channel = first_channel; 257 + domain_info->triplet[no_of_triplet] 258 + .chans.num_channels = no_of_parsed_chan; 259 + domain_info->triplet[no_of_triplet] 260 + .chans.max_power = max_pwr; 261 + no_of_triplet++; 262 + flag = 0; 263 + } 264 + } 265 + if (flag) { 266 + domain_info->triplet[no_of_triplet] 267 + .chans.first_channel = first_channel; 268 + domain_info->triplet[no_of_triplet] 269 + .chans.num_channels = no_of_parsed_chan; 270 + domain_info->triplet[no_of_triplet] 271 + .chans.max_power = max_pwr; 272 + no_of_triplet++; 273 + } 274 + } 275 + 276 + domain_info->no_triplet = no_of_triplet; 277 + 278 + /* Set domain info */ 279 + ret = lbs_11d_set_domain_info(priv); 280 + if (ret) 281 + lbs_pr_err("11D: error setting domain info in FW\n"); 282 + 283 + lbs_deb_leave(LBS_DEB_CFG80211); 284 + } 285 + 286 + int lbs_reg_notifier(struct wiphy *wiphy, 287 + struct regulatory_request *request) 288 + { 289 + lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " 290 + "callback for domain %c%c\n", request->alpha2[0], 291 + request->alpha2[1]); 292 + 293 + lbs_send_domain_info_cmd_fw(wiphy, request); 294 + 295 + lbs_deb_leave(LBS_DEB_CFG80211); 296 + 297 + return 0; 298 + } 299 + 300 + void lbs_scan_deinit(struct lbs_private *priv) 301 + { 302 + lbs_deb_enter(LBS_DEB_CFG80211); 303 + cancel_delayed_work_sync(&priv->scan_work); 2060 304 } 2061 305 2062 306
+16 -5
drivers/net/wireless/libertas/cfg.h
··· 1 1 #ifndef __LBS_CFG80211_H__ 2 2 #define __LBS_CFG80211_H__ 3 3 4 - #include "dev.h" 4 + struct device; 5 + struct lbs_private; 6 + struct regulatory_request; 7 + struct wiphy; 5 8 6 9 struct wireless_dev *lbs_cfg_alloc(struct device *dev); 7 10 int lbs_cfg_register(struct lbs_private *priv); 8 11 void lbs_cfg_free(struct lbs_private *priv); 9 12 10 - int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, 11 - u8 ssid_len); 12 - int lbs_scan_networks(struct lbs_private *priv, int full_scan); 13 - void lbs_cfg_scan_worker(struct work_struct *work); 13 + int lbs_reg_notifier(struct wiphy *wiphy, 14 + struct regulatory_request *request); 14 15 16 + /* All of those are TODOs: */ 17 + #define lbs_cmd_802_11_rssi(priv, cmdptr) (0) 18 + #define lbs_ret_802_11_rssi(priv, resp) (0) 19 + #define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0) 20 + #define lbs_ret_802_11_bcn_ctrl(priv, resp) (0) 21 + 22 + void lbs_send_disconnect_notification(struct lbs_private *priv); 23 + void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); 24 + 25 + void lbs_scan_deinit(struct lbs_private *priv); 15 26 16 27 #endif
+76 -11
drivers/net/wireless/libertas/cmd.c
··· 7 7 #include <linux/sched.h> 8 8 #include <linux/slab.h> 9 9 10 - #include "host.h" 11 10 #include "decl.h" 12 - #include "defs.h" 13 - #include "dev.h" 14 - #include "assoc.h" 15 - #include "wext.h" 16 - #include "scan.h" 11 + #include "cfg.h" 17 12 #include "cmd.h" 18 13 19 14 ··· 171 176 memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN); 172 177 if (priv->mesh_dev) 173 178 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN); 174 - 175 - if (lbs_set_regiontable(priv, priv->regioncode, 0)) { 176 - ret = -1; 177 - goto out; 178 - } 179 179 180 180 out: 181 181 lbs_deb_leave(LBS_DEB_CMD); ··· 899 909 } 900 910 901 911 /** 912 + * @brief This function implements command CMD_802_11D_DOMAIN_INFO 913 + * @param priv pointer to struct lbs_private 914 + * @param cmd pointer to cmd buffer 915 + * @param cmdno cmd ID 916 + * @param cmdOption cmd action 917 + * @return 0 918 + */ 919 + int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, 920 + struct cmd_ds_command *cmd, 921 + u16 cmdoption) 922 + { 923 + struct cmd_ds_802_11d_domain_info *pdomaininfo = 924 + &cmd->params.domaininfo; 925 + struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain; 926 + u8 nr_triplet = priv->domain_reg.no_triplet; 927 + 928 + lbs_deb_enter(LBS_DEB_11D); 929 + 930 + lbs_deb_11d("nr_triplet=%x\n", nr_triplet); 931 + 932 + pdomaininfo->action = cpu_to_le16(cmdoption); 933 + if (cmdoption == CMD_ACT_GET) { 934 + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + 935 + sizeof(struct cmd_header)); 936 + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, 937 + le16_to_cpu(cmd->size)); 938 + goto done; 939 + } 940 + 941 + domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); 942 + memcpy(domain->countrycode, priv->domain_reg.country_code, 943 + sizeof(domain->countrycode)); 944 + 945 + domain->header.len = cpu_to_le16(nr_triplet 946 + * sizeof(struct ieee80211_country_ie_triplet) 947 + + sizeof(domain->countrycode)); 948 + 949 + if (nr_triplet) { 950 + memcpy(domain->triplet, priv->domain_reg.triplet, 951 + nr_triplet * 952 + sizeof(struct ieee80211_country_ie_triplet)); 953 + 954 + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + 955 + le16_to_cpu(domain->header.len) + 956 + sizeof(struct mrvl_ie_header) + 957 + sizeof(struct cmd_header)); 958 + } else { 959 + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + 960 + sizeof(struct cmd_header)); 961 + } 962 + 963 + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, 964 + le16_to_cpu(cmd->size)); 965 + 966 + done: 967 + lbs_deb_enter(LBS_DEB_11D); 968 + return 0; 969 + } 970 + 971 + /** 902 972 * @brief This function prepare the command before send to firmware. 903 973 * 904 974 * @param priv A pointer to struct lbs_private structure ··· 1055 1005 1056 1006 ret = 0; 1057 1007 goto done; 1008 + 1009 + case CMD_802_11D_DOMAIN_INFO: 1010 + cmdptr->command = cpu_to_le16(cmd_no); 1011 + ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action); 1012 + break; 1058 1013 1059 1014 case CMD_802_11_TPC_CFG: 1060 1015 cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); ··· 1380 1325 * check if in power save mode, if yes, put the device back 1381 1326 * to PS mode 1382 1327 */ 1328 + #ifdef TODO 1329 + /* 1330 + * This was the old code for libertas+wext. Someone that 1331 + * understands this beast should re-code it in a sane way. 1332 + * 1333 + * I actually don't understand why this is related to WPA 1334 + * and to connection status, shouldn't powering should be 1335 + * independ of such things? 1336 + */ 1383 1337 if ((priv->psmode != LBS802_11POWERMODECAM) && 1384 1338 (priv->psstate == PS_STATE_FULL_POWER) && 1385 1339 ((priv->connect_status == LBS_CONNECTED) || ··· 1410 1346 lbs_ps_sleep(priv, 0); 1411 1347 } 1412 1348 } 1349 + #endif 1413 1350 } 1414 1351 1415 1352 ret = 0;
+56 -27
drivers/net/wireless/libertas/cmdresp.c
··· 5 5 #include <linux/slab.h> 6 6 #include <linux/delay.h> 7 7 #include <linux/sched.h> 8 - #include <linux/if_arp.h> 9 - #include <linux/netdevice.h> 10 8 #include <asm/unaligned.h> 11 - #include <net/iw_handler.h> 9 + #include <net/cfg80211.h> 12 10 13 - #include "host.h" 14 - #include "decl.h" 15 - #include "cmd.h" 16 - #include "defs.h" 17 - #include "dev.h" 18 - #include "assoc.h" 19 - #include "wext.h" 11 + #include "cfg.h" 20 12 #include "cmd.h" 21 13 22 14 /** ··· 31 39 * It causes problem in the Supplicant 32 40 */ 33 41 msleep_interruptible(1000); 34 - lbs_send_disconnect_notification(priv); 42 + 43 + if (priv->wdev->iftype == NL80211_IFTYPE_STATION) 44 + lbs_send_disconnect_notification(priv); 35 45 36 46 /* report disconnect to upper layer */ 37 47 netif_stop_queue(priv->dev); ··· 44 50 priv->currenttxskb = NULL; 45 51 priv->tx_pending_len = 0; 46 52 47 - /* reset SNR/NF/RSSI values */ 48 - memset(priv->SNR, 0x00, sizeof(priv->SNR)); 49 - memset(priv->NF, 0x00, sizeof(priv->NF)); 50 - memset(priv->RSSI, 0x00, sizeof(priv->RSSI)); 51 - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); 52 - memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); 53 - priv->nextSNRNF = 0; 54 - priv->numSNRNF = 0; 55 53 priv->connect_status = LBS_DISCONNECTED; 56 - 57 - /* Clear out associated SSID and BSSID since connection is 58 - * no longer valid. 59 - */ 60 - memset(&priv->curbssparams.bssid, 0, ETH_ALEN); 61 - memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN); 62 - priv->curbssparams.ssid_len = 0; 63 54 64 55 if (priv->psstate != PS_STATE_FULL_POWER) { 65 56 /* make firmware to exit PS mode */ ··· 97 118 return ret; 98 119 } 99 120 121 + /** 122 + * @brief This function parses countryinfo from AP and download country info to FW 123 + * @param priv pointer to struct lbs_private 124 + * @param resp pointer to command response buffer 125 + * @return 0; -1 126 + */ 127 + static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) 128 + { 129 + struct cmd_ds_802_11d_domain_info *domaininfo = 130 + &resp->params.domaininforesp; 131 + struct mrvl_ie_domain_param_set *domain = &domaininfo->domain; 132 + u16 action = le16_to_cpu(domaininfo->action); 133 + s16 ret = 0; 134 + u8 nr_triplet = 0; 135 + 136 + lbs_deb_enter(LBS_DEB_11D); 137 + 138 + lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp, 139 + (int)le16_to_cpu(resp->size)); 140 + 141 + nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / 142 + sizeof(struct ieee80211_country_ie_triplet); 143 + 144 + lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet); 145 + 146 + if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) { 147 + lbs_deb_11d("invalid number of triplets returned!!\n"); 148 + return -1; 149 + } 150 + 151 + switch (action) { 152 + case CMD_ACT_SET: /*Proc set action */ 153 + break; 154 + 155 + case CMD_ACT_GET: 156 + break; 157 + default: 158 + lbs_deb_11d("invalid action:%d\n", domaininfo->action); 159 + ret = -1; 160 + break; 161 + } 162 + 163 + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); 164 + return ret; 165 + } 166 + 100 167 static inline int handle_cmd_response(struct lbs_private *priv, 101 168 struct cmd_header *cmd_response) 102 169 { ··· 174 149 175 150 case CMD_RET(CMD_802_11_RSSI): 176 151 ret = lbs_ret_802_11_rssi(priv, resp); 152 + break; 153 + 154 + case CMD_RET(CMD_802_11D_DOMAIN_INFO): 155 + ret = lbs_ret_802_11d_domain_info(resp); 177 156 break; 178 157 179 158 case CMD_RET(CMD_802_11_TPC_CFG): ··· 291 262 * ad-hoc mode. It takes place in 292 263 * lbs_execute_next_command(). 293 264 */ 294 - if (priv->mode == IW_MODE_ADHOC && 265 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR && 295 266 action == CMD_SUBCMD_ENTER_PS) 296 267 priv->psmode = LBS802_11POWERMODECAM; 297 268 } else if (action == CMD_SUBCMD_ENTER_PS) {
+1 -53
drivers/net/wireless/libertas/debugfs.c
··· 1 - #include <linux/module.h> 2 1 #include <linux/dcache.h> 3 2 #include <linux/debugfs.h> 4 3 #include <linux/delay.h> 5 4 #include <linux/mm.h> 6 5 #include <linux/string.h> 7 6 #include <linux/slab.h> 8 - #include <net/iw_handler.h> 9 - #include <net/lib80211.h> 10 7 11 - #include "dev.h" 12 8 #include "decl.h" 13 - #include "host.h" 14 - #include "debugfs.h" 15 9 #include "cmd.h" 10 + #include "debugfs.h" 16 11 17 12 static struct dentry *lbs_dir; 18 13 static char *szStates[] = { ··· 48 53 szStates[priv->connect_status]); 49 54 pos += snprintf(buf+pos, len-pos, "region_code = %02x\n", 50 55 (u32) priv->regioncode); 51 - 52 - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 53 - 54 - free_page(addr); 55 - return res; 56 - } 57 - 58 - 59 - static ssize_t lbs_getscantable(struct file *file, char __user *userbuf, 60 - size_t count, loff_t *ppos) 61 - { 62 - struct lbs_private *priv = file->private_data; 63 - size_t pos = 0; 64 - int numscansdone = 0, res; 65 - unsigned long addr = get_zeroed_page(GFP_KERNEL); 66 - char *buf = (char *)addr; 67 - DECLARE_SSID_BUF(ssid); 68 - struct bss_descriptor * iter_bss; 69 - if (!buf) 70 - return -ENOMEM; 71 - 72 - pos += snprintf(buf+pos, len-pos, 73 - "# | ch | rssi | bssid | cap | Qual | SSID\n"); 74 - 75 - mutex_lock(&priv->lock); 76 - list_for_each_entry (iter_bss, &priv->network_list, list) { 77 - u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS); 78 - u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY); 79 - u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); 80 - 81 - pos += snprintf(buf+pos, len-pos, "%02u| %03d | %04d | %pM |", 82 - numscansdone, iter_bss->channel, iter_bss->rssi, 83 - iter_bss->bssid); 84 - pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); 85 - pos += snprintf(buf+pos, len-pos, "%c%c%c |", 86 - ibss ? 'A' : 'I', privacy ? 'P' : ' ', 87 - spectrum_mgmt ? 'S' : ' '); 88 - pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi)); 89 - pos += snprintf(buf+pos, len-pos, " %s\n", 90 - print_ssid(ssid, iter_bss->ssid, 91 - iter_bss->ssid_len)); 92 - 93 - numscansdone++; 94 - } 95 - mutex_unlock(&priv->lock); 96 56 97 57 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 98 58 ··· 673 723 674 724 static const struct lbs_debugfs_files debugfs_files[] = { 675 725 { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), }, 676 - { "getscantable", 0444, FOPS(lbs_getscantable, 677 - write_file_dummy), }, 678 726 { "sleepparams", 0644, FOPS(lbs_sleepparams_read, 679 727 lbs_sleepparams_write), }, 680 728 };
+8
drivers/net/wireless/libertas/decl.h
··· 1 + 1 2 /** 2 3 * This file contains declaration referring to 3 4 * functions defined in other source files ··· 13 12 struct lbs_private; 14 13 struct sk_buff; 15 14 struct net_device; 15 + struct cmd_ds_command; 16 16 17 17 18 18 /* ethtool.c */ ··· 36 34 void lbs_stop_card(struct lbs_private *priv); 37 35 void lbs_host_to_card_done(struct lbs_private *priv); 38 36 37 + int lbs_rtap_supported(struct lbs_private *priv); 38 + 39 39 int lbs_set_mac_address(struct net_device *dev, void *addr); 40 40 void lbs_set_multicast_list(struct net_device *dev); 41 41 ··· 53 49 u32 lbs_fw_index_to_data_rate(u8 index); 54 50 u8 lbs_data_rate_to_fw_index(u32 rate); 55 51 52 + int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, 53 + struct cmd_ds_command *cmd, u16 cmdoption); 54 + 55 + int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp); 56 56 57 57 #endif
+12 -50
drivers/net/wireless/libertas/dev.h
··· 7 7 #define _LBS_DEV_H_ 8 8 9 9 #include "mesh.h" 10 - #include "scan.h" 11 - #include "assoc.h" 10 + #include "defs.h" 11 + #include "host.h" 12 12 13 13 #include <linux/kfifo.h> 14 14 ··· 29 29 /* Basic networking */ 30 30 struct net_device *dev; 31 31 u32 connect_status; 32 - int infra_open; 33 32 struct work_struct mcast_work; 34 33 u32 nr_of_multicastmacaddr; 35 34 u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; ··· 36 37 /* CFG80211 */ 37 38 struct wireless_dev *wdev; 38 39 bool wiphy_registered; 40 + struct cfg80211_scan_request *scan_req; 41 + u8 assoc_bss[ETH_ALEN]; 42 + u8 disassoc_reason; 39 43 40 44 /* Mesh */ 41 45 struct net_device *mesh_dev; /* Virtual device */ ··· 51 49 u8 mesh_ssid_len; 52 50 #endif 53 51 54 - /* Monitor mode */ 55 - struct net_device *rtap_net_dev; 56 - u32 monitormode; 57 - 58 52 /* Debugfs */ 59 53 struct dentry *debugfs_dir; 60 54 struct dentry *debugfs_debug; ··· 59 61 struct dentry *debugfs_events_files[6]; 60 62 struct dentry *regs_dir; 61 63 struct dentry *debugfs_regs_files[6]; 64 + 65 + /** 11D and domain regulatory data */ 66 + struct lbs_802_11d_domain_reg domain_reg; 62 67 63 68 /* Hardware debugging */ 64 69 u32 mac_offset; ··· 134 133 struct workqueue_struct *work_thread; 135 134 136 135 /** Encryption stuff */ 137 - struct lbs_802_11_security secinfo; 138 - struct enc_key wpa_mcast_key; 139 - struct enc_key wpa_unicast_key; 140 - u8 wpa_ie[MAX_WPA_IE_LEN]; 141 - u8 wpa_ie_len; 142 - u16 wep_tx_keyidx; 143 - struct enc_key wep_keys[4]; 144 136 u8 authtype_auto; 137 + u8 wep_tx_key; 138 + u8 wep_key[4][WLAN_KEY_LEN_WEP104]; 139 + u8 wep_key_len[4]; 145 140 146 141 /* Wake On LAN */ 147 142 uint32_t wol_criteria; ··· 158 161 /* NIC/link operation characteristics */ 159 162 u16 mac_control; 160 163 u8 radio_on; 164 + u8 cur_rate; 161 165 u8 channel; 162 166 s16 txpower_cur; 163 167 s16 txpower_min; ··· 167 169 /** Scanning */ 168 170 struct delayed_work scan_work; 169 171 int scan_channel; 170 - /* remember which channel was scanned last, != 0 if currently scanning */ 171 - u8 scan_ssid[IEEE80211_MAX_SSID_LEN + 1]; 172 - u8 scan_ssid_len; 173 - 174 - /* Associating */ 175 - struct delayed_work assoc_work; 176 - struct current_bss_params curbssparams; 177 - u8 mode; 178 - struct list_head network_list; 179 - struct list_head network_free_list; 180 - struct bss_descriptor *networks; 181 - struct assoc_request * pending_assoc_req; 182 - struct assoc_request * in_progress_assoc_req; 183 - uint16_t enablehwauto; 184 - 185 - /* ADHOC */ 186 - u16 beacon_period; 187 - u8 beacon_enable; 188 - u8 adhoccreate; 189 - 190 - /* WEXT */ 191 - char name[DEV_NAME_LEN]; 192 - u8 nodename[16]; 193 - struct iw_statistics wstats; 194 - u8 cur_rate; 195 - #define MAX_REGION_CHANNEL_NUM 2 196 - struct region_channel region_channel[MAX_REGION_CHANNEL_NUM]; 197 - 198 - /** Requested Signal Strength*/ 199 - u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG]; 200 - u16 NF[MAX_TYPE_B][MAX_TYPE_AVG]; 201 - u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG]; 202 - u8 rawSNR[DEFAULT_DATA_AVG_FACTOR]; 203 - u8 rawNF[DEFAULT_DATA_AVG_FACTOR]; 204 - u16 nextSNRNF; 205 - u16 numSNRNF; 206 172 }; 207 173 208 174 extern struct cmd_confirm_sleep confirm_sleep;
-5
drivers/net/wireless/libertas/ethtool.c
··· 2 2 #include <linux/ethtool.h> 3 3 #include <linux/delay.h> 4 4 5 - #include "host.h" 6 5 #include "decl.h" 7 - #include "defs.h" 8 - #include "dev.h" 9 - #include "wext.h" 10 6 #include "cmd.h" 11 - #include "mesh.h" 12 7 13 8 14 9 static void lbs_ethtool_get_drvinfo(struct net_device *dev,
+27 -1
drivers/net/wireless/libertas/host.h
··· 389 389 u32 value; 390 390 } __packed; 391 391 392 + #define MRVDRV_MAX_TRIPLET_802_11D 83 393 + 394 + #define COUNTRY_CODE_LEN 3 395 + 396 + struct mrvl_ie_domain_param_set { 397 + struct mrvl_ie_header header; 398 + 399 + u8 countrycode[COUNTRY_CODE_LEN]; 400 + struct ieee80211_country_ie_triplet triplet[1]; 401 + } __attribute__ ((packed)); 402 + 403 + struct cmd_ds_802_11d_domain_info { 404 + __le16 action; 405 + struct mrvl_ie_domain_param_set domain; 406 + } __attribute__ ((packed)); 407 + 408 + struct lbs_802_11d_domain_reg { 409 + /** Country code*/ 410 + u8 country_code[COUNTRY_CODE_LEN]; 411 + /** No. of triplet*/ 412 + u8 no_triplet; 413 + struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D]; 414 + } __attribute__ ((packed)); 415 + 392 416 /* 393 417 * Define data structure for CMD_GET_HW_SPEC 394 418 * This structure defines the response for the GET_HW_SPEC command ··· 973 949 struct cmd_ds_bbp_reg_access bbpreg; 974 950 struct cmd_ds_rf_reg_access rfreg; 975 951 952 + struct cmd_ds_802_11d_domain_info domaininfo; 953 + struct cmd_ds_802_11d_domain_info domaininforesp; 954 + 976 955 struct cmd_ds_802_11_tpc_cfg tpccfg; 977 956 struct cmd_ds_802_11_afc afc; 978 957 struct cmd_ds_802_11_led_ctrl ledgpio; ··· 985 958 struct cmd_ds_802_11_beacon_control bcn_ctrl; 986 959 } params; 987 960 } __packed; 988 - 989 961 #endif
+7 -219
drivers/net/wireless/libertas/main.c
··· 11 11 #include <linux/if_arp.h> 12 12 #include <linux/kthread.h> 13 13 #include <linux/kfifo.h> 14 - #include <linux/stddef.h> 15 - #include <linux/ieee80211.h> 16 14 #include <linux/slab.h> 17 - #include <net/iw_handler.h> 18 15 #include <net/cfg80211.h> 19 16 20 17 #include "host.h" 21 18 #include "decl.h" 22 19 #include "dev.h" 23 - #include "wext.h" 24 20 #include "cfg.h" 25 21 #include "debugfs.h" 26 - #include "scan.h" 27 - #include "assoc.h" 28 22 #include "cmd.h" 29 23 30 24 #define DRIVER_RELEASE_VERSION "323.p0" ··· 90 96 } 91 97 92 98 93 - static int lbs_add_rtap(struct lbs_private *priv); 94 - static void lbs_remove_rtap(struct lbs_private *priv); 95 - 96 - 97 - /** 98 - * Get function for sysfs attribute rtap 99 - */ 100 - static ssize_t lbs_rtap_get(struct device *dev, 101 - struct device_attribute *attr, char * buf) 102 - { 103 - struct lbs_private *priv = to_net_dev(dev)->ml_priv; 104 - return snprintf(buf, 5, "0x%X\n", priv->monitormode); 105 - } 106 - 107 - /** 108 - * Set function for sysfs attribute rtap 109 - */ 110 - static ssize_t lbs_rtap_set(struct device *dev, 111 - struct device_attribute *attr, const char * buf, size_t count) 112 - { 113 - int monitor_mode; 114 - struct lbs_private *priv = to_net_dev(dev)->ml_priv; 115 - 116 - sscanf(buf, "%x", &monitor_mode); 117 - if (monitor_mode) { 118 - if (priv->monitormode == monitor_mode) 119 - return strlen(buf); 120 - if (!priv->monitormode) { 121 - if (priv->infra_open || lbs_mesh_open(priv)) 122 - return -EBUSY; 123 - if (priv->mode == IW_MODE_INFRA) 124 - lbs_cmd_80211_deauthenticate(priv, 125 - priv->curbssparams.bssid, 126 - WLAN_REASON_DEAUTH_LEAVING); 127 - else if (priv->mode == IW_MODE_ADHOC) 128 - lbs_adhoc_stop(priv); 129 - lbs_add_rtap(priv); 130 - } 131 - priv->monitormode = monitor_mode; 132 - } else { 133 - if (!priv->monitormode) 134 - return strlen(buf); 135 - priv->monitormode = 0; 136 - lbs_remove_rtap(priv); 137 - 138 - if (priv->currenttxskb) { 139 - dev_kfree_skb_any(priv->currenttxskb); 140 - priv->currenttxskb = NULL; 141 - } 142 - 143 - /* Wake queues, command thread, etc. */ 144 - lbs_host_to_card_done(priv); 145 - } 146 - 147 - lbs_prepare_and_send_command(priv, 148 - CMD_802_11_MONITOR_MODE, CMD_ACT_SET, 149 - CMD_OPTION_WAITFORRSP, 0, &priv->monitormode); 150 - return strlen(buf); 151 - } 152 - 153 - /** 154 - * lbs_rtap attribute to be exported per ethX interface 155 - * through sysfs (/sys/class/net/ethX/lbs_rtap) 156 - */ 157 - static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set ); 158 - 159 99 /** 160 100 * @brief This function opens the ethX interface 161 101 * ··· 105 177 106 178 spin_lock_irq(&priv->driver_lock); 107 179 108 - if (priv->monitormode) { 109 - ret = -EBUSY; 110 - goto out; 111 - } 112 - 113 - priv->infra_open = 1; 114 - 115 180 if (priv->connect_status == LBS_CONNECTED) 116 181 netif_carrier_on(dev); 117 182 else ··· 112 191 113 192 if (!priv->tx_pending_len) 114 193 netif_wake_queue(dev); 115 - out: 116 194 117 195 spin_unlock_irq(&priv->driver_lock); 118 196 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); ··· 131 211 lbs_deb_enter(LBS_DEB_NET); 132 212 133 213 spin_lock_irq(&priv->driver_lock); 134 - priv->infra_open = 0; 135 214 netif_stop_queue(dev); 136 215 spin_unlock_irq(&priv->driver_lock); 137 216 ··· 652 733 priv->txpower_max = maxlevel; 653 734 } 654 735 736 + /* Send cmd to FW to enable 11D function */ 737 + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1); 738 + 655 739 lbs_set_mac_control(priv); 656 740 done: 657 741 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); ··· 744 822 745 823 static int lbs_init_adapter(struct lbs_private *priv) 746 824 { 747 - size_t bufsize; 748 - int i, ret = 0; 825 + int ret; 749 826 750 827 lbs_deb_enter(LBS_DEB_MAIN); 751 - 752 - /* Allocate buffer to store the BSSID list */ 753 - bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor); 754 - priv->networks = kzalloc(bufsize, GFP_KERNEL); 755 - if (!priv->networks) { 756 - lbs_pr_err("Out of memory allocating beacons\n"); 757 - ret = -1; 758 - goto out; 759 - } 760 - 761 - /* Initialize scan result lists */ 762 - INIT_LIST_HEAD(&priv->network_free_list); 763 - INIT_LIST_HEAD(&priv->network_list); 764 - for (i = 0; i < MAX_NETWORK_COUNT; i++) { 765 - list_add_tail(&priv->networks[i].list, 766 - &priv->network_free_list); 767 - } 768 828 769 829 memset(priv->current_addr, 0xff, ETH_ALEN); 770 830 771 831 priv->connect_status = LBS_DISCONNECTED; 772 - priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 773 - priv->mode = IW_MODE_INFRA; 774 832 priv->channel = DEFAULT_AD_HOC_CHANNEL; 775 833 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 776 834 priv->radio_on = 1; 777 - priv->enablehwauto = 1; 778 835 priv->psmode = LBS802_11POWERMODECAM; 779 836 priv->psstate = PS_STATE_FULL_POWER; 780 837 priv->is_deep_sleep = 0; ··· 808 907 kfifo_free(&priv->event_fifo); 809 908 del_timer(&priv->command_timer); 810 909 del_timer(&priv->auto_deepsleep_timer); 811 - kfree(priv->networks); 812 - priv->networks = NULL; 813 910 814 911 lbs_deb_leave(LBS_DEB_MAIN); 815 912 } ··· 844 945 lbs_pr_err("cfg80211 init failed\n"); 845 946 goto done; 846 947 } 847 - /* TODO? */ 948 + 848 949 wdev->iftype = NL80211_IFTYPE_STATION; 849 950 priv = wdev_priv(wdev); 850 951 priv->wdev = wdev; ··· 854 955 goto err_wdev; 855 956 } 856 957 857 - //TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES); 858 958 dev = alloc_netdev(0, "wlan%d", ether_setup); 859 959 if (!dev) { 860 960 dev_err(dmdev, "no memory for network device instance\n"); ··· 869 971 dev->netdev_ops = &lbs_netdev_ops; 870 972 dev->watchdog_timeo = 5 * HZ; 871 973 dev->ethtool_ops = &lbs_ethtool_ops; 872 - #ifdef WIRELESS_EXT 873 - dev->wireless_handlers = &lbs_handler_def; 874 - #endif 875 974 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 876 975 877 - 878 - // TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ?? 879 - 880 - 881 976 priv->card = card; 882 - priv->infra_open = 0; 883 977 884 - 885 - priv->rtap_net_dev = NULL; 886 978 strcpy(dev->name, "wlan%d"); 887 979 888 980 lbs_deb_thread("Starting main thread...\n"); ··· 884 996 } 885 997 886 998 priv->work_thread = create_singlethread_workqueue("lbs_worker"); 887 - INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); 888 - INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 889 999 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 890 1000 891 1001 priv->wol_criteria = 0xffffffff; ··· 917 1031 lbs_deb_enter(LBS_DEB_MAIN); 918 1032 919 1033 lbs_remove_mesh(priv); 920 - lbs_remove_rtap(priv); 1034 + lbs_scan_deinit(priv); 921 1035 922 1036 dev = priv->dev; 923 1037 924 - cancel_delayed_work_sync(&priv->scan_work); 925 - cancel_delayed_work_sync(&priv->assoc_work); 926 1038 cancel_work_sync(&priv->mcast_work); 927 1039 928 1040 /* worker thread destruction blocks on the in-flight command which ··· 934 1050 priv->psmode = LBS802_11POWERMODECAM; 935 1051 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 936 1052 } 937 - 938 - lbs_send_disconnect_notification(priv); 939 1053 940 1054 if (priv->is_deep_sleep) { 941 1055 priv->is_deep_sleep = 0; ··· 959 1077 EXPORT_SYMBOL_GPL(lbs_remove_card); 960 1078 961 1079 962 - static int lbs_rtap_supported(struct lbs_private *priv) 1080 + int lbs_rtap_supported(struct lbs_private *priv) 963 1081 { 964 1082 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) 965 1083 return 1; ··· 991 1109 992 1110 lbs_init_mesh(priv); 993 1111 994 - /* 995 - * While rtap isn't related to mesh, only mesh-enabled 996 - * firmware implements the rtap functionality via 997 - * CMD_802_11_MONITOR_MODE. 998 - */ 999 - if (lbs_rtap_supported(priv)) { 1000 - if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1001 - lbs_pr_err("cannot register lbs_rtap attribute\n"); 1002 - } 1003 - 1004 1112 lbs_debugfs_init_one(priv, dev); 1005 1113 1006 1114 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); ··· 1021 1149 1022 1150 lbs_debugfs_remove_one(priv); 1023 1151 lbs_deinit_mesh(priv); 1024 - 1025 - if (lbs_rtap_supported(priv)) 1026 - device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1027 1152 1028 1153 /* Delete the timeout of the currently processing command */ 1029 1154 del_timer_sync(&priv->command_timer); ··· 1106 1237 lbs_deb_enter(LBS_DEB_MAIN); 1107 1238 lbs_debugfs_remove(); 1108 1239 lbs_deb_leave(LBS_DEB_MAIN); 1109 - } 1110 - 1111 - /* 1112 - * rtap interface support fuctions 1113 - */ 1114 - 1115 - static int lbs_rtap_open(struct net_device *dev) 1116 - { 1117 - /* Yes, _stop_ the queue. Because we don't support injection */ 1118 - lbs_deb_enter(LBS_DEB_MAIN); 1119 - netif_carrier_off(dev); 1120 - netif_stop_queue(dev); 1121 - lbs_deb_leave(LBS_DEB_LEAVE); 1122 - return 0; 1123 - } 1124 - 1125 - static int lbs_rtap_stop(struct net_device *dev) 1126 - { 1127 - lbs_deb_enter(LBS_DEB_MAIN); 1128 - lbs_deb_leave(LBS_DEB_MAIN); 1129 - return 0; 1130 - } 1131 - 1132 - static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb, 1133 - struct net_device *dev) 1134 - { 1135 - netif_stop_queue(dev); 1136 - return NETDEV_TX_BUSY; 1137 - } 1138 - 1139 - static void lbs_remove_rtap(struct lbs_private *priv) 1140 - { 1141 - lbs_deb_enter(LBS_DEB_MAIN); 1142 - if (priv->rtap_net_dev == NULL) 1143 - goto out; 1144 - unregister_netdev(priv->rtap_net_dev); 1145 - free_netdev(priv->rtap_net_dev); 1146 - priv->rtap_net_dev = NULL; 1147 - out: 1148 - lbs_deb_leave(LBS_DEB_MAIN); 1149 - } 1150 - 1151 - static const struct net_device_ops rtap_netdev_ops = { 1152 - .ndo_open = lbs_rtap_open, 1153 - .ndo_stop = lbs_rtap_stop, 1154 - .ndo_start_xmit = lbs_rtap_hard_start_xmit, 1155 - }; 1156 - 1157 - static int lbs_add_rtap(struct lbs_private *priv) 1158 - { 1159 - int ret = 0; 1160 - struct net_device *rtap_dev; 1161 - 1162 - lbs_deb_enter(LBS_DEB_MAIN); 1163 - if (priv->rtap_net_dev) { 1164 - ret = -EPERM; 1165 - goto out; 1166 - } 1167 - 1168 - rtap_dev = alloc_netdev(0, "rtap%d", ether_setup); 1169 - if (rtap_dev == NULL) { 1170 - ret = -ENOMEM; 1171 - goto out; 1172 - } 1173 - 1174 - memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN); 1175 - rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP; 1176 - rtap_dev->netdev_ops = &rtap_netdev_ops; 1177 - rtap_dev->ml_priv = priv; 1178 - SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent); 1179 - 1180 - ret = register_netdev(rtap_dev); 1181 - if (ret) { 1182 - free_netdev(rtap_dev); 1183 - goto out; 1184 - } 1185 - priv->rtap_net_dev = rtap_dev; 1186 - 1187 - out: 1188 - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); 1189 - return ret; 1190 1240 } 1191 1241 1192 1242 module_init(lbs_init_module);
+2 -4
drivers/net/wireless/libertas/mesh.c
··· 5 5 #include <linux/if_arp.h> 6 6 #include <linux/kthread.h> 7 7 #include <linux/kfifo.h> 8 + #include <net/cfg80211.h> 8 9 9 10 #include "mesh.h" 10 11 #include "decl.h" ··· 315 314 316 315 spin_lock_irq(&priv->driver_lock); 317 316 318 - if (priv->monitormode) { 317 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 319 318 ret = -EBUSY; 320 319 goto out; 321 320 } ··· 370 369 371 370 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); 372 371 373 - #ifdef WIRELESS_EXT 374 - mesh_dev->wireless_handlers = &mesh_handler_def; 375 - #endif 376 372 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 377 373 /* Register virtual mesh interface */ 378 374 ret = register_netdev(mesh_dev);
-5
drivers/net/wireless/libertas/mesh.h
··· 70 70 void lbs_persist_config_remove(struct net_device *net); 71 71 72 72 73 - /* WEXT handler */ 74 - 75 - extern struct iw_handler_def mesh_handler_def; 76 - 77 - 78 73 /* Ethtool statistics */ 79 74 80 75 struct ethtool_stats;
+11 -110
drivers/net/wireless/libertas/rx.c
··· 4 4 #include <linux/etherdevice.h> 5 5 #include <linux/slab.h> 6 6 #include <linux/types.h> 7 + #include <net/cfg80211.h> 7 8 9 + #include "defs.h" 8 10 #include "host.h" 9 11 #include "radiotap.h" 10 12 #include "decl.h" 11 13 #include "dev.h" 12 - #include "wext.h" 13 14 14 15 struct eth803hdr { 15 16 u8 dest_addr[6]; ··· 40 39 struct sk_buff *skb); 41 40 42 41 /** 43 - * @brief This function computes the avgSNR . 44 - * 45 - * @param priv A pointer to struct lbs_private structure 46 - * @return avgSNR 47 - */ 48 - static u8 lbs_getavgsnr(struct lbs_private *priv) 49 - { 50 - u8 i; 51 - u16 temp = 0; 52 - if (priv->numSNRNF == 0) 53 - return 0; 54 - for (i = 0; i < priv->numSNRNF; i++) 55 - temp += priv->rawSNR[i]; 56 - return (u8) (temp / priv->numSNRNF); 57 - 58 - } 59 - 60 - /** 61 - * @brief This function computes the AvgNF 62 - * 63 - * @param priv A pointer to struct lbs_private structure 64 - * @return AvgNF 65 - */ 66 - static u8 lbs_getavgnf(struct lbs_private *priv) 67 - { 68 - u8 i; 69 - u16 temp = 0; 70 - if (priv->numSNRNF == 0) 71 - return 0; 72 - for (i = 0; i < priv->numSNRNF; i++) 73 - temp += priv->rawNF[i]; 74 - return (u8) (temp / priv->numSNRNF); 75 - 76 - } 77 - 78 - /** 79 - * @brief This function save the raw SNR/NF to our internel buffer 80 - * 81 - * @param priv A pointer to struct lbs_private structure 82 - * @param prxpd A pointer to rxpd structure of received packet 83 - * @return n/a 84 - */ 85 - static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) 86 - { 87 - if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR) 88 - priv->numSNRNF++; 89 - priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr; 90 - priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf; 91 - priv->nextSNRNF++; 92 - if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR) 93 - priv->nextSNRNF = 0; 94 - } 95 - 96 - /** 97 - * @brief This function computes the RSSI in received packet. 98 - * 99 - * @param priv A pointer to struct lbs_private structure 100 - * @param prxpd A pointer to rxpd structure of received packet 101 - * @return n/a 102 - */ 103 - static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) 104 - { 105 - 106 - lbs_deb_enter(LBS_DEB_RX); 107 - 108 - lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf); 109 - lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n", 110 - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, 111 - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); 112 - 113 - priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr; 114 - priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf; 115 - lbs_save_rawSNRNF(priv, p_rx_pd); 116 - 117 - priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE; 118 - priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE; 119 - lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n", 120 - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, 121 - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); 122 - 123 - priv->RSSI[TYPE_RXPD][TYPE_NOAVG] = 124 - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG], 125 - priv->NF[TYPE_RXPD][TYPE_NOAVG]); 126 - 127 - priv->RSSI[TYPE_RXPD][TYPE_AVG] = 128 - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, 129 - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); 130 - 131 - lbs_deb_leave(LBS_DEB_RX); 132 - } 133 - 134 - /** 135 42 * @brief This function processes received packet and forwards it 136 43 * to kernel/upper layer 137 44 * ··· 63 154 64 155 skb->ip_summed = CHECKSUM_NONE; 65 156 66 - if (priv->monitormode) 157 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) 67 158 return process_rxed_802_11_packet(priv, skb); 68 159 69 160 p_rx_pd = (struct rxpd *) skb->data; ··· 134 225 */ 135 226 skb_pull(skb, hdrchop); 136 227 137 - /* Take the data rate from the rxpd structure 138 - * only if the rate is auto 139 - */ 140 - if (priv->enablehwauto) 141 - priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); 142 - 143 - lbs_compute_rssi(priv, p_rx_pd); 228 + priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); 144 229 145 230 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 146 231 dev->stats.rx_bytes += skb->len; ··· 255 352 pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr)); 256 353 memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr)); 257 354 258 - /* Take the data rate from the rxpd structure 259 - * only if the rate is auto 260 - */ 261 - if (priv->enablehwauto) 262 - priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); 263 - 264 - lbs_compute_rssi(priv, prxpd); 355 + priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); 265 356 266 357 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 267 358 dev->stats.rx_bytes += skb->len; 268 359 dev->stats.rx_packets++; 269 360 270 - skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); 271 - netif_rx(skb); 361 + skb->protocol = eth_type_trans(skb, priv->dev); 362 + 363 + if (in_interrupt()) 364 + netif_rx(skb); 365 + else 366 + netif_rx_ni(skb); 272 367 273 368 ret = 0; 274 369
-1354
drivers/net/wireless/libertas/scan.c
··· 1 - /** 2 - * Functions implementing wlan scan IOCTL and firmware command APIs 3 - * 4 - * IOCTL handlers as well as command preperation and response routines 5 - * for sending scan commands to the firmware. 6 - */ 7 - #include <linux/slab.h> 8 - #include <linux/types.h> 9 - #include <linux/kernel.h> 10 - #include <linux/etherdevice.h> 11 - #include <linux/if_arp.h> 12 - #include <asm/unaligned.h> 13 - #include <net/lib80211.h> 14 - 15 - #include "host.h" 16 - #include "dev.h" 17 - #include "scan.h" 18 - #include "assoc.h" 19 - #include "wext.h" 20 - #include "cmd.h" 21 - 22 - //! Approximate amount of data needed to pass a scan result back to iwlist 23 - #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ 24 - + IEEE80211_MAX_SSID_LEN \ 25 - + IW_EV_UINT_LEN \ 26 - + IW_EV_FREQ_LEN \ 27 - + IW_EV_QUAL_LEN \ 28 - + IEEE80211_MAX_SSID_LEN \ 29 - + IW_EV_PARAM_LEN \ 30 - + 40) /* 40 for WPAIE */ 31 - 32 - //! Memory needed to store a max sized channel List TLV for a firmware scan 33 - #define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \ 34 - + (MRVDRV_MAX_CHANNELS_PER_SCAN \ 35 - * sizeof(struct chanscanparamset))) 36 - 37 - //! Memory needed to store a max number/size SSID TLV for a firmware scan 38 - #define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set)) 39 - 40 - //! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max 41 - #define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ 42 - + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE) 43 - 44 - //! The maximum number of channels the firmware can scan per command 45 - #define MRVDRV_MAX_CHANNELS_PER_SCAN 14 46 - 47 - /** 48 - * @brief Number of channels to scan per firmware scan command issuance. 49 - * 50 - * Number restricted to prevent hitting the limit on the amount of scan data 51 - * returned in a single firmware scan command. 52 - */ 53 - #define MRVDRV_CHANNELS_PER_SCAN_CMD 4 54 - 55 - //! Scan time specified in the channel TLV for each channel for passive scans 56 - #define MRVDRV_PASSIVE_SCAN_CHAN_TIME 100 57 - 58 - //! Scan time specified in the channel TLV for each channel for active scans 59 - #define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 60 - 61 - #define DEFAULT_MAX_SCAN_AGE (15 * HZ) 62 - 63 - static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, 64 - struct cmd_header *resp); 65 - 66 - /*********************************************************************/ 67 - /* */ 68 - /* Misc helper functions */ 69 - /* */ 70 - /*********************************************************************/ 71 - 72 - /** 73 - * @brief Unsets the MSB on basic rates 74 - * 75 - * Scan through an array and unset the MSB for basic data rates. 76 - * 77 - * @param rates buffer of data rates 78 - * @param len size of buffer 79 - */ 80 - static void lbs_unset_basic_rate_flags(u8 *rates, size_t len) 81 - { 82 - int i; 83 - 84 - for (i = 0; i < len; i++) 85 - rates[i] &= 0x7f; 86 - } 87 - 88 - 89 - static inline void clear_bss_descriptor(struct bss_descriptor *bss) 90 - { 91 - /* Don't blow away ->list, just BSS data */ 92 - memset(bss, 0, offsetof(struct bss_descriptor, list)); 93 - } 94 - 95 - /** 96 - * @brief Compare two SSIDs 97 - * 98 - * @param ssid1 A pointer to ssid to compare 99 - * @param ssid2 A pointer to ssid to compare 100 - * 101 - * @return 0: ssid is same, otherwise is different 102 - */ 103 - int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2, 104 - uint8_t ssid2_len) 105 - { 106 - if (ssid1_len != ssid2_len) 107 - return -1; 108 - 109 - return memcmp(ssid1, ssid2, ssid1_len); 110 - } 111 - 112 - static inline int is_same_network(struct bss_descriptor *src, 113 - struct bss_descriptor *dst) 114 - { 115 - /* A network is only a duplicate if the channel, BSSID, and ESSID 116 - * all match. We treat all <hidden> with the same BSSID and channel 117 - * as one network */ 118 - return ((src->ssid_len == dst->ssid_len) && 119 - (src->channel == dst->channel) && 120 - !compare_ether_addr(src->bssid, dst->bssid) && 121 - !memcmp(src->ssid, dst->ssid, src->ssid_len)); 122 - } 123 - 124 - 125 - 126 - /*********************************************************************/ 127 - /* */ 128 - /* Region channel support */ 129 - /* */ 130 - /*********************************************************************/ 131 - 132 - #define LBS_TX_PWR_DEFAULT 20 /*100mW */ 133 - #define LBS_TX_PWR_US_DEFAULT 20 /*100mW */ 134 - #define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */ 135 - #define LBS_TX_PWR_FR_DEFAULT 20 /*100mW */ 136 - #define LBS_TX_PWR_EMEA_DEFAULT 20 /*100mW */ 137 - 138 - /* Format { channel, frequency (MHz), maxtxpower } */ 139 - /* band: 'B/G', region: USA FCC/Canada IC */ 140 - static struct chan_freq_power channel_freq_power_US_BG[] = { 141 - {1, 2412, LBS_TX_PWR_US_DEFAULT}, 142 - {2, 2417, LBS_TX_PWR_US_DEFAULT}, 143 - {3, 2422, LBS_TX_PWR_US_DEFAULT}, 144 - {4, 2427, LBS_TX_PWR_US_DEFAULT}, 145 - {5, 2432, LBS_TX_PWR_US_DEFAULT}, 146 - {6, 2437, LBS_TX_PWR_US_DEFAULT}, 147 - {7, 2442, LBS_TX_PWR_US_DEFAULT}, 148 - {8, 2447, LBS_TX_PWR_US_DEFAULT}, 149 - {9, 2452, LBS_TX_PWR_US_DEFAULT}, 150 - {10, 2457, LBS_TX_PWR_US_DEFAULT}, 151 - {11, 2462, LBS_TX_PWR_US_DEFAULT} 152 - }; 153 - 154 - /* band: 'B/G', region: Europe ETSI */ 155 - static struct chan_freq_power channel_freq_power_EU_BG[] = { 156 - {1, 2412, LBS_TX_PWR_EMEA_DEFAULT}, 157 - {2, 2417, LBS_TX_PWR_EMEA_DEFAULT}, 158 - {3, 2422, LBS_TX_PWR_EMEA_DEFAULT}, 159 - {4, 2427, LBS_TX_PWR_EMEA_DEFAULT}, 160 - {5, 2432, LBS_TX_PWR_EMEA_DEFAULT}, 161 - {6, 2437, LBS_TX_PWR_EMEA_DEFAULT}, 162 - {7, 2442, LBS_TX_PWR_EMEA_DEFAULT}, 163 - {8, 2447, LBS_TX_PWR_EMEA_DEFAULT}, 164 - {9, 2452, LBS_TX_PWR_EMEA_DEFAULT}, 165 - {10, 2457, LBS_TX_PWR_EMEA_DEFAULT}, 166 - {11, 2462, LBS_TX_PWR_EMEA_DEFAULT}, 167 - {12, 2467, LBS_TX_PWR_EMEA_DEFAULT}, 168 - {13, 2472, LBS_TX_PWR_EMEA_DEFAULT} 169 - }; 170 - 171 - /* band: 'B/G', region: Spain */ 172 - static struct chan_freq_power channel_freq_power_SPN_BG[] = { 173 - {10, 2457, LBS_TX_PWR_DEFAULT}, 174 - {11, 2462, LBS_TX_PWR_DEFAULT} 175 - }; 176 - 177 - /* band: 'B/G', region: France */ 178 - static struct chan_freq_power channel_freq_power_FR_BG[] = { 179 - {10, 2457, LBS_TX_PWR_FR_DEFAULT}, 180 - {11, 2462, LBS_TX_PWR_FR_DEFAULT}, 181 - {12, 2467, LBS_TX_PWR_FR_DEFAULT}, 182 - {13, 2472, LBS_TX_PWR_FR_DEFAULT} 183 - }; 184 - 185 - /* band: 'B/G', region: Japan */ 186 - static struct chan_freq_power channel_freq_power_JPN_BG[] = { 187 - {1, 2412, LBS_TX_PWR_JP_DEFAULT}, 188 - {2, 2417, LBS_TX_PWR_JP_DEFAULT}, 189 - {3, 2422, LBS_TX_PWR_JP_DEFAULT}, 190 - {4, 2427, LBS_TX_PWR_JP_DEFAULT}, 191 - {5, 2432, LBS_TX_PWR_JP_DEFAULT}, 192 - {6, 2437, LBS_TX_PWR_JP_DEFAULT}, 193 - {7, 2442, LBS_TX_PWR_JP_DEFAULT}, 194 - {8, 2447, LBS_TX_PWR_JP_DEFAULT}, 195 - {9, 2452, LBS_TX_PWR_JP_DEFAULT}, 196 - {10, 2457, LBS_TX_PWR_JP_DEFAULT}, 197 - {11, 2462, LBS_TX_PWR_JP_DEFAULT}, 198 - {12, 2467, LBS_TX_PWR_JP_DEFAULT}, 199 - {13, 2472, LBS_TX_PWR_JP_DEFAULT}, 200 - {14, 2484, LBS_TX_PWR_JP_DEFAULT} 201 - }; 202 - 203 - /** 204 - * the structure for channel, frequency and power 205 - */ 206 - struct region_cfp_table { 207 - u8 region; 208 - struct chan_freq_power *cfp_BG; 209 - int cfp_no_BG; 210 - }; 211 - 212 - /** 213 - * the structure for the mapping between region and CFP 214 - */ 215 - static struct region_cfp_table region_cfp_table[] = { 216 - {0x10, /*US FCC */ 217 - channel_freq_power_US_BG, 218 - ARRAY_SIZE(channel_freq_power_US_BG), 219 - } 220 - , 221 - {0x20, /*CANADA IC */ 222 - channel_freq_power_US_BG, 223 - ARRAY_SIZE(channel_freq_power_US_BG), 224 - } 225 - , 226 - {0x30, /*EU*/ channel_freq_power_EU_BG, 227 - ARRAY_SIZE(channel_freq_power_EU_BG), 228 - } 229 - , 230 - {0x31, /*SPAIN*/ channel_freq_power_SPN_BG, 231 - ARRAY_SIZE(channel_freq_power_SPN_BG), 232 - } 233 - , 234 - {0x32, /*FRANCE*/ channel_freq_power_FR_BG, 235 - ARRAY_SIZE(channel_freq_power_FR_BG), 236 - } 237 - , 238 - {0x40, /*JAPAN*/ channel_freq_power_JPN_BG, 239 - ARRAY_SIZE(channel_freq_power_JPN_BG), 240 - } 241 - , 242 - /*Add new region here */ 243 - }; 244 - 245 - /** 246 - * @brief This function finds the CFP in 247 - * region_cfp_table based on region and band parameter. 248 - * 249 - * @param region The region code 250 - * @param band The band 251 - * @param cfp_no A pointer to CFP number 252 - * @return A pointer to CFP 253 - */ 254 - static struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no) 255 - { 256 - int i, end; 257 - 258 - lbs_deb_enter(LBS_DEB_MAIN); 259 - 260 - end = ARRAY_SIZE(region_cfp_table); 261 - 262 - for (i = 0; i < end ; i++) { 263 - lbs_deb_main("region_cfp_table[i].region=%d\n", 264 - region_cfp_table[i].region); 265 - if (region_cfp_table[i].region == region) { 266 - *cfp_no = region_cfp_table[i].cfp_no_BG; 267 - lbs_deb_leave(LBS_DEB_MAIN); 268 - return region_cfp_table[i].cfp_BG; 269 - } 270 - } 271 - 272 - lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL"); 273 - return NULL; 274 - } 275 - 276 - int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band) 277 - { 278 - int ret = 0; 279 - int i = 0; 280 - 281 - struct chan_freq_power *cfp; 282 - int cfp_no; 283 - 284 - lbs_deb_enter(LBS_DEB_MAIN); 285 - 286 - memset(priv->region_channel, 0, sizeof(priv->region_channel)); 287 - 288 - cfp = lbs_get_region_cfp_table(region, &cfp_no); 289 - if (cfp != NULL) { 290 - priv->region_channel[i].nrcfp = cfp_no; 291 - priv->region_channel[i].CFP = cfp; 292 - } else { 293 - lbs_deb_main("wrong region code %#x in band B/G\n", 294 - region); 295 - ret = -1; 296 - goto out; 297 - } 298 - priv->region_channel[i].valid = 1; 299 - priv->region_channel[i].region = region; 300 - priv->region_channel[i].band = band; 301 - i++; 302 - out: 303 - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); 304 - return ret; 305 - } 306 - 307 - 308 - 309 - 310 - /*********************************************************************/ 311 - /* */ 312 - /* Main scanning support */ 313 - /* */ 314 - /*********************************************************************/ 315 - 316 - /** 317 - * @brief Create a channel list for the driver to scan based on region info 318 - * 319 - * Only used from lbs_scan_setup_scan_config() 320 - * 321 - * Use the driver region/band information to construct a comprehensive list 322 - * of channels to scan. This routine is used for any scan that is not 323 - * provided a specific channel list to scan. 324 - * 325 - * @param priv A pointer to struct lbs_private structure 326 - * @param scanchanlist Output parameter: resulting channel list to scan 327 - * 328 - * @return void 329 - */ 330 - static int lbs_scan_create_channel_list(struct lbs_private *priv, 331 - struct chanscanparamset *scanchanlist) 332 - { 333 - struct region_channel *scanregion; 334 - struct chan_freq_power *cfp; 335 - int rgnidx; 336 - int chanidx; 337 - int nextchan; 338 - uint8_t scantype; 339 - 340 - chanidx = 0; 341 - 342 - /* Set the default scan type to the user specified type, will later 343 - * be changed to passive on a per channel basis if restricted by 344 - * regulatory requirements (11d or 11h) 345 - */ 346 - scantype = CMD_SCAN_TYPE_ACTIVE; 347 - 348 - for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) { 349 - if (!priv->region_channel[rgnidx].valid) 350 - continue; 351 - scanregion = &priv->region_channel[rgnidx]; 352 - 353 - for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) { 354 - struct chanscanparamset *chan = &scanchanlist[chanidx]; 355 - 356 - cfp = scanregion->CFP + nextchan; 357 - 358 - if (scanregion->band == BAND_B || scanregion->band == BAND_G) 359 - chan->radiotype = CMD_SCAN_RADIO_TYPE_BG; 360 - 361 - if (scantype == CMD_SCAN_TYPE_PASSIVE) { 362 - chan->maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); 363 - chan->chanscanmode.passivescan = 1; 364 - } else { 365 - chan->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); 366 - chan->chanscanmode.passivescan = 0; 367 - } 368 - 369 - chan->channumber = cfp->channel; 370 - } 371 - } 372 - return chanidx; 373 - } 374 - 375 - /* 376 - * Add SSID TLV of the form: 377 - * 378 - * TLV-ID SSID 00 00 379 - * length 06 00 380 - * ssid 4d 4e 54 45 53 54 381 - */ 382 - static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) 383 - { 384 - struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; 385 - 386 - ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 387 - ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); 388 - memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len); 389 - return sizeof(ssid_tlv->header) + priv->scan_ssid_len; 390 - } 391 - 392 - /* 393 - * Add CHANLIST TLV of the form 394 - * 395 - * TLV-ID CHANLIST 01 01 396 - * length 5b 00 397 - * channel 1 00 01 00 00 00 64 00 398 - * radio type 00 399 - * channel 01 400 - * scan type 00 401 - * min scan time 00 00 402 - * max scan time 64 00 403 - * channel 2 00 02 00 00 00 64 00 404 - * channel 3 00 03 00 00 00 64 00 405 - * channel 4 00 04 00 00 00 64 00 406 - * channel 5 00 05 00 00 00 64 00 407 - * channel 6 00 06 00 00 00 64 00 408 - * channel 7 00 07 00 00 00 64 00 409 - * channel 8 00 08 00 00 00 64 00 410 - * channel 9 00 09 00 00 00 64 00 411 - * channel 10 00 0a 00 00 00 64 00 412 - * channel 11 00 0b 00 00 00 64 00 413 - * channel 12 00 0c 00 00 00 64 00 414 - * channel 13 00 0d 00 00 00 64 00 415 - * 416 - */ 417 - static int lbs_scan_add_chanlist_tlv(uint8_t *tlv, 418 - struct chanscanparamset *chan_list, 419 - int chan_count) 420 - { 421 - size_t size = sizeof(struct chanscanparamset) *chan_count; 422 - struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv; 423 - 424 - chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); 425 - memcpy(chan_tlv->chanscanparam, chan_list, size); 426 - chan_tlv->header.len = cpu_to_le16(size); 427 - return sizeof(chan_tlv->header) + size; 428 - } 429 - 430 - /* 431 - * Add RATES TLV of the form 432 - * 433 - * TLV-ID RATES 01 00 434 - * length 0e 00 435 - * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 436 - * 437 - * The rates are in lbs_bg_rates[], but for the 802.11b 438 - * rates the high bit isn't set. 439 - */ 440 - static int lbs_scan_add_rates_tlv(uint8_t *tlv) 441 - { 442 - int i; 443 - struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; 444 - 445 - rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 446 - tlv += sizeof(rate_tlv->header); 447 - for (i = 0; i < MAX_RATES; i++) { 448 - *tlv = lbs_bg_rates[i]; 449 - if (*tlv == 0) 450 - break; 451 - /* This code makes sure that the 802.11b rates (1 MBit/s, 2 452 - MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set. 453 - Note that the values are MBit/s * 2, to mark them as 454 - basic rates so that the firmware likes it better */ 455 - if (*tlv == 0x02 || *tlv == 0x04 || 456 - *tlv == 0x0b || *tlv == 0x16) 457 - *tlv |= 0x80; 458 - tlv++; 459 - } 460 - rate_tlv->header.len = cpu_to_le16(i); 461 - return sizeof(rate_tlv->header) + i; 462 - } 463 - 464 - /* 465 - * Generate the CMD_802_11_SCAN command with the proper tlv 466 - * for a bunch of channels. 467 - */ 468 - static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, 469 - struct chanscanparamset *chan_list, int chan_count) 470 - { 471 - int ret = -ENOMEM; 472 - struct cmd_ds_802_11_scan *scan_cmd; 473 - uint8_t *tlv; /* pointer into our current, growing TLV storage area */ 474 - 475 - lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d", 476 - bsstype, chan_list ? chan_list[0].channumber : -1, 477 - chan_count); 478 - 479 - /* create the fixed part for scan command */ 480 - scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); 481 - if (scan_cmd == NULL) 482 - goto out; 483 - 484 - tlv = scan_cmd->tlvbuffer; 485 - /* TODO: do we need to scan for a specific BSSID? 486 - memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */ 487 - scan_cmd->bsstype = bsstype; 488 - 489 - /* add TLVs */ 490 - if (priv->scan_ssid_len) 491 - tlv += lbs_scan_add_ssid_tlv(priv, tlv); 492 - if (chan_list && chan_count) 493 - tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count); 494 - tlv += lbs_scan_add_rates_tlv(tlv); 495 - 496 - /* This is the final data we are about to send */ 497 - scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd); 498 - lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 499 - sizeof(*scan_cmd)); 500 - lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, 501 - tlv - scan_cmd->tlvbuffer); 502 - 503 - ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, 504 - le16_to_cpu(scan_cmd->hdr.size), 505 - lbs_ret_80211_scan, 0); 506 - 507 - out: 508 - kfree(scan_cmd); 509 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 510 - return ret; 511 - } 512 - 513 - /** 514 - * @brief Internal function used to start a scan based on an input config 515 - * 516 - * Use the input user scan configuration information when provided in 517 - * order to send the appropriate scan commands to firmware to populate or 518 - * update the internal driver scan table 519 - * 520 - * @param priv A pointer to struct lbs_private structure 521 - * @param full_scan Do a full-scan (blocking) 522 - * 523 - * @return 0 or < 0 if error 524 - */ 525 - int lbs_scan_networks(struct lbs_private *priv, int full_scan) 526 - { 527 - int ret = -ENOMEM; 528 - struct chanscanparamset *chan_list; 529 - struct chanscanparamset *curr_chans; 530 - int chan_count; 531 - uint8_t bsstype = CMD_BSS_TYPE_ANY; 532 - int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; 533 - union iwreq_data wrqu; 534 - #ifdef CONFIG_LIBERTAS_DEBUG 535 - struct bss_descriptor *iter; 536 - int i = 0; 537 - DECLARE_SSID_BUF(ssid); 538 - #endif 539 - 540 - lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan); 541 - 542 - /* Cancel any partial outstanding partial scans if this scan 543 - * is a full scan. 544 - */ 545 - if (full_scan && delayed_work_pending(&priv->scan_work)) 546 - cancel_delayed_work(&priv->scan_work); 547 - 548 - /* User-specified bsstype or channel list 549 - TODO: this can be implemented if some user-space application 550 - need the feature. Formerly, it was accessible from debugfs, 551 - but then nowhere used. 552 - if (user_cfg) { 553 - if (user_cfg->bsstype) 554 - bsstype = user_cfg->bsstype; 555 - } */ 556 - 557 - lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype); 558 - 559 - /* Create list of channels to scan */ 560 - chan_list = kzalloc(sizeof(struct chanscanparamset) * 561 - LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); 562 - if (!chan_list) { 563 - lbs_pr_alert("SCAN: chan_list empty\n"); 564 - goto out; 565 - } 566 - 567 - /* We want to scan all channels */ 568 - chan_count = lbs_scan_create_channel_list(priv, chan_list); 569 - 570 - netif_stop_queue(priv->dev); 571 - if (priv->mesh_dev) 572 - netif_stop_queue(priv->mesh_dev); 573 - 574 - /* Prepare to continue an interrupted scan */ 575 - lbs_deb_scan("chan_count %d, scan_channel %d\n", 576 - chan_count, priv->scan_channel); 577 - curr_chans = chan_list; 578 - /* advance channel list by already-scanned-channels */ 579 - if (priv->scan_channel > 0) { 580 - curr_chans += priv->scan_channel; 581 - chan_count -= priv->scan_channel; 582 - } 583 - 584 - /* Send scan command(s) 585 - * numchannels contains the number of channels we should maximally scan 586 - * chan_count is the total number of channels to scan 587 - */ 588 - 589 - while (chan_count) { 590 - int to_scan = min(numchannels, chan_count); 591 - lbs_deb_scan("scanning %d of %d channels\n", 592 - to_scan, chan_count); 593 - ret = lbs_do_scan(priv, bsstype, curr_chans, 594 - to_scan); 595 - if (ret) { 596 - lbs_pr_err("SCAN_CMD failed\n"); 597 - goto out2; 598 - } 599 - curr_chans += to_scan; 600 - chan_count -= to_scan; 601 - 602 - /* somehow schedule the next part of the scan */ 603 - if (chan_count && !full_scan && 604 - !priv->surpriseremoved) { 605 - /* -1 marks just that we're currently scanning */ 606 - if (priv->scan_channel < 0) 607 - priv->scan_channel = to_scan; 608 - else 609 - priv->scan_channel += to_scan; 610 - cancel_delayed_work(&priv->scan_work); 611 - queue_delayed_work(priv->work_thread, &priv->scan_work, 612 - msecs_to_jiffies(300)); 613 - /* skip over GIWSCAN event */ 614 - goto out; 615 - } 616 - 617 - } 618 - memset(&wrqu, 0, sizeof(union iwreq_data)); 619 - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); 620 - 621 - #ifdef CONFIG_LIBERTAS_DEBUG 622 - /* Dump the scan table */ 623 - mutex_lock(&priv->lock); 624 - lbs_deb_scan("scan table:\n"); 625 - list_for_each_entry(iter, &priv->network_list, list) 626 - lbs_deb_scan("%02d: BSSID %pM, RSSI %d, SSID '%s'\n", 627 - i++, iter->bssid, iter->rssi, 628 - print_ssid(ssid, iter->ssid, iter->ssid_len)); 629 - mutex_unlock(&priv->lock); 630 - #endif 631 - 632 - out2: 633 - priv->scan_channel = 0; 634 - 635 - out: 636 - if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) 637 - netif_wake_queue(priv->dev); 638 - 639 - if (priv->mesh_dev && lbs_mesh_connected(priv) && 640 - !priv->tx_pending_len) 641 - netif_wake_queue(priv->mesh_dev); 642 - 643 - kfree(chan_list); 644 - 645 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 646 - return ret; 647 - } 648 - 649 - void lbs_scan_worker(struct work_struct *work) 650 - { 651 - struct lbs_private *priv = 652 - container_of(work, struct lbs_private, scan_work.work); 653 - 654 - lbs_deb_enter(LBS_DEB_SCAN); 655 - lbs_scan_networks(priv, 0); 656 - lbs_deb_leave(LBS_DEB_SCAN); 657 - } 658 - 659 - 660 - /*********************************************************************/ 661 - /* */ 662 - /* Result interpretation */ 663 - /* */ 664 - /*********************************************************************/ 665 - 666 - /** 667 - * @brief Interpret a BSS scan response returned from the firmware 668 - * 669 - * Parse the various fixed fields and IEs passed back for a BSS probe 670 - * response or beacon from the scan command. Record information as needed 671 - * in the scan table struct bss_descriptor for that entry. 672 - * 673 - * @param bss Output parameter: Pointer to the BSS Entry 674 - * 675 - * @return 0 or -1 676 - */ 677 - static int lbs_process_bss(struct bss_descriptor *bss, 678 - uint8_t **pbeaconinfo, int *bytesleft) 679 - { 680 - struct ieee_ie_fh_param_set *fh; 681 - struct ieee_ie_ds_param_set *ds; 682 - struct ieee_ie_cf_param_set *cf; 683 - struct ieee_ie_ibss_param_set *ibss; 684 - DECLARE_SSID_BUF(ssid); 685 - uint8_t *pos, *end, *p; 686 - uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; 687 - uint16_t beaconsize = 0; 688 - int ret; 689 - 690 - lbs_deb_enter(LBS_DEB_SCAN); 691 - 692 - if (*bytesleft >= sizeof(beaconsize)) { 693 - /* Extract & convert beacon size from the command buffer */ 694 - beaconsize = get_unaligned_le16(*pbeaconinfo); 695 - *bytesleft -= sizeof(beaconsize); 696 - *pbeaconinfo += sizeof(beaconsize); 697 - } 698 - 699 - if (beaconsize == 0 || beaconsize > *bytesleft) { 700 - *pbeaconinfo += *bytesleft; 701 - *bytesleft = 0; 702 - ret = -1; 703 - goto done; 704 - } 705 - 706 - /* Initialize the current working beacon pointer for this BSS iteration */ 707 - pos = *pbeaconinfo; 708 - end = pos + beaconsize; 709 - 710 - /* Advance the return beacon pointer past the current beacon */ 711 - *pbeaconinfo += beaconsize; 712 - *bytesleft -= beaconsize; 713 - 714 - memcpy(bss->bssid, pos, ETH_ALEN); 715 - lbs_deb_scan("process_bss: BSSID %pM\n", bss->bssid); 716 - pos += ETH_ALEN; 717 - 718 - if ((end - pos) < 12) { 719 - lbs_deb_scan("process_bss: Not enough bytes left\n"); 720 - ret = -1; 721 - goto done; 722 - } 723 - 724 - /* 725 - * next 4 fields are RSSI, time stamp, beacon interval, 726 - * and capability information 727 - */ 728 - 729 - /* RSSI is 1 byte long */ 730 - bss->rssi = *pos; 731 - lbs_deb_scan("process_bss: RSSI %d\n", *pos); 732 - pos++; 733 - 734 - /* time stamp is 8 bytes long */ 735 - pos += 8; 736 - 737 - /* beacon interval is 2 bytes long */ 738 - bss->beaconperiod = get_unaligned_le16(pos); 739 - pos += 2; 740 - 741 - /* capability information is 2 bytes long */ 742 - bss->capability = get_unaligned_le16(pos); 743 - lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability); 744 - pos += 2; 745 - 746 - if (bss->capability & WLAN_CAPABILITY_PRIVACY) 747 - lbs_deb_scan("process_bss: WEP enabled\n"); 748 - if (bss->capability & WLAN_CAPABILITY_IBSS) 749 - bss->mode = IW_MODE_ADHOC; 750 - else 751 - bss->mode = IW_MODE_INFRA; 752 - 753 - /* rest of the current buffer are IE's */ 754 - lbs_deb_scan("process_bss: IE len %zd\n", end - pos); 755 - lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos); 756 - 757 - /* process variable IE */ 758 - while (pos <= end - 2) { 759 - if (pos + pos[1] > end) { 760 - lbs_deb_scan("process_bss: error in processing IE, " 761 - "bytes left < IE length\n"); 762 - break; 763 - } 764 - 765 - switch (pos[0]) { 766 - case WLAN_EID_SSID: 767 - bss->ssid_len = min_t(int, IEEE80211_MAX_SSID_LEN, pos[1]); 768 - memcpy(bss->ssid, pos + 2, bss->ssid_len); 769 - lbs_deb_scan("got SSID IE: '%s', len %u\n", 770 - print_ssid(ssid, bss->ssid, bss->ssid_len), 771 - bss->ssid_len); 772 - break; 773 - 774 - case WLAN_EID_SUPP_RATES: 775 - n_basic_rates = min_t(uint8_t, MAX_RATES, pos[1]); 776 - memcpy(bss->rates, pos + 2, n_basic_rates); 777 - got_basic_rates = 1; 778 - lbs_deb_scan("got RATES IE\n"); 779 - break; 780 - 781 - case WLAN_EID_FH_PARAMS: 782 - fh = (struct ieee_ie_fh_param_set *) pos; 783 - memcpy(&bss->phy.fh, fh, sizeof(*fh)); 784 - lbs_deb_scan("got FH IE\n"); 785 - break; 786 - 787 - case WLAN_EID_DS_PARAMS: 788 - ds = (struct ieee_ie_ds_param_set *) pos; 789 - bss->channel = ds->channel; 790 - memcpy(&bss->phy.ds, ds, sizeof(*ds)); 791 - lbs_deb_scan("got DS IE, channel %d\n", bss->channel); 792 - break; 793 - 794 - case WLAN_EID_CF_PARAMS: 795 - cf = (struct ieee_ie_cf_param_set *) pos; 796 - memcpy(&bss->ss.cf, cf, sizeof(*cf)); 797 - lbs_deb_scan("got CF IE\n"); 798 - break; 799 - 800 - case WLAN_EID_IBSS_PARAMS: 801 - ibss = (struct ieee_ie_ibss_param_set *) pos; 802 - bss->atimwindow = ibss->atimwindow; 803 - memcpy(&bss->ss.ibss, ibss, sizeof(*ibss)); 804 - lbs_deb_scan("got IBSS IE\n"); 805 - break; 806 - 807 - case WLAN_EID_EXT_SUPP_RATES: 808 - /* only process extended supported rate if data rate is 809 - * already found. Data rate IE should come before 810 - * extended supported rate IE 811 - */ 812 - lbs_deb_scan("got RATESEX IE\n"); 813 - if (!got_basic_rates) { 814 - lbs_deb_scan("... but ignoring it\n"); 815 - break; 816 - } 817 - 818 - n_ex_rates = pos[1]; 819 - if (n_basic_rates + n_ex_rates > MAX_RATES) 820 - n_ex_rates = MAX_RATES - n_basic_rates; 821 - 822 - p = bss->rates + n_basic_rates; 823 - memcpy(p, pos + 2, n_ex_rates); 824 - break; 825 - 826 - case WLAN_EID_GENERIC: 827 - if (pos[1] >= 4 && 828 - pos[2] == 0x00 && pos[3] == 0x50 && 829 - pos[4] == 0xf2 && pos[5] == 0x01) { 830 - bss->wpa_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN); 831 - memcpy(bss->wpa_ie, pos, bss->wpa_ie_len); 832 - lbs_deb_scan("got WPA IE\n"); 833 - lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, 834 - bss->wpa_ie_len); 835 - } else if (pos[1] >= MARVELL_MESH_IE_LENGTH && 836 - pos[2] == 0x00 && pos[3] == 0x50 && 837 - pos[4] == 0x43 && pos[5] == 0x04) { 838 - lbs_deb_scan("got mesh IE\n"); 839 - bss->mesh = 1; 840 - } else { 841 - lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n", 842 - pos[2], pos[3], 843 - pos[4], pos[5], 844 - pos[1]); 845 - } 846 - break; 847 - 848 - case WLAN_EID_RSN: 849 - lbs_deb_scan("got RSN IE\n"); 850 - bss->rsn_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN); 851 - memcpy(bss->rsn_ie, pos, bss->rsn_ie_len); 852 - lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", 853 - bss->rsn_ie, bss->rsn_ie_len); 854 - break; 855 - 856 - default: 857 - lbs_deb_scan("got IE 0x%04x, len %d\n", 858 - pos[0], pos[1]); 859 - break; 860 - } 861 - 862 - pos += pos[1] + 2; 863 - } 864 - 865 - /* Timestamp */ 866 - bss->last_scanned = jiffies; 867 - lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); 868 - 869 - ret = 0; 870 - 871 - done: 872 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 873 - return ret; 874 - } 875 - 876 - /** 877 - * @brief Send a scan command for all available channels filtered on a spec 878 - * 879 - * Used in association code and from debugfs 880 - * 881 - * @param priv A pointer to struct lbs_private structure 882 - * @param ssid A pointer to the SSID to scan for 883 - * @param ssid_len Length of the SSID 884 - * 885 - * @return 0-success, otherwise fail 886 - */ 887 - int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, 888 - uint8_t ssid_len) 889 - { 890 - DECLARE_SSID_BUF(ssid_buf); 891 - int ret = 0; 892 - 893 - lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n", 894 - print_ssid(ssid_buf, ssid, ssid_len)); 895 - 896 - if (!ssid_len) 897 - goto out; 898 - 899 - memcpy(priv->scan_ssid, ssid, ssid_len); 900 - priv->scan_ssid_len = ssid_len; 901 - 902 - lbs_scan_networks(priv, 1); 903 - if (priv->surpriseremoved) { 904 - ret = -1; 905 - goto out; 906 - } 907 - 908 - out: 909 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 910 - return ret; 911 - } 912 - 913 - 914 - 915 - 916 - /*********************************************************************/ 917 - /* */ 918 - /* Support for Wireless Extensions */ 919 - /* */ 920 - /*********************************************************************/ 921 - 922 - 923 - #define MAX_CUSTOM_LEN 64 924 - 925 - static inline char *lbs_translate_scan(struct lbs_private *priv, 926 - struct iw_request_info *info, 927 - char *start, char *stop, 928 - struct bss_descriptor *bss) 929 - { 930 - struct chan_freq_power *cfp; 931 - char *current_val; /* For rates */ 932 - struct iw_event iwe; /* Temporary buffer */ 933 - int j; 934 - #define PERFECT_RSSI ((uint8_t)50) 935 - #define WORST_RSSI ((uint8_t)0) 936 - #define RSSI_DIFF ((uint8_t)(PERFECT_RSSI - WORST_RSSI)) 937 - uint8_t rssi; 938 - 939 - lbs_deb_enter(LBS_DEB_SCAN); 940 - 941 - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, bss->channel); 942 - if (!cfp) { 943 - lbs_deb_scan("Invalid channel number %d\n", bss->channel); 944 - start = NULL; 945 - goto out; 946 - } 947 - 948 - /* First entry *MUST* be the BSSID */ 949 - iwe.cmd = SIOCGIWAP; 950 - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 951 - memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); 952 - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); 953 - 954 - /* SSID */ 955 - iwe.cmd = SIOCGIWESSID; 956 - iwe.u.data.flags = 1; 957 - iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IEEE80211_MAX_SSID_LEN); 958 - start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); 959 - 960 - /* Mode */ 961 - iwe.cmd = SIOCGIWMODE; 962 - iwe.u.mode = bss->mode; 963 - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); 964 - 965 - /* Frequency */ 966 - iwe.cmd = SIOCGIWFREQ; 967 - iwe.u.freq.m = (long)cfp->freq * 100000; 968 - iwe.u.freq.e = 1; 969 - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); 970 - 971 - /* Add quality statistics */ 972 - iwe.cmd = IWEVQUAL; 973 - iwe.u.qual.updated = IW_QUAL_ALL_UPDATED; 974 - iwe.u.qual.level = SCAN_RSSI(bss->rssi); 975 - 976 - rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; 977 - iwe.u.qual.qual = 978 - (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * 979 - (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / 980 - (RSSI_DIFF * RSSI_DIFF); 981 - if (iwe.u.qual.qual > 100) 982 - iwe.u.qual.qual = 100; 983 - 984 - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { 985 - iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; 986 - } else { 987 - iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); 988 - } 989 - 990 - /* Locally created ad-hoc BSSs won't have beacons if this is the 991 - * only station in the adhoc network; so get signal strength 992 - * from receive statistics. 993 - */ 994 - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate 995 - && !lbs_ssid_cmp(priv->curbssparams.ssid, 996 - priv->curbssparams.ssid_len, 997 - bss->ssid, bss->ssid_len)) { 998 - int snr, nf; 999 - snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; 1000 - nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; 1001 - iwe.u.qual.level = CAL_RSSI(snr, nf); 1002 - } 1003 - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); 1004 - 1005 - /* Add encryption capability */ 1006 - iwe.cmd = SIOCGIWENCODE; 1007 - if (bss->capability & WLAN_CAPABILITY_PRIVACY) { 1008 - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 1009 - } else { 1010 - iwe.u.data.flags = IW_ENCODE_DISABLED; 1011 - } 1012 - iwe.u.data.length = 0; 1013 - start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); 1014 - 1015 - current_val = start + iwe_stream_lcp_len(info); 1016 - 1017 - iwe.cmd = SIOCGIWRATE; 1018 - iwe.u.bitrate.fixed = 0; 1019 - iwe.u.bitrate.disabled = 0; 1020 - iwe.u.bitrate.value = 0; 1021 - 1022 - for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) { 1023 - /* Bit rate given in 500 kb/s units */ 1024 - iwe.u.bitrate.value = bss->rates[j] * 500000; 1025 - current_val = iwe_stream_add_value(info, start, current_val, 1026 - stop, &iwe, IW_EV_PARAM_LEN); 1027 - } 1028 - if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate 1029 - && !lbs_ssid_cmp(priv->curbssparams.ssid, 1030 - priv->curbssparams.ssid_len, 1031 - bss->ssid, bss->ssid_len)) { 1032 - iwe.u.bitrate.value = 22 * 500000; 1033 - current_val = iwe_stream_add_value(info, start, current_val, 1034 - stop, &iwe, IW_EV_PARAM_LEN); 1035 - } 1036 - /* Check if we added any event */ 1037 - if ((current_val - start) > iwe_stream_lcp_len(info)) 1038 - start = current_val; 1039 - 1040 - memset(&iwe, 0, sizeof(iwe)); 1041 - if (bss->wpa_ie_len) { 1042 - char buf[MAX_WPA_IE_LEN]; 1043 - memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); 1044 - iwe.cmd = IWEVGENIE; 1045 - iwe.u.data.length = bss->wpa_ie_len; 1046 - start = iwe_stream_add_point(info, start, stop, &iwe, buf); 1047 - } 1048 - 1049 - memset(&iwe, 0, sizeof(iwe)); 1050 - if (bss->rsn_ie_len) { 1051 - char buf[MAX_WPA_IE_LEN]; 1052 - memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); 1053 - iwe.cmd = IWEVGENIE; 1054 - iwe.u.data.length = bss->rsn_ie_len; 1055 - start = iwe_stream_add_point(info, start, stop, &iwe, buf); 1056 - } 1057 - 1058 - if (bss->mesh) { 1059 - char custom[MAX_CUSTOM_LEN]; 1060 - char *p = custom; 1061 - 1062 - iwe.cmd = IWEVCUSTOM; 1063 - p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); 1064 - iwe.u.data.length = p - custom; 1065 - if (iwe.u.data.length) 1066 - start = iwe_stream_add_point(info, start, stop, 1067 - &iwe, custom); 1068 - } 1069 - 1070 - out: 1071 - lbs_deb_leave_args(LBS_DEB_SCAN, "start %p", start); 1072 - return start; 1073 - } 1074 - 1075 - 1076 - /** 1077 - * @brief Handle Scan Network ioctl 1078 - * 1079 - * @param dev A pointer to net_device structure 1080 - * @param info A pointer to iw_request_info structure 1081 - * @param vwrq A pointer to iw_param structure 1082 - * @param extra A pointer to extra data buf 1083 - * 1084 - * @return 0 --success, otherwise fail 1085 - */ 1086 - int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, 1087 - union iwreq_data *wrqu, char *extra) 1088 - { 1089 - DECLARE_SSID_BUF(ssid); 1090 - struct lbs_private *priv = dev->ml_priv; 1091 - int ret = 0; 1092 - 1093 - lbs_deb_enter(LBS_DEB_WEXT); 1094 - 1095 - if (!priv->radio_on) { 1096 - ret = -EINVAL; 1097 - goto out; 1098 - } 1099 - 1100 - if (!netif_running(dev)) { 1101 - ret = -ENETDOWN; 1102 - goto out; 1103 - } 1104 - 1105 - /* mac80211 does this: 1106 - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1107 - if (sdata->type != IEEE80211_IF_TYPE_xxx) { 1108 - ret = -EOPNOTSUPP; 1109 - goto out; 1110 - } 1111 - */ 1112 - 1113 - if (wrqu->data.length == sizeof(struct iw_scan_req) && 1114 - wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1115 - struct iw_scan_req *req = (struct iw_scan_req *)extra; 1116 - priv->scan_ssid_len = req->essid_len; 1117 - memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); 1118 - lbs_deb_wext("set_scan, essid '%s'\n", 1119 - print_ssid(ssid, priv->scan_ssid, priv->scan_ssid_len)); 1120 - } else { 1121 - priv->scan_ssid_len = 0; 1122 - } 1123 - 1124 - if (!delayed_work_pending(&priv->scan_work)) 1125 - queue_delayed_work(priv->work_thread, &priv->scan_work, 1126 - msecs_to_jiffies(50)); 1127 - /* set marker that currently a scan is taking place */ 1128 - priv->scan_channel = -1; 1129 - 1130 - if (priv->surpriseremoved) 1131 - ret = -EIO; 1132 - 1133 - out: 1134 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1135 - return ret; 1136 - } 1137 - 1138 - 1139 - /** 1140 - * @brief Handle Retrieve scan table ioctl 1141 - * 1142 - * @param dev A pointer to net_device structure 1143 - * @param info A pointer to iw_request_info structure 1144 - * @param dwrq A pointer to iw_point structure 1145 - * @param extra A pointer to extra data buf 1146 - * 1147 - * @return 0 --success, otherwise fail 1148 - */ 1149 - int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, 1150 - struct iw_point *dwrq, char *extra) 1151 - { 1152 - #define SCAN_ITEM_SIZE 128 1153 - struct lbs_private *priv = dev->ml_priv; 1154 - int err = 0; 1155 - char *ev = extra; 1156 - char *stop = ev + dwrq->length; 1157 - struct bss_descriptor *iter_bss; 1158 - struct bss_descriptor *safe; 1159 - 1160 - lbs_deb_enter(LBS_DEB_WEXT); 1161 - 1162 - /* iwlist should wait until the current scan is finished */ 1163 - if (priv->scan_channel) 1164 - return -EAGAIN; 1165 - 1166 - /* Update RSSI if current BSS is a locally created ad-hoc BSS */ 1167 - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) { 1168 - err = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 1169 - CMD_OPTION_WAITFORRSP, 0, NULL); 1170 - if (err) 1171 - goto out; 1172 - } 1173 - 1174 - mutex_lock(&priv->lock); 1175 - list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { 1176 - char *next_ev; 1177 - unsigned long stale_time; 1178 - 1179 - if (stop - ev < SCAN_ITEM_SIZE) { 1180 - err = -E2BIG; 1181 - break; 1182 - } 1183 - 1184 - /* For mesh device, list only mesh networks */ 1185 - if (dev == priv->mesh_dev && !iter_bss->mesh) 1186 - continue; 1187 - 1188 - /* Prune old an old scan result */ 1189 - stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; 1190 - if (time_after(jiffies, stale_time)) { 1191 - list_move_tail(&iter_bss->list, &priv->network_free_list); 1192 - clear_bss_descriptor(iter_bss); 1193 - continue; 1194 - } 1195 - 1196 - /* Translate to WE format this entry */ 1197 - next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss); 1198 - if (next_ev == NULL) 1199 - continue; 1200 - ev = next_ev; 1201 - } 1202 - mutex_unlock(&priv->lock); 1203 - 1204 - dwrq->length = (ev - extra); 1205 - dwrq->flags = 0; 1206 - out: 1207 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err); 1208 - return err; 1209 - } 1210 - 1211 - 1212 - 1213 - 1214 - /*********************************************************************/ 1215 - /* */ 1216 - /* Command execution */ 1217 - /* */ 1218 - /*********************************************************************/ 1219 - 1220 - 1221 - /** 1222 - * @brief This function handles the command response of scan 1223 - * 1224 - * Called from handle_cmd_response() in cmdrespc. 1225 - * 1226 - * The response buffer for the scan command has the following 1227 - * memory layout: 1228 - * 1229 - * .-----------------------------------------------------------. 1230 - * | header (4 * sizeof(u16)): Standard command response hdr | 1231 - * .-----------------------------------------------------------. 1232 - * | bufsize (u16) : sizeof the BSS Description data | 1233 - * .-----------------------------------------------------------. 1234 - * | NumOfSet (u8) : Number of BSS Descs returned | 1235 - * .-----------------------------------------------------------. 1236 - * | BSSDescription data (variable, size given in bufsize) | 1237 - * .-----------------------------------------------------------. 1238 - * | TLV data (variable, size calculated using header->size, | 1239 - * | bufsize and sizeof the fixed fields above) | 1240 - * .-----------------------------------------------------------. 1241 - * 1242 - * @param priv A pointer to struct lbs_private structure 1243 - * @param resp A pointer to cmd_ds_command 1244 - * 1245 - * @return 0 or -1 1246 - */ 1247 - static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, 1248 - struct cmd_header *resp) 1249 - { 1250 - struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; 1251 - struct bss_descriptor *iter_bss; 1252 - struct bss_descriptor *safe; 1253 - uint8_t *bssinfo; 1254 - uint16_t scanrespsize; 1255 - int bytesleft; 1256 - int idx; 1257 - int tlvbufsize; 1258 - int ret; 1259 - 1260 - lbs_deb_enter(LBS_DEB_SCAN); 1261 - 1262 - /* Prune old entries from scan table */ 1263 - list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { 1264 - unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; 1265 - if (time_before(jiffies, stale_time)) 1266 - continue; 1267 - list_move_tail (&iter_bss->list, &priv->network_free_list); 1268 - clear_bss_descriptor(iter_bss); 1269 - } 1270 - 1271 - if (scanresp->nr_sets > MAX_NETWORK_COUNT) { 1272 - lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n", 1273 - scanresp->nr_sets, MAX_NETWORK_COUNT); 1274 - ret = -1; 1275 - goto done; 1276 - } 1277 - 1278 - bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize); 1279 - lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); 1280 - 1281 - scanrespsize = le16_to_cpu(resp->size); 1282 - lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets); 1283 - 1284 - bssinfo = scanresp->bssdesc_and_tlvbuffer; 1285 - 1286 - /* The size of the TLV buffer is equal to the entire command response 1287 - * size (scanrespsize) minus the fixed fields (sizeof()'s), the 1288 - * BSS Descriptions (bssdescriptsize as bytesLef) and the command 1289 - * response header (sizeof(struct cmd_header)) 1290 - */ 1291 - tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize) 1292 - + sizeof(scanresp->nr_sets) 1293 - + sizeof(struct cmd_header)); 1294 - 1295 - /* 1296 - * Process each scan response returned (scanresp->nr_sets). Save 1297 - * the information in the newbssentry and then insert into the 1298 - * driver scan table either as an update to an existing entry 1299 - * or as an addition at the end of the table 1300 - */ 1301 - for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) { 1302 - struct bss_descriptor new; 1303 - struct bss_descriptor *found = NULL; 1304 - struct bss_descriptor *oldest = NULL; 1305 - 1306 - /* Process the data fields and IEs returned for this BSS */ 1307 - memset(&new, 0, sizeof (struct bss_descriptor)); 1308 - if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) { 1309 - /* error parsing the scan response, skipped */ 1310 - lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); 1311 - continue; 1312 - } 1313 - 1314 - /* Try to find this bss in the scan table */ 1315 - list_for_each_entry (iter_bss, &priv->network_list, list) { 1316 - if (is_same_network(iter_bss, &new)) { 1317 - found = iter_bss; 1318 - break; 1319 - } 1320 - 1321 - if ((oldest == NULL) || 1322 - (iter_bss->last_scanned < oldest->last_scanned)) 1323 - oldest = iter_bss; 1324 - } 1325 - 1326 - if (found) { 1327 - /* found, clear it */ 1328 - clear_bss_descriptor(found); 1329 - } else if (!list_empty(&priv->network_free_list)) { 1330 - /* Pull one from the free list */ 1331 - found = list_entry(priv->network_free_list.next, 1332 - struct bss_descriptor, list); 1333 - list_move_tail(&found->list, &priv->network_list); 1334 - } else if (oldest) { 1335 - /* If there are no more slots, expire the oldest */ 1336 - found = oldest; 1337 - clear_bss_descriptor(found); 1338 - list_move_tail(&found->list, &priv->network_list); 1339 - } else { 1340 - continue; 1341 - } 1342 - 1343 - lbs_deb_scan("SCAN_RESP: BSSID %pM\n", new.bssid); 1344 - 1345 - /* Copy the locally created newbssentry to the scan table */ 1346 - memcpy(found, &new, offsetof(struct bss_descriptor, list)); 1347 - } 1348 - 1349 - ret = 0; 1350 - 1351 - done: 1352 - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 1353 - return ret; 1354 - }
-63
drivers/net/wireless/libertas/scan.h
··· 1 - /** 2 - * Interface for the wlan network scan routines 3 - * 4 - * Driver interface functions and type declarations for the scan module 5 - * implemented in scan.c. 6 - */ 7 - #ifndef _LBS_SCAN_H 8 - #define _LBS_SCAN_H 9 - 10 - #include <net/iw_handler.h> 11 - 12 - struct lbs_private; 13 - 14 - #define MAX_NETWORK_COUNT 128 15 - 16 - /** Chan-freq-TxPower mapping table*/ 17 - struct chan_freq_power { 18 - /** channel Number */ 19 - u16 channel; 20 - /** frequency of this channel */ 21 - u32 freq; 22 - /** Max allowed Tx power level */ 23 - u16 maxtxpower; 24 - /** TRUE:channel unsupported; FLASE:supported*/ 25 - u8 unsupported; 26 - }; 27 - 28 - /** region-band mapping table*/ 29 - struct region_channel { 30 - /** TRUE if this entry is valid */ 31 - u8 valid; 32 - /** region code for US, Japan ... */ 33 - u8 region; 34 - /** band B/G/A, used for BAND_CONFIG cmd */ 35 - u8 band; 36 - /** Actual No. of elements in the array below */ 37 - u8 nrcfp; 38 - /** chan-freq-txpower mapping table*/ 39 - struct chan_freq_power *CFP; 40 - }; 41 - 42 - /** 43 - * @brief Maximum number of channels that can be sent in a setuserscan ioctl 44 - */ 45 - #define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 46 - 47 - int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); 48 - 49 - int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band); 50 - 51 - int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, 52 - u8 ssid_len); 53 - 54 - int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, 55 - struct iw_point *dwrq, char *extra); 56 - int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, 57 - union iwreq_data *wrqu, char *extra); 58 - 59 - int lbs_scan_networks(struct lbs_private *priv, int full_scan); 60 - 61 - void lbs_scan_worker(struct work_struct *work); 62 - 63 - #endif
+7 -5
drivers/net/wireless/libertas/tx.c
··· 4 4 #include <linux/netdevice.h> 5 5 #include <linux/etherdevice.h> 6 6 #include <linux/sched.h> 7 + #include <net/cfg80211.h> 7 8 8 9 #include "host.h" 9 10 #include "radiotap.h" 10 11 #include "decl.h" 11 12 #include "defs.h" 12 13 #include "dev.h" 13 - #include "wext.h" 14 14 15 15 /** 16 16 * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE ··· 111 111 p802x_hdr = skb->data; 112 112 pkt_len = skb->len; 113 113 114 - if (dev == priv->rtap_net_dev) { 114 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 115 115 struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data; 116 116 117 117 /* set txpd fields from the radiotap header */ ··· 147 147 dev->stats.tx_packets++; 148 148 dev->stats.tx_bytes += skb->len; 149 149 150 - if (priv->monitormode) { 150 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 151 151 /* Keep the skb to echo it back once Tx feedback is 152 152 received from FW */ 153 153 skb_orphan(skb); ··· 158 158 free: 159 159 dev_kfree_skb_any(skb); 160 160 } 161 + 161 162 unlock: 162 163 spin_unlock_irqrestore(&priv->driver_lock, flags); 163 164 wake_up(&priv->waitq); ··· 180 179 { 181 180 struct tx_radiotap_hdr *radiotap_hdr; 182 181 183 - if (!priv->monitormode || priv->currenttxskb == NULL) 182 + if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR || 183 + priv->currenttxskb == NULL) 184 184 return; 185 185 186 186 radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data; ··· 190 188 (1 + priv->txretrycount - try_count) : 0; 191 189 192 190 priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb, 193 - priv->rtap_net_dev); 191 + priv->dev); 194 192 netif_rx(priv->currenttxskb); 195 193 196 194 priv->currenttxskb = NULL;
-2353
drivers/net/wireless/libertas/wext.c
··· 1 - /** 2 - * This file contains ioctl functions 3 - */ 4 - #include <linux/ctype.h> 5 - #include <linux/slab.h> 6 - #include <linux/delay.h> 7 - #include <linux/if.h> 8 - #include <linux/if_arp.h> 9 - #include <linux/wireless.h> 10 - #include <linux/bitops.h> 11 - 12 - #include <net/lib80211.h> 13 - #include <net/iw_handler.h> 14 - 15 - #include "host.h" 16 - #include "radiotap.h" 17 - #include "decl.h" 18 - #include "defs.h" 19 - #include "dev.h" 20 - #include "wext.h" 21 - #include "scan.h" 22 - #include "assoc.h" 23 - #include "cmd.h" 24 - 25 - 26 - static inline void lbs_postpone_association_work(struct lbs_private *priv) 27 - { 28 - if (priv->surpriseremoved) 29 - return; 30 - cancel_delayed_work(&priv->assoc_work); 31 - queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2); 32 - } 33 - 34 - static inline void lbs_do_association_work(struct lbs_private *priv) 35 - { 36 - if (priv->surpriseremoved) 37 - return; 38 - cancel_delayed_work(&priv->assoc_work); 39 - queue_delayed_work(priv->work_thread, &priv->assoc_work, 0); 40 - } 41 - 42 - static inline void lbs_cancel_association_work(struct lbs_private *priv) 43 - { 44 - cancel_delayed_work(&priv->assoc_work); 45 - kfree(priv->pending_assoc_req); 46 - priv->pending_assoc_req = NULL; 47 - } 48 - 49 - void lbs_send_disconnect_notification(struct lbs_private *priv) 50 - { 51 - union iwreq_data wrqu; 52 - 53 - memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); 54 - wrqu.ap_addr.sa_family = ARPHRD_ETHER; 55 - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 56 - } 57 - 58 - static void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str) 59 - { 60 - union iwreq_data iwrq; 61 - u8 buf[50]; 62 - 63 - lbs_deb_enter(LBS_DEB_WEXT); 64 - 65 - memset(&iwrq, 0, sizeof(union iwreq_data)); 66 - memset(buf, 0, sizeof(buf)); 67 - 68 - snprintf(buf, sizeof(buf) - 1, "%s", str); 69 - 70 - iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN; 71 - 72 - /* Send Event to upper layer */ 73 - lbs_deb_wext("event indication string %s\n", (char *)buf); 74 - lbs_deb_wext("event indication length %d\n", iwrq.data.length); 75 - lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str); 76 - 77 - wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf); 78 - 79 - lbs_deb_leave(LBS_DEB_WEXT); 80 - } 81 - 82 - /** 83 - * @brief This function handles MIC failure event. 84 - * 85 - * @param priv A pointer to struct lbs_private structure 86 - * @para event the event id 87 - * @return n/a 88 - */ 89 - void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) 90 - { 91 - char buf[50]; 92 - 93 - lbs_deb_enter(LBS_DEB_CMD); 94 - memset(buf, 0, sizeof(buf)); 95 - 96 - sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication "); 97 - 98 - if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) 99 - strcat(buf, "unicast "); 100 - else 101 - strcat(buf, "multicast "); 102 - 103 - lbs_send_iwevcustom_event(priv, buf); 104 - lbs_deb_leave(LBS_DEB_CMD); 105 - } 106 - 107 - /** 108 - * @brief Find the channel frequency power info with specific channel 109 - * 110 - * @param priv A pointer to struct lbs_private structure 111 - * @param band it can be BAND_A, BAND_G or BAND_B 112 - * @param channel the channel for looking 113 - * @return A pointer to struct chan_freq_power structure or NULL if not find. 114 - */ 115 - struct chan_freq_power *lbs_find_cfp_by_band_and_channel( 116 - struct lbs_private *priv, 117 - u8 band, 118 - u16 channel) 119 - { 120 - struct chan_freq_power *cfp = NULL; 121 - struct region_channel *rc; 122 - int i, j; 123 - 124 - for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) { 125 - rc = &priv->region_channel[j]; 126 - 127 - if (!rc->valid || !rc->CFP) 128 - continue; 129 - if (rc->band != band) 130 - continue; 131 - for (i = 0; i < rc->nrcfp; i++) { 132 - if (rc->CFP[i].channel == channel) { 133 - cfp = &rc->CFP[i]; 134 - break; 135 - } 136 - } 137 - } 138 - 139 - if (!cfp && channel) 140 - lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find " 141 - "cfp by band %d / channel %d\n", band, channel); 142 - 143 - return cfp; 144 - } 145 - 146 - /** 147 - * @brief Find the channel frequency power info with specific frequency 148 - * 149 - * @param priv A pointer to struct lbs_private structure 150 - * @param band it can be BAND_A, BAND_G or BAND_B 151 - * @param freq the frequency for looking 152 - * @return A pointer to struct chan_freq_power structure or NULL if not find. 153 - */ 154 - static struct chan_freq_power *find_cfp_by_band_and_freq( 155 - struct lbs_private *priv, 156 - u8 band, 157 - u32 freq) 158 - { 159 - struct chan_freq_power *cfp = NULL; 160 - struct region_channel *rc; 161 - int i, j; 162 - 163 - for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) { 164 - rc = &priv->region_channel[j]; 165 - 166 - if (!rc->valid || !rc->CFP) 167 - continue; 168 - if (rc->band != band) 169 - continue; 170 - for (i = 0; i < rc->nrcfp; i++) { 171 - if (rc->CFP[i].freq == freq) { 172 - cfp = &rc->CFP[i]; 173 - break; 174 - } 175 - } 176 - } 177 - 178 - if (!cfp && freq) 179 - lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by " 180 - "band %d / freq %d\n", band, freq); 181 - 182 - return cfp; 183 - } 184 - 185 - /** 186 - * @brief Copy active data rates based on adapter mode and status 187 - * 188 - * @param priv A pointer to struct lbs_private structure 189 - * @param rate The buf to return the active rates 190 - */ 191 - static void copy_active_data_rates(struct lbs_private *priv, u8 *rates) 192 - { 193 - lbs_deb_enter(LBS_DEB_WEXT); 194 - 195 - if ((priv->connect_status != LBS_CONNECTED) && 196 - !lbs_mesh_connected(priv)) 197 - memcpy(rates, lbs_bg_rates, MAX_RATES); 198 - else 199 - memcpy(rates, priv->curbssparams.rates, MAX_RATES); 200 - 201 - lbs_deb_leave(LBS_DEB_WEXT); 202 - } 203 - 204 - static int lbs_get_name(struct net_device *dev, struct iw_request_info *info, 205 - char *cwrq, char *extra) 206 - { 207 - 208 - lbs_deb_enter(LBS_DEB_WEXT); 209 - 210 - /* We could add support for 802.11n here as needed. Jean II */ 211 - snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g"); 212 - 213 - lbs_deb_leave(LBS_DEB_WEXT); 214 - return 0; 215 - } 216 - 217 - static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, 218 - struct iw_freq *fwrq, char *extra) 219 - { 220 - struct lbs_private *priv = dev->ml_priv; 221 - struct chan_freq_power *cfp; 222 - 223 - lbs_deb_enter(LBS_DEB_WEXT); 224 - 225 - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, 226 - priv->channel); 227 - 228 - if (!cfp) { 229 - if (priv->channel) 230 - lbs_deb_wext("invalid channel %d\n", 231 - priv->channel); 232 - return -EINVAL; 233 - } 234 - 235 - fwrq->m = (long)cfp->freq * 100000; 236 - fwrq->e = 1; 237 - 238 - lbs_deb_wext("freq %u\n", fwrq->m); 239 - lbs_deb_leave(LBS_DEB_WEXT); 240 - return 0; 241 - } 242 - 243 - static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, 244 - struct sockaddr *awrq, char *extra) 245 - { 246 - struct lbs_private *priv = dev->ml_priv; 247 - 248 - lbs_deb_enter(LBS_DEB_WEXT); 249 - 250 - if (priv->connect_status == LBS_CONNECTED) { 251 - memcpy(awrq->sa_data, priv->curbssparams.bssid, ETH_ALEN); 252 - } else { 253 - memset(awrq->sa_data, 0, ETH_ALEN); 254 - } 255 - awrq->sa_family = ARPHRD_ETHER; 256 - 257 - lbs_deb_leave(LBS_DEB_WEXT); 258 - return 0; 259 - } 260 - 261 - static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, 262 - struct iw_point *dwrq, char *extra) 263 - { 264 - struct lbs_private *priv = dev->ml_priv; 265 - 266 - lbs_deb_enter(LBS_DEB_WEXT); 267 - 268 - /* 269 - * Check the size of the string 270 - */ 271 - 272 - if (dwrq->length > 16) { 273 - return -E2BIG; 274 - } 275 - 276 - mutex_lock(&priv->lock); 277 - memset(priv->nodename, 0, sizeof(priv->nodename)); 278 - memcpy(priv->nodename, extra, dwrq->length); 279 - mutex_unlock(&priv->lock); 280 - 281 - lbs_deb_leave(LBS_DEB_WEXT); 282 - return 0; 283 - } 284 - 285 - static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, 286 - struct iw_point *dwrq, char *extra) 287 - { 288 - struct lbs_private *priv = dev->ml_priv; 289 - 290 - lbs_deb_enter(LBS_DEB_WEXT); 291 - 292 - dwrq->length = strlen(priv->nodename); 293 - memcpy(extra, priv->nodename, dwrq->length); 294 - extra[dwrq->length] = '\0'; 295 - 296 - dwrq->flags = 1; /* active */ 297 - 298 - lbs_deb_leave(LBS_DEB_WEXT); 299 - return 0; 300 - } 301 - 302 - #ifdef CONFIG_LIBERTAS_MESH 303 - static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, 304 - struct iw_point *dwrq, char *extra) 305 - { 306 - struct lbs_private *priv = dev->ml_priv; 307 - 308 - lbs_deb_enter(LBS_DEB_WEXT); 309 - 310 - /* Use nickname to indicate that mesh is on */ 311 - 312 - if (lbs_mesh_connected(priv)) { 313 - strncpy(extra, "Mesh", 12); 314 - extra[12] = '\0'; 315 - dwrq->length = strlen(extra); 316 - } 317 - 318 - else { 319 - extra[0] = '\0'; 320 - dwrq->length = 0; 321 - } 322 - 323 - lbs_deb_leave(LBS_DEB_WEXT); 324 - return 0; 325 - } 326 - #endif 327 - 328 - static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, 329 - struct iw_param *vwrq, char *extra) 330 - { 331 - int ret = 0; 332 - struct lbs_private *priv = dev->ml_priv; 333 - u32 val = vwrq->value; 334 - 335 - lbs_deb_enter(LBS_DEB_WEXT); 336 - 337 - if (vwrq->disabled) 338 - val = MRVDRV_RTS_MAX_VALUE; 339 - 340 - if (val > MRVDRV_RTS_MAX_VALUE) /* min rts value is 0 */ 341 - return -EINVAL; 342 - 343 - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, (u16) val); 344 - 345 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 346 - return ret; 347 - } 348 - 349 - static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, 350 - struct iw_param *vwrq, char *extra) 351 - { 352 - struct lbs_private *priv = dev->ml_priv; 353 - int ret = 0; 354 - u16 val = 0; 355 - 356 - lbs_deb_enter(LBS_DEB_WEXT); 357 - 358 - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val); 359 - if (ret) 360 - goto out; 361 - 362 - vwrq->value = val; 363 - vwrq->disabled = val > MRVDRV_RTS_MAX_VALUE; /* min rts value is 0 */ 364 - vwrq->fixed = 1; 365 - 366 - out: 367 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 368 - return ret; 369 - } 370 - 371 - static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, 372 - struct iw_param *vwrq, char *extra) 373 - { 374 - struct lbs_private *priv = dev->ml_priv; 375 - int ret = 0; 376 - u32 val = vwrq->value; 377 - 378 - lbs_deb_enter(LBS_DEB_WEXT); 379 - 380 - if (vwrq->disabled) 381 - val = MRVDRV_FRAG_MAX_VALUE; 382 - 383 - if (val < MRVDRV_FRAG_MIN_VALUE || val > MRVDRV_FRAG_MAX_VALUE) 384 - return -EINVAL; 385 - 386 - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, (u16) val); 387 - 388 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 389 - return ret; 390 - } 391 - 392 - static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, 393 - struct iw_param *vwrq, char *extra) 394 - { 395 - struct lbs_private *priv = dev->ml_priv; 396 - int ret = 0; 397 - u16 val = 0; 398 - 399 - lbs_deb_enter(LBS_DEB_WEXT); 400 - 401 - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val); 402 - if (ret) 403 - goto out; 404 - 405 - vwrq->value = val; 406 - vwrq->disabled = ((val < MRVDRV_FRAG_MIN_VALUE) 407 - || (val > MRVDRV_FRAG_MAX_VALUE)); 408 - vwrq->fixed = 1; 409 - 410 - out: 411 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 412 - return ret; 413 - } 414 - 415 - static int lbs_get_mode(struct net_device *dev, 416 - struct iw_request_info *info, u32 * uwrq, char *extra) 417 - { 418 - struct lbs_private *priv = dev->ml_priv; 419 - 420 - lbs_deb_enter(LBS_DEB_WEXT); 421 - 422 - *uwrq = priv->mode; 423 - 424 - lbs_deb_leave(LBS_DEB_WEXT); 425 - return 0; 426 - } 427 - 428 - #ifdef CONFIG_LIBERTAS_MESH 429 - static int mesh_wlan_get_mode(struct net_device *dev, 430 - struct iw_request_info *info, u32 * uwrq, 431 - char *extra) 432 - { 433 - lbs_deb_enter(LBS_DEB_WEXT); 434 - 435 - *uwrq = IW_MODE_REPEAT; 436 - 437 - lbs_deb_leave(LBS_DEB_WEXT); 438 - return 0; 439 - } 440 - #endif 441 - 442 - static int lbs_get_txpow(struct net_device *dev, 443 - struct iw_request_info *info, 444 - struct iw_param *vwrq, char *extra) 445 - { 446 - struct lbs_private *priv = dev->ml_priv; 447 - s16 curlevel = 0; 448 - int ret = 0; 449 - 450 - lbs_deb_enter(LBS_DEB_WEXT); 451 - 452 - if (!priv->radio_on) { 453 - lbs_deb_wext("tx power off\n"); 454 - vwrq->value = 0; 455 - vwrq->disabled = 1; 456 - goto out; 457 - } 458 - 459 - ret = lbs_get_tx_power(priv, &curlevel, NULL, NULL); 460 - if (ret) 461 - goto out; 462 - 463 - lbs_deb_wext("tx power level %d dbm\n", curlevel); 464 - priv->txpower_cur = curlevel; 465 - 466 - vwrq->value = curlevel; 467 - vwrq->fixed = 1; 468 - vwrq->disabled = 0; 469 - vwrq->flags = IW_TXPOW_DBM; 470 - 471 - out: 472 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 473 - return ret; 474 - } 475 - 476 - static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, 477 - struct iw_param *vwrq, char *extra) 478 - { 479 - struct lbs_private *priv = dev->ml_priv; 480 - int ret = 0; 481 - u16 slimit = 0, llimit = 0; 482 - 483 - lbs_deb_enter(LBS_DEB_WEXT); 484 - 485 - if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) 486 - return -EOPNOTSUPP; 487 - 488 - /* The MAC has a 4-bit Total_Tx_Count register 489 - Total_Tx_Count = 1 + Tx_Retry_Count */ 490 - #define TX_RETRY_MIN 0 491 - #define TX_RETRY_MAX 14 492 - if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX) 493 - return -EINVAL; 494 - 495 - /* Add 1 to convert retry count to try count */ 496 - if (vwrq->flags & IW_RETRY_SHORT) 497 - slimit = (u16) (vwrq->value + 1); 498 - else if (vwrq->flags & IW_RETRY_LONG) 499 - llimit = (u16) (vwrq->value + 1); 500 - else 501 - slimit = llimit = (u16) (vwrq->value + 1); /* set both */ 502 - 503 - if (llimit) { 504 - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT, 505 - llimit); 506 - if (ret) 507 - goto out; 508 - } 509 - 510 - if (slimit) { 511 - /* txretrycount follows the short retry limit */ 512 - priv->txretrycount = slimit; 513 - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT, 514 - slimit); 515 - if (ret) 516 - goto out; 517 - } 518 - 519 - out: 520 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 521 - return ret; 522 - } 523 - 524 - static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, 525 - struct iw_param *vwrq, char *extra) 526 - { 527 - struct lbs_private *priv = dev->ml_priv; 528 - int ret = 0; 529 - u16 val = 0; 530 - 531 - lbs_deb_enter(LBS_DEB_WEXT); 532 - 533 - vwrq->disabled = 0; 534 - 535 - if (vwrq->flags & IW_RETRY_LONG) { 536 - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT, &val); 537 - if (ret) 538 - goto out; 539 - 540 - /* Subtract 1 to convert try count to retry count */ 541 - vwrq->value = val - 1; 542 - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; 543 - } else { 544 - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT, &val); 545 - if (ret) 546 - goto out; 547 - 548 - /* txretry count follows the short retry limit */ 549 - priv->txretrycount = val; 550 - /* Subtract 1 to convert try count to retry count */ 551 - vwrq->value = val - 1; 552 - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; 553 - } 554 - 555 - out: 556 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 557 - return ret; 558 - } 559 - 560 - static inline void sort_channels(struct iw_freq *freq, int num) 561 - { 562 - int i, j; 563 - struct iw_freq temp; 564 - 565 - for (i = 0; i < num; i++) 566 - for (j = i + 1; j < num; j++) 567 - if (freq[i].i > freq[j].i) { 568 - temp.i = freq[i].i; 569 - temp.m = freq[i].m; 570 - 571 - freq[i].i = freq[j].i; 572 - freq[i].m = freq[j].m; 573 - 574 - freq[j].i = temp.i; 575 - freq[j].m = temp.m; 576 - } 577 - } 578 - 579 - /* data rate listing 580 - MULTI_BANDS: 581 - abg a b b/g 582 - Infra G(12) A(8) B(4) G(12) 583 - Adhoc A+B(12) A(8) B(4) B(4) 584 - 585 - non-MULTI_BANDS: 586 - b b/g 587 - Infra B(4) G(12) 588 - Adhoc B(4) B(4) 589 - */ 590 - /** 591 - * @brief Get Range Info 592 - * 593 - * @param dev A pointer to net_device structure 594 - * @param info A pointer to iw_request_info structure 595 - * @param vwrq A pointer to iw_param structure 596 - * @param extra A pointer to extra data buf 597 - * @return 0 --success, otherwise fail 598 - */ 599 - static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, 600 - struct iw_point *dwrq, char *extra) 601 - { 602 - int i, j; 603 - struct lbs_private *priv = dev->ml_priv; 604 - struct iw_range *range = (struct iw_range *)extra; 605 - struct chan_freq_power *cfp; 606 - u8 rates[MAX_RATES + 1]; 607 - 608 - lbs_deb_enter(LBS_DEB_WEXT); 609 - 610 - dwrq->length = sizeof(struct iw_range); 611 - memset(range, 0, sizeof(struct iw_range)); 612 - 613 - range->min_nwid = 0; 614 - range->max_nwid = 0; 615 - 616 - memset(rates, 0, sizeof(rates)); 617 - copy_active_data_rates(priv, rates); 618 - range->num_bitrates = strnlen(rates, IW_MAX_BITRATES); 619 - for (i = 0; i < range->num_bitrates; i++) 620 - range->bitrate[i] = rates[i] * 500000; 621 - range->num_bitrates = i; 622 - lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, 623 - range->num_bitrates); 624 - 625 - range->num_frequency = 0; 626 - 627 - range->scan_capa = IW_SCAN_CAPA_ESSID; 628 - 629 - for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES) 630 - && (j < ARRAY_SIZE(priv->region_channel)); j++) { 631 - cfp = priv->region_channel[j].CFP; 632 - for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES) 633 - && priv->region_channel[j].valid 634 - && cfp 635 - && (i < priv->region_channel[j].nrcfp); i++) { 636 - range->freq[range->num_frequency].i = 637 - (long)cfp->channel; 638 - range->freq[range->num_frequency].m = 639 - (long)cfp->freq * 100000; 640 - range->freq[range->num_frequency].e = 1; 641 - cfp++; 642 - range->num_frequency++; 643 - } 644 - } 645 - 646 - lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n", 647 - IW_MAX_FREQUENCIES, range->num_frequency); 648 - 649 - range->num_channels = range->num_frequency; 650 - 651 - sort_channels(&range->freq[0], range->num_frequency); 652 - 653 - /* 654 - * Set an indication of the max TCP throughput in bit/s that we can 655 - * expect using this interface 656 - */ 657 - if (i > 2) 658 - range->throughput = 5000 * 1000; 659 - else 660 - range->throughput = 1500 * 1000; 661 - 662 - range->min_rts = MRVDRV_RTS_MIN_VALUE; 663 - range->max_rts = MRVDRV_RTS_MAX_VALUE; 664 - range->min_frag = MRVDRV_FRAG_MIN_VALUE; 665 - range->max_frag = MRVDRV_FRAG_MAX_VALUE; 666 - 667 - range->encoding_size[0] = 5; 668 - range->encoding_size[1] = 13; 669 - range->num_encoding_sizes = 2; 670 - range->max_encoding_tokens = 4; 671 - 672 - /* 673 - * Right now we support only "iwconfig ethX power on|off" 674 - */ 675 - range->pm_capa = IW_POWER_ON; 676 - 677 - /* 678 - * Minimum version we recommend 679 - */ 680 - range->we_version_source = 15; 681 - 682 - /* 683 - * Version we are compiled with 684 - */ 685 - range->we_version_compiled = WIRELESS_EXT; 686 - 687 - range->retry_capa = IW_RETRY_LIMIT; 688 - range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 689 - 690 - range->min_retry = TX_RETRY_MIN; 691 - range->max_retry = TX_RETRY_MAX; 692 - 693 - /* 694 - * Set the qual, level and noise range values 695 - */ 696 - range->max_qual.qual = 100; 697 - range->max_qual.level = 0; 698 - range->max_qual.noise = 0; 699 - range->max_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 700 - 701 - range->avg_qual.qual = 70; 702 - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ 703 - range->avg_qual.level = 0; 704 - range->avg_qual.noise = 0; 705 - range->avg_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 706 - 707 - range->sensitivity = 0; 708 - 709 - /* Setup the supported power level ranges */ 710 - memset(range->txpower, 0, sizeof(range->txpower)); 711 - range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE; 712 - range->txpower[0] = priv->txpower_min; 713 - range->txpower[1] = priv->txpower_max; 714 - range->num_txpower = 2; 715 - 716 - range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 717 - IW_EVENT_CAPA_MASK(SIOCGIWAP) | 718 - IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); 719 - range->event_capa[1] = IW_EVENT_CAPA_K_1; 720 - 721 - if (priv->fwcapinfo & FW_CAPINFO_WPA) { 722 - range->enc_capa = IW_ENC_CAPA_WPA 723 - | IW_ENC_CAPA_WPA2 724 - | IW_ENC_CAPA_CIPHER_TKIP 725 - | IW_ENC_CAPA_CIPHER_CCMP; 726 - } 727 - 728 - lbs_deb_leave(LBS_DEB_WEXT); 729 - return 0; 730 - } 731 - 732 - static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, 733 - struct iw_param *vwrq, char *extra) 734 - { 735 - struct lbs_private *priv = dev->ml_priv; 736 - int ret = 0; 737 - 738 - lbs_deb_enter(LBS_DEB_WEXT); 739 - 740 - if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { 741 - if (vwrq->disabled) 742 - return 0; 743 - else 744 - return -EINVAL; 745 - } 746 - 747 - /* PS is currently supported only in Infrastructure mode 748 - * Remove this check if it is to be supported in IBSS mode also 749 - */ 750 - 751 - if (vwrq->disabled) { 752 - priv->psmode = LBS802_11POWERMODECAM; 753 - if (priv->psstate != PS_STATE_FULL_POWER) { 754 - lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 755 - } 756 - 757 - return 0; 758 - } 759 - 760 - if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 761 - lbs_deb_wext( 762 - "setting power timeout is not supported\n"); 763 - return -EINVAL; 764 - } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { 765 - vwrq->value = vwrq->value / 1000; 766 - if (!priv->enter_deep_sleep) { 767 - lbs_pr_err("deep sleep feature is not implemented " 768 - "for this interface driver\n"); 769 - return -EINVAL; 770 - } 771 - 772 - if (priv->connect_status == LBS_CONNECTED) { 773 - if ((priv->is_auto_deep_sleep_enabled) && 774 - (vwrq->value == -1000)) { 775 - lbs_exit_auto_deep_sleep(priv); 776 - return 0; 777 - } else { 778 - lbs_pr_err("can't use deep sleep cmd in " 779 - "connected state\n"); 780 - return -EINVAL; 781 - } 782 - } 783 - 784 - if ((vwrq->value < 0) && (vwrq->value != -1000)) { 785 - lbs_pr_err("unknown option\n"); 786 - return -EINVAL; 787 - } 788 - 789 - if (vwrq->value > 0) { 790 - if (!priv->is_auto_deep_sleep_enabled) { 791 - priv->is_activity_detected = 0; 792 - priv->auto_deep_sleep_timeout = vwrq->value; 793 - lbs_enter_auto_deep_sleep(priv); 794 - } else { 795 - priv->auto_deep_sleep_timeout = vwrq->value; 796 - lbs_deb_debugfs("auto deep sleep: " 797 - "already enabled\n"); 798 - } 799 - return 0; 800 - } else { 801 - if (priv->is_auto_deep_sleep_enabled) { 802 - lbs_exit_auto_deep_sleep(priv); 803 - /* Try to exit deep sleep if auto */ 804 - /*deep sleep disabled */ 805 - ret = lbs_set_deep_sleep(priv, 0); 806 - } 807 - if (vwrq->value == 0) 808 - ret = lbs_set_deep_sleep(priv, 1); 809 - else if (vwrq->value == -1000) 810 - ret = lbs_set_deep_sleep(priv, 0); 811 - return ret; 812 - } 813 - } 814 - 815 - if (priv->psmode != LBS802_11POWERMODECAM) { 816 - return 0; 817 - } 818 - 819 - priv->psmode = LBS802_11POWERMODEMAX_PSP; 820 - 821 - if (priv->connect_status == LBS_CONNECTED) { 822 - lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP); 823 - } 824 - 825 - lbs_deb_leave(LBS_DEB_WEXT); 826 - 827 - return 0; 828 - } 829 - 830 - static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, 831 - struct iw_param *vwrq, char *extra) 832 - { 833 - struct lbs_private *priv = dev->ml_priv; 834 - 835 - lbs_deb_enter(LBS_DEB_WEXT); 836 - 837 - vwrq->value = 0; 838 - vwrq->flags = 0; 839 - vwrq->disabled = priv->psmode == LBS802_11POWERMODECAM 840 - || priv->connect_status == LBS_DISCONNECTED; 841 - 842 - lbs_deb_leave(LBS_DEB_WEXT); 843 - return 0; 844 - } 845 - 846 - static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) 847 - { 848 - enum { 849 - POOR = 30, 850 - FAIR = 60, 851 - GOOD = 80, 852 - VERY_GOOD = 90, 853 - EXCELLENT = 95, 854 - PERFECT = 100 855 - }; 856 - struct lbs_private *priv = dev->ml_priv; 857 - u32 rssi_qual; 858 - u32 tx_qual; 859 - u32 quality = 0; 860 - int ret, stats_valid = 0; 861 - u8 rssi; 862 - u32 tx_retries; 863 - struct cmd_ds_802_11_get_log log; 864 - 865 - lbs_deb_enter(LBS_DEB_WEXT); 866 - 867 - priv->wstats.status = priv->mode; 868 - 869 - /* If we're not associated, all quality values are meaningless */ 870 - if ((priv->connect_status != LBS_CONNECTED) && 871 - !lbs_mesh_connected(priv)) 872 - goto out; 873 - 874 - /* Quality by RSSI */ 875 - priv->wstats.qual.level = 876 - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], 877 - priv->NF[TYPE_BEACON][TYPE_NOAVG]); 878 - 879 - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { 880 - priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; 881 - } else { 882 - priv->wstats.qual.noise = 883 - CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); 884 - } 885 - 886 - lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level); 887 - lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise); 888 - 889 - rssi = priv->wstats.qual.level - priv->wstats.qual.noise; 890 - if (rssi < 15) 891 - rssi_qual = rssi * POOR / 10; 892 - else if (rssi < 20) 893 - rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR; 894 - else if (rssi < 30) 895 - rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR; 896 - else if (rssi < 40) 897 - rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) / 898 - 10 + GOOD; 899 - else 900 - rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) / 901 - 10 + VERY_GOOD; 902 - quality = rssi_qual; 903 - 904 - /* Quality by TX errors */ 905 - priv->wstats.discard.retries = dev->stats.tx_errors; 906 - 907 - memset(&log, 0, sizeof(log)); 908 - log.hdr.size = cpu_to_le16(sizeof(log)); 909 - ret = lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log); 910 - if (ret) 911 - goto out; 912 - 913 - tx_retries = le32_to_cpu(log.retry); 914 - 915 - if (tx_retries > 75) 916 - tx_qual = (90 - tx_retries) * POOR / 15; 917 - else if (tx_retries > 70) 918 - tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR; 919 - else if (tx_retries > 65) 920 - tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; 921 - else if (tx_retries > 50) 922 - tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / 923 - 15 + GOOD; 924 - else 925 - tx_qual = (50 - tx_retries) * 926 - (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; 927 - quality = min(quality, tx_qual); 928 - 929 - priv->wstats.discard.code = le32_to_cpu(log.wepundecryptable); 930 - priv->wstats.discard.retries = tx_retries; 931 - priv->wstats.discard.misc = le32_to_cpu(log.ackfailure); 932 - 933 - /* Calculate quality */ 934 - priv->wstats.qual.qual = min_t(u8, quality, 100); 935 - priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 936 - stats_valid = 1; 937 - 938 - /* update stats asynchronously for future calls */ 939 - ret = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 940 - 0, 0, NULL); 941 - if (ret) 942 - lbs_pr_err("RSSI command failed\n"); 943 - out: 944 - if (!stats_valid) { 945 - priv->wstats.miss.beacon = 0; 946 - priv->wstats.discard.retries = 0; 947 - priv->wstats.qual.qual = 0; 948 - priv->wstats.qual.level = 0; 949 - priv->wstats.qual.noise = 0; 950 - priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED; 951 - priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID | 952 - IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 953 - } 954 - 955 - lbs_deb_leave(LBS_DEB_WEXT); 956 - return &priv->wstats; 957 - 958 - 959 - } 960 - 961 - static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info, 962 - struct iw_freq *fwrq, char *extra) 963 - { 964 - int ret = -EINVAL; 965 - struct lbs_private *priv = dev->ml_priv; 966 - struct chan_freq_power *cfp; 967 - struct assoc_request * assoc_req; 968 - 969 - lbs_deb_enter(LBS_DEB_WEXT); 970 - 971 - mutex_lock(&priv->lock); 972 - assoc_req = lbs_get_association_request(priv); 973 - if (!assoc_req) { 974 - ret = -ENOMEM; 975 - goto out; 976 - } 977 - 978 - /* If setting by frequency, convert to a channel */ 979 - if (fwrq->e == 1) { 980 - long f = fwrq->m / 100000; 981 - 982 - cfp = find_cfp_by_band_and_freq(priv, 0, f); 983 - if (!cfp) { 984 - lbs_deb_wext("invalid freq %ld\n", f); 985 - goto out; 986 - } 987 - 988 - fwrq->e = 0; 989 - fwrq->m = (int) cfp->channel; 990 - } 991 - 992 - /* Setting by channel number */ 993 - if (fwrq->m > 1000 || fwrq->e > 0) { 994 - goto out; 995 - } 996 - 997 - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m); 998 - if (!cfp) { 999 - goto out; 1000 - } 1001 - 1002 - assoc_req->channel = fwrq->m; 1003 - ret = 0; 1004 - 1005 - out: 1006 - if (ret == 0) { 1007 - set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags); 1008 - lbs_postpone_association_work(priv); 1009 - } else { 1010 - lbs_cancel_association_work(priv); 1011 - } 1012 - mutex_unlock(&priv->lock); 1013 - 1014 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1015 - return ret; 1016 - } 1017 - 1018 - #ifdef CONFIG_LIBERTAS_MESH 1019 - static int lbs_mesh_set_freq(struct net_device *dev, 1020 - struct iw_request_info *info, 1021 - struct iw_freq *fwrq, char *extra) 1022 - { 1023 - struct lbs_private *priv = dev->ml_priv; 1024 - struct chan_freq_power *cfp; 1025 - int ret = -EINVAL; 1026 - 1027 - lbs_deb_enter(LBS_DEB_WEXT); 1028 - 1029 - /* If setting by frequency, convert to a channel */ 1030 - if (fwrq->e == 1) { 1031 - long f = fwrq->m / 100000; 1032 - 1033 - cfp = find_cfp_by_band_and_freq(priv, 0, f); 1034 - if (!cfp) { 1035 - lbs_deb_wext("invalid freq %ld\n", f); 1036 - goto out; 1037 - } 1038 - 1039 - fwrq->e = 0; 1040 - fwrq->m = (int) cfp->channel; 1041 - } 1042 - 1043 - /* Setting by channel number */ 1044 - if (fwrq->m > 1000 || fwrq->e > 0) { 1045 - goto out; 1046 - } 1047 - 1048 - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m); 1049 - if (!cfp) { 1050 - goto out; 1051 - } 1052 - 1053 - if (fwrq->m != priv->channel) { 1054 - lbs_deb_wext("mesh channel change forces eth disconnect\n"); 1055 - if (priv->mode == IW_MODE_INFRA) 1056 - lbs_cmd_80211_deauthenticate(priv, 1057 - priv->curbssparams.bssid, 1058 - WLAN_REASON_DEAUTH_LEAVING); 1059 - else if (priv->mode == IW_MODE_ADHOC) 1060 - lbs_adhoc_stop(priv); 1061 - } 1062 - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m); 1063 - lbs_update_channel(priv); 1064 - ret = 0; 1065 - 1066 - out: 1067 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1068 - return ret; 1069 - } 1070 - #endif 1071 - 1072 - static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, 1073 - struct iw_param *vwrq, char *extra) 1074 - { 1075 - struct lbs_private *priv = dev->ml_priv; 1076 - u8 new_rate = 0; 1077 - int ret = -EINVAL; 1078 - u8 rates[MAX_RATES + 1]; 1079 - 1080 - lbs_deb_enter(LBS_DEB_WEXT); 1081 - 1082 - lbs_deb_wext("vwrq->value %d\n", vwrq->value); 1083 - lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed); 1084 - 1085 - if (vwrq->fixed && vwrq->value == -1) 1086 - goto out; 1087 - 1088 - /* Auto rate? */ 1089 - priv->enablehwauto = !vwrq->fixed; 1090 - 1091 - if (vwrq->value == -1) 1092 - priv->cur_rate = 0; 1093 - else { 1094 - if (vwrq->value % 100000) 1095 - goto out; 1096 - 1097 - new_rate = vwrq->value / 500000; 1098 - priv->cur_rate = new_rate; 1099 - /* the rest is only needed for lbs_set_data_rate() */ 1100 - memset(rates, 0, sizeof(rates)); 1101 - copy_active_data_rates(priv, rates); 1102 - if (!memchr(rates, new_rate, sizeof(rates))) { 1103 - lbs_pr_alert("fixed data rate 0x%X out of range\n", 1104 - new_rate); 1105 - goto out; 1106 - } 1107 - if (priv->fwrelease < 0x09000000) { 1108 - ret = lbs_set_power_adapt_cfg(priv, 0, 1109 - POW_ADAPT_DEFAULT_P0, 1110 - POW_ADAPT_DEFAULT_P1, 1111 - POW_ADAPT_DEFAULT_P2); 1112 - if (ret) 1113 - goto out; 1114 - } 1115 - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, 1116 - TPC_DEFAULT_P2, 1); 1117 - if (ret) 1118 - goto out; 1119 - } 1120 - 1121 - /* Try the newer command first (Firmware Spec 5.1 and above) */ 1122 - ret = lbs_cmd_802_11_rate_adapt_rateset(priv, CMD_ACT_SET); 1123 - 1124 - /* Fallback to older version */ 1125 - if (ret) 1126 - ret = lbs_set_data_rate(priv, new_rate); 1127 - 1128 - out: 1129 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1130 - return ret; 1131 - } 1132 - 1133 - static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, 1134 - struct iw_param *vwrq, char *extra) 1135 - { 1136 - struct lbs_private *priv = dev->ml_priv; 1137 - 1138 - lbs_deb_enter(LBS_DEB_WEXT); 1139 - 1140 - if (priv->connect_status == LBS_CONNECTED) { 1141 - vwrq->value = priv->cur_rate * 500000; 1142 - 1143 - if (priv->enablehwauto) 1144 - vwrq->fixed = 0; 1145 - else 1146 - vwrq->fixed = 1; 1147 - 1148 - } else { 1149 - vwrq->fixed = 0; 1150 - vwrq->value = 0; 1151 - } 1152 - 1153 - lbs_deb_leave(LBS_DEB_WEXT); 1154 - return 0; 1155 - } 1156 - 1157 - static int lbs_set_mode(struct net_device *dev, 1158 - struct iw_request_info *info, u32 * uwrq, char *extra) 1159 - { 1160 - int ret = 0; 1161 - struct lbs_private *priv = dev->ml_priv; 1162 - struct assoc_request * assoc_req; 1163 - 1164 - lbs_deb_enter(LBS_DEB_WEXT); 1165 - 1166 - if ( (*uwrq != IW_MODE_ADHOC) 1167 - && (*uwrq != IW_MODE_INFRA) 1168 - && (*uwrq != IW_MODE_AUTO)) { 1169 - lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq); 1170 - ret = -EINVAL; 1171 - goto out; 1172 - } 1173 - 1174 - mutex_lock(&priv->lock); 1175 - assoc_req = lbs_get_association_request(priv); 1176 - if (!assoc_req) { 1177 - ret = -ENOMEM; 1178 - lbs_cancel_association_work(priv); 1179 - } else { 1180 - assoc_req->mode = *uwrq; 1181 - set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); 1182 - lbs_postpone_association_work(priv); 1183 - lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq); 1184 - } 1185 - mutex_unlock(&priv->lock); 1186 - 1187 - out: 1188 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1189 - return ret; 1190 - } 1191 - 1192 - 1193 - /** 1194 - * @brief Get Encryption key 1195 - * 1196 - * @param dev A pointer to net_device structure 1197 - * @param info A pointer to iw_request_info structure 1198 - * @param vwrq A pointer to iw_param structure 1199 - * @param extra A pointer to extra data buf 1200 - * @return 0 --success, otherwise fail 1201 - */ 1202 - static int lbs_get_encode(struct net_device *dev, 1203 - struct iw_request_info *info, 1204 - struct iw_point *dwrq, u8 * extra) 1205 - { 1206 - struct lbs_private *priv = dev->ml_priv; 1207 - int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 1208 - 1209 - lbs_deb_enter(LBS_DEB_WEXT); 1210 - 1211 - lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n", 1212 - dwrq->flags, index, dwrq->length, priv->wep_tx_keyidx); 1213 - 1214 - dwrq->flags = 0; 1215 - 1216 - /* Authentication method */ 1217 - switch (priv->secinfo.auth_mode) { 1218 - case IW_AUTH_ALG_OPEN_SYSTEM: 1219 - dwrq->flags = IW_ENCODE_OPEN; 1220 - break; 1221 - 1222 - case IW_AUTH_ALG_SHARED_KEY: 1223 - case IW_AUTH_ALG_LEAP: 1224 - dwrq->flags = IW_ENCODE_RESTRICTED; 1225 - break; 1226 - default: 1227 - dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN; 1228 - break; 1229 - } 1230 - 1231 - memset(extra, 0, 16); 1232 - 1233 - mutex_lock(&priv->lock); 1234 - 1235 - /* Default to returning current transmit key */ 1236 - if (index < 0) 1237 - index = priv->wep_tx_keyidx; 1238 - 1239 - if ((priv->wep_keys[index].len) && priv->secinfo.wep_enabled) { 1240 - memcpy(extra, priv->wep_keys[index].key, 1241 - priv->wep_keys[index].len); 1242 - dwrq->length = priv->wep_keys[index].len; 1243 - 1244 - dwrq->flags |= (index + 1); 1245 - /* Return WEP enabled */ 1246 - dwrq->flags &= ~IW_ENCODE_DISABLED; 1247 - } else if ((priv->secinfo.WPAenabled) 1248 - || (priv->secinfo.WPA2enabled)) { 1249 - /* return WPA enabled */ 1250 - dwrq->flags &= ~IW_ENCODE_DISABLED; 1251 - dwrq->flags |= IW_ENCODE_NOKEY; 1252 - } else { 1253 - dwrq->flags |= IW_ENCODE_DISABLED; 1254 - } 1255 - 1256 - mutex_unlock(&priv->lock); 1257 - 1258 - lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n", 1259 - extra[0], extra[1], extra[2], 1260 - extra[3], extra[4], extra[5], dwrq->length); 1261 - 1262 - lbs_deb_wext("return flags 0x%x\n", dwrq->flags); 1263 - 1264 - lbs_deb_leave(LBS_DEB_WEXT); 1265 - return 0; 1266 - } 1267 - 1268 - /** 1269 - * @brief Set Encryption key (internal) 1270 - * 1271 - * @param priv A pointer to private card structure 1272 - * @param key_material A pointer to key material 1273 - * @param key_length length of key material 1274 - * @param index key index to set 1275 - * @param set_tx_key Force set TX key (1 = yes, 0 = no) 1276 - * @return 0 --success, otherwise fail 1277 - */ 1278 - static int lbs_set_wep_key(struct assoc_request *assoc_req, 1279 - const char *key_material, 1280 - u16 key_length, 1281 - u16 index, 1282 - int set_tx_key) 1283 - { 1284 - int ret = 0; 1285 - struct enc_key *pkey; 1286 - 1287 - lbs_deb_enter(LBS_DEB_WEXT); 1288 - 1289 - /* Paranoid validation of key index */ 1290 - if (index > 3) { 1291 - ret = -EINVAL; 1292 - goto out; 1293 - } 1294 - 1295 - /* validate max key length */ 1296 - if (key_length > KEY_LEN_WEP_104) { 1297 - ret = -EINVAL; 1298 - goto out; 1299 - } 1300 - 1301 - pkey = &assoc_req->wep_keys[index]; 1302 - 1303 - if (key_length > 0) { 1304 - memset(pkey, 0, sizeof(struct enc_key)); 1305 - pkey->type = KEY_TYPE_ID_WEP; 1306 - 1307 - /* Standardize the key length */ 1308 - pkey->len = (key_length > KEY_LEN_WEP_40) ? 1309 - KEY_LEN_WEP_104 : KEY_LEN_WEP_40; 1310 - memcpy(pkey->key, key_material, key_length); 1311 - } 1312 - 1313 - if (set_tx_key) { 1314 - /* Ensure the chosen key is valid */ 1315 - if (!pkey->len) { 1316 - lbs_deb_wext("key not set, so cannot enable it\n"); 1317 - ret = -EINVAL; 1318 - goto out; 1319 - } 1320 - assoc_req->wep_tx_keyidx = index; 1321 - } 1322 - 1323 - assoc_req->secinfo.wep_enabled = 1; 1324 - 1325 - out: 1326 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1327 - return ret; 1328 - } 1329 - 1330 - static int validate_key_index(u16 def_index, u16 raw_index, 1331 - u16 *out_index, u16 *is_default) 1332 - { 1333 - if (!out_index || !is_default) 1334 - return -EINVAL; 1335 - 1336 - /* Verify index if present, otherwise use default TX key index */ 1337 - if (raw_index > 0) { 1338 - if (raw_index > 4) 1339 - return -EINVAL; 1340 - *out_index = raw_index - 1; 1341 - } else { 1342 - *out_index = def_index; 1343 - *is_default = 1; 1344 - } 1345 - return 0; 1346 - } 1347 - 1348 - static void disable_wep(struct assoc_request *assoc_req) 1349 - { 1350 - int i; 1351 - 1352 - lbs_deb_enter(LBS_DEB_WEXT); 1353 - 1354 - /* Set Open System auth mode */ 1355 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1356 - 1357 - /* Clear WEP keys and mark WEP as disabled */ 1358 - assoc_req->secinfo.wep_enabled = 0; 1359 - for (i = 0; i < 4; i++) 1360 - assoc_req->wep_keys[i].len = 0; 1361 - 1362 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1363 - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1364 - 1365 - lbs_deb_leave(LBS_DEB_WEXT); 1366 - } 1367 - 1368 - static void disable_wpa(struct assoc_request *assoc_req) 1369 - { 1370 - lbs_deb_enter(LBS_DEB_WEXT); 1371 - 1372 - memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_key)); 1373 - assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST; 1374 - set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); 1375 - 1376 - memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key)); 1377 - assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST; 1378 - set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); 1379 - 1380 - assoc_req->secinfo.WPAenabled = 0; 1381 - assoc_req->secinfo.WPA2enabled = 0; 1382 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1383 - 1384 - lbs_deb_leave(LBS_DEB_WEXT); 1385 - } 1386 - 1387 - /** 1388 - * @brief Set Encryption key 1389 - * 1390 - * @param dev A pointer to net_device structure 1391 - * @param info A pointer to iw_request_info structure 1392 - * @param vwrq A pointer to iw_param structure 1393 - * @param extra A pointer to extra data buf 1394 - * @return 0 --success, otherwise fail 1395 - */ 1396 - static int lbs_set_encode(struct net_device *dev, 1397 - struct iw_request_info *info, 1398 - struct iw_point *dwrq, char *extra) 1399 - { 1400 - int ret = 0; 1401 - struct lbs_private *priv = dev->ml_priv; 1402 - struct assoc_request * assoc_req; 1403 - u16 is_default = 0, index = 0, set_tx_key = 0; 1404 - 1405 - lbs_deb_enter(LBS_DEB_WEXT); 1406 - 1407 - mutex_lock(&priv->lock); 1408 - assoc_req = lbs_get_association_request(priv); 1409 - if (!assoc_req) { 1410 - ret = -ENOMEM; 1411 - goto out; 1412 - } 1413 - 1414 - if (dwrq->flags & IW_ENCODE_DISABLED) { 1415 - disable_wep (assoc_req); 1416 - disable_wpa (assoc_req); 1417 - goto out; 1418 - } 1419 - 1420 - ret = validate_key_index(assoc_req->wep_tx_keyidx, 1421 - (dwrq->flags & IW_ENCODE_INDEX), 1422 - &index, &is_default); 1423 - if (ret) { 1424 - ret = -EINVAL; 1425 - goto out; 1426 - } 1427 - 1428 - /* If WEP isn't enabled, or if there is no key data but a valid 1429 - * index, set the TX key. 1430 - */ 1431 - if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default)) 1432 - set_tx_key = 1; 1433 - 1434 - ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); 1435 - if (ret) 1436 - goto out; 1437 - 1438 - if (dwrq->length) 1439 - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1440 - if (set_tx_key) 1441 - set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); 1442 - 1443 - if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1444 - priv->authtype_auto = 0; 1445 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1446 - } else if (dwrq->flags & IW_ENCODE_OPEN) { 1447 - priv->authtype_auto = 0; 1448 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1449 - } 1450 - 1451 - out: 1452 - if (ret == 0) { 1453 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1454 - lbs_postpone_association_work(priv); 1455 - } else { 1456 - lbs_cancel_association_work(priv); 1457 - } 1458 - mutex_unlock(&priv->lock); 1459 - 1460 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1461 - return ret; 1462 - } 1463 - 1464 - /** 1465 - * @brief Get Extended Encryption key (WPA/802.1x and WEP) 1466 - * 1467 - * @param dev A pointer to net_device structure 1468 - * @param info A pointer to iw_request_info structure 1469 - * @param vwrq A pointer to iw_param structure 1470 - * @param extra A pointer to extra data buf 1471 - * @return 0 on success, otherwise failure 1472 - */ 1473 - static int lbs_get_encodeext(struct net_device *dev, 1474 - struct iw_request_info *info, 1475 - struct iw_point *dwrq, 1476 - char *extra) 1477 - { 1478 - int ret = -EINVAL; 1479 - struct lbs_private *priv = dev->ml_priv; 1480 - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1481 - int index, max_key_len; 1482 - 1483 - lbs_deb_enter(LBS_DEB_WEXT); 1484 - 1485 - max_key_len = dwrq->length - sizeof(*ext); 1486 - if (max_key_len < 0) 1487 - goto out; 1488 - 1489 - index = dwrq->flags & IW_ENCODE_INDEX; 1490 - if (index) { 1491 - if (index < 1 || index > 4) 1492 - goto out; 1493 - index--; 1494 - } else { 1495 - index = priv->wep_tx_keyidx; 1496 - } 1497 - 1498 - if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && 1499 - ext->alg != IW_ENCODE_ALG_WEP) { 1500 - if (index != 0 || priv->mode != IW_MODE_INFRA) 1501 - goto out; 1502 - } 1503 - 1504 - dwrq->flags = index + 1; 1505 - memset(ext, 0, sizeof(*ext)); 1506 - 1507 - if ( !priv->secinfo.wep_enabled 1508 - && !priv->secinfo.WPAenabled 1509 - && !priv->secinfo.WPA2enabled) { 1510 - ext->alg = IW_ENCODE_ALG_NONE; 1511 - ext->key_len = 0; 1512 - dwrq->flags |= IW_ENCODE_DISABLED; 1513 - } else { 1514 - u8 *key = NULL; 1515 - 1516 - if ( priv->secinfo.wep_enabled 1517 - && !priv->secinfo.WPAenabled 1518 - && !priv->secinfo.WPA2enabled) { 1519 - /* WEP */ 1520 - ext->alg = IW_ENCODE_ALG_WEP; 1521 - ext->key_len = priv->wep_keys[index].len; 1522 - key = &priv->wep_keys[index].key[0]; 1523 - } else if ( !priv->secinfo.wep_enabled 1524 - && (priv->secinfo.WPAenabled || 1525 - priv->secinfo.WPA2enabled)) { 1526 - /* WPA */ 1527 - struct enc_key * pkey = NULL; 1528 - 1529 - if ( priv->wpa_mcast_key.len 1530 - && (priv->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED)) 1531 - pkey = &priv->wpa_mcast_key; 1532 - else if ( priv->wpa_unicast_key.len 1533 - && (priv->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED)) 1534 - pkey = &priv->wpa_unicast_key; 1535 - 1536 - if (pkey) { 1537 - if (pkey->type == KEY_TYPE_ID_AES) { 1538 - ext->alg = IW_ENCODE_ALG_CCMP; 1539 - } else { 1540 - ext->alg = IW_ENCODE_ALG_TKIP; 1541 - } 1542 - ext->key_len = pkey->len; 1543 - key = &pkey->key[0]; 1544 - } else { 1545 - ext->alg = IW_ENCODE_ALG_TKIP; 1546 - ext->key_len = 0; 1547 - } 1548 - } else { 1549 - goto out; 1550 - } 1551 - 1552 - if (ext->key_len > max_key_len) { 1553 - ret = -E2BIG; 1554 - goto out; 1555 - } 1556 - 1557 - if (ext->key_len) 1558 - memcpy(ext->key, key, ext->key_len); 1559 - else 1560 - dwrq->flags |= IW_ENCODE_NOKEY; 1561 - dwrq->flags |= IW_ENCODE_ENABLED; 1562 - } 1563 - ret = 0; 1564 - 1565 - out: 1566 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1567 - return ret; 1568 - } 1569 - 1570 - /** 1571 - * @brief Set Encryption key Extended (WPA/802.1x and WEP) 1572 - * 1573 - * @param dev A pointer to net_device structure 1574 - * @param info A pointer to iw_request_info structure 1575 - * @param vwrq A pointer to iw_param structure 1576 - * @param extra A pointer to extra data buf 1577 - * @return 0 --success, otherwise fail 1578 - */ 1579 - static int lbs_set_encodeext(struct net_device *dev, 1580 - struct iw_request_info *info, 1581 - struct iw_point *dwrq, 1582 - char *extra) 1583 - { 1584 - int ret = 0; 1585 - struct lbs_private *priv = dev->ml_priv; 1586 - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1587 - int alg = ext->alg; 1588 - struct assoc_request * assoc_req; 1589 - 1590 - lbs_deb_enter(LBS_DEB_WEXT); 1591 - 1592 - mutex_lock(&priv->lock); 1593 - assoc_req = lbs_get_association_request(priv); 1594 - if (!assoc_req) { 1595 - ret = -ENOMEM; 1596 - goto out; 1597 - } 1598 - 1599 - if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) { 1600 - disable_wep (assoc_req); 1601 - disable_wpa (assoc_req); 1602 - } else if (alg == IW_ENCODE_ALG_WEP) { 1603 - u16 is_default = 0, index, set_tx_key = 0; 1604 - 1605 - ret = validate_key_index(assoc_req->wep_tx_keyidx, 1606 - (dwrq->flags & IW_ENCODE_INDEX), 1607 - &index, &is_default); 1608 - if (ret) 1609 - goto out; 1610 - 1611 - /* If WEP isn't enabled, or if there is no key data but a valid 1612 - * index, or if the set-TX-key flag was passed, set the TX key. 1613 - */ 1614 - if ( !assoc_req->secinfo.wep_enabled 1615 - || (dwrq->length == 0 && !is_default) 1616 - || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) 1617 - set_tx_key = 1; 1618 - 1619 - /* Copy key to driver */ 1620 - ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index, 1621 - set_tx_key); 1622 - if (ret) 1623 - goto out; 1624 - 1625 - if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1626 - priv->authtype_auto = 0; 1627 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1628 - } else if (dwrq->flags & IW_ENCODE_OPEN) { 1629 - priv->authtype_auto = 0; 1630 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1631 - } 1632 - 1633 - /* Mark the various WEP bits as modified */ 1634 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1635 - if (dwrq->length) 1636 - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1637 - if (set_tx_key) 1638 - set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); 1639 - } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { 1640 - struct enc_key * pkey; 1641 - 1642 - /* validate key length */ 1643 - if (((alg == IW_ENCODE_ALG_TKIP) 1644 - && (ext->key_len != KEY_LEN_WPA_TKIP)) 1645 - || ((alg == IW_ENCODE_ALG_CCMP) 1646 - && (ext->key_len != KEY_LEN_WPA_AES))) { 1647 - lbs_deb_wext("invalid size %d for key of alg " 1648 - "type %d\n", 1649 - ext->key_len, 1650 - alg); 1651 - ret = -EINVAL; 1652 - goto out; 1653 - } 1654 - 1655 - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 1656 - pkey = &assoc_req->wpa_mcast_key; 1657 - set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); 1658 - } else { 1659 - pkey = &assoc_req->wpa_unicast_key; 1660 - set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); 1661 - } 1662 - 1663 - memset(pkey, 0, sizeof (struct enc_key)); 1664 - memcpy(pkey->key, ext->key, ext->key_len); 1665 - pkey->len = ext->key_len; 1666 - if (pkey->len) 1667 - pkey->flags |= KEY_INFO_WPA_ENABLED; 1668 - 1669 - /* Do this after zeroing key structure */ 1670 - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 1671 - pkey->flags |= KEY_INFO_WPA_MCAST; 1672 - } else { 1673 - pkey->flags |= KEY_INFO_WPA_UNICAST; 1674 - } 1675 - 1676 - if (alg == IW_ENCODE_ALG_TKIP) { 1677 - pkey->type = KEY_TYPE_ID_TKIP; 1678 - } else if (alg == IW_ENCODE_ALG_CCMP) { 1679 - pkey->type = KEY_TYPE_ID_AES; 1680 - } 1681 - 1682 - /* If WPA isn't enabled yet, do that now */ 1683 - if ( assoc_req->secinfo.WPAenabled == 0 1684 - && assoc_req->secinfo.WPA2enabled == 0) { 1685 - assoc_req->secinfo.WPAenabled = 1; 1686 - assoc_req->secinfo.WPA2enabled = 1; 1687 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1688 - } 1689 - 1690 - /* Only disable wep if necessary: can't waste time here. */ 1691 - if (priv->mac_control & CMD_ACT_MAC_WEP_ENABLE) 1692 - disable_wep(assoc_req); 1693 - } 1694 - 1695 - out: 1696 - if (ret == 0) { 1697 - /* 802.1x and WPA rekeying must happen as quickly as possible, 1698 - * especially during the 4-way handshake; thus if in 1699 - * infrastructure mode, and either (a) 802.1x is enabled or 1700 - * (b) WPA is being used, set the key right away. 1701 - */ 1702 - if (assoc_req->mode == IW_MODE_INFRA && 1703 - ((assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_802_1X) || 1704 - (assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_PSK) || 1705 - assoc_req->secinfo.WPAenabled || 1706 - assoc_req->secinfo.WPA2enabled)) { 1707 - lbs_do_association_work(priv); 1708 - } else 1709 - lbs_postpone_association_work(priv); 1710 - } else { 1711 - lbs_cancel_association_work(priv); 1712 - } 1713 - mutex_unlock(&priv->lock); 1714 - 1715 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1716 - return ret; 1717 - } 1718 - 1719 - 1720 - static int lbs_set_genie(struct net_device *dev, 1721 - struct iw_request_info *info, 1722 - struct iw_point *dwrq, 1723 - char *extra) 1724 - { 1725 - struct lbs_private *priv = dev->ml_priv; 1726 - int ret = 0; 1727 - struct assoc_request * assoc_req; 1728 - 1729 - lbs_deb_enter(LBS_DEB_WEXT); 1730 - 1731 - mutex_lock(&priv->lock); 1732 - assoc_req = lbs_get_association_request(priv); 1733 - if (!assoc_req) { 1734 - ret = -ENOMEM; 1735 - goto out; 1736 - } 1737 - 1738 - if (dwrq->length > MAX_WPA_IE_LEN || 1739 - (dwrq->length && extra == NULL)) { 1740 - ret = -EINVAL; 1741 - goto out; 1742 - } 1743 - 1744 - if (dwrq->length) { 1745 - memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length); 1746 - assoc_req->wpa_ie_len = dwrq->length; 1747 - } else { 1748 - memset(&assoc_req->wpa_ie[0], 0, sizeof(priv->wpa_ie)); 1749 - assoc_req->wpa_ie_len = 0; 1750 - } 1751 - 1752 - out: 1753 - if (ret == 0) { 1754 - set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags); 1755 - lbs_postpone_association_work(priv); 1756 - } else { 1757 - lbs_cancel_association_work(priv); 1758 - } 1759 - mutex_unlock(&priv->lock); 1760 - 1761 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1762 - return ret; 1763 - } 1764 - 1765 - static int lbs_get_genie(struct net_device *dev, 1766 - struct iw_request_info *info, 1767 - struct iw_point *dwrq, 1768 - char *extra) 1769 - { 1770 - int ret = 0; 1771 - struct lbs_private *priv = dev->ml_priv; 1772 - 1773 - lbs_deb_enter(LBS_DEB_WEXT); 1774 - 1775 - if (priv->wpa_ie_len == 0) { 1776 - dwrq->length = 0; 1777 - goto out; 1778 - } 1779 - 1780 - if (dwrq->length < priv->wpa_ie_len) { 1781 - ret = -E2BIG; 1782 - goto out; 1783 - } 1784 - 1785 - dwrq->length = priv->wpa_ie_len; 1786 - memcpy(extra, &priv->wpa_ie[0], priv->wpa_ie_len); 1787 - 1788 - out: 1789 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1790 - return ret; 1791 - } 1792 - 1793 - 1794 - static int lbs_set_auth(struct net_device *dev, 1795 - struct iw_request_info *info, 1796 - struct iw_param *dwrq, 1797 - char *extra) 1798 - { 1799 - struct lbs_private *priv = dev->ml_priv; 1800 - struct assoc_request * assoc_req; 1801 - int ret = 0; 1802 - int updated = 0; 1803 - 1804 - lbs_deb_enter(LBS_DEB_WEXT); 1805 - 1806 - mutex_lock(&priv->lock); 1807 - assoc_req = lbs_get_association_request(priv); 1808 - if (!assoc_req) { 1809 - ret = -ENOMEM; 1810 - goto out; 1811 - } 1812 - 1813 - switch (dwrq->flags & IW_AUTH_INDEX) { 1814 - case IW_AUTH_PRIVACY_INVOKED: 1815 - case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1816 - case IW_AUTH_TKIP_COUNTERMEASURES: 1817 - case IW_AUTH_CIPHER_PAIRWISE: 1818 - case IW_AUTH_CIPHER_GROUP: 1819 - case IW_AUTH_DROP_UNENCRYPTED: 1820 - /* 1821 - * libertas does not use these parameters 1822 - */ 1823 - break; 1824 - 1825 - case IW_AUTH_KEY_MGMT: 1826 - assoc_req->secinfo.key_mgmt = dwrq->value; 1827 - updated = 1; 1828 - break; 1829 - 1830 - case IW_AUTH_WPA_VERSION: 1831 - if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) { 1832 - assoc_req->secinfo.WPAenabled = 0; 1833 - assoc_req->secinfo.WPA2enabled = 0; 1834 - disable_wpa (assoc_req); 1835 - } 1836 - if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) { 1837 - assoc_req->secinfo.WPAenabled = 1; 1838 - assoc_req->secinfo.wep_enabled = 0; 1839 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1840 - } 1841 - if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) { 1842 - assoc_req->secinfo.WPA2enabled = 1; 1843 - assoc_req->secinfo.wep_enabled = 0; 1844 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1845 - } 1846 - updated = 1; 1847 - break; 1848 - 1849 - case IW_AUTH_80211_AUTH_ALG: 1850 - if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) { 1851 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1852 - } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) { 1853 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1854 - } else if (dwrq->value & IW_AUTH_ALG_LEAP) { 1855 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP; 1856 - } else { 1857 - ret = -EINVAL; 1858 - } 1859 - updated = 1; 1860 - break; 1861 - 1862 - case IW_AUTH_WPA_ENABLED: 1863 - if (dwrq->value) { 1864 - if (!assoc_req->secinfo.WPAenabled && 1865 - !assoc_req->secinfo.WPA2enabled) { 1866 - assoc_req->secinfo.WPAenabled = 1; 1867 - assoc_req->secinfo.WPA2enabled = 1; 1868 - assoc_req->secinfo.wep_enabled = 0; 1869 - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1870 - } 1871 - } else { 1872 - assoc_req->secinfo.WPAenabled = 0; 1873 - assoc_req->secinfo.WPA2enabled = 0; 1874 - disable_wpa (assoc_req); 1875 - } 1876 - updated = 1; 1877 - break; 1878 - 1879 - default: 1880 - ret = -EOPNOTSUPP; 1881 - break; 1882 - } 1883 - 1884 - out: 1885 - if (ret == 0) { 1886 - if (updated) 1887 - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 1888 - lbs_postpone_association_work(priv); 1889 - } else if (ret != -EOPNOTSUPP) { 1890 - lbs_cancel_association_work(priv); 1891 - } 1892 - mutex_unlock(&priv->lock); 1893 - 1894 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1895 - return ret; 1896 - } 1897 - 1898 - static int lbs_get_auth(struct net_device *dev, 1899 - struct iw_request_info *info, 1900 - struct iw_param *dwrq, 1901 - char *extra) 1902 - { 1903 - int ret = 0; 1904 - struct lbs_private *priv = dev->ml_priv; 1905 - 1906 - lbs_deb_enter(LBS_DEB_WEXT); 1907 - 1908 - switch (dwrq->flags & IW_AUTH_INDEX) { 1909 - case IW_AUTH_KEY_MGMT: 1910 - dwrq->value = priv->secinfo.key_mgmt; 1911 - break; 1912 - 1913 - case IW_AUTH_WPA_VERSION: 1914 - dwrq->value = 0; 1915 - if (priv->secinfo.WPAenabled) 1916 - dwrq->value |= IW_AUTH_WPA_VERSION_WPA; 1917 - if (priv->secinfo.WPA2enabled) 1918 - dwrq->value |= IW_AUTH_WPA_VERSION_WPA2; 1919 - if (!dwrq->value) 1920 - dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED; 1921 - break; 1922 - 1923 - case IW_AUTH_80211_AUTH_ALG: 1924 - dwrq->value = priv->secinfo.auth_mode; 1925 - break; 1926 - 1927 - case IW_AUTH_WPA_ENABLED: 1928 - if (priv->secinfo.WPAenabled && priv->secinfo.WPA2enabled) 1929 - dwrq->value = 1; 1930 - break; 1931 - 1932 - default: 1933 - ret = -EOPNOTSUPP; 1934 - } 1935 - 1936 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1937 - return ret; 1938 - } 1939 - 1940 - 1941 - static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info, 1942 - struct iw_param *vwrq, char *extra) 1943 - { 1944 - int ret = 0; 1945 - struct lbs_private *priv = dev->ml_priv; 1946 - s16 dbm = (s16) vwrq->value; 1947 - 1948 - lbs_deb_enter(LBS_DEB_WEXT); 1949 - 1950 - if (vwrq->disabled) { 1951 - lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0); 1952 - goto out; 1953 - } 1954 - 1955 - if (vwrq->fixed == 0) { 1956 - /* User requests automatic tx power control, however there are 1957 - * many auto tx settings. For now use firmware defaults until 1958 - * we come up with a good way to expose these to the user. */ 1959 - if (priv->fwrelease < 0x09000000) { 1960 - ret = lbs_set_power_adapt_cfg(priv, 1, 1961 - POW_ADAPT_DEFAULT_P0, 1962 - POW_ADAPT_DEFAULT_P1, 1963 - POW_ADAPT_DEFAULT_P2); 1964 - if (ret) 1965 - goto out; 1966 - } 1967 - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, 1968 - TPC_DEFAULT_P2, 1); 1969 - if (ret) 1970 - goto out; 1971 - dbm = priv->txpower_max; 1972 - } else { 1973 - /* Userspace check in iwrange if it should use dBm or mW, 1974 - * therefore this should never happen... Jean II */ 1975 - if ((vwrq->flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) { 1976 - ret = -EOPNOTSUPP; 1977 - goto out; 1978 - } 1979 - 1980 - /* Validate requested power level against firmware allowed 1981 - * levels */ 1982 - if (priv->txpower_min && (dbm < priv->txpower_min)) { 1983 - ret = -EINVAL; 1984 - goto out; 1985 - } 1986 - 1987 - if (priv->txpower_max && (dbm > priv->txpower_max)) { 1988 - ret = -EINVAL; 1989 - goto out; 1990 - } 1991 - if (priv->fwrelease < 0x09000000) { 1992 - ret = lbs_set_power_adapt_cfg(priv, 0, 1993 - POW_ADAPT_DEFAULT_P0, 1994 - POW_ADAPT_DEFAULT_P1, 1995 - POW_ADAPT_DEFAULT_P2); 1996 - if (ret) 1997 - goto out; 1998 - } 1999 - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, 2000 - TPC_DEFAULT_P2, 1); 2001 - if (ret) 2002 - goto out; 2003 - } 2004 - 2005 - /* If the radio was off, turn it on */ 2006 - if (!priv->radio_on) { 2007 - ret = lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 1); 2008 - if (ret) 2009 - goto out; 2010 - } 2011 - 2012 - lbs_deb_wext("txpower set %d dBm\n", dbm); 2013 - 2014 - ret = lbs_set_tx_power(priv, dbm); 2015 - 2016 - out: 2017 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 2018 - return ret; 2019 - } 2020 - 2021 - static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, 2022 - struct iw_point *dwrq, char *extra) 2023 - { 2024 - struct lbs_private *priv = dev->ml_priv; 2025 - 2026 - lbs_deb_enter(LBS_DEB_WEXT); 2027 - 2028 - /* 2029 - * Note : if dwrq->flags != 0, we should get the relevant SSID from 2030 - * the SSID list... 2031 - */ 2032 - 2033 - /* 2034 - * Get the current SSID 2035 - */ 2036 - if (priv->connect_status == LBS_CONNECTED) { 2037 - memcpy(extra, priv->curbssparams.ssid, 2038 - priv->curbssparams.ssid_len); 2039 - } else { 2040 - memset(extra, 0, 32); 2041 - } 2042 - /* 2043 - * If none, we may want to get the one that was set 2044 - */ 2045 - 2046 - dwrq->length = priv->curbssparams.ssid_len; 2047 - 2048 - dwrq->flags = 1; /* active */ 2049 - 2050 - lbs_deb_leave(LBS_DEB_WEXT); 2051 - return 0; 2052 - } 2053 - 2054 - static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, 2055 - struct iw_point *dwrq, char *extra) 2056 - { 2057 - struct lbs_private *priv = dev->ml_priv; 2058 - int ret = 0; 2059 - u8 ssid[IEEE80211_MAX_SSID_LEN]; 2060 - u8 ssid_len = 0; 2061 - struct assoc_request * assoc_req; 2062 - int in_ssid_len = dwrq->length; 2063 - DECLARE_SSID_BUF(ssid_buf); 2064 - 2065 - lbs_deb_enter(LBS_DEB_WEXT); 2066 - 2067 - if (!priv->radio_on) { 2068 - ret = -EINVAL; 2069 - goto out; 2070 - } 2071 - 2072 - /* Check the size of the string */ 2073 - if (in_ssid_len > IEEE80211_MAX_SSID_LEN) { 2074 - ret = -E2BIG; 2075 - goto out; 2076 - } 2077 - 2078 - memset(&ssid, 0, sizeof(ssid)); 2079 - 2080 - if (!dwrq->flags || !in_ssid_len) { 2081 - /* "any" SSID requested; leave SSID blank */ 2082 - } else { 2083 - /* Specific SSID requested */ 2084 - memcpy(&ssid, extra, in_ssid_len); 2085 - ssid_len = in_ssid_len; 2086 - } 2087 - 2088 - if (!ssid_len) { 2089 - lbs_deb_wext("requested any SSID\n"); 2090 - } else { 2091 - lbs_deb_wext("requested SSID '%s'\n", 2092 - print_ssid(ssid_buf, ssid, ssid_len)); 2093 - } 2094 - 2095 - out: 2096 - mutex_lock(&priv->lock); 2097 - if (ret == 0) { 2098 - /* Get or create the current association request */ 2099 - assoc_req = lbs_get_association_request(priv); 2100 - if (!assoc_req) { 2101 - ret = -ENOMEM; 2102 - } else { 2103 - /* Copy the SSID to the association request */ 2104 - memcpy(&assoc_req->ssid, &ssid, IEEE80211_MAX_SSID_LEN); 2105 - assoc_req->ssid_len = ssid_len; 2106 - set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); 2107 - lbs_postpone_association_work(priv); 2108 - } 2109 - } 2110 - 2111 - /* Cancel the association request if there was an error */ 2112 - if (ret != 0) { 2113 - lbs_cancel_association_work(priv); 2114 - } 2115 - 2116 - mutex_unlock(&priv->lock); 2117 - 2118 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 2119 - return ret; 2120 - } 2121 - 2122 - #ifdef CONFIG_LIBERTAS_MESH 2123 - static int lbs_mesh_get_essid(struct net_device *dev, 2124 - struct iw_request_info *info, 2125 - struct iw_point *dwrq, char *extra) 2126 - { 2127 - struct lbs_private *priv = dev->ml_priv; 2128 - 2129 - lbs_deb_enter(LBS_DEB_WEXT); 2130 - 2131 - memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len); 2132 - 2133 - dwrq->length = priv->mesh_ssid_len; 2134 - 2135 - dwrq->flags = 1; /* active */ 2136 - 2137 - lbs_deb_leave(LBS_DEB_WEXT); 2138 - return 0; 2139 - } 2140 - 2141 - static int lbs_mesh_set_essid(struct net_device *dev, 2142 - struct iw_request_info *info, 2143 - struct iw_point *dwrq, char *extra) 2144 - { 2145 - struct lbs_private *priv = dev->ml_priv; 2146 - int ret = 0; 2147 - 2148 - lbs_deb_enter(LBS_DEB_WEXT); 2149 - 2150 - if (!priv->radio_on) { 2151 - ret = -EINVAL; 2152 - goto out; 2153 - } 2154 - 2155 - /* Check the size of the string */ 2156 - if (dwrq->length > IEEE80211_MAX_SSID_LEN) { 2157 - ret = -E2BIG; 2158 - goto out; 2159 - } 2160 - 2161 - if (!dwrq->flags || !dwrq->length) { 2162 - ret = -EINVAL; 2163 - goto out; 2164 - } else { 2165 - /* Specific SSID requested */ 2166 - memcpy(priv->mesh_ssid, extra, dwrq->length); 2167 - priv->mesh_ssid_len = dwrq->length; 2168 - } 2169 - 2170 - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 2171 - priv->channel); 2172 - out: 2173 - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 2174 - return ret; 2175 - } 2176 - #endif 2177 - 2178 - /** 2179 - * @brief Connect to the AP or Ad-hoc Network with specific bssid 2180 - * 2181 - * @param dev A pointer to net_device structure 2182 - * @param info A pointer to iw_request_info structure 2183 - * @param awrq A pointer to iw_param structure 2184 - * @param extra A pointer to extra data buf 2185 - * @return 0 --success, otherwise fail 2186 - */ 2187 - static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, 2188 - struct sockaddr *awrq, char *extra) 2189 - { 2190 - struct lbs_private *priv = dev->ml_priv; 2191 - struct assoc_request * assoc_req; 2192 - int ret = 0; 2193 - 2194 - lbs_deb_enter(LBS_DEB_WEXT); 2195 - 2196 - if (!priv->radio_on) 2197 - return -EINVAL; 2198 - 2199 - if (awrq->sa_family != ARPHRD_ETHER) 2200 - return -EINVAL; 2201 - 2202 - lbs_deb_wext("ASSOC: WAP: sa_data %pM\n", awrq->sa_data); 2203 - 2204 - mutex_lock(&priv->lock); 2205 - 2206 - /* Get or create the current association request */ 2207 - assoc_req = lbs_get_association_request(priv); 2208 - if (!assoc_req) { 2209 - lbs_cancel_association_work(priv); 2210 - ret = -ENOMEM; 2211 - } else { 2212 - /* Copy the BSSID to the association request */ 2213 - memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN); 2214 - set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags); 2215 - lbs_postpone_association_work(priv); 2216 - } 2217 - 2218 - mutex_unlock(&priv->lock); 2219 - 2220 - return ret; 2221 - } 2222 - 2223 - /* 2224 - * iwconfig settable callbacks 2225 - */ 2226 - static const iw_handler lbs_handler[] = { 2227 - (iw_handler) NULL, /* SIOCSIWCOMMIT */ 2228 - (iw_handler) lbs_get_name, /* SIOCGIWNAME */ 2229 - (iw_handler) NULL, /* SIOCSIWNWID */ 2230 - (iw_handler) NULL, /* SIOCGIWNWID */ 2231 - (iw_handler) lbs_set_freq, /* SIOCSIWFREQ */ 2232 - (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ 2233 - (iw_handler) lbs_set_mode, /* SIOCSIWMODE */ 2234 - (iw_handler) lbs_get_mode, /* SIOCGIWMODE */ 2235 - (iw_handler) NULL, /* SIOCSIWSENS */ 2236 - (iw_handler) NULL, /* SIOCGIWSENS */ 2237 - (iw_handler) NULL, /* SIOCSIWRANGE */ 2238 - (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ 2239 - (iw_handler) NULL, /* SIOCSIWPRIV */ 2240 - (iw_handler) NULL, /* SIOCGIWPRIV */ 2241 - (iw_handler) NULL, /* SIOCSIWSTATS */ 2242 - (iw_handler) NULL, /* SIOCGIWSTATS */ 2243 - iw_handler_set_spy, /* SIOCSIWSPY */ 2244 - iw_handler_get_spy, /* SIOCGIWSPY */ 2245 - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ 2246 - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ 2247 - (iw_handler) lbs_set_wap, /* SIOCSIWAP */ 2248 - (iw_handler) lbs_get_wap, /* SIOCGIWAP */ 2249 - (iw_handler) NULL, /* SIOCSIWMLME */ 2250 - (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ 2251 - (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ 2252 - (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ 2253 - (iw_handler) lbs_set_essid, /* SIOCSIWESSID */ 2254 - (iw_handler) lbs_get_essid, /* SIOCGIWESSID */ 2255 - (iw_handler) lbs_set_nick, /* SIOCSIWNICKN */ 2256 - (iw_handler) lbs_get_nick, /* SIOCGIWNICKN */ 2257 - (iw_handler) NULL, /* -- hole -- */ 2258 - (iw_handler) NULL, /* -- hole -- */ 2259 - (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ 2260 - (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ 2261 - (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ 2262 - (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ 2263 - (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ 2264 - (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ 2265 - (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ 2266 - (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ 2267 - (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ 2268 - (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ 2269 - (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ 2270 - (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ 2271 - (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ 2272 - (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ 2273 - (iw_handler) NULL, /* -- hole -- */ 2274 - (iw_handler) NULL, /* -- hole -- */ 2275 - (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ 2276 - (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ 2277 - (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ 2278 - (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ 2279 - (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ 2280 - (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2281 - (iw_handler) NULL, /* SIOCSIWPMKSA */ 2282 - }; 2283 - struct iw_handler_def lbs_handler_def = { 2284 - .num_standard = ARRAY_SIZE(lbs_handler), 2285 - .standard = (iw_handler *) lbs_handler, 2286 - .get_wireless_stats = lbs_get_wireless_stats, 2287 - }; 2288 - 2289 - #ifdef CONFIG_LIBERTAS_MESH 2290 - static const iw_handler mesh_wlan_handler[] = { 2291 - (iw_handler) NULL, /* SIOCSIWCOMMIT */ 2292 - (iw_handler) lbs_get_name, /* SIOCGIWNAME */ 2293 - (iw_handler) NULL, /* SIOCSIWNWID */ 2294 - (iw_handler) NULL, /* SIOCGIWNWID */ 2295 - (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */ 2296 - (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ 2297 - (iw_handler) NULL, /* SIOCSIWMODE */ 2298 - (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */ 2299 - (iw_handler) NULL, /* SIOCSIWSENS */ 2300 - (iw_handler) NULL, /* SIOCGIWSENS */ 2301 - (iw_handler) NULL, /* SIOCSIWRANGE */ 2302 - (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ 2303 - (iw_handler) NULL, /* SIOCSIWPRIV */ 2304 - (iw_handler) NULL, /* SIOCGIWPRIV */ 2305 - (iw_handler) NULL, /* SIOCSIWSTATS */ 2306 - (iw_handler) NULL, /* SIOCGIWSTATS */ 2307 - iw_handler_set_spy, /* SIOCSIWSPY */ 2308 - iw_handler_get_spy, /* SIOCGIWSPY */ 2309 - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ 2310 - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ 2311 - (iw_handler) NULL, /* SIOCSIWAP */ 2312 - (iw_handler) NULL, /* SIOCGIWAP */ 2313 - (iw_handler) NULL, /* SIOCSIWMLME */ 2314 - (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ 2315 - (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ 2316 - (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ 2317 - (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */ 2318 - (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */ 2319 - (iw_handler) NULL, /* SIOCSIWNICKN */ 2320 - (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */ 2321 - (iw_handler) NULL, /* -- hole -- */ 2322 - (iw_handler) NULL, /* -- hole -- */ 2323 - (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ 2324 - (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ 2325 - (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ 2326 - (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ 2327 - (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ 2328 - (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ 2329 - (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ 2330 - (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ 2331 - (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ 2332 - (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ 2333 - (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ 2334 - (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ 2335 - (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ 2336 - (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ 2337 - (iw_handler) NULL, /* -- hole -- */ 2338 - (iw_handler) NULL, /* -- hole -- */ 2339 - (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ 2340 - (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ 2341 - (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ 2342 - (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ 2343 - (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ 2344 - (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2345 - (iw_handler) NULL, /* SIOCSIWPMKSA */ 2346 - }; 2347 - 2348 - struct iw_handler_def mesh_handler_def = { 2349 - .num_standard = ARRAY_SIZE(mesh_wlan_handler), 2350 - .standard = (iw_handler *) mesh_wlan_handler, 2351 - .get_wireless_stats = lbs_get_wireless_stats, 2352 - }; 2353 - #endif
-17
drivers/net/wireless/libertas/wext.h
··· 1 - /** 2 - * This file contains definition for IOCTL call. 3 - */ 4 - #ifndef _LBS_WEXT_H_ 5 - #define _LBS_WEXT_H_ 6 - 7 - void lbs_send_disconnect_notification(struct lbs_private *priv); 8 - void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); 9 - 10 - struct chan_freq_power *lbs_find_cfp_by_band_and_channel( 11 - struct lbs_private *priv, 12 - u8 band, 13 - u16 channel); 14 - 15 - extern struct iw_handler_def lbs_handler_def; 16 - 17 - #endif
+5
drivers/net/wireless/mac80211_hwsim.c
··· 1291 1291 hw->wiphy->n_addresses = 2; 1292 1292 hw->wiphy->addresses = data->addresses; 1293 1293 1294 + if (fake_hw_scan) { 1295 + hw->wiphy->max_scan_ssids = 255; 1296 + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 1297 + } 1298 + 1294 1299 hw->channel_change_time = 1; 1295 1300 hw->queues = 4; 1296 1301 hw->wiphy->interface_modes =
+13 -7
drivers/net/wireless/rndis_wlan.c
··· 520 520 521 521 static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); 522 522 523 - static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, 524 - int dbm); 523 + static int rndis_set_tx_power(struct wiphy *wiphy, 524 + enum nl80211_tx_power_setting type, 525 + int mbm); 525 526 static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); 526 527 527 528 static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, ··· 1857 1856 return 0; 1858 1857 } 1859 1858 1860 - static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, 1861 - int dbm) 1859 + static int rndis_set_tx_power(struct wiphy *wiphy, 1860 + enum nl80211_tx_power_setting type, 1861 + int mbm) 1862 1862 { 1863 1863 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 1864 1864 struct usbnet *usbdev = priv->usbdev; 1865 1865 1866 - netdev_dbg(usbdev->net, "%s(): type:0x%x dbm:%i\n", 1867 - __func__, type, dbm); 1866 + netdev_dbg(usbdev->net, "%s(): type:0x%x mbm:%i\n", 1867 + __func__, type, mbm); 1868 + 1869 + if (mbm < 0 || (mbm % 100)) 1870 + return -ENOTSUPP; 1868 1871 1869 1872 /* Device doesn't support changing txpower after initialization, only 1870 1873 * turn off/on radio. Support 'auto' mode and setting same dBm that is 1871 1874 * currently used. 1872 1875 */ 1873 - if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) { 1876 + if (type == NL80211_TX_POWER_AUTOMATIC || 1877 + MBM_TO_DBM(mbm) == get_bcm4320_power_dbm(priv)) { 1874 1878 if (!priv->radio_on) 1875 1879 disassociate(usbdev, true); /* turn on radio */ 1876 1880
+1 -2
drivers/net/wireless/rt2x00/rt2400pci.c
··· 1229 1229 } 1230 1230 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); 1231 1231 1232 - rt2x00pci_txdone(entry, &txdesc); 1232 + rt2x00lib_txdone(entry, &txdesc); 1233 1233 } 1234 1234 } 1235 1235 ··· 1588 1588 .reset_tuner = rt2400pci_reset_tuner, 1589 1589 .link_tuner = rt2400pci_link_tuner, 1590 1590 .write_tx_desc = rt2400pci_write_tx_desc, 1591 - .write_tx_data = rt2x00pci_write_tx_data, 1592 1591 .write_beacon = rt2400pci_write_beacon, 1593 1592 .kick_tx_queue = rt2400pci_kick_tx_queue, 1594 1593 .kill_tx_queue = rt2400pci_kill_tx_queue,
+1 -2
drivers/net/wireless/rt2x00/rt2500pci.c
··· 1365 1365 } 1366 1366 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); 1367 1367 1368 - rt2x00pci_txdone(entry, &txdesc); 1368 + rt2x00lib_txdone(entry, &txdesc); 1369 1369 } 1370 1370 } 1371 1371 ··· 1886 1886 .reset_tuner = rt2500pci_reset_tuner, 1887 1887 .link_tuner = rt2500pci_link_tuner, 1888 1888 .write_tx_desc = rt2500pci_write_tx_desc, 1889 - .write_tx_data = rt2x00pci_write_tx_data, 1890 1889 .write_beacon = rt2500pci_write_beacon, 1891 1890 .kick_tx_queue = rt2500pci_kick_tx_queue, 1892 1891 .kill_tx_queue = rt2500pci_kill_tx_queue,
+10 -1
drivers/net/wireless/rt2x00/rt2500usb.c
··· 347 347 { 348 348 u32 mask; 349 349 u16 reg; 350 + enum cipher curr_cipher; 350 351 351 352 if (crypto->cmd == SET_KEY) { 352 353 /* ··· 358 357 mask = TXRX_CSR0_KEY_ID.bit_mask; 359 358 360 359 rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg); 360 + curr_cipher = rt2x00_get_field16(reg, TXRX_CSR0_ALGORITHM); 361 361 reg &= mask; 362 362 363 363 if (reg && reg == mask) ··· 367 365 reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); 368 366 369 367 key->hw_key_idx += reg ? ffz(reg) : 0; 368 + /* 369 + * Hardware requires that all keys use the same cipher 370 + * (e.g. TKIP-only, AES-only, but not TKIP+AES). 371 + * If this is not the first key, compare the cipher with the 372 + * first one and fall back to SW crypto if not the same. 373 + */ 374 + if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher) 375 + return -EOPNOTSUPP; 370 376 371 377 rt2500usb_register_multiwrite(rt2x00dev, reg, 372 378 crypto->key, sizeof(crypto->key)); ··· 1779 1769 .link_stats = rt2500usb_link_stats, 1780 1770 .reset_tuner = rt2500usb_reset_tuner, 1781 1771 .write_tx_desc = rt2500usb_write_tx_desc, 1782 - .write_tx_data = rt2x00usb_write_tx_data, 1783 1772 .write_beacon = rt2500usb_write_beacon, 1784 1773 .get_tx_data_len = rt2500usb_get_tx_data_len, 1785 1774 .kick_tx_queue = rt2x00usb_kick_tx_queue,
+73 -31
drivers/net/wireless/rt2x00/rt2800lib.c
··· 99 99 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word); 100 100 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1); 101 101 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0); 102 - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) 103 - rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 102 + rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 104 103 105 104 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); 106 105 } ··· 127 128 rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word); 128 129 rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1); 129 130 rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1); 130 - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) 131 - rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 131 + rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1); 132 132 133 133 rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); 134 134 ··· 430 432 } 431 433 EXPORT_SYMBOL(rt2800_write_beacon); 432 434 435 + static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, 436 + unsigned int beacon_base) 437 + { 438 + int i; 439 + 440 + /* 441 + * For the Beacon base registers we only need to clear 442 + * the whole TXWI which (when set to 0) will invalidate 443 + * the entire beacon. 444 + */ 445 + for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32)) 446 + rt2800_register_write(rt2x00dev, beacon_base + i, 0); 447 + } 448 + 433 449 #ifdef CONFIG_RT2X00_LIB_DEBUGFS 434 450 const struct rt2x00debug rt2800_rt2x00debug = { 435 451 .owner = THIS_MODULE, ··· 745 733 void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, 746 734 struct rt2x00intf_conf *conf, const unsigned int flags) 747 735 { 748 - unsigned int beacon_base; 749 736 u32 reg; 750 737 751 738 if (flags & CONFIG_UPDATE_TYPE) { 752 739 /* 753 740 * Clear current synchronisation setup. 754 - * For the Beacon base registers we only need to clear 755 - * the first byte since that byte contains the VALID and OWNER 756 - * bits which (when set to 0) will invalidate the entire beacon. 757 741 */ 758 - beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); 759 - rt2800_register_write(rt2x00dev, beacon_base, 0); 760 - 742 + rt2800_clear_beacon(rt2x00dev, 743 + HW_BEACON_OFFSET(intf->beacon->entry_idx)); 761 744 /* 762 745 * Enable synchronisation. 763 746 */ ··· 775 768 776 769 if (flags & CONFIG_UPDATE_BSSID) { 777 770 reg = le32_to_cpu(conf->bssid[1]); 778 - rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0); 779 - rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0); 771 + rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3); 772 + rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7); 780 773 conf->bssid[1] = cpu_to_le32(reg); 781 774 782 775 rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, ··· 834 827 switch ((int)ant->tx) { 835 828 case 1: 836 829 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); 837 - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) 838 - rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); 839 830 break; 840 831 case 2: 841 832 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); 842 833 break; 843 834 case 3: 844 - /* Do nothing */ 835 + rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); 845 836 break; 846 837 } 847 838 ··· 1570 1565 1571 1566 /* 1572 1567 * Clear all beacons 1573 - * For the Beacon base registers we only need to clear 1574 - * the first byte since that byte contains the VALID and OWNER 1575 - * bits which (when set to 0) will invalidate the entire beacon. 1576 1568 */ 1577 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0); 1578 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0); 1579 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0); 1580 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0); 1581 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0); 1582 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0); 1583 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0); 1584 - rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); 1569 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0); 1570 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1); 1571 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2); 1572 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3); 1573 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4); 1574 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5); 1575 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6); 1576 + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7); 1585 1577 1586 1578 if (rt2x00_is_usb(rt2x00dev)) { 1587 1579 rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg); ··· 2187 2185 rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); 2188 2186 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); 2189 2187 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); 2188 + rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0); 2189 + rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0); 2190 2190 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); 2191 2191 EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); 2192 2192 } ··· 2196 2192 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); 2197 2193 if ((word & 0x00ff) == 0x00ff) { 2198 2194 rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); 2195 + rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); 2196 + EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); 2197 + } 2198 + if ((word & 0xff00) == 0xff00) { 2199 2199 rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, 2200 2200 LED_MODE_TXRX_ACTIVITY); 2201 2201 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); ··· 2207 2199 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); 2208 2200 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); 2209 2201 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); 2210 - EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); 2202 + EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); 2211 2203 } 2212 2204 2213 2205 /* ··· 2507 2499 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2508 2500 IEEE80211_HW_SIGNAL_DBM | 2509 2501 IEEE80211_HW_SUPPORTS_PS | 2510 - IEEE80211_HW_PS_NULLFUNC_STACK; 2502 + IEEE80211_HW_PS_NULLFUNC_STACK | 2503 + IEEE80211_HW_AMPDU_AGGREGATION; 2511 2504 2512 2505 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); 2513 2506 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, ··· 2568 2559 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 2569 2560 IEEE80211_HT_CAP_GRN_FLD | 2570 2561 IEEE80211_HT_CAP_SGI_20 | 2571 - IEEE80211_HT_CAP_SGI_40 | 2572 - IEEE80211_HT_CAP_RX_STBC; 2562 + IEEE80211_HT_CAP_SGI_40; 2573 2563 2574 2564 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) 2575 2565 spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; 2566 + 2567 + spec->ht.cap |= 2568 + rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) << 2569 + IEEE80211_HT_CAP_RX_STBC_SHIFT; 2576 2570 2577 2571 spec->ht.ampdu_factor = 3; 2578 2572 spec->ht.ampdu_density = 4; ··· 2763 2751 return tsf; 2764 2752 } 2765 2753 2754 + static int rt2800_ampdu_action(struct ieee80211_hw *hw, 2755 + struct ieee80211_vif *vif, 2756 + enum ieee80211_ampdu_mlme_action action, 2757 + struct ieee80211_sta *sta, 2758 + u16 tid, u16 *ssn) 2759 + { 2760 + int ret = 0; 2761 + 2762 + switch (action) { 2763 + case IEEE80211_AMPDU_RX_START: 2764 + case IEEE80211_AMPDU_RX_STOP: 2765 + /* we don't support RX aggregation yet */ 2766 + ret = -ENOTSUPP; 2767 + break; 2768 + case IEEE80211_AMPDU_TX_START: 2769 + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 2770 + break; 2771 + case IEEE80211_AMPDU_TX_STOP: 2772 + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 2773 + break; 2774 + case IEEE80211_AMPDU_TX_OPERATIONAL: 2775 + break; 2776 + default: 2777 + WARNING((struct rt2x00_dev *)hw->priv, "Unknown AMPDU action\n"); 2778 + } 2779 + 2780 + return ret; 2781 + } 2782 + 2766 2783 const struct ieee80211_ops rt2800_mac80211_ops = { 2767 2784 .tx = rt2x00mac_tx, 2768 2785 .start = rt2x00mac_start, ··· 2809 2768 .conf_tx = rt2800_conf_tx, 2810 2769 .get_tsf = rt2800_get_tsf, 2811 2770 .rfkill_poll = rt2x00mac_rfkill_poll, 2771 + .ampdu_action = rt2800_ampdu_action, 2812 2772 }; 2813 2773 EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); 2814 2774
+25 -8
drivers/net/wireless/rt2x00/rt2800pci.c
··· 139 139 eeprom.data = rt2x00dev; 140 140 eeprom.register_read = rt2800pci_eepromregister_read; 141 141 eeprom.register_write = rt2800pci_eepromregister_write; 142 - eeprom.width = !rt2x00_get_field32(reg, E2PROM_CSR_TYPE) ? 143 - PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; 142 + switch (rt2x00_get_field32(reg, E2PROM_CSR_TYPE)) 143 + { 144 + case 0: 145 + eeprom.width = PCI_EEPROM_WIDTH_93C46; 146 + break; 147 + case 1: 148 + eeprom.width = PCI_EEPROM_WIDTH_93C66; 149 + break; 150 + default: 151 + eeprom.width = PCI_EEPROM_WIDTH_93C86; 152 + break; 153 + } 144 154 eeprom.reg_data_in = 0; 145 155 eeprom.reg_data_out = 0; 146 156 eeprom.reg_data_clock = 0; ··· 655 645 /* 656 646 * TX descriptor initialization 657 647 */ 658 - static void rt2800pci_write_tx_datadesc(struct queue_entry* entry, 659 - struct txentry_desc *txdesc) 648 + static void rt2800pci_write_tx_data(struct queue_entry* entry, 649 + struct txentry_desc *txdesc) 660 650 { 661 - rt2800_write_txwi((__le32 *) entry->skb->data, txdesc); 651 + __le32 *txwi = (__le32 *) entry->skb->data; 652 + 653 + rt2800_write_txwi(txwi, txdesc); 662 654 } 663 655 664 656 ··· 917 905 if (txdesc.retry) 918 906 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 919 907 920 - rt2x00pci_txdone(entry, &txdesc); 908 + rt2x00lib_txdone(entry, &txdesc); 921 909 } 922 910 } 923 911 ··· 952 940 953 941 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) 954 942 rt2800pci_txdone(rt2x00dev); 943 + 944 + /* 945 + * Current beacon was sent out, fetch the next one 946 + */ 947 + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) 948 + rt2x00lib_beacondone(rt2x00dev); 955 949 956 950 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) 957 951 rt2800pci_wakeup(rt2x00dev); ··· 1062 1044 .reset_tuner = rt2800_reset_tuner, 1063 1045 .link_tuner = rt2800_link_tuner, 1064 1046 .write_tx_desc = rt2800pci_write_tx_desc, 1065 - .write_tx_data = rt2x00pci_write_tx_data, 1066 - .write_tx_datadesc = rt2800pci_write_tx_datadesc, 1047 + .write_tx_data = rt2800pci_write_tx_data, 1067 1048 .write_beacon = rt2800_write_beacon, 1068 1049 .kick_tx_queue = rt2800pci_kick_tx_queue, 1069 1050 .kill_tx_queue = rt2800pci_kill_tx_queue,
+10 -7
drivers/net/wireless/rt2x00/rt2800usb.c
··· 430 430 /* 431 431 * TX descriptor initialization 432 432 */ 433 + static void rt2800usb_write_tx_data(struct queue_entry* entry, 434 + struct txentry_desc *txdesc) 435 + { 436 + __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); 437 + 438 + rt2800_write_txwi(txwi, txdesc); 439 + } 440 + 441 + 433 442 static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, 434 443 struct sk_buff *skb, 435 444 struct txentry_desc *txdesc) 436 445 { 437 446 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 438 447 __le32 *txi = (__le32 *) skb->data; 439 - __le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE); 440 448 u32 word; 441 - 442 - /* 443 - * Initialize TXWI descriptor 444 - */ 445 - rt2800_write_txwi(txwi, txdesc); 446 449 447 450 /* 448 451 * Initialize TXINFO descriptor ··· 655 652 .reset_tuner = rt2800_reset_tuner, 656 653 .link_tuner = rt2800_link_tuner, 657 654 .write_tx_desc = rt2800usb_write_tx_desc, 658 - .write_tx_data = rt2x00usb_write_tx_data, 655 + .write_tx_data = rt2800usb_write_tx_data, 659 656 .write_beacon = rt2800_write_beacon, 660 657 .get_tx_data_len = rt2800usb_get_tx_data_len, 661 658 .kick_tx_queue = rt2x00usb_kick_tx_queue,
+2 -4
drivers/net/wireless/rt2x00/rt2x00.h
··· 550 550 void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, 551 551 struct sk_buff *skb, 552 552 struct txentry_desc *txdesc); 553 - int (*write_tx_data) (struct queue_entry *entry, 554 - struct txentry_desc *txdesc); 555 - void (*write_tx_datadesc) (struct queue_entry *entry, 556 - struct txentry_desc *txdesc); 553 + void (*write_tx_data) (struct queue_entry *entry, 554 + struct txentry_desc *txdesc); 557 555 void (*write_beacon) (struct queue_entry *entry, 558 556 struct txentry_desc *txdesc); 559 557 int (*get_tx_data_len) (struct queue_entry *entry);
+30
drivers/net/wireless/rt2x00/rt2x00dev.c
··· 211 211 bool success; 212 212 213 213 /* 214 + * Unmap the skb. 215 + */ 216 + rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 217 + 218 + /* 219 + * Remove the extra tx headroom from the skb. 220 + */ 221 + skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom); 222 + 223 + /* 224 + * Signal that the TX descriptor is no longer in the skb. 225 + */ 226 + skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; 227 + 228 + /* 214 229 * Remove L2 padding which was added during 215 230 */ 216 231 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) ··· 299 284 tx_info->flags |= IEEE80211_TX_STAT_ACK; 300 285 else 301 286 rt2x00dev->low_level_stats.dot11ACKFailureCount++; 287 + } 288 + 289 + /* 290 + * Every single frame has it's own tx status, hence report 291 + * every frame as ampdu of size 1. 292 + * 293 + * TODO: if we can find out how many frames were aggregated 294 + * by the hw we could provide the real ampdu_len to mac80211 295 + * which would allow the rc algorithm to better decide on 296 + * which rates are suitable. 297 + */ 298 + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 299 + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; 300 + tx_info->status.ampdu_len = 1; 301 + tx_info->status.ampdu_ack_len = success ? 1 : 0; 302 302 } 303 303 304 304 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+4 -4
drivers/net/wireless/rt2x00/rt2x00link.c
··· 271 271 272 272 /* 273 273 * Link tuning should only be performed when 274 - * an active sta or master interface exists. 275 - * Single monitor mode interfaces should never have 276 - * work with link tuners. 274 + * an active sta interface exists. AP interfaces 275 + * don't need link tuning and monitor mode interfaces 276 + * should never have to work with link tuners. 277 277 */ 278 - if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) 278 + if (!rt2x00dev->intf_sta_count) 279 279 return; 280 280 281 281 rt2x00link_reset_tuner(rt2x00dev, false);
+4 -6
drivers/net/wireless/rt2x00/rt2x00mac.c
··· 282 282 * has been initialized. Otherwise the device can reset 283 283 * the MAC registers. 284 284 */ 285 - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, intf->mac, NULL); 285 + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, 286 + intf->mac, intf->bssid); 286 287 287 288 /* 288 289 * Some filters depend on the current working mode. We can force ··· 563 562 { 564 563 struct rt2x00_dev *rt2x00dev = hw->priv; 565 564 struct rt2x00_intf *intf = vif_to_intf(vif); 566 - int update_bssid = 0; 567 565 568 566 /* 569 567 * mac80211 might be calling this function while we are trying ··· 577 577 * conf->bssid can be NULL if coming from the internal 578 578 * beacon update routine. 579 579 */ 580 - if (changes & BSS_CHANGED_BSSID) { 581 - update_bssid = 1; 580 + if (changes & BSS_CHANGED_BSSID) 582 581 memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN); 583 - } 584 582 585 583 spin_unlock(&intf->lock); 586 584 ··· 590 592 */ 591 593 if (changes & BSS_CHANGED_BSSID) 592 594 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, 593 - update_bssid ? bss_conf->bssid : NULL); 595 + bss_conf->bssid); 594 596 595 597 /* 596 598 * Update the beacon.
-74
drivers/net/wireless/rt2x00/rt2x00pci.c
··· 60 60 } 61 61 EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); 62 62 63 - /* 64 - * TX data handlers. 65 - */ 66 - int rt2x00pci_write_tx_data(struct queue_entry *entry, 67 - struct txentry_desc *txdesc) 68 - { 69 - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 70 - 71 - /* 72 - * This should not happen, we already checked the entry 73 - * was ours. When the hardware disagrees there has been 74 - * a queue corruption! 75 - */ 76 - if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) { 77 - ERROR(rt2x00dev, 78 - "Corrupt queue %d, accessing entry which is not ours.\n" 79 - "Please file bug report to %s.\n", 80 - entry->queue->qid, DRV_PROJECT); 81 - return -EINVAL; 82 - } 83 - 84 - /* 85 - * Add the requested extra tx headroom in front of the skb. 86 - */ 87 - skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom); 88 - memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom); 89 - 90 - /* 91 - * Call the driver's write_tx_datadesc function, if it exists. 92 - */ 93 - if (rt2x00dev->ops->lib->write_tx_datadesc) 94 - rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc); 95 - 96 - /* 97 - * Map the skb to DMA. 98 - */ 99 - if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) 100 - rt2x00queue_map_txskb(rt2x00dev, entry->skb); 101 - 102 - return 0; 103 - } 104 - EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); 105 - 106 - /* 107 - * TX/RX data handlers. 108 - */ 109 - void rt2x00pci_txdone(struct queue_entry *entry, 110 - struct txdone_entry_desc *txdesc) 111 - { 112 - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 113 - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 114 - 115 - /* 116 - * Unmap the skb. 117 - */ 118 - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 119 - 120 - /* 121 - * Remove the extra tx headroom from the skb. 122 - */ 123 - skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom); 124 - 125 - /* 126 - * Signal that the TX descriptor is no longer in the skb. 127 - */ 128 - skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; 129 - 130 - /* 131 - * Pass on to rt2x00lib. 132 - */ 133 - rt2x00lib_txdone(entry, txdesc); 134 - } 135 - EXPORT_SYMBOL_GPL(rt2x00pci_txdone); 136 - 137 63 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) 138 64 { 139 65 struct data_queue *queue = rt2x00dev->rx;
-18
drivers/net/wireless/rt2x00/rt2x00pci.h
··· 86 86 u32 *reg); 87 87 88 88 /** 89 - * rt2x00pci_write_tx_data - Initialize data for TX operation 90 - * @entry: The entry where the frame is located 91 - * 92 - * This function will initialize the DMA and skb descriptor 93 - * to prepare the entry for the actual TX operation. 94 - */ 95 - int rt2x00pci_write_tx_data(struct queue_entry *entry, 96 - struct txentry_desc *txdesc); 97 - 98 - /** 99 89 * struct queue_entry_priv_pci: Per entry PCI specific information 100 90 * 101 91 * @desc: Pointer to device descriptor ··· 97 107 __le32 *desc; 98 108 dma_addr_t desc_dma; 99 109 }; 100 - 101 - /** 102 - * rt2x00pci_txdone - Handle TX done events. 103 - * @entry: The queue entry for which a TX done event was received. 104 - * @txdesc: The TX done descriptor for the entry. 105 - */ 106 - void rt2x00pci_txdone(struct queue_entry *entry, 107 - struct txdone_entry_desc *txdesc); 108 110 109 111 /** 110 112 * rt2x00pci_rxdone - Handle RX done events
+41 -2
drivers/net/wireless/rt2x00/rt2x00queue.c
··· 404 404 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); 405 405 } 406 406 407 + static int rt2x00queue_write_tx_data(struct queue_entry *entry, 408 + struct txentry_desc *txdesc) 409 + { 410 + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 411 + 412 + /* 413 + * This should not happen, we already checked the entry 414 + * was ours. When the hardware disagrees there has been 415 + * a queue corruption! 416 + */ 417 + if (unlikely(rt2x00dev->ops->lib->get_entry_state && 418 + rt2x00dev->ops->lib->get_entry_state(entry))) { 419 + ERROR(rt2x00dev, 420 + "Corrupt queue %d, accessing entry which is not ours.\n" 421 + "Please file bug report to %s.\n", 422 + entry->queue->qid, DRV_PROJECT); 423 + return -EINVAL; 424 + } 425 + 426 + /* 427 + * Add the requested extra tx headroom in front of the skb. 428 + */ 429 + skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom); 430 + memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom); 431 + 432 + /* 433 + * Call the driver's write_tx_data function, if it exists. 434 + */ 435 + if (rt2x00dev->ops->lib->write_tx_data) 436 + rt2x00dev->ops->lib->write_tx_data(entry, txdesc); 437 + 438 + /* 439 + * Map the skb to DMA. 440 + */ 441 + if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) 442 + rt2x00queue_map_txskb(rt2x00dev, entry->skb); 443 + 444 + return 0; 445 + } 446 + 407 447 static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, 408 448 struct txentry_desc *txdesc) 409 449 { ··· 555 515 * call failed. Since we always return NETDEV_TX_OK to mac80211, 556 516 * this frame will simply be dropped. 557 517 */ 558 - if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry, 559 - &txdesc))) { 518 + if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { 560 519 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 561 520 entry->skb = NULL; 562 521 return -EIO;
+13 -38
drivers/net/wireless/rt2x00/rt2x00usb.c
··· 178 178 return; 179 179 180 180 /* 181 - * Remove the descriptor from the front of the skb. 182 - */ 183 - skb_pull(entry->skb, entry->queue->desc_size); 184 - 185 - /* 186 181 * Obtain the status about this packet. 187 182 * Note that when the status is 0 it does not mean the 188 183 * frame was send out correctly. It only means the frame ··· 196 201 rt2x00lib_txdone(entry, &txdesc); 197 202 } 198 203 199 - int rt2x00usb_write_tx_data(struct queue_entry *entry, 200 - struct txentry_desc *txdesc) 204 + static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 201 205 { 202 206 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 203 207 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 204 208 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 205 209 u32 length; 206 210 207 - /* 208 - * Add the descriptor in front of the skb. 209 - */ 210 - skb_push(entry->skb, entry->queue->desc_size); 211 - memset(entry->skb->data, 0, entry->queue->desc_size); 211 + if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { 212 + /* 213 + * USB devices cannot blindly pass the skb->len as the 214 + * length of the data to usb_fill_bulk_urb. Pass the skb 215 + * to the driver to determine what the length should be. 216 + */ 217 + length = rt2x00dev->ops->lib->get_tx_data_len(entry); 212 218 213 - /* 214 - * USB devices cannot blindly pass the skb->len as the 215 - * length of the data to usb_fill_bulk_urb. Pass the skb 216 - * to the driver to determine what the length should be. 217 - */ 218 - length = rt2x00dev->ops->lib->get_tx_data_len(entry); 219 + usb_fill_bulk_urb(entry_priv->urb, usb_dev, 220 + usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), 221 + entry->skb->data, length, 222 + rt2x00usb_interrupt_txdone, entry); 219 223 220 - usb_fill_bulk_urb(entry_priv->urb, usb_dev, 221 - usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), 222 - entry->skb->data, length, 223 - rt2x00usb_interrupt_txdone, entry); 224 - 225 - /* 226 - * Call the driver's write_tx_datadesc function, if it exists. 227 - */ 228 - if (rt2x00dev->ops->lib->write_tx_datadesc) 229 - rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc); 230 - 231 - return 0; 232 - } 233 - EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); 234 - 235 - static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 236 - { 237 - struct queue_entry_priv_usb *entry_priv = entry->priv_data; 238 - 239 - if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) 240 224 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 225 + } 241 226 } 242 227 243 228 void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-10
drivers/net/wireless/rt2x00/rt2x00usb.h
··· 351 351 void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); 352 352 353 353 /** 354 - * rt2x00usb_write_tx_data - Initialize URB for TX operation 355 - * @entry: The entry where the frame is located 356 - * 357 - * This function will initialize the URB and skb descriptor 358 - * to prepare the entry for the actual TX operation. 359 - */ 360 - int rt2x00usb_write_tx_data(struct queue_entry *entry, 361 - struct txentry_desc *txdesc); 362 - 363 - /** 364 354 * struct queue_entry_priv_usb: Per entry USB specific information 365 355 * 366 356 * @urb: Urb structure used for device communication.
+8 -3
drivers/net/wireless/rt2x00/rt61pci.c
··· 2108 2108 __set_bit(TXDONE_UNKNOWN, &txdesc.flags); 2109 2109 txdesc.retry = 0; 2110 2110 2111 - rt2x00pci_txdone(entry_done, &txdesc); 2111 + rt2x00lib_txdone(entry_done, &txdesc); 2112 2112 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 2113 2113 } 2114 2114 ··· 2135 2135 if (txdesc.retry) 2136 2136 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 2137 2137 2138 - rt2x00pci_txdone(entry, &txdesc); 2138 + rt2x00lib_txdone(entry, &txdesc); 2139 2139 } 2140 2140 } 2141 2141 ··· 2199 2199 */ 2200 2200 if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP)) 2201 2201 rt61pci_wakeup(rt2x00dev); 2202 + 2203 + /* 2204 + * 5 - Beacon done interrupt. 2205 + */ 2206 + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) 2207 + rt2x00lib_beacondone(rt2x00dev); 2202 2208 2203 2209 return IRQ_HANDLED; 2204 2210 } ··· 2806 2800 .reset_tuner = rt61pci_reset_tuner, 2807 2801 .link_tuner = rt61pci_link_tuner, 2808 2802 .write_tx_desc = rt61pci_write_tx_desc, 2809 - .write_tx_data = rt2x00pci_write_tx_data, 2810 2803 .write_beacon = rt61pci_write_beacon, 2811 2804 .kick_tx_queue = rt61pci_kick_tx_queue, 2812 2805 .kill_tx_queue = rt61pci_kill_tx_queue,
-1
drivers/net/wireless/rt2x00/rt73usb.c
··· 2249 2249 .reset_tuner = rt73usb_reset_tuner, 2250 2250 .link_tuner = rt73usb_link_tuner, 2251 2251 .write_tx_desc = rt73usb_write_tx_desc, 2252 - .write_tx_data = rt2x00usb_write_tx_data, 2253 2252 .write_beacon = rt73usb_write_beacon, 2254 2253 .get_tx_data_len = rt73usb_get_tx_data_len, 2255 2254 .kick_tx_queue = rt2x00usb_kick_tx_queue,
+1 -1
drivers/net/wireless/rtl818x/rtl8180_dev.c
··· 671 671 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; 672 672 } 673 673 674 - void rtl8180_beacon_work(struct work_struct *work) 674 + static void rtl8180_beacon_work(struct work_struct *work) 675 675 { 676 676 struct rtl8180_vif *vif_priv = 677 677 container_of(work, struct rtl8180_vif, beacon_work.work);
+1
include/linux/eeprom_93cx6.h
··· 30 30 #define PCI_EEPROM_WIDTH_93C46 6 31 31 #define PCI_EEPROM_WIDTH_93C56 8 32 32 #define PCI_EEPROM_WIDTH_93C66 8 33 + #define PCI_EEPROM_WIDTH_93C86 8 33 34 #define PCI_EEPROM_WIDTH_OPCODE 3 34 35 #define PCI_EEPROM_WRITE_OPCODE 0x05 35 36 #define PCI_EEPROM_READ_OPCODE 0x06
+22
include/linux/nl80211.h
··· 725 725 * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations 726 726 * connected to this BSS. 727 727 * 728 + * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See 729 + * &enum nl80211_tx_power_setting for possible values. 730 + * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units. 731 + * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING 732 + * for non-automatic settings. 733 + * 728 734 * @NL80211_ATTR_MAX: highest attribute number currently defined 729 735 * @__NL80211_ATTR_AFTER_LAST: internal use 730 736 */ ··· 887 881 NL80211_ATTR_LOCAL_STATE_CHANGE, 888 882 889 883 NL80211_ATTR_AP_ISOLATE, 884 + 885 + NL80211_ATTR_WIPHY_TX_POWER_SETTING, 886 + NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 890 887 891 888 /* add attributes here, update the policy in nl80211.c */ 892 889 ··· 1666 1657 enum nl80211_cqm_rssi_threshold_event { 1667 1658 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, 1668 1659 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, 1660 + }; 1661 + 1662 + 1663 + /** 1664 + * enum nl80211_tx_power_setting - TX power adjustment 1665 + * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power 1666 + * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter 1667 + * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter 1668 + */ 1669 + enum nl80211_tx_power_setting { 1670 + NL80211_TX_POWER_AUTOMATIC, 1671 + NL80211_TX_POWER_LIMITED, 1672 + NL80211_TX_POWER_FIXED, 1669 1673 }; 1670 1674 1671 1675 #endif /* __LINUX_NL80211_H */
+1 -14
include/net/cfg80211.h
··· 875 875 WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, 876 876 }; 877 877 878 - /** 879 - * enum tx_power_setting - TX power adjustment 880 - * 881 - * @TX_POWER_AUTOMATIC: the dbm parameter is ignored 882 - * @TX_POWER_LIMITED: limit TX power by the dbm parameter 883 - * @TX_POWER_FIXED: fix TX power to the dbm parameter 884 - */ 885 - enum tx_power_setting { 886 - TX_POWER_AUTOMATIC, 887 - TX_POWER_LIMITED, 888 - TX_POWER_FIXED, 889 - }; 890 - 891 878 /* 892 879 * cfg80211_bitrate_mask - masks for bitrate control 893 880 */ ··· 1136 1149 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); 1137 1150 1138 1151 int (*set_tx_power)(struct wiphy *wiphy, 1139 - enum tx_power_setting type, int dbm); 1152 + enum nl80211_tx_power_setting type, int mbm); 1140 1153 int (*get_tx_power)(struct wiphy *wiphy, int *dbm); 1141 1154 1142 1155 int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
+39
include/net/mac80211.h
··· 1271 1271 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS 1272 1272 * enabled whenever user has enabled powersave. 1273 1273 * 1274 + * Some hardware need to toggle a single shared antenna between WLAN and 1275 + * Bluetooth to facilitate co-existence. These types of hardware set 1276 + * limitations on the use of host controlled dynamic powersave whenever there 1277 + * is simultaneous WLAN and Bluetooth traffic. For these types of hardware, the 1278 + * driver may request temporarily going into full power save, in order to 1279 + * enable toggling the antenna between BT and WLAN. If the driver requests 1280 + * disabling dynamic powersave, the @dynamic_ps_timeout value will be 1281 + * temporarily set to zero until the driver re-enables dynamic powersave. 1282 + * 1274 1283 * Driver informs U-APSD client support by enabling 1275 1284 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the 1276 1285 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS ··· 2454 2445 * without connection recovery attempts. 2455 2446 */ 2456 2447 void ieee80211_connection_loss(struct ieee80211_vif *vif); 2448 + 2449 + /** 2450 + * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm 2451 + * 2452 + * @vif: &struct ieee80211_vif pointer from the add_interface callback. 2453 + * 2454 + * Some hardware require full power save to manage simultaneous BT traffic 2455 + * on the WLAN frequency. Full PSM is required periodically, whenever there are 2456 + * burst of BT traffic. The hardware gets information of BT traffic via 2457 + * hardware co-existence lines, and consequentially requests mac80211 to 2458 + * (temporarily) enter full psm. 2459 + * This function will only temporarily disable dynamic PS, not enable PSM if 2460 + * it was not already enabled. 2461 + * The driver must make sure to re-enable dynamic PS using 2462 + * ieee80211_enable_dyn_ps() if the driver has disabled it. 2463 + * 2464 + */ 2465 + void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif); 2466 + 2467 + /** 2468 + * ieee80211_enable_dyn_ps - restore dynamic psm after being disabled 2469 + * 2470 + * @vif: &struct ieee80211_vif pointer from the add_interface callback. 2471 + * 2472 + * This function restores dynamic PS after being temporarily disabled via 2473 + * ieee80211_disable_dyn_ps(). Each ieee80211_disable_dyn_ps() call must 2474 + * be coupled with an eventual call to this function. 2475 + * 2476 + */ 2477 + void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif); 2457 2478 2458 2479 /** 2459 2480 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring
+1
net/mac80211/Kconfig
··· 69 69 70 70 config MAC80211_RC_DEFAULT 71 71 string 72 + default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT 72 73 default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL 73 74 default "pid" if MAC80211_RC_DEFAULT_PID 74 75 default ""
+11 -14
net/mac80211/cfg.c
··· 413 413 { 414 414 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 415 415 416 - if (!local->ops->get_survey) 417 - return -EOPNOTSUPP; 418 - 419 416 return drv_get_survey(local, idx, survey); 420 417 } 421 418 ··· 1326 1329 } 1327 1330 1328 1331 static int ieee80211_set_tx_power(struct wiphy *wiphy, 1329 - enum tx_power_setting type, int dbm) 1332 + enum nl80211_tx_power_setting type, int mbm) 1330 1333 { 1331 1334 struct ieee80211_local *local = wiphy_priv(wiphy); 1332 1335 struct ieee80211_channel *chan = local->hw.conf.channel; 1333 1336 u32 changes = 0; 1334 1337 1335 1338 switch (type) { 1336 - case TX_POWER_AUTOMATIC: 1339 + case NL80211_TX_POWER_AUTOMATIC: 1337 1340 local->user_power_level = -1; 1338 1341 break; 1339 - case TX_POWER_LIMITED: 1340 - if (dbm < 0) 1341 - return -EINVAL; 1342 - local->user_power_level = dbm; 1342 + case NL80211_TX_POWER_LIMITED: 1343 + if (mbm < 0 || (mbm % 100)) 1344 + return -EOPNOTSUPP; 1345 + local->user_power_level = MBM_TO_DBM(mbm); 1343 1346 break; 1344 - case TX_POWER_FIXED: 1345 - if (dbm < 0) 1346 - return -EINVAL; 1347 + case NL80211_TX_POWER_FIXED: 1348 + if (mbm < 0 || (mbm % 100)) 1349 + return -EOPNOTSUPP; 1347 1350 /* TODO: move to cfg80211 when it knows the channel */ 1348 - if (dbm > chan->max_power) 1351 + if (MBM_TO_DBM(mbm) > chan->max_power) 1349 1352 return -EINVAL; 1350 - local->user_power_level = dbm; 1353 + local->user_power_level = MBM_TO_DBM(mbm); 1351 1354 break; 1352 1355 } 1353 1356
+6 -1
net/mac80211/driver-ops.h
··· 375 375 struct survey_info *survey) 376 376 { 377 377 int ret = -EOPNOTSUPP; 378 + 379 + trace_drv_get_survey(local, idx, survey); 380 + 378 381 if (local->ops->get_survey) 379 382 ret = local->ops->get_survey(&local->hw, idx, survey); 380 - /* trace_drv_get_survey(local, idx, survey, ret); */ 383 + 384 + trace_drv_return_int(local, ret); 385 + 381 386 return ret; 382 387 } 383 388
+22
net/mac80211/driver-trace.h
··· 761 761 ) 762 762 ); 763 763 764 + TRACE_EVENT(drv_get_survey, 765 + TP_PROTO(struct ieee80211_local *local, int idx, 766 + struct survey_info *survey), 767 + 768 + TP_ARGS(local, idx, survey), 769 + 770 + TP_STRUCT__entry( 771 + LOCAL_ENTRY 772 + __field(int, idx) 773 + ), 774 + 775 + TP_fast_assign( 776 + LOCAL_ASSIGN; 777 + __entry->idx = idx; 778 + ), 779 + 780 + TP_printk( 781 + LOCAL_PR_FMT " idx:%d", 782 + LOCAL_PR_ARG, __entry->idx 783 + ) 784 + ); 785 + 764 786 TRACE_EVENT(drv_flush, 765 787 TP_PROTO(struct ieee80211_local *local, bool drop), 766 788
+2
net/mac80211/ieee80211_i.h
··· 855 855 * this will override whatever chosen by mac80211 internally. 856 856 */ 857 857 int dynamic_ps_forced_timeout; 858 + int dynamic_ps_user_timeout; 859 + bool disable_dynamic_ps; 858 860 859 861 int user_power_level; /* in dBm */ 860 862 int power_constr_level; /* in dBm */
+31 -11
net/mac80211/mesh_plink.c
··· 65 65 { 66 66 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); 67 67 mesh_accept_plinks_update(sdata); 68 - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 69 68 } 70 69 71 70 static inline ··· 72 73 { 73 74 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); 74 75 mesh_accept_plinks_update(sdata); 75 - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 76 76 } 77 77 78 78 /** ··· 113 115 } 114 116 115 117 /** 116 - * mesh_plink_deactivate - deactivate mesh peer link 118 + * __mesh_plink_deactivate - deactivate mesh peer link 117 119 * 118 120 * @sta: mesh peer link to deactivate 119 121 * ··· 121 123 * 122 124 * Locking: the caller must hold sta->lock 123 125 */ 124 - static void __mesh_plink_deactivate(struct sta_info *sta) 126 + static bool __mesh_plink_deactivate(struct sta_info *sta) 125 127 { 126 128 struct ieee80211_sub_if_data *sdata = sta->sdata; 129 + bool deactivated = false; 127 130 128 - if (sta->plink_state == PLINK_ESTAB) 131 + if (sta->plink_state == PLINK_ESTAB) { 129 132 mesh_plink_dec_estab_count(sdata); 133 + deactivated = true; 134 + } 130 135 sta->plink_state = PLINK_BLOCKED; 131 136 mesh_path_flush_by_nexthop(sta); 137 + 138 + return deactivated; 132 139 } 133 140 134 141 /** 135 - * __mesh_plink_deactivate - deactivate mesh peer link 142 + * mesh_plink_deactivate - deactivate mesh peer link 136 143 * 137 144 * @sta: mesh peer link to deactivate 138 145 * ··· 145 142 */ 146 143 void mesh_plink_deactivate(struct sta_info *sta) 147 144 { 145 + struct ieee80211_sub_if_data *sdata = sta->sdata; 146 + bool deactivated; 147 + 148 148 spin_lock_bh(&sta->lock); 149 - __mesh_plink_deactivate(sta); 149 + deactivated = __mesh_plink_deactivate(sta); 150 150 spin_unlock_bh(&sta->lock); 151 + 152 + if (deactivated) 153 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 151 154 } 152 155 153 156 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, ··· 390 381 391 382 void mesh_plink_block(struct sta_info *sta) 392 383 { 384 + struct ieee80211_sub_if_data *sdata = sta->sdata; 385 + bool deactivated; 386 + 393 387 spin_lock_bh(&sta->lock); 394 - __mesh_plink_deactivate(sta); 388 + deactivated = __mesh_plink_deactivate(sta); 395 389 sta->plink_state = PLINK_BLOCKED; 396 390 spin_unlock_bh(&sta->lock); 391 + 392 + if (deactivated) 393 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 397 394 } 398 395 399 396 ··· 412 397 enum plink_event event; 413 398 enum plink_frame_type ftype; 414 399 size_t baselen; 400 + bool deactivated; 415 401 u8 ie_len; 416 402 u8 *baseaddr; 417 403 __le16 plid, llid, reason; ··· 667 651 case CNF_ACPT: 668 652 del_timer(&sta->plink_timer); 669 653 sta->plink_state = PLINK_ESTAB; 670 - mesh_plink_inc_estab_count(sdata); 671 654 spin_unlock_bh(&sta->lock); 655 + mesh_plink_inc_estab_count(sdata); 656 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 672 657 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 673 658 sta->sta.addr); 674 659 break; ··· 701 684 case OPN_ACPT: 702 685 del_timer(&sta->plink_timer); 703 686 sta->plink_state = PLINK_ESTAB; 704 - mesh_plink_inc_estab_count(sdata); 705 687 spin_unlock_bh(&sta->lock); 688 + mesh_plink_inc_estab_count(sdata); 689 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 706 690 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 707 691 sta->sta.addr); 708 692 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, ··· 720 702 case CLS_ACPT: 721 703 reason = cpu_to_le16(MESH_CLOSE_RCVD); 722 704 sta->reason = reason; 723 - __mesh_plink_deactivate(sta); 705 + deactivated = __mesh_plink_deactivate(sta); 724 706 sta->plink_state = PLINK_HOLDING; 725 707 llid = sta->llid; 726 708 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 727 709 spin_unlock_bh(&sta->lock); 710 + if (deactivated) 711 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 728 712 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 729 713 plid, reason); 730 714 break;
+38 -1
net/mac80211/mlme.c
··· 478 478 } 479 479 } 480 480 481 + void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif) 482 + { 483 + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 484 + struct ieee80211_local *local = sdata->local; 485 + struct ieee80211_conf *conf = &local->hw.conf; 486 + 487 + WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION || 488 + !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) || 489 + (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)); 490 + 491 + local->disable_dynamic_ps = false; 492 + conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout; 493 + } 494 + EXPORT_SYMBOL(ieee80211_enable_dyn_ps); 495 + 496 + void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif) 497 + { 498 + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 499 + struct ieee80211_local *local = sdata->local; 500 + struct ieee80211_conf *conf = &local->hw.conf; 501 + 502 + WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION || 503 + !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) || 504 + (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)); 505 + 506 + local->disable_dynamic_ps = true; 507 + conf->dynamic_ps_timeout = 0; 508 + del_timer_sync(&local->dynamic_ps_timer); 509 + ieee80211_queue_work(&local->hw, 510 + &local->dynamic_ps_enable_work); 511 + } 512 + EXPORT_SYMBOL(ieee80211_disable_dyn_ps); 513 + 481 514 /* powersave */ 482 515 static void ieee80211_enable_ps(struct ieee80211_local *local, 483 516 struct ieee80211_sub_if_data *sdata) ··· 586 553 found->u.mgd.associated->beacon_ies && 587 554 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 588 555 IEEE80211_STA_CONNECTION_POLL))) { 556 + struct ieee80211_conf *conf = &local->hw.conf; 589 557 s32 beaconint_us; 590 558 591 559 if (latency < 0) ··· 609 575 else 610 576 timeout = 100; 611 577 } 612 - local->hw.conf.dynamic_ps_timeout = timeout; 578 + local->dynamic_ps_user_timeout = timeout; 579 + if (!local->disable_dynamic_ps) 580 + conf->dynamic_ps_timeout = 581 + local->dynamic_ps_user_timeout; 613 582 614 583 if (beaconint_us > latency) { 615 584 local->ps_sdata = NULL;
+2 -1
net/mac80211/rc80211_minstrel_ht.c
··· 328 328 } 329 329 330 330 static void 331 - minstrel_downgrade_rate(struct minstrel_ht_sta *mi, int *idx, bool primary) 331 + minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, 332 + bool primary) 332 333 { 333 334 int group, orig_group; 334 335
+2
net/mac80211/rc80211_minstrel_ht.h
··· 29 29 unsigned int duration[MCS_GROUP_RATES]; 30 30 }; 31 31 32 + extern const struct mcs_group minstrel_mcs_groups[]; 33 + 32 34 struct minstrel_rate_stats { 33 35 /* current / last sampling period attempts/success counters */ 34 36 unsigned int attempts, last_attempts;
-2
net/mac80211/rc80211_minstrel_ht_debugfs.c
··· 14 14 #include "rc80211_minstrel.h" 15 15 #include "rc80211_minstrel_ht.h" 16 16 17 - extern const struct mcs_group minstrel_mcs_groups[]; 18 - 19 17 static int 20 18 minstrel_ht_stats_open(struct inode *inode, struct file *file) 21 19 {
+9 -9
net/mac80211/rx.c
··· 293 293 skb2 = skb_clone(skb, GFP_ATOMIC); 294 294 if (skb2) { 295 295 skb2->dev = prev_dev; 296 - netif_rx(skb2); 296 + netif_receive_skb(skb2); 297 297 } 298 298 } 299 299 ··· 304 304 305 305 if (prev_dev) { 306 306 skb->dev = prev_dev; 307 - netif_rx(skb); 307 + netif_receive_skb(skb); 308 308 } else 309 309 dev_kfree_skb(skb); 310 310 ··· 1578 1578 /* deliver to local stack */ 1579 1579 skb->protocol = eth_type_trans(skb, dev); 1580 1580 memset(skb->cb, 0, sizeof(skb->cb)); 1581 - netif_rx(skb); 1581 + netif_receive_skb(skb); 1582 1582 } 1583 1583 } 1584 1584 ··· 2056 2056 nskb = skb_copy_expand(rx->skb, local->hw.extra_tx_headroom, 0, 2057 2057 GFP_ATOMIC); 2058 2058 if (nskb) { 2059 - struct ieee80211_mgmt *mgmt = (void *)nskb->data; 2059 + struct ieee80211_mgmt *nmgmt = (void *)nskb->data; 2060 2060 2061 - mgmt->u.action.category |= 0x80; 2062 - memcpy(mgmt->da, mgmt->sa, ETH_ALEN); 2063 - memcpy(mgmt->sa, rx->sdata->vif.addr, ETH_ALEN); 2061 + nmgmt->u.action.category |= 0x80; 2062 + memcpy(nmgmt->da, nmgmt->sa, ETH_ALEN); 2063 + memcpy(nmgmt->sa, rx->sdata->vif.addr, ETH_ALEN); 2064 2064 2065 2065 memset(nskb->cb, 0, sizeof(nskb->cb)); 2066 2066 ··· 2244 2244 skb2 = skb_clone(skb, GFP_ATOMIC); 2245 2245 if (skb2) { 2246 2246 skb2->dev = prev_dev; 2247 - netif_rx(skb2); 2247 + netif_receive_skb(skb2); 2248 2248 } 2249 2249 } 2250 2250 ··· 2255 2255 2256 2256 if (prev_dev) { 2257 2257 skb->dev = prev_dev; 2258 - netif_rx(skb); 2258 + netif_receive_skb(skb); 2259 2259 skb = NULL; 2260 2260 } else 2261 2261 goto out_free_skb;
+3 -3
net/mac80211/scan.c
··· 286 286 local->scanning = 0; 287 287 local->scan_channel = NULL; 288 288 289 + drv_sw_scan_complete(local); 290 + 289 291 /* we only have to protect scan_req and hw/sw scan */ 290 292 mutex_unlock(&local->scan_mtx); 291 293 ··· 296 294 goto done; 297 295 298 296 ieee80211_configure_filter(local); 299 - 300 - drv_sw_scan_complete(local); 301 297 302 298 ieee80211_offchannel_return(local, true); 303 299 ··· 734 734 { 735 735 struct ieee80211_local *local = sdata->local; 736 736 int ret = -EBUSY; 737 - enum nl80211_band band; 737 + enum ieee80211_band band; 738 738 739 739 mutex_lock(&local->scan_mtx); 740 740
+8 -8
net/mac80211/sta_info.h
··· 427 427 { 428 428 } 429 429 430 - #define for_each_sta_info(local, _addr, sta, nxt) \ 430 + #define for_each_sta_info(local, _addr, _sta, nxt) \ 431 431 for ( /* initialise loop */ \ 432 - sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\ 433 - nxt = sta ? rcu_dereference(sta->hnext) : NULL; \ 432 + _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\ 433 + nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \ 434 434 /* typecheck */ \ 435 - for_each_sta_info_type_check(local, (_addr), sta, nxt), \ 435 + for_each_sta_info_type_check(local, (_addr), _sta, nxt),\ 436 436 /* continue condition */ \ 437 - sta; \ 437 + _sta; \ 438 438 /* advance loop */ \ 439 - sta = nxt, \ 440 - nxt = sta ? rcu_dereference(sta->hnext) : NULL \ 439 + _sta = nxt, \ 440 + nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ 441 441 ) \ 442 442 /* compare address and run code only if it matches */ \ 443 - if (memcmp(sta->sta.addr, (_addr), ETH_ALEN) == 0) 443 + if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) 444 444 445 445 /* 446 446 * Get STA info by index, BROKEN!
+2 -2
net/mac80211/status.c
··· 377 377 skb2 = skb_clone(skb, GFP_ATOMIC); 378 378 if (skb2) { 379 379 skb2->dev = prev_dev; 380 - netif_rx(skb2); 380 + netif_receive_skb(skb2); 381 381 } 382 382 } 383 383 ··· 386 386 } 387 387 if (prev_dev) { 388 388 skb->dev = prev_dev; 389 - netif_rx(skb); 389 + netif_receive_skb(skb); 390 390 skb = NULL; 391 391 } 392 392 rcu_read_unlock();
+1 -1
net/wireless/core.c
··· 894 894 } 895 895 subsys_initcall(cfg80211_init); 896 896 897 - static void cfg80211_exit(void) 897 + static void __exit cfg80211_exit(void) 898 898 { 899 899 debugfs_remove(ieee80211_debugfs_dir); 900 900 nl80211_exit();
+31
net/wireless/nl80211.c
··· 153 153 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, 154 154 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, 155 155 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, 156 + 157 + [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, 158 + [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, 156 159 }; 157 160 158 161 /* policy for the attributes */ ··· 868 865 869 866 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 870 867 result = __nl80211_set_channel(rdev, wdev, info); 868 + if (result) 869 + goto bad_res; 870 + } 871 + 872 + if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { 873 + enum nl80211_tx_power_setting type; 874 + int idx, mbm = 0; 875 + 876 + if (!rdev->ops->set_tx_power) { 877 + return -EOPNOTSUPP; 878 + goto bad_res; 879 + } 880 + 881 + idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING; 882 + type = nla_get_u32(info->attrs[idx]); 883 + 884 + if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] && 885 + (type != NL80211_TX_POWER_AUTOMATIC)) { 886 + result = -EINVAL; 887 + goto bad_res; 888 + } 889 + 890 + if (type != NL80211_TX_POWER_AUTOMATIC) { 891 + idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL; 892 + mbm = nla_get_u32(info->attrs[idx]); 893 + } 894 + 895 + result = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); 871 896 if (result) 872 897 goto bad_res; 873 898 }
+3 -3
net/wireless/reg.c
··· 80 80 * - country_ie_regdomain 81 81 * - last_request 82 82 */ 83 - DEFINE_MUTEX(reg_mutex); 83 + static DEFINE_MUTEX(reg_mutex); 84 84 #define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex)) 85 85 86 86 /* Used to queue up regulatory hints */ ··· 2630 2630 mutex_unlock(&reg_mutex); 2631 2631 } 2632 2632 2633 - int regulatory_init(void) 2633 + int __init regulatory_init(void) 2634 2634 { 2635 2635 int err = 0; 2636 2636 ··· 2676 2676 return 0; 2677 2677 } 2678 2678 2679 - void regulatory_exit(void) 2679 + void /* __init_or_exit */ regulatory_exit(void) 2680 2680 { 2681 2681 struct regulatory_request *reg_request, *tmp; 2682 2682 struct reg_beacon *reg_beacon, *btmp;
+1 -1
net/wireless/reg.h
··· 10 10 11 11 void reg_device_remove(struct wiphy *wiphy); 12 12 13 - int regulatory_init(void); 13 + int __init regulatory_init(void); 14 14 void regulatory_exit(void); 15 15 16 16 int set_regdom(const struct ieee80211_regdomain *rd);
+5 -5
net/wireless/wext-compat.c
··· 829 829 { 830 830 struct wireless_dev *wdev = dev->ieee80211_ptr; 831 831 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 832 - enum tx_power_setting type; 832 + enum nl80211_tx_power_setting type; 833 833 int dbm = 0; 834 834 835 835 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) ··· 852 852 if (data->txpower.value < 0) 853 853 return -EINVAL; 854 854 dbm = data->txpower.value; 855 - type = TX_POWER_FIXED; 855 + type = NL80211_TX_POWER_FIXED; 856 856 /* TODO: do regulatory check! */ 857 857 } else { 858 858 /* ··· 860 860 * passed in from userland. 861 861 */ 862 862 if (data->txpower.value < 0) { 863 - type = TX_POWER_AUTOMATIC; 863 + type = NL80211_TX_POWER_AUTOMATIC; 864 864 } else { 865 865 dbm = data->txpower.value; 866 - type = TX_POWER_LIMITED; 866 + type = NL80211_TX_POWER_LIMITED; 867 867 } 868 868 } 869 869 } else { ··· 872 872 return 0; 873 873 } 874 874 875 - return rdev->ops->set_tx_power(wdev->wiphy, type, dbm); 875 + return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); 876 876 } 877 877 EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); 878 878