treewide: remove extra semicolons
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtlwifi / 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 #include "wifi.h"
30 #include "core.h"
31 #include "cam.h"
32 #include "base.h"
33 #include "ps.h"
34
35 /*mutex for start & stop is must here. */
36 static int rtl_op_start(struct ieee80211_hw *hw)
37 {
38         int err = 0;
39         struct rtl_priv *rtlpriv = rtl_priv(hw);
40         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
41
42         if (!is_hal_stop(rtlhal))
43                 return 0;
44         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
45                 return 0;
46         mutex_lock(&rtlpriv->locks.conf_mutex);
47         err = rtlpriv->intf_ops->adapter_start(hw);
48         if (err)
49                 goto out;
50         rtl_watch_dog_timer_callback((unsigned long)hw);
51 out:
52         mutex_unlock(&rtlpriv->locks.conf_mutex);
53         return err;
54 }
55
56 static void rtl_op_stop(struct ieee80211_hw *hw)
57 {
58         struct rtl_priv *rtlpriv = rtl_priv(hw);
59         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
60         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
61         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
62
63         if (is_hal_stop(rtlhal))
64                 return;
65
66         if (unlikely(ppsc->rfpwr_state == ERFOFF)) {
67                 rtl_ips_nic_on(hw);
68                 mdelay(1);
69         }
70
71         mutex_lock(&rtlpriv->locks.conf_mutex);
72
73         mac->link_state = MAC80211_NOLINK;
74         memset(mac->bssid, 0, 6);
75
76         /*reset sec info */
77         rtl_cam_reset_sec_info(hw);
78
79         rtl_deinit_deferred_work(hw);
80         rtlpriv->intf_ops->adapter_stop(hw);
81
82         mutex_unlock(&rtlpriv->locks.conf_mutex);
83 }
84
85 static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
86 {
87         struct rtl_priv *rtlpriv = rtl_priv(hw);
88         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
89         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
90
91         if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
92                 goto err_free;
93
94         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
95                 goto err_free;
96
97
98         rtlpriv->intf_ops->adapter_tx(hw, skb);
99
100         return;
101
102 err_free:
103         dev_kfree_skb_any(skb);
104 }
105
106 static int rtl_op_add_interface(struct ieee80211_hw *hw,
107                 struct ieee80211_vif *vif)
108 {
109         struct rtl_priv *rtlpriv = rtl_priv(hw);
110         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
111         int err = 0;
112
113         if (mac->vif) {
114                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
115                          ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
116                 return -EOPNOTSUPP;
117         }
118
119         rtl_ips_nic_on(hw);
120
121         mutex_lock(&rtlpriv->locks.conf_mutex);
122         switch (vif->type) {
123         case NL80211_IFTYPE_STATION:
124                 if (mac->beacon_enabled == 1) {
125                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
126                                  ("NL80211_IFTYPE_STATION\n"));
127                         mac->beacon_enabled = 0;
128                         rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
129                                         rtlpriv->cfg->maps
130                                         [RTL_IBSS_INT_MASKS]);
131                 }
132                 break;
133         case NL80211_IFTYPE_ADHOC:
134                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
135                          ("NL80211_IFTYPE_ADHOC\n"));
136
137                 mac->link_state = MAC80211_LINKED;
138                 rtlpriv->cfg->ops->set_bcn_reg(hw);
139                 break;
140         case NL80211_IFTYPE_AP:
141                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
142                          ("NL80211_IFTYPE_AP\n"));
143                 break;
144         default:
145                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
146                          ("operation mode %d is not support!\n", vif->type));
147                 err = -EOPNOTSUPP;
148                 goto out;
149         }
150
151         mac->vif = vif;
152         mac->opmode = vif->type;
153         rtlpriv->cfg->ops->set_network_type(hw, vif->type);
154         memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
155         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
156
157 out:
158         mutex_unlock(&rtlpriv->locks.conf_mutex);
159         return err;
160 }
161
162 static void rtl_op_remove_interface(struct ieee80211_hw *hw,
163                 struct ieee80211_vif *vif)
164 {
165         struct rtl_priv *rtlpriv = rtl_priv(hw);
166         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
167
168         mutex_lock(&rtlpriv->locks.conf_mutex);
169
170         /* Free beacon resources */
171         if ((mac->opmode == NL80211_IFTYPE_AP) ||
172             (mac->opmode == NL80211_IFTYPE_ADHOC) ||
173             (mac->opmode == NL80211_IFTYPE_MESH_POINT)) {
174                 if (mac->beacon_enabled == 1) {
175                         mac->beacon_enabled = 0;
176                         rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
177                                         rtlpriv->cfg->maps
178                                         [RTL_IBSS_INT_MASKS]);
179                 }
180         }
181
182         /*
183          *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
184          *NO LINK for our hardware.
185          */
186         mac->vif = NULL;
187         mac->link_state = MAC80211_NOLINK;
188         memset(mac->bssid, 0, 6);
189         mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
190         rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
191
192         mutex_unlock(&rtlpriv->locks.conf_mutex);
193 }
194
195
196 static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
197 {
198         struct rtl_priv *rtlpriv = rtl_priv(hw);
199         struct rtl_phy *rtlphy = &(rtlpriv->phy);
200         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
201         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
202         struct ieee80211_conf *conf = &hw->conf;
203
204         mutex_lock(&rtlpriv->locks.conf_mutex);
205         if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {  /*BIT(2)*/
206                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
207                          ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
208         }
209
210         /*For IPS */
211         if (changed & IEEE80211_CONF_CHANGE_IDLE) {
212                 if (hw->conf.flags & IEEE80211_CONF_IDLE)
213                         rtl_ips_nic_off(hw);
214                 else
215                         rtl_ips_nic_on(hw);
216         } else {
217                 /*
218                  *although rfoff may not cause by ips, but we will
219                  *check the reason in set_rf_power_state function
220                  */
221                 if (unlikely(ppsc->rfpwr_state == ERFOFF))
222                         rtl_ips_nic_on(hw);
223         }
224
225         /*For LPS */
226         if (changed & IEEE80211_CONF_CHANGE_PS) {
227                 if (conf->flags & IEEE80211_CONF_PS)
228                         rtl_lps_enter(hw);
229                 else
230                         rtl_lps_leave(hw);
231         }
232
233         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
234                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
235                          ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
236                           hw->conf.long_frame_max_tx_count));
237                 mac->retry_long = hw->conf.long_frame_max_tx_count;
238                 mac->retry_short = hw->conf.long_frame_max_tx_count;
239                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
240                                               (u8 *) (&hw->conf.
241                                                       long_frame_max_tx_count));
242         }
243
244         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
245                 struct ieee80211_channel *channel = hw->conf.channel;
246                 u8 wide_chan = (u8) channel->hw_value;
247
248                 /*
249                  *because we should back channel to
250                  *current_network.chan in in scanning,
251                  *So if set_chan == current_network.chan
252                  *we should set it.
253                  *because mac80211 tell us wrong bw40
254                  *info for cisco1253 bw20, so we modify
255                  *it here based on UPPER & LOWER
256                  */
257                 switch (hw->conf.channel_type) {
258                 case NL80211_CHAN_HT20:
259                 case NL80211_CHAN_NO_HT:
260                         /* SC */
261                         mac->cur_40_prime_sc =
262                             PRIME_CHNL_OFFSET_DONT_CARE;
263                         rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
264                         mac->bw_40 = false;
265                         break;
266                 case NL80211_CHAN_HT40MINUS:
267                         /* SC */
268                         mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
269                         rtlphy->current_chan_bw =
270                             HT_CHANNEL_WIDTH_20_40;
271                         mac->bw_40 = true;
272
273                         /*wide channel */
274                         wide_chan -= 2;
275
276                         break;
277                 case NL80211_CHAN_HT40PLUS:
278                         /* SC */
279                         mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
280                         rtlphy->current_chan_bw =
281                             HT_CHANNEL_WIDTH_20_40;
282                         mac->bw_40 = true;
283
284                         /*wide channel */
285                         wide_chan += 2;
286
287                         break;
288                 default:
289                         mac->bw_40 = false;
290                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
291                                  ("switch case not processed\n"));
292                         break;
293                 }
294
295                 if (wide_chan <= 0)
296                         wide_chan = 1;
297                 rtlphy->current_channel = wide_chan;
298
299                 rtlpriv->cfg->ops->set_channel_access(hw);
300                 rtlpriv->cfg->ops->switch_channel(hw);
301                 rtlpriv->cfg->ops->set_bw_mode(hw,
302                                                hw->conf.channel_type);
303         }
304
305         mutex_unlock(&rtlpriv->locks.conf_mutex);
306
307         return 0;
308 }
309
310 static void rtl_op_configure_filter(struct ieee80211_hw *hw,
311                              unsigned int changed_flags,
312                              unsigned int *new_flags, u64 multicast)
313 {
314         struct rtl_priv *rtlpriv = rtl_priv(hw);
315         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
316
317         *new_flags &= RTL_SUPPORTED_FILTERS;
318         if (!changed_flags)
319                 return;
320
321         /*TODO: we disable broadcase now, so enable here */
322         if (changed_flags & FIF_ALLMULTI) {
323                 if (*new_flags & FIF_ALLMULTI) {
324                         mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
325                             rtlpriv->cfg->maps[MAC_RCR_AB];
326                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
327                                  ("Enable receive multicast frame.\n"));
328                 } else {
329                         mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
330                                           rtlpriv->cfg->maps[MAC_RCR_AB]);
331                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
332                                  ("Disable receive multicast frame.\n"));
333                 }
334         }
335
336         if (changed_flags & FIF_FCSFAIL) {
337                 if (*new_flags & FIF_FCSFAIL) {
338                         mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
339                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
340                                  ("Enable receive FCS error frame.\n"));
341                 } else {
342                         mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
343                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
344                                  ("Disable receive FCS error frame.\n"));
345                 }
346         }
347
348         if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
349                 /*
350                  *TODO: BIT(5) is probe response BIT(8) is beacon
351                  *TODO: Use define for BIT(5) and BIT(8)
352                  */
353                 if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
354                         mac->rx_mgt_filter |= (BIT(5) | BIT(8));
355                 else
356                         mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
357         }
358
359         if (changed_flags & FIF_CONTROL) {
360                 if (*new_flags & FIF_CONTROL) {
361                         mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
362                         mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;
363
364                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
365                                  ("Enable receive control frame.\n"));
366                 } else {
367                         mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
368                         mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
369                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
370                                  ("Disable receive control frame.\n"));
371                 }
372         }
373
374         if (changed_flags & FIF_OTHER_BSS) {
375                 if (*new_flags & FIF_OTHER_BSS) {
376                         mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
377                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
378                                  ("Enable receive other BSS's frame.\n"));
379                 } else {
380                         mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
381                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
382                                  ("Disable receive other BSS's frame.\n"));
383                 }
384         }
385
386         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
387         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
388                                       (u8 *) (&mac->rx_mgt_filter));
389         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
390                                       (u8 *) (&mac->rx_ctrl_filter));
391 }
392
393 static int _rtl_get_hal_qnum(u16 queue)
394 {
395         int qnum;
396
397         switch (queue) {
398         case 0:
399                 qnum = AC3_VO;
400                 break;
401         case 1:
402                 qnum = AC2_VI;
403                 break;
404         case 2:
405                 qnum = AC0_BE;
406                 break;
407         case 3:
408                 qnum = AC1_BK;
409                 break;
410         default:
411                 qnum = AC0_BE;
412                 break;
413         }
414         return qnum;
415 }
416
417 /*
418  *for mac80211 VO=0, VI=1, BE=2, BK=3
419  *for rtl819x  BE=0, BK=1, VI=2, VO=3
420  */
421 static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
422                    const struct ieee80211_tx_queue_params *param)
423 {
424         struct rtl_priv *rtlpriv = rtl_priv(hw);
425         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
426         int aci;
427
428         if (queue >= AC_MAX) {
429                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
430                          ("queue number %d is incorrect!\n", queue));
431                 return -EINVAL;
432         }
433
434         aci = _rtl_get_hal_qnum(queue);
435         mac->ac[aci].aifs = param->aifs;
436         mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);
437         mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);
438         mac->ac[aci].tx_op = cpu_to_le16(param->txop);
439         memcpy(&mac->edca_param[aci], param, sizeof(*param));
440         rtlpriv->cfg->ops->set_qos(hw, aci);
441         return 0;
442 }
443
444 static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
445                              struct ieee80211_vif *vif,
446                              struct ieee80211_bss_conf *bss_conf, u32 changed)
447 {
448         struct rtl_priv *rtlpriv = rtl_priv(hw);
449         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
450         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
451
452         mutex_lock(&rtlpriv->locks.conf_mutex);
453
454         if ((vif->type == NL80211_IFTYPE_ADHOC) ||
455             (vif->type == NL80211_IFTYPE_AP) ||
456             (vif->type == NL80211_IFTYPE_MESH_POINT)) {
457
458                 if ((changed & BSS_CHANGED_BEACON) ||
459                     (changed & BSS_CHANGED_BEACON_ENABLED &&
460                      bss_conf->enable_beacon)) {
461
462                         if (mac->beacon_enabled == 0) {
463                                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
464                                          ("BSS_CHANGED_BEACON_ENABLED\n"));
465
466                                 /*start hw beacon interrupt. */
467                                 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
468                                 mac->beacon_enabled = 1;
469                                 rtlpriv->cfg->ops->update_interrupt_mask(hw,
470                                                 rtlpriv->cfg->maps
471                                                 [RTL_IBSS_INT_MASKS],
472                                                 0);
473                         }
474                 } else {
475                         if (mac->beacon_enabled == 1) {
476                                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
477                                          ("ADHOC DISABLE BEACON\n"));
478
479                                 mac->beacon_enabled = 0;
480                                 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
481                                                 rtlpriv->cfg->maps
482                                                 [RTL_IBSS_INT_MASKS]);
483                         }
484                 }
485
486                 if (changed & BSS_CHANGED_BEACON_INT) {
487                         RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
488                                  ("BSS_CHANGED_BEACON_INT\n"));
489                         mac->beacon_interval = bss_conf->beacon_int;
490                         rtlpriv->cfg->ops->set_bcn_intv(hw);
491                 }
492         }
493
494         /*TODO: reference to enum ieee80211_bss_change */
495         if (changed & BSS_CHANGED_ASSOC) {
496                 if (bss_conf->assoc) {
497                         mac->link_state = MAC80211_LINKED;
498                         mac->cnt_after_linked = 0;
499                         mac->assoc_id = bss_conf->aid;
500                         memcpy(mac->bssid, bss_conf->bssid, 6);
501
502                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
503                                  ("BSS_CHANGED_ASSOC\n"));
504                 } else {
505                         if (mac->link_state == MAC80211_LINKED)
506                                 rtl_lps_leave(hw);
507
508                         mac->link_state = MAC80211_NOLINK;
509                         memset(mac->bssid, 0, 6);
510
511                         /* reset sec info */
512                         rtl_cam_reset_sec_info(hw);
513
514                         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
515                                  ("BSS_CHANGED_UN_ASSOC\n"));
516                 }
517         }
518
519         if (changed & BSS_CHANGED_ERP_CTS_PROT) {
520                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
521                          ("BSS_CHANGED_ERP_CTS_PROT\n"));
522                 mac->use_cts_protect = bss_conf->use_cts_prot;
523         }
524
525         if (changed & BSS_CHANGED_ERP_PREAMBLE) {
526                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
527                          ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
528                           bss_conf->use_short_preamble));
529
530                 mac->short_preamble = bss_conf->use_short_preamble;
531                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
532                                               (u8 *) (&mac->short_preamble));
533         }
534
535         if (changed & BSS_CHANGED_ERP_SLOT) {
536                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
537                          ("BSS_CHANGED_ERP_SLOT\n"));
538
539                 if (bss_conf->use_short_slot)
540                         mac->slot_time = RTL_SLOT_TIME_9;
541                 else
542                         mac->slot_time = RTL_SLOT_TIME_20;
543
544                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
545                                               (u8 *) (&mac->slot_time));
546         }
547
548         if (changed & BSS_CHANGED_HT) {
549                 struct ieee80211_sta *sta = NULL;
550
551                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
552                          ("BSS_CHANGED_HT\n"));
553
554                 rcu_read_lock();
555                 sta = ieee80211_find_sta(mac->vif, mac->bssid);
556
557                 if (sta) {
558                         if (sta->ht_cap.ampdu_density >
559                             mac->current_ampdu_density)
560                                 mac->current_ampdu_density =
561                                     sta->ht_cap.ampdu_density;
562                         if (sta->ht_cap.ampdu_factor <
563                             mac->current_ampdu_factor)
564                                 mac->current_ampdu_factor =
565                                     sta->ht_cap.ampdu_factor;
566                 }
567                 rcu_read_unlock();
568
569                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
570                                               (u8 *) (&mac->max_mss_density));
571                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
572                                               &mac->current_ampdu_factor);
573                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
574                                               &mac->current_ampdu_density);
575         }
576
577         if (changed & BSS_CHANGED_BSSID) {
578                 struct ieee80211_sta *sta = NULL;
579                 u32 basic_rates;
580                 u8 i;
581
582                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
583                                               (u8 *) bss_conf->bssid);
584
585                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
586                          (MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
587
588                 memcpy(mac->bssid, bss_conf->bssid, 6);
589                 if (is_valid_ether_addr(bss_conf->bssid)) {
590                         switch (vif->type) {
591                         case NL80211_IFTYPE_UNSPECIFIED:
592                                 break;
593                         case NL80211_IFTYPE_ADHOC:
594                                 break;
595                         case NL80211_IFTYPE_STATION:
596                                 break;
597                         case NL80211_IFTYPE_AP:
598                                 break;
599                         default:
600                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
601                                          ("switch case not process\n"));
602                                 break;
603                         }
604                         rtlpriv->cfg->ops->set_network_type(hw, vif->type);
605                 } else
606                         rtlpriv->cfg->ops->set_network_type(hw,
607                                         NL80211_IFTYPE_UNSPECIFIED);
608
609                 memset(mac->mcs, 0, 16);
610                 mac->ht_enable = false;
611                 mac->sgi_40 = false;
612                 mac->sgi_20 = false;
613
614                 if (!bss_conf->use_short_slot)
615                         mac->mode = WIRELESS_MODE_B;
616                 else
617                         mac->mode = WIRELESS_MODE_G;
618
619                 rcu_read_lock();
620                 sta = ieee80211_find_sta(mac->vif, mac->bssid);
621
622                 if (sta) {
623                         if (sta->ht_cap.ht_supported) {
624                                 mac->mode = WIRELESS_MODE_N_24G;
625                                 mac->ht_enable = true;
626                         }
627
628                         if (mac->ht_enable) {
629                                 u16 ht_cap = sta->ht_cap.cap;
630                                 memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16);
631
632                                 for (i = 0; i < 16; i++)
633                                         RT_TRACE(rtlpriv, COMP_MAC80211,
634                                                  DBG_LOUD, ("%x ",
635                                                             mac->mcs[i]));
636                                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
637                                          ("\n"));
638
639                                 if (ht_cap & IEEE80211_HT_CAP_SGI_40)
640                                         mac->sgi_40 = true;
641
642                                 if (ht_cap & IEEE80211_HT_CAP_SGI_20)
643                                         mac->sgi_20 = true;
644
645                                 /*
646                                  * for cisco 1252 bw20 it's wrong
647                                  * if (ht_cap &
648                                  *     IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
649                                  *      mac->bw_40 = true;
650                                  * }
651                                  */
652                         }
653                 }
654                 rcu_read_unlock();
655
656                 /*mac80211 just give us CCK rates any time
657                  *So we add G rate in basic rates when
658                  not in B mode*/
659                 if (changed & BSS_CHANGED_BASIC_RATES) {
660                         if (mac->mode == WIRELESS_MODE_B)
661                                 basic_rates = bss_conf->basic_rates | 0x00f;
662                         else
663                                 basic_rates = bss_conf->basic_rates | 0xff0;
664
665                         if (!vif)
666                                 goto out;
667
668                         mac->basic_rates = basic_rates;
669                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
670                                         (u8 *) (&basic_rates));
671
672                         if (rtlpriv->dm.useramask)
673                                 rtlpriv->cfg->ops->update_rate_mask(hw, 0);
674                         else
675                                 rtlpriv->cfg->ops->update_rate_table(hw);
676
677                 }
678         }
679
680         /*
681          * For FW LPS:
682          * To tell firmware we have connected
683          * to an AP. For 92SE/CE power save v2.
684          */
685         if (changed & BSS_CHANGED_ASSOC) {
686                 if (bss_conf->assoc) {
687                         if (ppsc->fwctrl_lps) {
688                                 u8 mstatus = RT_MEDIA_CONNECT;
689                                 rtlpriv->cfg->ops->set_hw_reg(hw,
690                                                       HW_VAR_H2C_FW_JOINBSSRPT,
691                                                       (u8 *) (&mstatus));
692                                 ppsc->report_linked = true;
693                         }
694                 } else {
695                         if (ppsc->fwctrl_lps) {
696                                 u8 mstatus = RT_MEDIA_DISCONNECT;
697                                 rtlpriv->cfg->ops->set_hw_reg(hw,
698                                                       HW_VAR_H2C_FW_JOINBSSRPT,
699                                                       (u8 *)(&mstatus));
700                                 ppsc->report_linked = false;
701                         }
702                 }
703         }
704
705 out:
706         mutex_unlock(&rtlpriv->locks.conf_mutex);
707 }
708
709 static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
710 {
711         struct rtl_priv *rtlpriv = rtl_priv(hw);
712         u64 tsf;
713
714         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
715         return tsf;
716 }
717
718 static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
719 {
720         struct rtl_priv *rtlpriv = rtl_priv(hw);
721         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
722         u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
723
724         mac->tsf = tsf;
725         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
726 }
727
728 static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
729 {
730         struct rtl_priv *rtlpriv = rtl_priv(hw);
731         u8 tmp = 0;
732
733         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
734 }
735
736 static void rtl_op_sta_notify(struct ieee80211_hw *hw,
737                               struct ieee80211_vif *vif,
738                               enum sta_notify_cmd cmd,
739                               struct ieee80211_sta *sta)
740 {
741         switch (cmd) {
742         case STA_NOTIFY_SLEEP:
743                 break;
744         case STA_NOTIFY_AWAKE:
745                 break;
746         default:
747                 break;
748         }
749 }
750
751 static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
752                                struct ieee80211_vif *vif,
753                                enum ieee80211_ampdu_mlme_action action,
754                                struct ieee80211_sta *sta, u16 tid, u16 *ssn,
755                                u8 buf_size)
756 {
757         struct rtl_priv *rtlpriv = rtl_priv(hw);
758
759         switch (action) {
760         case IEEE80211_AMPDU_TX_START:
761                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
762                          ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
763                 return rtl_tx_agg_start(hw, sta->addr, tid, ssn);
764                 break;
765         case IEEE80211_AMPDU_TX_STOP:
766                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
767                          ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
768                 return rtl_tx_agg_stop(hw, sta->addr, tid);
769                 break;
770         case IEEE80211_AMPDU_TX_OPERATIONAL:
771                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
772                          ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
773                 break;
774         case IEEE80211_AMPDU_RX_START:
775                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
776                          ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
777                 break;
778         case IEEE80211_AMPDU_RX_STOP:
779                 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
780                          ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
781                 break;
782         default:
783                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
784                          ("IEEE80211_AMPDU_ERR!!!!:\n"));
785                 return -EOPNOTSUPP;
786         }
787         return 0;
788 }
789
790 static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
791 {
792         struct rtl_priv *rtlpriv = rtl_priv(hw);
793         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
794
795         mac->act_scanning = true;
796
797         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
798
799         if (mac->link_state == MAC80211_LINKED) {
800                 rtl_lps_leave(hw);
801                 mac->link_state = MAC80211_LINKED_SCANNING;
802         } else
803                 rtl_ips_nic_on(hw);
804
805         rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
806         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
807 }
808
809 static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
810 {
811         struct rtl_priv *rtlpriv = rtl_priv(hw);
812         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
813
814         RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
815
816         rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
817         mac->act_scanning = false;
818         if (mac->link_state == MAC80211_LINKED_SCANNING) {
819                 mac->link_state = MAC80211_LINKED;
820
821                 /* fix fwlps issue */
822                 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
823
824                 if (rtlpriv->dm.useramask)
825                         rtlpriv->cfg->ops->update_rate_mask(hw, 0);
826                 else
827                         rtlpriv->cfg->ops->update_rate_table(hw);
828
829         }
830
831 }
832
833 static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
834                           struct ieee80211_vif *vif, struct ieee80211_sta *sta,
835                           struct ieee80211_key_conf *key)
836 {
837         struct rtl_priv *rtlpriv = rtl_priv(hw);
838         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
839         u8 key_type = NO_ENCRYPTION;
840         u8 key_idx;
841         bool group_key = false;
842         bool wep_only = false;
843         int err = 0;
844         u8 mac_addr[ETH_ALEN];
845         u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
846         u8 zero_addr[ETH_ALEN] = { 0 };
847
848         if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
849                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
850                          ("not open hw encryption\n"));
851                 return -ENOSPC; /*User disabled HW-crypto */
852         }
853         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
854                  ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
855                   cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
856                   sta ? sta->addr : bcast_addr));
857         rtlpriv->sec.being_setkey = true;
858         rtl_ips_nic_on(hw);
859         mutex_lock(&rtlpriv->locks.conf_mutex);
860         /* <1> get encryption alg */
861         switch (key->cipher) {
862         case WLAN_CIPHER_SUITE_WEP40:
863                 key_type = WEP40_ENCRYPTION;
864                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
865                 rtlpriv->sec.use_defaultkey = true;
866                 break;
867         case WLAN_CIPHER_SUITE_WEP104:
868                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
869                          ("alg:WEP104\n"));
870                 key_type = WEP104_ENCRYPTION;
871                 rtlpriv->sec.use_defaultkey = true;
872                 break;
873         case WLAN_CIPHER_SUITE_TKIP:
874                 key_type = TKIP_ENCRYPTION;
875                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
876                 if (mac->opmode == NL80211_IFTYPE_ADHOC)
877                         rtlpriv->sec.use_defaultkey = true;
878                 break;
879         case WLAN_CIPHER_SUITE_CCMP:
880                 key_type = AESCCMP_ENCRYPTION;
881                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
882                 if (mac->opmode == NL80211_IFTYPE_ADHOC)
883                         rtlpriv->sec.use_defaultkey = true;
884                 break;
885         default:
886                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
887                          ("alg_err:%x!!!!:\n", key->cipher));
888                 goto out_unlock;
889         }
890         /* <2> get key_idx */
891         key_idx = (u8) (key->keyidx);
892         if (key_idx > 3)
893                 goto out_unlock;
894         /* <3> if pairwise key enable_hw_sec */
895         group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
896         if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
897             rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
898                 if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
899                     (key_type == WEP40_ENCRYPTION ||
900                      key_type == WEP104_ENCRYPTION))
901                         wep_only = true;
902                 rtlpriv->sec.pairwise_enc_algorithm = key_type;
903                 rtlpriv->cfg->ops->enable_hw_sec(hw);
904         }
905         /* <4> set key based on cmd */
906         switch (cmd) {
907         case SET_KEY:
908                 if (wep_only) {
909                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
910                                  ("set WEP(group/pairwise) key\n"));
911                         /* Pairwise key with an assigned MAC address. */
912                         rtlpriv->sec.pairwise_enc_algorithm = key_type;
913                         rtlpriv->sec.group_enc_algorithm = key_type;
914                         /*set local buf about wep key. */
915                         memcpy(rtlpriv->sec.key_buf[key_idx],
916                                key->key, key->keylen);
917                         rtlpriv->sec.key_len[key_idx] = key->keylen;
918                         memcpy(mac_addr, zero_addr, ETH_ALEN);
919                 } else if (group_key) { /* group key */
920                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
921                                  ("set group key\n"));
922                         /* group key */
923                         rtlpriv->sec.group_enc_algorithm = key_type;
924                         /*set local buf about group key. */
925                         memcpy(rtlpriv->sec.key_buf[key_idx],
926                                key->key, key->keylen);
927                         rtlpriv->sec.key_len[key_idx] = key->keylen;
928                         memcpy(mac_addr, bcast_addr, ETH_ALEN);
929                 } else {        /* pairwise key */
930                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
931                                  ("set pairwise key\n"));
932                         if (!sta) {
933                                 RT_ASSERT(false, ("pairwise key withnot"
934                                                   "mac_addr\n"));
935                                 err = -EOPNOTSUPP;
936                                 goto out_unlock;
937                         }
938                         /* Pairwise key with an assigned MAC address. */
939                         rtlpriv->sec.pairwise_enc_algorithm = key_type;
940                         /*set local buf about pairwise key. */
941                         memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
942                                key->key, key->keylen);
943                         rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
944                         rtlpriv->sec.pairwise_key =
945                             rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
946                         memcpy(mac_addr, sta->addr, ETH_ALEN);
947                 }
948                 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
949                                            group_key, key_type, wep_only,
950                                            false);
951                 /* <5> tell mac80211 do something: */
952                 /*must use sw generate IV, or can not work !!!!. */
953                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
954                 key->hw_key_idx = key_idx;
955                 if (key_type == TKIP_ENCRYPTION)
956                         key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
957                 break;
958         case DISABLE_KEY:
959                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
960                          ("disable key delete one entry\n"));
961                 /*set local buf about wep key. */
962                 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
963                 rtlpriv->sec.key_len[key_idx] = 0;
964                 memcpy(mac_addr, zero_addr, ETH_ALEN);
965                 /*
966                  *mac80211 will delete entrys one by one,
967                  *so don't use rtl_cam_reset_all_entry
968                  *or clear all entry here.
969                  */
970                 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
971                 break;
972         default:
973                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
974                          ("cmd_err:%x!!!!:\n", cmd));
975         }
976 out_unlock:
977         mutex_unlock(&rtlpriv->locks.conf_mutex);
978         rtlpriv->sec.being_setkey = false;
979         return err;
980 }
981
982 static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
983 {
984         struct rtl_priv *rtlpriv = rtl_priv(hw);
985
986         bool radio_state;
987         bool blocked;
988         u8 valid = 0;
989
990         if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
991                 return;
992
993         mutex_lock(&rtlpriv->locks.conf_mutex);
994
995         /*if Radio On return true here */
996         radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
997
998         if (valid) {
999                 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
1000                         rtlpriv->rfkill.rfkill_state = radio_state;
1001
1002                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1003                                  (KERN_INFO "wireless radio switch turned %s\n",
1004                                   radio_state ? "on" : "off"));
1005
1006                         blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
1007                         wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1008                 }
1009         }
1010
1011         mutex_unlock(&rtlpriv->locks.conf_mutex);
1012 }
1013
1014 const struct ieee80211_ops rtl_ops = {
1015         .start = rtl_op_start,
1016         .stop = rtl_op_stop,
1017         .tx = rtl_op_tx,
1018         .add_interface = rtl_op_add_interface,
1019         .remove_interface = rtl_op_remove_interface,
1020         .config = rtl_op_config,
1021         .configure_filter = rtl_op_configure_filter,
1022         .set_key = rtl_op_set_key,
1023         .conf_tx = rtl_op_conf_tx,
1024         .bss_info_changed = rtl_op_bss_info_changed,
1025         .get_tsf = rtl_op_get_tsf,
1026         .set_tsf = rtl_op_set_tsf,
1027         .reset_tsf = rtl_op_reset_tsf,
1028         .sta_notify = rtl_op_sta_notify,
1029         .ampdu_action = rtl_op_ampdu_action,
1030         .sw_scan_start = rtl_op_sw_scan_start,
1031         .sw_scan_complete = rtl_op_sw_scan_complete,
1032         .rfkill_poll = rtl_op_rfkill_poll,
1033 };