.. | .. |
---|
1 | | -/* Marvell Wireless LAN device driver: TDLS handling |
---|
| 1 | +/* |
---|
| 2 | + * NXP Wireless LAN device driver: TDLS handling |
---|
2 | 3 | * |
---|
3 | | - * Copyright (C) 2014, Marvell International Ltd. |
---|
| 4 | + * Copyright 2011-2020 NXP |
---|
4 | 5 | * |
---|
5 | | - * This software file (the "File") is distributed by Marvell International |
---|
6 | | - * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
---|
| 6 | + * This software file (the "File") is distributed by NXP |
---|
| 7 | + * under the terms of the GNU General Public License Version 2, June 1991 |
---|
7 | 8 | * (the "License"). You may use, redistribute and/or modify this File in |
---|
8 | 9 | * accordance with the terms and conditions of the License, a copy of which |
---|
9 | 10 | * is available on the worldwide web at |
---|
.. | .. |
---|
33 | 34 | struct list_head *tid_list; |
---|
34 | 35 | struct sk_buff *skb, *tmp; |
---|
35 | 36 | struct mwifiex_txinfo *tx_info; |
---|
36 | | - unsigned long flags; |
---|
37 | 37 | u32 tid; |
---|
38 | 38 | u8 tid_down; |
---|
39 | 39 | |
---|
40 | 40 | mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac); |
---|
41 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); |
---|
| 41 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
42 | 42 | |
---|
43 | 43 | skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) { |
---|
44 | 44 | if (!ether_addr_equal(mac, skb->data)) |
---|
.. | .. |
---|
78 | 78 | atomic_inc(&priv->wmm.tx_pkts_queued); |
---|
79 | 79 | } |
---|
80 | 80 | |
---|
81 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
---|
| 81 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
82 | 82 | return; |
---|
83 | 83 | } |
---|
84 | 84 | |
---|
.. | .. |
---|
88 | 88 | struct mwifiex_ra_list_tbl *ra_list; |
---|
89 | 89 | struct list_head *ra_list_head; |
---|
90 | 90 | struct sk_buff *skb, *tmp; |
---|
91 | | - unsigned long flags; |
---|
92 | 91 | int i; |
---|
93 | 92 | |
---|
94 | 93 | mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac); |
---|
95 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); |
---|
| 94 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
96 | 95 | |
---|
97 | 96 | for (i = 0; i < MAX_NUM_TID; i++) { |
---|
98 | 97 | if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) { |
---|
.. | .. |
---|
111 | 110 | } |
---|
112 | 111 | } |
---|
113 | 112 | |
---|
114 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
---|
| 113 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
115 | 114 | return; |
---|
116 | 115 | } |
---|
117 | 116 | |
---|
.. | .. |
---|
733 | 732 | u16 status_code, struct sk_buff *skb) |
---|
734 | 733 | { |
---|
735 | 734 | struct ieee80211_mgmt *mgmt; |
---|
736 | | - u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
---|
737 | 735 | int ret; |
---|
738 | 736 | u16 capab; |
---|
739 | 737 | struct ieee80211_ht_cap *ht_cap; |
---|
| 738 | + unsigned int extra; |
---|
740 | 739 | u8 radio, *pos; |
---|
741 | 740 | |
---|
742 | 741 | capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; |
---|
.. | .. |
---|
755 | 754 | |
---|
756 | 755 | switch (action_code) { |
---|
757 | 756 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: |
---|
758 | | - skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); |
---|
| 757 | + /* See the layout of 'struct ieee80211_mgmt'. */ |
---|
| 758 | + extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + |
---|
| 759 | + sizeof(mgmt->u.action.category); |
---|
| 760 | + skb_put(skb, extra); |
---|
759 | 761 | mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; |
---|
760 | 762 | mgmt->u.action.u.tdls_discover_resp.action_code = |
---|
761 | 763 | WLAN_PUB_ACTION_TDLS_DISCOVER_RES; |
---|
.. | .. |
---|
764 | 766 | mgmt->u.action.u.tdls_discover_resp.capability = |
---|
765 | 767 | cpu_to_le16(capab); |
---|
766 | 768 | /* move back for addr4 */ |
---|
767 | | - memmove(pos + ETH_ALEN, &mgmt->u.action.category, |
---|
768 | | - sizeof(mgmt->u.action.u.tdls_discover_resp)); |
---|
| 769 | + memmove(pos + ETH_ALEN, &mgmt->u.action, extra); |
---|
769 | 770 | /* init address 4 */ |
---|
770 | | - memcpy(pos, bc_addr, ETH_ALEN); |
---|
| 771 | + eth_broadcast_addr(pos); |
---|
771 | 772 | |
---|
772 | 773 | ret = mwifiex_tdls_append_rates_ie(priv, skb); |
---|
773 | 774 | if (ret) { |
---|
.. | .. |
---|
1109 | 1110 | { |
---|
1110 | 1111 | struct mwifiex_sta_node *sta_ptr; |
---|
1111 | 1112 | struct mwifiex_ds_tdls_oper tdls_oper; |
---|
1112 | | - unsigned long flags; |
---|
1113 | 1113 | |
---|
1114 | 1114 | memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); |
---|
1115 | 1115 | sta_ptr = mwifiex_get_sta_entry(priv, peer); |
---|
.. | .. |
---|
1117 | 1117 | if (sta_ptr) { |
---|
1118 | 1118 | if (sta_ptr->is_11n_enabled) { |
---|
1119 | 1119 | mwifiex_11n_cleanup_reorder_tbl(priv); |
---|
1120 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, |
---|
1121 | | - flags); |
---|
| 1120 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
1122 | 1121 | mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); |
---|
1123 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
---|
1124 | | - flags); |
---|
| 1122 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
1125 | 1123 | } |
---|
1126 | 1124 | mwifiex_del_sta_entry(priv, peer); |
---|
1127 | 1125 | } |
---|
.. | .. |
---|
1139 | 1137 | { |
---|
1140 | 1138 | struct mwifiex_sta_node *sta_ptr; |
---|
1141 | 1139 | struct ieee80211_mcs_info mcs; |
---|
1142 | | - unsigned long flags; |
---|
1143 | 1140 | int i; |
---|
1144 | 1141 | |
---|
1145 | 1142 | sta_ptr = mwifiex_get_sta_entry(priv, peer); |
---|
.. | .. |
---|
1184 | 1181 | "tdls: enable link %pM failed\n", peer); |
---|
1185 | 1182 | if (sta_ptr) { |
---|
1186 | 1183 | mwifiex_11n_cleanup_reorder_tbl(priv); |
---|
1187 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, |
---|
1188 | | - flags); |
---|
| 1184 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
1189 | 1185 | mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); |
---|
1190 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
---|
1191 | | - flags); |
---|
| 1186 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
1192 | 1187 | mwifiex_del_sta_entry(priv, peer); |
---|
1193 | 1188 | } |
---|
1194 | 1189 | mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); |
---|
.. | .. |
---|
1233 | 1228 | struct mwifiex_sta_node *sta_ptr; |
---|
1234 | 1229 | struct tdls_peer_info *peer = buf; |
---|
1235 | 1230 | int count = 0; |
---|
1236 | | - unsigned long flags; |
---|
1237 | 1231 | |
---|
1238 | 1232 | if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) |
---|
1239 | 1233 | return 0; |
---|
.. | .. |
---|
1242 | 1236 | if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) |
---|
1243 | 1237 | return 0; |
---|
1244 | 1238 | |
---|
1245 | | - spin_lock_irqsave(&priv->sta_list_spinlock, flags); |
---|
| 1239 | + spin_lock_bh(&priv->sta_list_spinlock); |
---|
1246 | 1240 | list_for_each_entry(sta_ptr, &priv->sta_list, list) { |
---|
1247 | 1241 | if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) { |
---|
1248 | 1242 | ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr); |
---|
.. | .. |
---|
1252 | 1246 | break; |
---|
1253 | 1247 | } |
---|
1254 | 1248 | } |
---|
1255 | | - spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); |
---|
| 1249 | + spin_unlock_bh(&priv->sta_list_spinlock); |
---|
1256 | 1250 | |
---|
1257 | 1251 | return count; |
---|
1258 | 1252 | } |
---|
.. | .. |
---|
1261 | 1255 | { |
---|
1262 | 1256 | struct mwifiex_sta_node *sta_ptr; |
---|
1263 | 1257 | struct mwifiex_ds_tdls_oper tdls_oper; |
---|
1264 | | - unsigned long flags; |
---|
1265 | 1258 | |
---|
1266 | 1259 | if (list_empty(&priv->sta_list)) |
---|
1267 | 1260 | return; |
---|
.. | .. |
---|
1271 | 1264 | |
---|
1272 | 1265 | if (sta_ptr->is_11n_enabled) { |
---|
1273 | 1266 | mwifiex_11n_cleanup_reorder_tbl(priv); |
---|
1274 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, |
---|
1275 | | - flags); |
---|
| 1267 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
1276 | 1268 | mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); |
---|
1277 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
---|
1278 | | - flags); |
---|
| 1269 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
1279 | 1270 | } |
---|
1280 | 1271 | |
---|
1281 | 1272 | mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr, |
---|
.. | .. |
---|
1295 | 1286 | int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb) |
---|
1296 | 1287 | { |
---|
1297 | 1288 | struct mwifiex_auto_tdls_peer *peer; |
---|
1298 | | - unsigned long flags; |
---|
1299 | 1289 | u8 mac[ETH_ALEN]; |
---|
1300 | 1290 | |
---|
1301 | 1291 | ether_addr_copy(mac, skb->data); |
---|
1302 | 1292 | |
---|
1303 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1293 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1304 | 1294 | list_for_each_entry(peer, &priv->auto_tdls_list, list) { |
---|
1305 | 1295 | if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) { |
---|
1306 | 1296 | if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && |
---|
.. | .. |
---|
1329 | 1319 | } |
---|
1330 | 1320 | } |
---|
1331 | 1321 | } |
---|
1332 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1322 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1333 | 1323 | |
---|
1334 | 1324 | return 0; |
---|
1335 | 1325 | } |
---|
.. | .. |
---|
1337 | 1327 | void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv) |
---|
1338 | 1328 | { |
---|
1339 | 1329 | struct mwifiex_auto_tdls_peer *peer, *tmp_node; |
---|
1340 | | - unsigned long flags; |
---|
1341 | 1330 | |
---|
1342 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1331 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1343 | 1332 | list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) { |
---|
1344 | 1333 | list_del(&peer->list); |
---|
1345 | 1334 | kfree(peer); |
---|
1346 | 1335 | } |
---|
1347 | 1336 | |
---|
1348 | 1337 | INIT_LIST_HEAD(&priv->auto_tdls_list); |
---|
1349 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1338 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1350 | 1339 | priv->check_tdls_tx = false; |
---|
1351 | 1340 | } |
---|
1352 | 1341 | |
---|
1353 | 1342 | void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) |
---|
1354 | 1343 | { |
---|
1355 | 1344 | struct mwifiex_auto_tdls_peer *tdls_peer; |
---|
1356 | | - unsigned long flags; |
---|
1357 | 1345 | |
---|
1358 | 1346 | if (!priv->adapter->auto_tdls) |
---|
1359 | 1347 | return; |
---|
1360 | 1348 | |
---|
1361 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1349 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1362 | 1350 | list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { |
---|
1363 | 1351 | if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) { |
---|
1364 | 1352 | tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; |
---|
1365 | 1353 | tdls_peer->rssi_jiffies = jiffies; |
---|
1366 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1354 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1367 | 1355 | return; |
---|
1368 | 1356 | } |
---|
1369 | 1357 | } |
---|
.. | .. |
---|
1380 | 1368 | "Add auto TDLS peer= %pM to list\n", mac); |
---|
1381 | 1369 | } |
---|
1382 | 1370 | |
---|
1383 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1371 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1384 | 1372 | } |
---|
1385 | 1373 | |
---|
1386 | 1374 | void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, |
---|
1387 | 1375 | const u8 *mac, u8 link_status) |
---|
1388 | 1376 | { |
---|
1389 | 1377 | struct mwifiex_auto_tdls_peer *peer; |
---|
1390 | | - unsigned long flags; |
---|
1391 | 1378 | |
---|
1392 | 1379 | if (!priv->adapter->auto_tdls) |
---|
1393 | 1380 | return; |
---|
1394 | 1381 | |
---|
1395 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1382 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1396 | 1383 | list_for_each_entry(peer, &priv->auto_tdls_list, list) { |
---|
1397 | 1384 | if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { |
---|
1398 | 1385 | if ((link_status == TDLS_NOT_SETUP) && |
---|
.. | .. |
---|
1405 | 1392 | break; |
---|
1406 | 1393 | } |
---|
1407 | 1394 | } |
---|
1408 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1395 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1409 | 1396 | } |
---|
1410 | 1397 | |
---|
1411 | 1398 | void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, |
---|
1412 | 1399 | u8 *mac, s8 snr, s8 nflr) |
---|
1413 | 1400 | { |
---|
1414 | 1401 | struct mwifiex_auto_tdls_peer *peer; |
---|
1415 | | - unsigned long flags; |
---|
1416 | 1402 | |
---|
1417 | 1403 | if (!priv->adapter->auto_tdls) |
---|
1418 | 1404 | return; |
---|
1419 | 1405 | |
---|
1420 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1406 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1421 | 1407 | list_for_each_entry(peer, &priv->auto_tdls_list, list) { |
---|
1422 | 1408 | if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { |
---|
1423 | 1409 | peer->rssi = nflr - snr; |
---|
.. | .. |
---|
1425 | 1411 | break; |
---|
1426 | 1412 | } |
---|
1427 | 1413 | } |
---|
1428 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1414 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1429 | 1415 | } |
---|
1430 | 1416 | |
---|
1431 | 1417 | void mwifiex_check_auto_tdls(struct timer_list *t) |
---|
1432 | 1418 | { |
---|
1433 | 1419 | struct mwifiex_private *priv = from_timer(priv, t, auto_tdls_timer); |
---|
1434 | 1420 | struct mwifiex_auto_tdls_peer *tdls_peer; |
---|
1435 | | - unsigned long flags; |
---|
1436 | 1421 | u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; |
---|
1437 | 1422 | |
---|
1438 | 1423 | if (WARN_ON_ONCE(!priv || !priv->adapter)) { |
---|
.. | .. |
---|
1452 | 1437 | |
---|
1453 | 1438 | priv->check_tdls_tx = false; |
---|
1454 | 1439 | |
---|
1455 | | - spin_lock_irqsave(&priv->auto_tdls_lock, flags); |
---|
| 1440 | + spin_lock_bh(&priv->auto_tdls_lock); |
---|
1456 | 1441 | list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { |
---|
1457 | 1442 | if ((jiffies - tdls_peer->rssi_jiffies) > |
---|
1458 | 1443 | (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) { |
---|
.. | .. |
---|
1487 | 1472 | tdls_peer->rssi); |
---|
1488 | 1473 | } |
---|
1489 | 1474 | } |
---|
1490 | | - spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); |
---|
| 1475 | + spin_unlock_bh(&priv->auto_tdls_lock); |
---|
1491 | 1476 | |
---|
1492 | 1477 | mod_timer(&priv->auto_tdls_timer, |
---|
1493 | 1478 | jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); |
---|