linux/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
<<
>>
Prefs
   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
  36uint oid_null_function(struct oid_par_priv *poid_par_priv)
  37{
  38        return RNDIS_STATUS_SUCCESS;
  39}
  40
  41uint 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
  67uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
  68{
  69        uint status = RNDIS_STATUS_SUCCESS;
  70        struct _adapter *Adapter = (struct _adapter *)
  71                                   (poid_par_priv->adapter_context);
  72        struct bb_reg_param *pbbreg;
  73        u16 offset;
  74        u32 value;
  75
  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 status;
  87}
  88
  89uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
  90{
  91        uint status = RNDIS_STATUS_SUCCESS;
  92        struct _adapter *Adapter = (struct _adapter *)
  93                                   (poid_par_priv->adapter_context);
  94        struct bb_reg_param *pbbreg;
  95        u16 offset;
  96        u32 value;
  97
  98        if (poid_par_priv->type_of_oid != QUERY_OID)
  99                return RNDIS_STATUS_NOT_ACCEPTED;
 100        if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
 101                return RNDIS_STATUS_INVALID_LENGTH;
 102        pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
 103        offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
 104        if (offset < BB_REG_BASE_ADDR)
 105                offset |= BB_REG_BASE_ADDR;
 106        value = r8712_bb_reg_read(Adapter, offset);
 107        pbbreg->value = value;
 108        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 109        return status;
 110}
 111
 112uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
 113{
 114        uint status = RNDIS_STATUS_SUCCESS;
 115        struct _adapter *Adapter = (struct _adapter *)
 116                                   (poid_par_priv->adapter_context);
 117        struct rf_reg_param *pbbreg;
 118        u8 path;
 119        u8 offset;
 120        u32 value;
 121
 122        if (poid_par_priv->type_of_oid != SET_OID)
 123                return RNDIS_STATUS_NOT_ACCEPTED;
 124        if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
 125                return RNDIS_STATUS_INVALID_LENGTH;
 126        pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
 127        path = (u8)pbbreg->path;
 128        if (path > RF_PATH_B)
 129                return RNDIS_STATUS_NOT_ACCEPTED;
 130        offset = (u8)pbbreg->offset;
 131        value = pbbreg->value;
 132        r8712_rf_reg_write(Adapter, path, offset, value);
 133        return status;
 134}
 135
 136uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
 137{
 138        struct _adapter *Adapter = (struct _adapter *)
 139                                   (poid_par_priv->adapter_context);
 140        uint status = RNDIS_STATUS_SUCCESS;
 141        struct rf_reg_param *pbbreg;
 142        u8 path;
 143        u8 offset;
 144        u32 value;
 145
 146        if (poid_par_priv->type_of_oid != QUERY_OID)
 147                return RNDIS_STATUS_NOT_ACCEPTED;
 148        if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
 149                return RNDIS_STATUS_INVALID_LENGTH;
 150        pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
 151        path = (u8)pbbreg->path;
 152        if (path > RF_PATH_B) /* 1T2R  path_a /path_b */
 153                return RNDIS_STATUS_NOT_ACCEPTED;
 154        offset = (u8)pbbreg->offset;
 155        value = r8712_rf_reg_read(Adapter, path, offset);
 156        pbbreg->value = value;
 157        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 158        return status;
 159}
 160
 161/*This function initializes the DUT to the MP test mode*/
 162static int mp_start_test(struct _adapter *padapter)
 163{
 164        struct mp_priv *pmppriv = &padapter->mppriv;
 165        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 166        struct wlan_network *tgt_network = &pmlmepriv->cur_network;
 167        struct ndis_wlan_bssid_ex bssid;
 168        struct sta_info *psta;
 169        unsigned long length;
 170        unsigned long irqL;
 171        int res = _SUCCESS;
 172
 173        /* 3 1. initialize a new struct ndis_wlan_bssid_ex */
 174        memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
 175        bssid.Ssid.SsidLength = 16;
 176        memcpy(bssid.Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc",
 177                bssid.Ssid.SsidLength);
 178        bssid.InfrastructureMode = Ndis802_11IBSS;
 179        bssid.NetworkTypeInUse = Ndis802_11DS;
 180        bssid.IELength = 0;
 181        length = r8712_get_ndis_wlan_bssid_ex_sz(&bssid);
 182        if (length % 4) {
 183                /*round up to multiple of 4 bytes.*/
 184                bssid.Length = ((length >> 2) + 1) << 2;
 185        } else
 186                bssid.Length = length;
 187        spin_lock_irqsave(&pmlmepriv->lock, irqL);
 188        if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
 189                goto end_of_mp_start_test;
 190        /*init mp_start_test status*/
 191        pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
 192        pmlmepriv->fw_state = WIFI_MP_STATE;
 193        if (pmppriv->mode == _LOOPBOOK_MODE_)
 194                set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
 195        set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
 196        /* 3 2. create a new psta for mp driver */
 197        /* clear psta in the cur_network, if any */
 198        psta = r8712_get_stainfo(&padapter->stapriv,
 199                                 tgt_network->network.MacAddress);
 200        if (psta)
 201                r8712_free_stainfo(padapter, psta);
 202        psta = r8712_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
 203        if (psta == NULL) {
 204                res = _FAIL;
 205                goto end_of_mp_start_test;
 206        }
 207        /* 3 3. join psudo AdHoc */
 208        tgt_network->join_res = 1;
 209        tgt_network->aid = psta->aid = 1;
 210        memcpy(&tgt_network->network, &bssid, length);
 211        _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
 212        r8712_os_indicate_connect(padapter);
 213        /* Set to LINKED STATE for MP TRX Testing */
 214        set_fwstate(pmlmepriv, _FW_LINKED);
 215end_of_mp_start_test:
 216        spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
 217        return res;
 218}
 219
 220/*This function change the DUT from the MP test mode into normal mode */
 221static int mp_stop_test(struct _adapter *padapter)
 222{
 223        struct mp_priv *pmppriv = &padapter->mppriv;
 224        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 225        struct wlan_network *tgt_network = &pmlmepriv->cur_network;
 226        struct sta_info *psta;
 227        unsigned long irqL;
 228
 229        spin_lock_irqsave(&pmlmepriv->lock, irqL);
 230        if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
 231                goto end_of_mp_stop_test;
 232        /* 3 1. disconnect psudo AdHoc */
 233        r8712_os_indicate_disconnect(padapter);
 234        /* 3 2. clear psta used in mp test mode. */
 235        psta = r8712_get_stainfo(&padapter->stapriv,
 236                                 tgt_network->network.MacAddress);
 237        if (psta)
 238                r8712_free_stainfo(padapter, psta);
 239        /* 3 3. return to normal state (default:station mode) */
 240        pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/
 241        /*flush the cur_network*/
 242        memset(tgt_network, 0, sizeof(struct wlan_network));
 243end_of_mp_stop_test:
 244        spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
 245        return _SUCCESS;
 246}
 247
 248int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid)
 249{
 250        struct mp_priv *pmppriv = &padapter->mppriv;
 251        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 252        unsigned char res = _SUCCESS;
 253
 254        if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
 255                return _FAIL;
 256        if (check_fwstate(pmlmepriv, _FW_LINKED) == false)
 257                return _FAIL;
 258        _clr_fwstate_(pmlmepriv, _FW_LINKED);
 259        res = r8712_setassocsta_cmd(padapter, pmppriv->network_macaddr);
 260        set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
 261        return res;
 262}
 263
 264uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv
 265                                         *poid_par_priv)
 266{
 267        struct _adapter *Adapter = (struct _adapter *)
 268                                   (poid_par_priv->adapter_context);
 269        uint status = RNDIS_STATUS_SUCCESS;
 270        u32 ratevalue;
 271
 272        if (poid_par_priv->type_of_oid != SET_OID)
 273                return RNDIS_STATUS_NOT_ACCEPTED;
 274        if (poid_par_priv->information_buf_len != sizeof(u32))
 275                return RNDIS_STATUS_INVALID_LENGTH;
 276        ratevalue = *((u32 *)poid_par_priv->information_buf);
 277        if (ratevalue >= MPT_RATE_LAST)
 278                return RNDIS_STATUS_INVALID_DATA;
 279        Adapter->mppriv.curr_rateidx = ratevalue;
 280        r8712_SetDataRate(Adapter);
 281        return status;
 282}
 283
 284uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv)
 285{
 286        struct _adapter *Adapter = (struct _adapter *)
 287                                   (poid_par_priv->adapter_context);
 288        uint status = RNDIS_STATUS_SUCCESS;
 289        u32 mode;
 290        u8 val8;
 291
 292        if (poid_par_priv->type_of_oid != SET_OID)
 293                return  RNDIS_STATUS_NOT_ACCEPTED;
 294        mode = *((u32 *)poid_par_priv->information_buf);
 295        Adapter->mppriv.mode = mode;/* 1 for loopback*/
 296        if (mp_start_test(Adapter) == _FAIL)
 297                status = RNDIS_STATUS_NOT_ACCEPTED;
 298        r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */
 299        r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */
 300        /* RCR disable Check BSSID, 0x1025004a */
 301        r8712_write8(Adapter, RCR+2, 0x57);
 302        /* disable RX filter map , mgt frames will put in RX FIFO 0 */
 303        r8712_write16(Adapter, RXFLTMAP0, 0x0);
 304        val8 = r8712_read8(Adapter, EE_9346CR);
 305        if (!(val8 & _9356SEL)) { /*boot from EFUSE*/
 306                r8712_efuse_reg_init(Adapter);
 307                r8712_efuse_change_max_size(Adapter);
 308                r8712_efuse_reg_uninit(Adapter);
 309        }
 310        return status;
 311}
 312
 313uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv)
 314{
 315        struct _adapter *Adapter = (struct _adapter *)
 316                                   (poid_par_priv->adapter_context);
 317        uint status = RNDIS_STATUS_SUCCESS;
 318
 319        if (poid_par_priv->type_of_oid != SET_OID)
 320                return RNDIS_STATUS_NOT_ACCEPTED;
 321        if (mp_stop_test(Adapter) == _FAIL)
 322                status = RNDIS_STATUS_NOT_ACCEPTED;
 323        return status;
 324}
 325
 326uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv
 327                                                   *poid_par_priv)
 328{
 329        struct _adapter *Adapter = (struct _adapter *)
 330                                   (poid_par_priv->adapter_context);
 331        uint status = RNDIS_STATUS_SUCCESS;
 332        u32             Channel;
 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        Channel = *((u32 *)poid_par_priv->information_buf);
 339        if (Channel > 14)
 340                return RNDIS_STATUS_NOT_ACCEPTED;
 341        Adapter->mppriv.curr_ch = Channel;
 342        r8712_SetChannel(Adapter);
 343        return status;
 344}
 345
 346uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv)
 347{
 348        struct _adapter *Adapter = (struct _adapter *)
 349                                   (poid_par_priv->adapter_context);
 350        uint status = RNDIS_STATUS_SUCCESS;
 351        u32 antenna;
 352
 353        if (poid_par_priv->type_of_oid != SET_OID)
 354                return RNDIS_STATUS_NOT_ACCEPTED;
 355        if (poid_par_priv->information_buf_len != sizeof(u32))
 356                return RNDIS_STATUS_INVALID_LENGTH;
 357        antenna = *((u32 *)poid_par_priv->information_buf);
 358        Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16);
 359        Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF);
 360        r8712_SwitchAntenna(Adapter);
 361        return status;
 362}
 363
 364uint oid_rt_pro_set_tx_power_control_hdl(
 365                                        struct oid_par_priv *poid_par_priv)
 366{
 367        struct _adapter *Adapter = (struct _adapter *)
 368                                   (poid_par_priv->adapter_context);
 369        uint status = RNDIS_STATUS_SUCCESS;
 370        u32 tx_pwr_idx;
 371
 372        if (poid_par_priv->type_of_oid != SET_OID)
 373                return RNDIS_STATUS_NOT_ACCEPTED;
 374        if (poid_par_priv->information_buf_len != sizeof(u32))
 375                return RNDIS_STATUS_INVALID_LENGTH;
 376        tx_pwr_idx = *((u32 *)poid_par_priv->information_buf);
 377        if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE)
 378                return RNDIS_STATUS_NOT_ACCEPTED;
 379        Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx;
 380        r8712_SetTxPower(Adapter);
 381        return status;
 382}
 383
 384uint oid_rt_pro_query_tx_packet_sent_hdl(
 385                                        struct oid_par_priv *poid_par_priv)
 386{
 387        uint status = RNDIS_STATUS_SUCCESS;
 388        struct _adapter *Adapter = (struct _adapter *)
 389                                   (poid_par_priv->adapter_context);
 390
 391        if (poid_par_priv->type_of_oid != QUERY_OID) {
 392                status = RNDIS_STATUS_NOT_ACCEPTED;
 393                return status;
 394        }
 395        if (poid_par_priv->information_buf_len == sizeof(u32)) {
 396                *(u32 *)poid_par_priv->information_buf =
 397                                        Adapter->mppriv.tx_pktcount;
 398                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 399        } else
 400                status = RNDIS_STATUS_INVALID_LENGTH;
 401        return status;
 402}
 403
 404uint oid_rt_pro_query_rx_packet_received_hdl(
 405                                        struct oid_par_priv *poid_par_priv)
 406{
 407        uint status = RNDIS_STATUS_SUCCESS;
 408        struct _adapter *Adapter = (struct _adapter *)
 409                                   (poid_par_priv->adapter_context);
 410
 411        if (poid_par_priv->type_of_oid != QUERY_OID) {
 412                status = RNDIS_STATUS_NOT_ACCEPTED;
 413                return status;
 414        }
 415        if (poid_par_priv->information_buf_len == sizeof(u32)) {
 416                *(u32 *)poid_par_priv->information_buf =
 417                                        Adapter->mppriv.rx_pktcount;
 418                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 419        } else
 420                status = RNDIS_STATUS_INVALID_LENGTH;
 421        return status;
 422}
 423
 424uint oid_rt_pro_query_rx_packet_crc32_error_hdl(
 425                                        struct oid_par_priv *poid_par_priv)
 426{
 427        uint status = RNDIS_STATUS_SUCCESS;
 428        struct _adapter *Adapter = (struct _adapter *)
 429                                   (poid_par_priv->adapter_context);
 430
 431        if (poid_par_priv->type_of_oid != QUERY_OID) {
 432                status = RNDIS_STATUS_NOT_ACCEPTED;
 433                return status;
 434        }
 435        if (poid_par_priv->information_buf_len == sizeof(u32)) {
 436                *(u32 *)poid_par_priv->information_buf =
 437                                        Adapter->mppriv.rx_crcerrpktcount;
 438                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 439        } else
 440                status = RNDIS_STATUS_INVALID_LENGTH;
 441        return status;
 442}
 443
 444uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv
 445                                                *poid_par_priv)
 446{
 447        struct _adapter *Adapter = (struct _adapter *)
 448                                   (poid_par_priv->adapter_context);
 449
 450        if (poid_par_priv->type_of_oid != SET_OID)
 451                return RNDIS_STATUS_NOT_ACCEPTED;
 452        Adapter->mppriv.tx_pktcount = 0;
 453        return RNDIS_STATUS_SUCCESS;
 454}
 455
 456uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv
 457                                                    *poid_par_priv)
 458{
 459        uint status = RNDIS_STATUS_SUCCESS;
 460        struct _adapter *Adapter = (struct _adapter *)
 461                                   (poid_par_priv->adapter_context);
 462
 463        if (poid_par_priv->type_of_oid != SET_OID)
 464                return RNDIS_STATUS_NOT_ACCEPTED;
 465        if (poid_par_priv->information_buf_len == sizeof(u32)) {
 466                Adapter->mppriv.rx_pktcount = 0;
 467                Adapter->mppriv.rx_crcerrpktcount = 0;
 468        } else
 469                status = RNDIS_STATUS_INVALID_LENGTH;
 470        return status;
 471}
 472
 473uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv
 474                                                 *poid_par_priv)
 475{
 476        struct _adapter *Adapter = (struct _adapter *)
 477                                   (poid_par_priv->adapter_context);
 478
 479        if (poid_par_priv->type_of_oid != SET_OID)
 480                return RNDIS_STATUS_NOT_ACCEPTED;
 481        r8712_ResetPhyRxPktCount(Adapter);
 482        return RNDIS_STATUS_SUCCESS;
 483}
 484
 485uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv
 486                                                  *poid_par_priv)
 487{
 488        struct _adapter *Adapter = (struct _adapter *)
 489                                   (poid_par_priv->adapter_context);
 490
 491        if (poid_par_priv->type_of_oid != QUERY_OID)
 492                return RNDIS_STATUS_NOT_ACCEPTED;
 493        if (poid_par_priv->information_buf_len != sizeof(u32))
 494                return RNDIS_STATUS_INVALID_LENGTH;
 495        *(u32 *)poid_par_priv->information_buf =
 496                                         r8712_GetPhyRxPktReceived(Adapter);
 497        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 498        return RNDIS_STATUS_SUCCESS;
 499}
 500
 501uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv
 502                                                     *poid_par_priv)
 503{
 504        struct _adapter *Adapter = (struct _adapter *)
 505                                   (poid_par_priv->adapter_context);
 506
 507        if (poid_par_priv->type_of_oid != QUERY_OID)
 508                return RNDIS_STATUS_NOT_ACCEPTED;
 509        if (poid_par_priv->information_buf_len != sizeof(u32))
 510                return RNDIS_STATUS_INVALID_LENGTH;
 511        *(u32 *)poid_par_priv->information_buf =
 512                                         r8712_GetPhyRxPktCRC32Error(Adapter);
 513        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 514        return RNDIS_STATUS_SUCCESS;
 515}
 516
 517uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv
 518                                          *poid_par_priv)
 519{
 520        struct _adapter *Adapter = (struct _adapter *)
 521                                   (poid_par_priv->adapter_context);
 522
 523        if (poid_par_priv->type_of_oid != SET_OID)
 524                return RNDIS_STATUS_NOT_ACCEPTED;
 525
 526        Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf);
 527        return RNDIS_STATUS_SUCCESS;
 528}
 529
 530uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv
 531                                             *poid_par_priv)
 532{
 533        struct _adapter *Adapter = (struct _adapter *)
 534                                   (poid_par_priv->adapter_context);
 535        u32             bStartTest;
 536
 537        if (poid_par_priv->type_of_oid != SET_OID)
 538                return RNDIS_STATUS_NOT_ACCEPTED;
 539        bStartTest = *((u32 *)poid_par_priv->information_buf);
 540        r8712_SetContinuousTx(Adapter, (u8)bStartTest);
 541        return RNDIS_STATUS_SUCCESS;
 542}
 543
 544uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv
 545                                                 *poid_par_priv)
 546{
 547        struct _adapter *Adapter = (struct _adapter *)
 548                                   (poid_par_priv->adapter_context);
 549        u32             bStartTest;
 550
 551        if (poid_par_priv->type_of_oid != SET_OID)
 552                return RNDIS_STATUS_NOT_ACCEPTED;
 553        bStartTest = *((u32 *)poid_par_priv->information_buf);
 554        r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest);
 555        return RNDIS_STATUS_SUCCESS;
 556}
 557
 558uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv
 559                                                      *poid_par_priv)
 560{
 561        struct _adapter *Adapter = (struct _adapter *)
 562                                   (poid_par_priv->adapter_context);
 563        u32             bStartTest;
 564
 565        if (poid_par_priv->type_of_oid != SET_OID)
 566                return RNDIS_STATUS_NOT_ACCEPTED;
 567        bStartTest = *((u32 *)poid_par_priv->information_buf);
 568        r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest);
 569        return RNDIS_STATUS_SUCCESS;
 570}
 571
 572uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
 573                                              *poid_par_priv)
 574{
 575        struct _adapter *Adapter = (struct _adapter *)
 576                                   (poid_par_priv->adapter_context);
 577        u32             bStartTest;
 578
 579        if (poid_par_priv->type_of_oid != SET_OID)
 580                return RNDIS_STATUS_NOT_ACCEPTED;
 581        bStartTest = *((u32 *)poid_par_priv->information_buf);
 582        r8712_SetSingleToneTx(Adapter, (u8)bStartTest);
 583        return RNDIS_STATUS_SUCCESS;
 584}
 585
 586uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
 587{
 588        struct _adapter *Adapter = (struct _adapter *)
 589                                   (poid_par_priv->adapter_context);
 590        uint status = RNDIS_STATUS_SUCCESS;
 591        struct ndis_802_11_ssid *pssid;
 592
 593        if (poid_par_priv->type_of_oid != SET_OID)
 594                return RNDIS_STATUS_NOT_ACCEPTED;
 595        *poid_par_priv->bytes_needed = (u32)sizeof(struct ndis_802_11_ssid);
 596        *poid_par_priv->bytes_rw = 0;
 597        if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
 598                return RNDIS_STATUS_INVALID_LENGTH;
 599        pssid = (struct ndis_802_11_ssid *)poid_par_priv->information_buf;
 600        if (mp_start_joinbss(Adapter, pssid) == _FAIL)
 601                status = RNDIS_STATUS_NOT_ACCEPTED;
 602        *poid_par_priv->bytes_rw = sizeof(struct ndis_802_11_ssid);
 603        return status;
 604}
 605
 606uint oid_rt_pro_read_register_hdl(struct oid_par_priv
 607                                         *poid_par_priv)
 608{
 609        struct _adapter *Adapter = (struct _adapter *)
 610                                   (poid_par_priv->adapter_context);
 611        uint status = RNDIS_STATUS_SUCCESS;
 612        struct mp_rw_reg *RegRWStruct;
 613        u16             offset;
 614
 615        if (poid_par_priv->type_of_oid != QUERY_OID)
 616                return RNDIS_STATUS_NOT_ACCEPTED;
 617        RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
 618        if ((RegRWStruct->offset >= 0x10250800) &&
 619            (RegRWStruct->offset <= 0x10250FFF)) {
 620                /*baseband register*/
 621                /*0ffset :0x800~0xfff*/
 622                offset = (u16)(RegRWStruct->offset) & 0xFFF;
 623                RegRWStruct->value = r8712_bb_reg_read(Adapter, offset);
 624        } else {
 625                switch (RegRWStruct->width) {
 626                case 1:
 627                        RegRWStruct->value = r8712_read8(Adapter,
 628                                                   RegRWStruct->offset);
 629                        break;
 630                case 2:
 631                        RegRWStruct->value = r8712_read16(Adapter,
 632                                                    RegRWStruct->offset);
 633                        break;
 634                case 4:
 635                        RegRWStruct->value = r8712_read32(Adapter,
 636                                                    RegRWStruct->offset);
 637                        break;
 638                default:
 639                        status = RNDIS_STATUS_NOT_ACCEPTED;
 640                        break;
 641                }
 642        }
 643        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 644        return status;
 645}
 646
 647uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
 648{
 649        struct _adapter *Adapter = (struct _adapter *)
 650                                   (poid_par_priv->adapter_context);
 651        uint status = RNDIS_STATUS_SUCCESS;
 652        struct mp_rw_reg *RegRWStruct;
 653        u16             offset;
 654        u32             value;
 655        u32 oldValue = 0;
 656
 657        if (poid_par_priv->type_of_oid != SET_OID)
 658                return RNDIS_STATUS_NOT_ACCEPTED;
 659        RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
 660        if ((RegRWStruct->offset >= 0x10250800) &&
 661            (RegRWStruct->offset <= 0x10250FFF)) {
 662                /*baseband register*/
 663                offset = (u16)(RegRWStruct->offset) & 0xFFF;
 664                value = RegRWStruct->value;
 665                switch (RegRWStruct->width) {
 666                case 1:
 667                        oldValue = r8712_bb_reg_read(Adapter, offset);
 668                        oldValue &= 0xFFFFFF00;
 669                        value &= 0x000000FF;
 670                        value |= oldValue;
 671                        break;
 672                case 2:
 673                        oldValue = r8712_bb_reg_read(Adapter, offset);
 674                        oldValue &= 0xFFFF0000;
 675                        value &= 0x0000FFFF;
 676                        value |= oldValue;
 677                        break;
 678                }
 679                r8712_bb_reg_write(Adapter, offset, value);
 680        } else {
 681                switch (RegRWStruct->width) {
 682                case 1:
 683                        r8712_write8(Adapter, RegRWStruct->offset,
 684                               (unsigned char)RegRWStruct->value);
 685                        break;
 686                case 2:
 687                        r8712_write16(Adapter, RegRWStruct->offset,
 688                                (unsigned short)RegRWStruct->value);
 689                        break;
 690                case 4:
 691                        r8712_write32(Adapter, RegRWStruct->offset,
 692                                (unsigned int)RegRWStruct->value);
 693                        break;
 694                default:
 695                        status = RNDIS_STATUS_NOT_ACCEPTED;
 696                        break;
 697                }
 698
 699                if ((status == RNDIS_STATUS_SUCCESS) &&
 700                    (RegRWStruct->offset == HIMR) &&
 701                    (RegRWStruct->width == 4))
 702                        Adapter->ImrContent = RegRWStruct->value;
 703        }
 704        return status;
 705}
 706
 707uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv
 708                                               *poid_par_priv)
 709{
 710        struct _adapter *Adapter = (struct _adapter *)
 711                                   (poid_par_priv->adapter_context);
 712        struct burst_rw_reg *pBstRwReg;
 713
 714        if (poid_par_priv->type_of_oid != QUERY_OID)
 715                return RNDIS_STATUS_NOT_ACCEPTED;
 716        pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
 717        r8712_read_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
 718                 pBstRwReg->Data);
 719        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 720        return RNDIS_STATUS_SUCCESS;
 721}
 722
 723uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv
 724                                                *poid_par_priv)
 725{
 726        struct _adapter *Adapter = (struct _adapter *)
 727                                   (poid_par_priv->adapter_context);
 728        struct burst_rw_reg *pBstRwReg;
 729
 730        if (poid_par_priv->type_of_oid != SET_OID)
 731                return RNDIS_STATUS_NOT_ACCEPTED;
 732        pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
 733        r8712_write_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
 734                  pBstRwReg->Data);
 735        return RNDIS_STATUS_SUCCESS;
 736}
 737
 738uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
 739{
 740        return RNDIS_STATUS_SUCCESS;
 741}
 742
 743uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
 744{
 745        struct _adapter *Adapter = (struct _adapter *)
 746                                   (poid_par_priv->adapter_context);
 747        struct eeprom_rw_param *pEEPROM;
 748
 749        if (poid_par_priv->type_of_oid != QUERY_OID)
 750                return RNDIS_STATUS_NOT_ACCEPTED;
 751        pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
 752        pEEPROM->value = r8712_eeprom_read16(Adapter,
 753                                             (u16)(pEEPROM->offset >> 1));
 754        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 755        return RNDIS_STATUS_SUCCESS;
 756}
 757
 758uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
 759{
 760        struct _adapter *Adapter = (struct _adapter *)
 761                                   (poid_par_priv->adapter_context);
 762        struct eeprom_rw_param *pEEPROM;
 763
 764        if (poid_par_priv->type_of_oid != SET_OID)
 765                return RNDIS_STATUS_NOT_ACCEPTED;
 766        pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
 767        r8712_eeprom_write16(Adapter, (u16)(pEEPROM->offset >> 1),
 768                             pEEPROM->value);
 769        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 770        return RNDIS_STATUS_SUCCESS;
 771}
 772
 773uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
 774{
 775        struct _adapter *Adapter = (struct _adapter *)
 776                                   (poid_par_priv->adapter_context);
 777        struct mp_wiparam *pwi_param;
 778
 779        if (poid_par_priv->type_of_oid != QUERY_OID)
 780                return RNDIS_STATUS_NOT_ACCEPTED;
 781        if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam))
 782                return RNDIS_STATUS_INVALID_LENGTH;
 783        if (Adapter->mppriv.workparam.bcompleted == false)
 784                return RNDIS_STATUS_NOT_ACCEPTED;
 785        pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf;
 786        memcpy(pwi_param, &Adapter->mppriv.workparam,
 787                sizeof(struct mp_wiparam));
 788        Adapter->mppriv.act_in_progress = false;
 789        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 790        return RNDIS_STATUS_SUCCESS;
 791}
 792
 793uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
 794{
 795        struct _adapter *Adapter = (struct _adapter *)
 796                                   (poid_par_priv->adapter_context);
 797
 798        if (poid_par_priv->type_of_oid != QUERY_OID)
 799                return RNDIS_STATUS_NOT_ACCEPTED;
 800        if (poid_par_priv->information_buf_len < sizeof(uint) * 2)
 801                return RNDIS_STATUS_INVALID_LENGTH;
 802        if (*(uint *)poid_par_priv->information_buf == 1)
 803                Adapter->mppriv.rx_pktloss = 0;
 804        *((uint *)poid_par_priv->information_buf+1) =
 805                                         Adapter->mppriv.rx_pktloss;
 806        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 807        return RNDIS_STATUS_SUCCESS;
 808}
 809
 810uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
 811{
 812        if (poid_par_priv->type_of_oid != QUERY_OID)
 813                return RNDIS_STATUS_NOT_ACCEPTED;
 814        return RNDIS_STATUS_SUCCESS;
 815}
 816
 817uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
 818{
 819        if (poid_par_priv->type_of_oid != SET_OID)
 820                return RNDIS_STATUS_NOT_ACCEPTED;
 821        return RNDIS_STATUS_SUCCESS;
 822}
 823
 824uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
 825{
 826        struct _adapter *Adapter = (struct _adapter *)
 827                                   (poid_par_priv->adapter_context);
 828        uint status = RNDIS_STATUS_SUCCESS;
 829
 830        if (poid_par_priv->type_of_oid != SET_OID)
 831                return RNDIS_STATUS_NOT_ACCEPTED;
 832        if (r8712_setrfintfs_cmd(Adapter, *(unsigned char *)
 833            poid_par_priv->information_buf) == _FAIL)
 834                status = RNDIS_STATUS_NOT_ACCEPTED;
 835        return status;
 836}
 837
 838uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
 839{
 840        struct _adapter *Adapter = (struct _adapter *)
 841                                   (poid_par_priv->adapter_context);
 842        uint status = RNDIS_STATUS_SUCCESS;
 843
 844        if (poid_par_priv->type_of_oid != QUERY_OID)
 845                return RNDIS_STATUS_NOT_ACCEPTED;
 846        memcpy(poid_par_priv->information_buf,
 847                (unsigned char *)&Adapter->mppriv.rxstat,
 848                sizeof(struct recv_stat));
 849        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 850        return status;
 851}
 852
 853uint oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv
 854                                             *poid_par_priv)
 855{
 856        return RNDIS_STATUS_SUCCESS;
 857}
 858
 859uint oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv
 860                                            *poid_par_priv)
 861{
 862        struct _adapter *Adapter = (struct _adapter *)
 863                                   (poid_par_priv->adapter_context);
 864        uint status = RNDIS_STATUS_SUCCESS;
 865
 866        if (poid_par_priv->type_of_oid != SET_OID)
 867                return RNDIS_STATUS_NOT_ACCEPTED;
 868        if (r8712_setdatarate_cmd(Adapter,
 869            poid_par_priv->information_buf) != _SUCCESS)
 870                status = RNDIS_STATUS_NOT_ACCEPTED;
 871        return status;
 872}
 873
 874uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
 875{
 876        struct _adapter *Adapter = (struct _adapter *)
 877                                   (poid_par_priv->adapter_context);
 878        uint status = RNDIS_STATUS_SUCCESS;
 879
 880        if (poid_par_priv->type_of_oid != QUERY_OID)
 881                return RNDIS_STATUS_NOT_ACCEPTED;
 882
 883        if (Adapter->mppriv.act_in_progress == true)
 884                return RNDIS_STATUS_NOT_ACCEPTED;
 885
 886        if (poid_par_priv->information_buf_len < sizeof(u8))
 887                return RNDIS_STATUS_INVALID_LENGTH;
 888        /*init workparam*/
 889        Adapter->mppriv.act_in_progress = true;
 890        Adapter->mppriv.workparam.bcompleted = false;
 891        Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER;
 892        Adapter->mppriv.workparam.io_offset = 0;
 893        Adapter->mppriv.workparam.io_value = 0xFFFFFFFF;
 894        r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value);
 895        Adapter->mppriv.workparam.bcompleted = true;
 896        Adapter->mppriv.act_in_progress = false;
 897        *(u32 *)poid_par_priv->information_buf =
 898                                 Adapter->mppriv.workparam.io_value;
 899        *poid_par_priv->bytes_rw = sizeof(u32);
 900        return status;
 901}
 902
 903uint oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv
 904                                              *poid_par_priv)
 905{
 906        struct _adapter *Adapter = (struct _adapter *)
 907                                   (poid_par_priv->adapter_context);
 908        uint status = RNDIS_STATUS_SUCCESS;
 909
 910        if (poid_par_priv->type_of_oid != SET_OID)
 911                return RNDIS_STATUS_NOT_ACCEPTED;
 912        if (poid_par_priv->information_buf_len < sizeof(u8))
 913                return RNDIS_STATUS_INVALID_LENGTH;
 914        if (!r8712_setptm_cmd(Adapter, *((u8 *)poid_par_priv->information_buf)))
 915                status = RNDIS_STATUS_NOT_ACCEPTED;
 916        return status;
 917}
 918
 919uint oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
 920{
 921        struct _adapter *Adapter = (struct _adapter *)
 922                                   (poid_par_priv->adapter_context);
 923        u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
 924        uint status = RNDIS_STATUS_SUCCESS;
 925        u32 ratevalue;
 926        u8 datarates[NumRates];
 927        int i;
 928
 929        if (poid_par_priv->type_of_oid != SET_OID)
 930                return RNDIS_STATUS_NOT_ACCEPTED;
 931        ratevalue = *((u32 *)poid_par_priv->information_buf);
 932        for (i = 0; i < NumRates; i++) {
 933                if (ratevalue == mpdatarate[i])
 934                        datarates[i] = mpdatarate[i];
 935                else
 936                        datarates[i] = 0xff;
 937        }
 938        if (r8712_setbasicrate_cmd(Adapter, datarates) != _SUCCESS)
 939                status = RNDIS_STATUS_NOT_ACCEPTED;
 940        return status;
 941}
 942
 943uint oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
 944{
 945        struct _adapter *Adapter = (struct _adapter *)
 946                                   (poid_par_priv->adapter_context);
 947
 948        if (poid_par_priv->type_of_oid != QUERY_OID)
 949                return RNDIS_STATUS_NOT_ACCEPTED;
 950        if (poid_par_priv->information_buf_len < 8)
 951                return RNDIS_STATUS_INVALID_LENGTH;
 952        *poid_par_priv->bytes_rw = 8;
 953        memcpy(poid_par_priv->information_buf,
 954                &(Adapter->pwrctrlpriv.pwr_mode), 8);
 955        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
 956        return RNDIS_STATUS_SUCCESS;
 957}
 958
 959uint oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
 960{
 961        struct _adapter *Adapter = (struct _adapter *)
 962                                   (poid_par_priv->adapter_context);
 963        uint pwr_mode, smart_ps;
 964
 965        if (poid_par_priv->type_of_oid != SET_OID)
 966                return RNDIS_STATUS_NOT_ACCEPTED;
 967        *poid_par_priv->bytes_rw = 0;
 968        *poid_par_priv->bytes_needed = 8;
 969        if (poid_par_priv->information_buf_len < 8)
 970                return RNDIS_STATUS_INVALID_LENGTH;
 971        pwr_mode = *(uint *)(poid_par_priv->information_buf);
 972        smart_ps = *(uint *)((addr_t)poid_par_priv->information_buf + 4);
 973        if (pwr_mode != Adapter->pwrctrlpriv.pwr_mode || smart_ps !=
 974                        Adapter->pwrctrlpriv.smart_ps)
 975                r8712_set_ps_mode(Adapter, pwr_mode, smart_ps);
 976        *poid_par_priv->bytes_rw = 8;
 977        return RNDIS_STATUS_SUCCESS;
 978}
 979
 980uint oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv
 981                                              *poid_par_priv)
 982{
 983        struct _adapter *Adapter = (struct _adapter *)
 984                                   (poid_par_priv->adapter_context);
 985        uint status = RNDIS_STATUS_SUCCESS;
 986        struct setratable_parm *prate_table;
 987        u8 res;
 988
 989        if (poid_par_priv->type_of_oid != SET_OID)
 990                return RNDIS_STATUS_NOT_ACCEPTED;
 991        *poid_par_priv->bytes_needed  = sizeof(struct setratable_parm);
 992        if (poid_par_priv->information_buf_len <
 993            sizeof(struct setratable_parm))
 994                return RNDIS_STATUS_INVALID_LENGTH;
 995        prate_table = (struct setratable_parm *)poid_par_priv->information_buf;
 996        res = r8712_setrttbl_cmd(Adapter, prate_table);
 997        if (res == _FAIL)
 998                status = RNDIS_STATUS_FAILURE;
 999        return status;
1000}
1001
1002uint oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv
1003                                              *poid_par_priv)
1004{
1005        if (poid_par_priv->type_of_oid != QUERY_OID)
1006                return RNDIS_STATUS_NOT_ACCEPTED;
1007        return RNDIS_STATUS_SUCCESS;
1008}
1009
1010uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv
1011                                           *poid_par_priv)
1012{
1013        struct _adapter *Adapter = (struct _adapter *)
1014                                   (poid_par_priv->adapter_context);
1015        struct security_priv *psecuritypriv = &Adapter->securitypriv;
1016        enum ENCRY_CTRL_STATE encry_mode = 0;
1017
1018        *poid_par_priv->bytes_needed = sizeof(u8);
1019        if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1020                return RNDIS_STATUS_INVALID_LENGTH;
1021
1022        if (poid_par_priv->type_of_oid == SET_OID) {
1023                encry_mode = *((u8 *)poid_par_priv->information_buf);
1024                switch (encry_mode) {
1025                case HW_CONTROL:
1026                        psecuritypriv->sw_decrypt = false;
1027                        psecuritypriv->sw_encrypt = false;
1028                        break;
1029                case SW_CONTROL:
1030                        psecuritypriv->sw_decrypt = true;
1031                        psecuritypriv->sw_encrypt = true;
1032                        break;
1033                case HW_ENCRY_SW_DECRY:
1034                        psecuritypriv->sw_decrypt = true;
1035                        psecuritypriv->sw_encrypt = false;
1036                        break;
1037                case SW_ENCRY_HW_DECRY:
1038                        psecuritypriv->sw_decrypt = false;
1039                        psecuritypriv->sw_encrypt = true;
1040                        break;
1041                }
1042        } else {
1043                if ((psecuritypriv->sw_encrypt == false) &&
1044                    (psecuritypriv->sw_decrypt == false))
1045                        encry_mode = HW_CONTROL;
1046                else if ((psecuritypriv->sw_encrypt == false) &&
1047                         (psecuritypriv->sw_decrypt == true))
1048                        encry_mode = HW_ENCRY_SW_DECRY;
1049                else if ((psecuritypriv->sw_encrypt == true) &&
1050                         (psecuritypriv->sw_decrypt == false))
1051                        encry_mode = SW_ENCRY_HW_DECRY;
1052                else if ((psecuritypriv->sw_encrypt == true) &&
1053                         (psecuritypriv->sw_decrypt == true))
1054                        encry_mode = SW_CONTROL;
1055                *(u8 *)poid_par_priv->information_buf =  encry_mode;
1056                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1057        }
1058        return RNDIS_STATUS_SUCCESS;
1059}
1060/*----------------------------------------------------------------------*/
1061uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1062{
1063        struct _adapter *Adapter = (struct _adapter *)
1064                                   (poid_par_priv->adapter_context);
1065
1066        uint status = RNDIS_STATUS_SUCCESS;
1067
1068        struct sta_info *psta = NULL;
1069        u8      *macaddr;
1070
1071
1072        if (poid_par_priv->type_of_oid != SET_OID)
1073                return RNDIS_STATUS_NOT_ACCEPTED;
1074
1075        *poid_par_priv->bytes_needed = ETH_ALEN;
1076        if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1077                return RNDIS_STATUS_INVALID_LENGTH;
1078        macaddr = (u8 *) poid_par_priv->information_buf;
1079        psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1080        if (psta == NULL) { /* the sta in sta_info_queue => do nothing*/
1081                psta = r8712_alloc_stainfo(&Adapter->stapriv, macaddr);
1082                if (psta == NULL)
1083                        status = RNDIS_STATUS_FAILURE;
1084        }
1085        return status;
1086}
1087/*-------------------------------------------------------------------------*/
1088uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
1089{
1090        struct _adapter *Adapter = (struct _adapter *)
1091                                   (poid_par_priv->adapter_context);
1092
1093        unsigned long                   irqL;
1094        uint status = RNDIS_STATUS_SUCCESS;
1095
1096        struct sta_info         *psta = NULL;
1097        u8                      *macaddr;
1098
1099
1100        if (poid_par_priv->type_of_oid != SET_OID)
1101                return RNDIS_STATUS_NOT_ACCEPTED;
1102
1103        *poid_par_priv->bytes_needed = ETH_ALEN;
1104        if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1105                return RNDIS_STATUS_INVALID_LENGTH;
1106
1107        macaddr = (u8 *)poid_par_priv->information_buf;
1108
1109        psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
1110        if (psta != NULL) {
1111                spin_lock_irqsave(&(Adapter->stapriv.sta_hash_lock), irqL);
1112                r8712_free_stainfo(Adapter, psta);
1113                spin_unlock_irqrestore(&(Adapter->stapriv.sta_hash_lock), irqL);
1114        }
1115
1116        return status;
1117}
1118/*--------------------------------------------------------------------------*/
1119static u32 mp_query_drv_var(struct _adapter *padapter, u8 offset, u32 var)
1120{
1121        return var;
1122}
1123
1124uint oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
1125{
1126        struct _adapter *Adapter = (struct _adapter *)
1127                                   (poid_par_priv->adapter_context);
1128
1129        uint status = RNDIS_STATUS_SUCCESS;
1130
1131        struct DR_VARIABLE_STRUCT *pdrv_var;
1132
1133        if (poid_par_priv->type_of_oid != QUERY_OID)
1134                return RNDIS_STATUS_NOT_ACCEPTED;
1135        *poid_par_priv->bytes_needed = sizeof(struct DR_VARIABLE_STRUCT);
1136        if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
1137                return RNDIS_STATUS_INVALID_LENGTH;
1138        pdrv_var = (struct DR_VARIABLE_STRUCT *)poid_par_priv->information_buf;
1139        pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset,
1140                                              pdrv_var->variable);
1141        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1142        return status;
1143}
1144
1145/*--------------------------------------------------------------------------*/
1146uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
1147{
1148        return RNDIS_STATUS_SUCCESS;
1149}
1150/*------------------------------------------------------------------------*/
1151uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
1152{
1153        struct _adapter *Adapter = (struct _adapter *)
1154                                   (poid_par_priv->adapter_context);
1155
1156        uint status = RNDIS_STATUS_SUCCESS;
1157
1158        struct EFUSE_ACCESS_STRUCT *pefuse;
1159        u8 *data;
1160        u16 addr = 0, cnts = 0;
1161
1162        if (poid_par_priv->type_of_oid != QUERY_OID)
1163                return RNDIS_STATUS_NOT_ACCEPTED;
1164        if (poid_par_priv->information_buf_len <
1165            sizeof(struct EFUSE_ACCESS_STRUCT))
1166                return RNDIS_STATUS_INVALID_LENGTH;
1167        pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
1168        addr = pefuse->start_addr;
1169        cnts = pefuse->cnts;
1170        data = pefuse->data;
1171        memset(data, 0xFF, cnts);
1172        if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) >
1173             EFUSE_MAX_SIZE)
1174                return RNDIS_STATUS_NOT_ACCEPTED;
1175        if (r8712_efuse_access(Adapter, true, addr, cnts, data) == false)
1176                status = RNDIS_STATUS_FAILURE;
1177        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1178        return status;
1179}
1180/*------------------------------------------------------------------------*/
1181uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
1182{
1183        struct _adapter *Adapter = (struct _adapter *)
1184                                   (poid_par_priv->adapter_context);
1185
1186        uint status = RNDIS_STATUS_SUCCESS;
1187
1188        struct EFUSE_ACCESS_STRUCT *pefuse;
1189        u8 *data;
1190        u16 addr = 0, cnts = 0;
1191
1192        if (poid_par_priv->type_of_oid != SET_OID)
1193                return RNDIS_STATUS_NOT_ACCEPTED;
1194
1195        pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
1196        addr = pefuse->start_addr;
1197        cnts = pefuse->cnts;
1198        data = pefuse->data;
1199
1200        if ((addr > 511) || (cnts < 1) || (cnts > 512) ||
1201            (addr + cnts) > r8712_efuse_get_max_size(Adapter))
1202                return RNDIS_STATUS_NOT_ACCEPTED;
1203        if (r8712_efuse_access(Adapter, false, addr, cnts, data) == false)
1204                status = RNDIS_STATUS_FAILURE;
1205        return status;
1206}
1207/*----------------------------------------------------------------------*/
1208uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
1209{
1210        struct _adapter *Adapter = (struct _adapter *)
1211                                   (poid_par_priv->adapter_context);
1212        uint status = RNDIS_STATUS_SUCCESS;
1213        struct PGPKT_STRUCT     *ppgpkt;
1214
1215        *poid_par_priv->bytes_rw = 0;
1216        if (poid_par_priv->information_buf_len < sizeof(struct PGPKT_STRUCT))
1217                return RNDIS_STATUS_INVALID_LENGTH;
1218        ppgpkt = (struct PGPKT_STRUCT *)poid_par_priv->information_buf;
1219        if (poid_par_priv->type_of_oid == QUERY_OID) {
1220                if (r8712_efuse_pg_packet_read(Adapter, ppgpkt->offset,
1221                    ppgpkt->data) == true)
1222                        *poid_par_priv->bytes_rw =
1223                                 poid_par_priv->information_buf_len;
1224                else
1225                        status = RNDIS_STATUS_FAILURE;
1226        } else {
1227                if (r8712_efuse_reg_init(Adapter) == true) {
1228                        if (r8712_efuse_pg_packet_write(Adapter, ppgpkt->offset,
1229                            ppgpkt->word_en, ppgpkt->data) == true)
1230                                *poid_par_priv->bytes_rw =
1231                                         poid_par_priv->information_buf_len;
1232                        else
1233                                status = RNDIS_STATUS_FAILURE;
1234                        r8712_efuse_reg_uninit(Adapter);
1235                } else
1236                        status = RNDIS_STATUS_FAILURE;
1237        }
1238        return status;
1239}
1240
1241uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
1242                                              *poid_par_priv)
1243{
1244        struct _adapter *Adapter = (struct _adapter *)
1245                                   (poid_par_priv->adapter_context);
1246        uint status = RNDIS_STATUS_SUCCESS;
1247
1248        if (poid_par_priv->type_of_oid != QUERY_OID)
1249                return RNDIS_STATUS_NOT_ACCEPTED;
1250        if (poid_par_priv->information_buf_len < sizeof(int))
1251                return RNDIS_STATUS_INVALID_LENGTH;
1252        r8712_efuse_reg_init(Adapter);
1253        *(int *)poid_par_priv->information_buf =
1254                                 r8712_efuse_get_current_size(Adapter);
1255        r8712_efuse_reg_uninit(Adapter);
1256        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1257        return status;
1258}
1259
1260uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv)
1261{
1262        struct _adapter *Adapter = (struct _adapter *)
1263                                   (poid_par_priv->adapter_context);
1264        uint status = RNDIS_STATUS_SUCCESS;
1265
1266        if (poid_par_priv->type_of_oid != QUERY_OID)
1267                return RNDIS_STATUS_NOT_ACCEPTED;
1268        if (poid_par_priv->information_buf_len < sizeof(u32))
1269                return RNDIS_STATUS_INVALID_LENGTH;
1270        *(int *)poid_par_priv->information_buf =
1271                                         r8712_efuse_get_max_size(Adapter);
1272        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1273        return status;
1274}
1275
1276uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv)
1277{
1278        uint status = RNDIS_STATUS_SUCCESS;
1279
1280        if (poid_par_priv->type_of_oid == QUERY_OID)
1281                status = oid_rt_pro_read_efuse_hdl(poid_par_priv);
1282        else
1283                status = oid_rt_pro_write_efuse_hdl(poid_par_priv);
1284        return status;
1285}
1286
1287uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv)
1288{
1289        struct _adapter *Adapter = (struct _adapter *)
1290                                   (poid_par_priv->adapter_context);
1291        uint status = RNDIS_STATUS_SUCCESS;
1292        u8              *data;
1293
1294        *poid_par_priv->bytes_rw = 0;
1295        if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE)
1296                return RNDIS_STATUS_INVALID_LENGTH;
1297        data = (u8 *)poid_par_priv->information_buf;
1298        if (poid_par_priv->type_of_oid == QUERY_OID) {
1299                if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data))
1300                        *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
1301                else
1302                        status = RNDIS_STATUS_FAILURE;
1303        } else {
1304                /* SET_OID */
1305                if (r8712_efuse_reg_init(Adapter) == true) {
1306                        if (r8712_efuse_map_write(Adapter, 0,
1307                            EFUSE_MAP_MAX_SIZE, data))
1308                                *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
1309                        else
1310                                status = RNDIS_STATUS_FAILURE;
1311                        r8712_efuse_reg_uninit(Adapter);
1312                } else {
1313                        status = RNDIS_STATUS_FAILURE;
1314                }
1315        }
1316        return status;
1317}
1318
1319uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
1320{
1321        struct _adapter *Adapter = (struct _adapter *)
1322                                   (poid_par_priv->adapter_context);
1323        uint status = RNDIS_STATUS_SUCCESS;
1324        u32             bandwidth;
1325
1326        if (poid_par_priv->type_of_oid != SET_OID)
1327                return RNDIS_STATUS_NOT_ACCEPTED;
1328        if (poid_par_priv->information_buf_len < sizeof(u32))
1329                return RNDIS_STATUS_INVALID_LENGTH;
1330        bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/
1331        if (bandwidth != HT_CHANNEL_WIDTH_20)
1332                bandwidth = HT_CHANNEL_WIDTH_40;
1333        Adapter->mppriv.curr_bandwidth = (u8)bandwidth;
1334        r8712_SwitchBandwidth(Adapter);
1335        return status;
1336}
1337
1338uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
1339{
1340        struct _adapter *Adapter = (struct _adapter *)
1341                                   (poid_par_priv->adapter_context);
1342        uint status = RNDIS_STATUS_SUCCESS;
1343        u32             crystal_cap = 0;
1344
1345        if (poid_par_priv->type_of_oid != SET_OID)
1346                return RNDIS_STATUS_NOT_ACCEPTED;
1347        if (poid_par_priv->information_buf_len < sizeof(u32))
1348                return RNDIS_STATUS_INVALID_LENGTH;
1349        crystal_cap = *((u32 *)poid_par_priv->information_buf);/*4*/
1350        if (crystal_cap > 0xf)
1351                return RNDIS_STATUS_NOT_ACCEPTED;
1352        Adapter->mppriv.curr_crystalcap = crystal_cap;
1353        r8712_SetCrystalCap(Adapter);
1354        return status;
1355}
1356
1357uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
1358                                           *poid_par_priv)
1359{
1360        struct _adapter *Adapter = (struct _adapter *)
1361                                   (poid_par_priv->adapter_context);
1362        u8              rx_pkt_type;
1363        u32             rcr_val32;
1364
1365        if (poid_par_priv->type_of_oid != SET_OID)
1366                return RNDIS_STATUS_NOT_ACCEPTED;
1367        if (poid_par_priv->information_buf_len < sizeof(u8))
1368                return RNDIS_STATUS_INVALID_LENGTH;
1369        rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/
1370        rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/
1371        rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP);
1372        switch (rx_pkt_type) {
1373        case RX_PKT_BROADCAST:
1374                rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
1375                break;
1376        case RX_PKT_DEST_ADDR:
1377                rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
1378                break;
1379        case RX_PKT_PHY_MATCH:
1380                rcr_val32 |= (RCR_APM|RCR_ACRC32);
1381                break;
1382        default:
1383                rcr_val32 &= ~(RCR_AAP |
1384                               RCR_APM |
1385                               RCR_AM |
1386                               RCR_AB |
1387                               RCR_ACRC32);
1388                break;
1389        }
1390        if (rx_pkt_type == RX_PKT_DEST_ADDR)
1391                Adapter->mppriv.check_mp_pkt = 1;
1392        else
1393                Adapter->mppriv.check_mp_pkt = 0;
1394        r8712_write32(Adapter, RCR, rcr_val32);
1395        return RNDIS_STATUS_SUCCESS;
1396}
1397
1398uint oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv
1399                                             *poid_par_priv)
1400{
1401        struct _adapter *Adapter = (struct _adapter *)
1402                                   (poid_par_priv->adapter_context);
1403        u32 txagc;
1404
1405        if (poid_par_priv->type_of_oid != SET_OID)
1406                return RNDIS_STATUS_NOT_ACCEPTED;
1407        if (poid_par_priv->information_buf_len < sizeof(u32))
1408                return RNDIS_STATUS_INVALID_LENGTH;
1409        txagc = *(u32 *)poid_par_priv->information_buf;
1410        r8712_SetTxAGCOffset(Adapter, txagc);
1411        return RNDIS_STATUS_SUCCESS;
1412}
1413
1414uint oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv
1415                                             *poid_par_priv)
1416{
1417        struct _adapter *Adapter = (struct _adapter *)
1418                                   (poid_par_priv->adapter_context);
1419        uint status = RNDIS_STATUS_SUCCESS;
1420        struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
1421        struct mp_priv          *pmppriv = &Adapter->mppriv;
1422        u32                     type;
1423
1424        if (poid_par_priv->type_of_oid != SET_OID)
1425                return RNDIS_STATUS_NOT_ACCEPTED;
1426
1427        if (poid_par_priv->information_buf_len < sizeof(u32))
1428                return RNDIS_STATUS_INVALID_LENGTH;
1429
1430        type = *(u32 *)poid_par_priv->information_buf;
1431
1432        if (_LOOPBOOK_MODE_ == type) {
1433                pmppriv->mode = type;
1434                set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
1435        } else if (_2MAC_MODE_ == type) {
1436                pmppriv->mode = type;
1437                _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE);
1438        } else
1439                status = RNDIS_STATUS_NOT_ACCEPTED;
1440        return status;
1441}
1442/*--------------------------------------------------------------------------*/
1443/*Linux*/
1444unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
1445{
1446        return _SUCCESS;
1447}
1448/*-------------------------------------------------------------------------*/
1449uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv)
1450{
1451        u8      bpwrup;
1452
1453        if (poid_par_priv->type_of_oid != SET_OID)
1454                return RNDIS_STATUS_NOT_ACCEPTED;
1455        bpwrup = *(u8 *)poid_par_priv->information_buf;
1456        /*CALL  the power_down function*/
1457        return RNDIS_STATUS_SUCCESS;
1458}
1459
1460/*-------------------------------------------------------------------------- */
1461uint oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv)
1462{
1463        struct _adapter *Adapter = (struct _adapter *)
1464                                   (poid_par_priv->adapter_context);
1465
1466        if (poid_par_priv->type_of_oid != QUERY_OID)
1467                return RNDIS_STATUS_NOT_ACCEPTED;
1468        if (poid_par_priv->information_buf_len < sizeof(u32))
1469                return RNDIS_STATUS_INVALID_LENGTH;
1470        *(int *)poid_par_priv->information_buf =
1471                 Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL;
1472        *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
1473        return RNDIS_STATUS_SUCCESS;
1474}
1475