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
 370uint oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv)
 371{
 372        return RNDIS_STATUS_SUCCESS;
 373}
 374
 375uint oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv
 376                                                   *poid_par_priv)
 377{
 378        return RNDIS_STATUS_SUCCESS;
 379}
 380
 381uint oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv
 382                                             *poid_par_priv)
 383{
 384        if (poid_par_priv->type_of_oid != QUERY_OID)
 385                return RNDIS_STATUS_NOT_ACCEPTED;
 386        return RNDIS_STATUS_SUCCESS;
 387}
 388
 389uint oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv
 390                                              *poid_par_priv)
 391{
 392        return RNDIS_STATUS_SUCCESS;
 393}
 394
 395uint oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv
 396                                                      *poid_par_priv)
 397{
 398        if (poid_par_priv->type_of_oid != QUERY_OID)
 399                return RNDIS_STATUS_NOT_ACCEPTED;
 400        return RNDIS_STATUS_SUCCESS;
 401}
 402
 403uint oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv*
 404                                              poid_par_priv)
 405{
 406        return RNDIS_STATUS_SUCCESS;
 407}
 408
 409uint oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv)
 410{
 411        return RNDIS_STATUS_SUCCESS;
 412}
 413
 414uint oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv)
 415{
 416        if (poid_par_priv->type_of_oid != SET_OID)
 417                return RNDIS_STATUS_NOT_ACCEPTED;
 418        return RNDIS_STATUS_SUCCESS;
 419}
 420
 421uint oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv*
 422                                             poid_par_priv)
 423{
 424        uint status = RNDIS_STATUS_SUCCESS;
 425        struct _adapter *Adapter = poid_par_priv->adapter_context;
 426
 427        if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
 428                return RNDIS_STATUS_NOT_ACCEPTED;
 429        if (poid_par_priv->information_buf_len ==
 430           (sizeof(unsigned long) * 3)) {
 431                if (r8712_setrfreg_cmd(Adapter,
 432                        *(unsigned char *)poid_par_priv->information_buf,
 433                        (unsigned long)(*((unsigned long *)
 434                                        poid_par_priv->information_buf + 2))))
 435                        status = RNDIS_STATUS_NOT_ACCEPTED;
 436        } else {
 437                status = RNDIS_STATUS_INVALID_LENGTH;
 438        }
 439        return status;
 440}
 441
 442uint oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv)
 443{
 444        uint status = RNDIS_STATUS_SUCCESS;
 445        struct _adapter *Adapter = poid_par_priv->adapter_context;
 446
 447        if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
 448                return RNDIS_STATUS_NOT_ACCEPTED;
 449        if (poid_par_priv->information_buf_len == (sizeof(unsigned long) *
 450                                                   3)) {
 451                if (Adapter->mppriv.act_in_progress) {
 452                        status = RNDIS_STATUS_NOT_ACCEPTED;
 453                } else {
 454                        /* init workparam */
 455                        Adapter->mppriv.act_in_progress = true;
 456                        Adapter->mppriv.workparam.bcompleted = false;
 457                        Adapter->mppriv.workparam.act_type = MPT_READ_RF;
 458                        Adapter->mppriv.workparam.io_offset = *(unsigned long *)
 459                                                poid_par_priv->information_buf;
 460                        Adapter->mppriv.workparam.io_value = 0xcccccccc;
 461
 462                /* RegOffsetValue       - The offset of RF register to read.
 463                 * RegDataWidth - The data width of RF register to read.
 464                 * RegDataValue - The value to read.
 465                 * RegOffsetValue = *((unsigned long *)InformationBuffer);
 466                 * RegDataWidth = *((unsigned long *)InformationBuffer+1);
 467                 * RegDataValue =  *((unsigned long *)InformationBuffer+2);
 468                 */
 469                        if (r8712_getrfreg_cmd(Adapter,
 470                            *(unsigned char *)poid_par_priv->information_buf,
 471                            (unsigned char *)&Adapter->mppriv.workparam.io_value
 472                            ))
 473                                status = RNDIS_STATUS_NOT_ACCEPTED;
 474                }
 475        } else {
 476                status = RNDIS_STATUS_INVALID_LENGTH;
 477        }
 478        return status;
 479}
 480
 481enum _CONNECT_STATE_ {
 482        CHECKINGSTATUS,
 483        ASSOCIATED,
 484        ADHOCMODE,
 485        NOTASSOCIATED
 486};
 487
 488uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
 489{
 490        struct _adapter *padapter = poid_par_priv->adapter_context;
 491        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 492        u32 ulInfo;
 493
 494        if (poid_par_priv->type_of_oid != QUERY_OID)
 495                return RNDIS_STATUS_NOT_ACCEPTED;
 496        /* nStatus==0   CheckingStatus
 497         * nStatus==1   Associated
 498         * nStatus==2   AdHocMode
 499         * nStatus==3   NotAssociated
 500         */
 501        if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
 502                ulInfo = CHECKINGSTATUS;
 503        else if (check_fwstate(pmlmepriv, _FW_LINKED))
 504                ulInfo = ASSOCIATED;
 505        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
 506                ulInfo = ADHOCMODE;
 507        else
 508                ulInfo = NOTASSOCIATED;
 509        *(u32 *)poid_par_priv->information_buf = ulInfo;
 510        *poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
 511        return RNDIS_STATUS_SUCCESS;
 512}
 513
 514uint oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv)
 515{
 516        if (poid_par_priv->type_of_oid != SET_OID)
 517                return RNDIS_STATUS_NOT_ACCEPTED;
 518        return RNDIS_STATUS_SUCCESS;
 519}
 520