forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/net/wireless/ti/wlcore/main.c
....@@ -1,23 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * This file is part of wlcore
34 *
45 * Copyright (C) 2008-2010 Nokia Corporation
56 * Copyright (C) 2011-2013 Texas Instruments Inc.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful, but
12
- * WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
- * 02110-1301 USA
20
- *
217 */
228
239 #include <linux/module.h>
....@@ -27,6 +13,7 @@
2713 #include <linux/interrupt.h>
2814 #include <linux/irq.h>
2915 #include <linux/pm_runtime.h>
16
+#include <linux/pm_wakeirq.h>
3017
3118 #include "wlcore.h"
3219 #include "debug.h"
....@@ -43,7 +30,6 @@
4330 #include "sysfs.h"
4431
4532 #define WL1271_BOOT_RETRIES 3
46
-#define WL1271_SUSPEND_SLEEP 100
4733 #define WL1271_WAKEUP_TIMEOUT 500
4834
4935 static char *fwlog_param;
....@@ -496,7 +482,7 @@
496482 }
497483
498484 /* update the host-chipset time offset */
499
- wl->time_offset = (ktime_get_boot_ns() >> 10) -
485
+ wl->time_offset = (ktime_get_boottime_ns() >> 10) -
500486 (s64)(status->fw_localtime);
501487
502488 wl->fw_fast_lnk_map = status->link_fast_bitmap;
....@@ -534,6 +520,7 @@
534520 int ret = 0;
535521 u32 intr;
536522 int loopcount = WL1271_IRQ_MAX_LOOPS;
523
+ bool run_tx_queue = true;
537524 bool done = false;
538525 unsigned int defer_count;
539526 unsigned long flags;
....@@ -557,16 +544,11 @@
557544 }
558545
559546 while (!done && loopcount--) {
560
- /*
561
- * In order to avoid a race with the hardirq, clear the flag
562
- * before acknowledging the chip.
563
- */
564
- clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
565547 smp_mb__after_atomic();
566548
567549 ret = wlcore_fw_status(wl, wl->fw_status);
568550 if (ret < 0)
569
- goto out;
551
+ goto err_ret;
570552
571553 wlcore_hw_tx_immediate_compl(wl);
572554
....@@ -583,7 +565,7 @@
583565 ret = -EIO;
584566
585567 /* restarting the chip. ignore any other interrupt. */
586
- goto out;
568
+ goto err_ret;
587569 }
588570
589571 if (unlikely(intr & WL1271_ACX_SW_INTR_WATCHDOG)) {
....@@ -593,7 +575,7 @@
593575 ret = -EIO;
594576
595577 /* restarting the chip. ignore any other interrupt. */
596
- goto out;
578
+ goto err_ret;
597579 }
598580
599581 if (likely(intr & WL1271_ACX_INTR_DATA)) {
....@@ -601,28 +583,31 @@
601583
602584 ret = wlcore_rx(wl, wl->fw_status);
603585 if (ret < 0)
604
- goto out;
586
+ goto err_ret;
605587
606588 /* Check if any tx blocks were freed */
607
- spin_lock_irqsave(&wl->wl_lock, flags);
608
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
609
- wl1271_tx_total_queue_count(wl) > 0) {
610
- spin_unlock_irqrestore(&wl->wl_lock, flags);
589
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) {
590
+ if (spin_trylock_irqsave(&wl->wl_lock, flags)) {
591
+ if (!wl1271_tx_total_queue_count(wl))
592
+ run_tx_queue = false;
593
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
594
+ }
595
+
611596 /*
612597 * In order to avoid starvation of the TX path,
613598 * call the work function directly.
614599 */
615
- ret = wlcore_tx_work_locked(wl);
616
- if (ret < 0)
617
- goto out;
618
- } else {
619
- spin_unlock_irqrestore(&wl->wl_lock, flags);
600
+ if (run_tx_queue) {
601
+ ret = wlcore_tx_work_locked(wl);
602
+ if (ret < 0)
603
+ goto err_ret;
604
+ }
620605 }
621606
622607 /* check for tx results */
623608 ret = wlcore_hw_tx_delayed_compl(wl);
624609 if (ret < 0)
625
- goto out;
610
+ goto err_ret;
626611
627612 /* Make sure the deferred queues don't get too long */
628613 defer_count = skb_queue_len(&wl->deferred_tx_queue) +
....@@ -635,14 +620,14 @@
635620 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
636621 ret = wl1271_event_handle(wl, 0);
637622 if (ret < 0)
638
- goto out;
623
+ goto err_ret;
639624 }
640625
641626 if (intr & WL1271_ACX_INTR_EVENT_B) {
642627 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
643628 ret = wl1271_event_handle(wl, 1);
644629 if (ret < 0)
645
- goto out;
630
+ goto err_ret;
646631 }
647632
648633 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
....@@ -653,6 +638,7 @@
653638 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
654639 }
655640
641
+err_ret:
656642 pm_runtime_mark_last_busy(wl->dev);
657643 pm_runtime_put_autosuspend(wl->dev);
658644
....@@ -665,25 +651,28 @@
665651 int ret;
666652 unsigned long flags;
667653 struct wl1271 *wl = cookie;
654
+ bool queue_tx_work = true;
655
+
656
+ set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
668657
669658 /* complete the ELP completion */
670
- spin_lock_irqsave(&wl->wl_lock, flags);
671
- set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
672
- if (wl->elp_compl) {
673
- complete(wl->elp_compl);
674
- wl->elp_compl = NULL;
659
+ if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) {
660
+ spin_lock_irqsave(&wl->wl_lock, flags);
661
+ if (wl->elp_compl)
662
+ complete(wl->elp_compl);
663
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
675664 }
676665
677666 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
678667 /* don't enqueue a work right now. mark it as pending */
679668 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
680669 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
670
+ spin_lock_irqsave(&wl->wl_lock, flags);
681671 disable_irq_nosync(wl->irq);
682672 pm_wakeup_event(wl->dev, 0);
683673 spin_unlock_irqrestore(&wl->wl_lock, flags);
684
- return IRQ_HANDLED;
674
+ goto out_handled;
685675 }
686
- spin_unlock_irqrestore(&wl->wl_lock, flags);
687676
688677 /* TX might be handled here, avoid redundant work */
689678 set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
....@@ -695,15 +684,22 @@
695684 if (ret)
696685 wl12xx_queue_recovery_work(wl);
697686
698
- spin_lock_irqsave(&wl->wl_lock, flags);
699
- /* In case TX was not handled here, queue TX work */
687
+ /* In case TX was not handled in wlcore_irq_locked(), queue TX work */
700688 clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
701
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
702
- wl1271_tx_total_queue_count(wl) > 0)
703
- ieee80211_queue_work(wl->hw, &wl->tx_work);
704
- spin_unlock_irqrestore(&wl->wl_lock, flags);
689
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) {
690
+ if (spin_trylock_irqsave(&wl->wl_lock, flags)) {
691
+ if (!wl1271_tx_total_queue_count(wl))
692
+ queue_tx_work = false;
693
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
694
+ }
695
+ if (queue_tx_work)
696
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
697
+ }
705698
706699 mutex_unlock(&wl->mutex);
700
+
701
+out_handled:
702
+ clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
707703
708704 return IRQ_HANDLED;
709705 }
....@@ -1447,7 +1443,7 @@
14471443
14481444 field = &filter->fields[filter->num_fields];
14491445
1450
- field->pattern = kzalloc(len, GFP_KERNEL);
1446
+ field->pattern = kmemdup(pattern, len, GFP_KERNEL);
14511447 if (!field->pattern) {
14521448 wl1271_warning("Failed to allocate RX filter pattern");
14531449 return -ENOMEM;
....@@ -1458,7 +1454,6 @@
14581454 field->offset = cpu_to_le16(offset);
14591455 field->flags = flags;
14601456 field->len = len;
1461
- memcpy(field->pattern, pattern, len);
14621457
14631458 return 0;
14641459 }
....@@ -1760,9 +1755,7 @@
17601755
17611756 ret = wl1271_configure_suspend(wl, wlvif, wow);
17621757 if (ret < 0) {
1763
- mutex_unlock(&wl->mutex);
1764
- wl1271_warning("couldn't prepare device to suspend");
1765
- return ret;
1758
+ goto out_sleep;
17661759 }
17671760 }
17681761
....@@ -2712,12 +2705,16 @@
27122705
27132706 if (!wlcore_is_p2p_mgmt(wlvif)) {
27142707 ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
2715
- if (ret < 0)
2708
+ if (ret < 0) {
2709
+ pm_runtime_put_noidle(wl->dev);
27162710 goto deinit;
2711
+ }
27172712 } else {
27182713 ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
2719
- if (ret < 0)
2714
+ if (ret < 0) {
2715
+ pm_runtime_put_noidle(wl->dev);
27202716 goto deinit;
2717
+ }
27212718 }
27222719
27232720 pm_runtime_mark_last_busy(wl->dev);
....@@ -3274,7 +3271,7 @@
32743271 static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
32753272 u8 id, u8 key_type, u8 key_size,
32763273 const u8 *key, u8 hlid, u32 tx_seq_32,
3277
- u16 tx_seq_16)
3274
+ u16 tx_seq_16, bool is_pairwise)
32783275 {
32793276 struct wl1271_ap_key *ap_key;
32803277 int i;
....@@ -3312,6 +3309,7 @@
33123309 ap_key->hlid = hlid;
33133310 ap_key->tx_seq_32 = tx_seq_32;
33143311 ap_key->tx_seq_16 = tx_seq_16;
3312
+ ap_key->is_pairwise = is_pairwise;
33153313
33163314 wlvif->ap.recorded_keys[i] = ap_key;
33173315 return 0;
....@@ -3347,7 +3345,7 @@
33473345 key->id, key->key_type,
33483346 key->key_size, key->key,
33493347 hlid, key->tx_seq_32,
3350
- key->tx_seq_16);
3348
+ key->tx_seq_16, key->is_pairwise);
33513349 if (ret < 0)
33523350 goto out;
33533351
....@@ -3370,7 +3368,8 @@
33703368 static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
33713369 u16 action, u8 id, u8 key_type,
33723370 u8 key_size, const u8 *key, u32 tx_seq_32,
3373
- u16 tx_seq_16, struct ieee80211_sta *sta)
3371
+ u16 tx_seq_16, struct ieee80211_sta *sta,
3372
+ bool is_pairwise)
33743373 {
33753374 int ret;
33763375 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
....@@ -3397,12 +3396,12 @@
33973396 ret = wl1271_record_ap_key(wl, wlvif, id,
33983397 key_type, key_size,
33993398 key, hlid, tx_seq_32,
3400
- tx_seq_16);
3399
+ tx_seq_16, is_pairwise);
34013400 } else {
34023401 ret = wl1271_cmd_set_ap_key(wl, wlvif, action,
34033402 id, key_type, key_size,
34043403 key, hlid, tx_seq_32,
3405
- tx_seq_16);
3404
+ tx_seq_16, is_pairwise);
34063405 }
34073406
34083407 if (ret < 0)
....@@ -3502,6 +3501,7 @@
35023501 u16 tx_seq_16 = 0;
35033502 u8 key_type;
35043503 u8 hlid;
3504
+ bool is_pairwise;
35053505
35063506 wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
35073507
....@@ -3551,12 +3551,14 @@
35513551 return -EOPNOTSUPP;
35523552 }
35533553
3554
+ is_pairwise = key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE;
3555
+
35543556 switch (cmd) {
35553557 case SET_KEY:
35563558 ret = wl1271_set_key(wl, wlvif, KEY_ADD_OR_REPLACE,
35573559 key_conf->keyidx, key_type,
35583560 key_conf->keylen, key_conf->key,
3559
- tx_seq_32, tx_seq_16, sta);
3561
+ tx_seq_32, tx_seq_16, sta, is_pairwise);
35603562 if (ret < 0) {
35613563 wl1271_error("Could not add or replace key");
35623564 return ret;
....@@ -3582,7 +3584,7 @@
35823584 ret = wl1271_set_key(wl, wlvif, KEY_REMOVE,
35833585 key_conf->keyidx, key_type,
35843586 key_conf->keylen, key_conf->key,
3585
- 0, 0, sta);
3587
+ 0, 0, sta, is_pairwise);
35863588 if (ret < 0) {
35873589 wl1271_error("Could not remove key");
35883590 return ret;
....@@ -5751,7 +5753,8 @@
57515753 ieee80211_remain_on_channel_expired(wl->hw);
57525754 }
57535755
5754
-static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw)
5756
+static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
5757
+ struct ieee80211_vif *vif)
57555758 {
57565759 struct wl1271 *wl = hw->priv;
57575760
....@@ -6225,6 +6228,7 @@
62256228
62266229 ieee80211_hw_set(wl->hw, SUPPORT_FAST_XMIT);
62276230 ieee80211_hw_set(wl->hw, CHANCTX_STA_CSA);
6231
+ ieee80211_hw_set(wl->hw, SUPPORTS_PER_STA_GTK);
62286232 ieee80211_hw_set(wl->hw, QUEUE_CONTROL);
62296233 ieee80211_hw_set(wl->hw, TX_AMPDU_SETUP_IN_HW);
62306234 ieee80211_hw_set(wl->hw, AMPDU_AGGREGATION);
....@@ -6269,7 +6273,8 @@
62696273
62706274 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
62716275 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
6272
- WIPHY_FLAG_HAS_CHANNEL_SWITCH;
6276
+ WIPHY_FLAG_HAS_CHANNEL_SWITCH |
6277
+ WIPHY_FLAG_IBSS_RSN;
62736278
62746279 wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
62756280
....@@ -6619,12 +6624,24 @@
66196624 }
66206625
66216626 #ifdef CONFIG_PM
6627
+ device_init_wakeup(wl->dev, true);
6628
+
66226629 ret = enable_irq_wake(wl->irq);
66236630 if (!ret) {
66246631 wl->irq_wake_enabled = true;
6625
- device_init_wakeup(wl->dev, 1);
66266632 if (pdev_data->pwr_in_suspend)
66276633 wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
6634
+ }
6635
+
6636
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
6637
+ if (res) {
6638
+ wl->wakeirq = res->start;
6639
+ wl->wakeirq_flags = res->flags & IRQF_TRIGGER_MASK;
6640
+ ret = dev_pm_set_dedicated_wake_irq(wl->dev, wl->wakeirq);
6641
+ if (ret)
6642
+ wl->wakeirq = -ENODEV;
6643
+ } else {
6644
+ wl->wakeirq = -ENODEV;
66286645 }
66296646 #endif
66306647 disable_irq(wl->irq);
....@@ -6653,6 +6670,9 @@
66536670 wl1271_unregister_hw(wl);
66546671
66556672 out_irq:
6673
+ if (wl->wakeirq >= 0)
6674
+ dev_pm_clear_wake_irq(wl->dev);
6675
+ device_init_wakeup(wl->dev, false);
66566676 free_irq(wl->irq, wl);
66576677
66586678 out_free_nvs:
....@@ -6703,7 +6723,6 @@
67036723 unsigned long flags;
67046724 int ret;
67056725 unsigned long start_time = jiffies;
6706
- bool pending = false;
67076726 bool recovery = false;
67086727
67096728 /* Nothing to do if no ELP mode requested */
....@@ -6713,49 +6732,35 @@
67136732 wl1271_debug(DEBUG_PSM, "waking up chip from elp");
67146733
67156734 spin_lock_irqsave(&wl->wl_lock, flags);
6716
- if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
6717
- pending = true;
6718
- else
6719
- wl->elp_compl = &compl;
6735
+ wl->elp_compl = &compl;
67206736 spin_unlock_irqrestore(&wl->wl_lock, flags);
67216737
67226738 ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
67236739 if (ret < 0) {
67246740 recovery = true;
6725
- goto err;
6726
- }
6727
-
6728
- if (!pending) {
6741
+ } else if (!test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) {
67296742 ret = wait_for_completion_timeout(&compl,
67306743 msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
67316744 if (ret == 0) {
67326745 wl1271_warning("ELP wakeup timeout!");
6733
-
6734
- /* Return no error for runtime PM for recovery */
6735
- ret = 0;
67366746 recovery = true;
6737
- goto err;
67386747 }
67396748 }
67406749
6741
- clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
6742
-
6743
- wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
6744
- jiffies_to_msecs(jiffies - start_time));
6745
-
6746
- return 0;
6747
-
6748
-err:
67496750 spin_lock_irqsave(&wl->wl_lock, flags);
67506751 wl->elp_compl = NULL;
67516752 spin_unlock_irqrestore(&wl->wl_lock, flags);
6753
+ clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
67526754
67536755 if (recovery) {
67546756 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
67556757 wl12xx_queue_recovery_work(wl);
6758
+ } else {
6759
+ wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
6760
+ jiffies_to_msecs(jiffies - start_time));
67566761 }
67576762
6758
- return ret;
6763
+ return 0;
67596764 }
67606765
67616766 static const struct dev_pm_ops wlcore_pm_ops = {
....@@ -6817,10 +6822,16 @@
68176822 if (!wl->initialized)
68186823 return 0;
68196824
6820
- if (wl->irq_wake_enabled) {
6821
- device_init_wakeup(wl->dev, 0);
6822
- disable_irq_wake(wl->irq);
6825
+ if (wl->wakeirq >= 0) {
6826
+ dev_pm_clear_wake_irq(wl->dev);
6827
+ wl->wakeirq = -ENODEV;
68236828 }
6829
+
6830
+ device_init_wakeup(wl->dev, false);
6831
+
6832
+ if (wl->irq_wake_enabled)
6833
+ disable_irq_wake(wl->irq);
6834
+
68246835 wl1271_unregister_hw(wl);
68256836
68266837 pm_runtime_put_sync(wl->dev);