Merge tag 'sound-5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-microblaze.git] / drivers / staging / rtl8712 / rtl871x_mp_ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  * rtl871x_mp_ioctl.c
4  *
5  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6  * Linux device driver for RTL8192SU
7  *
8  * Modifications for inclusion into the Linux staging tree are
9  * Copyright(c) 2010 Larry Finger. All rights reserved.
10  *
11  * Contact information:
12  * WLAN FAE <wlanfae@realtek.com>
13  * Larry Finger <Larry.Finger@lwfinger.net>
14  *
15  ******************************************************************************/
16
17 #include <linux/rndis.h>
18 #include "osdep_service.h"
19 #include "drv_types.h"
20 #include "mlme_osdep.h"
21 #include "rtl871x_mp.h"
22 #include "rtl871x_mp_ioctl.h"
23
24 uint oid_null_function(struct oid_par_priv *poid_par_priv)
25 {
26         return RNDIS_STATUS_SUCCESS;
27 }
28
29 uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
30 {
31         uint status = RNDIS_STATUS_SUCCESS;
32         struct _adapter *Adapter = (struct _adapter *)
33                                    (poid_par_priv->adapter_context);
34
35         if (poid_par_priv->type_of_oid == SET_OID) {
36                 if (poid_par_priv->information_buf_len >= sizeof(u8))
37                         Adapter->registrypriv.wireless_mode =
38                                         *(u8 *)poid_par_priv->information_buf;
39                 else
40                         status = RNDIS_STATUS_INVALID_LENGTH;
41         } else if (poid_par_priv->type_of_oid == QUERY_OID) {
42                 if (poid_par_priv->information_buf_len >= sizeof(u8)) {
43                         *(u8 *)poid_par_priv->information_buf =
44                                          Adapter->registrypriv.wireless_mode;
45                         *poid_par_priv->bytes_rw =
46                                         poid_par_priv->information_buf_len;
47                 } else {
48                         status = RNDIS_STATUS_INVALID_LENGTH;
49                 }
50         } else {
51                 status = RNDIS_STATUS_NOT_ACCEPTED;
52         }
53         return status;
54 }
55
56 uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
57 {
58         struct _adapter *Adapter = (struct _adapter *)
59                                    (poid_par_priv->adapter_context);
60         struct bb_reg_param *pbbreg;
61         u16 offset;
62         u32 value;
63
64         if (poid_par_priv->type_of_oid != SET_OID)
65                 return RNDIS_STATUS_NOT_ACCEPTED;
66         if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
67                 return RNDIS_STATUS_INVALID_LENGTH;
68         pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
69         offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
70         if (offset < BB_REG_BASE_ADDR)
71                 offset |= BB_REG_BASE_ADDR;
72         value = pbbreg->value;
73         r8712_bb_reg_write(Adapter, offset, value);
74         return RNDIS_STATUS_SUCCESS;
75 }
76
77 uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
78 {
79         struct _adapter *Adapter = (struct _adapter *)
80                                    (poid_par_priv->adapter_context);
81         struct bb_reg_param *pbbreg;
82         u16 offset;
83         u32 value;
84
85         if (poid_par_priv->type_of_oid != QUERY_OID)
86                 return RNDIS_STATUS_NOT_ACCEPTED;
87         if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
88                 return RNDIS_STATUS_INVALID_LENGTH;
89         pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
90         offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
91         if (offset < BB_REG_BASE_ADDR)
92                 offset |= BB_REG_BASE_ADDR;
93         value = r8712_bb_reg_read(Adapter, offset);
94         pbbreg->value = value;
95         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
96         return RNDIS_STATUS_SUCCESS;
97 }
98
99 uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
100 {
101         struct _adapter *Adapter = (struct _adapter *)
102                                    (poid_par_priv->adapter_context);
103         struct rf_reg_param *pbbreg;
104         u8 path;
105         u8 offset;
106         u32 value;
107
108         if (poid_par_priv->type_of_oid != SET_OID)
109                 return RNDIS_STATUS_NOT_ACCEPTED;
110         if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
111                 return RNDIS_STATUS_INVALID_LENGTH;
112         pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
113         path = (u8)pbbreg->path;
114         if (path > RF_PATH_B)
115                 return RNDIS_STATUS_NOT_ACCEPTED;
116         offset = (u8)pbbreg->offset;
117         value = pbbreg->value;
118         r8712_rf_reg_write(Adapter, path, offset, value);
119         return RNDIS_STATUS_SUCCESS;
120 }
121
122 uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
123 {
124         struct _adapter *Adapter = (struct _adapter *)
125                                    (poid_par_priv->adapter_context);
126         struct rf_reg_param *pbbreg;
127         u8 path;
128         u8 offset;
129         u32 value;
130
131         if (poid_par_priv->type_of_oid != QUERY_OID)
132                 return RNDIS_STATUS_NOT_ACCEPTED;
133         if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
134                 return RNDIS_STATUS_INVALID_LENGTH;
135         pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
136         path = (u8)pbbreg->path;
137         if (path > RF_PATH_B) /* 1T2R  path_a /path_b */
138                 return RNDIS_STATUS_NOT_ACCEPTED;
139         offset = (u8)pbbreg->offset;
140         value = r8712_rf_reg_read(Adapter, path, offset);
141         pbbreg->value = value;
142         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
143         return RNDIS_STATUS_SUCCESS;
144 }
145
146 /*This function initializes the DUT to the MP test mode*/
147 static int mp_start_test(struct _adapter *padapter)
148 {
149         struct mp_priv *pmppriv = &padapter->mppriv;
150         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
151         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
152         struct wlan_bssid_ex bssid;
153         struct sta_info *psta;
154         unsigned long length;
155         unsigned long irqL;
156         int res = 0;
157
158         /* 3 1. initialize a new struct wlan_bssid_ex */
159         memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
160         bssid.Ssid.SsidLength = 16;
161         memcpy(bssid.Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc",
162                 bssid.Ssid.SsidLength);
163         bssid.InfrastructureMode = Ndis802_11IBSS;
164         bssid.NetworkTypeInUse = Ndis802_11DS;
165         bssid.IELength = 0;
166         length = r8712_get_wlan_bssid_ex_sz(&bssid);
167         if (length % 4) {
168                 /*round up to multiple of 4 bytes.*/
169                 bssid.Length = ((length >> 2) + 1) << 2;
170         } else {
171                 bssid.Length = length;
172         }
173         spin_lock_irqsave(&pmlmepriv->lock, irqL);
174         if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
175                 goto end_of_mp_start_test;
176         /*init mp_start_test status*/
177         pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
178         pmlmepriv->fw_state = WIFI_MP_STATE;
179         if (pmppriv->mode == _LOOPBOOK_MODE_)
180                 set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
181         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
182         /* 3 2. create a new psta for mp driver */
183         /* clear psta in the cur_network, if any */
184         psta = r8712_get_stainfo(&padapter->stapriv,
185                                  tgt_network->network.MacAddress);
186         if (psta)
187                 r8712_free_stainfo(padapter, psta);
188         psta = r8712_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
189         if (!psta) {
190                 res = -ENOMEM;
191                 goto end_of_mp_start_test;
192         }
193         /* 3 3. join pseudo AdHoc */
194         tgt_network->join_res = 1;
195         tgt_network->aid = psta->aid = 1;
196         memcpy(&tgt_network->network, &bssid, length);
197         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
198         r8712_os_indicate_connect(padapter);
199         /* Set to LINKED STATE for MP TRX Testing */
200         set_fwstate(pmlmepriv, _FW_LINKED);
201 end_of_mp_start_test:
202         spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
203         return res;
204 }
205
206 /*This function change the DUT from the MP test mode into normal mode */
207 static int mp_stop_test(struct _adapter *padapter)
208 {
209         struct mp_priv *pmppriv = &padapter->mppriv;
210         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
211         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
212         struct sta_info *psta;
213         unsigned long irqL;
214
215         spin_lock_irqsave(&pmlmepriv->lock, irqL);
216         if (!check_fwstate(pmlmepriv, WIFI_MP_STATE))
217                 goto end_of_mp_stop_test;
218         /* 3 1. disconnect pseudo AdHoc */
219         r8712_os_indicate_disconnect(padapter);
220         /* 3 2. clear psta used in mp test mode. */
221         psta = r8712_get_stainfo(&padapter->stapriv,
222                                  tgt_network->network.MacAddress);
223         if (psta)
224                 r8712_free_stainfo(padapter, psta);
225         /* 3 3. return to normal state (default:station mode) */
226         pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/
227         /*flush the cur_network*/
228         memset(tgt_network, 0, sizeof(struct wlan_network));
229 end_of_mp_stop_test:
230         spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
231         return _SUCCESS;
232 }
233
234 uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv)
235 {
236         struct _adapter *Adapter = (struct _adapter *)
237                                    (poid_par_priv->adapter_context);
238         u32 ratevalue;
239
240         if (poid_par_priv->type_of_oid != SET_OID)
241                 return RNDIS_STATUS_NOT_ACCEPTED;
242         if (poid_par_priv->information_buf_len != sizeof(u32))
243                 return RNDIS_STATUS_INVALID_LENGTH;
244         ratevalue = *((u32 *)poid_par_priv->information_buf);
245         if (ratevalue >= MPT_RATE_LAST)
246                 return RNDIS_STATUS_INVALID_DATA;
247         Adapter->mppriv.curr_rateidx = ratevalue;
248         r8712_SetDataRate(Adapter);
249         return RNDIS_STATUS_SUCCESS;
250 }
251
252 uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv)
253 {
254         struct _adapter *Adapter = (struct _adapter *)
255                                    (poid_par_priv->adapter_context);
256         uint status = RNDIS_STATUS_SUCCESS;
257         u32 mode;
258         u8 val8;
259
260         if (poid_par_priv->type_of_oid != SET_OID)
261                 return  RNDIS_STATUS_NOT_ACCEPTED;
262         mode = *((u32 *)poid_par_priv->information_buf);
263         Adapter->mppriv.mode = mode;/* 1 for loopback*/
264         if (mp_start_test(Adapter))
265                 status = RNDIS_STATUS_NOT_ACCEPTED;
266         r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */
267         r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */
268         /* RCR disable Check BSSID, 0x1025004a */
269         r8712_write8(Adapter, RCR + 2, 0x57);
270         /* disable RX filter map , mgt frames will put in RX FIFO 0 */
271         r8712_write16(Adapter, RXFLTMAP0, 0x0);
272         val8 = r8712_read8(Adapter, EE_9346CR);
273         if (!(val8 & _9356SEL)) { /*boot from EFUSE*/
274                 r8712_efuse_reg_init(Adapter);
275                 r8712_efuse_change_max_size(Adapter);
276                 r8712_efuse_reg_uninit(Adapter);
277         }
278         return status;
279 }
280
281 uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv)
282 {
283         struct _adapter *Adapter = (struct _adapter *)
284                                    (poid_par_priv->adapter_context);
285
286         if (poid_par_priv->type_of_oid != SET_OID)
287                 return RNDIS_STATUS_NOT_ACCEPTED;
288         if (mp_stop_test(Adapter) == _FAIL)
289                 return RNDIS_STATUS_NOT_ACCEPTED;
290         return RNDIS_STATUS_SUCCESS;
291 }
292
293 uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv)
294 {
295         struct _adapter *Adapter = (struct _adapter *)
296                                    (poid_par_priv->adapter_context);
297         u32             Channel;
298
299         if (poid_par_priv->type_of_oid != SET_OID)
300                 return RNDIS_STATUS_NOT_ACCEPTED;
301         if (poid_par_priv->information_buf_len != sizeof(u32))
302                 return RNDIS_STATUS_INVALID_LENGTH;
303         Channel = *((u32 *)poid_par_priv->information_buf);
304         if (Channel > 14)
305                 return RNDIS_STATUS_NOT_ACCEPTED;
306         Adapter->mppriv.curr_ch = Channel;
307         r8712_SetChannel(Adapter);
308         return RNDIS_STATUS_SUCCESS;
309 }
310
311 uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv)
312 {
313         struct _adapter *Adapter = (struct _adapter *)
314                                    (poid_par_priv->adapter_context);
315         u32 antenna;
316
317         if (poid_par_priv->type_of_oid != SET_OID)
318                 return RNDIS_STATUS_NOT_ACCEPTED;
319         if (poid_par_priv->information_buf_len != sizeof(u32))
320                 return RNDIS_STATUS_INVALID_LENGTH;
321         antenna = *((u32 *)poid_par_priv->information_buf);
322         Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16);
323         Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF);
324         r8712_SwitchAntenna(Adapter);
325         return RNDIS_STATUS_SUCCESS;
326 }
327
328 uint oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv)
329 {
330         struct _adapter *Adapter = (struct _adapter *)
331                                    (poid_par_priv->adapter_context);
332         u32 tx_pwr_idx;
333
334         if (poid_par_priv->type_of_oid != SET_OID)
335                 return RNDIS_STATUS_NOT_ACCEPTED;
336         if (poid_par_priv->information_buf_len != sizeof(u32))
337                 return RNDIS_STATUS_INVALID_LENGTH;
338         tx_pwr_idx = *((u32 *)poid_par_priv->information_buf);
339         if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE)
340                 return RNDIS_STATUS_NOT_ACCEPTED;
341         Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx;
342         r8712_SetTxPower(Adapter);
343         return RNDIS_STATUS_SUCCESS;
344 }
345
346 uint oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv)
347 {
348         struct _adapter *Adapter = (struct _adapter *)
349                                    (poid_par_priv->adapter_context);
350
351         if (poid_par_priv->type_of_oid != QUERY_OID)
352                 return RNDIS_STATUS_NOT_ACCEPTED;
353
354         if (poid_par_priv->information_buf_len == sizeof(u32)) {
355                 *(u32 *)poid_par_priv->information_buf =
356                                         Adapter->mppriv.tx_pktcount;
357                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
358         } else {
359                 return RNDIS_STATUS_INVALID_LENGTH;
360         }
361         return RNDIS_STATUS_SUCCESS;
362 }
363
364 uint oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
365 {
366         struct _adapter *Adapter = (struct _adapter *)
367                                    (poid_par_priv->adapter_context);
368
369         if (poid_par_priv->type_of_oid != QUERY_OID)
370                 return RNDIS_STATUS_NOT_ACCEPTED;
371
372         if (poid_par_priv->information_buf_len == sizeof(u32)) {
373                 *(u32 *)poid_par_priv->information_buf =
374                                         Adapter->mppriv.rx_pktcount;
375                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
376         } else {
377                 return RNDIS_STATUS_INVALID_LENGTH;
378         }
379         return RNDIS_STATUS_SUCCESS;
380 }
381
382 uint oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv)
383 {
384         struct _adapter *Adapter = (struct _adapter *)
385                                    (poid_par_priv->adapter_context);
386
387         if (poid_par_priv->type_of_oid != QUERY_OID)
388                 return RNDIS_STATUS_NOT_ACCEPTED;
389
390         if (poid_par_priv->information_buf_len == sizeof(u32)) {
391                 *(u32 *)poid_par_priv->information_buf =
392                                         Adapter->mppriv.rx_crcerrpktcount;
393                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
394         } else {
395                 return RNDIS_STATUS_INVALID_LENGTH;
396         }
397         return RNDIS_STATUS_SUCCESS;
398 }
399
400 uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv)
401 {
402         struct _adapter *Adapter = (struct _adapter *)
403                                    (poid_par_priv->adapter_context);
404
405         if (poid_par_priv->type_of_oid != SET_OID)
406                 return RNDIS_STATUS_NOT_ACCEPTED;
407         Adapter->mppriv.tx_pktcount = 0;
408         return RNDIS_STATUS_SUCCESS;
409 }
410
411 uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
412 {
413         struct _adapter *Adapter = (struct _adapter *)
414                                    (poid_par_priv->adapter_context);
415
416         if (poid_par_priv->type_of_oid != SET_OID)
417                 return RNDIS_STATUS_NOT_ACCEPTED;
418         if (poid_par_priv->information_buf_len == sizeof(u32)) {
419                 Adapter->mppriv.rx_pktcount = 0;
420                 Adapter->mppriv.rx_crcerrpktcount = 0;
421         } else {
422                 return RNDIS_STATUS_INVALID_LENGTH;
423         }
424         return RNDIS_STATUS_SUCCESS;
425 }
426
427 uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv)
428 {
429         struct _adapter *Adapter = (struct _adapter *)
430                                    (poid_par_priv->adapter_context);
431
432         if (poid_par_priv->type_of_oid != SET_OID)
433                 return RNDIS_STATUS_NOT_ACCEPTED;
434         r8712_ResetPhyRxPktCount(Adapter);
435         return RNDIS_STATUS_SUCCESS;
436 }
437
438 uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
439 {
440         struct _adapter *Adapter = (struct _adapter *)
441                                    (poid_par_priv->adapter_context);
442
443         if (poid_par_priv->type_of_oid != QUERY_OID)
444                 return RNDIS_STATUS_NOT_ACCEPTED;
445         if (poid_par_priv->information_buf_len != sizeof(u32))
446                 return RNDIS_STATUS_INVALID_LENGTH;
447         *(u32 *)poid_par_priv->information_buf =
448                                          r8712_GetPhyRxPktReceived(Adapter);
449         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
450         return RNDIS_STATUS_SUCCESS;
451 }
452
453 uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv)
454 {
455         struct _adapter *Adapter = (struct _adapter *)
456                                    (poid_par_priv->adapter_context);
457
458         if (poid_par_priv->type_of_oid != QUERY_OID)
459                 return RNDIS_STATUS_NOT_ACCEPTED;
460         if (poid_par_priv->information_buf_len != sizeof(u32))
461                 return RNDIS_STATUS_INVALID_LENGTH;
462         *(u32 *)poid_par_priv->information_buf =
463                                          r8712_GetPhyRxPktCRC32Error(Adapter);
464         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
465         return RNDIS_STATUS_SUCCESS;
466 }
467
468 uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv)
469 {
470         struct _adapter *Adapter = (struct _adapter *)
471                                    (poid_par_priv->adapter_context);
472
473         if (poid_par_priv->type_of_oid != SET_OID)
474                 return RNDIS_STATUS_NOT_ACCEPTED;
475
476         Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf);
477         return RNDIS_STATUS_SUCCESS;
478 }
479
480 uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv)
481 {
482         struct _adapter *Adapter = (struct _adapter *)
483                                    (poid_par_priv->adapter_context);
484         u32             bStartTest;
485
486         if (poid_par_priv->type_of_oid != SET_OID)
487                 return RNDIS_STATUS_NOT_ACCEPTED;
488         bStartTest = *((u32 *)poid_par_priv->information_buf);
489         r8712_SetContinuousTx(Adapter, (u8)bStartTest);
490         return RNDIS_STATUS_SUCCESS;
491 }
492
493 uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv)
494 {
495         struct _adapter *Adapter = (struct _adapter *)
496                                    (poid_par_priv->adapter_context);
497         u32             bStartTest;
498
499         if (poid_par_priv->type_of_oid != SET_OID)
500                 return RNDIS_STATUS_NOT_ACCEPTED;
501         bStartTest = *((u32 *)poid_par_priv->information_buf);
502         r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest);
503         return RNDIS_STATUS_SUCCESS;
504 }
505
506 uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv)
507 {
508         struct _adapter *Adapter = (struct _adapter *)
509                                    (poid_par_priv->adapter_context);
510         u32             bStartTest;
511
512         if (poid_par_priv->type_of_oid != SET_OID)
513                 return RNDIS_STATUS_NOT_ACCEPTED;
514         bStartTest = *((u32 *)poid_par_priv->information_buf);
515         r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest);
516         return RNDIS_STATUS_SUCCESS;
517 }
518
519 uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv)
520 {
521         struct _adapter *Adapter = (struct _adapter *)
522                                    (poid_par_priv->adapter_context);
523         u32             bStartTest;
524
525         if (poid_par_priv->type_of_oid != SET_OID)
526                 return RNDIS_STATUS_NOT_ACCEPTED;
527         bStartTest = *((u32 *)poid_par_priv->information_buf);
528         r8712_SetSingleToneTx(Adapter, (u8)bStartTest);
529         return RNDIS_STATUS_SUCCESS;
530 }
531
532 uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
533 {
534         struct _adapter *Adapter = (struct _adapter *)
535                                    (poid_par_priv->adapter_context);
536         uint status = RNDIS_STATUS_SUCCESS;
537         struct mp_rw_reg *RegRWStruct;
538         u16             offset;
539
540         if (poid_par_priv->type_of_oid != QUERY_OID)
541                 return RNDIS_STATUS_NOT_ACCEPTED;
542         RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
543         if ((RegRWStruct->offset >= 0x10250800) &&
544             (RegRWStruct->offset <= 0x10250FFF)) {
545                 /*baseband register*/
546                 /*0ffset :0x800~0xfff*/
547                 offset = (u16)(RegRWStruct->offset) & 0xFFF;
548                 RegRWStruct->value = r8712_bb_reg_read(Adapter, offset);
549         } else {
550                 switch (RegRWStruct->width) {
551                 case 1:
552                         RegRWStruct->value = r8712_read8(Adapter,
553                                                    RegRWStruct->offset);
554                         break;
555                 case 2:
556                         RegRWStruct->value = r8712_read16(Adapter,
557                                                     RegRWStruct->offset);
558                         break;
559                 case 4:
560                         RegRWStruct->value = r8712_read32(Adapter,
561                                                     RegRWStruct->offset);
562                         break;
563                 default:
564                         status = RNDIS_STATUS_NOT_ACCEPTED;
565                         break;
566                 }
567         }
568         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
569         return status;
570 }
571
572 uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
573 {
574         struct _adapter *Adapter = (struct _adapter *)
575                                    (poid_par_priv->adapter_context);
576         uint status = RNDIS_STATUS_SUCCESS;
577         struct mp_rw_reg *RegRWStruct;
578         u16             offset;
579         u32             value;
580         u32 oldValue = 0;
581
582         if (poid_par_priv->type_of_oid != SET_OID)
583                 return RNDIS_STATUS_NOT_ACCEPTED;
584         RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
585         if ((RegRWStruct->offset >= 0x10250800) &&
586             (RegRWStruct->offset <= 0x10250FFF)) {
587                 /*baseband register*/
588                 offset = (u16)(RegRWStruct->offset) & 0xFFF;
589                 value = RegRWStruct->value;
590                 switch (RegRWStruct->width) {
591                 case 1:
592                         oldValue = r8712_bb_reg_read(Adapter, offset);
593                         oldValue &= 0xFFFFFF00;
594                         value &= 0x000000FF;
595                         value |= oldValue;
596                         break;
597                 case 2:
598                         oldValue = r8712_bb_reg_read(Adapter, offset);
599                         oldValue &= 0xFFFF0000;
600                         value &= 0x0000FFFF;
601                         value |= oldValue;
602                         break;
603                 }
604                 r8712_bb_reg_write(Adapter, offset, value);
605         } else {
606                 switch (RegRWStruct->width) {
607                 case 1:
608                         r8712_write8(Adapter, RegRWStruct->offset,
609                                (unsigned char)RegRWStruct->value);
610                         break;
611                 case 2:
612                         r8712_write16(Adapter, RegRWStruct->offset,
613                                 (unsigned short)RegRWStruct->value);
614                         break;
615                 case 4:
616                         r8712_write32(Adapter, RegRWStruct->offset,
617                                 (unsigned int)RegRWStruct->value);
618                         break;
619                 default:
620                         status = RNDIS_STATUS_NOT_ACCEPTED;
621                         break;
622                 }
623         }
624         return status;
625 }
626
627 uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
628 {
629         struct _adapter *Adapter = (struct _adapter *)
630                                    (poid_par_priv->adapter_context);
631
632         if (poid_par_priv->type_of_oid != QUERY_OID)
633                 return RNDIS_STATUS_NOT_ACCEPTED;
634
635         if (Adapter->mppriv.act_in_progress)
636                 return RNDIS_STATUS_NOT_ACCEPTED;
637
638         if (poid_par_priv->information_buf_len < sizeof(u8))
639                 return RNDIS_STATUS_INVALID_LENGTH;
640         /*init workparam*/
641         Adapter->mppriv.act_in_progress = true;
642         Adapter->mppriv.workparam.bcompleted = false;
643         Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER;
644         Adapter->mppriv.workparam.io_offset = 0;
645         Adapter->mppriv.workparam.io_value = 0xFFFFFFFF;
646         r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value);
647         Adapter->mppriv.workparam.bcompleted = true;
648         Adapter->mppriv.act_in_progress = false;
649         *(u32 *)poid_par_priv->information_buf =
650                                  Adapter->mppriv.workparam.io_value;
651         *poid_par_priv->bytes_rw = sizeof(u32);
652         return RNDIS_STATUS_SUCCESS;
653 }
654
655 uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
656 {
657         struct _adapter *Adapter = (struct _adapter *)
658                                    (poid_par_priv->adapter_context);
659
660         uint status = RNDIS_STATUS_SUCCESS;
661
662         struct EFUSE_ACCESS_STRUCT *pefuse;
663         u8 *data;
664         u16 addr = 0, cnts = 0;
665
666         if (poid_par_priv->type_of_oid != QUERY_OID)
667                 return RNDIS_STATUS_NOT_ACCEPTED;
668         if (poid_par_priv->information_buf_len <
669             sizeof(struct EFUSE_ACCESS_STRUCT))
670                 return RNDIS_STATUS_INVALID_LENGTH;
671         pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
672         addr = pefuse->start_addr;
673         cnts = pefuse->cnts;
674         data = pefuse->data;
675         memset(data, 0xFF, cnts);
676         if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) >
677              EFUSE_MAX_SIZE)
678                 return RNDIS_STATUS_NOT_ACCEPTED;
679         if (!r8712_efuse_access(Adapter, true, addr, cnts, data))
680                 status = RNDIS_STATUS_FAILURE;
681         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
682         return status;
683 }
684
685 /*------------------------------------------------------------------------*/
686 uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
687 {
688         struct _adapter *Adapter = (struct _adapter *)
689                                    (poid_par_priv->adapter_context);
690
691         uint status = RNDIS_STATUS_SUCCESS;
692
693         struct EFUSE_ACCESS_STRUCT *pefuse;
694         u8 *data;
695         u16 addr = 0, cnts = 0;
696
697         if (poid_par_priv->type_of_oid != SET_OID)
698                 return RNDIS_STATUS_NOT_ACCEPTED;
699
700         pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
701         addr = pefuse->start_addr;
702         cnts = pefuse->cnts;
703         data = pefuse->data;
704
705         if ((addr > 511) || (cnts < 1) || (cnts > 512) ||
706             (addr + cnts) > r8712_efuse_get_max_size(Adapter))
707                 return RNDIS_STATUS_NOT_ACCEPTED;
708         if (!r8712_efuse_access(Adapter, false, addr, cnts, data))
709                 status = RNDIS_STATUS_FAILURE;
710         return status;
711 }
712
713 /*----------------------------------------------------------------------*/
714
715 uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv)
716 {
717         struct _adapter *Adapter = (struct _adapter *)
718                                    (poid_par_priv->adapter_context);
719
720         if (poid_par_priv->type_of_oid != QUERY_OID)
721                 return RNDIS_STATUS_NOT_ACCEPTED;
722         if (poid_par_priv->information_buf_len < sizeof(int))
723                 return RNDIS_STATUS_INVALID_LENGTH;
724         r8712_efuse_reg_init(Adapter);
725         *(int *)poid_par_priv->information_buf =
726                                  r8712_efuse_get_current_size(Adapter);
727         r8712_efuse_reg_uninit(Adapter);
728         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
729         return RNDIS_STATUS_SUCCESS;
730 }
731
732 uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv)
733 {
734         struct _adapter *Adapter = (struct _adapter *)
735                                    (poid_par_priv->adapter_context);
736
737         if (poid_par_priv->type_of_oid != QUERY_OID)
738                 return RNDIS_STATUS_NOT_ACCEPTED;
739         if (poid_par_priv->information_buf_len < sizeof(u32))
740                 return RNDIS_STATUS_INVALID_LENGTH;
741         *(int *)poid_par_priv->information_buf =
742                                          r8712_efuse_get_max_size(Adapter);
743         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
744         return RNDIS_STATUS_SUCCESS;
745 }
746
747 uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv)
748 {
749         uint status = RNDIS_STATUS_SUCCESS;
750
751         if (poid_par_priv->type_of_oid == QUERY_OID)
752                 status = oid_rt_pro_read_efuse_hdl(poid_par_priv);
753         else
754                 status = oid_rt_pro_write_efuse_hdl(poid_par_priv);
755         return status;
756 }
757
758 uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv)
759 {
760         struct _adapter *Adapter = (struct _adapter *)
761                                    (poid_par_priv->adapter_context);
762         uint status = RNDIS_STATUS_SUCCESS;
763         u8              *data;
764
765         *poid_par_priv->bytes_rw = 0;
766         if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE)
767                 return RNDIS_STATUS_INVALID_LENGTH;
768         data = (u8 *)poid_par_priv->information_buf;
769         if (poid_par_priv->type_of_oid == QUERY_OID) {
770                 if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data))
771                         *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
772                 else
773                         status = RNDIS_STATUS_FAILURE;
774         } else {
775                 /* SET_OID */
776                 if (r8712_efuse_reg_init(Adapter)) {
777                         if (r8712_efuse_map_write(Adapter, 0,
778                             EFUSE_MAP_MAX_SIZE, data))
779                                 *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
780                         else
781                                 status = RNDIS_STATUS_FAILURE;
782                         r8712_efuse_reg_uninit(Adapter);
783                 } else {
784                         status = RNDIS_STATUS_FAILURE;
785                 }
786         }
787         return status;
788 }
789
790 uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
791 {
792         struct _adapter *Adapter = (struct _adapter *)
793                                    (poid_par_priv->adapter_context);
794         u32             bandwidth;
795
796         if (poid_par_priv->type_of_oid != SET_OID)
797                 return RNDIS_STATUS_NOT_ACCEPTED;
798         if (poid_par_priv->information_buf_len < sizeof(u32))
799                 return RNDIS_STATUS_INVALID_LENGTH;
800         bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/
801         if (bandwidth != HT_CHANNEL_WIDTH_20)
802                 bandwidth = HT_CHANNEL_WIDTH_40;
803         Adapter->mppriv.curr_bandwidth = (u8)bandwidth;
804         r8712_SwitchBandwidth(Adapter);
805         return RNDIS_STATUS_SUCCESS;
806 }
807
808 uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
809 {
810         struct _adapter *Adapter = (struct _adapter *)
811                                    (poid_par_priv->adapter_context);
812         u8              rx_pkt_type;
813         u32             rcr_val32;
814
815         if (poid_par_priv->type_of_oid != SET_OID)
816                 return RNDIS_STATUS_NOT_ACCEPTED;
817         if (poid_par_priv->information_buf_len < sizeof(u8))
818                 return RNDIS_STATUS_INVALID_LENGTH;
819         rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/
820         rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/
821         rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP);
822         switch (rx_pkt_type) {
823         case RX_PKT_BROADCAST:
824                 rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
825                 break;
826         case RX_PKT_DEST_ADDR:
827                 rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
828                 break;
829         case RX_PKT_PHY_MATCH:
830                 rcr_val32 |= (RCR_APM | RCR_ACRC32);
831                 break;
832         default:
833                 rcr_val32 &= ~(RCR_AAP |
834                                RCR_APM |
835                                RCR_AM |
836                                RCR_AB |
837                                RCR_ACRC32);
838                 break;
839         }
840         if (rx_pkt_type == RX_PKT_DEST_ADDR)
841                 Adapter->mppriv.check_mp_pkt = 1;
842         else
843                 Adapter->mppriv.check_mp_pkt = 0;
844         r8712_write32(Adapter, RCR, rcr_val32);
845         return RNDIS_STATUS_SUCCESS;
846 }
847
848 /*--------------------------------------------------------------------------*/
849 /*Linux*/
850 unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
851 {
852         return _SUCCESS;
853 }
854
855 /*-------------------------------------------------------------------------*/
856 uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv)
857 {
858         if (poid_par_priv->type_of_oid != SET_OID)
859                 return RNDIS_STATUS_NOT_ACCEPTED;
860         /*CALL  the power_down function*/
861         return RNDIS_STATUS_SUCCESS;
862 }
863
864 /*-------------------------------------------------------------------------- */
865 uint oid_rt_get_power_mode_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         if (poid_par_priv->information_buf_len < sizeof(u32))
873                 return RNDIS_STATUS_INVALID_LENGTH;
874         *(int *)poid_par_priv->information_buf =
875                  Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL;
876         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
877         return RNDIS_STATUS_SUCCESS;
878 }