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