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