Merge git://www.linux-watchdog.org/linux-watchdog
[linux-2.6-block.git] / drivers / net / wireless / rtlwifi / core.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2012  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 "pci.h"
35 #include "ps.h"
36
37 #include <linux/export.h>
38
39 void rtl_addr_delay(u32 addr)
40 {
41         if (addr == 0xfe)
42                 mdelay(50);
43         else if (addr == 0xfd)
44                 mdelay(5);
45         else if (addr == 0xfc)
46                 mdelay(1);
47         else if (addr == 0xfb)
48                 udelay(50);
49         else if (addr == 0xfa)
50                 udelay(5);
51         else if (addr == 0xf9)
52                 udelay(1);
53 }
54 EXPORT_SYMBOL(rtl_addr_delay);
55
56 void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
57                      u32 mask, u32 data)
58 {
59         if (addr == 0xfe) {
60                 mdelay(50);
61         } else if (addr == 0xfd) {
62                 mdelay(5);
63         } else if (addr == 0xfc) {
64                 mdelay(1);
65         } else if (addr == 0xfb) {
66                 udelay(50);
67         } else if (addr == 0xfa) {
68                 udelay(5);
69         } else if (addr == 0xf9) {
70                 udelay(1);
71         } else {
72                 rtl_set_rfreg(hw, rfpath, addr, mask, data);
73                 udelay(1);
74         }
75 }
76 EXPORT_SYMBOL(rtl_rfreg_delay);
77
78 void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
79 {
80         if (addr == 0xfe) {
81                 mdelay(50);
82         } else if (addr == 0xfd) {
83                 mdelay(5);
84         } else if (addr == 0xfc) {
85                 mdelay(1);
86         } else if (addr == 0xfb) {
87                 udelay(50);
88         } else if (addr == 0xfa) {
89                 udelay(5);
90         } else if (addr == 0xf9) {
91                 udelay(1);
92         } else {
93                 rtl_set_bbreg(hw, addr, MASKDWORD, data);
94                 udelay(1);
95         }
96 }
97 EXPORT_SYMBOL(rtl_bb_delay);
98
99 void rtl_fw_cb(const struct firmware *firmware, void *context)
100 {
101         struct ieee80211_hw *hw = context;
102         struct rtl_priv *rtlpriv = rtl_priv(hw);
103         int err;
104
105         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
106                          "Firmware callback routine entered!\n");
107         complete(&rtlpriv->firmware_loading_complete);
108         if (!firmware) {
109                 if (rtlpriv->cfg->alt_fw_name) {
110                         err = request_firmware(&firmware,
111                                                rtlpriv->cfg->alt_fw_name,
112                                                rtlpriv->io.dev);
113                         pr_info("Loading alternative firmware %s\n",
114                                 rtlpriv->cfg->alt_fw_name);
115                         if (!err)
116                                 goto found_alt;
117                 }
118                 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
119                 rtlpriv->max_fw_size = 0;
120                 return;
121         }
122 found_alt:
123         if (firmware->size > rtlpriv->max_fw_size) {
124                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
125                          "Firmware is too big!\n");
126                 release_firmware(firmware);
127                 return;
128         }
129         memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
130         rtlpriv->rtlhal.fwsize = firmware->size;
131         release_firmware(firmware);
132
133         err = ieee80211_register_hw(hw);
134         if (err) {
135                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
136                          "Can't register mac80211 hw\n");
137                 return;
138         } else {
139                 rtlpriv->mac80211.mac80211_registered = 1;
140         }
141         set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
142
143         /*init rfkill */
144         rtl_init_rfkill(hw);
145 }
146 EXPORT_SYMBOL(rtl_fw_cb);
147
148 /*mutex for start & stop is must here. */
149 static int rtl_op_start(struct ieee80211_hw *hw)
150 {
151         int err;
152         struct rtl_priv *rtlpriv = rtl_priv(hw);
153         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
154
155         if (!is_hal_stop(rtlhal))
156                 return 0;
157         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
158                 return 0;
159         mutex_lock(&rtlpriv->locks.conf_mutex);
160         err = rtlpriv->intf_ops->adapter_start(hw);
161         if (!err)
162                 rtl_watch_dog_timer_callback((unsigned long)hw);
163         mutex_unlock(&rtlpriv->locks.conf_mutex);
164         return err;
165 }
166
167 static void rtl_op_stop(struct ieee80211_hw *hw)
168 {
169         struct rtl_priv *rtlpriv = rtl_priv(hw);
170         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
171         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
172         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
173
174         if (is_hal_stop(rtlhal))
175                 return;
176
177         /* here is must, because adhoc do stop and start,
178          * but stop with RFOFF may cause something wrong,
179          * like adhoc TP
180          */
181         if (unlikely(ppsc->rfpwr_state == ERFOFF)) {
182                 rtl_ips_nic_on(hw);
183         }
184
185         mutex_lock(&rtlpriv->locks.conf_mutex);
186
187         mac->link_state = MAC80211_NOLINK;
188         memset(mac->bssid, 0, ETH_ALEN);
189         mac->vendor = PEER_UNKNOWN;
190
191         /*reset sec info */
192         rtl_cam_reset_sec_info(hw);
193
194         rtl_deinit_deferred_work(hw);
195         rtlpriv->intf_ops->adapter_stop(hw);
196
197         mutex_unlock(&rtlpriv->locks.conf_mutex);
198 }
199
200 static void rtl_op_tx(struct ieee80211_hw *hw,
201                       struct ieee80211_tx_control *control,
202                       struct sk_buff *skb)
203 {
204         struct rtl_priv *rtlpriv = rtl_priv(hw);
205         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
206         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
207         struct rtl_tcb_desc tcb_desc;
208         memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
209
210         if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
211                 goto err_free;
212
213         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
214                 goto err_free;
215
216         if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb))
217                 rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc);
218
219         return;
220
221 err_free:
222         dev_kfree_skb_any(skb);
223 }
224
225 static int rtl_op_add_interface(struct ieee80211_hw *hw,
226                 struct ieee80211_vif *vif)
227 {
228         struct rtl_priv *rtlpriv = rtl_priv(hw);
229         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
230         int err = 0;
231
232         vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
233
234         if (mac->vif) {
235                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
236                          "vif has been set!! mac->vif = 0x%p\n", mac->vif);
237                 return -EOPNOTSUPP;
238         }
239
240         rtl_ips_nic_on(hw);
241
242         mutex_lock(&rtlpriv->locks.conf_mutex);
243
244         switch (ieee80211_vif_type_p2p(vif)) {
245         case NL80211_IFTYPE_P2P_CLIENT:
246                 mac->p2p = P2P_ROLE_CLIENT;
247                 /*fall through*/
248         case NL80211_IFTYPE_STATION:
249                 if (mac->beacon_enabled == 1) {
250                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
251                                  "NL80211_IFTYPE_STATION\n");
252                         mac->beacon_enabled = 0;
253                         rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
254                                         rtlpriv->cfg->maps
255                                         [RTL_IBSS_INT_MASKS]);
256                 }
257                 mac->link_state = MAC80211_LINKED;
258                 break;
259         case NL80211_IFTYPE_ADHOC:
260                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
261                          "NL80211_IFTYPE_ADHOC\n");
262
263                 mac->link_state = MAC80211_LINKED;
264                 rtlpriv->cfg->ops->set_bcn_reg(hw);
265                 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
266                         mac->basic_rates = 0xfff;
267                 else
268                         mac->basic_rates = 0xff0;
269                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
270                                 (u8 *) (&mac->basic_rates));
271
272                 break;
273         case NL80211_IFTYPE_P2P_GO:
274                 mac->p2p = P2P_ROLE_GO;
275                 /*fall through*/
276         case NL80211_IFTYPE_AP:
277                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
278                          "NL80211_IFTYPE_AP\n");
279
280                 mac->link_state = MAC80211_LINKED;
281                 rtlpriv->cfg->ops->set_bcn_reg(hw);
282                 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
283                         mac->basic_rates = 0xfff;
284                 else
285                         mac->basic_rates = 0xff0;
286                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
287                                 (u8 *) (&mac->basic_rates));
288                 break;
289         case NL80211_IFTYPE_MESH_POINT:
290                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
291                          "NL80211_IFTYPE_MESH_POINT\n");
292
293                 mac->link_state = MAC80211_LINKED;
294                 rtlpriv->cfg->ops->set_bcn_reg(hw);
295                 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
296                         mac->basic_rates = 0xfff;
297                 else
298                         mac->basic_rates = 0xff0;
299                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
300                                 (u8 *)(&mac->basic_rates));
301                 break;
302         default:
303                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
304                          "operation mode %d is not supported!\n", vif->type);
305                 err = -EOPNOTSUPP;
306                 goto out;
307         }
308
309         if (mac->p2p) {
310                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
311                          "p2p role %x\n", vif->type);
312                 mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
313                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
314                                 (u8 *)(&mac->basic_rates));
315         }
316         mac->vif = vif;
317         mac->opmode = vif->type;
318         rtlpriv->cfg->ops->set_network_type(hw, vif->type);
319         memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
320         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
321
322 out:
323         mutex_unlock(&rtlpriv->locks.conf_mutex);
324         return err;
325 }
326
327 static void rtl_op_remove_interface(struct ieee80211_hw *hw,
328                 struct ieee80211_vif *vif)
329 {
330         struct rtl_priv *rtlpriv = rtl_priv(hw);
331         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
332
333         mutex_lock(&rtlpriv->locks.conf_mutex);
334
335         /* Free beacon resources */
336         if ((vif->type == NL80211_IFTYPE_AP) ||
337             (vif->type == NL80211_IFTYPE_ADHOC) ||
338             (vif->type == NL80211_IFTYPE_MESH_POINT)) {
339                 if (mac->beacon_enabled == 1) {
340                         mac->beacon_enabled = 0;
341                         rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
342                                         rtlpriv->cfg->maps
343                                         [RTL_IBSS_INT_MASKS]);
344                 }
345         }
346
347         /*
348          *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
349          *NO LINK for our hardware.
350          */
351         mac->p2p = 0;
352         mac->vif = NULL;
353         mac->link_state = MAC80211_NOLINK;
354         memset(mac->bssid, 0, ETH_ALEN);
355         mac->vendor = PEER_UNKNOWN;
356         mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
357         rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
358         mutex_unlock(&rtlpriv->locks.conf_mutex);
359 }
360
361 static int rtl_op_change_interface(struct ieee80211_hw *hw,
362                                       struct ieee80211_vif *vif,
363                                       enum nl80211_iftype new_type, bool p2p)
364 {
365         struct rtl_priv *rtlpriv = rtl_priv(hw);
366         int ret;
367         rtl_op_remove_interface(hw, vif);
368
369         vif->type = new_type;
370         vif->p2p = p2p;
371         ret = rtl_op_add_interface(hw, vif);
372         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
373                  "p2p %x\n", p2p);
374         return ret;
375 }
376
377 static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
378 {
379         struct rtl_priv *rtlpriv = rtl_priv(hw);
380         struct rtl_phy *rtlphy = &(rtlpriv->phy);
381         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
382         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
383         struct ieee80211_conf *conf = &hw->conf;
384
385         if (mac->skip_scan)
386                 return 1;
387
388         mutex_lock(&rtlpriv->locks.conf_mutex);
389         if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {  /*BIT(2)*/
390                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
391                          "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n");
392         }
393
394         /*For IPS */
395         if (changed & IEEE80211_CONF_CHANGE_IDLE) {
396                 if (hw->conf.flags & IEEE80211_CONF_IDLE)
397                         rtl_ips_nic_off(hw);
398                 else
399                         rtl_ips_nic_on(hw);
400         } else {
401                 /*
402                  *although rfoff may not cause by ips, but we will
403                  *check the reason in set_rf_power_state function
404                  */
405                 if (unlikely(ppsc->rfpwr_state == ERFOFF))
406                         rtl_ips_nic_on(hw);
407         }
408
409         /*For LPS */
410         if (changed & IEEE80211_CONF_CHANGE_PS) {
411                 cancel_delayed_work(&rtlpriv->works.ps_work);
412                 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
413                 if (conf->flags & IEEE80211_CONF_PS) {
414                         rtlpriv->psc.sw_ps_enabled = true;
415                         /* sleep here is must, or we may recv the beacon and
416                          * cause mac80211 into wrong ps state, this will cause
417                          * power save nullfunc send fail, and further cause
418                          * pkt loss, So sleep must quickly but not immediatly
419                          * because that will cause nullfunc send by mac80211
420                          * fail, and cause pkt loss, we have tested that 5mA
421                          * is worked very well */
422                         if (!rtlpriv->psc.multi_buffered)
423                                 queue_delayed_work(rtlpriv->works.rtl_wq,
424                                                 &rtlpriv->works.ps_work,
425                                                 MSECS(5));
426                 } else {
427                         rtl_swlps_rf_awake(hw);
428                         rtlpriv->psc.sw_ps_enabled = false;
429                 }
430         }
431
432         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
433                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
434                          "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
435                          hw->conf.long_frame_max_tx_count);
436                 mac->retry_long = hw->conf.long_frame_max_tx_count;
437                 mac->retry_short = hw->conf.long_frame_max_tx_count;
438                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
439                                               (u8 *) (&hw->conf.
440                                                       long_frame_max_tx_count));
441         }
442
443         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
444                 struct ieee80211_channel *channel = hw->conf.chandef.chan;
445                 u8 wide_chan = (u8) channel->hw_value;
446
447                 if (mac->act_scanning)
448                         mac->n_channels++;
449
450                 if (rtlpriv->dm.supp_phymode_switch &&
451                     mac->link_state < MAC80211_LINKED &&
452                     !mac->act_scanning) {
453                         if (rtlpriv->cfg->ops->chk_switch_dmdp)
454                                 rtlpriv->cfg->ops->chk_switch_dmdp(hw);
455                 }
456
457                 /*
458                  *because we should back channel to
459                  *current_network.chan in in scanning,
460                  *So if set_chan == current_network.chan
461                  *we should set it.
462                  *because mac80211 tell us wrong bw40
463                  *info for cisco1253 bw20, so we modify
464                  *it here based on UPPER & LOWER
465                  */
466                 switch (cfg80211_get_chandef_type(&hw->conf.chandef)) {
467                 case NL80211_CHAN_HT20:
468                 case NL80211_CHAN_NO_HT:
469                         /* SC */
470                         mac->cur_40_prime_sc =
471                                 PRIME_CHNL_OFFSET_DONT_CARE;
472                         rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
473                         mac->bw_40 = false;
474                         break;
475                 case NL80211_CHAN_HT40MINUS:
476                         /* SC */
477                         mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
478                         rtlphy->current_chan_bw =
479                                 HT_CHANNEL_WIDTH_20_40;
480                         mac->bw_40 = true;
481
482                         /*wide channel */
483                         wide_chan -= 2;
484
485                         break;
486                 case NL80211_CHAN_HT40PLUS:
487                         /* SC */
488                         mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
489                         rtlphy->current_chan_bw =
490                                 HT_CHANNEL_WIDTH_20_40;
491                         mac->bw_40 = true;
492
493                         /*wide channel */
494                         wide_chan += 2;
495
496                         break;
497                 default:
498                         mac->bw_40 = false;
499                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
500                                  "switch case not processed\n");
501                         break;
502                 }
503
504                 if (wide_chan <= 0)
505                         wide_chan = 1;
506
507                 /* In scanning, before we go offchannel we may send a ps = 1
508                  * null to AP, and then we may send a ps = 0 null to AP quickly,
509                  * but first null may have caused AP to put lots of packet to
510                  * hw tx buffer. These packets must be tx'd before we go off
511                  * channel so we must delay more time to let AP flush these
512                  * packets before going offchannel, or dis-association or
513                  * delete BA will be caused by AP
514                  */
515                 if (rtlpriv->mac80211.offchan_delay) {
516                         rtlpriv->mac80211.offchan_delay = false;
517                         mdelay(50);
518                 }
519                 rtlphy->current_channel = wide_chan;
520
521                 rtlpriv->cfg->ops->switch_channel(hw);
522                 rtlpriv->cfg->ops->set_channel_access(hw);
523                 rtlpriv->cfg->ops->set_bw_mode(hw,
524                                 cfg80211_get_chandef_type(&hw->conf.chandef));
525         }
526
527         mutex_unlock(&rtlpriv->locks.conf_mutex);
528
529         return 0;
530 }
531
532 static void rtl_op_configure_filter(struct ieee80211_hw *hw,
533                              unsigned int changed_flags,
534                              unsigned int *new_flags, u64 multicast)
535 {
536         struct rtl_priv *rtlpriv = rtl_priv(hw);
537         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
538         u32 rx_conf;
539
540         *new_flags &= RTL_SUPPORTED_FILTERS;
541         if (!changed_flags)
542                 return;
543
544         /* if ssid not set to hw don't check bssid
545          * here just used for linked scanning, & linked
546          * and nolink check bssid is set in set network_type */
547         if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
548                 (mac->link_state >= MAC80211_LINKED)) {
549                 if (mac->opmode != NL80211_IFTYPE_AP &&
550                     mac->opmode != NL80211_IFTYPE_MESH_POINT) {
551                         if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
552                                 rtlpriv->cfg->ops->set_chk_bssid(hw, false);
553                         } else {
554                                 rtlpriv->cfg->ops->set_chk_bssid(hw, true);
555                         }
556                 }
557         }
558
559         /* must be called after set_chk_bssid since that function modifies the
560          * RCR register too. */
561         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf));
562
563         /*TODO: we disable broadcase now, so enable here */
564         if (changed_flags & FIF_ALLMULTI) {
565                 if (*new_flags & FIF_ALLMULTI) {
566                         rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
567                             rtlpriv->cfg->maps[MAC_RCR_AB];
568                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
569                                  "Enable receive multicast frame\n");
570                 } else {
571                         rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
572                                           rtlpriv->cfg->maps[MAC_RCR_AB]);
573                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
574                                  "Disable receive multicast frame\n");
575                 }
576         }
577
578         if (changed_flags & FIF_FCSFAIL) {
579                 if (*new_flags & FIF_FCSFAIL) {
580                         rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
581                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
582                                  "Enable receive FCS error frame\n");
583                 } else {
584                         rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
585                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
586                                  "Disable receive FCS error frame\n");
587                 }
588         }
589
590
591         if (changed_flags & FIF_CONTROL) {
592                 if (*new_flags & FIF_CONTROL) {
593                         rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
594
595                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
596                                  "Enable receive control frame\n");
597                 } else {
598                         rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
599                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
600                                  "Disable receive control frame\n");
601                 }
602         }
603
604         if (changed_flags & FIF_OTHER_BSS) {
605                 if (*new_flags & FIF_OTHER_BSS) {
606                         rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
607                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
608                                  "Enable receive other BSS's frame\n");
609                 } else {
610                         rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
611                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
612                                  "Disable receive other BSS's frame\n");
613                 }
614         }
615
616         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf));
617 }
618 static int rtl_op_sta_add(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_hal *rtlhal = rtl_hal(rtl_priv(hw));
624         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
625         struct rtl_sta_info *sta_entry;
626
627         if (sta) {
628                 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
629                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
630                 list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
631                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
632                 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
633                         sta_entry->wireless_mode = WIRELESS_MODE_G;
634                         if (sta->supp_rates[0] <= 0xf)
635                                 sta_entry->wireless_mode = WIRELESS_MODE_B;
636                         if (sta->ht_cap.ht_supported == true)
637                                 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
638
639                         if (vif->type == NL80211_IFTYPE_ADHOC)
640                                 sta_entry->wireless_mode = WIRELESS_MODE_G;
641                 } else if (rtlhal->current_bandtype == BAND_ON_5G) {
642                         sta_entry->wireless_mode = WIRELESS_MODE_A;
643                         if (sta->ht_cap.ht_supported == true)
644                                 sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
645
646                         if (vif->type == NL80211_IFTYPE_ADHOC)
647                                 sta_entry->wireless_mode = WIRELESS_MODE_A;
648                 }
649                 /*disable cck rate for p2p*/
650                 if (mac->p2p)
651                         sta->supp_rates[0] &= 0xfffffff0;
652
653                 memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
654                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
655                          "Add sta addr is %pM\n", sta->addr);
656                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
657         }
658         return 0;
659 }
660
661 static int rtl_op_sta_remove(struct ieee80211_hw *hw,
662                                 struct ieee80211_vif *vif,
663                                 struct ieee80211_sta *sta)
664 {
665         struct rtl_priv *rtlpriv = rtl_priv(hw);
666         struct rtl_sta_info *sta_entry;
667         if (sta) {
668                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
669                          "Remove sta addr is %pM\n", sta->addr);
670                 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
671                 sta_entry->wireless_mode = 0;
672                 sta_entry->ratr_index = 0;
673
674                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
675                 list_del(&sta_entry->list);
676                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
677         }
678         return 0;
679 }
680
681 static int _rtl_get_hal_qnum(u16 queue)
682 {
683         int qnum;
684
685         switch (queue) {
686         case 0:
687                 qnum = AC3_VO;
688                 break;
689         case 1:
690                 qnum = AC2_VI;
691                 break;
692         case 2:
693                 qnum = AC0_BE;
694                 break;
695         case 3:
696                 qnum = AC1_BK;
697                 break;
698         default:
699                 qnum = AC0_BE;
700                 break;
701         }
702         return qnum;
703 }
704
705 /*
706  *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3
707  *for rtl819x  BE = 0, BK = 1, VI = 2, VO = 3
708  */
709 static int rtl_op_conf_tx(struct ieee80211_hw *hw,
710                    struct ieee80211_vif *vif, u16 queue,
711                    const struct ieee80211_tx_queue_params *param)
712 {
713         struct rtl_priv *rtlpriv = rtl_priv(hw);
714         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
715         int aci;
716
717         if (queue >= AC_MAX) {
718                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
719                          "queue number %d is incorrect!\n", queue);
720                 return -EINVAL;
721         }
722
723         aci = _rtl_get_hal_qnum(queue);
724         mac->ac[aci].aifs = param->aifs;
725         mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);
726         mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);
727         mac->ac[aci].tx_op = cpu_to_le16(param->txop);
728         memcpy(&mac->edca_param[aci], param, sizeof(*param));
729         rtlpriv->cfg->ops->set_qos(hw, aci);
730         return 0;
731 }
732
733 static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
734                              struct ieee80211_vif *vif,
735                              struct ieee80211_bss_conf *bss_conf, u32 changed)
736 {
737         struct rtl_priv *rtlpriv = rtl_priv(hw);
738         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
739         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
740         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
741         struct ieee80211_sta *sta = NULL;
742
743         mutex_lock(&rtlpriv->locks.conf_mutex);
744         if ((vif->type == NL80211_IFTYPE_ADHOC) ||
745             (vif->type == NL80211_IFTYPE_AP) ||
746             (vif->type == NL80211_IFTYPE_MESH_POINT)) {
747                 if ((changed & BSS_CHANGED_BEACON) ||
748                     (changed & BSS_CHANGED_BEACON_ENABLED &&
749                      bss_conf->enable_beacon)) {
750                         if (mac->beacon_enabled == 0) {
751                                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
752                                          "BSS_CHANGED_BEACON_ENABLED\n");
753
754                                 /*start hw beacon interrupt. */
755                                 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
756                                 mac->beacon_enabled = 1;
757                                 rtlpriv->cfg->ops->update_interrupt_mask(hw,
758                                                 rtlpriv->cfg->maps
759                                                 [RTL_IBSS_INT_MASKS],
760                                                 0);
761
762                                 if (rtlpriv->cfg->ops->linked_set_reg)
763                                         rtlpriv->cfg->ops->linked_set_reg(hw);
764                         }
765                 }
766                 if ((changed & BSS_CHANGED_BEACON_ENABLED &&
767                         !bss_conf->enable_beacon)) {
768                         if (mac->beacon_enabled == 1) {
769                                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
770                                          "ADHOC DISABLE BEACON\n");
771
772                                 mac->beacon_enabled = 0;
773                                 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
774                                                 rtlpriv->cfg->maps
775                                                 [RTL_IBSS_INT_MASKS]);
776                         }
777                 }
778                 if (changed & BSS_CHANGED_BEACON_INT) {
779                         RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
780                                  "BSS_CHANGED_BEACON_INT\n");
781                         mac->beacon_interval = bss_conf->beacon_int;
782                         rtlpriv->cfg->ops->set_bcn_intv(hw);
783                 }
784         }
785
786         /*TODO: reference to enum ieee80211_bss_change */
787         if (changed & BSS_CHANGED_ASSOC) {
788                 if (bss_conf->assoc) {
789                         struct ieee80211_sta *sta = NULL;
790                         /* we should reset all sec info & cam
791                          * before set cam after linked, we should not
792                          * reset in disassoc, that will cause tkip->wep
793                          * fail because some flag will be wrong */
794                         /* reset sec info */
795                         rtl_cam_reset_sec_info(hw);
796                         /* reset cam to fix wep fail issue
797                          * when change from wpa to wep */
798                         rtl_cam_reset_all_entry(hw);
799
800                         mac->link_state = MAC80211_LINKED;
801                         mac->cnt_after_linked = 0;
802                         mac->assoc_id = bss_conf->aid;
803                         memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);
804
805                         if (rtlpriv->cfg->ops->linked_set_reg)
806                                 rtlpriv->cfg->ops->linked_set_reg(hw);
807                         rcu_read_lock();
808                         sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid);
809                         if (!sta) {
810                                 pr_err("ieee80211_find_sta returned NULL\n");
811                                 rcu_read_unlock();
812                                 goto out;
813                         }
814
815                         if (vif->type == NL80211_IFTYPE_STATION && sta)
816                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
817                         RT_TRACE(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD,
818                                  "send PS STATIC frame\n");
819                         if (rtlpriv->dm.supp_phymode_switch) {
820                                 if (sta->ht_cap.ht_supported)
821                                         rtl_send_smps_action(hw, sta,
822                                                  IEEE80211_SMPS_STATIC);
823                         }
824                         rcu_read_unlock();
825
826                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
827                                  "BSS_CHANGED_ASSOC\n");
828                 } else {
829                         if (mac->link_state == MAC80211_LINKED) {
830                                 rtlpriv->enter_ps = false;
831                                 schedule_work(&rtlpriv->works.lps_change_work);
832                         }
833
834                         if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
835                                 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
836                         mac->link_state = MAC80211_NOLINK;
837                         memset(mac->bssid, 0, ETH_ALEN);
838                         mac->vendor = PEER_UNKNOWN;
839
840                         if (rtlpriv->dm.supp_phymode_switch) {
841                                 if (rtlpriv->cfg->ops->chk_switch_dmdp)
842                                         rtlpriv->cfg->ops->chk_switch_dmdp(hw);
843                         }
844
845                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
846                                  "BSS_CHANGED_UN_ASSOC\n");
847                 }
848         }
849
850         if (changed & BSS_CHANGED_ERP_CTS_PROT) {
851                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
852                          "BSS_CHANGED_ERP_CTS_PROT\n");
853                 mac->use_cts_protect = bss_conf->use_cts_prot;
854         }
855
856         if (changed & BSS_CHANGED_ERP_PREAMBLE) {
857                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
858                          "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
859                          bss_conf->use_short_preamble);
860
861                 mac->short_preamble = bss_conf->use_short_preamble;
862                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
863                                               &mac->short_preamble);
864         }
865
866         if (changed & BSS_CHANGED_ERP_SLOT) {
867                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
868                          "BSS_CHANGED_ERP_SLOT\n");
869
870                 if (bss_conf->use_short_slot)
871                         mac->slot_time = RTL_SLOT_TIME_9;
872                 else
873                         mac->slot_time = RTL_SLOT_TIME_20;
874
875                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
876                                               &mac->slot_time);
877         }
878
879         if (changed & BSS_CHANGED_HT) {
880                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n");
881                 rcu_read_lock();
882                 sta = get_sta(hw, vif, bss_conf->bssid);
883                 if (sta) {
884                         if (sta->ht_cap.ampdu_density >
885                             mac->current_ampdu_density)
886                                 mac->current_ampdu_density =
887                                     sta->ht_cap.ampdu_density;
888                         if (sta->ht_cap.ampdu_factor <
889                             mac->current_ampdu_factor)
890                                 mac->current_ampdu_factor =
891                                     sta->ht_cap.ampdu_factor;
892                 }
893                 rcu_read_unlock();
894
895                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
896                                               &mac->max_mss_density);
897                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
898                                               &mac->current_ampdu_factor);
899                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
900                                               &mac->current_ampdu_density);
901         }
902
903         if (changed & BSS_CHANGED_BSSID) {
904                 u32 basic_rates;
905
906                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
907                                               (u8 *) bss_conf->bssid);
908
909                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n",
910                          bss_conf->bssid);
911
912                 mac->vendor = PEER_UNKNOWN;
913                 memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);
914                 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
915
916                 rcu_read_lock();
917                 sta = get_sta(hw, vif, bss_conf->bssid);
918                 if (!sta) {
919                         rcu_read_unlock();
920                         goto out;
921                 }
922
923                 if (rtlhal->current_bandtype == BAND_ON_5G) {
924                         mac->mode = WIRELESS_MODE_A;
925                 } else {
926                         if (sta->supp_rates[0] <= 0xf)
927                                 mac->mode = WIRELESS_MODE_B;
928                         else
929                                 mac->mode = WIRELESS_MODE_G;
930                 }
931
932                 if (sta->ht_cap.ht_supported) {
933                         if (rtlhal->current_bandtype == BAND_ON_2_4G)
934                                 mac->mode = WIRELESS_MODE_N_24G;
935                         else
936                                 mac->mode = WIRELESS_MODE_N_5G;
937                 }
938
939                 /* just station need it, because ibss & ap mode will
940                  * set in sta_add, and will be NULL here */
941                 if (mac->opmode == NL80211_IFTYPE_STATION) {
942                         struct rtl_sta_info *sta_entry;
943                         sta_entry = (struct rtl_sta_info *) sta->drv_priv;
944                         sta_entry->wireless_mode = mac->mode;
945                 }
946
947                 if (sta->ht_cap.ht_supported) {
948                         mac->ht_enable = true;
949
950                         /*
951                          * for cisco 1252 bw20 it's wrong
952                          * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
953                          *      mac->bw_40 = true;
954                          * }
955                          * */
956                 }
957
958                 if (changed & BSS_CHANGED_BASIC_RATES) {
959                         /* for 5G must << RATE_6M_INDEX = 4,
960                          * because 5G have no cck rate*/
961                         if (rtlhal->current_bandtype == BAND_ON_5G)
962                                 basic_rates = sta->supp_rates[1] << 4;
963                         else
964                                 basic_rates = sta->supp_rates[0];
965
966                         mac->basic_rates = basic_rates;
967                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
968                                         (u8 *)(&basic_rates));
969                 }
970                 rcu_read_unlock();
971         }
972
973         /*
974          * For FW LPS:
975          * To tell firmware we have connected
976          * to an AP. For 92SE/CE power save v2.
977          */
978         if (changed & BSS_CHANGED_ASSOC) {
979                 if (bss_conf->assoc) {
980                         if (ppsc->fwctrl_lps) {
981                                 u8 mstatus = RT_MEDIA_CONNECT;
982                                 u8 keep_alive = 10;
983                                 rtlpriv->cfg->ops->set_hw_reg(hw,
984                                                  HW_VAR_KEEP_ALIVE,
985                                                  &keep_alive);
986
987                                 rtlpriv->cfg->ops->set_hw_reg(hw,
988                                                       HW_VAR_H2C_FW_JOINBSSRPT,
989                                                       &mstatus);
990                                 ppsc->report_linked = true;
991                         }
992                 } else {
993                         if (ppsc->fwctrl_lps) {
994                                 u8 mstatus = RT_MEDIA_DISCONNECT;
995                                 rtlpriv->cfg->ops->set_hw_reg(hw,
996                                                       HW_VAR_H2C_FW_JOINBSSRPT,
997                                                       &mstatus);
998                                 ppsc->report_linked = false;
999                         }
1000                 }
1001                 if (rtlpriv->cfg->ops->bt_wifi_media_status_notify)
1002                         rtlpriv->cfg->ops->bt_wifi_media_status_notify(hw,
1003                                                          ppsc->report_linked);
1004         }
1005
1006 out:
1007         mutex_unlock(&rtlpriv->locks.conf_mutex);
1008 }
1009
1010 static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1011 {
1012         struct rtl_priv *rtlpriv = rtl_priv(hw);
1013         u64 tsf;
1014
1015         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
1016         return tsf;
1017 }
1018
1019 static void rtl_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1020                            u64 tsf)
1021 {
1022         struct rtl_priv *rtlpriv = rtl_priv(hw);
1023         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1024         u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
1025
1026         mac->tsf = tsf;
1027         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, &bibss);
1028 }
1029
1030 static void rtl_op_reset_tsf(struct ieee80211_hw *hw,
1031                              struct ieee80211_vif *vif)
1032 {
1033         struct rtl_priv *rtlpriv = rtl_priv(hw);
1034         u8 tmp = 0;
1035
1036         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, &tmp);
1037 }
1038
1039 static void rtl_op_sta_notify(struct ieee80211_hw *hw,
1040                               struct ieee80211_vif *vif,
1041                               enum sta_notify_cmd cmd,
1042                               struct ieee80211_sta *sta)
1043 {
1044         switch (cmd) {
1045         case STA_NOTIFY_SLEEP:
1046                 break;
1047         case STA_NOTIFY_AWAKE:
1048                 break;
1049         default:
1050                 break;
1051         }
1052 }
1053
1054 static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
1055                                struct ieee80211_vif *vif,
1056                                enum ieee80211_ampdu_mlme_action action,
1057                                struct ieee80211_sta *sta, u16 tid, u16 *ssn,
1058                                u8 buf_size)
1059 {
1060         struct rtl_priv *rtlpriv = rtl_priv(hw);
1061
1062         switch (action) {
1063         case IEEE80211_AMPDU_TX_START:
1064                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
1065                          "IEEE80211_AMPDU_TX_START: TID:%d\n", tid);
1066                 return rtl_tx_agg_start(hw, sta, tid, ssn);
1067         case IEEE80211_AMPDU_TX_STOP_CONT:
1068         case IEEE80211_AMPDU_TX_STOP_FLUSH:
1069         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1070                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
1071                          "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);
1072                 return rtl_tx_agg_stop(hw, sta, tid);
1073         case IEEE80211_AMPDU_TX_OPERATIONAL:
1074                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
1075                          "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);
1076                 rtl_tx_agg_oper(hw, sta, tid);
1077                 break;
1078         case IEEE80211_AMPDU_RX_START:
1079                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
1080                          "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);
1081                 return rtl_rx_agg_start(hw, sta, tid);
1082         case IEEE80211_AMPDU_RX_STOP:
1083                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
1084                          "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
1085                 return rtl_rx_agg_stop(hw, sta, tid);
1086         default:
1087                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1088                          "IEEE80211_AMPDU_ERR!!!!:\n");
1089                 return -EOPNOTSUPP;
1090         }
1091         return 0;
1092 }
1093
1094 static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
1095 {
1096         struct rtl_priv *rtlpriv = rtl_priv(hw);
1097         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1098
1099         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
1100         mac->act_scanning = true;
1101         if (rtlpriv->link_info.higher_busytraffic) {
1102                 mac->skip_scan = true;
1103                 return;
1104         }
1105
1106         if (rtlpriv->dm.supp_phymode_switch) {
1107                 if (rtlpriv->cfg->ops->chk_switch_dmdp)
1108                         rtlpriv->cfg->ops->chk_switch_dmdp(hw);
1109         }
1110         if (mac->link_state == MAC80211_LINKED) {
1111                 rtlpriv->enter_ps = false;
1112                 schedule_work(&rtlpriv->works.lps_change_work);
1113                 mac->link_state = MAC80211_LINKED_SCANNING;
1114         } else {
1115                 rtl_ips_nic_on(hw);
1116         }
1117
1118         /* Dual mac */
1119         rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
1120
1121         rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
1122         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
1123 }
1124
1125 static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
1126 {
1127         struct rtl_priv *rtlpriv = rtl_priv(hw);
1128         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1129
1130         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
1131         mac->act_scanning = false;
1132         mac->skip_scan = false;
1133         if (rtlpriv->link_info.higher_busytraffic)
1134                 return;
1135
1136         /*p2p will use 1/6/11 to scan */
1137         if (mac->n_channels == 3)
1138                 mac->p2p_in_use = true;
1139         else
1140                 mac->p2p_in_use = false;
1141         mac->n_channels = 0;
1142         /* Dual mac */
1143         rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
1144
1145         if (mac->link_state == MAC80211_LINKED_SCANNING) {
1146                 mac->link_state = MAC80211_LINKED;
1147                 if (mac->opmode == NL80211_IFTYPE_STATION) {
1148                         /* fix fwlps issue */
1149                         rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
1150                 }
1151         }
1152
1153         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
1154 }
1155
1156 static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1157                           struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1158                           struct ieee80211_key_conf *key)
1159 {
1160         struct rtl_priv *rtlpriv = rtl_priv(hw);
1161         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1162         u8 key_type = NO_ENCRYPTION;
1163         u8 key_idx;
1164         bool group_key = false;
1165         bool wep_only = false;
1166         int err = 0;
1167         u8 mac_addr[ETH_ALEN];
1168         u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1169
1170         if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1171                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1172                          "not open hw encryption\n");
1173                 return -ENOSPC; /*User disabled HW-crypto */
1174         }
1175         /* To support IBSS, use sw-crypto for GTK */
1176         if (((vif->type == NL80211_IFTYPE_ADHOC) ||
1177              (vif->type == NL80211_IFTYPE_MESH_POINT)) &&
1178               !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1179                 return -ENOSPC;
1180         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1181                  "%s hardware based encryption for keyidx: %d, mac: %pM\n",
1182                  cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
1183                  sta ? sta->addr : bcast_addr);
1184         rtlpriv->sec.being_setkey = true;
1185         rtl_ips_nic_on(hw);
1186         mutex_lock(&rtlpriv->locks.conf_mutex);
1187         /* <1> get encryption alg */
1188
1189         switch (key->cipher) {
1190         case WLAN_CIPHER_SUITE_WEP40:
1191                 key_type = WEP40_ENCRYPTION;
1192                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n");
1193                 break;
1194         case WLAN_CIPHER_SUITE_WEP104:
1195                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n");
1196                 key_type = WEP104_ENCRYPTION;
1197                 break;
1198         case WLAN_CIPHER_SUITE_TKIP:
1199                 key_type = TKIP_ENCRYPTION;
1200                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n");
1201                 break;
1202         case WLAN_CIPHER_SUITE_CCMP:
1203                 key_type = AESCCMP_ENCRYPTION;
1204                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");
1205                 break;
1206         case WLAN_CIPHER_SUITE_AES_CMAC:
1207                 /*HW doesn't support CMAC encryption, use software CMAC */
1208                 key_type = AESCMAC_ENCRYPTION;
1209                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n");
1210                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1211                          "HW don't support CMAC encryption, use software CMAC\n");
1212                 err = -EOPNOTSUPP;
1213                 goto out_unlock;
1214         default:
1215                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n",
1216                          key->cipher);
1217                 goto out_unlock;
1218         }
1219         if (key_type == WEP40_ENCRYPTION ||
1220                         key_type == WEP104_ENCRYPTION ||
1221                         mac->opmode == NL80211_IFTYPE_ADHOC)
1222                 rtlpriv->sec.use_defaultkey = true;
1223
1224         /* <2> get key_idx */
1225         key_idx = (u8) (key->keyidx);
1226         if (key_idx > 3)
1227                 goto out_unlock;
1228         /* <3> if pairwise key enable_hw_sec */
1229         group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
1230
1231         /* wep always be group key, but there are two conditions:
1232          * 1) wep only: is just for wep enc, in this condition
1233          * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
1234          * will be true & enable_hw_sec will be set when wep
1235          * key setting.
1236          * 2) wep(group) + AES(pairwise): some AP like cisco
1237          * may use it, in this condition enable_hw_sec will not
1238          * be set when wep key setting */
1239         /* we must reset sec_info after lingked before set key,
1240          * or some flag will be wrong*/
1241         if (vif->type == NL80211_IFTYPE_AP ||
1242             vif->type == NL80211_IFTYPE_MESH_POINT) {
1243                 if (!group_key || key_type == WEP40_ENCRYPTION ||
1244                         key_type == WEP104_ENCRYPTION) {
1245                         if (group_key)
1246                                 wep_only = true;
1247                         rtlpriv->cfg->ops->enable_hw_sec(hw);
1248                 }
1249         } else {
1250                 if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
1251                      rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
1252                         if (rtlpriv->sec.pairwise_enc_algorithm ==
1253                             NO_ENCRYPTION &&
1254                             (key_type == WEP40_ENCRYPTION ||
1255                             key_type == WEP104_ENCRYPTION))
1256                                 wep_only = true;
1257                         rtlpriv->sec.pairwise_enc_algorithm = key_type;
1258                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1259                                  "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n",
1260                                  key_type);
1261                         rtlpriv->cfg->ops->enable_hw_sec(hw);
1262                 }
1263         }
1264         /* <4> set key based on cmd */
1265         switch (cmd) {
1266         case SET_KEY:
1267                 if (wep_only) {
1268                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1269                                  "set WEP(group/pairwise) key\n");
1270                         /* Pairwise key with an assigned MAC address. */
1271                         rtlpriv->sec.pairwise_enc_algorithm = key_type;
1272                         rtlpriv->sec.group_enc_algorithm = key_type;
1273                         /*set local buf about wep key. */
1274                         memcpy(rtlpriv->sec.key_buf[key_idx],
1275                                key->key, key->keylen);
1276                         rtlpriv->sec.key_len[key_idx] = key->keylen;
1277                         eth_zero_addr(mac_addr);
1278                 } else if (group_key) { /* group key */
1279                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1280                                  "set group key\n");
1281                         /* group key */
1282                         rtlpriv->sec.group_enc_algorithm = key_type;
1283                         /*set local buf about group key. */
1284                         memcpy(rtlpriv->sec.key_buf[key_idx],
1285                                key->key, key->keylen);
1286                         rtlpriv->sec.key_len[key_idx] = key->keylen;
1287                         memcpy(mac_addr, bcast_addr, ETH_ALEN);
1288                 } else {        /* pairwise key */
1289                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1290                                  "set pairwise key\n");
1291                         if (!sta) {
1292                                 RT_ASSERT(false,
1293                                           "pairwise key without mac_addr\n");
1294
1295                                 err = -EOPNOTSUPP;
1296                                 goto out_unlock;
1297                         }
1298                         /* Pairwise key with an assigned MAC address. */
1299                         rtlpriv->sec.pairwise_enc_algorithm = key_type;
1300                         /*set local buf about pairwise key. */
1301                         memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
1302                                key->key, key->keylen);
1303                         rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
1304                         rtlpriv->sec.pairwise_key =
1305                             rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
1306                         memcpy(mac_addr, sta->addr, ETH_ALEN);
1307                 }
1308                 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
1309                                            group_key, key_type, wep_only,
1310                                            false);
1311                 /* <5> tell mac80211 do something: */
1312                 /*must use sw generate IV, or can not work !!!!. */
1313                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1314                 key->hw_key_idx = key_idx;
1315                 if (key_type == TKIP_ENCRYPTION)
1316                         key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1317                 /*use software CCMP encryption for management frames (MFP) */
1318                 if (key_type == AESCCMP_ENCRYPTION)
1319                         key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1320                 break;
1321         case DISABLE_KEY:
1322                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1323                          "disable key delete one entry\n");
1324                 /*set local buf about wep key. */
1325                 if (vif->type == NL80211_IFTYPE_AP ||
1326                     vif->type == NL80211_IFTYPE_MESH_POINT) {
1327                         if (sta)
1328                                 rtl_cam_del_entry(hw, sta->addr);
1329                 }
1330                 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
1331                 rtlpriv->sec.key_len[key_idx] = 0;
1332                 eth_zero_addr(mac_addr);
1333                 /*
1334                  *mac80211 will delete entrys one by one,
1335                  *so don't use rtl_cam_reset_all_entry
1336                  *or clear all entry here.
1337                  */
1338                 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
1339
1340                 rtl_cam_reset_sec_info(hw);
1341
1342                 break;
1343         default:
1344                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1345                          "cmd_err:%x!!!!\n", cmd);
1346         }
1347 out_unlock:
1348         mutex_unlock(&rtlpriv->locks.conf_mutex);
1349         rtlpriv->sec.being_setkey = false;
1350         return err;
1351 }
1352
1353 static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1354 {
1355         struct rtl_priv *rtlpriv = rtl_priv(hw);
1356
1357         bool radio_state;
1358         bool blocked;
1359         u8 valid = 0;
1360
1361         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
1362                 return;
1363
1364         mutex_lock(&rtlpriv->locks.conf_mutex);
1365
1366         /*if Radio On return true here */
1367         radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
1368
1369         if (valid) {
1370                 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
1371                         rtlpriv->rfkill.rfkill_state = radio_state;
1372
1373                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1374                                  "wireless radio switch turned %s\n",
1375                                  radio_state ? "on" : "off");
1376
1377                         blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
1378                         wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1379                 }
1380         }
1381
1382         mutex_unlock(&rtlpriv->locks.conf_mutex);
1383 }
1384
1385 /* this function is called by mac80211 to flush tx buffer
1386  * before switch channel or power save, or tx buffer packet
1387  * maybe send after offchannel or rf sleep, this may cause
1388  * dis-association by AP */
1389 static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1390                          u32 queues, bool drop)
1391 {
1392         struct rtl_priv *rtlpriv = rtl_priv(hw);
1393
1394         if (rtlpriv->intf_ops->flush)
1395                 rtlpriv->intf_ops->flush(hw, drop);
1396 }
1397
1398 const struct ieee80211_ops rtl_ops = {
1399         .start = rtl_op_start,
1400         .stop = rtl_op_stop,
1401         .tx = rtl_op_tx,
1402         .add_interface = rtl_op_add_interface,
1403         .remove_interface = rtl_op_remove_interface,
1404         .change_interface = rtl_op_change_interface,
1405         .config = rtl_op_config,
1406         .configure_filter = rtl_op_configure_filter,
1407         .sta_add = rtl_op_sta_add,
1408         .sta_remove = rtl_op_sta_remove,
1409         .set_key = rtl_op_set_key,
1410         .conf_tx = rtl_op_conf_tx,
1411         .bss_info_changed = rtl_op_bss_info_changed,
1412         .get_tsf = rtl_op_get_tsf,
1413         .set_tsf = rtl_op_set_tsf,
1414         .reset_tsf = rtl_op_reset_tsf,
1415         .sta_notify = rtl_op_sta_notify,
1416         .ampdu_action = rtl_op_ampdu_action,
1417         .sw_scan_start = rtl_op_sw_scan_start,
1418         .sw_scan_complete = rtl_op_sw_scan_complete,
1419         .rfkill_poll = rtl_op_rfkill_poll,
1420         .flush = rtl_op_flush,
1421 };
1422 EXPORT_SYMBOL_GPL(rtl_ops);