1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
36 #include "btcoexist/rtl_btc.h"
38 /*mutex for start & stop is must here. */
39 static int rtl_op_start(struct ieee80211_hw *hw)
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
45 if (!is_hal_stop(rtlhal))
47 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
49 mutex_lock(&rtlpriv->locks.conf_mutex);
50 err = rtlpriv->intf_ops->adapter_start(hw);
53 rtl_watch_dog_timer_callback((unsigned long)hw);
56 mutex_unlock(&rtlpriv->locks.conf_mutex);
60 static void rtl_op_stop(struct ieee80211_hw *hw)
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
64 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
65 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
67 if (is_hal_stop(rtlhal))
70 /* here is must, because adhoc do stop and start,
71 * but stop with RFOFF may cause something wrong,
73 if (unlikely(ppsc->rfpwr_state == ERFOFF))
76 mutex_lock(&rtlpriv->locks.conf_mutex);
78 mac->link_state = MAC80211_NOLINK;
79 memset(mac->bssid, 0, 6);
80 mac->vendor = PEER_UNKNOWN;
83 rtl_cam_reset_sec_info(hw);
85 rtl_deinit_deferred_work(hw);
86 rtlpriv->intf_ops->adapter_stop(hw);
88 mutex_unlock(&rtlpriv->locks.conf_mutex);
91 /*<delete in kernel start>*/
92 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
93 static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
95 struct rtl_priv *rtlpriv = rtl_priv(hw);
96 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
97 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
98 struct rtl_tcb_desc tcb_desc;
99 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
101 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
104 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
107 if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
108 rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
113 dev_kfree_skb_any(skb);
117 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
118 static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
120 /*<delete in kernel end>*/
121 static void rtl_op_tx(struct ieee80211_hw *hw,
122 struct ieee80211_tx_control *control,
124 /*<delete in kernel start>*/
126 /*<delete in kernel end>*/
128 struct rtl_priv *rtlpriv = rtl_priv(hw);
129 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
130 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
131 struct rtl_tcb_desc tcb_desc;
132 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
134 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
137 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
140 /*<delete in kernel start>*/
141 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
142 if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
143 rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
145 /*<delete in kernel end>*/
146 if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb))
147 rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc);
148 /*<delete in kernel start>*/
150 /*<delete in kernel end>*/
154 dev_kfree_skb_any(skb);
157 /*<delete in kernel start>*/
159 /*<delete in kernel end>*/
161 static int rtl_op_add_interface(struct ieee80211_hw *hw,
162 struct ieee80211_vif *vif)
164 struct rtl_priv *rtlpriv = rtl_priv(hw);
165 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
169 RT_TRACE(COMP_ERR, DBG_WARNING,
170 ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
174 /*This flag is not defined before kernel 3.4*/
175 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
176 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
181 mutex_lock(&rtlpriv->locks.conf_mutex);
182 /*<delete in kernel start>*/
183 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
184 switch (ieee80211_vif_type_p2p(vif)) {
185 case NL80211_IFTYPE_P2P_CLIENT:
186 mac->p2p = P2P_ROLE_CLIENT;
189 /*<delete in kernel end>*/
191 /*<delete in kernel start>*/
193 /*<delete in kernel end>*/
194 case NL80211_IFTYPE_STATION:
195 if (mac->beacon_enabled == 1) {
196 RT_TRACE(COMP_MAC80211, DBG_LOUD,
197 ("NL80211_IFTYPE_STATION \n"));
198 mac->beacon_enabled = 0;
199 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
200 rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
203 case NL80211_IFTYPE_ADHOC:
204 RT_TRACE(COMP_MAC80211, DBG_LOUD,
205 ("NL80211_IFTYPE_ADHOC \n"));
207 mac->link_state = MAC80211_LINKED;
208 rtlpriv->cfg->ops->set_bcn_reg(hw);
209 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
210 mac->basic_rates = 0xfff;
212 mac->basic_rates = 0xff0;
213 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
214 (u8 *) (&mac->basic_rates));
217 /*<delete in kernel start>*/
218 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
219 case NL80211_IFTYPE_P2P_GO:
220 mac->p2p = P2P_ROLE_GO;
223 /*<delete in kernel end>*/
224 case NL80211_IFTYPE_AP:
225 RT_TRACE(COMP_MAC80211, DBG_LOUD,
226 ("NL80211_IFTYPE_AP \n"));
228 mac->link_state = MAC80211_LINKED;
229 rtlpriv->cfg->ops->set_bcn_reg(hw);
230 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
231 mac->basic_rates = 0xfff;
233 mac->basic_rates = 0xff0;
234 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
235 (u8 *) (&mac->basic_rates));
237 case NL80211_IFTYPE_MESH_POINT:
238 RT_TRACE(COMP_MAC80211, DBG_LOUD,
239 ("NL80211_IFTYPE_MESH_POINT \n"));
241 mac->link_state = MAC80211_LINKED;
242 rtlpriv->cfg->ops->set_bcn_reg(hw);
243 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
244 mac->basic_rates = 0xfff;
246 mac->basic_rates = 0xff0;
247 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
248 (u8 *) (&mac->basic_rates));
251 RT_TRACE(COMP_ERR, DBG_EMERG,
252 ("operation mode %d is not support!\n", vif->type));
258 if (!rtl_set_vif_info(hw, vif))
263 RT_TRACE(COMP_MAC80211, DBG_LOUD,
264 ("p2p role %x \n",vif->type));
265 mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
266 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
267 (u8 *) (&mac->basic_rates));
270 mac->opmode = vif->type;
271 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
272 memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
273 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
276 mutex_unlock(&rtlpriv->locks.conf_mutex);
280 static void rtl_op_remove_interface(struct ieee80211_hw *hw,
281 struct ieee80211_vif *vif)
283 struct rtl_priv *rtlpriv = rtl_priv(hw);
284 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
286 mutex_lock(&rtlpriv->locks.conf_mutex);
288 /* Free beacon resources */
289 if ((vif->type == NL80211_IFTYPE_AP) ||
290 (vif->type == NL80211_IFTYPE_ADHOC) ||
291 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
292 if (mac->beacon_enabled == 1) {
293 mac->beacon_enabled = 0;
294 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
295 rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
300 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
301 *NO LINK for our hardware.
305 mac->link_state = MAC80211_NOLINK;
306 memset(mac->bssid, 0, 6);
307 mac->vendor = PEER_UNKNOWN;
308 mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
309 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
311 mutex_unlock(&rtlpriv->locks.conf_mutex);
313 /*<delete in kernel start>*/
314 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
315 /*<delete in kernel end>*/
316 static int rtl_op_change_interface(struct ieee80211_hw *hw,
317 struct ieee80211_vif *vif,
318 enum nl80211_iftype new_type, bool p2p)
320 struct rtl_priv *rtlpriv = rtl_priv(hw);
322 rtl_op_remove_interface(hw, vif);
324 vif->type = new_type;
326 ret = rtl_op_add_interface(hw, vif);
327 RT_TRACE(COMP_MAC80211, DBG_LOUD,
331 /*<delete in kernel start>*/
333 /*<delete in kernel end>*/
334 static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
336 struct rtl_priv *rtlpriv = rtl_priv(hw);
337 struct rtl_phy *rtlphy = &(rtlpriv->phy);
338 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
339 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
340 struct ieee80211_conf *conf = &hw->conf;
346 mutex_lock(&rtlpriv->locks.conf_mutex);
347 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2) */
348 RT_TRACE(COMP_MAC80211, DBG_LOUD,
349 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
353 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
354 if (hw->conf.flags & IEEE80211_CONF_IDLE)
360 *although rfoff may not cause by ips, but we will
361 *check the reason in set_rf_power_state function
363 if (unlikely(ppsc->rfpwr_state == ERFOFF))
368 if (changed & IEEE80211_CONF_CHANGE_PS) {
369 cancel_delayed_work(&rtlpriv->works.ps_work);
370 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
371 if (conf->flags & IEEE80211_CONF_PS) {
372 rtlpriv->psc.sw_ps_enabled = true;
373 /* sleep here is must, or we may recv the beacon and
374 * cause mac80211 into wrong ps state, this will cause
375 * power save nullfunc send fail, and further cause
376 * pkt loss, So sleep must quickly but not immediatly
377 * because that will cause nullfunc send by mac80211
378 * fail, and cause pkt loss, we have tested that 5mA
379 * is worked very well */
380 if (!rtlpriv->psc.multi_buffered)
381 queue_delayed_work(rtlpriv->works.rtl_wq,
382 &rtlpriv->works.ps_work,
385 rtl_swlps_rf_awake(hw);
386 rtlpriv->psc.sw_ps_enabled = false;
390 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
391 RT_TRACE(COMP_MAC80211, DBG_LOUD,
392 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
393 hw->conf.long_frame_max_tx_count));
394 mac->retry_long = hw->conf.long_frame_max_tx_count;
395 mac->retry_short = hw->conf.long_frame_max_tx_count;
396 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
397 (u8 *) (&hw->conf.long_frame_max_tx_count));
400 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
401 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
402 struct ieee80211_channel *channel = hw->conf.chandef.chan;
403 enum nl80211_channel_type channel_type =
404 cfg80211_get_chandef_type(&(hw->conf.chandef));
406 struct ieee80211_channel *channel = hw->conf.channel;
407 enum nl80211_channel_type channel_type = hw->conf.channel_type;
409 u8 wide_chan = (u8) channel->hw_value;
411 if (mac->act_scanning)
414 if (rtlpriv->dm.supp_phymode_switch &&
415 mac->link_state < MAC80211_LINKED &&
416 !mac->act_scanning) {
417 if (rtlpriv->cfg->ops->check_switch_to_dmdp)
418 rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
422 *because we should back channel to
423 *current_network.chan in in scanning,
424 *So if set_chan == current_network.chan
426 *because mac80211 tell us wrong bw40
427 *info for cisco1253 bw20, so we modify
428 *it here based on UPPER & LOWER
430 switch (channel_type) {
431 case NL80211_CHAN_HT20:
432 case NL80211_CHAN_NO_HT:
434 mac->cur_40_prime_sc =
435 PRIME_CHNL_OFFSET_DONT_CARE;
436 rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
439 case NL80211_CHAN_HT40MINUS:
441 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
442 rtlphy->current_chan_bw =
443 HT_CHANNEL_WIDTH_20_40;
450 case NL80211_CHAN_HT40PLUS:
452 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
453 rtlphy->current_chan_bw =
454 HT_CHANNEL_WIDTH_20_40;
463 RT_TRACE(COMP_ERR, DBG_EMERG,
464 ("switch case not processed \n"));
471 /* in scanning, when before we offchannel we may send a ps=1
472 * null to AP, and then we may send a ps = 0 null to AP quickly,
473 * but first null have cause AP's put lots of packet to hw tx
474 * buffer, these packet must be tx before off channel so we must
475 * delay more time to let AP flush these packets before
476 * offchannel, or dis-association or delete BA will happen by AP
478 if (rtlpriv->mac80211.offchan_deley) {
479 rtlpriv->mac80211.offchan_deley = false;
483 rtlphy->current_channel = wide_chan;
485 rtlpriv->cfg->ops->switch_channel(hw);
486 rtlpriv->cfg->ops->set_channel_access(hw);
487 rtlpriv->cfg->ops->set_bw_mode(hw,
491 mutex_unlock(&rtlpriv->locks.conf_mutex);
496 static void rtl_op_configure_filter(struct ieee80211_hw *hw,
497 unsigned int changed_flags,
498 unsigned int *new_flags, u64 multicast)
500 struct rtl_priv *rtlpriv = rtl_priv(hw);
501 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
503 *new_flags &= RTL_SUPPORTED_FILTERS;
504 if (0 == changed_flags)
507 /*TODO: we disable broadcase now, so enable here */
508 if (changed_flags & FIF_ALLMULTI) {
509 if (*new_flags & FIF_ALLMULTI) {
510 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
511 rtlpriv->cfg->maps[MAC_RCR_AB];
512 RT_TRACE(COMP_MAC80211, DBG_LOUD,
513 ("Enable receive multicast frame.\n"));
515 mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
516 rtlpriv->cfg->maps[MAC_RCR_AB]);
517 RT_TRACE(COMP_MAC80211, DBG_LOUD,
518 ("Disable receive multicast frame.\n"));
522 if (changed_flags & FIF_FCSFAIL) {
523 if (*new_flags & FIF_FCSFAIL) {
524 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
525 RT_TRACE(COMP_MAC80211, DBG_LOUD,
526 ("Enable receive FCS error frame.\n"));
528 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
529 RT_TRACE(COMP_MAC80211, DBG_LOUD,
530 ("Disable receive FCS error frame.\n"));
534 /* if ssid not set to hw don't check bssid
535 * here just used for linked scanning, & linked
536 * and nolink check bssid is set in set network_type */
537 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
538 (mac->link_state >= MAC80211_LINKED)) {
539 if (mac->opmode != NL80211_IFTYPE_AP &&
540 mac->opmode != NL80211_IFTYPE_MESH_POINT) {
541 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
542 rtlpriv->cfg->ops->set_chk_bssid(hw, false);
544 rtlpriv->cfg->ops->set_chk_bssid(hw, true);
549 if (changed_flags & FIF_CONTROL) {
550 if (*new_flags & FIF_CONTROL) {
551 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
553 RT_TRACE(COMP_MAC80211, DBG_LOUD,
554 ("Enable receive control frame.\n"));
556 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
557 RT_TRACE(COMP_MAC80211, DBG_LOUD,
558 ("Disable receive control frame.\n"));
562 if (changed_flags & FIF_OTHER_BSS) {
563 if (*new_flags & FIF_OTHER_BSS) {
564 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
565 RT_TRACE(COMP_MAC80211, DBG_LOUD,
566 ("Enable receive other BSS's frame.\n"));
568 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
569 RT_TRACE(COMP_MAC80211, DBG_LOUD,
570 ("Disable receive other BSS's frame.\n"));
574 static int rtl_op_sta_add(struct ieee80211_hw *hw,
575 struct ieee80211_vif *vif,
576 struct ieee80211_sta *sta)
578 struct rtl_priv *rtlpriv = rtl_priv(hw);
579 struct rtl_hal *rtlhal= rtl_hal(rtl_priv(hw));
580 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
581 struct rtl_sta_info *sta_entry;
584 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
585 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
586 list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
587 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
588 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
589 sta_entry->wireless_mode = WIRELESS_MODE_G;
590 if (sta->supp_rates[0] <= 0xf)
591 sta_entry->wireless_mode = WIRELESS_MODE_B;
592 if (sta->ht_cap.ht_supported == true)
593 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
595 if (vif->type == NL80211_IFTYPE_ADHOC)
596 sta_entry->wireless_mode = WIRELESS_MODE_G;
597 } else if (rtlhal->current_bandtype == BAND_ON_5G) {
598 sta_entry->wireless_mode = WIRELESS_MODE_A;
599 if (sta->ht_cap.ht_supported == true)
600 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
602 if (vif->type == NL80211_IFTYPE_ADHOC)
603 sta_entry->wireless_mode = WIRELESS_MODE_A;
605 /*disable cck rate for p2p*/
607 sta->supp_rates[0] &= 0xfffffff0;
609 memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
610 RT_TRACE(COMP_MAC80211, DBG_DMESG,
611 ("Add sta addr is %pM\n",sta->addr));
612 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
618 static int rtl_op_sta_remove(struct ieee80211_hw *hw,
619 struct ieee80211_vif *vif,
620 struct ieee80211_sta *sta)
622 struct rtl_priv *rtlpriv = rtl_priv(hw);
623 struct rtl_sta_info *sta_entry;
625 RT_TRACE(COMP_MAC80211, DBG_DMESG,
626 ("Remove sta addr is %pM\n",sta->addr));
627 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
628 sta_entry->wireless_mode = 0;
629 sta_entry->ratr_index = 0;
630 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
631 list_del(&sta_entry->list);
632 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
636 static int _rtl_get_hal_qnum(u16 queue)
661 *for mac80211 VO=0, VI=1, BE=2, BK=3
662 *for rtl819x BE=0, BK=1, VI=2, VO=3
664 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
665 static int rtl_op_conf_tx(struct ieee80211_hw *hw,
666 struct ieee80211_vif *vif, u16 queue,
667 const struct ieee80211_tx_queue_params *param)
669 static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
670 const struct ieee80211_tx_queue_params *param)
673 struct rtl_priv *rtlpriv = rtl_priv(hw);
674 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
677 if (queue >= AC_MAX) {
678 RT_TRACE(COMP_ERR, DBG_WARNING,
679 ("queue number %d is incorrect!\n", queue));
683 aci = _rtl_get_hal_qnum(queue);
684 mac->ac[aci].aifs = param->aifs;
685 mac->ac[aci].cw_min = param->cw_min;
686 mac->ac[aci].cw_max = param->cw_max;
687 mac->ac[aci].tx_op = param->txop;
688 memcpy(&mac->edca_param[aci], param, sizeof(*param));
689 rtlpriv->cfg->ops->set_qos(hw, aci);
693 static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
694 struct ieee80211_vif *vif,
695 struct ieee80211_bss_conf *bss_conf,
698 struct rtl_priv *rtlpriv = rtl_priv(hw);
699 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
700 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
701 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
703 mutex_lock(&rtlpriv->locks.conf_mutex);
704 if ((vif->type == NL80211_IFTYPE_ADHOC) ||
705 (vif->type == NL80211_IFTYPE_AP) ||
706 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
707 if ((changed & BSS_CHANGED_BEACON) ||
708 (changed & BSS_CHANGED_BEACON_ENABLED &&
709 bss_conf->enable_beacon)) {
710 if (mac->beacon_enabled == 0) {
711 RT_TRACE(COMP_MAC80211, DBG_DMESG,
712 ("BSS_CHANGED_BEACON_ENABLED \n"));
714 /*start hw beacon interrupt. */
715 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
716 mac->beacon_enabled = 1;
717 rtlpriv->cfg->ops->update_interrupt_mask(hw,
719 [RTL_IBSS_INT_MASKS], 0);
721 if (rtlpriv->cfg->ops->linked_set_reg)
722 rtlpriv->cfg->ops->linked_set_reg(hw);
725 if ((changed & BSS_CHANGED_BEACON_ENABLED &&
726 !bss_conf->enable_beacon)){
727 if (mac->beacon_enabled == 1) {
728 RT_TRACE(COMP_MAC80211, DBG_DMESG,
729 ("ADHOC DISABLE BEACON\n"));
731 mac->beacon_enabled = 0;
732 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
734 [RTL_IBSS_INT_MASKS]);
737 if (changed & BSS_CHANGED_BEACON_INT) {
738 RT_TRACE(COMP_BEACON, DBG_TRACE,
739 ("BSS_CHANGED_BEACON_INT\n"));
740 mac->beacon_interval = bss_conf->beacon_int;
741 rtlpriv->cfg->ops->set_bcn_intv(hw);
745 /*TODO: reference to enum ieee80211_bss_change */
746 if (changed & BSS_CHANGED_ASSOC) {
747 if (bss_conf->assoc) {
748 struct ieee80211_sta *sta = NULL;
749 /* we should reset all sec info & cam
750 * before set cam after linked, we should not
751 * reset in disassoc, that will cause tkip->wep
752 * fail because some flag will be wrong */
754 rtl_cam_reset_sec_info(hw);
755 /* reset cam to fix wep fail issue
756 * when change from wpa to wep */
757 rtl_cam_reset_all_entry(hw);
759 mac->link_state = MAC80211_LINKED;
760 mac->cnt_after_linked = 0;
761 mac->assoc_id = bss_conf->aid;
762 memcpy(mac->bssid, bss_conf->bssid, 6);
764 if (rtlpriv->cfg->ops->linked_set_reg)
765 rtlpriv->cfg->ops->linked_set_reg(hw);
768 sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
770 if (vif->type == NL80211_IFTYPE_STATION && sta)
771 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
772 RT_TRACE(COMP_EASY_CONCURRENT, DBG_LOUD,
773 ("send PS STATIC frame \n"));
774 if (rtlpriv->dm.supp_phymode_switch) {
775 if (sta->ht_cap.ht_supported)
776 rtl_send_smps_action(hw, sta,
777 IEEE80211_SMPS_STATIC);
781 RT_TRACE(COMP_MAC80211, DBG_DMESG,
782 ("BSS_CHANGED_ASSOC\n"));
784 if (mac->link_state == MAC80211_LINKED)
786 if (ppsc->p2p_ps_info.p2p_ps_mode> P2P_PS_NONE)
787 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
788 mac->link_state = MAC80211_NOLINK;
789 memset(mac->bssid, 0, 6);
790 mac->vendor = PEER_UNKNOWN;
792 if (rtlpriv->dm.supp_phymode_switch) {
793 if (rtlpriv->cfg->ops->check_switch_to_dmdp)
794 rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
796 RT_TRACE(COMP_MAC80211, DBG_DMESG,
797 ("BSS_CHANGED_UN_ASSOC\n"));
801 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
802 RT_TRACE(COMP_MAC80211, DBG_TRACE,
803 ("BSS_CHANGED_ERP_CTS_PROT\n"));
804 mac->use_cts_protect = bss_conf->use_cts_prot;
807 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
808 RT_TRACE(COMP_MAC80211, DBG_LOUD,
809 ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x \n",
810 bss_conf->use_short_preamble));
812 mac->short_preamble = bss_conf->use_short_preamble;
813 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
814 (u8 *) (&mac->short_preamble));
817 if (changed & BSS_CHANGED_ERP_SLOT) {
818 RT_TRACE(COMP_MAC80211, DBG_TRACE,
819 ("BSS_CHANGED_ERP_SLOT\n"));
821 if (bss_conf->use_short_slot)
822 mac->slot_time = RTL_SLOT_TIME_9;
824 mac->slot_time = RTL_SLOT_TIME_20;
826 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
827 (u8 *) (&mac->slot_time));
830 if (changed & BSS_CHANGED_HT) {
831 struct ieee80211_sta *sta = NULL;
833 RT_TRACE(COMP_MAC80211, DBG_TRACE,
834 ("BSS_CHANGED_HT\n"));
837 sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
839 if (sta->ht_cap.ampdu_density >
840 mac->current_ampdu_density)
841 mac->current_ampdu_density =
842 sta->ht_cap.ampdu_density;
843 if (sta->ht_cap.ampdu_factor <
844 mac->current_ampdu_factor)
845 mac->current_ampdu_factor =
846 sta->ht_cap.ampdu_factor;
850 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
851 (u8 *) (&mac->max_mss_density));
852 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
853 &mac->current_ampdu_factor);
854 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
855 &mac->current_ampdu_density);
858 if (changed & BSS_CHANGED_BSSID) {
860 struct ieee80211_sta *sta = NULL;
862 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
863 (u8 *) bss_conf->bssid);
865 RT_TRACE(COMP_MAC80211, DBG_DMESG,
866 ("bssid: %pM\n", bss_conf->bssid));
868 mac->vendor = PEER_UNKNOWN;
869 memcpy(mac->bssid, bss_conf->bssid, 6);
870 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
873 sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
879 if (rtlhal->current_bandtype == BAND_ON_5G) {
880 mac->mode = WIRELESS_MODE_A;
882 if (sta->supp_rates[0] <= 0xf)
883 mac->mode = WIRELESS_MODE_B;
885 mac->mode = WIRELESS_MODE_G;
888 if (sta->ht_cap.ht_supported) {
889 if (rtlhal->current_bandtype == BAND_ON_2_4G)
890 mac->mode = WIRELESS_MODE_N_24G;
892 mac->mode = WIRELESS_MODE_N_5G;
895 /* just station need it, because ibss & ap mode will
896 * set in sta_add, and will be NULL here */
897 if (vif->type == NL80211_IFTYPE_STATION) {
898 struct rtl_sta_info *sta_entry;
899 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
900 sta_entry->wireless_mode = mac->mode;
903 if (sta->ht_cap.ht_supported) {
904 mac->ht_enable = true;
907 * for cisco 1252 bw20 it's wrong
908 * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
914 if (changed & BSS_CHANGED_BASIC_RATES) {
915 /* for 5G must << RATE_6M_INDEX=4,
916 * because 5G have no cck rate*/
917 if (rtlhal->current_bandtype == BAND_ON_5G)
918 basic_rates = sta->supp_rates[1] << 4;
920 basic_rates = sta->supp_rates[0];
922 mac->basic_rates = basic_rates;
923 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
924 (u8 *) (&basic_rates));
930 * For FW LPS and Keep Alive:
931 * To tell firmware we have connected
932 * to an AP. For 92SE/CE power save v2.
934 if (changed & BSS_CHANGED_ASSOC) {
935 if (bss_conf->assoc) {
937 u8 mstatus = RT_MEDIA_CONNECT;
938 rtlpriv->cfg->ops->set_hw_reg(hw,
940 (u8 *) (&keep_alive));
942 rtlpriv->cfg->ops->set_hw_reg(hw,
943 HW_VAR_H2C_FW_JOINBSSRPT,
945 ppsc->report_linked = true;
949 u8 mstatus = RT_MEDIA_DISCONNECT;
950 rtlpriv->cfg->ops->set_hw_reg(hw,
951 HW_VAR_H2C_FW_JOINBSSRPT,
953 ppsc->report_linked = false;
957 if (rtlpriv->cfg->ops->get_btc_status()){
958 rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify(
959 rtlpriv, ppsc->report_linked);
964 mutex_unlock(&rtlpriv->locks.conf_mutex);
967 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
968 static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
970 static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
973 struct rtl_priv *rtlpriv = rtl_priv(hw);
976 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
980 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
981 static void rtl_op_set_tsf(struct ieee80211_hw *hw,
982 struct ieee80211_vif *vif, u64 tsf)
984 static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
987 struct rtl_priv *rtlpriv = rtl_priv(hw);
988 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
989 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
992 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
995 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
996 static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
998 static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
1001 struct rtl_priv *rtlpriv = rtl_priv(hw);
1004 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
1007 static void rtl_op_sta_notify(struct ieee80211_hw *hw,
1008 struct ieee80211_vif *vif,
1009 enum sta_notify_cmd cmd,
1010 struct ieee80211_sta *sta)
1013 case STA_NOTIFY_SLEEP:
1015 case STA_NOTIFY_AWAKE:
1022 static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
1023 struct ieee80211_vif *vif,
1024 enum ieee80211_ampdu_mlme_action action,
1025 struct ieee80211_sta *sta, u16 tid, u16 * ssn
1026 /*<delete in kernel start>*/
1027 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
1028 /*<delete in kernel end>*/
1030 /*<delete in kernel start>*/
1032 /*<delete in kernel end>*/
1035 struct rtl_priv *rtlpriv = rtl_priv(hw);
1038 case IEEE80211_AMPDU_TX_START:
1039 RT_TRACE(COMP_MAC80211, DBG_TRACE,
1040 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
1041 return rtl_tx_agg_start(hw, vif, sta, tid, ssn);
1043 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
1044 case IEEE80211_AMPDU_TX_STOP_CONT:
1045 case IEEE80211_AMPDU_TX_STOP_FLUSH:
1046 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1048 case IEEE80211_AMPDU_TX_STOP:
1050 RT_TRACE(COMP_MAC80211, DBG_TRACE,
1051 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
1052 return rtl_tx_agg_stop(hw, vif, sta, tid);
1054 case IEEE80211_AMPDU_TX_OPERATIONAL:
1055 RT_TRACE(COMP_MAC80211, DBG_TRACE,
1056 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
1057 rtl_tx_agg_oper(hw, sta, tid);
1059 case IEEE80211_AMPDU_RX_START:
1060 RT_TRACE(COMP_MAC80211, DBG_TRACE,
1061 ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
1062 return rtl_rx_agg_start(hw, sta, tid);
1064 case IEEE80211_AMPDU_RX_STOP:
1065 RT_TRACE(COMP_MAC80211, DBG_TRACE,
1066 ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
1067 return rtl_rx_agg_stop(hw, sta, tid);
1070 RT_TRACE(COMP_ERR, DBG_EMERG,
1071 ("IEEE80211_AMPDU_ERR!!!!:\n"));
1077 static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
1079 struct rtl_priv *rtlpriv = rtl_priv(hw);
1080 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1082 RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n"));
1083 mac->act_scanning = true;
1084 /*rtlpriv->btcops->btc_scan_notify(rtlpriv, 0); */
1085 if (rtlpriv->link_info.b_higher_busytraffic) {
1086 mac->skip_scan = true;
1090 if (rtlpriv->dm.supp_phymode_switch) {
1091 if (rtlpriv->cfg->ops->check_switch_to_dmdp)
1092 rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
1095 if (mac->link_state == MAC80211_LINKED) {
1097 mac->link_state = MAC80211_LINKED_SCANNING;
1103 rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
1105 rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
1107 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);
1111 static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
1113 struct rtl_priv *rtlpriv = rtl_priv(hw);
1114 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1116 RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n"));
1117 mac->act_scanning = false;
1118 mac->skip_scan = false;
1119 if (rtlpriv->link_info.b_higher_busytraffic) {
1123 /* p2p will use 1/6/11 to scan */
1124 if (mac->n_channels == 3)
1125 mac->p2p_in_use = true;
1127 mac->p2p_in_use = false;
1128 mac->n_channels = 0;
1130 rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
1132 if (mac->link_state == MAC80211_LINKED_SCANNING) {
1133 mac->link_state = MAC80211_LINKED;
1134 if (mac->opmode == NL80211_IFTYPE_STATION) {
1135 /* fix fwlps issue */
1136 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
1140 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
1141 /* rtlpriv->btcops->btc_scan_notify(rtlpriv, 1); */
1144 static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1145 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1146 struct ieee80211_key_conf *key)
1148 struct rtl_priv *rtlpriv = rtl_priv(hw);
1149 u8 key_type = NO_ENCRYPTION;
1151 bool group_key = false;
1152 bool wep_only = false;
1154 u8 mac_addr[ETH_ALEN];
1155 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1156 u8 zero_addr[ETH_ALEN] = { 0 };
1158 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1159 RT_TRACE(COMP_ERR, DBG_WARNING,
1160 ("not open hw encryption\n"));
1161 return -ENOSPC; /*User disabled HW-crypto */
1163 /* To support IBSS, use sw-crypto for GTK */
1164 if(((vif->type == NL80211_IFTYPE_ADHOC) ||
1165 (vif->type == NL80211_IFTYPE_MESH_POINT)) &&
1166 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1168 RT_TRACE(COMP_SEC, DBG_DMESG,
1169 ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
1170 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
1171 sta ? sta->addr : bcast_addr));
1172 rtlpriv->sec.being_setkey = true;
1174 mutex_lock(&rtlpriv->locks.conf_mutex);
1175 /* <1> get encryption alg */
1177 /*<delete in kernel start>*/
1178 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1179 /*<delete in kernel end>*/
1180 switch (key->cipher) {
1181 case WLAN_CIPHER_SUITE_WEP40:
1182 key_type = WEP40_ENCRYPTION;
1183 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
1185 case WLAN_CIPHER_SUITE_WEP104:
1186 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP104\n"));
1187 key_type = WEP104_ENCRYPTION;
1189 case WLAN_CIPHER_SUITE_TKIP:
1190 key_type = TKIP_ENCRYPTION;
1191 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
1193 case WLAN_CIPHER_SUITE_CCMP:
1194 key_type = AESCCMP_ENCRYPTION;
1195 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
1197 case WLAN_CIPHER_SUITE_AES_CMAC:
1198 /* HW don't support CMAC encryption,
1199 * use software CMAC encryption */
1200 key_type = AESCMAC_ENCRYPTION;
1201 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CMAC\n"));
1202 RT_TRACE(COMP_SEC, DBG_DMESG,
1203 ("HW don't support CMAC encrypiton, "
1204 "use software CMAC encrypiton\n"));
1208 RT_TRACE(COMP_ERR, DBG_EMERG,
1209 ("alg_err:%x!!!!:\n", key->cipher));
1212 /*<delete in kernel start>*/
1216 if (key->keylen == WLAN_KEY_LEN_WEP40) {
1217 key_type = WEP40_ENCRYPTION;
1218 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
1220 RT_TRACE(COMP_SEC, DBG_DMESG,
1222 key_type = WEP104_ENCRYPTION;
1226 key_type = TKIP_ENCRYPTION;
1227 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
1230 key_type = AESCCMP_ENCRYPTION;
1231 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
1234 /*HW don't support CMAC encryption, use software CMAC encryption */
1235 key_type = AESCMAC_ENCRYPTION;
1236 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CMAC\n"));
1237 RT_TRACE(COMP_SEC, DBG_DMESG,
1238 ("HW don't support CMAC encrypiton, "
1239 "use software CMAC encrypiton\n"));
1243 RT_TRACE(COMP_ERR, DBG_EMERG,
1244 ("alg_err:%x!!!!:\n", key->alg));
1248 /*<delete in kernel end>*/
1249 if(key_type == WEP40_ENCRYPTION ||
1250 key_type == WEP104_ENCRYPTION ||
1251 vif->type == NL80211_IFTYPE_ADHOC)
1252 rtlpriv->sec.use_defaultkey = true;
1254 /* <2> get key_idx */
1255 key_idx = (u8) (key->keyidx);
1258 /* <3> if pairwise key enable_hw_sec */
1259 group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
1261 /* wep always be group key, but there are two conditions:
1262 * 1) wep only: is just for wep enc, in this condition
1263 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
1264 * will be true & enable_hw_sec will be set when wep
1266 * 2) wep(group) + AES(pairwise): some AP like cisco
1267 * may use it, in this condition enable_hw_sec will not
1268 * be set when wep key setting */
1269 /* we must reset sec_info after lingked before set key,
1270 * or some flag will be wrong*/
1271 if (vif->type == NL80211_IFTYPE_AP ||
1272 vif->type == NL80211_IFTYPE_MESH_POINT) {
1273 if (!group_key || key_type == WEP40_ENCRYPTION ||
1274 key_type == WEP104_ENCRYPTION) {
1278 rtlpriv->cfg->ops->enable_hw_sec(hw);
1281 if ((!group_key) || (vif->type == NL80211_IFTYPE_ADHOC) ||
1282 rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
1283 if (rtlpriv->sec.pairwise_enc_algorithm ==
1285 (key_type == WEP40_ENCRYPTION ||
1286 key_type == WEP104_ENCRYPTION))
1288 rtlpriv->sec.pairwise_enc_algorithm = key_type;
1289 RT_TRACE(COMP_SEC, DBG_DMESG,
1290 ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:"
1291 "1 TKIP:2 AES:4 WEP104:5)\n", key_type));
1292 rtlpriv->cfg->ops->enable_hw_sec(hw);
1295 /* <4> set key based on cmd */
1299 RT_TRACE(COMP_SEC, DBG_DMESG,
1300 ("set WEP(group/pairwise) key\n"));
1301 /* Pairwise key with an assigned MAC address. */
1302 rtlpriv->sec.pairwise_enc_algorithm = key_type;
1303 rtlpriv->sec.group_enc_algorithm = key_type;
1304 /*set local buf about wep key. */
1305 memcpy(rtlpriv->sec.key_buf[key_idx],
1306 key->key, key->keylen);
1307 rtlpriv->sec.key_len[key_idx] = key->keylen;
1308 memcpy(mac_addr, zero_addr, ETH_ALEN);
1309 } else if (group_key) { /* group key */
1310 RT_TRACE(COMP_SEC, DBG_DMESG,
1311 ("set group key\n"));
1313 rtlpriv->sec.group_enc_algorithm = key_type;
1314 /*set local buf about group key. */
1315 memcpy(rtlpriv->sec.key_buf[key_idx],
1316 key->key, key->keylen);
1317 rtlpriv->sec.key_len[key_idx] = key->keylen;
1318 memcpy(mac_addr, bcast_addr, ETH_ALEN);
1319 } else { /* pairwise key */
1320 RT_TRACE(COMP_SEC, DBG_DMESG,
1321 ("set pairwise key\n"));
1323 RT_ASSERT(false, ("pairwise key withnot"
1329 /* Pairwise key with an assigned MAC address. */
1330 rtlpriv->sec.pairwise_enc_algorithm = key_type;
1331 /*set local buf about pairwise key. */
1332 memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
1333 key->key, key->keylen);
1334 rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
1335 rtlpriv->sec.pairwise_key =
1336 rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
1337 memcpy(mac_addr, sta->addr, ETH_ALEN);
1339 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
1340 group_key, key_type, wep_only,
1342 /* <5> tell mac80211 do something: */
1343 /*must use sw generate IV, or can not work !!!!. */
1344 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1345 key->hw_key_idx = key_idx;
1346 if (key_type == TKIP_ENCRYPTION)
1347 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1348 /*use software CCMP encryption for management frames (MFP) */
1349 if (key_type == AESCCMP_ENCRYPTION)
1350 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1353 RT_TRACE(COMP_SEC, DBG_DMESG,
1354 ("disable key delete one entry\n"));
1355 /*set local buf about wep key. */
1356 if (vif->type == NL80211_IFTYPE_AP ||
1357 vif->type == NL80211_IFTYPE_MESH_POINT) {
1359 rtl_cam_del_entry(hw, sta->addr);
1361 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
1362 rtlpriv->sec.key_len[key_idx] = 0;
1363 memcpy(mac_addr, zero_addr, ETH_ALEN);
1365 *mac80211 will delete entrys one by one,
1366 *so don't use rtl_cam_reset_all_entry
1367 *or clear all entry here.
1369 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
1372 RT_TRACE(COMP_ERR, DBG_EMERG,
1373 ("cmd_err:%x!!!!:\n", cmd));
1376 mutex_unlock(&rtlpriv->locks.conf_mutex);
1377 rtlpriv->sec.being_setkey = false;
1381 static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1383 struct rtl_priv *rtlpriv = rtl_priv(hw);
1389 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
1392 mutex_lock(&rtlpriv->locks.conf_mutex);
1394 /*if Radio On return true here */
1395 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
1398 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
1399 rtlpriv->rfkill.rfkill_state = radio_state;
1401 RT_TRACE(COMP_RF, DBG_DMESG,
1402 (KERN_INFO "wireless radio switch turned %s\n",
1403 radio_state ? "on" : "off"));
1405 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
1406 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1410 mutex_unlock(&rtlpriv->locks.conf_mutex);
1413 /* this function is called by mac80211 to flush tx buffer
1414 * before switch channle or power save, or tx buffer packet
1415 * maybe send after offchannel or rf sleep, this may cause
1416 * dis-association by AP */
1417 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
1418 static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1420 struct rtl_priv *rtlpriv = rtl_priv(hw);
1422 if (rtlpriv->intf_ops->flush)
1423 rtlpriv->intf_ops->flush(hw, queues, drop);
1426 static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
1428 struct rtl_priv *rtlpriv = rtl_priv(hw);
1430 if (rtlpriv->intf_ops->flush)
1431 rtlpriv->intf_ops->flush(hw, drop);
1435 const struct ieee80211_ops rtl_ops = {
1436 .start = rtl_op_start,
1437 .stop = rtl_op_stop,
1439 .add_interface = rtl_op_add_interface,
1440 .remove_interface = rtl_op_remove_interface,
1441 /*<delete in kernel start>*/
1442 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1443 /*<delete in kernel end>*/
1444 .change_interface = rtl_op_change_interface,
1445 /*<delete in kernel start>*/
1447 /*<delete in kernel end>*/
1448 .config = rtl_op_config,
1449 .configure_filter = rtl_op_configure_filter,
1450 .set_key = rtl_op_set_key,
1451 .conf_tx = rtl_op_conf_tx,
1452 .bss_info_changed = rtl_op_bss_info_changed,
1453 .get_tsf = rtl_op_get_tsf,
1454 .set_tsf = rtl_op_set_tsf,
1455 .reset_tsf = rtl_op_reset_tsf,
1456 .sta_notify = rtl_op_sta_notify,
1457 .ampdu_action = rtl_op_ampdu_action,
1458 .sw_scan_start = rtl_op_sw_scan_start,
1459 .sw_scan_complete = rtl_op_sw_scan_complete,
1460 .rfkill_poll = rtl_op_rfkill_poll,
1461 .sta_add = rtl_op_sta_add,
1462 .sta_remove = rtl_op_sta_remove,
1463 .flush = rtl_op_flush,