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