@@ -564,6 +564,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
564
564
spin_lock_init (& rtlpriv -> locks .waitq_lock );
565
565
spin_lock_init (& rtlpriv -> locks .entry_list_lock );
566
566
spin_lock_init (& rtlpriv -> locks .c2hcmd_lock );
567
+ spin_lock_init (& rtlpriv -> locks .scan_list_lock );
567
568
spin_lock_init (& rtlpriv -> locks .cck_and_rw_pagea_lock );
568
569
spin_lock_init (& rtlpriv -> locks .check_sendpkt_lock );
569
570
spin_lock_init (& rtlpriv -> locks .fw_ps_lock );
@@ -572,6 +573,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
572
573
/* <5> init list */
573
574
INIT_LIST_HEAD (& rtlpriv -> entry_list );
574
575
INIT_LIST_HEAD (& rtlpriv -> c2hcmd_list );
576
+ INIT_LIST_HEAD (& rtlpriv -> scan_list .list );
575
577
576
578
rtlmac -> link_state = MAC80211_NOLINK ;
577
579
@@ -582,9 +584,12 @@ int rtl_init_core(struct ieee80211_hw *hw)
582
584
}
583
585
EXPORT_SYMBOL_GPL (rtl_init_core );
584
586
587
+ static void rtl_free_entries_from_scan_list (struct ieee80211_hw * hw );
588
+
585
589
void rtl_deinit_core (struct ieee80211_hw * hw )
586
590
{
587
591
rtl_c2hcmd_launcher (hw , 0 );
592
+ rtl_free_entries_from_scan_list (hw );
588
593
}
589
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
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
1806
void rtl_watchdog_wq_callback (void * data )
1708
1807
{
1709
1808
struct rtl_works * rtlworks = container_of_dwork_rtl (data ,
@@ -1861,6 +1960,9 @@ void rtl_watchdog_wq_callback(void *data)
1861
1960
rtlpriv -> btcoexist .btc_ops -> btc_periodical (rtlpriv );
1862
1961
1863
1962
rtlpriv -> link_info .bcn_rx_inperiod = 0 ;
1963
+
1964
+ /* <6> scan list */
1965
+ rtl_scan_list_expire (hw );
1864
1966
}
1865
1967
1866
1968
void rtl_watch_dog_timer_callback (unsigned long data )
0 commit comments