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_ioctl_rtl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  * rtl871x_ioctl_rtl.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 #define  _RTL871X_IOCTL_RTL_C_
18
19 #include <linux/rndis.h>
20 #include "osdep_service.h"
21 #include "drv_types.h"
22 #include "wlan_bssdef.h"
23 #include "wifi.h"
24 #include "rtl871x_ioctl.h"
25 #include "rtl871x_ioctl_set.h"
26 #include "rtl871x_ioctl_rtl.h"
27 #include "mp_custom_oid.h"
28 #include "rtl871x_mp.h"
29 #include "rtl871x_mp_ioctl.h"
30
31 uint oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv)
32 {
33         if (poid_par_priv->type_of_oid != QUERY_OID)
34                 return RNDIS_STATUS_NOT_ACCEPTED;
35         return RNDIS_STATUS_SUCCESS;
36 }
37
38 uint oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
39 {
40         struct _adapter *padapter = poid_par_priv->adapter_context;
41
42         if (poid_par_priv->type_of_oid != QUERY_OID)
43                 return RNDIS_STATUS_NOT_ACCEPTED;
44         if (poid_par_priv->information_buf_len >=  sizeof(u32)) {
45                 *(u32 *)poid_par_priv->information_buf =
46                                 padapter->recvpriv.rx_smallpacket_crcerr;
47                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
48         } else {
49                 return RNDIS_STATUS_INVALID_LENGTH;
50         }
51         return RNDIS_STATUS_SUCCESS;
52 }
53
54 uint oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
55 {
56         struct _adapter *padapter = poid_par_priv->adapter_context;
57
58         if (poid_par_priv->type_of_oid != QUERY_OID)
59                 return RNDIS_STATUS_NOT_ACCEPTED;
60         if (poid_par_priv->information_buf_len >=  sizeof(u32)) {
61                 *(u32 *)poid_par_priv->information_buf =
62                                 padapter->recvpriv.rx_middlepacket_crcerr;
63                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
64         } else {
65                 return RNDIS_STATUS_INVALID_LENGTH;
66         }
67         return RNDIS_STATUS_SUCCESS;
68 }
69
70 uint oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
71 {
72         struct _adapter *padapter = poid_par_priv->adapter_context;
73
74         if (poid_par_priv->type_of_oid != QUERY_OID)
75                 return RNDIS_STATUS_NOT_ACCEPTED;
76         if (poid_par_priv->information_buf_len >=  sizeof(u32)) {
77                 *(u32 *)poid_par_priv->information_buf =
78                                  padapter->recvpriv.rx_largepacket_crcerr;
79                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
80         } else {
81                 return RNDIS_STATUS_INVALID_LENGTH;
82         }
83         return RNDIS_STATUS_SUCCESS;
84 }
85
86 uint oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv)
87 {
88         if (poid_par_priv->type_of_oid != QUERY_OID)
89                 return RNDIS_STATUS_NOT_ACCEPTED;
90         return RNDIS_STATUS_SUCCESS;
91 }
92
93 uint oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv)
94 {
95         if (poid_par_priv->type_of_oid != QUERY_OID)
96                 return RNDIS_STATUS_NOT_ACCEPTED;
97         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
98         return RNDIS_STATUS_SUCCESS;
99 }
100
101 uint oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv)
102 {
103         struct _adapter *padapter = poid_par_priv->adapter_context;
104
105         if (poid_par_priv->type_of_oid != QUERY_OID)
106                 return RNDIS_STATUS_NOT_ACCEPTED;
107         if (poid_par_priv->information_buf_len >=  sizeof(u32)) {
108                 *(u32 *)poid_par_priv->information_buf =
109                                          padapter->recvpriv.rx_pkts +
110                                          padapter->recvpriv.rx_drop;
111                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
112         } else {
113                 return RNDIS_STATUS_INVALID_LENGTH;
114         }
115         return RNDIS_STATUS_SUCCESS;
116 }
117
118 uint oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv)
119 {
120         if (poid_par_priv->type_of_oid != QUERY_OID)
121                 return RNDIS_STATUS_NOT_ACCEPTED;
122         return RNDIS_STATUS_SUCCESS;
123 }
124
125 uint oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv)
126 {
127         if (poid_par_priv->type_of_oid != QUERY_OID)
128                 return RNDIS_STATUS_NOT_ACCEPTED;
129         return RNDIS_STATUS_SUCCESS;
130 }
131
132 uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
133 {
134         struct _adapter *padapter = poid_par_priv->adapter_context;
135
136         if (poid_par_priv->type_of_oid != QUERY_OID)
137                 return RNDIS_STATUS_NOT_ACCEPTED;
138         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
139                 *(uint *)poid_par_priv->information_buf =
140                                          padapter->recvpriv.rx_icv_err;
141                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
142         } else {
143                 return RNDIS_STATUS_INVALID_LENGTH;
144         }
145         return RNDIS_STATUS_SUCCESS;
146 }
147
148 uint oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv
149                                                 *poid_par_priv)
150 {
151         if (poid_par_priv->type_of_oid != SET_OID)
152                 return RNDIS_STATUS_NOT_ACCEPTED;
153         return RNDIS_STATUS_SUCCESS;
154 }
155
156 uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
157 {
158         struct _adapter *padapter = poid_par_priv->adapter_context;
159         u32 preamblemode = 0;
160
161         if (poid_par_priv->type_of_oid != QUERY_OID)
162                 return RNDIS_STATUS_NOT_ACCEPTED;
163         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
164                 if (padapter->registrypriv.preamble == PREAMBLE_LONG)
165                         preamblemode = 0;
166                 else if (padapter->registrypriv.preamble == PREAMBLE_AUTO)
167                         preamblemode = 1;
168                 else if (padapter->registrypriv.preamble == PREAMBLE_SHORT)
169                         preamblemode = 2;
170                 *(u32 *)poid_par_priv->information_buf = preamblemode;
171                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
172         } else {
173                 return RNDIS_STATUS_INVALID_LENGTH;
174         }
175         return RNDIS_STATUS_SUCCESS;
176 }
177
178 uint oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv)
179 {
180         if (poid_par_priv->type_of_oid != QUERY_OID)
181                 return RNDIS_STATUS_NOT_ACCEPTED;
182         return RNDIS_STATUS_SUCCESS;
183 }
184
185 uint oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv)
186 {
187         struct _adapter *padapter = poid_par_priv->adapter_context;
188         struct eeprom_priv *peeprompriv = &padapter->eeprompriv;
189
190         if (poid_par_priv->type_of_oid != QUERY_OID)
191                 return RNDIS_STATUS_NOT_ACCEPTED;
192         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
193         *(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan;
194         return RNDIS_STATUS_SUCCESS;
195 }
196
197 uint oid_rt_set_channelplan_hdl(struct oid_par_priv
198                                        *poid_par_priv)
199 {
200         struct _adapter *padapter = poid_par_priv->adapter_context;
201         struct eeprom_priv *peeprompriv = &padapter->eeprompriv;
202
203         if (poid_par_priv->type_of_oid != SET_OID)
204                 return RNDIS_STATUS_NOT_ACCEPTED;
205         peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf;
206         return RNDIS_STATUS_SUCCESS;
207 }
208
209 uint oid_rt_set_preamble_mode_hdl(struct oid_par_priv
210                                          *poid_par_priv)
211 {
212         struct _adapter *padapter = poid_par_priv->adapter_context;
213         u32 preamblemode = 0;
214
215         if (poid_par_priv->type_of_oid != SET_OID)
216                 return RNDIS_STATUS_NOT_ACCEPTED;
217         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
218                 preamblemode = *(u32 *)poid_par_priv->information_buf;
219                 if (preamblemode == 0)
220                         padapter->registrypriv.preamble = PREAMBLE_LONG;
221                 else if (preamblemode == 1)
222                         padapter->registrypriv.preamble = PREAMBLE_AUTO;
223                 else if (preamblemode == 2)
224                         padapter->registrypriv.preamble = PREAMBLE_SHORT;
225                 *(u32 *)poid_par_priv->information_buf = preamblemode;
226                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
227         } else {
228                 return RNDIS_STATUS_INVALID_LENGTH;
229         }
230         return RNDIS_STATUS_SUCCESS;
231 }
232
233 uint oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv)
234 {
235         if (poid_par_priv->type_of_oid != SET_OID)
236                 return RNDIS_STATUS_NOT_ACCEPTED;
237         return RNDIS_STATUS_SUCCESS;
238 }
239
240 uint oid_rt_dedicate_probe_hdl(struct oid_par_priv
241                                       *poid_par_priv)
242 {
243         return RNDIS_STATUS_SUCCESS;
244 }
245
246 uint oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv
247                                           *poid_par_priv)
248 {
249         struct _adapter *padapter = poid_par_priv->adapter_context;
250
251         if (poid_par_priv->type_of_oid != QUERY_OID)
252                 return RNDIS_STATUS_NOT_ACCEPTED;
253         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
254                 *(u32 *)poid_par_priv->information_buf =
255                                                  padapter->xmitpriv.tx_bytes;
256                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
257         } else {
258                 return RNDIS_STATUS_INVALID_LENGTH;
259         }
260         return RNDIS_STATUS_SUCCESS;
261 }
262
263 uint oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv
264                                           *poid_par_priv)
265 {
266         struct _adapter *padapter = poid_par_priv->adapter_context;
267
268         if (poid_par_priv->type_of_oid != QUERY_OID)
269                 return RNDIS_STATUS_NOT_ACCEPTED;
270         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
271                 *(u32 *)poid_par_priv->information_buf =
272                                            padapter->recvpriv.rx_bytes;
273                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
274         } else {
275                 return RNDIS_STATUS_INVALID_LENGTH;
276         }
277         return RNDIS_STATUS_SUCCESS;
278 }
279
280 uint oid_rt_current_tx_power_level_hdl(struct oid_par_priv
281                                               *poid_par_priv)
282 {
283         return RNDIS_STATUS_SUCCESS;
284 }
285
286 uint oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv
287                                                   *poid_par_priv)
288 {
289         if (poid_par_priv->type_of_oid != QUERY_OID)
290                 return RNDIS_STATUS_NOT_ACCEPTED;
291         return RNDIS_STATUS_SUCCESS;
292 }
293
294 uint oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv
295                                                *poid_par_priv)
296 {
297         if (poid_par_priv->type_of_oid != QUERY_OID)
298                 return RNDIS_STATUS_NOT_ACCEPTED;
299         return RNDIS_STATUS_SUCCESS;
300 }
301
302 uint oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv)
303 {
304         struct _adapter *padapter = poid_par_priv->adapter_context;
305         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
306         struct NDIS_802_11_CONFIGURATION *pnic_Config;
307         u32   channelnum;
308
309         if (poid_par_priv->type_of_oid != QUERY_OID)
310                 return RNDIS_STATUS_NOT_ACCEPTED;
311         if (check_fwstate(pmlmepriv, _FW_LINKED) ||
312             check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
313                 pnic_Config = &pmlmepriv->cur_network.network.Configuration;
314         else
315                 pnic_Config = &padapter->registrypriv.dev_network.Configuration;
316         channelnum = pnic_Config->DSConfig;
317         *(u32 *)poid_par_priv->information_buf = channelnum;
318         *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
319         return RNDIS_STATUS_SUCCESS;
320 }
321
322 uint oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv
323                          *poid_par_priv)
324 {
325         if (poid_par_priv->type_of_oid != QUERY_OID)
326                 return RNDIS_STATUS_NOT_ACCEPTED;
327         return RNDIS_STATUS_SUCCESS;
328 }
329
330 uint oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv)
331 {
332         if (poid_par_priv->type_of_oid != QUERY_OID)
333                 return RNDIS_STATUS_NOT_ACCEPTED;
334         return RNDIS_STATUS_SUCCESS;
335 }
336
337 uint oid_rt_supported_wireless_mode_hdl(struct oid_par_priv
338                                                *poid_par_priv)
339 {
340         u32 ulInfo = 0;
341
342         if (poid_par_priv->type_of_oid != QUERY_OID)
343                 return RNDIS_STATUS_NOT_ACCEPTED;
344         if (poid_par_priv->information_buf_len >= sizeof(u32)) {
345                 ulInfo |= 0x0100; /* WIRELESS_MODE_B */
346                 ulInfo |= 0x0200; /* WIRELESS_MODE_G */
347                 ulInfo |= 0x0400; /* WIRELESS_MODE_A */
348                 *(u32 *) poid_par_priv->information_buf = ulInfo;
349                 *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
350         } else {
351                 return RNDIS_STATUS_INVALID_LENGTH;
352         }
353         return RNDIS_STATUS_SUCCESS;
354 }
355
356 uint oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv)
357 {
358         if (poid_par_priv->type_of_oid != QUERY_OID)
359                 return RNDIS_STATUS_NOT_ACCEPTED;
360         return RNDIS_STATUS_SUCCESS;
361 }
362
363 uint oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv)
364 {
365         if (poid_par_priv->type_of_oid != QUERY_OID)
366                 return RNDIS_STATUS_NOT_ACCEPTED;
367         return RNDIS_STATUS_SUCCESS;
368 }
369
370
371 uint oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv)
372 {
373         return RNDIS_STATUS_SUCCESS;
374 }
375
376 uint oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv
377                                                    *poid_par_priv)
378 {
379         return RNDIS_STATUS_SUCCESS;
380 }
381
382 uint oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv
383                                              *poid_par_priv)
384 {
385         if (poid_par_priv->type_of_oid != QUERY_OID)
386                 return RNDIS_STATUS_NOT_ACCEPTED;
387         return RNDIS_STATUS_SUCCESS;
388 }
389
390 uint oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv
391                                               *poid_par_priv)
392 {
393         return RNDIS_STATUS_SUCCESS;
394 }
395
396 uint oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv
397                                                       *poid_par_priv)
398 {
399         if (poid_par_priv->type_of_oid != QUERY_OID)
400                 return RNDIS_STATUS_NOT_ACCEPTED;
401         return RNDIS_STATUS_SUCCESS;
402 }
403
404 uint oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv*
405                                               poid_par_priv)
406 {
407         return RNDIS_STATUS_SUCCESS;
408 }
409
410 uint oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv)
411 {
412         return RNDIS_STATUS_SUCCESS;
413 }
414
415 uint oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv)
416 {
417         if (poid_par_priv->type_of_oid != SET_OID)
418                 return RNDIS_STATUS_NOT_ACCEPTED;
419         return RNDIS_STATUS_SUCCESS;
420 }
421
422 uint oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv*
423                                              poid_par_priv)
424 {
425         uint status = RNDIS_STATUS_SUCCESS;
426         struct _adapter *Adapter = poid_par_priv->adapter_context;
427
428         if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
429                 return RNDIS_STATUS_NOT_ACCEPTED;
430         if (poid_par_priv->information_buf_len ==
431            (sizeof(unsigned long) * 3)) {
432                 if (r8712_setrfreg_cmd(Adapter,
433                         *(unsigned char *)poid_par_priv->information_buf,
434                         (unsigned long)(*((unsigned long *)
435                                         poid_par_priv->information_buf + 2))))
436                         status = RNDIS_STATUS_NOT_ACCEPTED;
437         } else {
438                 status = RNDIS_STATUS_INVALID_LENGTH;
439         }
440         return status;
441 }
442
443 uint oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv)
444 {
445         uint status = RNDIS_STATUS_SUCCESS;
446         struct _adapter *Adapter = poid_par_priv->adapter_context;
447
448         if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
449                 return RNDIS_STATUS_NOT_ACCEPTED;
450         if (poid_par_priv->information_buf_len == (sizeof(unsigned long) *
451                                                    3)) {
452                 if (Adapter->mppriv.act_in_progress) {
453                         status = RNDIS_STATUS_NOT_ACCEPTED;
454                 } else {
455                         /* init workparam */
456                         Adapter->mppriv.act_in_progress = true;
457                         Adapter->mppriv.workparam.bcompleted = false;
458                         Adapter->mppriv.workparam.act_type = MPT_READ_RF;
459                         Adapter->mppriv.workparam.io_offset = *(unsigned long *)
460                                                 poid_par_priv->information_buf;
461                         Adapter->mppriv.workparam.io_value = 0xcccccccc;
462
463                 /* RegOffsetValue       - The offset of RF register to read.
464                  * RegDataWidth - The data width of RF register to read.
465                  * RegDataValue - The value to read.
466                  * RegOffsetValue = *((unsigned long *)InformationBuffer);
467                  * RegDataWidth = *((unsigned long *)InformationBuffer+1);
468                  * RegDataValue =  *((unsigned long *)InformationBuffer+2);
469                  */
470                         if (r8712_getrfreg_cmd(Adapter,
471                             *(unsigned char *)poid_par_priv->information_buf,
472                             (unsigned char *)&Adapter->mppriv.workparam.io_value
473                             ))
474                                 status = RNDIS_STATUS_NOT_ACCEPTED;
475                 }
476         } else {
477                 status = RNDIS_STATUS_INVALID_LENGTH;
478         }
479         return status;
480 }
481
482 enum _CONNECT_STATE_ {
483         CHECKINGSTATUS,
484         ASSOCIATED,
485         ADHOCMODE,
486         NOTASSOCIATED
487 };
488
489 uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
490 {
491         struct _adapter *padapter = poid_par_priv->adapter_context;
492         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
493         u32 ulInfo;
494
495         if (poid_par_priv->type_of_oid != QUERY_OID)
496                 return RNDIS_STATUS_NOT_ACCEPTED;
497         /* nStatus==0   CheckingStatus
498          * nStatus==1   Associated
499          * nStatus==2   AdHocMode
500          * nStatus==3   NotAssociated
501          */
502         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
503                 ulInfo = CHECKINGSTATUS;
504         else if (check_fwstate(pmlmepriv, _FW_LINKED))
505                 ulInfo = ASSOCIATED;
506         else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
507                 ulInfo = ADHOCMODE;
508         else
509                 ulInfo = NOTASSOCIATED;
510         *(u32 *)poid_par_priv->information_buf = ulInfo;
511         *poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
512         return RNDIS_STATUS_SUCCESS;
513 }
514
515 uint oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv)
516 {
517         if (poid_par_priv->type_of_oid != SET_OID)
518                 return RNDIS_STATUS_NOT_ACCEPTED;
519         return RNDIS_STATUS_SUCCESS;
520 }