]> Pileus Git - ~andy/linux/blob - drivers/staging/rtl8821ae/core.c
random32: assign to network folks in MAINTAINERS
[~andy/linux] / drivers / staging / rtl8821ae / core.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  Realtek Corporation.
4  *
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.
8  *
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
12  * more details.
13  *
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
17  *
18  * The full GNU General Public License is included in this distribution in the
19  * file called LICENSE.
20  *
21  * Contact Information:
22  * wlanfae <wlanfae@realtek.com>
23  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24  * Hsinchu 300, Taiwan.
25  *
26  * Larry Finger <Larry.Finger@lwfinger.net>
27  *
28  *****************************************************************************/
29
30 #include "wifi.h"
31 #include "core.h"
32 #include "cam.h"
33 #include "base.h"
34 #include "ps.h"
35
36 #include "btcoexist/rtl_btc.h"
37
38 /*mutex for start & stop is must here. */
39 static int rtl_op_start(struct ieee80211_hw *hw)
40 {
41         int err = 0;
42         struct rtl_priv *rtlpriv = rtl_priv(hw);
43         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
44
45         if (!is_hal_stop(rtlhal))
46                 return 0;
47         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
48                 return 0;
49         mutex_lock(&rtlpriv->locks.conf_mutex);
50         err = rtlpriv->intf_ops->adapter_start(hw);
51         if (err)
52                 goto out;
53         rtl_watch_dog_timer_callback((unsigned long)hw);
54
55 out:
56         mutex_unlock(&rtlpriv->locks.conf_mutex);
57         return err;
58 }
59
60 static void rtl_op_stop(struct ieee80211_hw *hw)
61 {
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));
66
67         if (is_hal_stop(rtlhal))
68                 return;
69
70         /* here is must, because adhoc do stop and start,
71          * but stop with RFOFF may cause something wrong,
72          * like adhoc TP */
73         if (unlikely(ppsc->rfpwr_state == ERFOFF))
74                 rtl_ips_nic_on(hw);
75
76         mutex_lock(&rtlpriv->locks.conf_mutex);
77
78         mac->link_state = MAC80211_NOLINK;
79         memset(mac->bssid, 0, 6);
80         mac->vendor = PEER_UNKNOWN;
81
82         /*reset sec info */
83         rtl_cam_reset_sec_info(hw);
84
85         rtl_deinit_deferred_work(hw);
86         rtlpriv->intf_ops->adapter_stop(hw);
87
88         mutex_unlock(&rtlpriv->locks.conf_mutex);
89 }
90
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)
94 {
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));
100
101         if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
102                 goto err_free;
103
104         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
105                 goto err_free;
106
107         if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
108                 rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
109
110         return NETDEV_TX_OK;
111
112 err_free:
113         dev_kfree_skb_any(skb);
114         return NETDEV_TX_OK;
115 }
116 #else
117 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
118 static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
119 #else
120 /*<delete in kernel end>*/
121 static void rtl_op_tx(struct ieee80211_hw *hw,
122                       struct ieee80211_tx_control *control,
123                       struct sk_buff *skb)
124 /*<delete in kernel start>*/
125 #endif
126 /*<delete in kernel end>*/
127 {
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));
133
134         if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
135                 goto err_free;
136
137         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
138                 goto err_free;
139
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);
144 #else
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>*/
149 #endif
150 /*<delete in kernel end>*/
151         return;
152
153 err_free:
154         dev_kfree_skb_any(skb);
155         return;
156 }
157 /*<delete in kernel start>*/
158 #endif
159 /*<delete in kernel end>*/
160
161 static int rtl_op_add_interface(struct ieee80211_hw *hw,
162                 struct ieee80211_vif *vif)
163 {
164         struct rtl_priv *rtlpriv = rtl_priv(hw);
165         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
166         int err = 0;
167
168         if (mac->vif) {
169                 RT_TRACE(COMP_ERR, DBG_WARNING,
170                          ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
171                 return -EOPNOTSUPP;
172         }
173
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;
177 #endif
178
179         rtl_ips_nic_on(hw);
180
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;
187                 /*fall through*/
188 #else
189 /*<delete in kernel end>*/
190         switch (vif->type) {
191 /*<delete in kernel start>*/
192 #endif
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]);
201                 }
202                 break;
203         case NL80211_IFTYPE_ADHOC:
204                 RT_TRACE(COMP_MAC80211, DBG_LOUD,
205                          ("NL80211_IFTYPE_ADHOC \n"));
206
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;
211                 else
212                         mac->basic_rates = 0xff0;
213                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
214                                 (u8 *) (&mac->basic_rates));
215
216                 break;
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;
221                 /*fall through*/
222 #endif
223 /*<delete in kernel end>*/
224         case NL80211_IFTYPE_AP:
225                 RT_TRACE(COMP_MAC80211, DBG_LOUD,
226                          ("NL80211_IFTYPE_AP \n"));
227
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;
232                 else
233                         mac->basic_rates = 0xff0;
234                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
235                                               (u8 *) (&mac->basic_rates));
236                 break;
237         case NL80211_IFTYPE_MESH_POINT:
238                 RT_TRACE(COMP_MAC80211, DBG_LOUD,
239                          ("NL80211_IFTYPE_MESH_POINT \n"));
240
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;
245                 else
246                         mac->basic_rates = 0xff0;
247                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
248                                 (u8 *) (&mac->basic_rates));
249                 break;
250         default:
251                 RT_TRACE(COMP_ERR, DBG_EMERG,
252                          ("operation mode %d is not support!\n", vif->type));
253                 err = -EOPNOTSUPP;
254                 goto out;
255         }
256
257 #ifdef VIF_TODO
258         if (!rtl_set_vif_info(hw, vif))
259                 goto out;
260 #endif
261
262         if (mac->p2p) {
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));
268         }
269         mac->vif = vif;
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);
274
275 out:
276         mutex_unlock(&rtlpriv->locks.conf_mutex);
277         return err;
278 }
279
280 static void rtl_op_remove_interface(struct ieee80211_hw *hw,
281                 struct ieee80211_vif *vif)
282 {
283         struct rtl_priv *rtlpriv = rtl_priv(hw);
284         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
285
286         mutex_lock(&rtlpriv->locks.conf_mutex);
287
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]);
296                 }
297         }
298
299         /*
300          *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
301          *NO LINK for our hardware.
302          */
303         mac->p2p = 0;
304         mac->vif = NULL;
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);
310
311         mutex_unlock(&rtlpriv->locks.conf_mutex);
312 }
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)
319 {
320         struct rtl_priv *rtlpriv = rtl_priv(hw);
321         int ret;
322         rtl_op_remove_interface(hw, vif);
323
324         vif->type = new_type;
325         vif->p2p = p2p;
326         ret = rtl_op_add_interface(hw, vif);
327         RT_TRACE(COMP_MAC80211, DBG_LOUD,
328                  (" p2p  %x\n",p2p));
329         return ret;
330 }
331 /*<delete in kernel start>*/
332 #endif
333 /*<delete in kernel end>*/
334 static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
335 {
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;
341
342         if (mac->skip_scan)
343                 return 1;
344
345
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"));
350         }
351
352         /*For IPS */
353         if (changed & IEEE80211_CONF_CHANGE_IDLE) {
354                 if (hw->conf.flags & IEEE80211_CONF_IDLE)
355                         rtl_ips_nic_off(hw);
356                 else
357                         rtl_ips_nic_on(hw);
358         } else {
359                 /*
360                  *although rfoff may not cause by ips, but we will
361                  *check the reason in set_rf_power_state function
362                  */
363                 if (unlikely(ppsc->rfpwr_state == ERFOFF))
364                         rtl_ips_nic_on(hw);
365         }
366
367         /*For LPS */
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,
383                                                    MSECS(5));
384                 } else {
385                         rtl_swlps_rf_awake(hw);
386                         rtlpriv->psc.sw_ps_enabled = false;
387                 }
388         }
389
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));
398         }
399
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));
405 #else
406                 struct ieee80211_channel *channel = hw->conf.channel;
407                 enum nl80211_channel_type channel_type = hw->conf.channel_type;
408 #endif
409                 u8 wide_chan = (u8) channel->hw_value;
410
411                 if (mac->act_scanning)
412                         mac->n_channels++;
413
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);
419                 }
420
421                 /*
422                  *because we should back channel to
423                  *current_network.chan in in scanning,
424                  *So if set_chan == current_network.chan
425                  *we should set it.
426                  *because mac80211 tell us wrong bw40
427                  *info for cisco1253 bw20, so we modify
428                  *it here based on UPPER & LOWER
429                  */
430                 switch (channel_type) {
431                         case NL80211_CHAN_HT20:
432                         case NL80211_CHAN_NO_HT:
433                                 /* SC */
434                                 mac->cur_40_prime_sc =
435                                         PRIME_CHNL_OFFSET_DONT_CARE;
436                                 rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
437                                 mac->bw_40 = false;
438                                 break;
439                         case NL80211_CHAN_HT40MINUS:
440                                 /* SC */
441                                 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
442                                 rtlphy->current_chan_bw =
443                                         HT_CHANNEL_WIDTH_20_40;
444                                 mac->bw_40 = true;
445
446                                 /*wide channel */
447                                 wide_chan -= 2;
448
449                                 break;
450                         case NL80211_CHAN_HT40PLUS:
451                                 /* SC */
452                                 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
453                                 rtlphy->current_chan_bw =
454                                         HT_CHANNEL_WIDTH_20_40;
455                                 mac->bw_40 = true;
456
457                                 /*wide channel */
458                                 wide_chan += 2;
459
460                                 break;
461                         default:
462                                 mac->bw_40 = false;
463                                 RT_TRACE(COMP_ERR, DBG_EMERG,
464                                                 ("switch case not processed \n"));
465                                 break;
466                 }
467
468                 if (wide_chan <= 0)
469                         wide_chan = 1;
470
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
477                  */
478                 if (rtlpriv->mac80211.offchan_deley) {
479                         rtlpriv->mac80211.offchan_deley = false;
480                         mdelay(50);
481                 }
482
483                 rtlphy->current_channel = wide_chan;
484
485                 rtlpriv->cfg->ops->switch_channel(hw);
486                 rtlpriv->cfg->ops->set_channel_access(hw);
487                 rtlpriv->cfg->ops->set_bw_mode(hw,
488                         channel_type);
489         }
490
491         mutex_unlock(&rtlpriv->locks.conf_mutex);
492
493         return 0;
494 }
495
496 static void rtl_op_configure_filter(struct ieee80211_hw *hw,
497                                     unsigned int changed_flags,
498                                     unsigned int *new_flags, u64 multicast)
499 {
500         struct rtl_priv *rtlpriv = rtl_priv(hw);
501         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
502
503         *new_flags &= RTL_SUPPORTED_FILTERS;
504         if (0 == changed_flags)
505                 return;
506
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"));
514                 } else {
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"));
519                 }
520         }
521
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"));
527                 } else {
528                         mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
529                         RT_TRACE(COMP_MAC80211, DBG_LOUD,
530                                  ("Disable receive FCS error frame.\n"));
531                 }
532         }
533
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);
543                         } else {
544                                 rtlpriv->cfg->ops->set_chk_bssid(hw, true);
545                         }
546                 }
547         }
548
549         if (changed_flags & FIF_CONTROL) {
550                 if (*new_flags & FIF_CONTROL) {
551                         mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
552
553                         RT_TRACE(COMP_MAC80211, DBG_LOUD,
554                                  ("Enable receive control frame.\n"));
555                 } else {
556                         mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
557                         RT_TRACE(COMP_MAC80211, DBG_LOUD,
558                                  ("Disable receive control frame.\n"));
559                 }
560         }
561
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"));
567                 } else {
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"));
571                 }
572         }
573 }
574 static int rtl_op_sta_add(struct ieee80211_hw *hw,
575                          struct ieee80211_vif *vif,
576                          struct ieee80211_sta *sta)
577 {
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;
582
583         if (sta) {
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;
594
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;
601
602                         if (vif->type == NL80211_IFTYPE_ADHOC)
603                                 sta_entry->wireless_mode = WIRELESS_MODE_A;
604                 }
605                 /*disable cck rate for p2p*/
606                 if (mac->p2p)
607                         sta->supp_rates[0] &= 0xfffffff0;
608
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);
613         }
614
615         return 0;
616 }
617
618 static int rtl_op_sta_remove(struct ieee80211_hw *hw,
619                                 struct ieee80211_vif *vif,
620                                 struct ieee80211_sta *sta)
621 {
622         struct rtl_priv *rtlpriv = rtl_priv(hw);
623         struct rtl_sta_info *sta_entry;
624         if (sta) {
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);
633         }
634         return 0;
635 }
636 static int _rtl_get_hal_qnum(u16 queue)
637 {
638         int qnum;
639
640         switch (queue) {
641         case 0:
642                 qnum = AC3_VO;
643                 break;
644         case 1:
645                 qnum = AC2_VI;
646                 break;
647         case 2:
648                 qnum = AC0_BE;
649                 break;
650         case 3:
651                 qnum = AC1_BK;
652                 break;
653         default:
654                 qnum = AC0_BE;
655                 break;
656         }
657         return qnum;
658 }
659
660 /*
661  *for mac80211 VO=0, VI=1, BE=2, BK=3
662  *for rtl819x  BE=0, BK=1, VI=2, VO=3
663  */
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)
668 #else
669 static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
670                           const struct ieee80211_tx_queue_params *param)
671 #endif
672 {
673         struct rtl_priv *rtlpriv = rtl_priv(hw);
674         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
675         int aci;
676
677         if (queue >= AC_MAX) {
678                 RT_TRACE(COMP_ERR, DBG_WARNING,
679                          ("queue number %d is incorrect!\n", queue));
680                 return -EINVAL;
681         }
682
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);
690         return 0;
691 }
692
693 static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
694                                     struct ieee80211_vif *vif,
695                                     struct ieee80211_bss_conf *bss_conf,
696                                     u32 changed)
697 {
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));
702
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"));
713
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,
718                                                 rtlpriv->cfg->maps
719                                                 [RTL_IBSS_INT_MASKS], 0);
720
721                                 if (rtlpriv->cfg->ops->linked_set_reg)
722                                         rtlpriv->cfg->ops->linked_set_reg(hw);
723                         }
724                 }
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"));
730
731                                 mac->beacon_enabled = 0;
732                                 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
733                                                 rtlpriv->cfg->maps
734                                                 [RTL_IBSS_INT_MASKS]);
735                         }
736                 }
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);
742                 }
743         }
744
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 */
753                         /* reset sec info */
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);
758
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);
763
764                         if (rtlpriv->cfg->ops->linked_set_reg)
765                                 rtlpriv->cfg->ops->linked_set_reg(hw);
766
767                         rcu_read_lock();
768                         sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
769
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);
778                         }
779                         rcu_read_unlock();
780
781                         RT_TRACE(COMP_MAC80211, DBG_DMESG,
782                                  ("BSS_CHANGED_ASSOC\n"));
783                 } else {
784                         if (mac->link_state == MAC80211_LINKED)
785                                 rtl_lps_leave(hw);
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;
791
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);
795                         }
796                         RT_TRACE(COMP_MAC80211, DBG_DMESG,
797                                  ("BSS_CHANGED_UN_ASSOC\n"));
798                 }
799         }
800
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;
805         }
806
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));
811
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));
815         }
816
817         if (changed & BSS_CHANGED_ERP_SLOT) {
818                 RT_TRACE(COMP_MAC80211, DBG_TRACE,
819                          ("BSS_CHANGED_ERP_SLOT\n"));
820
821                 if (bss_conf->use_short_slot)
822                         mac->slot_time = RTL_SLOT_TIME_9;
823                 else
824                         mac->slot_time = RTL_SLOT_TIME_20;
825
826                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
827                                               (u8 *) (&mac->slot_time));
828         }
829
830         if (changed & BSS_CHANGED_HT) {
831                 struct ieee80211_sta *sta = NULL;
832
833                 RT_TRACE(COMP_MAC80211, DBG_TRACE,
834                          ("BSS_CHANGED_HT\n"));
835
836                 rcu_read_lock();
837                 sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
838                 if (sta) {
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;
847                 }
848                 rcu_read_unlock();
849
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);
856         }
857
858         if (changed & BSS_CHANGED_BSSID) {
859                 u32 basic_rates;
860                 struct ieee80211_sta *sta = NULL;
861
862                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
863                                               (u8 *) bss_conf->bssid);
864
865                 RT_TRACE(COMP_MAC80211, DBG_DMESG,
866                          ("bssid: %pM\n", bss_conf->bssid));
867
868                 mac->vendor = PEER_UNKNOWN;
869                 memcpy(mac->bssid, bss_conf->bssid, 6);
870                 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
871
872                 rcu_read_lock();
873                 sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
874                 if (!sta) {
875                         rcu_read_unlock();
876                         goto out;
877                 }
878
879                 if (rtlhal->current_bandtype == BAND_ON_5G) {
880                         mac->mode = WIRELESS_MODE_A;
881                 } else {
882                         if (sta->supp_rates[0] <= 0xf)
883                                 mac->mode = WIRELESS_MODE_B;
884                         else
885                                 mac->mode = WIRELESS_MODE_G;
886                 }
887
888                 if (sta->ht_cap.ht_supported) {
889                         if (rtlhal->current_bandtype == BAND_ON_2_4G)
890                                 mac->mode = WIRELESS_MODE_N_24G;
891                         else
892                                 mac->mode = WIRELESS_MODE_N_5G;
893                 }
894
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;
901                 }
902
903                 if (sta->ht_cap.ht_supported) {
904                         mac->ht_enable = true;
905
906                         /*
907                          * for cisco 1252 bw20 it's wrong
908                          * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
909                          *      mac->bw_40 = true;
910                          * }
911                          * */
912                 }
913
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;
919                         else
920                                 basic_rates = sta->supp_rates[0];
921
922                         mac->basic_rates = basic_rates;
923                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
924                                         (u8 *) (&basic_rates));
925                 }
926                 rcu_read_unlock();
927         }
928
929         /*
930          * For FW LPS and Keep Alive:
931          * To tell firmware we have connected
932          * to an AP. For 92SE/CE power save v2.
933          */
934         if (changed & BSS_CHANGED_ASSOC) {
935                 if (bss_conf->assoc) {
936                         u8 keep_alive = 10;
937                         u8 mstatus = RT_MEDIA_CONNECT;
938                         rtlpriv->cfg->ops->set_hw_reg(hw,
939                                                       HW_VAR_KEEP_ALIVE,
940                                                       (u8 *) (&keep_alive));
941
942                         rtlpriv->cfg->ops->set_hw_reg(hw,
943                                                       HW_VAR_H2C_FW_JOINBSSRPT,
944                                                       (u8 *) (&mstatus));
945                         ppsc->report_linked = true;
946
947                 } else {
948
949                         u8 mstatus = RT_MEDIA_DISCONNECT;
950                         rtlpriv->cfg->ops->set_hw_reg(hw,
951                                                       HW_VAR_H2C_FW_JOINBSSRPT,
952                                                       (u8 *) (&mstatus));
953                         ppsc->report_linked = false;
954
955                 }
956
957                 if (rtlpriv->cfg->ops->get_btc_status()){
958                         rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify(
959                                                 rtlpriv, ppsc->report_linked);
960                 }
961         }
962
963 out:
964         mutex_unlock(&rtlpriv->locks.conf_mutex);
965 }
966
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)
969 #else
970 static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
971 #endif
972 {
973         struct rtl_priv *rtlpriv = rtl_priv(hw);
974         u64 tsf;
975
976         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
977         return tsf;
978 }
979
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)
983 #else
984 static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
985 #endif
986 {
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;
990
991         mac->tsf = tsf;
992         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
993 }
994
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)
997 #else
998 static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
999 #endif
1000 {
1001         struct rtl_priv *rtlpriv = rtl_priv(hw);
1002         u8 tmp = 0;
1003
1004         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
1005 }
1006
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)
1011 {
1012         switch (cmd) {
1013         case STA_NOTIFY_SLEEP:
1014                 break;
1015         case STA_NOTIFY_AWAKE:
1016                 break;
1017         default:
1018                 break;
1019         }
1020 }
1021
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>*/
1029                                ,u8 buf_size
1030 /*<delete in kernel start>*/
1031 #endif
1032 /*<delete in kernel end>*/
1033                                )
1034 {
1035         struct rtl_priv *rtlpriv = rtl_priv(hw);
1036
1037         switch (action) {
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);
1042                 break;
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:
1047 #else
1048         case IEEE80211_AMPDU_TX_STOP:
1049 #endif
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);
1053                 break;
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);
1058                 break;
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);
1063                 break;
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);
1068                 break;
1069         default:
1070                 RT_TRACE(COMP_ERR, DBG_EMERG,
1071                          ("IEEE80211_AMPDU_ERR!!!!:\n"));
1072                 return -EOPNOTSUPP;
1073         }
1074         return 0;
1075 }
1076
1077 static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
1078 {
1079         struct rtl_priv *rtlpriv = rtl_priv(hw);
1080         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1081
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;
1087                 return;
1088         }
1089
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);
1093         }
1094
1095         if (mac->link_state == MAC80211_LINKED) {
1096                 rtl_lps_leave(hw);
1097                 mac->link_state = MAC80211_LINKED_SCANNING;
1098         } else {
1099                 rtl_ips_nic_on(hw);
1100         }
1101
1102         /* Dul mac */
1103         rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
1104
1105         rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
1106
1107         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);
1108
1109 }
1110
1111 static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
1112 {
1113         struct rtl_priv *rtlpriv = rtl_priv(hw);
1114         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1115
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) {
1120                 return;
1121         }
1122
1123         /* p2p will use 1/6/11 to scan */
1124         if (mac->n_channels == 3)
1125                 mac->p2p_in_use = true;
1126         else
1127                 mac->p2p_in_use = false;
1128         mac->n_channels = 0;
1129         /* Dul mac */
1130         rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
1131
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);
1137                 }
1138         }
1139
1140         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
1141         /* rtlpriv->btcops->btc_scan_notify(rtlpriv, 1); */
1142 }
1143
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)
1147 {
1148         struct rtl_priv *rtlpriv = rtl_priv(hw);
1149         u8 key_type = NO_ENCRYPTION;
1150         u8 key_idx;
1151         bool group_key = false;
1152         bool wep_only = false;
1153         int err = 0;
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 };
1157
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 */
1162         }
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))
1167                 return -ENOSPC;
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;
1173         rtl_ips_nic_on(hw);
1174         mutex_lock(&rtlpriv->locks.conf_mutex);
1175         /* <1> get encryption alg */
1176
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"));
1184                 break;
1185         case WLAN_CIPHER_SUITE_WEP104:
1186                 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP104\n"));
1187                 key_type = WEP104_ENCRYPTION;
1188                 break;
1189         case WLAN_CIPHER_SUITE_TKIP:
1190                 key_type = TKIP_ENCRYPTION;
1191                 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
1192                 break;
1193         case WLAN_CIPHER_SUITE_CCMP:
1194                 key_type = AESCCMP_ENCRYPTION;
1195                 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
1196                 break;
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"));
1205                 err = -EOPNOTSUPP;
1206                 goto out_unlock;
1207         default:
1208                 RT_TRACE(COMP_ERR, DBG_EMERG,
1209                          ("alg_err:%x!!!!:\n", key->cipher));
1210                 goto out_unlock;
1211         }
1212 /*<delete in kernel start>*/
1213 #else
1214         switch (key->alg) {
1215         case ALG_WEP:
1216                 if (key->keylen == WLAN_KEY_LEN_WEP40) {
1217                         key_type = WEP40_ENCRYPTION;
1218                         RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
1219                 } else {
1220                         RT_TRACE(COMP_SEC, DBG_DMESG,
1221                                  ("alg:WEP104\n"));
1222                         key_type = WEP104_ENCRYPTION;
1223                 }
1224                 break;
1225         case ALG_TKIP:
1226                 key_type = TKIP_ENCRYPTION;
1227                 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
1228                 break;
1229         case ALG_CCMP:
1230                 key_type = AESCCMP_ENCRYPTION;
1231                 RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
1232                 break;
1233         case ALG_AES_CMAC:
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"));
1240                 err = -EOPNOTSUPP;
1241                 goto out_unlock;
1242         default:
1243                 RT_TRACE(COMP_ERR, DBG_EMERG,
1244                          ("alg_err:%x!!!!:\n", key->alg));
1245                 goto out_unlock;
1246         }
1247 #endif
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;
1253
1254         /* <2> get key_idx */
1255         key_idx = (u8) (key->keyidx);
1256         if (key_idx > 3)
1257                 goto out_unlock;
1258         /* <3> if pairwise key enable_hw_sec */
1259         group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
1260
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
1265          * ke setting.
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) {
1275                         if (group_key) {
1276                                 wep_only = true;
1277                         }
1278                         rtlpriv->cfg->ops->enable_hw_sec(hw);
1279                 }
1280         } else {
1281                 if ((!group_key) || (vif->type == NL80211_IFTYPE_ADHOC) ||
1282                     rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
1283                         if (rtlpriv->sec.pairwise_enc_algorithm ==
1284                             NO_ENCRYPTION &&
1285                            (key_type == WEP40_ENCRYPTION ||
1286                             key_type == WEP104_ENCRYPTION))
1287                                 wep_only = true;
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);
1293                 }
1294         }
1295         /* <4> set key based on cmd */
1296         switch (cmd) {
1297         case SET_KEY:
1298                 if (wep_only) {
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"));
1312                         /* group key */
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"));
1322                         if (!sta) {
1323                                 RT_ASSERT(false, ("pairwise key withnot"
1324                                                   "mac_addr\n"));
1325
1326                                 err = -EOPNOTSUPP;
1327                                 goto out_unlock;
1328                         }
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);
1338                 }
1339                 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
1340                                            group_key, key_type, wep_only,
1341                                            false);
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;
1351                 break;
1352         case DISABLE_KEY:
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) {
1358                         if (sta)
1359                                 rtl_cam_del_entry(hw, sta->addr);
1360                 }
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);
1364                 /*
1365                  *mac80211 will delete entrys one by one,
1366                  *so don't use rtl_cam_reset_all_entry
1367                  *or clear all entry here.
1368                  */
1369                 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
1370                 break;
1371         default:
1372                 RT_TRACE(COMP_ERR, DBG_EMERG,
1373                          ("cmd_err:%x!!!!:\n", cmd));
1374         }
1375 out_unlock:
1376         mutex_unlock(&rtlpriv->locks.conf_mutex);
1377         rtlpriv->sec.being_setkey = false;
1378         return err;
1379 }
1380
1381 static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1382 {
1383         struct rtl_priv *rtlpriv = rtl_priv(hw);
1384
1385         bool radio_state;
1386         bool blocked;
1387         u8 valid = 0;
1388
1389         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
1390                 return;
1391
1392         mutex_lock(&rtlpriv->locks.conf_mutex);
1393
1394         /*if Radio On return true here */
1395         radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
1396
1397         if (valid) {
1398                 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
1399                         rtlpriv->rfkill.rfkill_state = radio_state;
1400
1401                         RT_TRACE(COMP_RF, DBG_DMESG,
1402                                  (KERN_INFO "wireless radio switch turned %s\n",
1403                                   radio_state ? "on" : "off"));
1404
1405                         blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
1406                         wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1407                 }
1408         }
1409
1410         mutex_unlock(&rtlpriv->locks.conf_mutex);
1411 }
1412
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)
1419 {
1420         struct rtl_priv *rtlpriv = rtl_priv(hw);
1421
1422         if (rtlpriv->intf_ops->flush)
1423                 rtlpriv->intf_ops->flush(hw, queues, drop);
1424 }
1425 #else
1426 static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
1427 {
1428         struct rtl_priv *rtlpriv = rtl_priv(hw);
1429
1430         if (rtlpriv->intf_ops->flush)
1431                 rtlpriv->intf_ops->flush(hw, drop);
1432 }
1433 #endif
1434
1435 const struct ieee80211_ops rtl_ops = {
1436         .start = rtl_op_start,
1437         .stop = rtl_op_stop,
1438         .tx = rtl_op_tx,
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>*/
1446 #endif
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,
1464 };