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