diff options
author | Ping-Ke Shih <pkshih@realtek.com> | 2018-01-17 01:15:21 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-01-17 10:09:10 -0500 |
commit | a3fa3669d18c959c265eda2048b998c0062a61ce (patch) | |
tree | 50aac2c73bb59847acc8bc536ce567b6218905a8 | |
parent | 98051872fd25077d3b106ab3d2b945fa7025c1ef (diff) |
rtlwifi: Use mutex to replace spin_lock to protect IPS and LPS
Enter/leavel IPS and LPS are large critical section, and they can't use
sleep function because running in atomic-context, which own a spin_lock.
In commit ba9f93f82aba ("rtlwifi: Fix enter/exit power_save"), it moves
LPS functions to thread-context, so this commit can simply change LPS's
spin lock to mutex.
Considering IPS functions, rtl_ips_nic_on() may be called by TX tasklet
(softirq-context) that check whether packet is auth frame. Fortunately,
current mac80211 will ask driver to leave IPS using op_config with
changed flag IEEE80211_CONF_CHANGE_IDLE, before issuing auth frame, so
IPS functions can run in thread-context and use mutex to protect critical
section, too.
Also, this commit removes some useless spin locks.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/ps.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/usb.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/wifi.h | 10 |
4 files changed, 14 insertions, 27 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 0ba9c0cc95e1..89ec318598ea 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c | |||
@@ -551,7 +551,8 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
551 | 551 | ||
552 | /* <4> locks */ | 552 | /* <4> locks */ |
553 | mutex_init(&rtlpriv->locks.conf_mutex); | 553 | mutex_init(&rtlpriv->locks.conf_mutex); |
554 | spin_lock_init(&rtlpriv->locks.ips_lock); | 554 | mutex_init(&rtlpriv->locks.ips_mutex); |
555 | mutex_init(&rtlpriv->locks.lps_mutex); | ||
555 | spin_lock_init(&rtlpriv->locks.irq_th_lock); | 556 | spin_lock_init(&rtlpriv->locks.irq_th_lock); |
556 | spin_lock_init(&rtlpriv->locks.h2c_lock); | 557 | spin_lock_init(&rtlpriv->locks.h2c_lock); |
557 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); | 558 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); |
@@ -561,9 +562,7 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
561 | spin_lock_init(&rtlpriv->locks.c2hcmd_lock); | 562 | spin_lock_init(&rtlpriv->locks.c2hcmd_lock); |
562 | spin_lock_init(&rtlpriv->locks.scan_list_lock); | 563 | spin_lock_init(&rtlpriv->locks.scan_list_lock); |
563 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); | 564 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); |
564 | spin_lock_init(&rtlpriv->locks.check_sendpkt_lock); | ||
565 | spin_lock_init(&rtlpriv->locks.fw_ps_lock); | 565 | spin_lock_init(&rtlpriv->locks.fw_ps_lock); |
566 | spin_lock_init(&rtlpriv->locks.lps_lock); | ||
567 | spin_lock_init(&rtlpriv->locks.iqk_lock); | 566 | spin_lock_init(&rtlpriv->locks.iqk_lock); |
568 | /* <5> init list */ | 567 | /* <5> init list */ |
569 | INIT_LIST_HEAD(&rtlpriv->entry_list); | 568 | INIT_LIST_HEAD(&rtlpriv->entry_list); |
@@ -1229,7 +1228,6 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1229 | } | 1228 | } |
1230 | if (ieee80211_is_auth(fc)) { | 1229 | if (ieee80211_is_auth(fc)) { |
1231 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); | 1230 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); |
1232 | rtl_ips_nic_on(hw); | ||
1233 | 1231 | ||
1234 | mac->link_state = MAC80211_LINKING; | 1232 | mac->link_state = MAC80211_LINKING; |
1235 | /* Dul mac */ | 1233 | /* Dul mac */ |
diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c index 24c87fae5382..6a4008845f49 100644 --- a/drivers/net/wireless/realtek/rtlwifi/ps.c +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c | |||
@@ -289,7 +289,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
289 | 289 | ||
290 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); | 290 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); |
291 | 291 | ||
292 | spin_lock(&rtlpriv->locks.ips_lock); | 292 | mutex_lock(&rtlpriv->locks.ips_mutex); |
293 | if (ppsc->inactiveps) { | 293 | if (ppsc->inactiveps) { |
294 | rtstate = ppsc->rfpwr_state; | 294 | rtstate = ppsc->rfpwr_state; |
295 | 295 | ||
@@ -306,7 +306,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
306 | ppsc->inactive_pwrstate); | 306 | ppsc->inactive_pwrstate); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | spin_unlock(&rtlpriv->locks.ips_lock); | 309 | mutex_unlock(&rtlpriv->locks.ips_mutex); |
310 | } | 310 | } |
311 | EXPORT_SYMBOL_GPL(rtl_ips_nic_on); | 311 | EXPORT_SYMBOL_GPL(rtl_ips_nic_on); |
312 | 312 | ||
@@ -415,7 +415,6 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw) | |||
415 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 415 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
416 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 416 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
417 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 417 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
418 | unsigned long flag; | ||
419 | 418 | ||
420 | if (!ppsc->fwctrl_lps) | 419 | if (!ppsc->fwctrl_lps) |
421 | return; | 420 | return; |
@@ -436,7 +435,7 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw) | |||
436 | if (mac->link_state != MAC80211_LINKED) | 435 | if (mac->link_state != MAC80211_LINKED) |
437 | return; | 436 | return; |
438 | 437 | ||
439 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 438 | mutex_lock(&rtlpriv->locks.lps_mutex); |
440 | 439 | ||
441 | /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because | 440 | /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because |
442 | * bt_ccoexist may ask to enter lps. | 441 | * bt_ccoexist may ask to enter lps. |
@@ -446,7 +445,7 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw) | |||
446 | "Enter 802.11 power save mode...\n"); | 445 | "Enter 802.11 power save mode...\n"); |
447 | rtl_lps_set_psmode(hw, EAUTOPS); | 446 | rtl_lps_set_psmode(hw, EAUTOPS); |
448 | 447 | ||
449 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 448 | mutex_unlock(&rtlpriv->locks.lps_mutex); |
450 | } | 449 | } |
451 | 450 | ||
452 | /* Interrupt safe routine to leave the leisure power save mode.*/ | 451 | /* Interrupt safe routine to leave the leisure power save mode.*/ |
@@ -455,9 +454,8 @@ static void rtl_lps_leave_core(struct ieee80211_hw *hw) | |||
455 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 454 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
456 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 455 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
457 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 456 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
458 | unsigned long flag; | ||
459 | 457 | ||
460 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 458 | mutex_lock(&rtlpriv->locks.lps_mutex); |
461 | 459 | ||
462 | if (ppsc->fwctrl_lps) { | 460 | if (ppsc->fwctrl_lps) { |
463 | if (ppsc->dot11_psmode != EACTIVE) { | 461 | if (ppsc->dot11_psmode != EACTIVE) { |
@@ -478,7 +476,7 @@ static void rtl_lps_leave_core(struct ieee80211_hw *hw) | |||
478 | rtl_lps_set_psmode(hw, EACTIVE); | 476 | rtl_lps_set_psmode(hw, EACTIVE); |
479 | } | 477 | } |
480 | } | 478 | } |
481 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 479 | mutex_unlock(&rtlpriv->locks.lps_mutex); |
482 | } | 480 | } |
483 | 481 | ||
484 | /* For sw LPS*/ | 482 | /* For sw LPS*/ |
@@ -568,7 +566,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
568 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 566 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
569 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 567 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
570 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 568 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
571 | unsigned long flag; | ||
572 | 569 | ||
573 | if (!rtlpriv->psc.swctrl_lps) | 570 | if (!rtlpriv->psc.swctrl_lps) |
574 | return; | 571 | return; |
@@ -581,9 +578,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
581 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 578 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
582 | } | 579 | } |
583 | 580 | ||
584 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 581 | mutex_lock(&rtlpriv->locks.lps_mutex); |
585 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); | 582 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
586 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 583 | mutex_unlock(&rtlpriv->locks.lps_mutex); |
587 | } | 584 | } |
588 | 585 | ||
589 | void rtl_swlps_rfon_wq_callback(void *data) | 586 | void rtl_swlps_rfon_wq_callback(void *data) |
@@ -600,7 +597,6 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
600 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 597 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
601 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 598 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
602 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 599 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
603 | unsigned long flag; | ||
604 | u8 sleep_intv; | 600 | u8 sleep_intv; |
605 | 601 | ||
606 | if (!rtlpriv->psc.sw_ps_enabled) | 602 | if (!rtlpriv->psc.sw_ps_enabled) |
@@ -624,9 +620,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
624 | } | 620 | } |
625 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | 621 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
626 | 622 | ||
627 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 623 | mutex_lock(&rtlpriv->locks.lps_mutex); |
628 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); | 624 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
629 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 625 | mutex_unlock(&rtlpriv->locks.lps_mutex); |
630 | 626 | ||
631 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 627 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
632 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 628 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index 39b033b3b53a..ce3103bb8ebb 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c | |||
@@ -962,7 +962,6 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, | |||
962 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | 962 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); |
963 | if (ieee80211_is_auth(fc)) { | 963 | if (ieee80211_is_auth(fc)) { |
964 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); | 964 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); |
965 | rtl_ips_nic_on(hw); | ||
966 | } | 965 | } |
967 | 966 | ||
968 | if (rtlpriv->psc.sw_ps_enabled) { | 967 | if (rtlpriv->psc.sw_ps_enabled) { |
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 0b1c54381a2f..941694060f48 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h | |||
@@ -2325,17 +2325,14 @@ struct rtl_hal_cfg { | |||
2325 | struct rtl_locks { | 2325 | struct rtl_locks { |
2326 | /* mutex */ | 2326 | /* mutex */ |
2327 | struct mutex conf_mutex; | 2327 | struct mutex conf_mutex; |
2328 | struct mutex ps_mutex; | 2328 | struct mutex ips_mutex; /* mutex for enter/leave IPS */ |
2329 | struct mutex lps_mutex; /* mutex for enter/leave LPS */ | ||
2329 | 2330 | ||
2330 | /*spin lock */ | 2331 | /*spin lock */ |
2331 | spinlock_t ips_lock; | ||
2332 | spinlock_t irq_th_lock; | 2332 | spinlock_t irq_th_lock; |
2333 | spinlock_t irq_pci_lock; | ||
2334 | spinlock_t tx_lock; | ||
2335 | spinlock_t h2c_lock; | 2333 | spinlock_t h2c_lock; |
2336 | spinlock_t rf_ps_lock; | 2334 | spinlock_t rf_ps_lock; |
2337 | spinlock_t rf_lock; | 2335 | spinlock_t rf_lock; |
2338 | spinlock_t lps_lock; | ||
2339 | spinlock_t waitq_lock; | 2336 | spinlock_t waitq_lock; |
2340 | spinlock_t entry_list_lock; | 2337 | spinlock_t entry_list_lock; |
2341 | spinlock_t usb_lock; | 2338 | spinlock_t usb_lock; |
@@ -2348,9 +2345,6 @@ struct rtl_locks { | |||
2348 | /*Dual mac*/ | 2345 | /*Dual mac*/ |
2349 | spinlock_t cck_and_rw_pagea_lock; | 2346 | spinlock_t cck_and_rw_pagea_lock; |
2350 | 2347 | ||
2351 | /*Easy concurrent*/ | ||
2352 | spinlock_t check_sendpkt_lock; | ||
2353 | |||
2354 | spinlock_t iqk_lock; | 2348 | spinlock_t iqk_lock; |
2355 | }; | 2349 | }; |
2356 | 2350 | ||