hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/wireless/ath/wil6210/main.c
....@@ -1,23 +1,13 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4
- *
5
- * Permission to use, copy, modify, and/or distribute this software for any
6
- * purpose with or without fee is hereby granted, provided that the above
7
- * copyright notice and this permission notice appear in all copies.
8
- *
9
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
165 */
176
187 #include <linux/moduleparam.h>
198 #include <linux/if_arp.h>
209 #include <linux/etherdevice.h>
10
+#include <linux/rtnetlink.h>
2111
2212 #include "wil6210.h"
2313 #include "txrx.h"
....@@ -80,7 +70,7 @@
8070 module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, 0444);
8171 MODULE_PARM_DESC(mtu_max, " Max MTU value.");
8272
83
-static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT;
73
+static uint rx_ring_order;
8474 static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT;
8575 static uint bcast_ring_order = WIL_BCAST_RING_SIZE_ORDER_DEFAULT;
8676
....@@ -183,6 +173,28 @@
183173 }
184174 }
185175
176
+/* Device memory access is prohibited while reset or suspend.
177
+ * wil_mem_access_lock protects accessing device memory in these cases
178
+ */
179
+int wil_mem_access_lock(struct wil6210_priv *wil)
180
+{
181
+ if (!down_read_trylock(&wil->mem_lock))
182
+ return -EBUSY;
183
+
184
+ if (test_bit(wil_status_suspending, wil->status) ||
185
+ test_bit(wil_status_suspended, wil->status)) {
186
+ up_read(&wil->mem_lock);
187
+ return -EBUSY;
188
+ }
189
+
190
+ return 0;
191
+}
192
+
193
+void wil_mem_access_unlock(struct wil6210_priv *wil)
194
+{
195
+ up_read(&wil->mem_lock);
196
+}
197
+
186198 static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
187199 {
188200 struct wil_ring *ring = &wil->ring_tx[id];
....@@ -214,8 +226,21 @@
214226 wil->txrx_ops.ring_fini_tx(wil, ring);
215227 }
216228
217
-static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
218
- u16 reason_code, bool from_event)
229
+static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
230
+{
231
+ int i;
232
+
233
+ for (i = 0; i < wil->max_assoc_sta; i++) {
234
+ if (wil->sta[i].mid == mid &&
235
+ wil->sta[i].status == wil_sta_connected)
236
+ return true;
237
+ }
238
+
239
+ return false;
240
+}
241
+
242
+static void wil_disconnect_cid_complete(struct wil6210_vif *vif, int cid,
243
+ u16 reason_code)
219244 __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
220245 {
221246 uint i;
....@@ -226,24 +251,14 @@
226251 int min_ring_id = wil_get_min_tx_ring_id(wil);
227252
228253 might_sleep();
229
- wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
254
+ wil_dbg_misc(wil,
255
+ "disconnect_cid_complete: CID %d, MID %d, status %d\n",
230256 cid, sta->mid, sta->status);
231
- /* inform upper/lower layers */
257
+ /* inform upper layers */
232258 if (sta->status != wil_sta_unused) {
233259 if (vif->mid != sta->mid) {
234260 wil_err(wil, "STA MID mismatch with VIF MID(%d)\n",
235261 vif->mid);
236
- /* let FW override sta->mid but be more strict with
237
- * user space requests
238
- */
239
- if (!from_event)
240
- return;
241
- }
242
- if (!from_event) {
243
- bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
244
- disable_ap_sme : false;
245
- wmi_disconnect_sta(vif, sta->addr, reason_code,
246
- true, del_sta);
247262 }
248263
249264 switch (wdev->iftype) {
....@@ -283,36 +298,20 @@
283298 sta->stats.tx_latency_min_us = U32_MAX;
284299 }
285300
286
-static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
287
-{
288
- int i;
289
-
290
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
291
- if (wil->sta[i].mid == mid &&
292
- wil->sta[i].status == wil_sta_connected)
293
- return true;
294
- }
295
-
296
- return false;
297
-}
298
-
299
-static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
300
- u16 reason_code, bool from_event)
301
+static void _wil6210_disconnect_complete(struct wil6210_vif *vif,
302
+ const u8 *bssid, u16 reason_code)
301303 {
302304 struct wil6210_priv *wil = vif_to_wil(vif);
303305 int cid = -ENOENT;
304306 struct net_device *ndev;
305307 struct wireless_dev *wdev;
306308
307
- if (unlikely(!vif))
308
- return;
309
-
310309 ndev = vif_to_ndev(vif);
311310 wdev = vif_to_wdev(vif);
312311
313312 might_sleep();
314
- wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid,
315
- reason_code, from_event ? "+" : "-");
313
+ wil_info(wil, "disconnect_complete: bssid=%pM, reason=%d\n",
314
+ bssid, reason_code);
316315
317316 /* Cases are:
318317 * - disconnect single STA, still connected
....@@ -327,14 +326,15 @@
327326 if (bssid && !is_broadcast_ether_addr(bssid) &&
328327 !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
329328 cid = wil_find_cid(wil, vif->mid, bssid);
330
- wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
329
+ wil_dbg_misc(wil,
330
+ "Disconnect complete %pM, CID=%d, reason=%d\n",
331331 bssid, cid, reason_code);
332
- if (cid >= 0) /* disconnect 1 peer */
333
- wil_disconnect_cid(vif, cid, reason_code, from_event);
332
+ if (wil_cid_valid(wil, cid)) /* disconnect 1 peer */
333
+ wil_disconnect_cid_complete(vif, cid, reason_code);
334334 } else { /* all */
335
- wil_dbg_misc(wil, "Disconnect all\n");
336
- for (cid = 0; cid < WIL6210_MAX_CID; cid++)
337
- wil_disconnect_cid(vif, cid, reason_code, from_event);
335
+ wil_dbg_misc(wil, "Disconnect complete all\n");
336
+ for (cid = 0; cid < wil->max_assoc_sta; cid++)
337
+ wil_disconnect_cid_complete(vif, cid, reason_code);
338338 }
339339
340340 /* link state */
....@@ -361,6 +361,9 @@
361361 vif->bss = NULL;
362362 }
363363 clear_bit(wil_vif_fwconnecting, vif->status);
364
+ clear_bit(wil_vif_ft_roam, vif->status);
365
+ vif->ptk_rekey_state = WIL_REKEY_IDLE;
366
+
364367 break;
365368 case NL80211_IFTYPE_AP:
366369 case NL80211_IFTYPE_P2P_GO:
....@@ -376,6 +379,82 @@
376379 default:
377380 break;
378381 }
382
+}
383
+
384
+static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
385
+ u16 reason_code)
386
+{
387
+ struct wil6210_priv *wil = vif_to_wil(vif);
388
+ struct wireless_dev *wdev = vif_to_wdev(vif);
389
+ struct wil_sta_info *sta = &wil->sta[cid];
390
+ bool del_sta = false;
391
+
392
+ might_sleep();
393
+ wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
394
+ cid, sta->mid, sta->status);
395
+
396
+ if (sta->status == wil_sta_unused)
397
+ return 0;
398
+
399
+ if (vif->mid != sta->mid) {
400
+ wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
401
+ return -EINVAL;
402
+ }
403
+
404
+ /* inform lower layers */
405
+ if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
406
+ del_sta = true;
407
+
408
+ /* disconnect by sending command disconnect/del_sta and wait
409
+ * synchronously for WMI_DISCONNECT_EVENTID event.
410
+ */
411
+ return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
412
+}
413
+
414
+static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
415
+ u16 reason_code)
416
+{
417
+ struct wil6210_priv *wil;
418
+ struct net_device *ndev;
419
+ int cid = -ENOENT;
420
+
421
+ if (unlikely(!vif))
422
+ return;
423
+
424
+ wil = vif_to_wil(vif);
425
+ ndev = vif_to_ndev(vif);
426
+
427
+ might_sleep();
428
+ wil_info(wil, "disconnect bssid=%pM, reason=%d\n", bssid, reason_code);
429
+
430
+ /* Cases are:
431
+ * - disconnect single STA, still connected
432
+ * - disconnect single STA, already disconnected
433
+ * - disconnect all
434
+ *
435
+ * For "disconnect all", there are 3 options:
436
+ * - bssid == NULL
437
+ * - bssid is broadcast address (ff:ff:ff:ff:ff:ff)
438
+ * - bssid is our MAC address
439
+ */
440
+ if (bssid && !is_broadcast_ether_addr(bssid) &&
441
+ !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
442
+ cid = wil_find_cid(wil, vif->mid, bssid);
443
+ wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
444
+ bssid, cid, reason_code);
445
+ if (wil_cid_valid(wil, cid)) /* disconnect 1 peer */
446
+ wil_disconnect_cid(vif, cid, reason_code);
447
+ } else { /* all */
448
+ wil_dbg_misc(wil, "Disconnect all\n");
449
+ for (cid = 0; cid < wil->max_assoc_sta; cid++)
450
+ wil_disconnect_cid(vif, cid, reason_code);
451
+ }
452
+
453
+ /* call event handler manually after processing wmi_call,
454
+ * to avoid deadlock - disconnect event handler acquires
455
+ * wil->mutex while it is already held here
456
+ */
457
+ _wil6210_disconnect_complete(vif, bssid, reason_code);
379458 }
380459
381460 void wil_disconnect_worker(struct work_struct *work)
....@@ -483,10 +562,11 @@
483562 if (wil_wait_for_recovery(wil) != 0)
484563 return;
485564
565
+ rtnl_lock();
486566 mutex_lock(&wil->mutex);
487567 /* Needs adaptation for multiple VIFs
488568 * need to go over all VIFs and consider the appropriate
489
- * recovery.
569
+ * recovery because each one can have different iftype.
490570 */
491571 switch (wdev->iftype) {
492572 case NL80211_IFTYPE_STATION:
....@@ -498,15 +578,24 @@
498578 break;
499579 case NL80211_IFTYPE_AP:
500580 case NL80211_IFTYPE_P2P_GO:
501
- wil_info(wil, "No recovery for AP-like interface\n");
502
- /* recovery in these modes is done by upper layers */
581
+ if (no_fw_recovery) /* upper layers do recovery */
582
+ break;
583
+ /* silent recovery, upper layers will see disconnect */
584
+ __wil_down(wil);
585
+ __wil_up(wil);
586
+ mutex_unlock(&wil->mutex);
587
+ wil_cfg80211_ap_recovery(wil);
588
+ mutex_lock(&wil->mutex);
589
+ wil_info(wil, "... completed\n");
503590 break;
504591 default:
505592 wil_err(wil, "No recovery - unknown interface type %d\n",
506593 wdev->iftype);
507594 break;
508595 }
596
+
509597 mutex_unlock(&wil->mutex);
598
+ rtnl_unlock();
510599 }
511600
512601 static int wil_find_free_ring(struct wil6210_priv *wil)
....@@ -586,7 +675,7 @@
586675 int i;
587676 struct wil6210_vif *vif;
588677
589
- for (i = 0; i < wil->max_vifs; i++) {
678
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
590679 vif = wil->vifs[i];
591680 if (vif)
592681 wil_bcast_fini(vif);
....@@ -625,7 +714,10 @@
625714 INIT_LIST_HEAD(&wil->pending_wmi_ev);
626715 spin_lock_init(&wil->wmi_ev_lock);
627716 spin_lock_init(&wil->net_queue_lock);
717
+ spin_lock_init(&wil->eap_lock);
718
+
628719 init_waitqueue_head(&wil->wq);
720
+ init_rwsem(&wil->mem_lock);
629721
630722 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
631723 if (!wil->wmi_wq)
....@@ -653,6 +745,7 @@
653745
654746 wil->reply_mid = U8_MAX;
655747 wil->max_vifs = 1;
748
+ wil->max_assoc_sta = max_assoc_sta;
656749
657750 /* edma configuration can be updated via debugfs before allocation */
658751 wil->num_rx_status_rings = WIL_DEFAULT_NUM_RX_STATUS_RINGS;
....@@ -669,7 +762,7 @@
669762 */
670763 wil->rx_buff_id_count = WIL_RX_BUFF_ARR_SIZE_DEFAULT;
671764
672
- wil->amsdu_en = 1;
765
+ wil->amsdu_en = true;
673766
674767 return 0;
675768
....@@ -692,20 +785,41 @@
692785 * @vif: virtual interface context
693786 * @bssid: peer to disconnect, NULL to disconnect all
694787 * @reason_code: Reason code for the Disassociation frame
695
- * @from_event: whether is invoked from FW event handler
696788 *
697
- * Disconnect and release associated resources. If invoked not from the
698
- * FW event handler, issue WMI command(s) to trigger MAC disconnect.
789
+ * Disconnect and release associated resources. Issue WMI
790
+ * command(s) to trigger MAC disconnect. When command was issued
791
+ * successfully, call the wil6210_disconnect_complete function
792
+ * to handle the event synchronously
699793 */
700794 void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
701
- u16 reason_code, bool from_event)
795
+ u16 reason_code)
702796 {
703797 struct wil6210_priv *wil = vif_to_wil(vif);
704798
705
- wil_dbg_misc(wil, "disconnect\n");
799
+ wil_dbg_misc(wil, "disconnecting\n");
706800
707801 del_timer_sync(&vif->connect_timer);
708
- _wil6210_disconnect(vif, bssid, reason_code, from_event);
802
+ _wil6210_disconnect(vif, bssid, reason_code);
803
+}
804
+
805
+/**
806
+ * wil6210_disconnect_complete - handle disconnect event
807
+ * @vif: virtual interface context
808
+ * @bssid: peer to disconnect, NULL to disconnect all
809
+ * @reason_code: Reason code for the Disassociation frame
810
+ *
811
+ * Release associated resources and indicate upper layers the
812
+ * connection is terminated.
813
+ */
814
+void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid,
815
+ u16 reason_code)
816
+{
817
+ struct wil6210_priv *wil = vif_to_wil(vif);
818
+
819
+ wil_dbg_misc(wil, "got disconnect\n");
820
+
821
+ del_timer_sync(&vif->connect_timer);
822
+ _wil6210_disconnect_complete(vif, bssid, reason_code);
709823 }
710824
711825 void wil_priv_deinit(struct wil6210_priv *wil)
....@@ -717,6 +831,7 @@
717831 wmi_event_flush(wil);
718832 destroy_workqueue(wil->wq_service);
719833 destroy_workqueue(wil->wmi_wq);
834
+ kfree(wil->brd_info);
720835 }
721836
722837 static void wil_shutdown_bl(struct wil6210_priv *wil)
....@@ -1158,6 +1273,8 @@
11581273 wil->max_agg_wsize = WIL_MAX_AGG_WSIZE;
11591274 wil->max_ampdu_size = WIL_MAX_AMPDU_SIZE;
11601275 }
1276
+
1277
+ update_supported_bands(wil);
11611278 }
11621279
11631280 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
....@@ -1290,13 +1407,22 @@
12901407 u8 mac[8];
12911408 int mac_addr;
12921409
1293
- if (wil->hw_version >= HW_VER_TALYN_MB)
1294
- mac_addr = RGF_OTP_MAC_TALYN_MB;
1295
- else
1296
- mac_addr = RGF_OTP_MAC;
1410
+ /* OEM MAC has precedence */
1411
+ mac_addr = RGF_OTP_OEM_MAC;
1412
+ wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(mac_addr), sizeof(mac));
12971413
1298
- wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(mac_addr),
1299
- sizeof(mac));
1414
+ if (is_valid_ether_addr(mac)) {
1415
+ wil_info(wil, "using OEM MAC %pM\n", mac);
1416
+ } else {
1417
+ if (wil->hw_version >= HW_VER_TALYN_MB)
1418
+ mac_addr = RGF_OTP_MAC_TALYN_MB;
1419
+ else
1420
+ mac_addr = RGF_OTP_MAC;
1421
+
1422
+ wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(mac_addr),
1423
+ sizeof(mac));
1424
+ }
1425
+
13001426 if (!is_valid_ether_addr(mac)) {
13011427 wil_err(wil, "Invalid MAC %pM\n", mac);
13021428 return -EINVAL;
....@@ -1360,7 +1486,7 @@
13601486
13611487 lockdep_assert_held(&wil->vif_mutex);
13621488
1363
- for (i = 0; i < wil->max_vifs; i++) {
1489
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
13641490 struct wil6210_vif *vif = wil->vifs[i];
13651491
13661492 if (vif)
....@@ -1388,6 +1514,7 @@
13881514
13891515 static void wil_pre_fw_config(struct wil6210_priv *wil)
13901516 {
1517
+ wil_clear_fw_log_addr(wil);
13911518 /* Mark FW as loaded from host */
13921519 wil_s(wil, RGF_USER_USAGE_6, 1);
13931520
....@@ -1400,11 +1527,6 @@
14001527 if (wil->hw_version < HW_VER_TALYN_MB) {
14011528 wil_s(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0);
14021529 wil_w(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0);
1403
- } else {
1404
- wil_s(wil,
1405
- RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, ICR), 0);
1406
- wil_w(wil, RGF_CAF_ICR_TALYN_MB +
1407
- offsetof(struct RGF_ICR, IMV), ~0);
14081530 }
14091531 /* clear PAL_UNIT_ICR (potential D0->D3 leftover)
14101532 * In Talyn-MB host cannot access this register due to
....@@ -1428,7 +1550,7 @@
14281550 struct wireless_dev *wdev;
14291551 int i, rc;
14301552
1431
- for (i = 0; i < wil->max_vifs; i++) {
1553
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
14321554 vif = wil->vifs[i];
14331555 if (!vif)
14341556 continue;
....@@ -1447,6 +1569,20 @@
14471569 }
14481570
14491571 return 0;
1572
+}
1573
+
1574
+/*
1575
+ * Clear FW and ucode log start addr to indicate FW log is not ready. The host
1576
+ * driver clears the addresses before FW starts and FW initializes the address
1577
+ * when it is ready to send logs.
1578
+ */
1579
+void wil_clear_fw_log_addr(struct wil6210_priv *wil)
1580
+{
1581
+ /* FW log addr */
1582
+ wil_w(wil, RGF_USER_USAGE_1, 0);
1583
+ /* ucode log addr */
1584
+ wil_w(wil, RGF_USER_USAGE_2, 0);
1585
+ wil_dbg_misc(wil, "Cleared FW and ucode log address");
14501586 }
14511587
14521588 /*
....@@ -1480,7 +1616,8 @@
14801616 if (wil->hw_version == HW_VER_UNKNOWN)
14811617 return -ENODEV;
14821618
1483
- if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa)) {
1619
+ if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa) &&
1620
+ wil->hw_version < HW_VER_TALYN_MB) {
14841621 wil_dbg_misc(wil, "Notify FW to set T_POWER_ON=0\n");
14851622 wil_s(wil, RGF_USER_USAGE_8, BIT_USER_SUPPORT_T_POWER_ON_0);
14861623 }
....@@ -1499,31 +1636,25 @@
14991636 }
15001637
15011638 set_bit(wil_status_resetting, wil->status);
1502
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
1503
- /* Device collects crash dump, cancel the reset.
1504
- * following crash dump collection, reset would take place.
1505
- */
1506
- wil_dbg_misc(wil, "reject reset while collecting crash dump\n");
1507
- rc = -EBUSY;
1508
- goto out;
1509
- }
1510
-
15111639 mutex_lock(&wil->vif_mutex);
15121640 wil_abort_scan_all_vifs(wil, false);
15131641 mutex_unlock(&wil->vif_mutex);
15141642
1515
- for (i = 0; i < wil->max_vifs; i++) {
1643
+ for (i = 0; i < GET_MAX_VIFS(wil); i++) {
15161644 vif = wil->vifs[i];
15171645 if (vif) {
15181646 cancel_work_sync(&vif->disconnect_worker);
15191647 wil6210_disconnect(vif, NULL,
1520
- WLAN_REASON_DEAUTH_LEAVING, false);
1648
+ WLAN_REASON_DEAUTH_LEAVING);
1649
+ vif->ptk_rekey_state = WIL_REKEY_IDLE;
15211650 }
15221651 }
15231652 wil_bcast_fini_all(wil);
15241653
15251654 /* Disable device led before reset*/
15261655 wmi_led_cfg(wil, false);
1656
+
1657
+ down_write(&wil->mem_lock);
15271658
15281659 /* prevent NAPI from being scheduled and prevent wmi commands */
15291660 mutex_lock(&wil->wmi_mutex);
....@@ -1573,6 +1704,7 @@
15731704
15741705 if (wil->secured_boot) {
15751706 wil_err(wil, "secured boot is not supported\n");
1707
+ up_write(&wil->mem_lock);
15761708 return -ENOTSUPP;
15771709 }
15781710
....@@ -1590,7 +1722,7 @@
15901722 rc = wil_request_firmware(wil, wil->wil_fw_name, true);
15911723 if (rc)
15921724 goto out;
1593
- if (wil->brd_file_addr)
1725
+ if (wil->num_of_brd_entries)
15941726 rc = wil_request_board(wil, board_file);
15951727 else
15961728 rc = wil_request_firmware(wil, board_file, true);
....@@ -1607,6 +1739,8 @@
16071739 reinit_completion(&wil->halp.comp);
16081740
16091741 clear_bit(wil_status_resetting, wil->status);
1742
+
1743
+ up_write(&wil->mem_lock);
16101744
16111745 if (load_fw) {
16121746 wil_unmask_irq(wil);
....@@ -1657,6 +1791,7 @@
16571791 return rc;
16581792
16591793 out:
1794
+ up_write(&wil->mem_lock);
16601795 clear_bit(wil_status_resetting, wil->status);
16611796 return rc;
16621797 }
....@@ -1687,6 +1822,11 @@
16871822 return rc;
16881823
16891824 /* Rx RING. After MAC and beacon */
1825
+ if (rx_ring_order == 0)
1826
+ rx_ring_order = wil->hw_version < HW_VER_TALYN_MB ?
1827
+ WIL_RX_RING_SIZE_ORDER_DEFAULT :
1828
+ WIL_RX_RING_SIZE_ORDER_TALYN_DEFAULT;
1829
+
16901830 rc = wil->txrx_ops.rx_init(wil, rx_ring_order);
16911831 if (rc)
16921832 return rc;
....@@ -1749,6 +1889,7 @@
17491889
17501890 int __wil_down(struct wil6210_priv *wil)
17511891 {
1892
+ int rc;
17521893 WARN_ON(!mutex_is_locked(&wil->mutex));
17531894
17541895 set_bit(wil_status_resetting, wil->status);
....@@ -1768,7 +1909,9 @@
17681909 wil_abort_scan_all_vifs(wil, false);
17691910 mutex_unlock(&wil->vif_mutex);
17701911
1771
- return wil_reset(wil, false);
1912
+ rc = wil_reset(wil, false);
1913
+
1914
+ return rc;
17721915 }
17731916
17741917 int wil_down(struct wil6210_priv *wil)
....@@ -1790,7 +1933,7 @@
17901933 int i;
17911934 int rc = -ENOENT;
17921935
1793
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1936
+ for (i = 0; i < wil->max_assoc_sta; i++) {
17941937 if (wil->sta[i].mid == mid &&
17951938 wil->sta[i].status != wil_sta_unused &&
17961939 ether_addr_equal(wil->sta[i].addr, mac)) {
....@@ -1806,6 +1949,9 @@
18061949 {
18071950 unsigned long rc;
18081951 unsigned long to_jiffies = msecs_to_jiffies(WAIT_FOR_HALP_VOTE_MS);
1952
+
1953
+ if (wil->hw_version >= HW_VER_TALYN_MB)
1954
+ return;
18091955
18101956 mutex_lock(&wil->halp.lock);
18111957
....@@ -1838,6 +1984,9 @@
18381984
18391985 void wil_halp_unvote(struct wil6210_priv *wil)
18401986 {
1987
+ if (wil->hw_version >= HW_VER_TALYN_MB)
1988
+ return;
1989
+
18411990 WARN_ON(wil->halp.ref_cnt == 0);
18421991
18431992 mutex_lock(&wil->halp.lock);