1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
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.
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
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
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
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"
36 uint
oid_null_function(struct oid_par_priv
*poid_par_priv
)
38 return RNDIS_STATUS_SUCCESS
;
41 uint
oid_rt_wireless_mode_hdl(struct oid_par_priv
*poid_par_priv
)
43 uint status
= RNDIS_STATUS_SUCCESS
;
44 struct _adapter
*Adapter
= (struct _adapter
*)
45 (poid_par_priv
->adapter_context
);
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
;
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
;
60 status
= RNDIS_STATUS_INVALID_LENGTH
;
63 status
= RNDIS_STATUS_NOT_ACCEPTED
;
68 uint
oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv
*poid_par_priv
)
70 struct _adapter
*Adapter
= (struct _adapter
*)
71 (poid_par_priv
->adapter_context
);
72 struct bb_reg_param
*pbbreg
;
76 if (poid_par_priv
->type_of_oid
!= SET_OID
)
77 return RNDIS_STATUS_NOT_ACCEPTED
;
78 if (poid_par_priv
->information_buf_len
< sizeof(struct bb_reg_param
))
79 return RNDIS_STATUS_INVALID_LENGTH
;
80 pbbreg
= (struct bb_reg_param
*)(poid_par_priv
->information_buf
);
81 offset
= (u16
)(pbbreg
->offset
) & 0xFFF; /*0ffset :0x800~0xfff*/
82 if (offset
< BB_REG_BASE_ADDR
)
83 offset
|= BB_REG_BASE_ADDR
;
84 value
= pbbreg
->value
;
85 r8712_bb_reg_write(Adapter
, offset
, value
);
86 return RNDIS_STATUS_SUCCESS
;
89 uint
oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv
*poid_par_priv
)
91 struct _adapter
*Adapter
= (struct _adapter
*)
92 (poid_par_priv
->adapter_context
);
93 struct bb_reg_param
*pbbreg
;
97 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
98 return RNDIS_STATUS_NOT_ACCEPTED
;
99 if (poid_par_priv
->information_buf_len
< sizeof(struct bb_reg_param
))
100 return RNDIS_STATUS_INVALID_LENGTH
;
101 pbbreg
= (struct bb_reg_param
*)(poid_par_priv
->information_buf
);
102 offset
= (u16
)(pbbreg
->offset
) & 0xFFF; /*0ffset :0x800~0xfff*/
103 if (offset
< BB_REG_BASE_ADDR
)
104 offset
|= BB_REG_BASE_ADDR
;
105 value
= r8712_bb_reg_read(Adapter
, offset
);
106 pbbreg
->value
= value
;
107 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
108 return RNDIS_STATUS_SUCCESS
;
111 uint
oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv
*poid_par_priv
)
113 struct _adapter
*Adapter
= (struct _adapter
*)
114 (poid_par_priv
->adapter_context
);
115 struct rf_reg_param
*pbbreg
;
120 if (poid_par_priv
->type_of_oid
!= SET_OID
)
121 return RNDIS_STATUS_NOT_ACCEPTED
;
122 if (poid_par_priv
->information_buf_len
< sizeof(struct rf_reg_param
))
123 return RNDIS_STATUS_INVALID_LENGTH
;
124 pbbreg
= (struct rf_reg_param
*)(poid_par_priv
->information_buf
);
125 path
= (u8
)pbbreg
->path
;
126 if (path
> RF_PATH_B
)
127 return RNDIS_STATUS_NOT_ACCEPTED
;
128 offset
= (u8
)pbbreg
->offset
;
129 value
= pbbreg
->value
;
130 r8712_rf_reg_write(Adapter
, path
, offset
, value
);
131 return RNDIS_STATUS_SUCCESS
;
134 uint
oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv
*poid_par_priv
)
136 struct _adapter
*Adapter
= (struct _adapter
*)
137 (poid_par_priv
->adapter_context
);
138 struct rf_reg_param
*pbbreg
;
143 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
144 return RNDIS_STATUS_NOT_ACCEPTED
;
145 if (poid_par_priv
->information_buf_len
< sizeof(struct rf_reg_param
))
146 return RNDIS_STATUS_INVALID_LENGTH
;
147 pbbreg
= (struct rf_reg_param
*)(poid_par_priv
->information_buf
);
148 path
= (u8
)pbbreg
->path
;
149 if (path
> RF_PATH_B
) /* 1T2R path_a /path_b */
150 return RNDIS_STATUS_NOT_ACCEPTED
;
151 offset
= (u8
)pbbreg
->offset
;
152 value
= r8712_rf_reg_read(Adapter
, path
, offset
);
153 pbbreg
->value
= value
;
154 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
155 return RNDIS_STATUS_SUCCESS
;
158 /*This function initializes the DUT to the MP test mode*/
159 static int mp_start_test(struct _adapter
*padapter
)
161 struct mp_priv
*pmppriv
= &padapter
->mppriv
;
162 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
163 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
164 struct wlan_bssid_ex bssid
;
165 struct sta_info
*psta
;
166 unsigned long length
;
170 /* 3 1. initialize a new struct wlan_bssid_ex */
171 memcpy(bssid
.MacAddress
, pmppriv
->network_macaddr
, ETH_ALEN
);
172 bssid
.Ssid
.SsidLength
= 16;
173 memcpy(bssid
.Ssid
.Ssid
, (unsigned char *)"mp_pseudo_adhoc",
174 bssid
.Ssid
.SsidLength
);
175 bssid
.InfrastructureMode
= Ndis802_11IBSS
;
176 bssid
.NetworkTypeInUse
= Ndis802_11DS
;
178 length
= r8712_get_wlan_bssid_ex_sz(&bssid
);
180 /*round up to multiple of 4 bytes.*/
181 bssid
.Length
= ((length
>> 2) + 1) << 2;
183 bssid
.Length
= length
;
185 spin_lock_irqsave(&pmlmepriv
->lock
, irqL
);
186 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
187 goto end_of_mp_start_test
;
188 /*init mp_start_test status*/
189 pmppriv
->prev_fw_state
= get_fwstate(pmlmepriv
);
190 pmlmepriv
->fw_state
= WIFI_MP_STATE
;
191 if (pmppriv
->mode
== _LOOPBOOK_MODE_
)
192 set_fwstate(pmlmepriv
, WIFI_MP_LPBK_STATE
); /*append txdesc*/
193 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
194 /* 3 2. create a new psta for mp driver */
195 /* clear psta in the cur_network, if any */
196 psta
= r8712_get_stainfo(&padapter
->stapriv
,
197 tgt_network
->network
.MacAddress
);
199 r8712_free_stainfo(padapter
, psta
);
200 psta
= r8712_alloc_stainfo(&padapter
->stapriv
, bssid
.MacAddress
);
203 goto end_of_mp_start_test
;
205 /* 3 3. join pseudo AdHoc */
206 tgt_network
->join_res
= 1;
207 tgt_network
->aid
= psta
->aid
= 1;
208 memcpy(&tgt_network
->network
, &bssid
, length
);
209 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
210 r8712_os_indicate_connect(padapter
);
211 /* Set to LINKED STATE for MP TRX Testing */
212 set_fwstate(pmlmepriv
, _FW_LINKED
);
213 end_of_mp_start_test
:
214 spin_unlock_irqrestore(&pmlmepriv
->lock
, irqL
);
218 /*This function change the DUT from the MP test mode into normal mode */
219 static int mp_stop_test(struct _adapter
*padapter
)
221 struct mp_priv
*pmppriv
= &padapter
->mppriv
;
222 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
223 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
224 struct sta_info
*psta
;
227 spin_lock_irqsave(&pmlmepriv
->lock
, irqL
);
228 if (!check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
229 goto end_of_mp_stop_test
;
230 /* 3 1. disconnect pseudo AdHoc */
231 r8712_os_indicate_disconnect(padapter
);
232 /* 3 2. clear psta used in mp test mode. */
233 psta
= r8712_get_stainfo(&padapter
->stapriv
,
234 tgt_network
->network
.MacAddress
);
236 r8712_free_stainfo(padapter
, psta
);
237 /* 3 3. return to normal state (default:station mode) */
238 pmlmepriv
->fw_state
= pmppriv
->prev_fw_state
; /* WIFI_STATION_STATE;*/
239 /*flush the cur_network*/
240 memset(tgt_network
, 0, sizeof(struct wlan_network
));
242 spin_unlock_irqrestore(&pmlmepriv
->lock
, irqL
);
246 int mp_start_joinbss(struct _adapter
*padapter
, struct ndis_802_11_ssid
*pssid
)
248 struct mp_priv
*pmppriv
= &padapter
->mppriv
;
249 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
250 unsigned char res
= _SUCCESS
;
252 if (!check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
254 if (!check_fwstate(pmlmepriv
, _FW_LINKED
))
256 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
257 res
= r8712_setassocsta_cmd(padapter
, pmppriv
->network_macaddr
);
258 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
262 uint
oid_rt_pro_set_data_rate_hdl(struct oid_par_priv
265 struct _adapter
*Adapter
= (struct _adapter
*)
266 (poid_par_priv
->adapter_context
);
269 if (poid_par_priv
->type_of_oid
!= SET_OID
)
270 return RNDIS_STATUS_NOT_ACCEPTED
;
271 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
272 return RNDIS_STATUS_INVALID_LENGTH
;
273 ratevalue
= *((u32
*)poid_par_priv
->information_buf
);
274 if (ratevalue
>= MPT_RATE_LAST
)
275 return RNDIS_STATUS_INVALID_DATA
;
276 Adapter
->mppriv
.curr_rateidx
= ratevalue
;
277 r8712_SetDataRate(Adapter
);
278 return RNDIS_STATUS_SUCCESS
;
281 uint
oid_rt_pro_start_test_hdl(struct oid_par_priv
*poid_par_priv
)
283 struct _adapter
*Adapter
= (struct _adapter
*)
284 (poid_par_priv
->adapter_context
);
285 uint status
= RNDIS_STATUS_SUCCESS
;
289 if (poid_par_priv
->type_of_oid
!= SET_OID
)
290 return RNDIS_STATUS_NOT_ACCEPTED
;
291 mode
= *((u32
*)poid_par_priv
->information_buf
);
292 Adapter
->mppriv
.mode
= mode
;/* 1 for loopback*/
293 if (mp_start_test(Adapter
) == _FAIL
)
294 status
= RNDIS_STATUS_NOT_ACCEPTED
;
295 r8712_write8(Adapter
, MSR
, 1); /* Link in ad hoc network, 0x1025004C */
296 r8712_write8(Adapter
, RCR
, 0); /* RCR : disable all pkt, 0x10250048 */
297 /* RCR disable Check BSSID, 0x1025004a */
298 r8712_write8(Adapter
, RCR
+ 2, 0x57);
299 /* disable RX filter map , mgt frames will put in RX FIFO 0 */
300 r8712_write16(Adapter
, RXFLTMAP0
, 0x0);
301 val8
= r8712_read8(Adapter
, EE_9346CR
);
302 if (!(val8
& _9356SEL
)) { /*boot from EFUSE*/
303 r8712_efuse_reg_init(Adapter
);
304 r8712_efuse_change_max_size(Adapter
);
305 r8712_efuse_reg_uninit(Adapter
);
310 uint
oid_rt_pro_stop_test_hdl(struct oid_par_priv
*poid_par_priv
)
312 struct _adapter
*Adapter
= (struct _adapter
*)
313 (poid_par_priv
->adapter_context
);
314 uint status
= RNDIS_STATUS_SUCCESS
;
316 if (poid_par_priv
->type_of_oid
!= SET_OID
)
317 return RNDIS_STATUS_NOT_ACCEPTED
;
318 if (mp_stop_test(Adapter
) == _FAIL
)
319 status
= RNDIS_STATUS_NOT_ACCEPTED
;
323 uint
oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv
326 struct _adapter
*Adapter
= (struct _adapter
*)
327 (poid_par_priv
->adapter_context
);
330 if (poid_par_priv
->type_of_oid
!= SET_OID
)
331 return RNDIS_STATUS_NOT_ACCEPTED
;
332 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
333 return RNDIS_STATUS_INVALID_LENGTH
;
334 Channel
= *((u32
*)poid_par_priv
->information_buf
);
336 return RNDIS_STATUS_NOT_ACCEPTED
;
337 Adapter
->mppriv
.curr_ch
= Channel
;
338 r8712_SetChannel(Adapter
);
339 return RNDIS_STATUS_SUCCESS
;
342 uint
oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv
*poid_par_priv
)
344 struct _adapter
*Adapter
= (struct _adapter
*)
345 (poid_par_priv
->adapter_context
);
348 if (poid_par_priv
->type_of_oid
!= SET_OID
)
349 return RNDIS_STATUS_NOT_ACCEPTED
;
350 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
351 return RNDIS_STATUS_INVALID_LENGTH
;
352 antenna
= *((u32
*)poid_par_priv
->information_buf
);
353 Adapter
->mppriv
.antenna_tx
= (u16
)((antenna
& 0xFFFF0000) >> 16);
354 Adapter
->mppriv
.antenna_rx
= (u16
)(antenna
& 0x0000FFFF);
355 r8712_SwitchAntenna(Adapter
);
356 return RNDIS_STATUS_SUCCESS
;
359 uint
oid_rt_pro_set_tx_power_control_hdl(
360 struct oid_par_priv
*poid_par_priv
)
362 struct _adapter
*Adapter
= (struct _adapter
*)
363 (poid_par_priv
->adapter_context
);
366 if (poid_par_priv
->type_of_oid
!= SET_OID
)
367 return RNDIS_STATUS_NOT_ACCEPTED
;
368 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
369 return RNDIS_STATUS_INVALID_LENGTH
;
370 tx_pwr_idx
= *((u32
*)poid_par_priv
->information_buf
);
371 if (tx_pwr_idx
> MAX_TX_PWR_INDEX_N_MODE
)
372 return RNDIS_STATUS_NOT_ACCEPTED
;
373 Adapter
->mppriv
.curr_txpoweridx
= (u8
)tx_pwr_idx
;
374 r8712_SetTxPower(Adapter
);
375 return RNDIS_STATUS_SUCCESS
;
378 uint
oid_rt_pro_query_tx_packet_sent_hdl(
379 struct oid_par_priv
*poid_par_priv
)
381 uint status
= RNDIS_STATUS_SUCCESS
;
382 struct _adapter
*Adapter
= (struct _adapter
*)
383 (poid_par_priv
->adapter_context
);
385 if (poid_par_priv
->type_of_oid
!= QUERY_OID
) {
386 status
= RNDIS_STATUS_NOT_ACCEPTED
;
389 if (poid_par_priv
->information_buf_len
== sizeof(u32
)) {
390 *(u32
*)poid_par_priv
->information_buf
=
391 Adapter
->mppriv
.tx_pktcount
;
392 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
394 status
= RNDIS_STATUS_INVALID_LENGTH
;
399 uint
oid_rt_pro_query_rx_packet_received_hdl(
400 struct oid_par_priv
*poid_par_priv
)
402 uint status
= RNDIS_STATUS_SUCCESS
;
403 struct _adapter
*Adapter
= (struct _adapter
*)
404 (poid_par_priv
->adapter_context
);
406 if (poid_par_priv
->type_of_oid
!= QUERY_OID
) {
407 status
= RNDIS_STATUS_NOT_ACCEPTED
;
410 if (poid_par_priv
->information_buf_len
== sizeof(u32
)) {
411 *(u32
*)poid_par_priv
->information_buf
=
412 Adapter
->mppriv
.rx_pktcount
;
413 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
415 status
= RNDIS_STATUS_INVALID_LENGTH
;
420 uint
oid_rt_pro_query_rx_packet_crc32_error_hdl(
421 struct oid_par_priv
*poid_par_priv
)
423 uint status
= RNDIS_STATUS_SUCCESS
;
424 struct _adapter
*Adapter
= (struct _adapter
*)
425 (poid_par_priv
->adapter_context
);
427 if (poid_par_priv
->type_of_oid
!= QUERY_OID
) {
428 status
= RNDIS_STATUS_NOT_ACCEPTED
;
431 if (poid_par_priv
->information_buf_len
== sizeof(u32
)) {
432 *(u32
*)poid_par_priv
->information_buf
=
433 Adapter
->mppriv
.rx_crcerrpktcount
;
434 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
436 status
= RNDIS_STATUS_INVALID_LENGTH
;
441 uint
oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv
444 struct _adapter
*Adapter
= (struct _adapter
*)
445 (poid_par_priv
->adapter_context
);
447 if (poid_par_priv
->type_of_oid
!= SET_OID
)
448 return RNDIS_STATUS_NOT_ACCEPTED
;
449 Adapter
->mppriv
.tx_pktcount
= 0;
450 return RNDIS_STATUS_SUCCESS
;
453 uint
oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv
456 uint status
= RNDIS_STATUS_SUCCESS
;
457 struct _adapter
*Adapter
= (struct _adapter
*)
458 (poid_par_priv
->adapter_context
);
460 if (poid_par_priv
->type_of_oid
!= SET_OID
)
461 return RNDIS_STATUS_NOT_ACCEPTED
;
462 if (poid_par_priv
->information_buf_len
== sizeof(u32
)) {
463 Adapter
->mppriv
.rx_pktcount
= 0;
464 Adapter
->mppriv
.rx_crcerrpktcount
= 0;
466 status
= RNDIS_STATUS_INVALID_LENGTH
;
471 uint
oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv
474 struct _adapter
*Adapter
= (struct _adapter
*)
475 (poid_par_priv
->adapter_context
);
477 if (poid_par_priv
->type_of_oid
!= SET_OID
)
478 return RNDIS_STATUS_NOT_ACCEPTED
;
479 r8712_ResetPhyRxPktCount(Adapter
);
480 return RNDIS_STATUS_SUCCESS
;
483 uint
oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv
486 struct _adapter
*Adapter
= (struct _adapter
*)
487 (poid_par_priv
->adapter_context
);
489 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
490 return RNDIS_STATUS_NOT_ACCEPTED
;
491 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
492 return RNDIS_STATUS_INVALID_LENGTH
;
493 *(u32
*)poid_par_priv
->information_buf
=
494 r8712_GetPhyRxPktReceived(Adapter
);
495 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
496 return RNDIS_STATUS_SUCCESS
;
499 uint
oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv
502 struct _adapter
*Adapter
= (struct _adapter
*)
503 (poid_par_priv
->adapter_context
);
505 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
506 return RNDIS_STATUS_NOT_ACCEPTED
;
507 if (poid_par_priv
->information_buf_len
!= sizeof(u32
))
508 return RNDIS_STATUS_INVALID_LENGTH
;
509 *(u32
*)poid_par_priv
->information_buf
=
510 r8712_GetPhyRxPktCRC32Error(Adapter
);
511 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
512 return RNDIS_STATUS_SUCCESS
;
515 uint
oid_rt_pro_set_modulation_hdl(struct oid_par_priv
518 struct _adapter
*Adapter
= (struct _adapter
*)
519 (poid_par_priv
->adapter_context
);
521 if (poid_par_priv
->type_of_oid
!= SET_OID
)
522 return RNDIS_STATUS_NOT_ACCEPTED
;
524 Adapter
->mppriv
.curr_modem
= *((u8
*)poid_par_priv
->information_buf
);
525 return RNDIS_STATUS_SUCCESS
;
528 uint
oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv
531 struct _adapter
*Adapter
= (struct _adapter
*)
532 (poid_par_priv
->adapter_context
);
535 if (poid_par_priv
->type_of_oid
!= SET_OID
)
536 return RNDIS_STATUS_NOT_ACCEPTED
;
537 bStartTest
= *((u32
*)poid_par_priv
->information_buf
);
538 r8712_SetContinuousTx(Adapter
, (u8
)bStartTest
);
539 return RNDIS_STATUS_SUCCESS
;
542 uint
oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv
545 struct _adapter
*Adapter
= (struct _adapter
*)
546 (poid_par_priv
->adapter_context
);
549 if (poid_par_priv
->type_of_oid
!= SET_OID
)
550 return RNDIS_STATUS_NOT_ACCEPTED
;
551 bStartTest
= *((u32
*)poid_par_priv
->information_buf
);
552 r8712_SetSingleCarrierTx(Adapter
, (u8
)bStartTest
);
553 return RNDIS_STATUS_SUCCESS
;
556 uint
oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv
559 struct _adapter
*Adapter
= (struct _adapter
*)
560 (poid_par_priv
->adapter_context
);
563 if (poid_par_priv
->type_of_oid
!= SET_OID
)
564 return RNDIS_STATUS_NOT_ACCEPTED
;
565 bStartTest
= *((u32
*)poid_par_priv
->information_buf
);
566 r8712_SetCarrierSuppressionTx(Adapter
, (u8
)bStartTest
);
567 return RNDIS_STATUS_SUCCESS
;
570 uint
oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
573 struct _adapter
*Adapter
= (struct _adapter
*)
574 (poid_par_priv
->adapter_context
);
577 if (poid_par_priv
->type_of_oid
!= SET_OID
)
578 return RNDIS_STATUS_NOT_ACCEPTED
;
579 bStartTest
= *((u32
*)poid_par_priv
->information_buf
);
580 r8712_SetSingleToneTx(Adapter
, (u8
)bStartTest
);
581 return RNDIS_STATUS_SUCCESS
;
584 uint
oid_rt_pro_read_register_hdl(struct oid_par_priv
587 struct _adapter
*Adapter
= (struct _adapter
*)
588 (poid_par_priv
->adapter_context
);
589 uint status
= RNDIS_STATUS_SUCCESS
;
590 struct mp_rw_reg
*RegRWStruct
;
593 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
594 return RNDIS_STATUS_NOT_ACCEPTED
;
595 RegRWStruct
= (struct mp_rw_reg
*)poid_par_priv
->information_buf
;
596 if ((RegRWStruct
->offset
>= 0x10250800) &&
597 (RegRWStruct
->offset
<= 0x10250FFF)) {
598 /*baseband register*/
599 /*0ffset :0x800~0xfff*/
600 offset
= (u16
)(RegRWStruct
->offset
) & 0xFFF;
601 RegRWStruct
->value
= r8712_bb_reg_read(Adapter
, offset
);
603 switch (RegRWStruct
->width
) {
605 RegRWStruct
->value
= r8712_read8(Adapter
,
606 RegRWStruct
->offset
);
609 RegRWStruct
->value
= r8712_read16(Adapter
,
610 RegRWStruct
->offset
);
613 RegRWStruct
->value
= r8712_read32(Adapter
,
614 RegRWStruct
->offset
);
617 status
= RNDIS_STATUS_NOT_ACCEPTED
;
621 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
625 uint
oid_rt_pro_write_register_hdl(struct oid_par_priv
*poid_par_priv
)
627 struct _adapter
*Adapter
= (struct _adapter
*)
628 (poid_par_priv
->adapter_context
);
629 uint status
= RNDIS_STATUS_SUCCESS
;
630 struct mp_rw_reg
*RegRWStruct
;
635 if (poid_par_priv
->type_of_oid
!= SET_OID
)
636 return RNDIS_STATUS_NOT_ACCEPTED
;
637 RegRWStruct
= (struct mp_rw_reg
*)poid_par_priv
->information_buf
;
638 if ((RegRWStruct
->offset
>= 0x10250800) &&
639 (RegRWStruct
->offset
<= 0x10250FFF)) {
640 /*baseband register*/
641 offset
= (u16
)(RegRWStruct
->offset
) & 0xFFF;
642 value
= RegRWStruct
->value
;
643 switch (RegRWStruct
->width
) {
645 oldValue
= r8712_bb_reg_read(Adapter
, offset
);
646 oldValue
&= 0xFFFFFF00;
651 oldValue
= r8712_bb_reg_read(Adapter
, offset
);
652 oldValue
&= 0xFFFF0000;
657 r8712_bb_reg_write(Adapter
, offset
, value
);
659 switch (RegRWStruct
->width
) {
661 r8712_write8(Adapter
, RegRWStruct
->offset
,
662 (unsigned char)RegRWStruct
->value
);
665 r8712_write16(Adapter
, RegRWStruct
->offset
,
666 (unsigned short)RegRWStruct
->value
);
669 r8712_write32(Adapter
, RegRWStruct
->offset
,
670 (unsigned int)RegRWStruct
->value
);
673 status
= RNDIS_STATUS_NOT_ACCEPTED
;
677 if ((status
== RNDIS_STATUS_SUCCESS
) &&
678 (RegRWStruct
->offset
== HIMR
) &&
679 (RegRWStruct
->width
== 4))
680 Adapter
->ImrContent
= RegRWStruct
->value
;
685 uint
oid_rt_get_thermal_meter_hdl(struct oid_par_priv
*poid_par_priv
)
687 struct _adapter
*Adapter
= (struct _adapter
*)
688 (poid_par_priv
->adapter_context
);
690 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
691 return RNDIS_STATUS_NOT_ACCEPTED
;
693 if (Adapter
->mppriv
.act_in_progress
)
694 return RNDIS_STATUS_NOT_ACCEPTED
;
696 if (poid_par_priv
->information_buf_len
< sizeof(u8
))
697 return RNDIS_STATUS_INVALID_LENGTH
;
699 Adapter
->mppriv
.act_in_progress
= true;
700 Adapter
->mppriv
.workparam
.bcompleted
= false;
701 Adapter
->mppriv
.workparam
.act_type
= MPT_GET_THERMAL_METER
;
702 Adapter
->mppriv
.workparam
.io_offset
= 0;
703 Adapter
->mppriv
.workparam
.io_value
= 0xFFFFFFFF;
704 r8712_GetThermalMeter(Adapter
, &Adapter
->mppriv
.workparam
.io_value
);
705 Adapter
->mppriv
.workparam
.bcompleted
= true;
706 Adapter
->mppriv
.act_in_progress
= false;
707 *(u32
*)poid_par_priv
->information_buf
=
708 Adapter
->mppriv
.workparam
.io_value
;
709 *poid_par_priv
->bytes_rw
= sizeof(u32
);
710 return RNDIS_STATUS_SUCCESS
;
713 uint
oid_rt_pro_read_efuse_hdl(struct oid_par_priv
*poid_par_priv
)
715 struct _adapter
*Adapter
= (struct _adapter
*)
716 (poid_par_priv
->adapter_context
);
718 uint status
= RNDIS_STATUS_SUCCESS
;
720 struct EFUSE_ACCESS_STRUCT
*pefuse
;
722 u16 addr
= 0, cnts
= 0;
724 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
725 return RNDIS_STATUS_NOT_ACCEPTED
;
726 if (poid_par_priv
->information_buf_len
<
727 sizeof(struct EFUSE_ACCESS_STRUCT
))
728 return RNDIS_STATUS_INVALID_LENGTH
;
729 pefuse
= (struct EFUSE_ACCESS_STRUCT
*)poid_par_priv
->information_buf
;
730 addr
= pefuse
->start_addr
;
733 memset(data
, 0xFF, cnts
);
734 if ((addr
> 511) || (cnts
< 1) || (cnts
> 512) || (addr
+ cnts
) >
736 return RNDIS_STATUS_NOT_ACCEPTED
;
737 if (!r8712_efuse_access(Adapter
, true, addr
, cnts
, data
))
738 status
= RNDIS_STATUS_FAILURE
;
739 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
742 /*------------------------------------------------------------------------*/
743 uint
oid_rt_pro_write_efuse_hdl(struct oid_par_priv
*poid_par_priv
)
745 struct _adapter
*Adapter
= (struct _adapter
*)
746 (poid_par_priv
->adapter_context
);
748 uint status
= RNDIS_STATUS_SUCCESS
;
750 struct EFUSE_ACCESS_STRUCT
*pefuse
;
752 u16 addr
= 0, cnts
= 0;
754 if (poid_par_priv
->type_of_oid
!= SET_OID
)
755 return RNDIS_STATUS_NOT_ACCEPTED
;
757 pefuse
= (struct EFUSE_ACCESS_STRUCT
*)poid_par_priv
->information_buf
;
758 addr
= pefuse
->start_addr
;
762 if ((addr
> 511) || (cnts
< 1) || (cnts
> 512) ||
763 (addr
+ cnts
) > r8712_efuse_get_max_size(Adapter
))
764 return RNDIS_STATUS_NOT_ACCEPTED
;
765 if (!r8712_efuse_access(Adapter
, false, addr
, cnts
, data
))
766 status
= RNDIS_STATUS_FAILURE
;
769 /*----------------------------------------------------------------------*/
771 uint
oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
774 struct _adapter
*Adapter
= (struct _adapter
*)
775 (poid_par_priv
->adapter_context
);
777 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
778 return RNDIS_STATUS_NOT_ACCEPTED
;
779 if (poid_par_priv
->information_buf_len
< sizeof(int))
780 return RNDIS_STATUS_INVALID_LENGTH
;
781 r8712_efuse_reg_init(Adapter
);
782 *(int *)poid_par_priv
->information_buf
=
783 r8712_efuse_get_current_size(Adapter
);
784 r8712_efuse_reg_uninit(Adapter
);
785 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
786 return RNDIS_STATUS_SUCCESS
;
789 uint
oid_rt_get_efuse_max_size_hdl(struct oid_par_priv
*poid_par_priv
)
791 struct _adapter
*Adapter
= (struct _adapter
*)
792 (poid_par_priv
->adapter_context
);
794 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
795 return RNDIS_STATUS_NOT_ACCEPTED
;
796 if (poid_par_priv
->information_buf_len
< sizeof(u32
))
797 return RNDIS_STATUS_INVALID_LENGTH
;
798 *(int *)poid_par_priv
->information_buf
=
799 r8712_efuse_get_max_size(Adapter
);
800 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
801 return RNDIS_STATUS_SUCCESS
;
804 uint
oid_rt_pro_efuse_hdl(struct oid_par_priv
*poid_par_priv
)
806 uint status
= RNDIS_STATUS_SUCCESS
;
808 if (poid_par_priv
->type_of_oid
== QUERY_OID
)
809 status
= oid_rt_pro_read_efuse_hdl(poid_par_priv
);
811 status
= oid_rt_pro_write_efuse_hdl(poid_par_priv
);
815 uint
oid_rt_pro_efuse_map_hdl(struct oid_par_priv
*poid_par_priv
)
817 struct _adapter
*Adapter
= (struct _adapter
*)
818 (poid_par_priv
->adapter_context
);
819 uint status
= RNDIS_STATUS_SUCCESS
;
822 *poid_par_priv
->bytes_rw
= 0;
823 if (poid_par_priv
->information_buf_len
< EFUSE_MAP_MAX_SIZE
)
824 return RNDIS_STATUS_INVALID_LENGTH
;
825 data
= (u8
*)poid_par_priv
->information_buf
;
826 if (poid_par_priv
->type_of_oid
== QUERY_OID
) {
827 if (r8712_efuse_map_read(Adapter
, 0, EFUSE_MAP_MAX_SIZE
, data
))
828 *poid_par_priv
->bytes_rw
= EFUSE_MAP_MAX_SIZE
;
830 status
= RNDIS_STATUS_FAILURE
;
833 if (r8712_efuse_reg_init(Adapter
)) {
834 if (r8712_efuse_map_write(Adapter
, 0,
835 EFUSE_MAP_MAX_SIZE
, data
))
836 *poid_par_priv
->bytes_rw
= EFUSE_MAP_MAX_SIZE
;
838 status
= RNDIS_STATUS_FAILURE
;
839 r8712_efuse_reg_uninit(Adapter
);
841 status
= RNDIS_STATUS_FAILURE
;
847 uint
oid_rt_set_bandwidth_hdl(struct oid_par_priv
*poid_par_priv
)
849 struct _adapter
*Adapter
= (struct _adapter
*)
850 (poid_par_priv
->adapter_context
);
853 if (poid_par_priv
->type_of_oid
!= SET_OID
)
854 return RNDIS_STATUS_NOT_ACCEPTED
;
855 if (poid_par_priv
->information_buf_len
< sizeof(u32
))
856 return RNDIS_STATUS_INVALID_LENGTH
;
857 bandwidth
= *((u32
*)poid_par_priv
->information_buf
);/*4*/
858 if (bandwidth
!= HT_CHANNEL_WIDTH_20
)
859 bandwidth
= HT_CHANNEL_WIDTH_40
;
860 Adapter
->mppriv
.curr_bandwidth
= (u8
)bandwidth
;
861 r8712_SwitchBandwidth(Adapter
);
862 return RNDIS_STATUS_SUCCESS
;
865 uint
oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
868 struct _adapter
*Adapter
= (struct _adapter
*)
869 (poid_par_priv
->adapter_context
);
873 if (poid_par_priv
->type_of_oid
!= SET_OID
)
874 return RNDIS_STATUS_NOT_ACCEPTED
;
875 if (poid_par_priv
->information_buf_len
< sizeof(u8
))
876 return RNDIS_STATUS_INVALID_LENGTH
;
877 rx_pkt_type
= *((u8
*)poid_par_priv
->information_buf
);/*4*/
878 rcr_val32
= r8712_read32(Adapter
, RCR
);/*RCR = 0x10250048*/
879 rcr_val32
&= ~(RCR_CBSSID
| RCR_AB
| RCR_AM
| RCR_APM
| RCR_AAP
);
880 switch (rx_pkt_type
) {
881 case RX_PKT_BROADCAST
:
882 rcr_val32
|= (RCR_AB
| RCR_AM
| RCR_APM
| RCR_AAP
| RCR_ACRC32
);
884 case RX_PKT_DEST_ADDR
:
885 rcr_val32
|= (RCR_AB
| RCR_AM
| RCR_APM
| RCR_AAP
| RCR_ACRC32
);
887 case RX_PKT_PHY_MATCH
:
888 rcr_val32
|= (RCR_APM
| RCR_ACRC32
);
891 rcr_val32
&= ~(RCR_AAP
|
898 if (rx_pkt_type
== RX_PKT_DEST_ADDR
)
899 Adapter
->mppriv
.check_mp_pkt
= 1;
901 Adapter
->mppriv
.check_mp_pkt
= 0;
902 r8712_write32(Adapter
, RCR
, rcr_val32
);
903 return RNDIS_STATUS_SUCCESS
;
906 /*--------------------------------------------------------------------------*/
908 unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv
*poid_par_priv
)
912 /*-------------------------------------------------------------------------*/
913 uint
oid_rt_set_power_down_hdl(struct oid_par_priv
*poid_par_priv
)
915 if (poid_par_priv
->type_of_oid
!= SET_OID
)
916 return RNDIS_STATUS_NOT_ACCEPTED
;
917 /*CALL the power_down function*/
918 return RNDIS_STATUS_SUCCESS
;
921 /*-------------------------------------------------------------------------- */
922 uint
oid_rt_get_power_mode_hdl(struct oid_par_priv
*poid_par_priv
)
924 struct _adapter
*Adapter
= (struct _adapter
*)
925 (poid_par_priv
->adapter_context
);
927 if (poid_par_priv
->type_of_oid
!= QUERY_OID
)
928 return RNDIS_STATUS_NOT_ACCEPTED
;
929 if (poid_par_priv
->information_buf_len
< sizeof(u32
))
930 return RNDIS_STATUS_INVALID_LENGTH
;
931 *(int *)poid_par_priv
->information_buf
=
932 Adapter
->registrypriv
.low_power
? POWER_LOW
: POWER_NORMAL
;
933 *poid_par_priv
->bytes_rw
= poid_par_priv
->information_buf_len
;
934 return RNDIS_STATUS_SUCCESS
;