Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / rtl8712 / rtl871x_mp_ioctl.c
1 /******************************************************************************
2  * rtl871x_mp_ioctl.c
3  *
4  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5  * Linux device driver for RTL8192SU
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * Modifications for inclusion into the Linux staging tree are
21  * Copyright(c) 2010 Larry Finger. All rights reserved.
22  *
23  * Contact information:
24  * WLAN FAE <wlanfae@realtek.com>
25  * Larry Finger <Larry.Finger@lwfinger.net>
26  *
27  ******************************************************************************/
28
29 #define _RTL871X_MP_IOCTL_C_
30
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "mlme_osdep.h"
34 #include "rtl871x_mp.h"
35 #include "rtl871x_mp_ioctl.h"
36
37 uint oid_null_function(struct oid_par_priv *poid_par_priv)
38 {
39         return NDIS_STATUS_SUCCESS;
40 }
41
42 uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
43 {
44         uint status = NDIS_STATUS_SUCCESS;
45         struct _adapter *Adapter = (struct _adapter *)
46                                    (poid_par_priv->adapter_context);
47
48         if (poid_par_priv->type_of_oid == SET_OID) {
49                 if (poid_par_priv->information_buf_len >= sizeof(u8))
50                         Adapter->registrypriv.wireless_mode =
51                                         *(u8 *)poid_par_priv->information_buf;
52                 else
53                         status = NDIS_STATUS_INVALID_LENGTH;
54         } else if (poid_par_priv->type_of_oid == QUERY_OID) {
55                 if (poid_par_priv->information_buf_len >= sizeof(u8)) {
56                         *(u8 *)poid_par_priv->information_buf =
57                                          Adapter->registrypriv.wireless_mode;
58                         *poid_par_priv->bytes_rw =
59                                         poid_par_priv->information_buf_len;
60                 } else
61                         status = NDIS_STATUS_INVALID_LENGTH;
62         } else {
63                 status = NDIS_STATUS_NOT_ACCEPTED;
64         }
65         return status;
66 }
67
68 uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
69 {
70         uint status = NDIS_STATUS_SUCCESS;
71         struct _adapter *Adapter = (struct _adapter *)
72                                    (poid_par_priv->adapter_context);
73         struct bb_reg_param *pbbreg;
74         u16 offset;
75         u32 value;
76
77         if (poid_par_priv->type_of_oid != SET_OID)
78                 return NDIS_STATUS_NOT_ACCEPTED;
79         if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
80                 return NDIS_STATUS_INVALID_LENGTH;
81         pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
82         offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
83         if (offset < BB_REG_BASE_ADDR)
84                 offset |= BB_REG_BASE_ADDR;
85         value = pbbreg->value;
86         r8712_bb_reg_write(Adapter, offset, value);
87         return status;
88 }
89
90 uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
91 {
92         uint status = NDIS_STATUS_SUCCESS;
93         struct _adapter *Adapter = (struct _adapter *)
94                                    (poid_par_priv->adapter_context);
95         struct bb_reg_param *pbbreg;
96         u16 offset;
97         u32 value;
98
99         if (poid_par_priv->type_of_oid != QUERY_OID)
100                 return NDIS_STATUS_NOT_ACCEPTED;
101         if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
102                 return NDIS_STATUS_INVALID_LENGTH;
103         pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
104         offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
105         if (offset < BB_REG_BASE_ADDR)
106                 offset |= BB_REG_BASE_ADDR;
107         value = r8712_bb_reg_read(Adapter, offset);
108         pbbreg->value = value;
109         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
110         return status;
111 }
112
113 uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
114 {
115         uint status = NDIS_STATUS_SUCCESS;
116         struct _adapter *Adapter = (struct _adapter *)
117                                    (poid_par_priv->adapter_context);
118         struct rf_reg_param *pbbreg;
119         u8 path;
120         u8 offset;
121         u32 value;
122
123         if (poid_par_priv->type_of_oid != SET_OID)
124                 return NDIS_STATUS_NOT_ACCEPTED;
125         if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
126                 return NDIS_STATUS_INVALID_LENGTH;
127         pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
128         path = (u8)pbbreg->path;
129         if (path > RF_PATH_B)
130                 return NDIS_STATUS_NOT_ACCEPTED;
131         offset = (u8)pbbreg->offset;
132         value = pbbreg->value;
133         r8712_rf_reg_write(Adapter, path, offset, value);
134         return status;
135 }
136
137 uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
138 {
139         struct _adapter *Adapter = (struct _adapter *)
140                                    (poid_par_priv->adapter_context);
141         uint status = NDIS_STATUS_SUCCESS;
142         struct rf_reg_param *pbbreg;
143         u8 path;
144         u8 offset;
145         u32 value;
146
147         if (poid_par_priv->type_of_oid != QUERY_OID)
148                 return NDIS_STATUS_NOT_ACCEPTED;
149         if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
150                 return NDIS_STATUS_INVALID_LENGTH;
151         pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
152         path = (u8)pbbreg->path;
153         if (path > RF_PATH_B) /* 1T2R  path_a /path_b */
154                 return NDIS_STATUS_NOT_ACCEPTED;
155         offset = (u8)pbbreg->offset;
156         value = r8712_rf_reg_read(Adapter, path, offset);
157         pbbreg->value = value;
158         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
159         return status;
160 }
161
162 /*This function initializes the DUT to the MP test mode*/
163 static int mp_start_test(struct _adapter *padapter)
164 {
165         struct mp_priv *pmppriv = &padapter->mppriv;
166         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
167         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
168         struct ndis_wlan_bssid_ex bssid;
169         struct sta_info *psta;
170         unsigned long length;
171         unsigned long irqL;
172         int res = _SUCCESS;
173
174         /* 3 1. initialize a new struct ndis_wlan_bssid_ex */
175         memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
176         bssid.Ssid.SsidLength = 16;
177         memcpy(bssid.Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc",
178                 bssid.Ssid.SsidLength);
179         bssid.InfrastructureMode = Ndis802_11IBSS;
180         bssid.NetworkTypeInUse = Ndis802_11DS;
181         bssid.IELength = 0;
182         length = r8712_get_ndis_wlan_bssid_ex_sz(&bssid);
183         if (length % 4) {
184                 /*round up to multiple of 4 bytes.*/
185                 bssid.Length = ((length >> 2) + 1) << 2;
186         } else
187                 bssid.Length = length;
188         spin_lock_irqsave(&pmlmepriv->lock, irqL);
189         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
190                 goto end_of_mp_start_test;
191         /*init mp_start_test status*/
192         pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
193         pmlmepriv->fw_state = WIFI_MP_STATE;
194         if (pmppriv->mode == _LOOPBOOK_MODE_)
195                 set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
196         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
197         /* 3 2. create a new psta for mp driver */
198         /* clear psta in the cur_network, if any */
199         psta = r8712_get_stainfo(&padapter->stapriv,
200                                  tgt_network->network.MacAddress);
201         if (psta)
202                 r8712_free_stainfo(padapter, psta);
203         psta = r8712_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
204         if (psta == NULL) {
205                 res = _FAIL;
206                 goto end_of_mp_start_test;
207         }
208         /* 3 3. join psudo AdHoc */
209         tgt_network->join_res = 1;
210         tgt_network->aid = psta->aid = 1;
211         memcpy(&tgt_network->network, &bssid, length);
212         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
213         r8712_os_indicate_connect(padapter);
214         /* Set to LINKED STATE for MP TRX Testing */
215         set_fwstate(pmlmepriv, _FW_LINKED);
216 end_of_mp_start_test:
217         spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
218         return res;
219 }
220
221 /*This function change the DUT from the MP test mode into normal mode */
222 static int mp_stop_test(struct _adapter *padapter)
223 {
224         struct mp_priv *pmppriv = &padapter->mppriv;
225         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
226         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
227         struct sta_info *psta;
228         unsigned long irqL;
229
230         spin_lock_irqsave(&pmlmepriv->lock, irqL);
231         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
232                 goto end_of_mp_stop_test;
233         /* 3 1. disconnect psudo AdHoc */
234         r8712_os_indicate_disconnect(padapter);
235         /* 3 2. clear psta used in mp test mode. */
236         psta = r8712_get_stainfo(&padapter->stapriv,
237                                  tgt_network->network.MacAddress);
238         if (psta)
239                 r8712_free_stainfo(padapter, psta);
240         /* 3 3. return to normal state (default:station mode) */
241         pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/
242         /*flush the cur_network*/
243         memset(tgt_network, 0, sizeof(struct wlan_network));
244 end_of_mp_stop_test:
245         spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
246         return _SUCCESS;
247 }
248
249 int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid)
250 {
251         struct mp_priv *pmppriv = &padapter->mppriv;
252         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
253         unsigned char res = _SUCCESS;
254
255         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
256                 return _FAIL;
257         if (check_fwstate(pmlmepriv, _FW_LINKED) == false)
258                 return _FAIL;
259         _clr_fwstate_(pmlmepriv, _FW_LINKED);
260         res = r8712_setassocsta_cmd(padapter, pmppriv->network_macaddr);
261         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
262         return res;
263 }
264
265 uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv
266                                          *poid_par_priv)
267 {
268         struct _adapter *Adapter = (struct _adapter *)
269                                    (poid_par_priv->adapter_context);
270         uint status = NDIS_STATUS_SUCCESS;
271         u32 ratevalue;
272
273         if (poid_par_priv->type_of_oid != SET_OID)
274                 return NDIS_STATUS_NOT_ACCEPTED;
275         if (poid_par_priv->information_buf_len != sizeof(u32))
276                 return NDIS_STATUS_INVALID_LENGTH;
277         ratevalue = *((u32 *)poid_par_priv->information_buf);
278         if (ratevalue >= MPT_RATE_LAST)
279                 return NDIS_STATUS_INVALID_DATA;
280         Adapter->mppriv.curr_rateidx = ratevalue;
281         r8712_SetDataRate(Adapter);
282         return status;
283 }
284
285 uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv)
286 {
287         struct _adapter *Adapter = (struct _adapter *)
288                                    (poid_par_priv->adapter_context);
289         uint status = NDIS_STATUS_SUCCESS;
290         u32 mode;
291         u8 val8;
292
293         if (poid_par_priv->type_of_oid != SET_OID)
294                 return  NDIS_STATUS_NOT_ACCEPTED;
295         mode = *((u32 *)poid_par_priv->information_buf);
296         Adapter->mppriv.mode = mode;/* 1 for loopback*/
297         if (mp_start_test(Adapter) == _FAIL)
298                 status = NDIS_STATUS_NOT_ACCEPTED;
299         r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */
300         r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */
301         /* RCR disable Check BSSID, 0x1025004a */
302         r8712_write8(Adapter, RCR+2, 0x57);
303         /* disable RX filter map , mgt frames will put in RX FIFO 0 */
304         r8712_write16(Adapter, RXFLTMAP0, 0x0);
305         val8 = r8712_read8(Adapter, EE_9346CR);
306         if (!(val8 & _9356SEL)) { /*boot from EFUSE*/
307                 r8712_efuse_reg_init(Adapter);
308                 r8712_efuse_change_max_size(Adapter);
309                 r8712_efuse_reg_uninit(Adapter);
310         }
311         return status;
312 }
313
314 uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv)
315 {
316         struct _adapter *Adapter = (struct _adapter *)
317                                    (poid_par_priv->adapter_context);
318         uint status = NDIS_STATUS_SUCCESS;
319
320         if (poid_par_priv->type_of_oid != SET_OID)
321                 return NDIS_STATUS_NOT_ACCEPTED;
322         if (mp_stop_test(Adapter) == _FAIL)
323                 status = NDIS_STATUS_NOT_ACCEPTED;
324         return status;
325 }
326
327 uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv
328                                                    *poid_par_priv)
329 {
330         struct _adapter *Adapter = (struct _adapter *)
331                                    (poid_par_priv->adapter_context);
332         uint status = NDIS_STATUS_SUCCESS;
333         u32             Channel;
334
335         if (poid_par_priv->type_of_oid != SET_OID)
336                 return NDIS_STATUS_NOT_ACCEPTED;
337         if (poid_par_priv->information_buf_len != sizeof(u32))
338                 return NDIS_STATUS_INVALID_LENGTH;
339         Channel = *((u32 *)poid_par_priv->information_buf);
340         if (Channel > 14)
341                 return NDIS_STATUS_NOT_ACCEPTED;
342         Adapter->mppriv.curr_ch = Channel;
343         r8712_SetChannel(Adapter);
344         return status;
345 }
346
347 uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv)
348 {
349         struct _adapter *Adapter = (struct _adapter *)
350                                    (poid_par_priv->adapter_context);
351         uint status = NDIS_STATUS_SUCCESS;
352         u32 antenna;
353
354         if (poid_par_priv->type_of_oid != SET_OID)
355                 return NDIS_STATUS_NOT_ACCEPTED;
356         if (poid_par_priv->information_buf_len != sizeof(u32))
357                 return NDIS_STATUS_INVALID_LENGTH;
358         antenna = *((u32 *)poid_par_priv->information_buf);
359         Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16);
360         Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF);
361         r8712_SwitchAntenna(Adapter);
362         return status;
363 }
364
365 uint oid_rt_pro_set_tx_power_control_hdl(
366                                         struct oid_par_priv *poid_par_priv)
367 {
368         struct _adapter *Adapter = (struct _adapter *)
369                                    (poid_par_priv->adapter_context);
370         uint status = NDIS_STATUS_SUCCESS;
371         u32 tx_pwr_idx;
372
373         if (poid_par_priv->type_of_oid != SET_OID)
374                 return NDIS_STATUS_NOT_ACCEPTED;
375         if (poid_par_priv->information_buf_len != sizeof(u32))
376                 return NDIS_STATUS_INVALID_LENGTH;
377         tx_pwr_idx = *((u32 *)poid_par_priv->information_buf);
378         if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE)
379                 return NDIS_STATUS_NOT_ACCEPTED;
380         Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx;
381         r8712_SetTxPower(Adapter);
382         return status;
383 }
384
385 uint oid_rt_pro_query_tx_packet_sent_hdl(
386                                         struct oid_par_priv *poid_par_priv)
387 {
388         uint status = NDIS_STATUS_SUCCESS;
389         struct _adapter *Adapter = (struct _adapter *)
390                                    (poid_par_priv->adapter_context);
391
392         if (poid_par_priv->type_of_oid != QUERY_OID) {
393                 status = NDIS_STATUS_NOT_ACCEPTED;
394                 return status;
395         }
396         if (poid_par_priv->information_buf_len == sizeof(u32)) {
397                 *(u32 *)poid_par_priv->information_buf =
398                                         Adapter->mppriv.tx_pktcount;
399                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
400         } else
401                 status = NDIS_STATUS_INVALID_LENGTH;
402         return status;
403 }
404
405 uint oid_rt_pro_query_rx_packet_received_hdl(
406                                         struct oid_par_priv *poid_par_priv)
407 {
408         uint status = NDIS_STATUS_SUCCESS;
409         struct _adapter *Adapter = (struct _adapter *)
410                                    (poid_par_priv->adapter_context);
411
412         if (poid_par_priv->type_of_oid != QUERY_OID) {
413                 status = NDIS_STATUS_NOT_ACCEPTED;
414                 return status;
415         }
416         if (poid_par_priv->information_buf_len == sizeof(u32)) {
417                 *(u32 *)poid_par_priv->information_buf =
418                                         Adapter->mppriv.rx_pktcount;
419                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
420         } else
421                 status = NDIS_STATUS_INVALID_LENGTH;
422         return status;
423 }
424
425 uint oid_rt_pro_query_rx_packet_crc32_error_hdl(
426                                         struct oid_par_priv *poid_par_priv)
427 {
428         uint status = NDIS_STATUS_SUCCESS;
429         struct _adapter *Adapter = (struct _adapter *)
430                                    (poid_par_priv->adapter_context);
431
432         if (poid_par_priv->type_of_oid != QUERY_OID) {
433                 status = NDIS_STATUS_NOT_ACCEPTED;
434                 return status;
435         }
436         if (poid_par_priv->information_buf_len == sizeof(u32)) {
437                 *(u32 *)poid_par_priv->information_buf =
438                                         Adapter->mppriv.rx_crcerrpktcount;
439                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
440         } else
441                 status = NDIS_STATUS_INVALID_LENGTH;
442         return status;
443 }
444
445 uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv
446                                                 *poid_par_priv)
447 {
448         struct _adapter *Adapter = (struct _adapter *)
449                                    (poid_par_priv->adapter_context);
450
451         if (poid_par_priv->type_of_oid != SET_OID)
452                 return NDIS_STATUS_NOT_ACCEPTED;
453         Adapter->mppriv.tx_pktcount = 0;
454         return NDIS_STATUS_SUCCESS;
455 }
456
457 uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv
458                                                     *poid_par_priv)
459 {
460         uint status = NDIS_STATUS_SUCCESS;
461         struct _adapter *Adapter = (struct _adapter *)
462                                    (poid_par_priv->adapter_context);
463
464         if (poid_par_priv->type_of_oid != SET_OID)
465                 return NDIS_STATUS_NOT_ACCEPTED;
466         if (poid_par_priv->information_buf_len == sizeof(u32)) {
467                 Adapter->mppriv.rx_pktcount = 0;
468                 Adapter->mppriv.rx_crcerrpktcount = 0;
469         } else
470                 status = NDIS_STATUS_INVALID_LENGTH;
471         return status;
472 }
473
474 uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv
475                                                  *poid_par_priv)
476 {
477         struct _adapter *Adapter = (struct _adapter *)
478                                    (poid_par_priv->adapter_context);
479
480         if (poid_par_priv->type_of_oid != SET_OID)
481                 return NDIS_STATUS_NOT_ACCEPTED;
482         r8712_ResetPhyRxPktCount(Adapter);
483         return NDIS_STATUS_SUCCESS;
484 }
485
486 uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv
487                                                   *poid_par_priv)
488 {
489         struct _adapter *Adapter = (struct _adapter *)
490                                    (poid_par_priv->adapter_context);
491
492         if (poid_par_priv->type_of_oid != QUERY_OID)
493                 return NDIS_STATUS_NOT_ACCEPTED;
494         if (poid_par_priv->information_buf_len != sizeof(u32))
495                 return NDIS_STATUS_INVALID_LENGTH;
496         *(u32 *)poid_par_priv->information_buf =
497                                          r8712_GetPhyRxPktReceived(Adapter);
498         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
499         return NDIS_STATUS_SUCCESS;
500 }
501
502 uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv
503                                                      *poid_par_priv)
504 {
505         struct _adapter *Adapter = (struct _adapter *)
506                                    (poid_par_priv->adapter_context);
507
508         if (poid_par_priv->type_of_oid != QUERY_OID)
509                 return NDIS_STATUS_NOT_ACCEPTED;
510         if (poid_par_priv->information_buf_len != sizeof(u32))
511                 return NDIS_STATUS_INVALID_LENGTH;
512         *(u32 *)poid_par_priv->information_buf =
513                                          r8712_GetPhyRxPktCRC32Error(Adapter);
514         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
515         return NDIS_STATUS_SUCCESS;
516 }
517
518 uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv
519                                           *poid_par_priv)
520 {
521         struct _adapter *Adapter = (struct _adapter *)
522                                    (poid_par_priv->adapter_context);
523
524         if (poid_par_priv->type_of_oid != SET_OID)
525                 return NDIS_STATUS_NOT_ACCEPTED;
526
527         Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf);
528         return NDIS_STATUS_SUCCESS;
529 }
530
531 uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv
532                                              *poid_par_priv)
533 {
534         struct _adapter *Adapter = (struct _adapter *)
535                                    (poid_par_priv->adapter_context);
536         u32             bStartTest;
537
538         if (poid_par_priv->type_of_oid != SET_OID)
539                 return NDIS_STATUS_NOT_ACCEPTED;
540         bStartTest = *((u32 *)poid_par_priv->information_buf);
541         r8712_SetContinuousTx(Adapter, (u8)bStartTest);
542         return NDIS_STATUS_SUCCESS;
543 }
544
545 uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv
546                                                  *poid_par_priv)
547 {
548         struct _adapter *Adapter = (struct _adapter *)
549                                    (poid_par_priv->adapter_context);
550         u32             bStartTest;
551
552         if (poid_par_priv->type_of_oid != SET_OID)
553                 return NDIS_STATUS_NOT_ACCEPTED;
554         bStartTest = *((u32 *)poid_par_priv->information_buf);
555         r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest);
556         return NDIS_STATUS_SUCCESS;
557 }
558
559 uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv
560                                                       *poid_par_priv)
561 {
562         struct _adapter *Adapter = (struct _adapter *)
563                                    (poid_par_priv->adapter_context);
564         u32             bStartTest;
565
566         if (poid_par_priv->type_of_oid != SET_OID)
567                 return NDIS_STATUS_NOT_ACCEPTED;
568         bStartTest = *((u32 *)poid_par_priv->information_buf);
569         r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest);
570         return NDIS_STATUS_SUCCESS;
571 }
572
573 uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
574                                               *poid_par_priv)
575 {
576         struct _adapter *Adapter = (struct _adapter *)
577                                    (poid_par_priv->adapter_context);
578         u32             bStartTest;
579
580         if (poid_par_priv->type_of_oid != SET_OID)
581                 return NDIS_STATUS_NOT_ACCEPTED;
582         bStartTest = *((u32 *)poid_par_priv->information_buf);
583         r8712_SetSingleToneTx(Adapter, (u8)bStartTest);
584         return NDIS_STATUS_SUCCESS;
585 }
586
587 uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
588 {
589         struct _adapter *Adapter = (struct _adapter *)
590                                    (poid_par_priv->adapter_context);
591         uint status = NDIS_STATUS_SUCCESS;
592         struct ndis_802_11_ssid *pssid;
593
594         if (poid_par_priv->type_of_oid != SET_OID)
595                 return NDIS_STATUS_NOT_ACCEPTED;
596         *poid_par_priv->bytes_needed = (u32)sizeof(struct ndis_802_11_ssid);
597         *poid_par_priv->bytes_rw = 0;
598         if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
599                 return NDIS_STATUS_INVALID_LENGTH;
600         pssid = (struct ndis_802_11_ssid *)poid_par_priv->information_buf;
601         if (mp_start_joinbss(Adapter, pssid) == _FAIL)
602                 status = NDIS_STATUS_NOT_ACCEPTED;
603         *poid_par_priv->bytes_rw = sizeof(struct ndis_802_11_ssid);
604         return status;
605 }
606
607 uint oid_rt_pro_read_register_hdl(struct oid_par_priv
608                                          *poid_par_priv)
609 {
610         struct _adapter *Adapter = (struct _adapter *)
611                                    (poid_par_priv->adapter_context);
612         uint status = NDIS_STATUS_SUCCESS;
613         struct mp_rw_reg *RegRWStruct;
614         u16             offset;
615
616         if (poid_par_priv->type_of_oid != QUERY_OID)
617                 return NDIS_STATUS_NOT_ACCEPTED;
618         RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
619         if ((RegRWStruct->offset >= 0x10250800) &&
620             (RegRWStruct->offset <= 0x10250FFF)) {
621                 /*baseband register*/
622                 /*0ffset :0x800~0xfff*/
623                 offset = (u16)(RegRWStruct->offset) & 0xFFF;
624                 RegRWStruct->value = r8712_bb_reg_read(Adapter, offset);
625         } else {
626                 switch (RegRWStruct->width) {
627                 case 1:
628                         RegRWStruct->value = r8712_read8(Adapter,
629                                                    RegRWStruct->offset);
630                         break;
631                 case 2:
632                         RegRWStruct->value = r8712_read16(Adapter,
633                                                     RegRWStruct->offset);
634                         break;
635                 case 4:
636                         RegRWStruct->value = r8712_read32(Adapter,
637                                                     RegRWStruct->offset);
638                         break;
639                 default:
640                         status = NDIS_STATUS_NOT_ACCEPTED;
641                         break;
642                 }
643         }
644         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
645         return status;
646 }
647
648 uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
649 {
650         struct _adapter *Adapter = (struct _adapter *)
651                                    (poid_par_priv->adapter_context);
652         uint status = NDIS_STATUS_SUCCESS;
653         struct mp_rw_reg *RegRWStruct;
654         u16             offset;
655         u32             value;
656         u32 oldValue = 0;
657
658         if (poid_par_priv->type_of_oid != SET_OID)
659                 return NDIS_STATUS_NOT_ACCEPTED;
660         RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
661         if ((RegRWStruct->offset >= 0x10250800) &&
662             (RegRWStruct->offset <= 0x10250FFF)) {
663                 /*baseband register*/
664                 offset = (u16)(RegRWStruct->offset) & 0xFFF;
665                 value = RegRWStruct->value;
666                 switch (RegRWStruct->width) {
667                 case 1:
668                         oldValue = r8712_bb_reg_read(Adapter, offset);
669                         oldValue &= 0xFFFFFF00;
670                         value &= 0x000000FF;
671                         value |= oldValue;
672                         break;
673                 case 2:
674                         oldValue = r8712_bb_reg_read(Adapter, offset);
675                         oldValue &= 0xFFFF0000;
676                         value &= 0x0000FFFF;
677                         value |= oldValue;
678                         break;
679                 }
680                 r8712_bb_reg_write(Adapter, offset, value);
681         } else {
682                 switch (RegRWStruct->width) {
683                 case 1:
684                         r8712_write8(Adapter, RegRWStruct->offset,
685                                (unsigned char)RegRWStruct->value);
686                         break;
687                 case 2:
688                         r8712_write16(Adapter, RegRWStruct->offset,
689                                 (unsigned short)RegRWStruct->value);
690                         break;
691                 case 4:
692                         r8712_write32(Adapter, RegRWStruct->offset,
693                                 (unsigned int)RegRWStruct->value);
694                         break;
695                 default:
696                         status = NDIS_STATUS_NOT_ACCEPTED;
697                         break;
698                 }
699
700                 if ((status == NDIS_STATUS_SUCCESS) &&
701                     (RegRWStruct->offset == HIMR) &&
702                     (RegRWStruct->width == 4))
703                         Adapter->ImrContent = RegRWStruct->value;
704         }
705         return status;
706 }
707
708 uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv
709                                                *poid_par_priv)
710 {
711         struct _adapter *Adapter = (struct _adapter *)
712                                    (poid_par_priv->adapter_context);
713         struct burst_rw_reg *pBstRwReg;
714
715         if (poid_par_priv->type_of_oid != QUERY_OID)
716                 return NDIS_STATUS_NOT_ACCEPTED;
717         pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
718         r8712_read_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
719                  pBstRwReg->Data);
720         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
721         return NDIS_STATUS_SUCCESS;
722 }
723
724 uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv
725                                                 *poid_par_priv)
726 {
727         struct _adapter *Adapter = (struct _adapter *)
728                                    (poid_par_priv->adapter_context);
729         struct burst_rw_reg *pBstRwReg;
730
731         if (poid_par_priv->type_of_oid != SET_OID)
732                 return NDIS_STATUS_NOT_ACCEPTED;
733         pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
734         r8712_write_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
735                   pBstRwReg->Data);
736         return NDIS_STATUS_SUCCESS;
737 }
738
739 uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
740 {
741         return NDIS_STATUS_SUCCESS;
742 }
743
744 uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
745 {
746         struct _adapter *Adapter = (struct _adapter *)
747                                    (poid_par_priv->adapter_context);
748         struct eeprom_rw_param *pEEPROM;
749
750         if (poid_par_priv->type_of_oid != QUERY_OID)
751                 return NDIS_STATUS_NOT_ACCEPTED;
752         pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
753         pEEPROM->value = r8712_eeprom_read16(Adapter,
754                                              (u16)(pEEPROM->offset >> 1));
755         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
756         return NDIS_STATUS_SUCCESS;
757 }
758
759 uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
760 {
761         struct _adapter *Adapter = (struct _adapter *)
762                                    (poid_par_priv->adapter_context);
763         struct eeprom_rw_param *pEEPROM;
764
765         if (poid_par_priv->type_of_oid != SET_OID)
766                 return NDIS_STATUS_NOT_ACCEPTED;
767         pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
768         r8712_eeprom_write16(Adapter, (u16)(pEEPROM->offset >> 1),
769                              pEEPROM->value);
770         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
771         return NDIS_STATUS_SUCCESS;
772 }
773
774 uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
775 {
776         struct _adapter *Adapter = (struct _adapter *)
777                                    (poid_par_priv->adapter_context);
778         struct mp_wiparam *pwi_param;
779
780         if (poid_par_priv->type_of_oid != QUERY_OID)
781                 return NDIS_STATUS_NOT_ACCEPTED;
782         if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam))
783                 return NDIS_STATUS_INVALID_LENGTH;
784         if (Adapter->mppriv.workparam.bcompleted == false)
785                 return NDIS_STATUS_NOT_ACCEPTED;
786         pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf;
787         memcpy(pwi_param, &Adapter->mppriv.workparam,
788                 sizeof(struct mp_wiparam));
789         Adapter->mppriv.act_in_progress = false;
790         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
791         return NDIS_STATUS_SUCCESS;
792 }
793
794 uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
795 {
796         struct _adapter *Adapter = (struct _adapter *)
797                                    (poid_par_priv->adapter_context);
798
799         if (poid_par_priv->type_of_oid != QUERY_OID)
800                 return NDIS_STATUS_NOT_ACCEPTED;
801         if (poid_par_priv->information_buf_len < sizeof(uint) * 2)
802                 return NDIS_STATUS_INVALID_LENGTH;
803         if (*(uint *)poid_par_priv->information_buf == 1)
804                 Adapter->mppriv.rx_pktloss = 0;
805         *((uint *)poid_par_priv->information_buf+1) =
806                                          Adapter->mppriv.rx_pktloss;
807         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
808         return NDIS_STATUS_SUCCESS;
809 }
810
811 uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
812 {
813         if (poid_par_priv->type_of_oid != QUERY_OID)
814                 return NDIS_STATUS_NOT_ACCEPTED;
815         return NDIS_STATUS_SUCCESS;
816 }
817
818 uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
819 {
820         if (poid_par_priv->type_of_oid != SET_OID)
821                 return NDIS_STATUS_NOT_ACCEPTED;
822         return NDIS_STATUS_SUCCESS;
823 }
824
825 uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
826 {
827         struct _adapter *Adapter = (struct _adapter *)
828                                    (poid_par_priv->adapter_context);
829         uint status = NDIS_STATUS_SUCCESS;
830
831         if (poid_par_priv->type_of_oid != SET_OID)
832                 return NDIS_STATUS_NOT_ACCEPTED;
833         if (r8712_setrfintfs_cmd(Adapter, *(unsigned char *)
834             poid_par_priv->information_buf) == _FAIL)
835                 status = NDIS_STATUS_NOT_ACCEPTED;
836         return status;
837 }
838
839 uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
840 {
841         struct _adapter *Adapter = (struct _adapter *)
842                                    (poid_par_priv->adapter_context);
843         uint status = NDIS_STATUS_SUCCESS;
844
845         if (poid_par_priv->type_of_oid != QUERY_OID)
846                 return NDIS_STATUS_NOT_ACCEPTED;
847         memcpy(poid_par_priv->information_buf,
848                 (unsigned char *)&Adapter->mppriv.rxstat,
849                 sizeof(struct recv_stat));
850         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
851         return status;
852 }
853
854 uint oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv
855                                              *poid_par_priv)
856 {
857         return NDIS_STATUS_SUCCESS;
858 }
859
860 uint oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv
861                                             *poid_par_priv)
862 {
863         struct _adapter *Adapter = (struct _adapter *)
864                                    (poid_par_priv->adapter_context);
865         uint status = NDIS_STATUS_SUCCESS;
866
867         if (poid_par_priv->type_of_oid != SET_OID)
868                 return NDIS_STATUS_NOT_ACCEPTED;
869         if (r8712_setdatarate_cmd(Adapter,
870             poid_par_priv->information_buf) != _SUCCESS)
871                 status = NDIS_STATUS_NOT_ACCEPTED;
872         return status;
873 }
874
875 uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
876 {
877         struct _adapter *Adapter = (struct _adapter *)
878                                    (poid_par_priv->adapter_context);
879         uint status = NDIS_STATUS_SUCCESS;
880
881         if (poid_par_priv->type_of_oid != QUERY_OID)
882                 return NDIS_STATUS_NOT_ACCEPTED;
883
884         if (Adapter->mppriv.act_in_progress == true)
885                 return NDIS_STATUS_NOT_ACCEPTED;
886
887         if (poid_par_priv->information_buf_len < sizeof(u8))
888                 return NDIS_STATUS_INVALID_LENGTH;
889         /*init workparam*/
890         Adapter->mppriv.act_in_progress = true;
891         Adapter->mppriv.workparam.bcompleted = false;
892         Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER;
893         Adapter->mppriv.workparam.io_offset = 0;
894         Adapter->mppriv.workparam.io_value = 0xFFFFFFFF;
895         r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value);
896         Adapter->mppriv.workparam.bcompleted = true;
897         Adapter->mppriv.act_in_progress = false;
898         *(u32 *)poid_par_priv->information_buf =
899                                  Adapter->mppriv.workparam.io_value;
900         *poid_par_priv->bytes_rw = sizeof(u32);
901         return status;
902 }
903
904 uint oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv
905                                               *poid_par_priv)
906 {
907         struct _adapter *Adapter = (struct _adapter *)
908                                    (poid_par_priv->adapter_context);
909         uint status = NDIS_STATUS_SUCCESS;
910
911         if (poid_par_priv->type_of_oid != SET_OID)
912                 return NDIS_STATUS_NOT_ACCEPTED;
913         if (poid_par_priv->information_buf_len < sizeof(u8))
914                 return NDIS_STATUS_INVALID_LENGTH;
915         if (!r8712_setptm_cmd(Adapter, *((u8 *)poid_par_priv->information_buf)))
916                 status = NDIS_STATUS_NOT_ACCEPTED;
917         return status;
918 }
919
920 uint oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
921 {
922         struct _adapter *Adapter = (struct _adapter *)
923                                    (poid_par_priv->adapter_context);
924         u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
925         uint status = NDIS_STATUS_SUCCESS;
926         u32 ratevalue;
927         u8 datarates[NumRates];
928         int i;
929
930         if (poid_par_priv->type_of_oid != SET_OID)
931                 return NDIS_STATUS_NOT_ACCEPTED;
932         ratevalue = *((u32 *)poid_par_priv->information_buf);
933         for (i = 0; i < NumRates; i++) {
934                 if (ratevalue == mpdatarate[i])
935                         datarates[i] = mpdatarate[i];
936                 else
937                         datarates[i] = 0xff;
938         }
939         if (r8712_setbasicrate_cmd(Adapter, datarates) != _SUCCESS)
940                 status = NDIS_STATUS_NOT_ACCEPTED;
941         return status;
942 }
943
944 uint oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
945 {
946         struct _adapter *Adapter = (struct _adapter *)
947                                    (poid_par_priv->adapter_context);
948
949         if (poid_par_priv->type_of_oid != QUERY_OID)
950                 return NDIS_STATUS_NOT_ACCEPTED;
951         if (poid_par_priv->information_buf_len < 8)
952                 return NDIS_STATUS_INVALID_LENGTH;
953         *poid_par_priv->bytes_rw = 8;
954         memcpy(poid_par_priv->information_buf,
955                 &(Adapter->pwrctrlpriv.pwr_mode), 8);
956         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
957         return NDIS_STATUS_SUCCESS;
958 }
959
960 uint oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
961 {
962         struct _adapter *Adapter = (struct _adapter *)
963                                    (poid_par_priv->adapter_context);
964         uint pwr_mode, smart_ps;
965
966         if (poid_par_priv->type_of_oid != SET_OID)
967                 return NDIS_STATUS_NOT_ACCEPTED;
968         *poid_par_priv->bytes_rw = 0;
969         *poid_par_priv->bytes_needed = 8;
970         if (poid_par_priv->information_buf_len < 8)
971                 return NDIS_STATUS_INVALID_LENGTH;
972         pwr_mode = *(uint *)(poid_par_priv->information_buf);
973         smart_ps = *(uint *)((addr_t)poid_par_priv->information_buf + 4);
974         if (pwr_mode != Adapter->pwrctrlpriv.pwr_mode || smart_ps !=
975                         Adapter->pwrctrlpriv.smart_ps)
976                 r8712_set_ps_mode(Adapter, pwr_mode, smart_ps);
977         *poid_par_priv->bytes_rw = 8;
978         return NDIS_STATUS_SUCCESS;
979 }
980
981 uint oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv
982                                               *poid_par_priv)
983 {
984         struct _adapter *Adapter = (struct _adapter *)
985                                    (poid_par_priv->adapter_context);
986         uint status = NDIS_STATUS_SUCCESS;
987         struct setratable_parm *prate_table;
988         u8 res;
989
990         if (poid_par_priv->type_of_oid != SET_OID)
991                 return NDIS_STATUS_NOT_ACCEPTED;
992         *poid_par_priv->bytes_needed  = sizeof(struct setratable_parm);
993         if (poid_par_priv->information_buf_len <
994             sizeof(struct setratable_parm))
995                 return NDIS_STATUS_INVALID_LENGTH;
996         prate_table = (struct setratable_parm *)poid_par_priv->information_buf;
997         res = r8712_setrttbl_cmd(Adapter, prate_table);
998         if (res == _FAIL)
999                 status = NDIS_STATUS_FAILURE;
1000         return status;
1001 }
1002
1003 uint oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv
1004                                               *poid_par_priv)
1005 {
1006         if (poid_par_priv->type_of_oid != QUERY_OID)
1007                 return NDIS_STATUS_NOT_ACCEPTED;
1008         return NDIS_STATUS_SUCCESS;
1009 }
1010
1011 uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv
1012                                            *poid_par_priv)
1013 {
1014         struct _adapter *Adapter = (struct _adapter *)
1015                                    (poid_par_priv->adapter_context);
1016         struct security_priv *psecuritypriv = &Adapter->securitypriv;
1017         enum ENCRY_CTRL_STATE encry_mode = 0;
1018
1019         *poid_par_priv->bytes_needed = sizeof(u8);
1020         if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1021                 return NDIS_STATUS_INVALID_LENGTH;
1022
1023         if (poid_par_priv->type_of_oid == SET_OID) {
1024                 encry_mode = *((u8 *)poid_par_priv->information_buf);
1025                 switch (encry_mode) {
1026                 case HW_CONTROL:
1027                         psecuritypriv->sw_decrypt = false;
1028                         psecuritypriv->sw_encrypt = false;
1029                         break;
1030                 case SW_CONTROL:
1031                         psecuritypriv->sw_decrypt = true;
1032                         psecuritypriv->sw_encrypt = true;
1033                         break;
1034                 case HW_ENCRY_SW_DECRY:
1035                         psecuritypriv->sw_decrypt = true;
1036                         psecuritypriv->sw_encrypt = false;
1037                         break;
1038                 case SW_ENCRY_HW_DECRY:
1039                         psecuritypriv->sw_decrypt = false;
1040                         psecuritypriv->sw_encrypt = true;
1041                         break;
1042                 }
1043         } else {
1044                 if ((psecuritypriv->sw_encrypt == false) &&
1045                     (psecuritypriv->sw_decrypt == false))
1046                         encry_mode = HW_CONTROL;
1047                 else if ((psecuritypriv->sw_encrypt == false) &&
1048                          (psecuritypriv->sw_decrypt == true))
1049                         encry_mode = HW_ENCRY_SW_DECRY;
1050                 else if ((psecuritypriv->sw_encrypt == true) &&
1051                          (psecuritypriv->sw_decrypt == false))
1052                         encry_mode = SW_ENCRY_HW_DECRY;
1053                 else if ((psecuritypriv->sw_encrypt == true) &&
1054                          (psecuritypriv->sw_decrypt == true))
1055                         encry_mode = SW_CONTROL;
1056                 *(u8 *)poid_par_priv->information_buf =  encry_mode;
1057                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1058         }
1059         return NDIS_STATUS_SUCCESS;
1060 }
1061 /*----------------------------------------------------------------------*/
1062 uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1063 {
1064         struct _adapter *Adapter = (struct _adapter *)
1065                                    (poid_par_priv->adapter_context);
1066
1067         uint status = NDIS_STATUS_SUCCESS;
1068
1069         struct sta_info *psta = NULL;
1070         u8      *macaddr;
1071
1072
1073         if (poid_par_priv->type_of_oid != SET_OID)
1074                 return NDIS_STATUS_NOT_ACCEPTED;
1075
1076         *poid_par_priv->bytes_needed = ETH_ALEN;
1077         if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1078                 return NDIS_STATUS_INVALID_LENGTH;
1079         macaddr = (u8 *) poid_par_priv->information_buf;
1080         psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1081         if (psta == NULL) { /* the sta in sta_info_queue => do nothing*/
1082                 psta = r8712_alloc_stainfo(&Adapter->stapriv, macaddr);
1083                 if (psta == NULL)
1084                         status = NDIS_STATUS_FAILURE;
1085         }
1086         return status;
1087 }
1088 /*-------------------------------------------------------------------------*/
1089 uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1090 {
1091         struct _adapter *Adapter = (struct _adapter *)
1092                                    (poid_par_priv->adapter_context);
1093
1094         unsigned long                   irqL;
1095         uint status = NDIS_STATUS_SUCCESS;
1096
1097         struct sta_info         *psta = NULL;
1098         u8                      *macaddr;
1099
1100
1101         if (poid_par_priv->type_of_oid != SET_OID)
1102                 return NDIS_STATUS_NOT_ACCEPTED;
1103
1104         *poid_par_priv->bytes_needed = ETH_ALEN;
1105         if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1106                 return NDIS_STATUS_INVALID_LENGTH;
1107
1108         macaddr = (u8 *)poid_par_priv->information_buf;
1109
1110         psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1111         if (psta != NULL) {
1112                 spin_lock_irqsave(&(Adapter->stapriv.sta_hash_lock), irqL);
1113                 r8712_free_stainfo(Adapter, psta);
1114                 spin_unlock_irqrestore(&(Adapter->stapriv.sta_hash_lock), irqL);
1115         }
1116
1117         return status;
1118 }
1119 /*--------------------------------------------------------------------------*/
1120 static u32 mp_query_drv_var(struct _adapter *padapter, u8 offset, u32 var)
1121 {
1122         return var;
1123 }
1124
1125 uint oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
1126 {
1127         struct _adapter *Adapter = (struct _adapter *)
1128                                    (poid_par_priv->adapter_context);
1129
1130         uint status = NDIS_STATUS_SUCCESS;
1131
1132         struct DR_VARIABLE_STRUCT *pdrv_var;
1133
1134         if (poid_par_priv->type_of_oid != QUERY_OID)
1135                 return NDIS_STATUS_NOT_ACCEPTED;
1136         *poid_par_priv->bytes_needed = sizeof(struct DR_VARIABLE_STRUCT);
1137         if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1138                 return NDIS_STATUS_INVALID_LENGTH;
1139         pdrv_var = (struct DR_VARIABLE_STRUCT *)poid_par_priv->information_buf;
1140         pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset,
1141                                               pdrv_var->variable);
1142         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1143         return status;
1144 }
1145
1146 /*--------------------------------------------------------------------------*/
1147 uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
1148 {
1149         return NDIS_STATUS_SUCCESS;
1150 }
1151 /*------------------------------------------------------------------------*/
1152 uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
1153 {
1154         struct _adapter *Adapter = (struct _adapter *)
1155                                    (poid_par_priv->adapter_context);
1156
1157         uint status = NDIS_STATUS_SUCCESS;
1158
1159         struct EFUSE_ACCESS_STRUCT *pefuse;
1160         u8 *data;
1161         u16 addr = 0, cnts = 0;
1162
1163         if (poid_par_priv->type_of_oid != QUERY_OID)
1164                 return NDIS_STATUS_NOT_ACCEPTED;
1165         if (poid_par_priv->information_buf_len <
1166             sizeof(struct EFUSE_ACCESS_STRUCT))
1167                 return NDIS_STATUS_INVALID_LENGTH;
1168         pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
1169         addr = pefuse->start_addr;
1170         cnts = pefuse->cnts;
1171         data = pefuse->data;
1172         memset(data, 0xFF, cnts);
1173         if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) >
1174              EFUSE_MAX_SIZE)
1175                 return NDIS_STATUS_NOT_ACCEPTED;
1176         if (r8712_efuse_access(Adapter, true, addr, cnts, data) == false)
1177                 status = NDIS_STATUS_FAILURE;
1178         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1179         return status;
1180 }
1181 /*------------------------------------------------------------------------*/
1182 uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
1183 {
1184         struct _adapter *Adapter = (struct _adapter *)
1185                                    (poid_par_priv->adapter_context);
1186
1187         uint status = NDIS_STATUS_SUCCESS;
1188
1189         struct EFUSE_ACCESS_STRUCT *pefuse;
1190         u8 *data;
1191         u16 addr = 0, cnts = 0;
1192
1193         if (poid_par_priv->type_of_oid != SET_OID)
1194                 return NDIS_STATUS_NOT_ACCEPTED;
1195
1196         pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
1197         addr = pefuse->start_addr;
1198         cnts = pefuse->cnts;
1199         data = pefuse->data;
1200
1201         if ((addr > 511) || (cnts < 1) || (cnts > 512) ||
1202             (addr + cnts) > r8712_efuse_get_max_size(Adapter))
1203                 return NDIS_STATUS_NOT_ACCEPTED;
1204         if (r8712_efuse_access(Adapter, false, addr, cnts, data) == false)
1205                 status = NDIS_STATUS_FAILURE;
1206         return status;
1207 }
1208 /*----------------------------------------------------------------------*/
1209 uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
1210 {
1211         struct _adapter *Adapter = (struct _adapter *)
1212                                    (poid_par_priv->adapter_context);
1213         uint status = NDIS_STATUS_SUCCESS;
1214         struct PGPKT_STRUCT     *ppgpkt;
1215
1216         *poid_par_priv->bytes_rw = 0;
1217         if (poid_par_priv->information_buf_len < sizeof(struct PGPKT_STRUCT))
1218                 return NDIS_STATUS_INVALID_LENGTH;
1219         ppgpkt = (struct PGPKT_STRUCT *)poid_par_priv->information_buf;
1220         if (poid_par_priv->type_of_oid == QUERY_OID) {
1221                 if (r8712_efuse_pg_packet_read(Adapter, ppgpkt->offset,
1222                     ppgpkt->data) == true)
1223                         *poid_par_priv->bytes_rw =
1224                                  poid_par_priv->information_buf_len;
1225                 else
1226                         status = NDIS_STATUS_FAILURE;
1227         } else {
1228                 if (r8712_efuse_reg_init(Adapter) == true) {
1229                         if (r8712_efuse_pg_packet_write(Adapter, ppgpkt->offset,
1230                             ppgpkt->word_en, ppgpkt->data) == true)
1231                                 *poid_par_priv->bytes_rw =
1232                                          poid_par_priv->information_buf_len;
1233                         else
1234                                 status = NDIS_STATUS_FAILURE;
1235                         r8712_efuse_reg_uninit(Adapter);
1236                 } else
1237                         status = NDIS_STATUS_FAILURE;
1238         }
1239         return status;
1240 }
1241
1242 uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
1243                                               *poid_par_priv)
1244 {
1245         struct _adapter *Adapter = (struct _adapter *)
1246                                    (poid_par_priv->adapter_context);
1247         uint status = NDIS_STATUS_SUCCESS;
1248
1249         if (poid_par_priv->type_of_oid != QUERY_OID)
1250                 return NDIS_STATUS_NOT_ACCEPTED;
1251         if (poid_par_priv->information_buf_len < sizeof(int))
1252                 return NDIS_STATUS_INVALID_LENGTH;
1253         r8712_efuse_reg_init(Adapter);
1254         *(int *)poid_par_priv->information_buf =
1255                                  r8712_efuse_get_current_size(Adapter);
1256         r8712_efuse_reg_uninit(Adapter);
1257         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1258         return status;
1259 }
1260
1261 uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv)
1262 {
1263         struct _adapter *Adapter = (struct _adapter *)
1264                                    (poid_par_priv->adapter_context);
1265         uint status = NDIS_STATUS_SUCCESS;
1266
1267         if (poid_par_priv->type_of_oid != QUERY_OID)
1268                 return NDIS_STATUS_NOT_ACCEPTED;
1269         if (poid_par_priv->information_buf_len < sizeof(u32))
1270                 return NDIS_STATUS_INVALID_LENGTH;
1271         *(int *)poid_par_priv->information_buf =
1272                                          r8712_efuse_get_max_size(Adapter);
1273         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1274         return status;
1275 }
1276
1277 uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv)
1278 {
1279         uint status = NDIS_STATUS_SUCCESS;
1280
1281         if (poid_par_priv->type_of_oid == QUERY_OID)
1282                 status = oid_rt_pro_read_efuse_hdl(poid_par_priv);
1283         else
1284                 status = oid_rt_pro_write_efuse_hdl(poid_par_priv);
1285         return status;
1286 }
1287
1288 uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv)
1289 {
1290         struct _adapter *Adapter = (struct _adapter *)
1291                                    (poid_par_priv->adapter_context);
1292         uint status = NDIS_STATUS_SUCCESS;
1293         u8              *data;
1294
1295         *poid_par_priv->bytes_rw = 0;
1296         if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE)
1297                 return NDIS_STATUS_INVALID_LENGTH;
1298         data = (u8 *)poid_par_priv->information_buf;
1299         if (poid_par_priv->type_of_oid == QUERY_OID) {
1300                 if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data))
1301                         *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
1302                 else
1303                         status = NDIS_STATUS_FAILURE;
1304         } else {
1305                 /* SET_OID */
1306                 if (r8712_efuse_reg_init(Adapter) == true) {
1307                         if (r8712_efuse_map_write(Adapter, 0,
1308                             EFUSE_MAP_MAX_SIZE, data))
1309                                 *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
1310                         else
1311                                 status = NDIS_STATUS_FAILURE;
1312                         r8712_efuse_reg_uninit(Adapter);
1313                 } else {
1314                         status = NDIS_STATUS_FAILURE;
1315                 }
1316         }
1317         return status;
1318 }
1319
1320 uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
1321 {
1322         struct _adapter *Adapter = (struct _adapter *)
1323                                    (poid_par_priv->adapter_context);
1324         uint status = NDIS_STATUS_SUCCESS;
1325         u32             bandwidth;
1326
1327         if (poid_par_priv->type_of_oid != SET_OID)
1328                 return NDIS_STATUS_NOT_ACCEPTED;
1329         if (poid_par_priv->information_buf_len < sizeof(u32))
1330                 return NDIS_STATUS_INVALID_LENGTH;
1331         bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/
1332         if (bandwidth != HT_CHANNEL_WIDTH_20)
1333                 bandwidth = HT_CHANNEL_WIDTH_40;
1334         Adapter->mppriv.curr_bandwidth = (u8)bandwidth;
1335         r8712_SwitchBandwidth(Adapter);
1336         return status;
1337 }
1338
1339 uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
1340 {
1341         struct _adapter *Adapter = (struct _adapter *)
1342                                    (poid_par_priv->adapter_context);
1343         uint status = NDIS_STATUS_SUCCESS;
1344         u32             crystal_cap = 0;
1345
1346         if (poid_par_priv->type_of_oid != SET_OID)
1347                 return NDIS_STATUS_NOT_ACCEPTED;
1348         if (poid_par_priv->information_buf_len < sizeof(u32))
1349                 return NDIS_STATUS_INVALID_LENGTH;
1350         crystal_cap = *((u32 *)poid_par_priv->information_buf);/*4*/
1351         if (crystal_cap > 0xf)
1352                 return NDIS_STATUS_NOT_ACCEPTED;
1353         Adapter->mppriv.curr_crystalcap = crystal_cap;
1354         r8712_SetCrystalCap(Adapter);
1355         return status;
1356 }
1357
1358 uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
1359                                            *poid_par_priv)
1360 {
1361         struct _adapter *Adapter = (struct _adapter *)
1362                                    (poid_par_priv->adapter_context);
1363         u8              rx_pkt_type;
1364         u32             rcr_val32;
1365
1366         if (poid_par_priv->type_of_oid != SET_OID)
1367                 return NDIS_STATUS_NOT_ACCEPTED;
1368         if (poid_par_priv->information_buf_len < sizeof(u8))
1369                 return NDIS_STATUS_INVALID_LENGTH;
1370         rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/
1371         rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/
1372         rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP);
1373         switch (rx_pkt_type) {
1374         case RX_PKT_BROADCAST:
1375                 rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
1376                 break;
1377         case RX_PKT_DEST_ADDR:
1378                 rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
1379                 break;
1380         case RX_PKT_PHY_MATCH:
1381                 rcr_val32 |= (RCR_APM|RCR_ACRC32);
1382                 break;
1383         default:
1384                 rcr_val32 &= ~(RCR_AAP |
1385                                RCR_APM |
1386                                RCR_AM |
1387                                RCR_AB |
1388                                RCR_ACRC32);
1389                 break;
1390         }
1391         if (rx_pkt_type == RX_PKT_DEST_ADDR)
1392                 Adapter->mppriv.check_mp_pkt = 1;
1393         else
1394                 Adapter->mppriv.check_mp_pkt = 0;
1395         r8712_write32(Adapter, RCR, rcr_val32);
1396         return NDIS_STATUS_SUCCESS;
1397 }
1398
1399 uint oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv
1400                                              *poid_par_priv)
1401 {
1402         struct _adapter *Adapter = (struct _adapter *)
1403                                    (poid_par_priv->adapter_context);
1404         u32 txagc;
1405
1406         if (poid_par_priv->type_of_oid != SET_OID)
1407                 return NDIS_STATUS_NOT_ACCEPTED;
1408         if (poid_par_priv->information_buf_len < sizeof(u32))
1409                 return NDIS_STATUS_INVALID_LENGTH;
1410         txagc = *(u32 *)poid_par_priv->information_buf;
1411         r8712_SetTxAGCOffset(Adapter, txagc);
1412         return NDIS_STATUS_SUCCESS;
1413 }
1414
1415 uint oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv
1416                                              *poid_par_priv)
1417 {
1418         struct _adapter *Adapter = (struct _adapter *)
1419                                    (poid_par_priv->adapter_context);
1420         uint status = NDIS_STATUS_SUCCESS;
1421         struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
1422         struct mp_priv          *pmppriv = &Adapter->mppriv;
1423         u32                     type;
1424
1425         if (poid_par_priv->type_of_oid != SET_OID)
1426                 return NDIS_STATUS_NOT_ACCEPTED;
1427
1428         if (poid_par_priv->information_buf_len < sizeof(u32))
1429                 return NDIS_STATUS_INVALID_LENGTH;
1430
1431         type = *(u32 *)poid_par_priv->information_buf;
1432
1433         if (_LOOPBOOK_MODE_ == type) {
1434                 pmppriv->mode = type;
1435                 set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
1436         } else if (_2MAC_MODE_ == type) {
1437                 pmppriv->mode = type;
1438                 _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE);
1439         } else
1440                 status = NDIS_STATUS_NOT_ACCEPTED;
1441         return status;
1442 }
1443 /*--------------------------------------------------------------------------*/
1444 /*Linux*/
1445 unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
1446 {
1447         return _SUCCESS;
1448 }
1449 /*-------------------------------------------------------------------------*/
1450 uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv)
1451 {
1452         u8      bpwrup;
1453
1454         if (poid_par_priv->type_of_oid != SET_OID)
1455                 return NDIS_STATUS_NOT_ACCEPTED;
1456         bpwrup = *(u8 *)poid_par_priv->information_buf;
1457         /*CALL  the power_down function*/
1458         return NDIS_STATUS_SUCCESS;
1459 }
1460
1461 /*-------------------------------------------------------------------------- */
1462 uint oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv)
1463 {
1464         struct _adapter *Adapter = (struct _adapter *)
1465                                    (poid_par_priv->adapter_context);
1466
1467         if (poid_par_priv->type_of_oid != QUERY_OID)
1468                 return NDIS_STATUS_NOT_ACCEPTED;
1469         if (poid_par_priv->information_buf_len < sizeof(u32))
1470                 return NDIS_STATUS_INVALID_LENGTH;
1471         *(int *)poid_par_priv->information_buf =
1472                  Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL;
1473         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1474         return NDIS_STATUS_SUCCESS;
1475 }