aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2017-06-21 13:15:37 -0400
committerKalle Valo <kvalo@codeaurora.org>2017-06-28 13:51:01 -0400
commitc76ab8e754426729199448ae1749e88fbbf04dd1 (patch)
treea416e553cf33df6fac69ac1618951ee75d9ba2cd
parentf1cb27eda3a69099c4e2c9feb0d6c7e5d6ddf668 (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.c102
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/core.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h13
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}
583EXPORT_SYMBOL_GPL(rtl_init_core); 585EXPORT_SYMBOL_GPL(rtl_init_core);
584 586
587static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw);
588
585void rtl_deinit_core(struct ieee80211_hw *hw) 589void 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}
589EXPORT_SYMBOL_GPL(rtl_deinit_core); 594EXPORT_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}
1705EXPORT_SYMBOL_GPL(rtl_beacon_statistic); 1710EXPORT_SYMBOL_GPL(rtl_beacon_statistic);
1706 1711
1712static 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
1724void 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
1751void 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
1801label_err:
1802 spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);
1803}
1804EXPORT_SYMBOL(rtl_collect_scan_list);
1805
1707void rtl_watchdog_wq_callback(void *data) 1806void 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
1866void rtl_watch_dog_timer_callback(unsigned long data) 1968void 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);
137void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms); 137void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms);
138 138
139void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); 139void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
140void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb);
141void rtl_scan_list_expire(struct ieee80211_hw *hw);
140int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 142int 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);
142int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 144int 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
2591struct rtl_bssid_entry {
2592 struct list_head list;
2593 u8 bssid[ETH_ALEN];
2594 u32 age;
2595};
2596
2597struct rtl_scan_list {
2598 int num;
2599 struct list_head list; /* sort by age */
2600};
2601
2590struct rtl_priv { 2602struct 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;