diff options
author | Ping-Ke Shih <pkshih@realtek.com> | 2017-06-21 13:15:37 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2017-06-28 13:51:01 -0400 |
commit | c76ab8e754426729199448ae1749e88fbbf04dd1 (patch) | |
tree | a416e553cf33df6fac69ac1618951ee75d9ba2cd | |
parent | f1cb27eda3a69099c4e2c9feb0d6c7e5d6ddf668 (diff) |
rtlwifi: Fill ap_num field by driver
Check beacon and probe_resp frames to know ap_num
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Yan-Hsuan Chuang <yhchuang@realtek.com>
Cc: Birming Chiu <birming@realtek.com>
Cc: Shaofu <shaofu@realtek.com>
Cc: Steven Ting <steventing@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.c | 102 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/core.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/pci.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/wifi.h | 13 |
5 files changed, 123 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index d34ad94c327b..e36ee592c660 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c | |||
@@ -564,6 +564,7 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
564 | spin_lock_init(&rtlpriv->locks.waitq_lock); | 564 | spin_lock_init(&rtlpriv->locks.waitq_lock); |
565 | spin_lock_init(&rtlpriv->locks.entry_list_lock); | 565 | spin_lock_init(&rtlpriv->locks.entry_list_lock); |
566 | spin_lock_init(&rtlpriv->locks.c2hcmd_lock); | 566 | spin_lock_init(&rtlpriv->locks.c2hcmd_lock); |
567 | spin_lock_init(&rtlpriv->locks.scan_list_lock); | ||
567 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); | 568 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); |
568 | spin_lock_init(&rtlpriv->locks.check_sendpkt_lock); | 569 | spin_lock_init(&rtlpriv->locks.check_sendpkt_lock); |
569 | spin_lock_init(&rtlpriv->locks.fw_ps_lock); | 570 | spin_lock_init(&rtlpriv->locks.fw_ps_lock); |
@@ -572,6 +573,7 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
572 | /* <5> init list */ | 573 | /* <5> init list */ |
573 | INIT_LIST_HEAD(&rtlpriv->entry_list); | 574 | INIT_LIST_HEAD(&rtlpriv->entry_list); |
574 | INIT_LIST_HEAD(&rtlpriv->c2hcmd_list); | 575 | INIT_LIST_HEAD(&rtlpriv->c2hcmd_list); |
576 | INIT_LIST_HEAD(&rtlpriv->scan_list.list); | ||
575 | 577 | ||
576 | rtlmac->link_state = MAC80211_NOLINK; | 578 | rtlmac->link_state = MAC80211_NOLINK; |
577 | 579 | ||
@@ -582,9 +584,12 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
582 | } | 584 | } |
583 | EXPORT_SYMBOL_GPL(rtl_init_core); | 585 | EXPORT_SYMBOL_GPL(rtl_init_core); |
584 | 586 | ||
587 | static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw); | ||
588 | |||
585 | void rtl_deinit_core(struct ieee80211_hw *hw) | 589 | void rtl_deinit_core(struct ieee80211_hw *hw) |
586 | { | 590 | { |
587 | rtl_c2hcmd_launcher(hw, 0); | 591 | rtl_c2hcmd_launcher(hw, 0); |
592 | rtl_free_entries_from_scan_list(hw); | ||
588 | } | 593 | } |
589 | EXPORT_SYMBOL_GPL(rtl_deinit_core); | 594 | EXPORT_SYMBOL_GPL(rtl_deinit_core); |
590 | 595 | ||
@@ -1704,6 +1709,100 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1704 | } | 1709 | } |
1705 | EXPORT_SYMBOL_GPL(rtl_beacon_statistic); | 1710 | EXPORT_SYMBOL_GPL(rtl_beacon_statistic); |
1706 | 1711 | ||
1712 | static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw) | ||
1713 | { | ||
1714 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1715 | struct rtl_bssid_entry *entry, *next; | ||
1716 | |||
1717 | list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) { | ||
1718 | list_del(&entry->list); | ||
1719 | kfree(entry); | ||
1720 | rtlpriv->scan_list.num--; | ||
1721 | } | ||
1722 | } | ||
1723 | |||
1724 | void rtl_scan_list_expire(struct ieee80211_hw *hw) | ||
1725 | { | ||
1726 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1727 | struct rtl_bssid_entry *entry, *next; | ||
1728 | unsigned long flags; | ||
1729 | |||
1730 | spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); | ||
1731 | |||
1732 | list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) { | ||
1733 | /* 180 seconds */ | ||
1734 | if (jiffies_to_msecs(jiffies - entry->age) < 180000) | ||
1735 | continue; | ||
1736 | |||
1737 | list_del(&entry->list); | ||
1738 | kfree(entry); | ||
1739 | rtlpriv->scan_list.num--; | ||
1740 | |||
1741 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, | ||
1742 | "BSSID=%pM is expire in scan list (total=%d)\n", | ||
1743 | entry->bssid, rtlpriv->scan_list.num); | ||
1744 | } | ||
1745 | |||
1746 | spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags); | ||
1747 | |||
1748 | rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num; | ||
1749 | } | ||
1750 | |||
1751 | void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1752 | { | ||
1753 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1754 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1755 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1756 | unsigned long flags; | ||
1757 | |||
1758 | struct rtl_bssid_entry *entry; | ||
1759 | bool entry_found = false; | ||
1760 | |||
1761 | /* check if it is scanning */ | ||
1762 | if (!mac->act_scanning) | ||
1763 | return; | ||
1764 | |||
1765 | /* check if this really is a beacon */ | ||
1766 | if (!ieee80211_is_beacon(hdr->frame_control) && | ||
1767 | !ieee80211_is_probe_resp(hdr->frame_control)) | ||
1768 | return; | ||
1769 | |||
1770 | spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); | ||
1771 | |||
1772 | list_for_each_entry(entry, &rtlpriv->scan_list.list, list) { | ||
1773 | if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) { | ||
1774 | list_del_init(&entry->list); | ||
1775 | entry_found = true; | ||
1776 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, | ||
1777 | "Update BSSID=%pM to scan list (total=%d)\n", | ||
1778 | hdr->addr3, rtlpriv->scan_list.num); | ||
1779 | break; | ||
1780 | } | ||
1781 | } | ||
1782 | |||
1783 | if (!entry_found) { | ||
1784 | entry = kmalloc(sizeof(*entry), GFP_ATOMIC); | ||
1785 | |||
1786 | if (!entry) | ||
1787 | goto label_err; | ||
1788 | |||
1789 | memcpy(entry->bssid, hdr->addr3, ETH_ALEN); | ||
1790 | rtlpriv->scan_list.num++; | ||
1791 | |||
1792 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, | ||
1793 | "Add BSSID=%pM to scan list (total=%d)\n", | ||
1794 | hdr->addr3, rtlpriv->scan_list.num); | ||
1795 | } | ||
1796 | |||
1797 | entry->age = jiffies; | ||
1798 | |||
1799 | list_add_tail(&entry->list, &rtlpriv->scan_list.list); | ||
1800 | |||
1801 | label_err: | ||
1802 | spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags); | ||
1803 | } | ||
1804 | EXPORT_SYMBOL(rtl_collect_scan_list); | ||
1805 | |||
1707 | void rtl_watchdog_wq_callback(void *data) | 1806 | void rtl_watchdog_wq_callback(void *data) |
1708 | { | 1807 | { |
1709 | struct rtl_works *rtlworks = container_of_dwork_rtl(data, | 1808 | struct rtl_works *rtlworks = container_of_dwork_rtl(data, |
@@ -1861,6 +1960,9 @@ label_lps_done: | |||
1861 | rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv); | 1960 | rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv); |
1862 | 1961 | ||
1863 | rtlpriv->link_info.bcn_rx_inperiod = 0; | 1962 | rtlpriv->link_info.bcn_rx_inperiod = 0; |
1963 | |||
1964 | /* <6> scan list */ | ||
1965 | rtl_scan_list_expire(hw); | ||
1864 | } | 1966 | } |
1865 | 1967 | ||
1866 | void rtl_watch_dog_timer_callback(unsigned long data) | 1968 | void rtl_watch_dog_timer_callback(unsigned long data) |
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h index 21fa4562f631..ab7d81904d25 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.h +++ b/drivers/net/wireless/realtek/rtlwifi/base.h | |||
@@ -137,6 +137,8 @@ bool rtl_check_tx_report_acked(struct ieee80211_hw *hw); | |||
137 | void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms); | 137 | void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms); |
138 | 138 | ||
139 | void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); | 139 | void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); |
140 | void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
141 | void rtl_scan_list_expire(struct ieee80211_hw *hw); | ||
140 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 142 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
141 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); | 143 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); |
142 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 144 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c index 1a53a95d373b..b0ad061048c5 100644 --- a/drivers/net/wireless/realtek/rtlwifi/core.c +++ b/drivers/net/wireless/realtek/rtlwifi/core.c | |||
@@ -1464,6 +1464,9 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw, | |||
1464 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); | 1464 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); |
1465 | mac->act_scanning = false; | 1465 | mac->act_scanning = false; |
1466 | mac->skip_scan = false; | 1466 | mac->skip_scan = false; |
1467 | |||
1468 | rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num; | ||
1469 | |||
1467 | if (rtlpriv->link_info.higher_busytraffic) | 1470 | if (rtlpriv->link_info.higher_busytraffic) |
1468 | return; | 1471 | return; |
1469 | 1472 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index a3997da72ed3..032b6317690d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c | |||
@@ -879,6 +879,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
879 | if (unicast) | 879 | if (unicast) |
880 | rtlpriv->link_info.num_rx_inperiod++; | 880 | rtlpriv->link_info.num_rx_inperiod++; |
881 | } | 881 | } |
882 | |||
883 | rtl_collect_scan_list(hw, skb); | ||
884 | |||
882 | /* static bcn for roaming */ | 885 | /* static bcn for roaming */ |
883 | rtl_beacon_statistic(hw, skb); | 886 | rtl_beacon_statistic(hw, skb); |
884 | rtl_p2p_info(hw, (void *)skb->data, skb->len); | 887 | rtl_p2p_info(hw, (void *)skb->data, skb->len); |
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 2fb83a7061dd..98183dc707aa 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h | |||
@@ -2333,6 +2333,7 @@ struct rtl_locks { | |||
2333 | spinlock_t entry_list_lock; | 2333 | spinlock_t entry_list_lock; |
2334 | spinlock_t usb_lock; | 2334 | spinlock_t usb_lock; |
2335 | spinlock_t c2hcmd_lock; | 2335 | spinlock_t c2hcmd_lock; |
2336 | spinlock_t scan_list_lock; /* lock for the scan list */ | ||
2336 | 2337 | ||
2337 | /*FW clock change */ | 2338 | /*FW clock change */ |
2338 | spinlock_t fw_ps_lock; | 2339 | spinlock_t fw_ps_lock; |
@@ -2587,6 +2588,17 @@ struct rtl_c2hcmd { | |||
2587 | u8 *val; | 2588 | u8 *val; |
2588 | }; | 2589 | }; |
2589 | 2590 | ||
2591 | struct rtl_bssid_entry { | ||
2592 | struct list_head list; | ||
2593 | u8 bssid[ETH_ALEN]; | ||
2594 | u32 age; | ||
2595 | }; | ||
2596 | |||
2597 | struct rtl_scan_list { | ||
2598 | int num; | ||
2599 | struct list_head list; /* sort by age */ | ||
2600 | }; | ||
2601 | |||
2590 | struct rtl_priv { | 2602 | struct rtl_priv { |
2591 | struct ieee80211_hw *hw; | 2603 | struct ieee80211_hw *hw; |
2592 | struct completion firmware_loading_complete; | 2604 | struct completion firmware_loading_complete; |
@@ -2608,6 +2620,7 @@ struct rtl_priv { | |||
2608 | struct rtl_efuse efuse; | 2620 | struct rtl_efuse efuse; |
2609 | struct rtl_led_ctl ledctl; | 2621 | struct rtl_led_ctl ledctl; |
2610 | struct rtl_tx_report tx_report; | 2622 | struct rtl_tx_report tx_report; |
2623 | struct rtl_scan_list scan_list; | ||
2611 | 2624 | ||
2612 | struct rtl_ps_ctl psc; | 2625 | struct rtl_ps_ctl psc; |
2613 | struct rate_adaptive ra; | 2626 | struct rate_adaptive ra; |