diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9002_mac.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 4 |
4 files changed, 66 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 857ede3a999c..741b38ddcb37 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -77,9 +77,16 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked, | |||
77 | mask2 |= ATH9K_INT_CST; | 77 | mask2 |= ATH9K_INT_CST; |
78 | if (isr2 & AR_ISR_S2_TSFOOR) | 78 | if (isr2 & AR_ISR_S2_TSFOOR) |
79 | mask2 |= ATH9K_INT_TSFOOR; | 79 | mask2 |= ATH9K_INT_TSFOOR; |
80 | |||
81 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
82 | REG_WRITE(ah, AR_ISR_S2, isr2); | ||
83 | isr &= ~AR_ISR_BCNMISC; | ||
84 | } | ||
80 | } | 85 | } |
81 | 86 | ||
82 | isr = REG_READ(ah, AR_ISR_RAC); | 87 | if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) |
88 | isr = REG_READ(ah, AR_ISR_RAC); | ||
89 | |||
83 | if (isr == 0xffffffff) { | 90 | if (isr == 0xffffffff) { |
84 | *masked = 0; | 91 | *masked = 0; |
85 | return false; | 92 | return false; |
@@ -98,11 +105,23 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked, | |||
98 | 105 | ||
99 | *masked |= ATH9K_INT_TX; | 106 | *masked |= ATH9K_INT_TX; |
100 | 107 | ||
101 | s0_s = REG_READ(ah, AR_ISR_S0_S); | 108 | if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) { |
109 | s0_s = REG_READ(ah, AR_ISR_S0_S); | ||
110 | s1_s = REG_READ(ah, AR_ISR_S1_S); | ||
111 | } else { | ||
112 | s0_s = REG_READ(ah, AR_ISR_S0); | ||
113 | REG_WRITE(ah, AR_ISR_S0, s0_s); | ||
114 | s1_s = REG_READ(ah, AR_ISR_S1); | ||
115 | REG_WRITE(ah, AR_ISR_S1, s1_s); | ||
116 | |||
117 | isr &= ~(AR_ISR_TXOK | | ||
118 | AR_ISR_TXDESC | | ||
119 | AR_ISR_TXERR | | ||
120 | AR_ISR_TXEOL); | ||
121 | } | ||
122 | |||
102 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); | 123 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); |
103 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); | 124 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); |
104 | |||
105 | s1_s = REG_READ(ah, AR_ISR_S1_S); | ||
106 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); | 125 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); |
107 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); | 126 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); |
108 | } | 127 | } |
@@ -115,13 +134,15 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked, | |||
115 | *masked |= mask2; | 134 | *masked |= mask2; |
116 | } | 135 | } |
117 | 136 | ||
118 | if (AR_SREV_9100(ah)) | 137 | if (!AR_SREV_9100(ah) && (isr & AR_ISR_GENTMR)) { |
119 | return true; | ||
120 | |||
121 | if (isr & AR_ISR_GENTMR) { | ||
122 | u32 s5_s; | 138 | u32 s5_s; |
123 | 139 | ||
124 | s5_s = REG_READ(ah, AR_ISR_S5_S); | 140 | if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) { |
141 | s5_s = REG_READ(ah, AR_ISR_S5_S); | ||
142 | } else { | ||
143 | s5_s = REG_READ(ah, AR_ISR_S5); | ||
144 | } | ||
145 | |||
125 | ah->intr_gen_timer_trigger = | 146 | ah->intr_gen_timer_trigger = |
126 | MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); | 147 | MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); |
127 | 148 | ||
@@ -134,8 +155,21 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked, | |||
134 | if ((s5_s & AR_ISR_S5_TIM_TIMER) && | 155 | if ((s5_s & AR_ISR_S5_TIM_TIMER) && |
135 | !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 156 | !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
136 | *masked |= ATH9K_INT_TIM_TIMER; | 157 | *masked |= ATH9K_INT_TIM_TIMER; |
158 | |||
159 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
160 | REG_WRITE(ah, AR_ISR_S5, s5_s); | ||
161 | isr &= ~AR_ISR_GENTMR; | ||
162 | } | ||
137 | } | 163 | } |
138 | 164 | ||
165 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
166 | REG_WRITE(ah, AR_ISR, isr); | ||
167 | REG_READ(ah, AR_ISR); | ||
168 | } | ||
169 | |||
170 | if (AR_SREV_9100(ah)) | ||
171 | return true; | ||
172 | |||
139 | if (sync_cause) { | 173 | if (sync_cause) { |
140 | if (sync_cause_p) | 174 | if (sync_cause_p) |
141 | *sync_cause_p = sync_cause; | 175 | *sync_cause_p = sync_cause; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a2657fdd9cc..608d739d1378 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -127,21 +127,26 @@ static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
127 | struct ath9k_vif_iter_data *iter_data = data; | 127 | struct ath9k_vif_iter_data *iter_data = data; |
128 | int i; | 128 | int i; |
129 | 129 | ||
130 | for (i = 0; i < ETH_ALEN; i++) | 130 | if (iter_data->hw_macaddr != NULL) { |
131 | iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); | 131 | for (i = 0; i < ETH_ALEN; i++) |
132 | iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); | ||
133 | } else { | ||
134 | iter_data->hw_macaddr = mac; | ||
135 | } | ||
132 | } | 136 | } |
133 | 137 | ||
134 | static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, | 138 | static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv, |
135 | struct ieee80211_vif *vif) | 139 | struct ieee80211_vif *vif) |
136 | { | 140 | { |
137 | struct ath_common *common = ath9k_hw_common(priv->ah); | 141 | struct ath_common *common = ath9k_hw_common(priv->ah); |
138 | struct ath9k_vif_iter_data iter_data; | 142 | struct ath9k_vif_iter_data iter_data; |
139 | 143 | ||
140 | /* | 144 | /* |
141 | * Use the hardware MAC address as reference, the hardware uses it | 145 | * Pick the MAC address of the first interface as the new hardware |
142 | * together with the BSSID mask when matching addresses. | 146 | * MAC address. The hardware will use it together with the BSSID mask |
147 | * when matching addresses. | ||
143 | */ | 148 | */ |
144 | iter_data.hw_macaddr = common->macaddr; | 149 | iter_data.hw_macaddr = NULL; |
145 | memset(&iter_data.mask, 0xff, ETH_ALEN); | 150 | memset(&iter_data.mask, 0xff, ETH_ALEN); |
146 | 151 | ||
147 | if (vif) | 152 | if (vif) |
@@ -153,6 +158,10 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, | |||
153 | ath9k_htc_bssid_iter, &iter_data); | 158 | ath9k_htc_bssid_iter, &iter_data); |
154 | 159 | ||
155 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); | 160 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); |
161 | |||
162 | if (iter_data.hw_macaddr) | ||
163 | memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN); | ||
164 | |||
156 | ath_hw_setbssidmask(common); | 165 | ath_hw_setbssidmask(common); |
157 | } | 166 | } |
158 | 167 | ||
@@ -1063,7 +1072,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1063 | goto out; | 1072 | goto out; |
1064 | } | 1073 | } |
1065 | 1074 | ||
1066 | ath9k_htc_set_bssid_mask(priv, vif); | 1075 | ath9k_htc_set_mac_bssid_mask(priv, vif); |
1067 | 1076 | ||
1068 | priv->vif_slot |= (1 << avp->index); | 1077 | priv->vif_slot |= (1 << avp->index); |
1069 | priv->nvifs++; | 1078 | priv->nvifs++; |
@@ -1128,7 +1137,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1128 | 1137 | ||
1129 | ath9k_htc_set_opmode(priv); | 1138 | ath9k_htc_set_opmode(priv); |
1130 | 1139 | ||
1131 | ath9k_htc_set_bssid_mask(priv, vif); | 1140 | ath9k_htc_set_mac_bssid_mask(priv, vif); |
1132 | 1141 | ||
1133 | /* | 1142 | /* |
1134 | * Stop ANI only if there are no associated station interfaces. | 1143 | * Stop ANI only if there are no associated station interfaces. |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 173a889f9dbb..21b764ba6400 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -994,8 +994,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
994 | struct ath_common *common = ath9k_hw_common(ah); | 994 | struct ath_common *common = ath9k_hw_common(ah); |
995 | 995 | ||
996 | /* | 996 | /* |
997 | * Use the hardware MAC address as reference, the hardware uses it | 997 | * Pick the MAC address of the first interface as the new hardware |
998 | * together with the BSSID mask when matching addresses. | 998 | * MAC address. The hardware will use it together with the BSSID mask |
999 | * when matching addresses. | ||
999 | */ | 1000 | */ |
1000 | memset(iter_data, 0, sizeof(*iter_data)); | 1001 | memset(iter_data, 0, sizeof(*iter_data)); |
1001 | memset(&iter_data->mask, 0xff, ETH_ALEN); | 1002 | memset(&iter_data->mask, 0xff, ETH_ALEN); |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 8707d1a94995..d7aa165fe677 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -738,6 +738,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
738 | }; | 738 | }; |
739 | int index = rtlpci->rx_ring[rx_queue_idx].idx; | 739 | int index = rtlpci->rx_ring[rx_queue_idx].idx; |
740 | 740 | ||
741 | if (rtlpci->driver_is_goingto_unload) | ||
742 | return; | ||
741 | /*RX NORMAL PKT */ | 743 | /*RX NORMAL PKT */ |
742 | while (count--) { | 744 | while (count--) { |
743 | /*rx descriptor */ | 745 | /*rx descriptor */ |
@@ -1634,6 +1636,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) | |||
1634 | */ | 1636 | */ |
1635 | set_hal_stop(rtlhal); | 1637 | set_hal_stop(rtlhal); |
1636 | 1638 | ||
1639 | rtlpci->driver_is_goingto_unload = true; | ||
1637 | rtlpriv->cfg->ops->disable_interrupt(hw); | 1640 | rtlpriv->cfg->ops->disable_interrupt(hw); |
1638 | cancel_work_sync(&rtlpriv->works.lps_change_work); | 1641 | cancel_work_sync(&rtlpriv->works.lps_change_work); |
1639 | 1642 | ||
@@ -1651,7 +1654,6 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) | |||
1651 | ppsc->rfchange_inprogress = true; | 1654 | ppsc->rfchange_inprogress = true; |
1652 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); | 1655 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); |
1653 | 1656 | ||
1654 | rtlpci->driver_is_goingto_unload = true; | ||
1655 | rtlpriv->cfg->ops->hw_disable(hw); | 1657 | rtlpriv->cfg->ops->hw_disable(hw); |
1656 | /* some things are not needed if firmware not available */ | 1658 | /* some things are not needed if firmware not available */ |
1657 | if (!rtlpriv->max_fw_size) | 1659 | if (!rtlpriv->max_fw_size) |