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