aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-08-28 06:27:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:58 -0400
commit5c52323e8c44a06183052986dbd028ce15622166 (patch)
treedf0cd094ba83e2b93f1a1753b1da12092af7e55c
parent9f77ccab57534f45b0289ceae3a6b85478d14182 (diff)
rndis_wlan: add cfg80211 connect, disconnect, join_ibss and leave_ibss
Add cfg80211 connect functions for station and ad-hoc modes and convert wext to use theim. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rndis_wlan.c669
1 files changed, 460 insertions, 209 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index c5a674d8d1f..c2af5be35d3 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -358,13 +358,6 @@ struct ndis_80211_assoc_info {
358 __le32 offset_resp_ies; 358 __le32 offset_resp_ies;
359} __attribute__((packed)); 359} __attribute__((packed));
360 360
361/* these have to match what is in wpa_supplicant */
362enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
363enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
364 CIPHER_WEP104 };
365enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
366 KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
367
368/* 361/*
369 * private data 362 * private data
370 */ 363 */
@@ -379,6 +372,15 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
379#define WORK_LINK_DOWN (1<<1) 372#define WORK_LINK_DOWN (1<<1)
380#define WORK_SET_MULTICAST_LIST (1<<2) 373#define WORK_SET_MULTICAST_LIST (1<<2)
381 374
375#define RNDIS_WLAN_ALG_NONE 0
376#define RNDIS_WLAN_ALG_WEP (1<<0)
377#define RNDIS_WLAN_ALG_TKIP (1<<1)
378#define RNDIS_WLAN_ALG_CCMP (1<<2)
379
380#define RNDIS_WLAN_KEY_MGMT_NONE 0
381#define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0)
382#define RNDIS_WLAN_KEY_MGMT_PSK (1<<1)
383
382#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) 384#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
383 385
384static const struct ieee80211_channel rndis_channels[] = { 386static const struct ieee80211_channel rndis_channels[] = {
@@ -469,15 +471,16 @@ struct rndis_wlan_private {
469 /* hardware state */ 471 /* hardware state */
470 int radio_on; 472 int radio_on;
471 int infra_mode; 473 int infra_mode;
474 bool connected;
472 struct ndis_80211_ssid essid; 475 struct ndis_80211_ssid essid;
473 __le32 current_command_oid; 476 __le32 current_command_oid;
474 477
475 /* encryption stuff */ 478 /* encryption stuff */
476 int encr_tx_key_index; 479 int encr_tx_key_index;
477 struct rndis_wlan_encr_key encr_keys[4]; 480 struct rndis_wlan_encr_key encr_keys[4];
481 enum nl80211_auth_type wpa_auth_type;
478 int wpa_version; 482 int wpa_version;
479 int wpa_keymgmt; 483 int wpa_keymgmt;
480 int wpa_authalg;
481 int wpa_ie_len; 484 int wpa_ie_len;
482 u8 *wpa_ie; 485 u8 *wpa_ie;
483 int wpa_cipher_pair; 486 int wpa_cipher_pair;
@@ -503,12 +506,27 @@ static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
503 int dbm); 506 int dbm);
504static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); 507static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm);
505 508
509static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
510 struct cfg80211_connect_params *sme);
511
512static int rndis_disconnect(struct wiphy *wiphy, struct net_device *dev,
513 u16 reason_code);
514
515static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
516 struct cfg80211_ibss_params *params);
517
518static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
519
506static struct cfg80211_ops rndis_config_ops = { 520static struct cfg80211_ops rndis_config_ops = {
507 .change_virtual_intf = rndis_change_virtual_intf, 521 .change_virtual_intf = rndis_change_virtual_intf,
508 .scan = rndis_scan, 522 .scan = rndis_scan,
509 .set_wiphy_params = rndis_set_wiphy_params, 523 .set_wiphy_params = rndis_set_wiphy_params,
510 .set_tx_power = rndis_set_tx_power, 524 .set_tx_power = rndis_set_tx_power,
511 .get_tx_power = rndis_get_tx_power, 525 .get_tx_power = rndis_get_tx_power,
526 .connect = rndis_connect,
527 .disconnect = rndis_disconnect,
528 .join_ibss = rndis_join_ibss,
529 .leave_ibss = rndis_leave_ibss,
512}; 530};
513 531
514static void *rndis_wiphy_privid = &rndis_wiphy_privid; 532static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -545,6 +563,34 @@ static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
545} 563}
546 564
547 565
566static int rndis_cipher_to_alg(u32 cipher)
567{
568 switch (cipher) {
569 default:
570 return RNDIS_WLAN_ALG_NONE;
571 case WLAN_CIPHER_SUITE_WEP40:
572 case WLAN_CIPHER_SUITE_WEP104:
573 return RNDIS_WLAN_ALG_WEP;
574 case WLAN_CIPHER_SUITE_TKIP:
575 return RNDIS_WLAN_ALG_TKIP;
576 case WLAN_CIPHER_SUITE_CCMP:
577 return RNDIS_WLAN_ALG_CCMP;
578 }
579}
580
581static int rndis_akm_suite_to_key_mgmt(u32 akm_suite)
582{
583 switch (akm_suite) {
584 default:
585 return RNDIS_WLAN_KEY_MGMT_NONE;
586 case WLAN_AKM_SUITE_8021X:
587 return RNDIS_WLAN_KEY_MGMT_802_1X;
588 case WLAN_AKM_SUITE_PSK:
589 return RNDIS_WLAN_KEY_MGMT_PSK;
590 }
591}
592
593
548#ifdef DEBUG 594#ifdef DEBUG
549static const char *oid_to_string(__le32 oid) 595static const char *oid_to_string(__le32 oid)
550{ 596{
@@ -925,35 +971,16 @@ static int set_infra_mode(struct usbnet *usbdev, int mode);
925static void restore_keys(struct usbnet *usbdev); 971static void restore_keys(struct usbnet *usbdev);
926static int rndis_check_bssid_list(struct usbnet *usbdev); 972static int rndis_check_bssid_list(struct usbnet *usbdev);
927 973
928static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
929{
930 int ret, len;
931
932 len = sizeof(*ssid);
933 ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
934
935 if (ret != 0)
936 ssid->length = 0;
937
938#ifdef DEBUG
939 {
940 unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
941
942 memcpy(tmp, ssid->essid, le32_to_cpu(ssid->length));
943 tmp[le32_to_cpu(ssid->length)] = 0;
944 devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
945 }
946#endif
947 return ret;
948}
949
950
951static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) 974static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
952{ 975{
953 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 976 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
954 int ret; 977 int ret;
955 978
956 ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); 979 ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
980 if (ret < 0) {
981 devwarn(usbdev, "setting SSID failed (%08X)", ret);
982 return ret;
983 }
957 if (ret == 0) { 984 if (ret == 0) {
958 memcpy(&priv->essid, ssid, sizeof(priv->essid)); 985 memcpy(&priv->essid, ssid, sizeof(priv->essid));
959 priv->radio_on = 1; 986 priv->radio_on = 1;
@@ -963,6 +990,25 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
963 return ret; 990 return ret;
964} 991}
965 992
993static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
994{
995 int ret;
996
997 ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
998 if (ret < 0) {
999 devwarn(usbdev, "setting BSSID[%pM] failed (%08X)", bssid, ret);
1000 return ret;
1001 }
1002
1003 return ret;
1004}
1005
1006static int clear_bssid(struct usbnet *usbdev)
1007{
1008 u8 broadcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1009
1010 return set_bssid(usbdev, broadcast_mac);
1011}
966 1012
967static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) 1013static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
968{ 1014{
@@ -984,11 +1030,15 @@ static int get_association_info(struct usbnet *usbdev,
984 info, &len); 1030 info, &len);
985} 1031}
986 1032
987static int is_associated(struct usbnet *usbdev) 1033static bool is_associated(struct usbnet *usbdev)
988{ 1034{
1035 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
989 u8 bssid[ETH_ALEN]; 1036 u8 bssid[ETH_ALEN];
990 int ret; 1037 int ret;
991 1038
1039 if (!priv->radio_on)
1040 return false;
1041
992 ret = get_bssid(usbdev, bssid); 1042 ret = get_bssid(usbdev, bssid);
993 1043
994 return (ret == 0 && !is_zero_ether_addr(bssid)); 1044 return (ret == 0 && !is_zero_ether_addr(bssid));
@@ -1032,34 +1082,34 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
1032} 1082}
1033 1083
1034 1084
1035static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) 1085static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
1086 enum nl80211_auth_type auth_type, int keymgmt)
1036{ 1087{
1037 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1088 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1038 __le32 tmp; 1089 __le32 tmp;
1039 int auth_mode, ret; 1090 int auth_mode, ret;
1040 1091
1041 devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x " 1092 devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
1042 "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt); 1093 "keymgmt=0x%x", wpa_version, auth_type, keymgmt);
1043 1094
1044 if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { 1095 if (wpa_version & NL80211_WPA_VERSION_2) {
1045 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) 1096 if (keymgmt & RNDIS_WLAN_KEY_MGMT_802_1X)
1046 auth_mode = NDIS_80211_AUTH_WPA2; 1097 auth_mode = NDIS_80211_AUTH_WPA2;
1047 else 1098 else
1048 auth_mode = NDIS_80211_AUTH_WPA2_PSK; 1099 auth_mode = NDIS_80211_AUTH_WPA2_PSK;
1049 } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { 1100 } else if (wpa_version & NL80211_WPA_VERSION_1) {
1050 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) 1101 if (keymgmt & RNDIS_WLAN_KEY_MGMT_802_1X)
1051 auth_mode = NDIS_80211_AUTH_WPA; 1102 auth_mode = NDIS_80211_AUTH_WPA;
1052 else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) 1103 else if (keymgmt & RNDIS_WLAN_KEY_MGMT_PSK)
1053 auth_mode = NDIS_80211_AUTH_WPA_PSK; 1104 auth_mode = NDIS_80211_AUTH_WPA_PSK;
1054 else 1105 else
1055 auth_mode = NDIS_80211_AUTH_WPA_NONE; 1106 auth_mode = NDIS_80211_AUTH_WPA_NONE;
1056 } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { 1107 } else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
1057 if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) 1108 auth_mode = NDIS_80211_AUTH_SHARED;
1058 auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; 1109 else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
1059 else
1060 auth_mode = NDIS_80211_AUTH_SHARED;
1061 } else
1062 auth_mode = NDIS_80211_AUTH_OPEN; 1110 auth_mode = NDIS_80211_AUTH_OPEN;
1111 else
1112 return -ENOTSUPP;
1063 1113
1064 tmp = cpu_to_le32(auth_mode); 1114 tmp = cpu_to_le32(auth_mode);
1065 ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, 1115 ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
@@ -1070,7 +1120,9 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
1070 } 1120 }
1071 1121
1072 priv->wpa_version = wpa_version; 1122 priv->wpa_version = wpa_version;
1073 priv->wpa_authalg = authalg; 1123 priv->wpa_auth_type = auth_type;
1124 priv->wpa_keymgmt = keymgmt;
1125
1074 return 0; 1126 return 0;
1075} 1127}
1076 1128
@@ -1082,8 +1134,8 @@ static int set_priv_filter(struct usbnet *usbdev)
1082 1134
1083 devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); 1135 devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
1084 1136
1085 if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || 1137 if (priv->wpa_version & NL80211_WPA_VERSION_2 ||
1086 priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) 1138 priv->wpa_version & NL80211_WPA_VERSION_1)
1087 tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP); 1139 tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP);
1088 else 1140 else
1089 tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); 1141 tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
@@ -1100,19 +1152,17 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1100 int encr_mode, ret; 1152 int encr_mode, ret;
1101 1153
1102 devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x", 1154 devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
1103 pairwise, 1155 pairwise, groupwise);
1104 groupwise);
1105 1156
1106 if (pairwise & IW_AUTH_CIPHER_CCMP) 1157 if (pairwise & RNDIS_WLAN_ALG_CCMP)
1107 encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; 1158 encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
1108 else if (pairwise & IW_AUTH_CIPHER_TKIP) 1159 else if (pairwise & RNDIS_WLAN_ALG_TKIP)
1109 encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; 1160 encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
1110 else if (pairwise & 1161 else if (pairwise & RNDIS_WLAN_ALG_WEP)
1111 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
1112 encr_mode = NDIS_80211_ENCR_WEP_ENABLED; 1162 encr_mode = NDIS_80211_ENCR_WEP_ENABLED;
1113 else if (groupwise & IW_AUTH_CIPHER_CCMP) 1163 else if (groupwise & RNDIS_WLAN_ALG_CCMP)
1114 encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; 1164 encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
1115 else if (groupwise & IW_AUTH_CIPHER_TKIP) 1165 else if (groupwise & RNDIS_WLAN_ALG_TKIP)
1116 encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; 1166 encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
1117 else 1167 else
1118 encr_mode = NDIS_80211_ENCR_DISABLED; 1168 encr_mode = NDIS_80211_ENCR_DISABLED;
@@ -1131,18 +1181,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1131} 1181}
1132 1182
1133 1183
1134static int set_assoc_params(struct usbnet *usbdev)
1135{
1136 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1137
1138 set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
1139 set_priv_filter(usbdev);
1140 set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
1141
1142 return 0;
1143}
1144
1145
1146static int set_infra_mode(struct usbnet *usbdev, int mode) 1184static int set_infra_mode(struct usbnet *usbdev, int mode)
1147{ 1185{
1148 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1186 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1201,16 +1239,11 @@ static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
1201 1239
1202static void set_default_iw_params(struct usbnet *usbdev) 1240static void set_default_iw_params(struct usbnet *usbdev)
1203{ 1241{
1204 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1205
1206 priv->wpa_keymgmt = 0;
1207 priv->wpa_version = 0;
1208
1209 set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); 1242 set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
1210 set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 1243 set_auth_mode(usbdev, 0, NL80211_AUTHTYPE_OPEN_SYSTEM,
1211 IW_AUTH_ALG_OPEN_SYSTEM); 1244 RNDIS_WLAN_KEY_MGMT_NONE);
1212 set_priv_filter(usbdev); 1245 set_priv_filter(usbdev);
1213 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); 1246 set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
1214} 1247}
1215 1248
1216 1249
@@ -1224,8 +1257,40 @@ static int deauthenticate(struct usbnet *usbdev)
1224} 1257}
1225 1258
1226 1259
1260static int set_channel(struct usbnet *usbdev, int channel)
1261{
1262 struct ndis_80211_conf config;
1263 unsigned int dsconfig;
1264 int len, ret;
1265
1266 devdbg(usbdev, "set_channel(%d)", channel);
1267
1268 /* this OID is valid only when not associated */
1269 if (is_associated(usbdev))
1270 return 0;
1271
1272 dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000;
1273
1274 len = sizeof(config);
1275 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
1276 if (ret < 0) {
1277 devdbg(usbdev, "set_channel: querying configuration failed");
1278 return ret;
1279 }
1280
1281 config.ds_config = cpu_to_le32(dsconfig);
1282 ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
1283 sizeof(config));
1284
1285 devdbg(usbdev, "set_channel: %d -> %d", channel, ret);
1286
1287 return ret;
1288}
1289
1290
1227/* index must be 0 - N, as per NDIS */ 1291/* index must be 0 - N, as per NDIS */
1228static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) 1292static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1293 int index)
1229{ 1294{
1230 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1295 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1231 struct ndis_80211_wep_key ndis_key; 1296 struct ndis_80211_wep_key ndis_key;
@@ -1248,8 +1313,8 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
1248 1313
1249 if (index == priv->encr_tx_key_index) { 1314 if (index == priv->encr_tx_key_index) {
1250 ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY; 1315 ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY;
1251 ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, 1316 ret = set_encr_mode(usbdev, RNDIS_WLAN_ALG_WEP,
1252 IW_AUTH_CIPHER_NONE); 1317 RNDIS_WLAN_ALG_NONE);
1253 if (ret) 1318 if (ret)
1254 devwarn(usbdev, "encryption couldn't be enabled (%08X)", 1319 devwarn(usbdev, "encryption couldn't be enabled (%08X)",
1255 ret); 1320 ret);
@@ -1458,7 +1523,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
1458 1523
1459 /* if it is transmit key, disable encryption */ 1524 /* if it is transmit key, disable encryption */
1460 if (index == priv->encr_tx_key_index) 1525 if (index == priv->encr_tx_key_index)
1461 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); 1526 set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
1462 1527
1463 return 0; 1528 return 0;
1464} 1529}
@@ -1765,6 +1830,243 @@ static void rndis_get_scan_results(struct work_struct *work)
1765 priv->scan_request = NULL; 1830 priv->scan_request = NULL;
1766} 1831}
1767 1832
1833static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
1834 struct cfg80211_connect_params *sme)
1835{
1836 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
1837 struct usbnet *usbdev = priv->usbdev;
1838 struct ieee80211_channel *channel = sme->channel;
1839 struct ndis_80211_ssid ssid;
1840 int pairwise = RNDIS_WLAN_ALG_NONE;
1841 int groupwise = RNDIS_WLAN_ALG_NONE;
1842 int keymgmt = RNDIS_WLAN_KEY_MGMT_NONE;
1843 int length, i, ret, chan = -1;
1844
1845 if (channel)
1846 chan = ieee80211_frequency_to_channel(channel->center_freq);
1847
1848 groupwise = rndis_cipher_to_alg(sme->crypto.cipher_group);
1849 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
1850 pairwise |=
1851 rndis_cipher_to_alg(sme->crypto.ciphers_pairwise[i]);
1852
1853 if (sme->crypto.n_ciphers_pairwise > 0 &&
1854 pairwise == RNDIS_WLAN_ALG_NONE) {
1855 deverr(usbdev, "Unsupported pairwise cipher");
1856 return -ENOTSUPP;
1857 }
1858
1859 for (i = 0; i < sme->crypto.n_akm_suites; i++)
1860 keymgmt |=
1861 rndis_akm_suite_to_key_mgmt(sme->crypto.akm_suites[i]);
1862
1863 if (sme->crypto.n_akm_suites > 0 &&
1864 keymgmt == RNDIS_WLAN_KEY_MGMT_NONE) {
1865 deverr(usbdev, "Invalid keymgmt");
1866 return -ENOTSUPP;
1867 }
1868
1869 devdbg(usbdev, "cfg80211.connect('%.32s':[%pM]:%d:[%d,0x%x:0x%x]:[0x%x:"
1870 "0x%x]:0x%x)", sme->ssid, sme->bssid, chan,
1871 sme->privacy, sme->crypto.wpa_versions, sme->auth_type,
1872 groupwise, pairwise, keymgmt);
1873
1874 if (is_associated(usbdev))
1875 disassociate(usbdev, false);
1876
1877 ret = set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
1878 if (ret < 0) {
1879 devdbg(usbdev, "connect: set_infra_mode failed, %d", ret);
1880 goto err_turn_radio_on;
1881 }
1882
1883 ret = set_auth_mode(usbdev, sme->crypto.wpa_versions, sme->auth_type,
1884 keymgmt);
1885 if (ret < 0) {
1886 devdbg(usbdev, "connect: set_auth_mode failed, %d", ret);
1887 goto err_turn_radio_on;
1888 }
1889
1890 set_priv_filter(usbdev);
1891
1892 ret = set_encr_mode(usbdev, pairwise, groupwise);
1893 if (ret < 0) {
1894 devdbg(usbdev, "connect: set_encr_mode failed, %d", ret);
1895 goto err_turn_radio_on;
1896 }
1897
1898 if (channel) {
1899 ret = set_channel(usbdev, chan);
1900 if (ret < 0) {
1901 devdbg(usbdev, "connect: set_channel failed, %d", ret);
1902 goto err_turn_radio_on;
1903 }
1904 }
1905
1906 if (sme->key && ((groupwise | pairwise) & RNDIS_WLAN_ALG_WEP)) {
1907 priv->encr_tx_key_index = sme->key_idx;
1908 ret = add_wep_key(usbdev, sme->key, sme->key_len, sme->key_idx);
1909 if (ret < 0) {
1910 devdbg(usbdev, "connect: add_wep_key failed, %d "
1911 "(%d, %d)", ret, sme->key_len, sme->key_idx);
1912 goto err_turn_radio_on;
1913 }
1914 }
1915
1916 if (sme->bssid && !is_zero_ether_addr(sme->bssid) &&
1917 !is_broadcast_ether_addr(sme->bssid)) {
1918 ret = set_bssid(usbdev, sme->bssid);
1919 if (ret < 0) {
1920 devdbg(usbdev, "connect: set_bssid failed, %d", ret);
1921 goto err_turn_radio_on;
1922 }
1923 } else
1924 clear_bssid(usbdev);
1925
1926 length = sme->ssid_len;
1927 if (length > NDIS_802_11_LENGTH_SSID)
1928 length = NDIS_802_11_LENGTH_SSID;
1929
1930 memset(&ssid, 0, sizeof(ssid));
1931 ssid.length = cpu_to_le32(length);
1932 memcpy(ssid.essid, sme->ssid, length);
1933
1934 /* Pause and purge rx queue, so we don't pass packets before
1935 * 'media connect'-indication.
1936 */
1937 usbnet_pause_rx(usbdev);
1938 usbnet_purge_paused_rxq(usbdev);
1939
1940 ret = set_essid(usbdev, &ssid);
1941 if (ret < 0)
1942 devdbg(usbdev, "connect: set_essid failed, %d", ret);
1943 return ret;
1944
1945err_turn_radio_on:
1946 disassociate(usbdev, 1);
1947
1948 return ret;
1949}
1950
1951static int rndis_disconnect(struct wiphy *wiphy, struct net_device *dev,
1952 u16 reason_code)
1953{
1954 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
1955 struct usbnet *usbdev = priv->usbdev;
1956
1957 devdbg(usbdev, "cfg80211.disconnect(%d)", reason_code);
1958
1959 priv->connected = false;
1960
1961 return deauthenticate(usbdev);
1962}
1963
1964static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1965 struct cfg80211_ibss_params *params)
1966{
1967 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
1968 struct usbnet *usbdev = priv->usbdev;
1969 struct ieee80211_channel *channel = params->channel;
1970 struct ndis_80211_ssid ssid;
1971 enum nl80211_auth_type auth_type;
1972 int ret, alg, length, chan = -1;
1973
1974 if (channel)
1975 chan = ieee80211_frequency_to_channel(channel->center_freq);
1976
1977 /* TODO: How to handle ad-hoc encryption?
1978 * connect() has *key, join_ibss() doesn't. RNDIS requires key to be
1979 * pre-shared for encryption (open/shared/wpa), is key set before
1980 * join_ibss? Which auth_type to use (not in params)? What about WPA?
1981 */
1982 if (params->privacy) {
1983 auth_type = NL80211_AUTHTYPE_SHARED_KEY;
1984 alg = RNDIS_WLAN_ALG_WEP;
1985 } else {
1986 auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1987 alg = RNDIS_WLAN_ALG_NONE;
1988 }
1989
1990 devdbg(usbdev, "cfg80211.join_ibss('%.32s':[%pM]:%d:%d)", params->ssid,
1991 params->bssid, chan, params->privacy);
1992
1993 if (is_associated(usbdev))
1994 disassociate(usbdev, false);
1995
1996 ret = set_infra_mode(usbdev, NDIS_80211_INFRA_ADHOC);
1997 if (ret < 0) {
1998 devdbg(usbdev, "join_ibss: set_infra_mode failed, %d", ret);
1999 goto err_turn_radio_on;
2000 }
2001
2002 ret = set_auth_mode(usbdev, 0, auth_type, RNDIS_WLAN_KEY_MGMT_NONE);
2003 if (ret < 0) {
2004 devdbg(usbdev, "join_ibss: set_auth_mode failed, %d", ret);
2005 goto err_turn_radio_on;
2006 }
2007
2008 set_priv_filter(usbdev);
2009
2010 ret = set_encr_mode(usbdev, alg, RNDIS_WLAN_ALG_NONE);
2011 if (ret < 0) {
2012 devdbg(usbdev, "join_ibss: set_encr_mode failed, %d", ret);
2013 goto err_turn_radio_on;
2014 }
2015
2016 if (channel) {
2017 ret = set_channel(usbdev, chan);
2018 if (ret < 0) {
2019 devdbg(usbdev, "join_ibss: set_channel failed, %d",
2020 ret);
2021 goto err_turn_radio_on;
2022 }
2023 }
2024
2025 if (params->bssid && !is_zero_ether_addr(params->bssid) &&
2026 !is_broadcast_ether_addr(params->bssid)) {
2027 ret = set_bssid(usbdev, params->bssid);
2028 if (ret < 0) {
2029 devdbg(usbdev, "join_ibss: set_bssid failed, %d", ret);
2030 goto err_turn_radio_on;
2031 }
2032 } else
2033 clear_bssid(usbdev);
2034
2035 length = params->ssid_len;
2036 if (length > NDIS_802_11_LENGTH_SSID)
2037 length = NDIS_802_11_LENGTH_SSID;
2038
2039 memset(&ssid, 0, sizeof(ssid));
2040 ssid.length = cpu_to_le32(length);
2041 memcpy(ssid.essid, params->ssid, length);
2042
2043 /* Don't need to pause rx queue for ad-hoc. */
2044 usbnet_purge_paused_rxq(usbdev);
2045 usbnet_resume_rx(usbdev);
2046
2047 ret = set_essid(usbdev, &ssid);
2048 if (ret < 0)
2049 devdbg(usbdev, "join_ibss: set_essid failed, %d", ret);
2050 return ret;
2051
2052err_turn_radio_on:
2053 disassociate(usbdev, 1);
2054
2055 return ret;
2056}
2057
2058static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2059{
2060 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2061 struct usbnet *usbdev = priv->usbdev;
2062
2063 devdbg(usbdev, "cfg80211.leave_ibss()");
2064
2065 priv->connected = false;
2066
2067 return deauthenticate(usbdev);
2068}
2069
1768 2070
1769/* 2071/*
1770 * wireless extension handlers 2072 * wireless extension handlers
@@ -1777,7 +2079,10 @@ static int rndis_iw_commit(struct net_device *dev,
1777 return 0; 2079 return 0;
1778} 2080}
1779 2081
1780 2082#if 0
2083/* Commented code out instead of removing to have more sane patch for review.
2084 * Will be removed later in the set.
2085 */
1781static int rndis_iw_set_essid(struct net_device *dev, 2086static int rndis_iw_set_essid(struct net_device *dev,
1782 struct iw_request_info *info, union iwreq_data *wrqu, char *essid) 2087 struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
1783{ 2088{
@@ -1990,6 +2295,7 @@ static int rndis_iw_get_auth(struct net_device *dev,
1990 } 2295 }
1991 return 0; 2296 return 0;
1992} 2297}
2298#endif
1993 2299
1994 2300
1995static int rndis_iw_set_encode(struct net_device *dev, 2301static int rndis_iw_set_encode(struct net_device *dev,
@@ -2024,11 +2330,11 @@ static int rndis_iw_set_encode(struct net_device *dev,
2024 2330
2025 /* global encryption state (for all keys) */ 2331 /* global encryption state (for all keys) */
2026 if (wrqu->data.flags & IW_ENCODE_OPEN) 2332 if (wrqu->data.flags & IW_ENCODE_OPEN)
2027 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 2333 ret = set_auth_mode(usbdev, 0, NL80211_AUTHTYPE_OPEN_SYSTEM,
2028 IW_AUTH_ALG_OPEN_SYSTEM); 2334 RNDIS_WLAN_KEY_MGMT_NONE);
2029 else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/ 2335 else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
2030 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 2336 ret = set_auth_mode(usbdev, 0, NL80211_AUTHTYPE_SHARED_KEY,
2031 IW_AUTH_ALG_SHARED_KEY); 2337 RNDIS_WLAN_KEY_MGMT_NONE);
2032 if (ret != 0) 2338 if (ret != 0)
2033 return ret; 2339 return ret;
2034 2340
@@ -2077,7 +2383,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
2077 return -EINVAL; 2383 return -EINVAL;
2078 } 2384 }
2079 2385
2080 if (ext->alg == WPA_ALG_WEP) { 2386 if (ext->alg == IW_ENCODE_ALG_WEP) {
2081 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 2387 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2082 priv->encr_tx_key_index = keyidx; 2388 priv->encr_tx_key_index = keyidx;
2083 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx); 2389 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
@@ -2110,63 +2416,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
2110} 2416}
2111 2417
2112 2418
2113static int rndis_iw_set_genie(struct net_device *dev,
2114 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2115{
2116 struct usbnet *usbdev = netdev_priv(dev);
2117 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2118 int ret = 0;
2119
2120#ifdef DEBUG
2121 int j;
2122 u8 *gie = extra;
2123 for (j = 0; j < wrqu->data.length; j += 8)
2124 devdbg(usbdev,
2125 "SIOCSIWGENIE %04x - "
2126 "%02x %02x %02x %02x %02x %02x %02x %02x", j,
2127 gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
2128 gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
2129#endif
2130 /* clear existing IEs */
2131 if (priv->wpa_ie_len) {
2132 kfree(priv->wpa_ie);
2133 priv->wpa_ie_len = 0;
2134 }
2135
2136 /* set new IEs */
2137 priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
2138 if (priv->wpa_ie) {
2139 priv->wpa_ie_len = wrqu->data.length;
2140 memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
2141 } else
2142 ret = -ENOMEM;
2143 return ret;
2144}
2145
2146
2147static int rndis_iw_get_genie(struct net_device *dev,
2148 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2149{
2150 struct usbnet *usbdev = netdev_priv(dev);
2151 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2152
2153 devdbg(usbdev, "SIOCGIWGENIE");
2154
2155 if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
2156 wrqu->data.length = 0;
2157 return 0;
2158 }
2159
2160 if (wrqu->data.length < priv->wpa_ie_len)
2161 return -E2BIG;
2162
2163 wrqu->data.length = priv->wpa_ie_len;
2164 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
2165
2166 return 0;
2167}
2168
2169
2170static int rndis_iw_set_freq(struct net_device *dev, 2419static int rndis_iw_set_freq(struct net_device *dev,
2171 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2420 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2172{ 2421{
@@ -2233,32 +2482,6 @@ static int rndis_iw_get_rate(struct net_device *dev,
2233} 2482}
2234 2483
2235 2484
2236static int rndis_iw_set_mlme(struct net_device *dev,
2237 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2238{
2239 struct usbnet *usbdev = netdev_priv(dev);
2240 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2241 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2242 unsigned char bssid[ETH_ALEN];
2243
2244 get_bssid(usbdev, bssid);
2245
2246 if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
2247 return -EINVAL;
2248
2249 switch (mlme->cmd) {
2250 case IW_MLME_DEAUTH:
2251 return deauthenticate(usbdev);
2252 case IW_MLME_DISASSOC:
2253 return disassociate(usbdev, priv->radio_on);
2254 default:
2255 return -EOPNOTSUPP;
2256 }
2257
2258 return 0;
2259}
2260
2261
2262static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) 2485static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
2263{ 2486{
2264 struct usbnet *usbdev = netdev_priv(dev); 2487 struct usbnet *usbdev = netdev_priv(dev);
@@ -2283,12 +2506,12 @@ static const iw_handler rndis_iw_handler[] =
2283 IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode, 2506 IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode,
2284 IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode, 2507 IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode,
2285 IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange, 2508 IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange,
2286 IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid, 2509 IW_IOCTL(SIOCSIWAP) = (iw_handler) cfg80211_wext_siwap,
2287 IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid, 2510 IW_IOCTL(SIOCGIWAP) = (iw_handler) cfg80211_wext_giwap,
2288 IW_IOCTL(SIOCSIWSCAN) = (iw_handler) cfg80211_wext_siwscan, 2511 IW_IOCTL(SIOCSIWSCAN) = (iw_handler) cfg80211_wext_siwscan,
2289 IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan, 2512 IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan,
2290 IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid, 2513 IW_IOCTL(SIOCSIWESSID) = (iw_handler) cfg80211_wext_siwessid,
2291 IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid, 2514 IW_IOCTL(SIOCGIWESSID) = (iw_handler) cfg80211_wext_giwessid,
2292 IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate, 2515 IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
2293 IW_IOCTL(SIOCSIWRTS) = (iw_handler) cfg80211_wext_siwrts, 2516 IW_IOCTL(SIOCSIWRTS) = (iw_handler) cfg80211_wext_siwrts,
2294 IW_IOCTL(SIOCGIWRTS) = (iw_handler) cfg80211_wext_giwrts, 2517 IW_IOCTL(SIOCGIWRTS) = (iw_handler) cfg80211_wext_giwrts,
@@ -2298,11 +2521,10 @@ static const iw_handler rndis_iw_handler[] =
2298 IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) cfg80211_wext_giwtxpower, 2521 IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) cfg80211_wext_giwtxpower,
2299 IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode, 2522 IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode,
2300 IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext, 2523 IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
2301 IW_IOCTL(SIOCSIWAUTH) = rndis_iw_set_auth, 2524 IW_IOCTL(SIOCSIWAUTH) = (iw_handler) cfg80211_wext_siwauth,
2302 IW_IOCTL(SIOCGIWAUTH) = rndis_iw_get_auth, 2525 IW_IOCTL(SIOCGIWAUTH) = (iw_handler) cfg80211_wext_giwauth,
2303 IW_IOCTL(SIOCSIWGENIE) = rndis_iw_set_genie, 2526 IW_IOCTL(SIOCSIWGENIE) = (iw_handler) cfg80211_wext_siwgenie,
2304 IW_IOCTL(SIOCGIWGENIE) = rndis_iw_get_genie, 2527 IW_IOCTL(SIOCSIWMLME) = (iw_handler) cfg80211_wext_siwmlme,
2305 IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme,
2306}; 2528};
2307 2529
2308static const iw_handler rndis_wlan_private_handler[] = { 2530static const iw_handler rndis_wlan_private_handler[] = {
@@ -2325,49 +2547,78 @@ static const struct iw_handler_def rndis_iw_handlers = {
2325 2547
2326static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) 2548static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2327{ 2549{
2550 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2328 struct ndis_80211_assoc_info *info; 2551 struct ndis_80211_assoc_info *info;
2329 union iwreq_data evt;
2330 u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32]; 2552 u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32];
2331 u8 bssid[ETH_ALEN]; 2553 u8 bssid[ETH_ALEN];
2554 int resp_ie_len, req_ie_len;
2555 u8 *req_ie, *resp_ie;
2332 int ret, offset; 2556 int ret, offset;
2557 bool roamed = false;
2558
2559 if (priv->infra_mode == NDIS_80211_INFRA_INFRA && priv->connected) {
2560 /* received media connect indication while connected, either
2561 * device reassociated with same AP or roamed to new. */
2562 roamed = true;
2563 }
2564
2565 req_ie_len = 0;
2566 resp_ie_len = 0;
2567 req_ie = NULL;
2568 resp_ie = NULL;
2569
2570 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
2571 memset(assoc_buf, 0, sizeof(assoc_buf));
2572 info = (void *)assoc_buf;
2573
2574 /* Get association info IEs from device and send them back to
2575 * userspace. */
2576 ret = get_association_info(usbdev, info, sizeof(assoc_buf));
2577 if (!ret) {
2578 req_ie_len = le32_to_cpu(info->req_ie_length);
2579 if (req_ie_len > 0) {
2580 offset = le32_to_cpu(info->offset_req_ies);
2581 req_ie = (u8 *)info + offset;
2582 }
2333 2583
2334 memset(assoc_buf, 0, sizeof(assoc_buf)); 2584 resp_ie_len = le32_to_cpu(info->resp_ie_length);
2335 info = (void *)assoc_buf; 2585 if (resp_ie_len > 0) {
2586 offset = le32_to_cpu(info->offset_resp_ies);
2587 resp_ie = (u8 *)info + offset;
2588 }
2589 }
2590 } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
2591 return;
2336 2592
2337 netif_carrier_on(usbdev->net); 2593 ret = get_bssid(usbdev, bssid);
2594 if (ret < 0)
2595 memset(bssid, 0, sizeof(bssid));
2338 2596
2339 /* Get association info IEs from device and send them back to 2597 devdbg(usbdev, "link up work: [%pM] %s", bssid, roamed ? "roamed" : "");
2340 * userspace. */
2341 ret = get_association_info(usbdev, info, sizeof(assoc_buf));
2342 if (!ret) {
2343 evt.data.length = le32_to_cpu(info->req_ie_length);
2344 if (evt.data.length > 0) {
2345 offset = le32_to_cpu(info->offset_req_ies);
2346 wireless_send_event(usbdev->net,
2347 IWEVASSOCREQIE, &evt,
2348 (char *)info + offset);
2349 }
2350 2598
2351 evt.data.length = le32_to_cpu(info->resp_ie_length); 2599 /* Internal bss list in device always contains at least the currently
2352 if (evt.data.length > 0) { 2600 * connected bss and we can get it to cfg80211 with
2353 offset = le32_to_cpu(info->offset_resp_ies); 2601 * rndis_check_bssid_list().
2354 wireless_send_event(usbdev->net, 2602 * NOTE: This is true for Broadcom chip, but not mentioned in RNDIS
2355 IWEVASSOCRESPIE, &evt, 2603 * spec.
2356 (char *)info + offset); 2604 */
2357 } 2605 rndis_check_bssid_list(usbdev);
2358 2606
2359 usbnet_resume_rx(usbdev); 2607 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
2360 } 2608 if (!roamed)
2609 cfg80211_connect_result(usbdev->net, bssid, req_ie,
2610 req_ie_len, resp_ie,
2611 resp_ie_len, 0, GFP_KERNEL);
2612 else
2613 cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len,
2614 resp_ie, resp_ie_len, GFP_KERNEL);
2615 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2616 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
2361 2617
2362 ret = get_bssid(usbdev, bssid); 2618 priv->connected = true;
2363 if (!ret) {
2364 evt.data.flags = 0;
2365 evt.data.length = 0;
2366 memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
2367 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
2368 }
2369 2619
2370 usbnet_resume_rx(usbdev); 2620 usbnet_resume_rx(usbdev);
2621 netif_carrier_on(usbdev->net);
2371} 2622}
2372 2623
2373static void rndis_wlan_do_link_down_work(struct usbnet *usbdev) 2624static void rndis_wlan_do_link_down_work(struct usbnet *usbdev)