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