| OLD | NEW |
| 1 /* | 1 //------------------------------------------------------------------------------ |
| 2 * | 2 // Copyright (c) 2004-2010 Atheros Communications Inc. |
| 3 * Copyright (c) 2004-2010 Atheros Communications Inc. | 3 // All rights reserved. |
| 4 * All rights reserved. | |
| 5 * | |
| 6 * | |
| 7 // This program is free software; you can redistribute it and/or modify | |
| 8 // it under the terms of the GNU General Public License version 2 as | |
| 9 // published by the Free Software Foundation; | |
| 10 // | 4 // |
| 11 // Software distributed under the License is distributed on an "AS | 5 // |
| 12 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | 6 // |
| 13 // implied. See the License for the specific language governing | 7 // Permission to use, copy, modify, and/or distribute this software for any |
| 14 // rights and limitations under the License. | 8 // purpose with or without fee is hereby granted, provided that the above |
| 9 // copyright notice and this permission notice appear in all copies. |
| 10 // |
| 11 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 12 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 13 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 14 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 15 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 16 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 17 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 15 // | 18 // |
| 16 // | 19 // |
| 17 * | 20 // |
| 18 */ | 21 // Author(s): ="Atheros" |
| 22 //------------------------------------------------------------------------------ |
| 19 | 23 |
| 20 | |
| 21 #include <linux/kernel.h> | |
| 22 #include <linux/netdevice.h> | |
| 23 #include <linux/wireless.h> | 24 #include <linux/wireless.h> |
| 24 #include <linux/ieee80211.h> | 25 #include <linux/ieee80211.h> |
| 25 #include <net/cfg80211.h> | 26 #include <net/cfg80211.h> |
| 26 | 27 |
| 27 #include "ar6000_drv.h" | 28 #include "ar6000_drv.h" |
| 28 | 29 |
| 29 | 30 |
| 30 extern A_WAITQUEUE_HEAD arEvent; | 31 extern A_WAITQUEUE_HEAD arEvent; |
| 31 extern unsigned int wmitimeout; | 32 extern unsigned int wmitimeout; |
| 32 extern int reconnect_flag; | 33 extern int reconnect_flag; |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 535 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
| 535 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); | 536 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); |
| 536 A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN); | 537 A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN); |
| 537 A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN); | 538 A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN); |
| 538 mgmt->u.beacon.beacon_int = beaconInterval; | 539 mgmt->u.beacon.beacon_int = beaconInterval; |
| 539 mgmt->u.beacon.capab_info = capability; | 540 mgmt->u.beacon.capab_info = capability; |
| 540 A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len); | 541 A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len); |
| 541 | 542 |
| 542 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel); | 543 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel); |
| 543 | 544 |
| 544 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, | 545 » AR_DEBUG_PRINTF(ATH_DEBUG_INFO, |
| 545 ("%s: inform bss with bssid %02x:%02x:%02x:%02x:%02x:%02
x "\ | 546 » » ("%s: inform bss with bssid %pM channel %d beaconInterval %d " |
| 546 "channel %d beaconInterval %d capability 0x%x\n", | 547 » » » "capability 0x%x\n", __func__, mgmt->bssid, |
| 547 __func__, | 548 » » » ibss_channel->hw_value, beaconInterval, capability)); |
| 548 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2], | |
| 549 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5], | |
| 550 ibss_channel->hw_value, beaconInterval, capability)); | |
| 551 | 549 |
| 552 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, | 550 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, |
| 553 ibss_channel, mgmt, | 551 ibss_channel, mgmt, |
| 554 le16_to_cpu(size), | 552 le16_to_cpu(size), |
| 555 signal, GFP_KERNEL); | 553 signal, GFP_KERNEL); |
| 556 A_FREE(ieeemgmtbuf); | 554 A_FREE(ieeemgmtbuf); |
| 557 cfg80211_put_bss(bss); | 555 cfg80211_put_bss(bss); |
| 558 } | 556 } |
| 559 | 557 |
| 560 if((ADHOC_NETWORK & networkType)) { | 558 if((ADHOC_NETWORK & networkType)) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); | 703 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); |
| 706 A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN); | 704 A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN); |
| 707 A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN); | 705 A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN); |
| 708 A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u), | 706 A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u), |
| 709 ni->ni_buf, ni->ni_framelen); | 707 ni->ni_buf, ni->ni_framelen); |
| 710 | 708 |
| 711 freq = cie->ie_chan; | 709 freq = cie->ie_chan; |
| 712 channel = ieee80211_get_channel(wiphy, freq); | 710 channel = ieee80211_get_channel(wiphy, freq); |
| 713 signal = ni->ni_snr * 100; | 711 signal = ni->ni_snr * 100; |
| 714 | 712 |
| 715 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, | 713 » AR_DEBUG_PRINTF(ATH_DEBUG_INFO, |
| 716 ("%s: bssid %02x:%02x:%02x:%02x:%02x:%02x channel %d freq %d
size %d\n", | 714 » » ("%s: bssid %pM channel %d freq %d size %d\n", __func__, |
| 717 __func__, | 715 » » » mgmt->bssid, channel->hw_value, freq, size)); |
| 718 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2], | |
| 719 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5], | |
| 720 channel->hw_value, freq, size)); | |
| 721 cfg80211_inform_bss_frame(wiphy, channel, mgmt, | 716 cfg80211_inform_bss_frame(wiphy, channel, mgmt, |
| 722 le16_to_cpu(size), | 717 le16_to_cpu(size), |
| 723 signal, GFP_KERNEL); | 718 signal, GFP_KERNEL); |
| 724 | 719 |
| 725 A_FREE (ieeemgmtbuf); | 720 A_FREE (ieeemgmtbuf); |
| 726 } | 721 } |
| 727 | 722 |
| 728 static int | 723 static int |
| 729 ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | 724 ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, |
| 730 struct cfg80211_scan_request *request) | 725 struct cfg80211_scan_request *request) |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 A_MEMCPY(key->key, params->key, key->key_len); | 853 A_MEMCPY(key->key, params->key, key->key_len); |
| 859 key->seq_len = params->seq_len; | 854 key->seq_len = params->seq_len; |
| 860 A_MEMCPY(key->seq, params->seq, key->seq_len); | 855 A_MEMCPY(key->seq, params->seq, key->seq_len); |
| 861 key->cipher = params->cipher; | 856 key->cipher = params->cipher; |
| 862 } | 857 } |
| 863 | 858 |
| 864 switch (key->cipher) { | 859 switch (key->cipher) { |
| 865 case WLAN_CIPHER_SUITE_WEP40: | 860 case WLAN_CIPHER_SUITE_WEP40: |
| 866 case WLAN_CIPHER_SUITE_WEP104: | 861 case WLAN_CIPHER_SUITE_WEP104: |
| 867 key_type = WEP_CRYPT; | 862 key_type = WEP_CRYPT; |
| 868 if(key_index == ar->arDefTxKeyIndex) { | |
| 869 key_usage = GROUP_USAGE | TX_USAGE; | |
| 870 } | |
| 871 break; | 863 break; |
| 872 | 864 |
| 873 case WLAN_CIPHER_SUITE_TKIP: | 865 case WLAN_CIPHER_SUITE_TKIP: |
| 874 key_type = TKIP_CRYPT; | 866 key_type = TKIP_CRYPT; |
| 875 break; | 867 break; |
| 876 | 868 |
| 877 case WLAN_CIPHER_SUITE_CCMP: | 869 case WLAN_CIPHER_SUITE_CCMP: |
| 878 key_type = AES_CRYPT; | 870 key_type = AES_CRYPT; |
| 879 break; | 871 break; |
| 880 | 872 |
| 881 default: | 873 default: |
| 882 return -ENOTSUPP; | 874 return -ENOTSUPP; |
| 883 } | 875 } |
| 884 | 876 |
| 885 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode))
&& | 877 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode))
&& |
| 886 (GROUP_USAGE & key_usage)) | 878 (GROUP_USAGE & key_usage)) |
| 887 { | 879 { |
| 888 A_UNTIMEOUT(&ar->disconnect_timer); | 880 A_UNTIMEOUT(&ar->disconnect_timer); |
| 889 } | 881 } |
| 890 | 882 |
| 891 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, | 883 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, |
| 892 ("%s: index %d, key_len %d, key_type 0x%x,"\ | 884 ("%s: index %d, key_len %d, key_type 0x%x,"\ |
| 893 " key_usage 0x%x, seq_len %d\n", | 885 " key_usage 0x%x, seq_len %d\n", |
| 894 __func__, key_index, key->key_len, key_type, | 886 __func__, key_index, key->key_len, key_type, |
| 895 key_usage, key->seq_len)); | 887 key_usage, key->seq_len)); |
| 896 | 888 |
| 897 status = wmi_addKey_cmd(ar->arWmi, key_index, key_type, key_usage, | 889 ar->arDefTxKeyIndex = key_index; |
| 890 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage, |
| 898 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, | 891 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, |
| 899 (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG); | 892 (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG); |
| 900 | 893 |
| 901 | 894 |
| 902 if(status != A_OK) { | 895 if(status != A_OK) { |
| 903 return -EIO; | 896 return -EIO; |
| 904 } | 897 } |
| 905 | 898 |
| 906 return 0; | 899 return 0; |
| 907 } | 900 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 973 |
| 981 return key->key_len ? 0 : -ENOENT; | 974 return key->key_len ? 0 : -ENOENT; |
| 982 } | 975 } |
| 983 | 976 |
| 984 | 977 |
| 985 static int | 978 static int |
| 986 ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, | 979 ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, |
| 987 A_UINT8 key_index) | 980 A_UINT8 key_index) |
| 988 { | 981 { |
| 989 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); | 982 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); |
| 983 struct ar_key *key = NULL; |
| 984 A_STATUS status = A_OK; |
| 990 | 985 |
| 991 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); | 986 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); |
| 992 | 987 |
| 993 if(ar->arWmiReady == FALSE) { | 988 if(ar->arWmiReady == FALSE) { |
| 994 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); | 989 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); |
| 995 return -EIO; | 990 return -EIO; |
| 996 } | 991 } |
| 997 | 992 |
| 998 if(ar->arWlanState == WLAN_DISABLED) { | 993 if(ar->arWlanState == WLAN_DISABLED) { |
| 999 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); | 994 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); |
| 1000 return -EIO; | 995 return -EIO; |
| 1001 } | 996 } |
| 1002 | 997 |
| 1003 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { | 998 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { |
| 1004 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, | 999 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, |
| 1005 ("%s: key index %d out of bounds\n", | 1000 ("%s: key index %d out of bounds\n", |
| 1006 __func__, key_index)); | 1001 __func__, key_index)); |
| 1007 return -ENOENT; | 1002 return -ENOENT; |
| 1008 } | 1003 } |
| 1009 | 1004 |
| 1010 if(!ar->keys[key_index].key_len) { | 1005 if(!ar->keys[key_index].key_len) { |
| 1011 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n", | 1006 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n", |
| 1012 __func__, key_index)); | 1007 __func__, key_index)); |
| 1013 return -EINVAL; | 1008 return -EINVAL; |
| 1014 } | 1009 } |
| 1015 | 1010 |
| 1016 ar->arDefTxKeyIndex = key_index; | 1011 ar->arDefTxKeyIndex = key_index; |
| 1012 key = &ar->keys[ar->arDefTxKeyIndex]; |
| 1013 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, |
| 1014 ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE, |
| 1015 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, |
| 1016 NULL, SYNC_BOTH_WMIFLAG); |
| 1017 if (status != A_OK) { |
| 1018 return -EIO; |
| 1019 } |
| 1017 | 1020 |
| 1018 return 0; | 1021 return 0; |
| 1019 } | 1022 } |
| 1020 | 1023 |
| 1021 static int | 1024 static int |
| 1022 ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, | 1025 ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, |
| 1023 A_UINT8 key_index) | 1026 A_UINT8 key_index) |
| 1024 { | 1027 { |
| 1025 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); | 1028 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); |
| 1026 | 1029 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 } | 1079 } |
| 1077 | 1080 |
| 1078 return 0; | 1081 return 0; |
| 1079 } | 1082 } |
| 1080 | 1083 |
| 1081 static int | 1084 static int |
| 1082 ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, | 1085 ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, |
| 1083 const A_UINT8 *peer, | 1086 const A_UINT8 *peer, |
| 1084 const struct cfg80211_bitrate_mask *mask) | 1087 const struct cfg80211_bitrate_mask *mask) |
| 1085 { | 1088 { |
| 1086 AR_SOFTC_T *ar = ar6k_priv(dev); | 1089 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n")); |
| 1087 A_STATUS status; | 1090 return -EIO; |
| 1088 | |
| 1089 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: mask 0x%x\n", __func__, mask->fixed)); | |
| 1090 | |
| 1091 if(ar->arWmiReady == FALSE) { | |
| 1092 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); | |
| 1093 return -EIO; | |
| 1094 } | |
| 1095 | |
| 1096 if(ar->arWlanState == WLAN_DISABLED) { | |
| 1097 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); | |
| 1098 return -EIO; | |
| 1099 } | |
| 1100 | |
| 1101 status = wmi_set_fixrates_cmd(ar->arWmi, mask->fixed); | |
| 1102 | |
| 1103 if(status == A_EINVAL) { | |
| 1104 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: invalid params\n", __func__)); | |
| 1105 return -EINVAL; | |
| 1106 } else if(status != A_OK) { | |
| 1107 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_fixrates_cmd failed\n", __f
unc__)); | |
| 1108 return -EIO; | |
| 1109 } | |
| 1110 | |
| 1111 return 0; | |
| 1112 } | 1091 } |
| 1113 | 1092 |
| 1093 /* The type nl80211_tx_power_setting replaces the following data type from 2.6.3
6 onwards */ |
| 1114 static int | 1094 static int |
| 1115 ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum tx_power_setting type, int d
bm) | 1095 ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum tx_power_setting type, int d
bm) |
| 1116 { | 1096 { |
| 1117 AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); | 1097 AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); |
| 1118 A_UINT8 ar_dbm; | 1098 A_UINT8 ar_dbm; |
| 1119 | 1099 |
| 1120 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type,
dbm)); | 1100 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type,
dbm)); |
| 1121 | 1101 |
| 1122 if(ar->arWmiReady == FALSE) { | 1102 if(ar->arWmiReady == FALSE) { |
| 1123 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); | 1103 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 wiphy_free(wdev->wiphy); | 1461 wiphy_free(wdev->wiphy); |
| 1482 kfree(wdev); | 1462 kfree(wdev); |
| 1483 } | 1463 } |
| 1484 | 1464 |
| 1485 | 1465 |
| 1486 | 1466 |
| 1487 | 1467 |
| 1488 | 1468 |
| 1489 | 1469 |
| 1490 | 1470 |
| OLD | NEW |