diff options
-rw-r--r-- | drivers/net/wireless/rtlwifi/base.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/core.c | 408 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/ps.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/usb.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/wifi.h | 4 |
7 files changed, 268 insertions, 160 deletions
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 7b3eadfdaf8c..2df99463a681 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -1182,14 +1182,8 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, | |||
1182 | info->control.rates[0].idx = 0; | 1182 | info->control.rates[0].idx = 0; |
1183 | info->control.sta = sta; | 1183 | info->control.sta = sta; |
1184 | info->band = hw->conf.channel->band; | 1184 | info->band = hw->conf.channel->band; |
1185 | #if 0 | ||
1186 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); | 1185 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); |
1187 | #else | ||
1188 | rtlpriv->intf_ops->adapter_tx(hw, skb); | ||
1189 | #endif | ||
1190 | } | 1186 | } |
1191 | return 1; | ||
1192 | |||
1193 | err_free: | 1187 | err_free: |
1194 | return 0; | 1188 | return 0; |
1195 | } | 1189 | } |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 8fed3c687619..fc89cd8c8320 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #include "wifi.h" | 30 | #include "wifi.h" |
@@ -70,6 +71,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) | |||
70 | 71 | ||
71 | mac->link_state = MAC80211_NOLINK; | 72 | mac->link_state = MAC80211_NOLINK; |
72 | memset(mac->bssid, 0, 6); | 73 | memset(mac->bssid, 0, 6); |
74 | mac->vendor = PEER_UNKNOWN; | ||
73 | 75 | ||
74 | /*reset sec info */ | 76 | /*reset sec info */ |
75 | rtl_cam_reset_sec_info(hw); | 77 | rtl_cam_reset_sec_info(hw); |
@@ -85,6 +87,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
85 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 87 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
86 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 88 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
87 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 89 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
90 | struct rtl_tcb_desc tcb_desc; | ||
91 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
88 | 92 | ||
89 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) | 93 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) |
90 | goto err_free; | 94 | goto err_free; |
@@ -92,8 +96,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
92 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) | 96 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) |
93 | goto err_free; | 97 | goto err_free; |
94 | 98 | ||
95 | 99 | if (!rtlpriv->intf_ops->waitq_insert(hw, skb)) | |
96 | rtlpriv->intf_ops->adapter_tx(hw, skb); | 100 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); |
97 | 101 | ||
98 | return; | 102 | return; |
99 | 103 | ||
@@ -134,10 +138,26 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, | |||
134 | 138 | ||
135 | mac->link_state = MAC80211_LINKED; | 139 | mac->link_state = MAC80211_LINKED; |
136 | rtlpriv->cfg->ops->set_bcn_reg(hw); | 140 | rtlpriv->cfg->ops->set_bcn_reg(hw); |
141 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) | ||
142 | mac->basic_rates = 0xfff; | ||
143 | else | ||
144 | mac->basic_rates = 0xff0; | ||
145 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | ||
146 | (u8 *) (&mac->basic_rates)); | ||
147 | |||
137 | break; | 148 | break; |
138 | case NL80211_IFTYPE_AP: | 149 | case NL80211_IFTYPE_AP: |
139 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 150 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
140 | ("NL80211_IFTYPE_AP\n")); | 151 | ("NL80211_IFTYPE_AP\n")); |
152 | |||
153 | mac->link_state = MAC80211_LINKED; | ||
154 | rtlpriv->cfg->ops->set_bcn_reg(hw); | ||
155 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) | ||
156 | mac->basic_rates = 0xfff; | ||
157 | else | ||
158 | mac->basic_rates = 0xff0; | ||
159 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | ||
160 | (u8 *) (&mac->basic_rates)); | ||
141 | break; | 161 | break; |
142 | default: | 162 | default: |
143 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 163 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
@@ -184,13 +204,12 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, | |||
184 | mac->vif = NULL; | 204 | mac->vif = NULL; |
185 | mac->link_state = MAC80211_NOLINK; | 205 | mac->link_state = MAC80211_NOLINK; |
186 | memset(mac->bssid, 0, 6); | 206 | memset(mac->bssid, 0, 6); |
207 | mac->vendor = PEER_UNKNOWN; | ||
187 | mac->opmode = NL80211_IFTYPE_UNSPECIFIED; | 208 | mac->opmode = NL80211_IFTYPE_UNSPECIFIED; |
188 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); | 209 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); |
189 | |||
190 | mutex_unlock(&rtlpriv->locks.conf_mutex); | 210 | mutex_unlock(&rtlpriv->locks.conf_mutex); |
191 | } | 211 | } |
192 | 212 | ||
193 | |||
194 | static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | 213 | static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) |
195 | { | 214 | { |
196 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 215 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -222,10 +241,25 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
222 | 241 | ||
223 | /*For LPS */ | 242 | /*For LPS */ |
224 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 243 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
225 | if (conf->flags & IEEE80211_CONF_PS) | 244 | cancel_delayed_work(&rtlpriv->works.ps_work); |
226 | rtl_lps_enter(hw); | 245 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); |
227 | else | 246 | if (conf->flags & IEEE80211_CONF_PS) { |
228 | rtl_lps_leave(hw); | 247 | rtlpriv->psc.sw_ps_enabled = true; |
248 | /* sleep here is must, or we may recv the beacon and | ||
249 | * cause mac80211 into wrong ps state, this will cause | ||
250 | * power save nullfunc send fail, and further cause | ||
251 | * pkt loss, So sleep must quickly but not immediatly | ||
252 | * because that will cause nullfunc send by mac80211 | ||
253 | * fail, and cause pkt loss, we have tested that 5mA | ||
254 | * is worked very well */ | ||
255 | if (!rtlpriv->psc.multi_buffered) | ||
256 | queue_delayed_work(rtlpriv->works.rtl_wq, | ||
257 | &rtlpriv->works.ps_work, | ||
258 | MSECS(5)); | ||
259 | } else { | ||
260 | rtl_swlps_rf_awake(hw); | ||
261 | rtlpriv->psc.sw_ps_enabled = false; | ||
262 | } | ||
229 | } | 263 | } |
230 | 264 | ||
231 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { | 265 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { |
@@ -257,7 +291,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
257 | case NL80211_CHAN_NO_HT: | 291 | case NL80211_CHAN_NO_HT: |
258 | /* SC */ | 292 | /* SC */ |
259 | mac->cur_40_prime_sc = | 293 | mac->cur_40_prime_sc = |
260 | PRIME_CHNL_OFFSET_DONT_CARE; | 294 | PRIME_CHNL_OFFSET_DONT_CARE; |
261 | rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; | 295 | rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; |
262 | mac->bw_40 = false; | 296 | mac->bw_40 = false; |
263 | break; | 297 | break; |
@@ -265,7 +299,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
265 | /* SC */ | 299 | /* SC */ |
266 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; | 300 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; |
267 | rtlphy->current_chan_bw = | 301 | rtlphy->current_chan_bw = |
268 | HT_CHANNEL_WIDTH_20_40; | 302 | HT_CHANNEL_WIDTH_20_40; |
269 | mac->bw_40 = true; | 303 | mac->bw_40 = true; |
270 | 304 | ||
271 | /*wide channel */ | 305 | /*wide channel */ |
@@ -276,7 +310,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
276 | /* SC */ | 310 | /* SC */ |
277 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; | 311 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; |
278 | rtlphy->current_chan_bw = | 312 | rtlphy->current_chan_bw = |
279 | HT_CHANNEL_WIDTH_20_40; | 313 | HT_CHANNEL_WIDTH_20_40; |
280 | mac->bw_40 = true; | 314 | mac->bw_40 = true; |
281 | 315 | ||
282 | /*wide channel */ | 316 | /*wide channel */ |
@@ -286,16 +320,29 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
286 | default: | 320 | default: |
287 | mac->bw_40 = false; | 321 | mac->bw_40 = false; |
288 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 322 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
289 | ("switch case not processed\n")); | 323 | ("switch case not processed\n")); |
290 | break; | 324 | break; |
291 | } | 325 | } |
292 | 326 | ||
293 | if (wide_chan <= 0) | 327 | if (wide_chan <= 0) |
294 | wide_chan = 1; | 328 | wide_chan = 1; |
329 | |||
330 | /* In scanning, before we go offchannel we may send a ps=1 null | ||
331 | * to AP, and then we may send a ps = 0 null to AP quickly, but | ||
332 | * first null may have caused AP to put lots of packet to hw tx | ||
333 | * buffer. These packets must be tx'd before we go off channel | ||
334 | * so we must delay more time to let AP flush these packets | ||
335 | * before going offchannel, or dis-association or delete BA will | ||
336 | * happen by AP | ||
337 | */ | ||
338 | if (rtlpriv->mac80211.offchan_deley) { | ||
339 | rtlpriv->mac80211.offchan_deley = false; | ||
340 | mdelay(50); | ||
341 | } | ||
295 | rtlphy->current_channel = wide_chan; | 342 | rtlphy->current_channel = wide_chan; |
296 | 343 | ||
297 | rtlpriv->cfg->ops->set_channel_access(hw); | ||
298 | rtlpriv->cfg->ops->switch_channel(hw); | 344 | rtlpriv->cfg->ops->switch_channel(hw); |
345 | rtlpriv->cfg->ops->set_channel_access(hw); | ||
299 | rtlpriv->cfg->ops->set_bw_mode(hw, | 346 | rtlpriv->cfg->ops->set_bw_mode(hw, |
300 | hw->conf.channel_type); | 347 | hw->conf.channel_type); |
301 | } | 348 | } |
@@ -343,27 +390,28 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, | |||
343 | } | 390 | } |
344 | } | 391 | } |
345 | 392 | ||
346 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { | 393 | /* if ssid not set to hw don't check bssid |
347 | /* | 394 | * here just used for linked scanning, & linked |
348 | *TODO: BIT(5) is probe response BIT(8) is beacon | 395 | * and nolink check bssid is set in set network_type */ |
349 | *TODO: Use define for BIT(5) and BIT(8) | 396 | if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && |
350 | */ | 397 | (mac->link_state >= MAC80211_LINKED)) { |
351 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) | 398 | if (mac->opmode != NL80211_IFTYPE_AP) { |
352 | mac->rx_mgt_filter |= (BIT(5) | BIT(8)); | 399 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { |
353 | else | 400 | rtlpriv->cfg->ops->set_chk_bssid(hw, false); |
354 | mac->rx_mgt_filter &= ~(BIT(5) | BIT(8)); | 401 | } else { |
402 | rtlpriv->cfg->ops->set_chk_bssid(hw, true); | ||
403 | } | ||
404 | } | ||
355 | } | 405 | } |
356 | 406 | ||
357 | if (changed_flags & FIF_CONTROL) { | 407 | if (changed_flags & FIF_CONTROL) { |
358 | if (*new_flags & FIF_CONTROL) { | 408 | if (*new_flags & FIF_CONTROL) { |
359 | mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; | 409 | mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; |
360 | mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER; | ||
361 | 410 | ||
362 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 411 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
363 | ("Enable receive control frame.\n")); | 412 | ("Enable receive control frame.\n")); |
364 | } else { | 413 | } else { |
365 | mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; | 414 | mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; |
366 | mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER; | ||
367 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 415 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
368 | ("Disable receive control frame.\n")); | 416 | ("Disable receive control frame.\n")); |
369 | } | 417 | } |
@@ -380,14 +428,54 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, | |||
380 | ("Disable receive other BSS's frame.\n")); | 428 | ("Disable receive other BSS's frame.\n")); |
381 | } | 429 | } |
382 | } | 430 | } |
383 | |||
384 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); | ||
385 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, | ||
386 | (u8 *) (&mac->rx_mgt_filter)); | ||
387 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, | ||
388 | (u8 *) (&mac->rx_ctrl_filter)); | ||
389 | } | 431 | } |
432 | static int rtl_op_sta_add(struct ieee80211_hw *hw, | ||
433 | struct ieee80211_vif *vif, | ||
434 | struct ieee80211_sta *sta) | ||
435 | { | ||
436 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
437 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
438 | struct rtl_sta_info *sta_entry; | ||
439 | |||
440 | if (sta) { | ||
441 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
442 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | ||
443 | sta_entry->wireless_mode = WIRELESS_MODE_G; | ||
444 | if (sta->supp_rates[0] <= 0xf) | ||
445 | sta_entry->wireless_mode = WIRELESS_MODE_B; | ||
446 | if (sta->ht_cap.ht_supported == true) | ||
447 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | ||
448 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { | ||
449 | sta_entry->wireless_mode = WIRELESS_MODE_A; | ||
450 | if (sta->ht_cap.ht_supported == true) | ||
451 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | ||
452 | } | ||
453 | |||
454 | /* I found some times mac80211 give wrong supp_rates for adhoc*/ | ||
455 | if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) | ||
456 | sta_entry->wireless_mode = WIRELESS_MODE_G; | ||
390 | 457 | ||
458 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | ||
459 | ("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); | ||
460 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
461 | } | ||
462 | return 0; | ||
463 | } | ||
464 | static int rtl_op_sta_remove(struct ieee80211_hw *hw, | ||
465 | struct ieee80211_vif *vif, | ||
466 | struct ieee80211_sta *sta) | ||
467 | { | ||
468 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
469 | struct rtl_sta_info *sta_entry; | ||
470 | if (sta) { | ||
471 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | ||
472 | ("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); | ||
473 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
474 | sta_entry->wireless_mode = 0; | ||
475 | sta_entry->ratr_index = 0; | ||
476 | } | ||
477 | return 0; | ||
478 | } | ||
391 | static int _rtl_get_hal_qnum(u16 queue) | 479 | static int _rtl_get_hal_qnum(u16 queue) |
392 | { | 480 | { |
393 | int qnum; | 481 | int qnum; |
@@ -444,19 +532,18 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
444 | struct ieee80211_bss_conf *bss_conf, u32 changed) | 532 | struct ieee80211_bss_conf *bss_conf, u32 changed) |
445 | { | 533 | { |
446 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 534 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
535 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
447 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 536 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
448 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 537 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
538 | struct ieee80211_sta *sta = NULL; | ||
449 | 539 | ||
450 | mutex_lock(&rtlpriv->locks.conf_mutex); | 540 | mutex_lock(&rtlpriv->locks.conf_mutex); |
451 | |||
452 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 541 | if ((vif->type == NL80211_IFTYPE_ADHOC) || |
453 | (vif->type == NL80211_IFTYPE_AP) || | 542 | (vif->type == NL80211_IFTYPE_AP) || |
454 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 543 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
455 | |||
456 | if ((changed & BSS_CHANGED_BEACON) || | 544 | if ((changed & BSS_CHANGED_BEACON) || |
457 | (changed & BSS_CHANGED_BEACON_ENABLED && | 545 | (changed & BSS_CHANGED_BEACON_ENABLED && |
458 | bss_conf->enable_beacon)) { | 546 | bss_conf->enable_beacon)) { |
459 | |||
460 | if (mac->beacon_enabled == 0) { | 547 | if (mac->beacon_enabled == 0) { |
461 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 548 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
462 | ("BSS_CHANGED_BEACON_ENABLED\n")); | 549 | ("BSS_CHANGED_BEACON_ENABLED\n")); |
@@ -468,8 +555,13 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
468 | rtlpriv->cfg->maps | 555 | rtlpriv->cfg->maps |
469 | [RTL_IBSS_INT_MASKS], | 556 | [RTL_IBSS_INT_MASKS], |
470 | 0); | 557 | 0); |
558 | |||
559 | if (rtlpriv->cfg->ops->linked_set_reg) | ||
560 | rtlpriv->cfg->ops->linked_set_reg(hw); | ||
471 | } | 561 | } |
472 | } else { | 562 | } |
563 | if ((changed & BSS_CHANGED_BEACON_ENABLED && | ||
564 | !bss_conf->enable_beacon)) { | ||
473 | if (mac->beacon_enabled == 1) { | 565 | if (mac->beacon_enabled == 1) { |
474 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 566 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
475 | ("ADHOC DISABLE BEACON\n")); | 567 | ("ADHOC DISABLE BEACON\n")); |
@@ -480,7 +572,6 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
480 | [RTL_IBSS_INT_MASKS]); | 572 | [RTL_IBSS_INT_MASKS]); |
481 | } | 573 | } |
482 | } | 574 | } |
483 | |||
484 | if (changed & BSS_CHANGED_BEACON_INT) { | 575 | if (changed & BSS_CHANGED_BEACON_INT) { |
485 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, | 576 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, |
486 | ("BSS_CHANGED_BEACON_INT\n")); | 577 | ("BSS_CHANGED_BEACON_INT\n")); |
@@ -492,11 +583,25 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
492 | /*TODO: reference to enum ieee80211_bss_change */ | 583 | /*TODO: reference to enum ieee80211_bss_change */ |
493 | if (changed & BSS_CHANGED_ASSOC) { | 584 | if (changed & BSS_CHANGED_ASSOC) { |
494 | if (bss_conf->assoc) { | 585 | if (bss_conf->assoc) { |
586 | /* we should reset all sec info & cam | ||
587 | * before set cam after linked, we should not | ||
588 | * reset in disassoc, that will cause tkip->wep | ||
589 | * fail because some flag will be wrong */ | ||
590 | /* reset sec info */ | ||
591 | rtl_cam_reset_sec_info(hw); | ||
592 | /* reset cam to fix wep fail issue | ||
593 | * when change from wpa to wep */ | ||
594 | rtl_cam_reset_all_entry(hw); | ||
595 | |||
495 | mac->link_state = MAC80211_LINKED; | 596 | mac->link_state = MAC80211_LINKED; |
496 | mac->cnt_after_linked = 0; | 597 | mac->cnt_after_linked = 0; |
497 | mac->assoc_id = bss_conf->aid; | 598 | mac->assoc_id = bss_conf->aid; |
498 | memcpy(mac->bssid, bss_conf->bssid, 6); | 599 | memcpy(mac->bssid, bss_conf->bssid, 6); |
499 | 600 | ||
601 | if (rtlpriv->cfg->ops->linked_set_reg) | ||
602 | rtlpriv->cfg->ops->linked_set_reg(hw); | ||
603 | if (mac->opmode == NL80211_IFTYPE_STATION && sta) | ||
604 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
500 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 605 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
501 | ("BSS_CHANGED_ASSOC\n")); | 606 | ("BSS_CHANGED_ASSOC\n")); |
502 | } else { | 607 | } else { |
@@ -505,9 +610,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
505 | 610 | ||
506 | mac->link_state = MAC80211_NOLINK; | 611 | mac->link_state = MAC80211_NOLINK; |
507 | memset(mac->bssid, 0, 6); | 612 | memset(mac->bssid, 0, 6); |
508 | 613 | mac->vendor = PEER_UNKNOWN; | |
509 | /* reset sec info */ | ||
510 | rtl_cam_reset_sec_info(hw); | ||
511 | 614 | ||
512 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 615 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
513 | ("BSS_CHANGED_UN_ASSOC\n")); | 616 | ("BSS_CHANGED_UN_ASSOC\n")); |
@@ -544,14 +647,10 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
544 | } | 647 | } |
545 | 648 | ||
546 | if (changed & BSS_CHANGED_HT) { | 649 | if (changed & BSS_CHANGED_HT) { |
547 | struct ieee80211_sta *sta = NULL; | ||
548 | |||
549 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 650 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
550 | ("BSS_CHANGED_HT\n")); | 651 | ("BSS_CHANGED_HT\n")); |
551 | |||
552 | rcu_read_lock(); | 652 | rcu_read_lock(); |
553 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 653 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); |
554 | |||
555 | if (sta) { | 654 | if (sta) { |
556 | if (sta->ht_cap.ampdu_density > | 655 | if (sta->ht_cap.ampdu_density > |
557 | mac->current_ampdu_density) | 656 | mac->current_ampdu_density) |
@@ -573,9 +672,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
573 | } | 672 | } |
574 | 673 | ||
575 | if (changed & BSS_CHANGED_BSSID) { | 674 | if (changed & BSS_CHANGED_BSSID) { |
576 | struct ieee80211_sta *sta = NULL; | ||
577 | u32 basic_rates; | 675 | u32 basic_rates; |
578 | u8 i; | ||
579 | 676 | ||
580 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, | 677 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, |
581 | (u8 *) bss_conf->bssid); | 678 | (u8 *) bss_conf->bssid); |
@@ -583,96 +680,65 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
583 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 680 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
584 | (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); | 681 | (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); |
585 | 682 | ||
683 | mac->vendor = PEER_UNKNOWN; | ||
586 | memcpy(mac->bssid, bss_conf->bssid, 6); | 684 | memcpy(mac->bssid, bss_conf->bssid, 6); |
587 | if (is_valid_ether_addr(bss_conf->bssid)) { | 685 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); |
588 | switch (vif->type) { | ||
589 | case NL80211_IFTYPE_UNSPECIFIED: | ||
590 | break; | ||
591 | case NL80211_IFTYPE_ADHOC: | ||
592 | break; | ||
593 | case NL80211_IFTYPE_STATION: | ||
594 | break; | ||
595 | case NL80211_IFTYPE_AP: | ||
596 | break; | ||
597 | default: | ||
598 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
599 | ("switch case not process\n")); | ||
600 | break; | ||
601 | } | ||
602 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); | ||
603 | } else | ||
604 | rtlpriv->cfg->ops->set_network_type(hw, | ||
605 | NL80211_IFTYPE_UNSPECIFIED); | ||
606 | |||
607 | memset(mac->mcs, 0, 16); | ||
608 | mac->ht_enable = false; | ||
609 | mac->sgi_40 = false; | ||
610 | mac->sgi_20 = false; | ||
611 | |||
612 | if (!bss_conf->use_short_slot) | ||
613 | mac->mode = WIRELESS_MODE_B; | ||
614 | else | ||
615 | mac->mode = WIRELESS_MODE_G; | ||
616 | 686 | ||
617 | rcu_read_lock(); | 687 | rcu_read_lock(); |
618 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 688 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); |
689 | if (!sta) { | ||
690 | rcu_read_unlock(); | ||
691 | goto out; | ||
692 | } | ||
619 | 693 | ||
620 | if (sta) { | 694 | if (rtlhal->current_bandtype == BAND_ON_5G) { |
621 | if (sta->ht_cap.ht_supported) { | 695 | mac->mode = WIRELESS_MODE_A; |
696 | } else { | ||
697 | if (sta->supp_rates[0] <= 0xf) | ||
698 | mac->mode = WIRELESS_MODE_B; | ||
699 | else | ||
700 | mac->mode = WIRELESS_MODE_G; | ||
701 | } | ||
702 | |||
703 | if (sta->ht_cap.ht_supported) { | ||
704 | if (rtlhal->current_bandtype == BAND_ON_2_4G) | ||
622 | mac->mode = WIRELESS_MODE_N_24G; | 705 | mac->mode = WIRELESS_MODE_N_24G; |
623 | mac->ht_enable = true; | 706 | else |
624 | } | 707 | mac->mode = WIRELESS_MODE_N_5G; |
708 | } | ||
625 | 709 | ||
626 | if (mac->ht_enable) { | 710 | /* just station need it, because ibss & ap mode will |
627 | u16 ht_cap = sta->ht_cap.cap; | 711 | * set in sta_add, and will be NULL here */ |
628 | memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16); | 712 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
629 | 713 | struct rtl_sta_info *sta_entry; | |
630 | for (i = 0; i < 16; i++) | 714 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
631 | RT_TRACE(rtlpriv, COMP_MAC80211, | 715 | sta_entry->wireless_mode = mac->mode; |
632 | DBG_LOUD, ("%x ", | 716 | } |
633 | mac->mcs[i])); | 717 | |
634 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 718 | if (sta->ht_cap.ht_supported) { |
635 | ("\n")); | 719 | mac->ht_enable = true; |
636 | 720 | ||
637 | if (ht_cap & IEEE80211_HT_CAP_SGI_40) | 721 | /* |
638 | mac->sgi_40 = true; | 722 | * for cisco 1252 bw20 it's wrong |
639 | 723 | * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | |
640 | if (ht_cap & IEEE80211_HT_CAP_SGI_20) | 724 | * mac->bw_40 = true; |
641 | mac->sgi_20 = true; | 725 | * } |
642 | 726 | * */ | |
643 | /* | ||
644 | * for cisco 1252 bw20 it's wrong | ||
645 | * if (ht_cap & | ||
646 | * IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | ||
647 | * mac->bw_40 = true; | ||
648 | * } | ||
649 | */ | ||
650 | } | ||
651 | } | 727 | } |
652 | rcu_read_unlock(); | ||
653 | 728 | ||
654 | /*mac80211 just give us CCK rates any time | ||
655 | *So we add G rate in basic rates when | ||
656 | not in B mode*/ | ||
657 | if (changed & BSS_CHANGED_BASIC_RATES) { | 729 | if (changed & BSS_CHANGED_BASIC_RATES) { |
658 | if (mac->mode == WIRELESS_MODE_B) | 730 | /* for 5G must << RATE_6M_INDEX=4, |
659 | basic_rates = bss_conf->basic_rates | 0x00f; | 731 | * because 5G have no cck rate*/ |
732 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
733 | basic_rates = sta->supp_rates[1] << 4; | ||
660 | else | 734 | else |
661 | basic_rates = bss_conf->basic_rates | 0xff0; | 735 | basic_rates = sta->supp_rates[0]; |
662 | |||
663 | if (!vif) | ||
664 | goto out; | ||
665 | 736 | ||
666 | mac->basic_rates = basic_rates; | 737 | mac->basic_rates = basic_rates; |
667 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | 738 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, |
668 | (u8 *) (&basic_rates)); | 739 | (u8 *) (&basic_rates)); |
669 | |||
670 | if (rtlpriv->dm.useramask) | ||
671 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | ||
672 | else | ||
673 | rtlpriv->cfg->ops->update_rate_table(hw); | ||
674 | |||
675 | } | 740 | } |
741 | rcu_read_unlock(); | ||
676 | } | 742 | } |
677 | 743 | ||
678 | /* | 744 | /* |
@@ -758,16 +824,17 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, | |||
758 | case IEEE80211_AMPDU_TX_START: | 824 | case IEEE80211_AMPDU_TX_START: |
759 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 825 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
760 | ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); | 826 | ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); |
761 | return rtl_tx_agg_start(hw, sta->addr, tid, ssn); | 827 | return rtl_tx_agg_start(hw, sta, tid, ssn); |
762 | break; | 828 | break; |
763 | case IEEE80211_AMPDU_TX_STOP: | 829 | case IEEE80211_AMPDU_TX_STOP: |
764 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 830 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
765 | ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); | 831 | ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); |
766 | return rtl_tx_agg_stop(hw, sta->addr, tid); | 832 | return rtl_tx_agg_stop(hw, sta, tid); |
767 | break; | 833 | break; |
768 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 834 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
769 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 835 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
770 | ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); | 836 | ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); |
837 | rtl_tx_agg_oper(hw, sta, tid); | ||
771 | break; | 838 | break; |
772 | case IEEE80211_AMPDU_RX_START: | 839 | case IEEE80211_AMPDU_RX_START: |
773 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 840 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
@@ -797,8 +864,12 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) | |||
797 | if (mac->link_state == MAC80211_LINKED) { | 864 | if (mac->link_state == MAC80211_LINKED) { |
798 | rtl_lps_leave(hw); | 865 | rtl_lps_leave(hw); |
799 | mac->link_state = MAC80211_LINKED_SCANNING; | 866 | mac->link_state = MAC80211_LINKED_SCANNING; |
800 | } else | 867 | } else { |
801 | rtl_ips_nic_on(hw); | 868 | rtl_ips_nic_on(hw); |
869 | } | ||
870 | |||
871 | /* Dual mac */ | ||
872 | rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; | ||
802 | 873 | ||
803 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); | 874 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); |
804 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); | 875 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); |
@@ -810,22 +881,19 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) | |||
810 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 881 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
811 | 882 | ||
812 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); | 883 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); |
813 | |||
814 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); | ||
815 | mac->act_scanning = false; | 884 | mac->act_scanning = false; |
885 | /* Dual mac */ | ||
886 | rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; | ||
887 | |||
816 | if (mac->link_state == MAC80211_LINKED_SCANNING) { | 888 | if (mac->link_state == MAC80211_LINKED_SCANNING) { |
817 | mac->link_state = MAC80211_LINKED; | 889 | mac->link_state = MAC80211_LINKED; |
818 | 890 | if (mac->opmode == NL80211_IFTYPE_STATION) { | |
819 | /* fix fwlps issue */ | 891 | /* fix fwlps issue */ |
820 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); | 892 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); |
821 | 893 | } | |
822 | if (rtlpriv->dm.useramask) | ||
823 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | ||
824 | else | ||
825 | rtlpriv->cfg->ops->update_rate_table(hw); | ||
826 | |||
827 | } | 894 | } |
828 | 895 | ||
896 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); | ||
829 | } | 897 | } |
830 | 898 | ||
831 | static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 899 | static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -856,49 +924,73 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
856 | rtl_ips_nic_on(hw); | 924 | rtl_ips_nic_on(hw); |
857 | mutex_lock(&rtlpriv->locks.conf_mutex); | 925 | mutex_lock(&rtlpriv->locks.conf_mutex); |
858 | /* <1> get encryption alg */ | 926 | /* <1> get encryption alg */ |
927 | |||
859 | switch (key->cipher) { | 928 | switch (key->cipher) { |
860 | case WLAN_CIPHER_SUITE_WEP40: | 929 | case WLAN_CIPHER_SUITE_WEP40: |
861 | key_type = WEP40_ENCRYPTION; | 930 | key_type = WEP40_ENCRYPTION; |
862 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); | 931 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); |
863 | rtlpriv->sec.use_defaultkey = true; | ||
864 | break; | 932 | break; |
865 | case WLAN_CIPHER_SUITE_WEP104: | 933 | case WLAN_CIPHER_SUITE_WEP104: |
866 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 934 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
867 | ("alg:WEP104\n")); | 935 | ("alg:WEP104\n")); |
868 | key_type = WEP104_ENCRYPTION; | 936 | key_type = WEP104_ENCRYPTION; |
869 | rtlpriv->sec.use_defaultkey = true; | ||
870 | break; | 937 | break; |
871 | case WLAN_CIPHER_SUITE_TKIP: | 938 | case WLAN_CIPHER_SUITE_TKIP: |
872 | key_type = TKIP_ENCRYPTION; | 939 | key_type = TKIP_ENCRYPTION; |
873 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); | 940 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); |
874 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
875 | rtlpriv->sec.use_defaultkey = true; | ||
876 | break; | 941 | break; |
877 | case WLAN_CIPHER_SUITE_CCMP: | 942 | case WLAN_CIPHER_SUITE_CCMP: |
878 | key_type = AESCCMP_ENCRYPTION; | 943 | key_type = AESCCMP_ENCRYPTION; |
879 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); | 944 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); |
880 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
881 | rtlpriv->sec.use_defaultkey = true; | ||
882 | break; | 945 | break; |
883 | default: | 946 | default: |
884 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 947 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
885 | ("alg_err:%x!!!!:\n", key->cipher)); | 948 | ("alg_err:%x!!!!:\n", key->cipher)); |
886 | goto out_unlock; | 949 | goto out_unlock; |
887 | } | 950 | } |
951 | if (key_type == WEP40_ENCRYPTION || | ||
952 | key_type == WEP104_ENCRYPTION || | ||
953 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
954 | rtlpriv->sec.use_defaultkey = true; | ||
955 | |||
888 | /* <2> get key_idx */ | 956 | /* <2> get key_idx */ |
889 | key_idx = (u8) (key->keyidx); | 957 | key_idx = (u8) (key->keyidx); |
890 | if (key_idx > 3) | 958 | if (key_idx > 3) |
891 | goto out_unlock; | 959 | goto out_unlock; |
892 | /* <3> if pairwise key enable_hw_sec */ | 960 | /* <3> if pairwise key enable_hw_sec */ |
893 | group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); | 961 | group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); |
894 | if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || | 962 | |
895 | rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { | 963 | /* wep always be group key, but there are two conditions: |
896 | if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION && | 964 | * 1) wep only: is just for wep enc, in this condition |
897 | (key_type == WEP40_ENCRYPTION || | 965 | * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION |
898 | key_type == WEP104_ENCRYPTION)) | 966 | * will be true & enable_hw_sec will be set when wep |
899 | wep_only = true; | 967 | * ke setting. |
900 | rtlpriv->sec.pairwise_enc_algorithm = key_type; | 968 | * 2) wep(group) + AES(pairwise): some AP like cisco |
901 | rtlpriv->cfg->ops->enable_hw_sec(hw); | 969 | * may use it, in this condition enable_hw_sec will not |
970 | * be set when wep key setting */ | ||
971 | /* we must reset sec_info after lingked before set key, | ||
972 | * or some flag will be wrong*/ | ||
973 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
974 | if (!group_key || key_type == WEP40_ENCRYPTION || | ||
975 | key_type == WEP104_ENCRYPTION) { | ||
976 | if (group_key) | ||
977 | wep_only = true; | ||
978 | rtlpriv->cfg->ops->enable_hw_sec(hw); | ||
979 | } | ||
980 | } else { | ||
981 | if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || | ||
982 | rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { | ||
983 | if (rtlpriv->sec.pairwise_enc_algorithm == | ||
984 | NO_ENCRYPTION && | ||
985 | (key_type == WEP40_ENCRYPTION || | ||
986 | key_type == WEP104_ENCRYPTION)) | ||
987 | wep_only = true; | ||
988 | rtlpriv->sec.pairwise_enc_algorithm = key_type; | ||
989 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
990 | ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" | ||
991 | " TKIP:2 AES:4 WEP104:5)\n", key_type)); | ||
992 | rtlpriv->cfg->ops->enable_hw_sec(hw); | ||
993 | } | ||
902 | } | 994 | } |
903 | /* <4> set key based on cmd */ | 995 | /* <4> set key based on cmd */ |
904 | switch (cmd) { | 996 | switch (cmd) { |
@@ -930,6 +1022,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
930 | if (!sta) { | 1022 | if (!sta) { |
931 | RT_ASSERT(false, ("pairwise key withnot" | 1023 | RT_ASSERT(false, ("pairwise key withnot" |
932 | "mac_addr\n")); | 1024 | "mac_addr\n")); |
1025 | |||
933 | err = -EOPNOTSUPP; | 1026 | err = -EOPNOTSUPP; |
934 | goto out_unlock; | 1027 | goto out_unlock; |
935 | } | 1028 | } |
@@ -957,6 +1050,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
957 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 1050 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
958 | ("disable key delete one entry\n")); | 1051 | ("disable key delete one entry\n")); |
959 | /*set local buf about wep key. */ | 1052 | /*set local buf about wep key. */ |
1053 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
1054 | if (sta) | ||
1055 | rtl_cam_del_entry(hw, sta->addr); | ||
1056 | } | ||
960 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); | 1057 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); |
961 | rtlpriv->sec.key_len[key_idx] = 0; | 1058 | rtlpriv->sec.key_len[key_idx] = 0; |
962 | memcpy(mac_addr, zero_addr, ETH_ALEN); | 1059 | memcpy(mac_addr, zero_addr, ETH_ALEN); |
@@ -1009,6 +1106,18 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) | |||
1009 | mutex_unlock(&rtlpriv->locks.conf_mutex); | 1106 | mutex_unlock(&rtlpriv->locks.conf_mutex); |
1010 | } | 1107 | } |
1011 | 1108 | ||
1109 | /* this function is called by mac80211 to flush tx buffer | ||
1110 | * before switch channle or power save, or tx buffer packet | ||
1111 | * maybe send after offchannel or rf sleep, this may cause | ||
1112 | * dis-association by AP */ | ||
1113 | static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) | ||
1114 | { | ||
1115 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1116 | |||
1117 | if (rtlpriv->intf_ops->flush) | ||
1118 | rtlpriv->intf_ops->flush(hw, drop); | ||
1119 | } | ||
1120 | |||
1012 | const struct ieee80211_ops rtl_ops = { | 1121 | const struct ieee80211_ops rtl_ops = { |
1013 | .start = rtl_op_start, | 1122 | .start = rtl_op_start, |
1014 | .stop = rtl_op_stop, | 1123 | .stop = rtl_op_stop, |
@@ -1017,6 +1126,8 @@ const struct ieee80211_ops rtl_ops = { | |||
1017 | .remove_interface = rtl_op_remove_interface, | 1126 | .remove_interface = rtl_op_remove_interface, |
1018 | .config = rtl_op_config, | 1127 | .config = rtl_op_config, |
1019 | .configure_filter = rtl_op_configure_filter, | 1128 | .configure_filter = rtl_op_configure_filter, |
1129 | .sta_add = rtl_op_sta_add, | ||
1130 | .sta_remove = rtl_op_sta_remove, | ||
1020 | .set_key = rtl_op_set_key, | 1131 | .set_key = rtl_op_set_key, |
1021 | .conf_tx = rtl_op_conf_tx, | 1132 | .conf_tx = rtl_op_conf_tx, |
1022 | .bss_info_changed = rtl_op_bss_info_changed, | 1133 | .bss_info_changed = rtl_op_bss_info_changed, |
@@ -1028,4 +1139,5 @@ const struct ieee80211_ops rtl_ops = { | |||
1028 | .sw_scan_start = rtl_op_sw_scan_start, | 1139 | .sw_scan_start = rtl_op_sw_scan_start, |
1029 | .sw_scan_complete = rtl_op_sw_scan_complete, | 1140 | .sw_scan_complete = rtl_op_sw_scan_complete, |
1030 | .rfkill_poll = rtl_op_rfkill_poll, | 1141 | .rfkill_poll = rtl_op_rfkill_poll, |
1142 | .flush = rtl_op_flush, | ||
1031 | }; | 1143 | }; |
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 0ef31c3c6196..4b247db2861d 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h | |||
@@ -24,6 +24,7 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #ifndef __RTL_CORE_H__ | 30 | #ifndef __RTL_CORE_H__ |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index bdb3c5f5c4b0..861849013c54 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -424,6 +424,10 @@ void rtl_swlps_wq_callback(void *data) | |||
424 | { | 424 | { |
425 | } | 425 | } |
426 | 426 | ||
427 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | ||
428 | { | ||
429 | } | ||
430 | |||
427 | /*Enter the leisure power save mode.*/ | 431 | /*Enter the leisure power save mode.*/ |
428 | void rtl_lps_enter(struct ieee80211_hw *hw) | 432 | void rtl_lps_enter(struct ieee80211_hw *hw) |
429 | { | 433 | { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 0df2fec27a08..cc5de0726938 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -504,7 +504,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
504 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 504 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
505 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 505 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
506 | bool defaultadapter = true; | 506 | bool defaultadapter = true; |
507 | struct ieee80211_sta *sta; | 507 | struct ieee80211_sta *sta = info->control.sta; |
508 | struct rtl_tcb_desc tcb_desc; | 508 | struct rtl_tcb_desc tcb_desc; |
509 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 509 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
510 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 510 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f4ab1b7732c3..14539eb9589e 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -885,7 +885,8 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
885 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); | 885 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); |
886 | } | 886 | } |
887 | 887 | ||
888 | static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 888 | static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb, |
889 | struct rtl_tcb_desc *dummy) | ||
889 | { | 890 | { |
890 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | 891 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); |
891 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 892 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 7c52435a1180..4776cd1ee4f8 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -1445,12 +1445,8 @@ struct rtl_intf_ops { | |||
1445 | int (*adapter_start) (struct ieee80211_hw *hw); | 1445 | int (*adapter_start) (struct ieee80211_hw *hw); |
1446 | void (*adapter_stop) (struct ieee80211_hw *hw); | 1446 | void (*adapter_stop) (struct ieee80211_hw *hw); |
1447 | 1447 | ||
1448 | #if 0 /* temporary */ | ||
1449 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb, | 1448 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb, |
1450 | struct rtl_tcb_desc *ptcb_desc); | 1449 | struct rtl_tcb_desc *ptcb_desc); |
1451 | #else | ||
1452 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); | ||
1453 | #endif | ||
1454 | void (*flush)(struct ieee80211_hw *hw, bool drop); | 1450 | void (*flush)(struct ieee80211_hw *hw, bool drop); |
1455 | int (*reset_trx_ring) (struct ieee80211_hw *hw); | 1451 | int (*reset_trx_ring) (struct ieee80211_hw *hw); |
1456 | bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); | 1452 | bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); |