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