diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/fw.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmd.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmdresp.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/tdls.c | 23 |
6 files changed, 137 insertions, 1 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index cac8aea69ce5..436ba437a4ba 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -2734,6 +2734,30 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, | |||
2734 | return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK); | 2734 | return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK); |
2735 | } | 2735 | } |
2736 | 2736 | ||
2737 | static int | ||
2738 | mwifiex_cfg80211_change_station(struct wiphy *wiphy, | ||
2739 | struct net_device *dev, | ||
2740 | u8 *mac, struct station_parameters *params) | ||
2741 | { | ||
2742 | int ret; | ||
2743 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | ||
2744 | |||
2745 | /* we support change_station handler only for TDLS peers*/ | ||
2746 | if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) | ||
2747 | return -ENOTSUPP; | ||
2748 | |||
2749 | /* make sure we are in station mode and connected */ | ||
2750 | if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected) | ||
2751 | return -ENOTSUPP; | ||
2752 | |||
2753 | priv->sta_params = params; | ||
2754 | |||
2755 | ret = mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CONFIG_LINK); | ||
2756 | priv->sta_params = NULL; | ||
2757 | |||
2758 | return ret; | ||
2759 | } | ||
2760 | |||
2737 | /* station cfg80211 operations */ | 2761 | /* station cfg80211 operations */ |
2738 | static struct cfg80211_ops mwifiex_cfg80211_ops = { | 2762 | static struct cfg80211_ops mwifiex_cfg80211_ops = { |
2739 | .add_virtual_intf = mwifiex_add_virtual_intf, | 2763 | .add_virtual_intf = mwifiex_add_virtual_intf, |
@@ -2772,6 +2796,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { | |||
2772 | .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt, | 2796 | .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt, |
2773 | .tdls_oper = mwifiex_cfg80211_tdls_oper, | 2797 | .tdls_oper = mwifiex_cfg80211_tdls_oper, |
2774 | .add_station = mwifiex_cfg80211_add_station, | 2798 | .add_station = mwifiex_cfg80211_add_station, |
2799 | .change_station = mwifiex_cfg80211_change_station, | ||
2775 | }; | 2800 | }; |
2776 | 2801 | ||
2777 | #ifdef CONFIG_PM | 2802 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 3180fc6b7c6d..8c119bc93899 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -1391,6 +1391,11 @@ struct mwifiex_ie_types_extcap { | |||
1391 | u8 ext_capab[0]; | 1391 | u8 ext_capab[0]; |
1392 | } __packed; | 1392 | } __packed; |
1393 | 1393 | ||
1394 | struct mwifiex_ie_types_qos_info { | ||
1395 | struct mwifiex_ie_types_header header; | ||
1396 | u8 qos_info; | ||
1397 | } __packed; | ||
1398 | |||
1394 | struct host_cmd_ds_mac_reg_access { | 1399 | struct host_cmd_ds_mac_reg_access { |
1395 | __le16 action; | 1400 | __le16 action; |
1396 | __le16 offset; | 1401 | __le16 offset; |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index d35c9950efba..c8c30a4c9a73 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -529,6 +529,7 @@ struct mwifiex_private { | |||
529 | unsigned long csa_expire_time; | 529 | unsigned long csa_expire_time; |
530 | u8 del_list_idx; | 530 | u8 del_list_idx; |
531 | bool hs2_enabled; | 531 | bool hs2_enabled; |
532 | struct station_parameters *sta_params; | ||
532 | }; | 533 | }; |
533 | 534 | ||
534 | enum mwifiex_ba_status { | 535 | enum mwifiex_ba_status { |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 1e36fa7a6463..8f1bcc3255dd 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -1288,14 +1288,24 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, | |||
1288 | struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper; | 1288 | struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper; |
1289 | struct mwifiex_ds_tdls_oper *oper = data_buf; | 1289 | struct mwifiex_ds_tdls_oper *oper = data_buf; |
1290 | struct mwifiex_sta_node *sta_ptr; | 1290 | struct mwifiex_sta_node *sta_ptr; |
1291 | struct host_cmd_tlv_rates *tlv_rates; | ||
1292 | struct mwifiex_ie_types_htcap *ht_capab; | ||
1293 | struct mwifiex_ie_types_qos_info *wmm_qos_info; | ||
1294 | struct mwifiex_ie_types_extcap *extcap; | ||
1295 | u8 *pos, qos_info; | ||
1296 | u16 config_len = 0; | ||
1297 | struct station_parameters *params = priv->sta_params; | ||
1291 | 1298 | ||
1292 | cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER); | 1299 | cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER); |
1293 | cmd->size = cpu_to_le16(S_DS_GEN); | 1300 | cmd->size = cpu_to_le16(S_DS_GEN); |
1301 | le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper)); | ||
1294 | 1302 | ||
1295 | tdls_oper->reason = 0; | 1303 | tdls_oper->reason = 0; |
1296 | memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN); | 1304 | memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN); |
1297 | sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac); | 1305 | sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac); |
1298 | 1306 | ||
1307 | pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper); | ||
1308 | |||
1299 | switch (oper->tdls_action) { | 1309 | switch (oper->tdls_action) { |
1300 | case MWIFIEX_TDLS_DISABLE_LINK: | 1310 | case MWIFIEX_TDLS_DISABLE_LINK: |
1301 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE); | 1311 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE); |
@@ -1303,12 +1313,71 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, | |||
1303 | case MWIFIEX_TDLS_CREATE_LINK: | 1313 | case MWIFIEX_TDLS_CREATE_LINK: |
1304 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE); | 1314 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE); |
1305 | break; | 1315 | break; |
1316 | case MWIFIEX_TDLS_CONFIG_LINK: | ||
1317 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CONFIG); | ||
1318 | |||
1319 | if (!params) { | ||
1320 | dev_err(priv->adapter->dev, | ||
1321 | "TDLS config params not available for %pM\n", | ||
1322 | oper->peer_mac); | ||
1323 | return -ENODATA; | ||
1324 | } | ||
1325 | |||
1326 | *(__le16 *)pos = cpu_to_le16(params->capability); | ||
1327 | config_len += sizeof(params->capability); | ||
1328 | |||
1329 | qos_info = params->uapsd_queues | (params->max_sp << 5); | ||
1330 | wmm_qos_info = (struct mwifiex_ie_types_qos_info *)(pos + | ||
1331 | config_len); | ||
1332 | wmm_qos_info->header.type = cpu_to_le16(WLAN_EID_QOS_CAPA); | ||
1333 | wmm_qos_info->header.len = cpu_to_le16(sizeof(qos_info)); | ||
1334 | wmm_qos_info->qos_info = qos_info; | ||
1335 | config_len += sizeof(struct mwifiex_ie_types_qos_info); | ||
1336 | |||
1337 | if (params->ht_capa) { | ||
1338 | ht_capab = (struct mwifiex_ie_types_htcap *)(pos + | ||
1339 | config_len); | ||
1340 | ht_capab->header.type = | ||
1341 | cpu_to_le16(WLAN_EID_HT_CAPABILITY); | ||
1342 | ht_capab->header.len = | ||
1343 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | ||
1344 | memcpy(&ht_capab->ht_cap, params->ht_capa, | ||
1345 | sizeof(struct ieee80211_ht_cap)); | ||
1346 | config_len += sizeof(struct mwifiex_ie_types_htcap); | ||
1347 | } | ||
1348 | |||
1349 | if (params->supported_rates && params->supported_rates_len) { | ||
1350 | tlv_rates = (struct host_cmd_tlv_rates *)(pos + | ||
1351 | config_len); | ||
1352 | tlv_rates->header.type = | ||
1353 | cpu_to_le16(WLAN_EID_SUPP_RATES); | ||
1354 | tlv_rates->header.len = | ||
1355 | cpu_to_le16(params->supported_rates_len); | ||
1356 | memcpy(tlv_rates->rates, params->supported_rates, | ||
1357 | params->supported_rates_len); | ||
1358 | config_len += sizeof(struct host_cmd_tlv_rates) + | ||
1359 | params->supported_rates_len; | ||
1360 | } | ||
1361 | |||
1362 | if (params->ext_capab && params->ext_capab_len) { | ||
1363 | extcap = (struct mwifiex_ie_types_extcap *)(pos + | ||
1364 | config_len); | ||
1365 | extcap->header.type = | ||
1366 | cpu_to_le16(WLAN_EID_EXT_CAPABILITY); | ||
1367 | extcap->header.len = cpu_to_le16(params->ext_capab_len); | ||
1368 | memcpy(extcap->ext_capab, params->ext_capab, | ||
1369 | params->ext_capab_len); | ||
1370 | config_len += sizeof(struct mwifiex_ie_types_extcap) + | ||
1371 | params->ext_capab_len; | ||
1372 | } | ||
1373 | |||
1374 | break; | ||
1306 | default: | 1375 | default: |
1307 | dev_err(priv->adapter->dev, "Unknown TDLS operation\n"); | 1376 | dev_err(priv->adapter->dev, "Unknown TDLS operation\n"); |
1308 | return -ENOTSUPP; | 1377 | return -ENOTSUPP; |
1309 | } | 1378 | } |
1310 | 1379 | ||
1311 | le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper)); | 1380 | le16_add_cpu(&cmd->size, config_len); |
1312 | 1381 | ||
1313 | return 0; | 1382 | return 0; |
1314 | } | 1383 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 396b93682bd8..48abab6bfce9 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -834,6 +834,19 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv, | |||
834 | cmd_tdls_oper->peer_mac); | 834 | cmd_tdls_oper->peer_mac); |
835 | } | 835 | } |
836 | break; | 836 | break; |
837 | case ACT_TDLS_CONFIG: | ||
838 | if (reason) { | ||
839 | dev_err(priv->adapter->dev, | ||
840 | "TDLS link config for %pM failed, reason %d\n", | ||
841 | cmd_tdls_oper->peer_mac, reason); | ||
842 | if (node) | ||
843 | node->tdls_status = TDLS_SETUP_FAILURE; | ||
844 | } else { | ||
845 | dev_dbg(priv->adapter->dev, | ||
846 | "TDLS link config for %pM successful\n", | ||
847 | cmd_tdls_oper->peer_mac); | ||
848 | } | ||
849 | break; | ||
837 | default: | 850 | default: |
838 | dev_err(priv->adapter->dev, | 851 | dev_err(priv->adapter->dev, |
839 | "Unknown TDLS command action respnse %d", action); | 852 | "Unknown TDLS command action respnse %d", action); |
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 1d5ed70432d6..f37862b5fabb 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c | |||
@@ -544,6 +544,27 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, | |||
544 | } | 544 | } |
545 | 545 | ||
546 | static int | 546 | static int |
547 | mwifiex_tdls_process_config_link(struct mwifiex_private *priv, u8 *peer) | ||
548 | { | ||
549 | struct mwifiex_sta_node *sta_ptr; | ||
550 | struct mwifiex_ds_tdls_oper tdls_oper; | ||
551 | |||
552 | memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); | ||
553 | sta_ptr = mwifiex_get_sta_entry(priv, peer); | ||
554 | |||
555 | if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) { | ||
556 | dev_err(priv->adapter->dev, | ||
557 | "link absent for peer %pM; cannot config\n", peer); | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | |||
561 | memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); | ||
562 | tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK; | ||
563 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TDLS_OPER, | ||
564 | HostCmd_ACT_GEN_SET, 0, &tdls_oper); | ||
565 | } | ||
566 | |||
567 | static int | ||
547 | mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer) | 568 | mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer) |
548 | { | 569 | { |
549 | struct mwifiex_sta_node *sta_ptr; | 570 | struct mwifiex_sta_node *sta_ptr; |
@@ -662,6 +683,8 @@ int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action) | |||
662 | return mwifiex_tdls_process_disable_link(priv, peer); | 683 | return mwifiex_tdls_process_disable_link(priv, peer); |
663 | case MWIFIEX_TDLS_CREATE_LINK: | 684 | case MWIFIEX_TDLS_CREATE_LINK: |
664 | return mwifiex_tdls_process_create_link(priv, peer); | 685 | return mwifiex_tdls_process_create_link(priv, peer); |
686 | case MWIFIEX_TDLS_CONFIG_LINK: | ||
687 | return mwifiex_tdls_process_config_link(priv, peer); | ||
665 | } | 688 | } |
666 | return 0; | 689 | return 0; |
667 | } | 690 | } |