linux/drivers/staging/ath6kl/os/linux/ioctl.c
<<
>>
Prefs
   1//------------------------------------------------------------------------------
   2// Copyright (c) 2004-2010 Atheros Communications Inc.
   3// All rights reserved.
   4//
   5// 
   6//
   7// Permission to use, copy, modify, and/or distribute this software for any
   8// purpose with or without fee is hereby granted, provided that the above
   9// copyright notice and this permission notice appear in all copies.
  10//
  11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18//
  19//
  20//
  21// Author(s): ="Atheros"
  22//------------------------------------------------------------------------------
  23
  24#include "ar6000_drv.h"
  25#include "ieee80211_ioctl.h"
  26#include "ar6kap_common.h"
  27#include "targaddrs.h"
  28#include "a_hci.h"
  29#include "wlan_config.h"
  30
  31extern int enablerssicompensation;
  32A_UINT32 tcmdRxFreq;
  33extern unsigned int wmitimeout;
  34extern A_WAITQUEUE_HEAD arEvent;
  35extern int tspecCompliance;
  36extern int bmienable;
  37extern int bypasswmi;
  38extern int loghci;
  39
  40static int
  41ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq)
  42{
  43    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
  44
  45    if (ar->arWmiReady == FALSE) {
  46        return -EIO;
  47    }
  48
  49    if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) {
  50        return -EIO;
  51    }
  52
  53    return 0;
  54}
  55
  56static int
  57ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq)
  58{
  59    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
  60
  61    if (ar->arWmiReady == FALSE) {
  62        return -EIO;
  63    }
  64
  65
  66    /* currently assume only roam times are required */
  67    if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) {
  68        return -EIO;
  69    }
  70
  71
  72    return 0;
  73}
  74
  75static int
  76ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata)
  77{
  78    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
  79    WMI_SET_ROAM_CTRL_CMD cmd;
  80    A_UINT8 size = sizeof(cmd);
  81
  82    if (ar->arWmiReady == FALSE) {
  83        return -EIO;
  84    }
  85
  86
  87    if (copy_from_user(&cmd, userdata, size)) {
  88        return -EFAULT;
  89    }
  90
  91    if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) {
  92        if (cmd.info.bssBiasInfo.numBss > 1) {
  93            size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS);
  94        }
  95    }
  96
  97    if (copy_from_user(&cmd, userdata, size)) {
  98        return -EFAULT;
  99    }
 100
 101    if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) {
 102        return -EIO;
 103    }
 104
 105    return 0;
 106}
 107
 108static int
 109ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata)
 110{
 111    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 112    WMI_POWERSAVE_TIMERS_POLICY_CMD cmd;
 113    A_UINT8 size = sizeof(cmd);
 114
 115    if (ar->arWmiReady == FALSE) {
 116        return -EIO;
 117    }
 118
 119    if (copy_from_user(&cmd, userdata, size)) {
 120        return -EFAULT;
 121    }
 122
 123    if (copy_from_user(&cmd, userdata, size)) {
 124        return -EFAULT;
 125    }
 126
 127    if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) {
 128        return -EIO;
 129    }
 130
 131    return 0;
 132}
 133
 134static int
 135ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq)
 136{
 137    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 138    WMI_SET_QOS_SUPP_CMD cmd;
 139    A_STATUS ret;
 140
 141    if ((dev->flags & IFF_UP) != IFF_UP) {
 142        return -EIO;
 143    }
 144    if (ar->arWmiReady == FALSE) {
 145        return -EIO;
 146    }
 147
 148    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
 149                                sizeof(cmd)))
 150    {
 151        return -EFAULT;
 152    }
 153
 154    ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status);
 155
 156    switch (ret) {
 157        case A_OK:
 158            return 0;
 159        case A_EBUSY :
 160            return -EBUSY;
 161        case A_NO_MEMORY:
 162            return -ENOMEM;
 163        case A_EINVAL:
 164        default:
 165            return -EFAULT;
 166    }
 167}
 168
 169static int
 170ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq)
 171{
 172    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 173    WMI_SET_WMM_CMD cmd;
 174    A_STATUS ret;
 175
 176    if ((dev->flags & IFF_UP) != IFF_UP) {
 177        return -EIO;
 178    }
 179    if (ar->arWmiReady == FALSE) {
 180        return -EIO;
 181    }
 182
 183    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
 184                                sizeof(cmd)))
 185    {
 186        return -EFAULT;
 187    }
 188
 189    if (cmd.status == WMI_WMM_ENABLED) {
 190        ar->arWmmEnabled = TRUE;
 191    } else {
 192        ar->arWmmEnabled = FALSE;
 193    }
 194
 195    ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status);
 196
 197    switch (ret) {
 198        case A_OK:
 199            return 0;
 200        case A_EBUSY :
 201            return -EBUSY;
 202        case A_NO_MEMORY:
 203            return -ENOMEM;
 204        case A_EINVAL:
 205        default:
 206            return -EFAULT;
 207    }
 208}
 209
 210static int
 211ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq)
 212{
 213    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 214    WMI_SET_WMM_TXOP_CMD cmd;
 215    A_STATUS ret;
 216
 217    if ((dev->flags & IFF_UP) != IFF_UP) {
 218        return -EIO;
 219    }
 220    if (ar->arWmiReady == FALSE) {
 221        return -EIO;
 222    }
 223
 224    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
 225                                sizeof(cmd)))
 226    {
 227        return -EFAULT;
 228    }
 229
 230    ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable);
 231
 232    switch (ret) {
 233        case A_OK:
 234            return 0;
 235        case A_EBUSY :
 236            return -EBUSY;
 237        case A_NO_MEMORY:
 238            return -ENOMEM;
 239        case A_EINVAL:
 240        default:
 241            return -EFAULT;
 242    }
 243}
 244
 245static int
 246ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq)
 247{
 248    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 249    A_STATUS ret = 0;
 250
 251    if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) {
 252        return -EIO;
 253    }
 254
 255    if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1),
 256                            &ar->arRegCode, sizeof(ar->arRegCode)))
 257        ret = -EFAULT;
 258
 259    return ret;
 260}
 261
 262static int
 263ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq)
 264{
 265    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 266    WMI_AP_SET_COUNTRY_CMD cmd;
 267    A_STATUS ret;
 268
 269    if ((dev->flags & IFF_UP) != IFF_UP) {
 270        return -EIO;
 271    }
 272    if (ar->arWmiReady == FALSE) {
 273        return -EIO;
 274    }
 275
 276    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
 277                                sizeof(cmd)))
 278    {
 279        return -EFAULT;
 280    }
 281
 282    ar->ap_profile_flag = 1; /* There is a change in profile */
 283
 284    ret = wmi_set_country(ar->arWmi, cmd.countryCode);
 285    A_MEMCPY(ar->ap_country_code, cmd.countryCode, 3);
 286
 287    switch (ret) {
 288        case A_OK:
 289            return 0;
 290        case A_EBUSY :
 291            return -EBUSY;
 292        case A_NO_MEMORY:
 293            return -ENOMEM;
 294        case A_EINVAL:
 295        default:
 296            return -EFAULT;
 297    }
 298}
 299
 300
 301/* Get power mode command */
 302static int
 303ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq)
 304{
 305    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 306    WMI_POWER_MODE_CMD power_mode;
 307    int ret = 0;
 308
 309    if (ar->arWmiReady == FALSE) {
 310        return -EIO;
 311    }
 312
 313    power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi);
 314    if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) {
 315        ret = -EFAULT;
 316    }
 317
 318    return ret;
 319}
 320
 321
 322static int
 323ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq)
 324{
 325    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 326    WMI_CHANNEL_PARAMS_CMD cmd, *cmdp;
 327    int ret = 0;
 328
 329    if (ar->arWmiReady == FALSE) {
 330        return -EIO;
 331    }
 332
 333
 334    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 335        return -EFAULT;
 336    }
 337
 338    if( (ar->arNextMode == AP_NETWORK) && (cmd.numChannels || cmd.scanParam) ) {
 339        A_PRINTF("ERROR: Only wmode is allowed in AP mode\n");
 340        return -EIO;
 341    }
 342
 343    if (cmd.numChannels > 1) {
 344        cmdp = A_MALLOC(130);
 345        if (copy_from_user(cmdp, rq->ifr_data,
 346                           sizeof (*cmdp) +
 347                           ((cmd.numChannels - 1) * sizeof(A_UINT16))))
 348        {
 349            kfree(cmdp);
 350            return -EFAULT;
 351        }
 352    } else {
 353        cmdp = &cmd;
 354    }
 355
 356    if ((ar->arPhyCapability == WMI_11G_CAPABILITY) &&
 357        ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE)))
 358    {
 359        ret = -EINVAL;
 360    }
 361
 362    if (!ret &&
 363        (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode,
 364                                   cmdp->numChannels, cmdp->channelList)
 365         != A_OK))
 366    {
 367        ret = -EIO;
 368    }
 369
 370    if (cmd.numChannels > 1) {
 371        kfree(cmdp);
 372    }
 373
 374    ar->ap_wmode = cmdp->phyMode;
 375    /* Set the profile change flag to allow a commit cmd */
 376    ar->ap_profile_flag = 1;
 377
 378    return ret;
 379}
 380
 381
 382static int
 383ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq)
 384{
 385
 386    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 387    WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
 388    int ret = 0;
 389
 390    if (ar->arWmiReady == FALSE) {
 391        return -EIO;
 392    }
 393
 394    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 395        return -EFAULT;
 396    }
 397
 398    if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != A_OK ) {
 399        ret = -EIO;
 400    }
 401
 402    return ret;
 403}
 404
 405static int
 406ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq)
 407{
 408#define SWAP_THOLD(thold1, thold2) do { \
 409    USER_RSSI_THOLD tmpThold;           \
 410    tmpThold.tag = thold1.tag;          \
 411    tmpThold.rssi = thold1.rssi;        \
 412    thold1.tag = thold2.tag;            \
 413    thold1.rssi = thold2.rssi;          \
 414    thold2.tag = tmpThold.tag;          \
 415    thold2.rssi = tmpThold.rssi;        \
 416} while (0)
 417
 418    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 419    WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
 420    USER_RSSI_PARAMS rssiParams;
 421    A_INT32 i, j;
 422    int ret = 0;
 423
 424    if (ar->arWmiReady == FALSE) {
 425        return -EIO;
 426    }
 427
 428    if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(USER_RSSI_PARAMS))) {
 429        return -EFAULT;
 430    }
 431    cmd.weight = rssiParams.weight;
 432    cmd.pollTime = rssiParams.pollTime;
 433
 434    A_MEMCPY(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map));
 435    /*
 436     *  only 6 elements, so use bubble sorting, in ascending order
 437     */
 438    for (i = 5; i > 0; i--) {
 439        for (j = 0; j < i; j++) { /* above tholds */
 440            if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
 441                SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
 442            } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
 443                return EFAULT;
 444            }
 445        }
 446    }
 447    for (i = 11; i > 6; i--) {
 448        for (j = 6; j < i; j++) { /* below tholds */
 449            if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
 450                SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
 451            } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
 452                return EFAULT;
 453            }
 454        }
 455    }
 456
 457#ifdef DEBUG
 458    for (i = 0; i < 12; i++) {
 459        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("thold[%d].tag: %d, thold[%d].rssi: %d \n",
 460                i, ar->rssi_map[i].tag, i, ar->rssi_map[i].rssi));
 461    }
 462#endif
 463
 464    if (enablerssicompensation) {
 465        for (i = 0; i < 6; i++)
 466            ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, TRUE);
 467        for (i = 6; i < 12; i++)
 468            ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, FALSE);
 469    }
 470
 471    cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi;
 472    cmd.thresholdAbove2_Val = ar->rssi_map[1].rssi;
 473    cmd.thresholdAbove3_Val = ar->rssi_map[2].rssi;
 474    cmd.thresholdAbove4_Val = ar->rssi_map[3].rssi;
 475    cmd.thresholdAbove5_Val = ar->rssi_map[4].rssi;
 476    cmd.thresholdAbove6_Val = ar->rssi_map[5].rssi;
 477    cmd.thresholdBelow1_Val = ar->rssi_map[6].rssi;
 478    cmd.thresholdBelow2_Val = ar->rssi_map[7].rssi;
 479    cmd.thresholdBelow3_Val = ar->rssi_map[8].rssi;
 480    cmd.thresholdBelow4_Val = ar->rssi_map[9].rssi;
 481    cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi;
 482    cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi;
 483
 484    if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != A_OK ) {
 485        ret = -EIO;
 486    }
 487
 488    return ret;
 489}
 490
 491static int
 492ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq)
 493{
 494
 495    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 496    WMI_LQ_THRESHOLD_PARAMS_CMD cmd;
 497    int ret = 0;
 498
 499    if (ar->arWmiReady == FALSE) {
 500        return -EIO;
 501    }
 502
 503    if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(cmd))) {
 504        return -EFAULT;
 505    }
 506
 507    if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != A_OK ) {
 508        ret = -EIO;
 509    }
 510
 511    return ret;
 512}
 513
 514
 515static int
 516ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq)
 517{
 518    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 519    WMI_PROBED_SSID_CMD cmd;
 520    int ret = 0;
 521
 522    if (ar->arWmiReady == FALSE) {
 523        return -EIO;
 524    }
 525
 526    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 527        return -EFAULT;
 528    }
 529
 530    if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength,
 531                                  cmd.ssid) != A_OK)
 532    {
 533        ret = -EIO;
 534    }
 535
 536    return ret;
 537}
 538
 539static int
 540ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq)
 541{
 542    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 543    WMI_ADD_BAD_AP_CMD cmd;
 544    int ret = 0;
 545
 546    if (ar->arWmiReady == FALSE) {
 547        return -EIO;
 548    }
 549
 550
 551    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 552        return -EFAULT;
 553    }
 554
 555    if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) {
 556        return -EIO;
 557    }
 558
 559    if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) {
 560        /*
 561         * This is a delete badAP.
 562         */
 563        if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) {
 564            ret = -EIO;
 565        }
 566    } else {
 567        if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) {
 568            ret = -EIO;
 569        }
 570    }
 571
 572    return ret;
 573}
 574
 575static int
 576ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq)
 577{
 578    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 579    WMI_CREATE_PSTREAM_CMD cmd;
 580    A_STATUS ret;
 581
 582    if (ar->arWmiReady == FALSE) {
 583        return -EIO;
 584    }
 585
 586
 587    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 588        return -EFAULT;
 589    }
 590
 591    ret = wmi_verify_tspec_params(&cmd, tspecCompliance);
 592    if (ret == A_OK)
 593        ret = wmi_create_pstream_cmd(ar->arWmi, &cmd);
 594
 595    switch (ret) {
 596        case A_OK:
 597            return 0;
 598        case A_EBUSY :
 599            return -EBUSY;
 600        case A_NO_MEMORY:
 601            return -ENOMEM;
 602        case A_EINVAL:
 603        default:
 604            return -EFAULT;
 605    }
 606}
 607
 608static int
 609ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq)
 610{
 611    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 612    WMI_DELETE_PSTREAM_CMD cmd;
 613    int ret = 0;
 614
 615    if (ar->arWmiReady == FALSE) {
 616        return -EIO;
 617    }
 618
 619    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 620        return -EFAULT;
 621    }
 622
 623    ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid);
 624
 625    switch (ret) {
 626        case A_OK:
 627            return 0;
 628        case A_EBUSY :
 629            return -EBUSY;
 630        case A_NO_MEMORY:
 631            return -ENOMEM;
 632        case A_EINVAL:
 633        default:
 634            return -EFAULT;
 635    }
 636}
 637
 638static int
 639ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq)
 640{
 641    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 642    struct ar6000_queuereq qreq;
 643    int ret = 0;
 644
 645    if (ar->arWmiReady == FALSE) {
 646        return -EIO;
 647    }
 648
 649    if( copy_from_user(&qreq, rq->ifr_data,
 650                  sizeof(struct ar6000_queuereq)))
 651        return -EFAULT;
 652
 653    qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass);
 654
 655    if (copy_to_user(rq->ifr_data, &qreq,
 656                 sizeof(struct ar6000_queuereq)))
 657    {
 658        ret = -EFAULT;
 659    }
 660
 661    return ret;
 662}
 663
 664#ifdef CONFIG_HOST_TCMD_SUPPORT
 665static A_STATUS
 666ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev,
 667                                 struct ifreq *rq, A_UINT8 *data, A_UINT32 len)
 668{
 669    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 670    A_UINT32    buf[4+TCMD_MAX_RATES];
 671    int ret = 0;
 672
 673    if (ar->bIsDestroyProgress) {
 674        return -EBUSY;
 675    }
 676
 677    if (ar->arWmiReady == FALSE) {
 678        return -EIO;
 679    }
 680
 681    if (down_interruptible(&ar->arSem)) {
 682        return -ERESTARTSYS;
 683    }
 684
 685    if (ar->bIsDestroyProgress) {
 686        up(&ar->arSem);
 687        return -EBUSY;
 688    }
 689
 690    ar->tcmdRxReport = 0;
 691    if (wmi_test_cmd(ar->arWmi, data, len) != A_OK) {
 692        up(&ar->arSem);
 693        return -EIO;
 694    }
 695
 696    wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ);
 697
 698    if (signal_pending(current)) {
 699        ret = -EINTR;
 700    }
 701
 702    buf[0] = ar->tcmdRxTotalPkt;
 703    buf[1] = ar->tcmdRxRssi;
 704    buf[2] = ar->tcmdRxcrcErrPkt;
 705    buf[3] = ar->tcmdRxsecErrPkt;
 706    A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt));
 707    A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(A_UINT16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
 708
 709    if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) {
 710        ret = -EFAULT;
 711    }
 712
 713    up(&ar->arSem);
 714
 715    return ret;
 716}
 717
 718void
 719ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len)
 720{
 721    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
 722    TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results;
 723
 724    if (enablerssicompensation) {
 725        rx_rep->u.report.rssiInDBm = rssi_compensation_calc_tcmd(tcmdRxFreq, rx_rep->u.report.rssiInDBm,rx_rep->u.report.totalPkt);
 726    }
 727
 728
 729    ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt;
 730    ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm;
 731    ar->tcmdRxcrcErrPkt = rx_rep->u.report.crcErrPkt;
 732    ar->tcmdRxsecErrPkt = rx_rep->u.report.secErrPkt;
 733    ar->tcmdRxReport = 1;
 734    A_MEMZERO(ar->tcmdRateCnt,  sizeof(ar->tcmdRateCnt));
 735    A_MEMZERO(ar->tcmdRateCntShortGuard,  sizeof(ar->tcmdRateCntShortGuard));
 736    A_MEMCPY(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt));
 737    A_MEMCPY(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
 738
 739    wake_up(&arEvent);
 740}
 741#endif /* CONFIG_HOST_TCMD_SUPPORT*/
 742
 743static int
 744ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq)
 745{
 746    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 747    WMI_TARGET_ERROR_REPORT_BITMASK cmd;
 748    int ret = 0;
 749
 750    if (ar->arWmiReady == FALSE) {
 751        return -EIO;
 752    }
 753
 754    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 755        return -EFAULT;
 756    }
 757
 758    ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask);
 759
 760    return  (ret==0 ? ret : -EINVAL);
 761}
 762
 763static int
 764ar6000_clear_target_stats(struct net_device *dev)
 765{
 766    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 767    TARGET_STATS *pStats = &ar->arTargetStats;
 768    int ret = 0;
 769
 770    if (ar->arWmiReady == FALSE) {
 771       return -EIO;
 772    }
 773    AR6000_SPIN_LOCK(&ar->arLock, 0);
 774    A_MEMZERO(pStats, sizeof(TARGET_STATS));
 775    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 776    return ret;
 777}
 778
 779static int
 780ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq)
 781{
 782    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 783    TARGET_STATS_CMD cmd;
 784    TARGET_STATS *pStats = &ar->arTargetStats;
 785    int ret = 0;
 786
 787    if (ar->bIsDestroyProgress) {
 788        return -EBUSY;
 789    }
 790    if (ar->arWmiReady == FALSE) {
 791        return -EIO;
 792    }
 793    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 794        return -EFAULT;
 795    }
 796    if (down_interruptible(&ar->arSem)) {
 797        return -ERESTARTSYS;
 798    }
 799    if (ar->bIsDestroyProgress) {
 800        up(&ar->arSem);
 801        return -EBUSY;
 802    }
 803
 804    ar->statsUpdatePending = TRUE;
 805
 806    if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
 807        up(&ar->arSem);
 808        return -EIO;
 809    }
 810
 811    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
 812
 813    if (signal_pending(current)) {
 814        ret = -EINTR;
 815    }
 816
 817    if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
 818        ret = -EFAULT;
 819    }
 820
 821    if (cmd.clearStats == 1) {
 822        ret = ar6000_clear_target_stats(dev);
 823    }
 824
 825    up(&ar->arSem);
 826
 827    return ret;
 828}
 829
 830static int
 831ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq)
 832{
 833    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 834    A_UINT32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */
 835    WMI_AP_MODE_STAT *pStats = &ar->arAPStats;
 836    int ret = 0;
 837
 838    if (ar->arWmiReady == FALSE) {
 839        return -EIO;
 840    }
 841    if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1),
 842                                sizeof(A_UINT32)))
 843    {
 844        return -EFAULT;
 845    }
 846    if (action == AP_CLEAR_STATS) {
 847        A_UINT8 i;
 848        AR6000_SPIN_LOCK(&ar->arLock, 0);
 849        for(i = 0; i < AP_MAX_NUM_STA; i++) {
 850            pStats->sta[i].tx_bytes = 0;
 851            pStats->sta[i].tx_pkts = 0;
 852            pStats->sta[i].tx_error = 0;
 853            pStats->sta[i].tx_discard = 0;
 854            pStats->sta[i].rx_bytes = 0;
 855            pStats->sta[i].rx_pkts = 0;
 856            pStats->sta[i].rx_error = 0;
 857            pStats->sta[i].rx_discard = 0;
 858        }
 859        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 860        return ret;
 861    }
 862
 863    if (down_interruptible(&ar->arSem)) {
 864        return -ERESTARTSYS;
 865    }
 866
 867    ar->statsUpdatePending = TRUE;
 868
 869    if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
 870        up(&ar->arSem);
 871        return -EIO;
 872    }
 873
 874    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
 875
 876    if (signal_pending(current)) {
 877        ret = -EINTR;
 878    }
 879
 880    if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
 881        ret = -EFAULT;
 882    }
 883
 884    up(&ar->arSem);
 885
 886    return ret;
 887}
 888
 889static int
 890ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq)
 891{
 892    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 893    WMI_SET_ACCESS_PARAMS_CMD cmd;
 894    int ret = 0;
 895
 896    if (ar->arWmiReady == FALSE) {
 897        return -EIO;
 898    }
 899
 900    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 901        return -EFAULT;
 902    }
 903
 904    if (wmi_set_access_params_cmd(ar->arWmi, cmd.ac, cmd.txop, cmd.eCWmin, cmd.eCWmax,
 905                                  cmd.aifsn) == A_OK)
 906    {
 907        ret = 0;
 908    } else {
 909        ret = -EINVAL;
 910    }
 911
 912    return (ret);
 913}
 914
 915static int
 916ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq)
 917{
 918    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 919    WMI_DISC_TIMEOUT_CMD cmd;
 920    int ret = 0;
 921
 922    if (ar->arWmiReady == FALSE) {
 923        return -EIO;
 924    }
 925
 926    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
 927        return -EFAULT;
 928    }
 929
 930    if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK)
 931    {
 932        ret = 0;
 933    } else {
 934        ret = -EINVAL;
 935    }
 936
 937    return (ret);
 938}
 939
 940static int
 941ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata)
 942{
 943    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 944    WMI_SET_VOICE_PKT_SIZE_CMD cmd;
 945    int ret = 0;
 946
 947    if (ar->arWmiReady == FALSE) {
 948        return -EIO;
 949    }
 950
 951    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
 952        return -EFAULT;
 953    }
 954
 955    if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK)
 956    {
 957        ret = 0;
 958    } else {
 959        ret = -EINVAL;
 960    }
 961
 962
 963    return (ret);
 964}
 965
 966static int
 967ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata)
 968{
 969    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 970    WMI_SET_MAX_SP_LEN_CMD cmd;
 971    int ret = 0;
 972
 973    if (ar->arWmiReady == FALSE) {
 974        return -EIO;
 975    }
 976
 977    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
 978        return -EFAULT;
 979    }
 980
 981    if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK)
 982    {
 983        ret = 0;
 984    } else {
 985        ret = -EINVAL;
 986    }
 987
 988    return (ret);
 989}
 990
 991
 992static int
 993ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata)
 994{
 995    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 996    WMI_SET_BT_STATUS_CMD cmd;
 997    int ret = 0;
 998
 999    if (ar->arWmiReady == FALSE) {
1000        return -EIO;
1001    }
1002
1003    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1004        return -EFAULT;
1005    }
1006
1007    if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == A_OK)
1008    {
1009        ret = 0;
1010    } else {
1011        ret = -EINVAL;
1012    }
1013
1014    return (ret);
1015}
1016
1017static int
1018ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata)
1019{
1020    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1021    WMI_SET_BT_PARAMS_CMD cmd;
1022    int ret = 0;
1023
1024    if (ar->arWmiReady == FALSE) {
1025        return -EIO;
1026    }
1027
1028    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1029        return -EFAULT;
1030    }
1031
1032    if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == A_OK)
1033    {
1034        ret = 0;
1035    } else {
1036        ret = -EINVAL;
1037    }
1038
1039    return (ret);
1040}
1041
1042static int
1043ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata)
1044{
1045        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1046        WMI_SET_BTCOEX_FE_ANT_CMD cmd;
1047    int ret = 0;
1048
1049        if (ar->arWmiReady == FALSE) {
1050                return -EIO;
1051        }
1052        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1053                return -EFAULT;
1054        }
1055
1056    if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == A_OK)
1057    {
1058        ret = 0;
1059    } else {
1060        ret = -EINVAL;
1061    }
1062
1063        return(ret);
1064}
1065
1066static int
1067ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * userdata)
1068{
1069        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1070        WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd;
1071    int ret = 0;
1072
1073        if (ar->arWmiReady == FALSE) {
1074                return -EIO;
1075        }
1076
1077        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1078                return -EFAULT;
1079        }
1080
1081    if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == A_OK)
1082    {
1083        ret = 0;
1084    } else {
1085        ret = -EINVAL;
1086    }
1087
1088        return(ret);
1089}
1090
1091static int
1092ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev,  char * userdata)
1093{
1094        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1095        WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd;
1096    int ret = 0;
1097
1098        if (ar->arWmiReady == FALSE) {
1099                return -EIO;
1100        }
1101
1102        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1103                return -EFAULT;
1104        }
1105
1106    if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == A_OK)
1107    {
1108        ret = 0;
1109    } else {
1110        ret = -EINVAL;
1111    }
1112
1113        return(ret);
1114}
1115
1116static int
1117ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata)
1118{
1119        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1120        WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd;
1121    int ret = 0;
1122
1123        if (ar->arWmiReady == FALSE) {
1124                return -EIO;
1125        }
1126
1127        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1128                return -EFAULT;
1129        }
1130
1131    if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == A_OK)
1132    {
1133        ret = 0;
1134    } else {
1135        ret = -EINVAL;
1136    }
1137
1138        return(ret);
1139}
1140
1141static int
1142ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev,
1143                                                                                                                char * userdata)
1144{
1145        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1146        WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd;
1147    int ret = 0;
1148
1149        if (ar->arWmiReady == FALSE) {
1150                return -EIO;
1151        }
1152
1153        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1154                return -EFAULT;
1155        }
1156
1157    if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == A_OK)
1158    {
1159        ret = 0;
1160    } else {
1161        ret = -EINVAL;
1162    }
1163
1164        return(ret);
1165}
1166
1167static int
1168ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * userdata)
1169{
1170        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1171        WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd;
1172    int ret = 0;
1173
1174        if (ar->arWmiReady == FALSE) {
1175                return -EIO;
1176        }
1177
1178        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1179                return -EFAULT;
1180        }
1181
1182    if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == A_OK)
1183    {
1184        ret = 0;
1185    } else {
1186        ret = -EINVAL;
1187    }
1188
1189        return(ret);
1190}
1191
1192static int
1193ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata)
1194{
1195        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1196        WMI_SET_BTCOEX_DEBUG_CMD cmd;
1197    int ret = 0;
1198
1199        if (ar->arWmiReady == FALSE) {
1200                return -EIO;
1201        }
1202
1203        if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1204                return -EFAULT;
1205        }
1206
1207    if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == A_OK)
1208    {
1209        ret = 0;
1210    } else {
1211        ret = -EINVAL;
1212    }
1213
1214        return(ret);
1215}
1216
1217static int
1218ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * userdata)
1219{
1220     AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1221     WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd;
1222     int ret = 0;
1223
1224    if (ar->arWmiReady == FALSE) {
1225        return -EIO;
1226    }
1227
1228    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1229        return -EFAULT;
1230    }
1231
1232    if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == A_OK)
1233    {
1234        ret = 0;
1235    } else {
1236        ret = -EINVAL;
1237    }
1238    return(ret);
1239}
1240
1241static int
1242ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata,
1243                                                                                        struct ifreq *rq)
1244{
1245
1246        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1247    AR6000_BTCOEX_CONFIG btcoexConfig;
1248    WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig;
1249
1250    int ret = 0;
1251
1252    if (ar->bIsDestroyProgress) {
1253            return -EBUSY;
1254    }
1255    if (ar->arWmiReady == FALSE) {
1256            return -EIO;
1257    }
1258        if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
1259                return -EFAULT;
1260        }
1261    if (down_interruptible(&ar->arSem)) {
1262        return -ERESTARTSYS;
1263    }
1264
1265    if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != A_OK)
1266    {
1267        up(&ar->arSem);
1268        return -EIO;
1269    }
1270
1271    ar->statsUpdatePending = TRUE;
1272
1273    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
1274
1275    if (signal_pending(current)) {
1276       ret = -EINTR;
1277    }
1278
1279    if (!ret && copy_to_user(btcoexConfig.configEvent, pbtcoexConfigEv, sizeof(WMI_BTCOEX_CONFIG_EVENT))) {
1280            ret = -EFAULT;
1281    }
1282    up(&ar->arSem);
1283    return ret;
1284}
1285
1286static int
1287ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, struct ifreq *rq)
1288{
1289        AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1290    AR6000_BTCOEX_STATS btcoexStats;
1291    WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats;
1292    int ret = 0;
1293
1294    if (ar->bIsDestroyProgress) {
1295            return -EBUSY;
1296    }
1297    if (ar->arWmiReady == FALSE) {
1298            return -EIO;
1299    }
1300
1301    if (down_interruptible(&ar->arSem)) {
1302        return -ERESTARTSYS;
1303    }
1304
1305        if (copy_from_user(&btcoexStats.statsEvent, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
1306                return -EFAULT;
1307        }
1308
1309    if (wmi_get_btcoex_stats_cmd(ar->arWmi) != A_OK)
1310    {
1311        up(&ar->arSem);
1312        return -EIO;
1313    }
1314
1315    ar->statsUpdatePending = TRUE;
1316
1317    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
1318
1319    if (signal_pending(current)) {
1320       ret = -EINTR;
1321    }
1322
1323    if (!ret && copy_to_user(btcoexStats.statsEvent, pbtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT))) {
1324            ret = -EFAULT;
1325    }
1326
1327
1328    up(&ar->arSem);
1329
1330        return(ret);
1331}
1332
1333#ifdef CONFIG_HOST_GPIO_SUPPORT
1334struct ar6000_gpio_intr_wait_cmd_s  gpio_intr_results;
1335/* gpio_reg_results and gpio_data_available are protected by arSem */
1336static struct ar6000_gpio_register_cmd_s gpio_reg_results;
1337static A_BOOL gpio_data_available; /* Requested GPIO data available */
1338static A_BOOL gpio_intr_available; /* GPIO interrupt info available */
1339static A_BOOL gpio_ack_received;   /* GPIO ack was received */
1340
1341/* Host-side initialization for General Purpose I/O support */
1342void ar6000_gpio_init(void)
1343{
1344    gpio_intr_available = FALSE;
1345    gpio_data_available = FALSE;
1346    gpio_ack_received   = FALSE;
1347}
1348
1349/*
1350 * Called when a GPIO interrupt is received from the Target.
1351 * intr_values shows which GPIO pins have interrupted.
1352 * input_values shows a recent value of GPIO pins.
1353 */
1354void
1355ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values)
1356{
1357    gpio_intr_results.intr_mask = intr_mask;
1358    gpio_intr_results.input_values = input_values;
1359    *((volatile A_BOOL *)&gpio_intr_available) = TRUE;
1360    wake_up(&arEvent);
1361}
1362
1363/*
1364 * This is called when a response is received from the Target
1365 * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get
1366 * call.
1367 */
1368void
1369ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value)
1370{
1371    gpio_reg_results.gpioreg_id = reg_id;
1372    gpio_reg_results.value = value;
1373    *((volatile A_BOOL *)&gpio_data_available) = TRUE;
1374    wake_up(&arEvent);
1375}
1376
1377/*
1378 * This is called when an acknowledgement is received from the Target
1379 * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set
1380 * call.
1381 */
1382void
1383ar6000_gpio_ack_rx(void)
1384{
1385    gpio_ack_received = TRUE;
1386    wake_up(&arEvent);
1387}
1388
1389A_STATUS
1390ar6000_gpio_output_set(struct net_device *dev,
1391                       A_UINT32 set_mask,
1392                       A_UINT32 clear_mask,
1393                       A_UINT32 enable_mask,
1394                       A_UINT32 disable_mask)
1395{
1396    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1397
1398    gpio_ack_received = FALSE;
1399    return wmi_gpio_output_set(ar->arWmi,
1400                set_mask, clear_mask, enable_mask, disable_mask);
1401}
1402
1403static A_STATUS
1404ar6000_gpio_input_get(struct net_device *dev)
1405{
1406    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1407
1408    *((volatile A_BOOL *)&gpio_data_available) = FALSE;
1409    return wmi_gpio_input_get(ar->arWmi);
1410}
1411
1412static A_STATUS
1413ar6000_gpio_register_set(struct net_device *dev,
1414                         A_UINT32 gpioreg_id,
1415                         A_UINT32 value)
1416{
1417    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1418
1419    gpio_ack_received = FALSE;
1420    return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value);
1421}
1422
1423static A_STATUS
1424ar6000_gpio_register_get(struct net_device *dev,
1425                         A_UINT32 gpioreg_id)
1426{
1427    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1428
1429    *((volatile A_BOOL *)&gpio_data_available) = FALSE;
1430    return wmi_gpio_register_get(ar->arWmi, gpioreg_id);
1431}
1432
1433static A_STATUS
1434ar6000_gpio_intr_ack(struct net_device *dev,
1435                     A_UINT32 ack_mask)
1436{
1437    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1438
1439    gpio_intr_available = FALSE;
1440    return wmi_gpio_intr_ack(ar->arWmi, ack_mask);
1441}
1442#endif /* CONFIG_HOST_GPIO_SUPPORT */
1443
1444#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1445static struct prof_count_s prof_count_results;
1446static A_BOOL prof_count_available; /* Requested GPIO data available */
1447
1448static A_STATUS
1449prof_count_get(struct net_device *dev)
1450{
1451    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1452
1453    *((volatile A_BOOL *)&prof_count_available) = FALSE;
1454    return wmi_prof_count_get_cmd(ar->arWmi);
1455}
1456
1457/*
1458 * This is called when a response is received from the Target
1459 * for a previous prof_count_get call.
1460 */
1461void
1462prof_count_rx(A_UINT32 addr, A_UINT32 count)
1463{
1464    prof_count_results.addr = addr;
1465    prof_count_results.count = count;
1466    *((volatile A_BOOL *)&prof_count_available) = TRUE;
1467    wake_up(&arEvent);
1468}
1469#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
1470
1471
1472static A_STATUS
1473ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p_osbuf)
1474{
1475    void *osbuf = NULL;
1476    A_UINT8 tmp_space[8];
1477    HCI_ACL_DATA_PKT *acl;
1478    A_UINT8 hdr_size, *datap=NULL;
1479    A_STATUS ret = A_OK;
1480
1481    /* ACL is in data path. There is a need to create pool
1482     * mechanism for allocating and freeing NETBUFs - ToDo later.
1483     */
1484
1485    *p_osbuf = NULL;
1486    acl = (HCI_ACL_DATA_PKT *)tmp_space;
1487    hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len);
1488
1489    do {
1490        if (a_copy_from_user(acl, userdata, hdr_size)) {
1491            ret = A_EFAULT;
1492            break;
1493        }
1494
1495        osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len);
1496        if (osbuf == NULL) {
1497           ret = A_NO_MEMORY;
1498           break;
1499        }
1500        A_NETBUF_PUT(osbuf, hdr_size + acl->data_len);
1501        datap = (A_UINT8 *)A_NETBUF_DATA(osbuf);
1502
1503        /* Real copy to osbuf */
1504        acl = (HCI_ACL_DATA_PKT *)(datap);
1505        A_MEMCPY(acl, tmp_space, hdr_size);
1506        if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) {
1507            ret = A_EFAULT;
1508            break;
1509        }
1510    } while(FALSE);
1511
1512    if (ret == A_OK) {
1513        *p_osbuf = osbuf;
1514    } else {
1515        A_NETBUF_FREE(osbuf);
1516    }
1517    return ret;
1518}
1519
1520
1521
1522int
1523ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value)
1524{
1525    int ret=0;
1526
1527    switch(param) {
1528        case IEEE80211_PARAM_WPA:
1529            switch (value) {
1530                case WPA_MODE_WPA1:
1531                    ar->arAuthMode = WPA_AUTH;
1532                    break;
1533                case WPA_MODE_WPA2:
1534                    ar->arAuthMode = WPA2_AUTH;
1535                    break;
1536                case WPA_MODE_AUTO:
1537                    ar->arAuthMode = WPA_AUTH | WPA2_AUTH;
1538                    break;
1539                case WPA_MODE_NONE:
1540                    ar->arAuthMode = NONE_AUTH;
1541                    break;
1542            }
1543            break;
1544        case IEEE80211_PARAM_AUTHMODE:
1545            if(value == IEEE80211_AUTH_WPA_PSK) {
1546                if (WPA_AUTH == ar->arAuthMode) {
1547                    ar->arAuthMode = WPA_PSK_AUTH;
1548                } else if (WPA2_AUTH == ar->arAuthMode) {
1549                    ar->arAuthMode = WPA2_PSK_AUTH;
1550                } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) {
1551                    ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH;
1552                } else {
1553                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
1554                        "mode when WPA param was set to %d\n",
1555                        ar->arAuthMode));
1556                    ret = -EIO;
1557                }
1558            }
1559            break;
1560        case IEEE80211_PARAM_UCASTCIPHER:
1561            ar->arPairwiseCrypto = 0;
1562            if(value & (1<<IEEE80211_CIPHER_AES_CCM)) {
1563                ar->arPairwiseCrypto |= AES_CRYPT;
1564            }
1565            if(value & (1<<IEEE80211_CIPHER_TKIP)) {
1566                ar->arPairwiseCrypto |= TKIP_CRYPT;
1567            }
1568            if(!ar->arPairwiseCrypto) {
1569                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1570                           ("Error - Invalid cipher in WPA \n"));
1571                ret = -EIO;
1572            }
1573            break;
1574        case IEEE80211_PARAM_PRIVACY:
1575            if(value == 0) {
1576                ar->arDot11AuthMode      = OPEN_AUTH;
1577                ar->arAuthMode           = NONE_AUTH;
1578                ar->arPairwiseCrypto     = NONE_CRYPT;
1579                ar->arPairwiseCryptoLen  = 0;
1580                ar->arGroupCrypto        = NONE_CRYPT;
1581                ar->arGroupCryptoLen     = 0;
1582            }
1583            break;
1584#ifdef WAPI_ENABLE
1585        case IEEE80211_PARAM_WAPI:
1586            A_PRINTF("WAPI Policy: %d\n", value);
1587            ar->arDot11AuthMode      = OPEN_AUTH;
1588            ar->arAuthMode           = NONE_AUTH;
1589            if(value & 0x1) {
1590                ar->arPairwiseCrypto     = WAPI_CRYPT;
1591                ar->arGroupCrypto        = WAPI_CRYPT;
1592            } else {
1593                ar->arPairwiseCrypto     = NONE_CRYPT;
1594                ar->arGroupCrypto        = NONE_CRYPT;
1595            }
1596            break;
1597#endif
1598    }
1599    return ret;
1600}
1601
1602int
1603ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value)
1604{
1605    A_BOOL profChanged = FALSE;
1606    int ret=0;
1607
1608    if(ar->arNextMode == AP_NETWORK) {
1609        ar->ap_profile_flag = 1; /* There is a change in profile */
1610        switch (param) {
1611            case IEEE80211_PARAM_WPA:
1612            case IEEE80211_PARAM_AUTHMODE:
1613            case IEEE80211_PARAM_UCASTCIPHER:
1614            case IEEE80211_PARAM_PRIVACY:
1615            case IEEE80211_PARAM_WAPI:
1616                ret = ar6000_ioctl_ap_setparam(ar, param, value);
1617                return ret;
1618        }
1619    }
1620
1621    switch (param) {
1622        case IEEE80211_PARAM_WPA:
1623            switch (value) {
1624                case WPA_MODE_WPA1:
1625                    ar->arAuthMode = WPA_AUTH;
1626                    profChanged    = TRUE;
1627                    break;
1628                case WPA_MODE_WPA2:
1629                    ar->arAuthMode = WPA2_AUTH;
1630                    profChanged    = TRUE;
1631                    break;
1632                case WPA_MODE_NONE:
1633                    ar->arAuthMode = NONE_AUTH;
1634                    profChanged    = TRUE;
1635                    break;
1636            }
1637            break;
1638        case IEEE80211_PARAM_AUTHMODE:
1639            switch(value) {
1640                case IEEE80211_AUTH_WPA_PSK:
1641                    if (WPA_AUTH == ar->arAuthMode) {
1642                        ar->arAuthMode = WPA_PSK_AUTH;
1643                        profChanged    = TRUE;
1644                    } else if (WPA2_AUTH == ar->arAuthMode) {
1645                        ar->arAuthMode = WPA2_PSK_AUTH;
1646                        profChanged    = TRUE;
1647                    } else {
1648                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
1649                            "mode when WPA param was set to %d\n",
1650                            ar->arAuthMode));
1651                        ret = -EIO;
1652                    }
1653                    break;
1654                case IEEE80211_AUTH_WPA_CCKM:
1655                    if (WPA2_AUTH == ar->arAuthMode) {
1656                        ar->arAuthMode = WPA2_AUTH_CCKM;
1657                    } else {
1658                        ar->arAuthMode = WPA_AUTH_CCKM;
1659                    }
1660                    break;
1661                default:
1662                    break;
1663            }
1664            break;
1665        case IEEE80211_PARAM_UCASTCIPHER:
1666            switch (value) {
1667                case IEEE80211_CIPHER_AES_CCM:
1668                    ar->arPairwiseCrypto = AES_CRYPT;
1669                    profChanged          = TRUE;
1670                    break;
1671                case IEEE80211_CIPHER_TKIP:
1672                    ar->arPairwiseCrypto = TKIP_CRYPT;
1673                    profChanged          = TRUE;
1674                    break;
1675                case IEEE80211_CIPHER_WEP:
1676                    ar->arPairwiseCrypto = WEP_CRYPT;
1677                    profChanged          = TRUE;
1678                    break;
1679                case IEEE80211_CIPHER_NONE:
1680                    ar->arPairwiseCrypto = NONE_CRYPT;
1681                    profChanged          = TRUE;
1682                    break;
1683            }
1684            break;
1685        case IEEE80211_PARAM_UCASTKEYLEN:
1686            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1687                ret = -EIO;
1688            } else {
1689                ar->arPairwiseCryptoLen = value;
1690            }
1691            break;
1692        case IEEE80211_PARAM_MCASTCIPHER:
1693            switch (value) {
1694                case IEEE80211_CIPHER_AES_CCM:
1695                    ar->arGroupCrypto = AES_CRYPT;
1696                    profChanged       = TRUE;
1697                    break;
1698                case IEEE80211_CIPHER_TKIP:
1699                    ar->arGroupCrypto = TKIP_CRYPT;
1700                    profChanged       = TRUE;
1701                    break;
1702                case IEEE80211_CIPHER_WEP:
1703                    ar->arGroupCrypto = WEP_CRYPT;
1704                    profChanged       = TRUE;
1705                    break;
1706                case IEEE80211_CIPHER_NONE:
1707                    ar->arGroupCrypto = NONE_CRYPT;
1708                    profChanged       = TRUE;
1709                    break;
1710            }
1711            break;
1712        case IEEE80211_PARAM_MCASTKEYLEN:
1713            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1714                ret = -EIO;
1715            } else {
1716                ar->arGroupCryptoLen = value;
1717            }
1718            break;
1719        case IEEE80211_PARAM_COUNTERMEASURES:
1720            if (ar->arWmiReady == FALSE) {
1721                return -EIO;
1722            }
1723            wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
1724            break;
1725        default:
1726            break;
1727    }
1728    if ((ar->arNextMode != AP_NETWORK) && (profChanged == TRUE)) {
1729        /*
1730         * profile has changed.  Erase ssid to signal change
1731         */
1732        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1733    }
1734
1735    return ret;
1736}
1737
1738int
1739ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik)
1740{
1741    KEY_USAGE keyUsage;
1742    A_STATUS status;
1743    CRYPTO_TYPE keyType = NONE_CRYPT;
1744
1745#ifdef USER_KEYS
1746    ar->user_saved_keys.keyOk = FALSE;
1747#endif
1748    if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) ||
1749         (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) {
1750        keyUsage = GROUP_USAGE;
1751        if(ar->arNextMode == AP_NETWORK) {
1752            A_MEMCPY(&ar->ap_mode_bkey, ik,
1753                     sizeof(struct ieee80211req_key));
1754#ifdef WAPI_ENABLE
1755            if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1756                return ap_set_wapi_key(ar, ik);
1757            }
1758#endif
1759        }
1760#ifdef USER_KEYS
1761        A_MEMCPY(&ar->user_saved_keys.bcast_ik, ik,
1762                 sizeof(struct ieee80211req_key));
1763#endif
1764    } else {
1765        keyUsage = PAIRWISE_USAGE;
1766#ifdef USER_KEYS
1767        A_MEMCPY(&ar->user_saved_keys.ucast_ik, ik,
1768                 sizeof(struct ieee80211req_key));
1769#endif
1770#ifdef WAPI_ENABLE
1771        if(ar->arNextMode == AP_NETWORK) {
1772            if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1773                return ap_set_wapi_key(ar, ik);
1774            }
1775        }
1776#endif
1777    }
1778
1779    switch (ik->ik_type) {
1780        case IEEE80211_CIPHER_WEP:
1781            keyType = WEP_CRYPT;
1782            break;
1783        case IEEE80211_CIPHER_TKIP:
1784            keyType = TKIP_CRYPT;
1785            break;
1786        case IEEE80211_CIPHER_AES_CCM:
1787            keyType = AES_CRYPT;
1788            break;
1789        default:
1790            break;
1791    }
1792#ifdef USER_KEYS
1793    ar->user_saved_keys.keyType = keyType;
1794#endif
1795    if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
1796        if (NONE_CRYPT == keyType) {
1797            return -EIO;
1798        }
1799
1800        if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) {
1801             int index = ik->ik_keyix;
1802
1803            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) {
1804                return -EIO;
1805            }
1806
1807            A_MEMZERO(ar->arWepKeyList[index].arKey,
1808                            sizeof(ar->arWepKeyList[index].arKey));
1809            A_MEMCPY(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen);
1810            ar->arWepKeyList[index].arKeyLen = ik->ik_keylen;
1811
1812            if(ik->ik_flags & IEEE80211_KEY_DEFAULT){
1813                ar->arDefTxKeyIndex = index;
1814            }
1815
1816            return 0;
1817        }
1818
1819        if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
1820            (GROUP_USAGE & keyUsage))
1821        {
1822            A_UNTIMEOUT(&ar->disconnect_timer);
1823        }
1824
1825        status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
1826                                ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
1827                                ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
1828                                SYNC_BOTH_WMIFLAG);
1829
1830        if (status != A_OK) {
1831            return -EIO;
1832        }
1833    } else {
1834        status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
1835    }
1836
1837#ifdef USER_KEYS
1838    ar->user_saved_keys.keyOk = TRUE;
1839#endif
1840
1841    return 0;
1842}
1843
1844int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1845{
1846    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1847    HIF_DEVICE *hifDevice = ar->arHifDevice;
1848    int ret = 0, param;
1849    unsigned int address = 0;
1850    unsigned int length = 0;
1851    unsigned char *buffer;
1852    char *userdata;
1853    A_UINT32 connectCtrlFlags;
1854
1855
1856    WMI_SET_AKMP_PARAMS_CMD  akmpParams;
1857    WMI_SET_PMKID_LIST_CMD   pmkidInfo;
1858
1859    WMI_SET_HT_CAP_CMD htCap;
1860    WMI_SET_HT_OP_CMD htOp;
1861
1862    /*
1863     * ioctl operations may have to wait for the Target, so we cannot hold rtnl.
1864     * Prevent the device from disappearing under us and release the lock during
1865     * the ioctl operation.
1866     */
1867    dev_hold(dev);
1868    rtnl_unlock();
1869
1870    if (cmd == AR6000_IOCTL_EXTENDED) {
1871        /*
1872         * This allows for many more wireless ioctls than would otherwise
1873         * be available.  Applications embed the actual ioctl command in
1874         * the first word of the parameter block, and use the command
1875         * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
1876         */
1877        if (get_user(cmd, (int *)rq->ifr_data)) {
1878            ret = -EFAULT;
1879            goto ioctl_done;
1880        }
1881        userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
1882        if(is_xioctl_allowed(ar->arNextMode, cmd) != A_OK) {
1883            A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd);
1884            ret = -EOPNOTSUPP;
1885            goto ioctl_done;
1886    }
1887    } else {
1888        A_STATUS ret = is_iwioctl_allowed(ar->arNextMode, cmd);
1889        if(ret == A_ENOTSUP) {
1890            A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd);
1891            ret = -EOPNOTSUPP;
1892            goto ioctl_done;
1893        } else if (ret == A_ERROR) {
1894            /* It is not our ioctl (out of range ioctl) */
1895            ret = -EOPNOTSUPP;
1896            goto ioctl_done;
1897        }
1898        userdata = (char *)rq->ifr_data;
1899    }
1900
1901    if ((ar->arWlanState == WLAN_DISABLED) &&
1902        ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) &&
1903         (cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) &&
1904         (cmd != AR6000_XIOCTL_DIAG_READ) &&
1905         (cmd != AR6000_XIOCTL_DIAG_WRITE) &&
1906         (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) &&
1907         (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) &&
1908         (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) &&
1909         (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) &&
1910         (cmd != AR6000_IOCTL_WMI_GETREV)))
1911    {
1912        ret = -EIO;
1913        goto ioctl_done;
1914    }
1915
1916    ret = 0;
1917    switch(cmd)
1918    {
1919        case IEEE80211_IOCTL_SETPARAM:
1920        {
1921            int param, value;
1922            int *ptr = (int *)rq->ifr_ifru.ifru_newname;
1923            if (ar->arWmiReady == FALSE) {
1924                ret = -EIO;
1925            } else {
1926                param = *ptr++;
1927                value = *ptr;
1928                ret = ar6000_ioctl_setparam(ar,param,value);
1929            }
1930            break;
1931        }
1932        case IEEE80211_IOCTL_SETKEY:
1933        {
1934            struct ieee80211req_key keydata;
1935            if (ar->arWmiReady == FALSE) {
1936                ret = -EIO;
1937            } else if (copy_from_user(&keydata, userdata,
1938                            sizeof(struct ieee80211req_key))) {
1939                ret = -EFAULT;
1940            } else {
1941                ar6000_ioctl_setkey(ar, &keydata);
1942            }
1943            break;
1944        }
1945        case IEEE80211_IOCTL_DELKEY:
1946        case IEEE80211_IOCTL_SETOPTIE:
1947        {
1948            //ret = -EIO;
1949            break;
1950        }
1951        case IEEE80211_IOCTL_SETMLME:
1952        {
1953            struct ieee80211req_mlme mlme;
1954            if (ar->arWmiReady == FALSE) {
1955                ret = -EIO;
1956            } else if (copy_from_user(&mlme, userdata,
1957                            sizeof(struct ieee80211req_mlme))) {
1958                ret = -EFAULT;
1959            } else {
1960                switch (mlme.im_op) {
1961                    case IEEE80211_MLME_AUTHORIZE:
1962                        A_PRINTF("setmlme AUTHORIZE %02X:%02X\n",
1963                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
1964                        break;
1965                    case IEEE80211_MLME_UNAUTHORIZE:
1966                        A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n",
1967                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
1968                        break;
1969                    case IEEE80211_MLME_DEAUTH:
1970                        A_PRINTF("setmlme DEAUTH %02X:%02X\n",
1971                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
1972                        //remove_sta(ar, mlme.im_macaddr);
1973                        break;
1974                    case IEEE80211_MLME_DISASSOC:
1975                        A_PRINTF("setmlme DISASSOC %02X:%02X\n",
1976                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
1977                        //remove_sta(ar, mlme.im_macaddr);
1978                        break;
1979                    default:
1980                        ret = 0;
1981                        goto ioctl_done;
1982                }
1983
1984                wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr,
1985                                mlme.im_reason);
1986            }
1987            break;
1988        }
1989        case IEEE80211_IOCTL_ADDPMKID:
1990        {
1991            struct ieee80211req_addpmkid  req;
1992            if (ar->arWmiReady == FALSE) {
1993                ret = -EIO;
1994            } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) {
1995                ret = -EFAULT;
1996            } else {
1997                A_STATUS status;
1998
1999                AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
2000                    req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2],
2001                    req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5],
2002                    req.pi_enable));
2003
2004                status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid,
2005                              req.pi_enable);
2006
2007                if (status != A_OK) {
2008                    ret = -EIO;
2009                    goto ioctl_done;
2010                }
2011            }
2012            break;
2013        }
2014#ifdef CONFIG_HOST_TCMD_SUPPORT
2015        case AR6000_XIOCTL_TCMD_CONT_TX:
2016            {
2017                TCMD_CONT_TX txCmd;
2018
2019                if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
2020                    (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
2021                {
2022                    A_PRINTF("Can NOT send tx tcmd when target is asleep! \n");
2023                    ret = -EFAULT;
2024                    goto ioctl_done;
2025                }
2026
2027                if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) {
2028                    ret = -EFAULT;
2029                    goto ioctl_done;
2030                } else {
2031                    wmi_test_cmd(ar->arWmi,(A_UINT8 *)&txCmd, sizeof(TCMD_CONT_TX));
2032                }
2033            }
2034            break;
2035        case AR6000_XIOCTL_TCMD_CONT_RX:
2036            {
2037                TCMD_CONT_RX rxCmd;
2038
2039                if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
2040                    (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
2041                {
2042                    A_PRINTF("Can NOT send rx tcmd when target is asleep! \n");
2043                    ret = -EFAULT;
2044                    goto ioctl_done;
2045                }
2046                if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) {
2047                    ret = -EFAULT;
2048                    goto ioctl_done;
2049                }
2050
2051                switch(rxCmd.act)
2052                {
2053                    case TCMD_CONT_RX_PROMIS:
2054                    case TCMD_CONT_RX_FILTER:
2055                    case TCMD_CONT_RX_SETMAC:
2056                    case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE:
2057                         wmi_test_cmd(ar->arWmi,(A_UINT8 *)&rxCmd,
2058                                                sizeof(TCMD_CONT_RX));
2059                         tcmdRxFreq = rxCmd.u.para.freq;
2060                         break;
2061                    case TCMD_CONT_RX_REPORT:
2062                         ar6000_ioctl_tcmd_get_rx_report(dev, rq,
2063                         (A_UINT8 *)&rxCmd, sizeof(TCMD_CONT_RX));
2064                         break;
2065                    default:
2066                         A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act);
2067                         ret = -EINVAL;
2068                         goto ioctl_done;
2069                }
2070            }
2071            break;
2072        case AR6000_XIOCTL_TCMD_PM:
2073            {
2074                TCMD_PM pmCmd;
2075
2076                if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) {
2077                    ret = -EFAULT;
2078                    goto ioctl_done;
2079                }
2080                ar->tcmdPm = pmCmd.mode;
2081                wmi_test_cmd(ar->arWmi, (A_UINT8*)&pmCmd, sizeof(TCMD_PM));
2082            }
2083            break;
2084#endif /* CONFIG_HOST_TCMD_SUPPORT */
2085
2086        case AR6000_XIOCTL_BMI_DONE:
2087            if(bmienable)
2088            {
2089                rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */
2090                ret = ar6000_init(dev);
2091                rtnl_unlock();
2092            }
2093            else
2094            {
2095                ret = BMIDone(hifDevice);
2096            }
2097            break;
2098
2099        case AR6000_XIOCTL_BMI_READ_MEMORY:
2100             if (get_user(address, (unsigned int *)userdata) ||
2101                get_user(length, (unsigned int *)userdata + 1)) {
2102                ret = -EFAULT;
2103                break;
2104            }
2105
2106            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n",
2107                             address, length));
2108            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2109                A_MEMZERO(buffer, length);
2110                ret = BMIReadMemory(hifDevice, address, buffer, length);
2111                if (copy_to_user(rq->ifr_data, buffer, length)) {
2112                    ret = -EFAULT;
2113                }
2114                A_FREE(buffer);
2115            } else {
2116                ret = -ENOMEM;
2117            }
2118            break;
2119
2120        case AR6000_XIOCTL_BMI_WRITE_MEMORY:
2121             if (get_user(address, (unsigned int *)userdata) ||
2122                get_user(length, (unsigned int *)userdata + 1)) {
2123                ret = -EFAULT;
2124                break;
2125            }
2126            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n",
2127                             address, length));
2128            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2129                A_MEMZERO(buffer, length);
2130                if (copy_from_user(buffer, &userdata[sizeof(address) +
2131                                   sizeof(length)], length))
2132                {
2133                    ret = -EFAULT;
2134                } else {
2135                    ret = BMIWriteMemory(hifDevice, address, buffer, length);
2136                }
2137                A_FREE(buffer);
2138            } else {
2139                ret = -ENOMEM;
2140            }
2141            break;
2142
2143        case AR6000_XIOCTL_BMI_TEST:
2144           AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n"));
2145           ret = -EOPNOTSUPP;
2146           break;
2147
2148        case AR6000_XIOCTL_BMI_EXECUTE:
2149             if (get_user(address, (unsigned int *)userdata) ||
2150                get_user(param, (unsigned int *)userdata + 1)) {
2151                ret = -EFAULT;
2152                break;
2153            }
2154            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n",
2155                             address, param));
2156            ret = BMIExecute(hifDevice, address, (A_UINT32*)&param);
2157            /* return value */
2158            if (put_user(param, (unsigned int *)rq->ifr_data)) {
2159                ret = -EFAULT;
2160                break;
2161            }
2162            break;
2163
2164        case AR6000_XIOCTL_BMI_SET_APP_START:
2165            if (get_user(address, (unsigned int *)userdata)) {
2166                ret = -EFAULT;
2167                break;
2168            }
2169            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address));
2170            ret = BMISetAppStart(hifDevice, address);
2171            break;
2172
2173        case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
2174            if (get_user(address, (unsigned int *)userdata)) {
2175                ret = -EFAULT;
2176                break;
2177            }
2178            ret = BMIReadSOCRegister(hifDevice, address, (A_UINT32*)&param);
2179            /* return value */
2180            if (put_user(param, (unsigned int *)rq->ifr_data)) {
2181                ret = -EFAULT;
2182                break;
2183            }
2184            break;
2185
2186        case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
2187            if (get_user(address, (unsigned int *)userdata) ||
2188                get_user(param, (unsigned int *)userdata + 1)) {
2189                ret = -EFAULT;
2190                break;
2191            }
2192            ret = BMIWriteSOCRegister(hifDevice, address, param);
2193            break;
2194
2195#ifdef HTC_RAW_INTERFACE
2196        case AR6000_XIOCTL_HTC_RAW_OPEN:
2197            ret = A_OK;
2198            if (!arRawIfEnabled(ar)) {
2199                /* make sure block size is set in case the target was reset since last
2200                  * BMI phase (i.e. flashup downloads) */
2201                ret = ar6000_set_htc_params(ar->arHifDevice,
2202                                            ar->arTargetType,
2203                                            0,  /* use default yield */
2204                                            0   /* use default number of HTC ctrl buffers */
2205                                            );
2206                if (A_FAILED(ret)) {
2207                    break;
2208                }
2209                /* Terminate the BMI phase */
2210                ret = BMIDone(hifDevice);
2211                if (ret == A_OK) {
2212                    ret = ar6000_htc_raw_open(ar);
2213                }
2214            }
2215            break;
2216
2217        case AR6000_XIOCTL_HTC_RAW_CLOSE:
2218            if (arRawIfEnabled(ar)) {
2219                ret = ar6000_htc_raw_close(ar);
2220                arRawIfEnabled(ar) = FALSE;
2221            } else {
2222                ret = A_ERROR;
2223            }
2224            break;
2225
2226        case AR6000_XIOCTL_HTC_RAW_READ:
2227            if (arRawIfEnabled(ar)) {
2228                unsigned int streamID;
2229                if (get_user(streamID, (unsigned int *)userdata) ||
2230                    get_user(length, (unsigned int *)userdata + 1)) {
2231                    ret = -EFAULT;
2232                    break;
2233                }
2234                buffer = (unsigned char*)rq->ifr_data + sizeof(length);
2235                ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID,
2236                                          (char*)buffer, length);
2237                if (put_user(ret, (unsigned int *)rq->ifr_data)) {
2238                    ret = -EFAULT;
2239                    break;
2240                }
2241            } else {
2242                ret = A_ERROR;
2243            }
2244            break;
2245
2246        case AR6000_XIOCTL_HTC_RAW_WRITE:
2247            if (arRawIfEnabled(ar)) {
2248                unsigned int streamID;
2249                if (get_user(streamID, (unsigned int *)userdata) ||
2250                    get_user(length, (unsigned int *)userdata + 1)) {
2251                    ret = -EFAULT;
2252                    break;
2253                }
2254                buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length);
2255                ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID,
2256                                           (char*)buffer, length);
2257                if (put_user(ret, (unsigned int *)rq->ifr_data)) {
2258                    ret = -EFAULT;
2259                    break;
2260                }
2261            } else {
2262                ret = A_ERROR;
2263            }
2264            break;
2265#endif /* HTC_RAW_INTERFACE */
2266
2267        case AR6000_XIOCTL_BMI_LZ_STREAM_START:
2268            if (get_user(address, (unsigned int *)userdata)) {
2269                ret = -EFAULT;
2270                break;
2271            }
2272            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address));
2273            ret = BMILZStreamStart(hifDevice, address);
2274            break;
2275
2276        case AR6000_XIOCTL_BMI_LZ_DATA:
2277            if (get_user(length, (unsigned int *)userdata)) {
2278                ret = -EFAULT;
2279                break;
2280            }
2281            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length));
2282            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2283                A_MEMZERO(buffer, length);
2284                if (copy_from_user(buffer, &userdata[sizeof(length)], length))
2285                {
2286                    ret = -EFAULT;
2287                } else {
2288                    ret = BMILZData(hifDevice, buffer, length);
2289                }
2290                A_FREE(buffer);
2291            } else {
2292                ret = -ENOMEM;
2293            }
2294            break;
2295
2296#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
2297        /*
2298         * Optional support for Target-side profiling.
2299         * Not needed in production.
2300         */
2301
2302        /* Configure Target-side profiling */
2303        case AR6000_XIOCTL_PROF_CFG:
2304        {
2305            A_UINT32 period;
2306            A_UINT32 nbins;
2307            if (get_user(period, (unsigned int *)userdata) ||
2308                get_user(nbins, (unsigned int *)userdata + 1)) {
2309                ret = -EFAULT;
2310                break;
2311            }
2312
2313            if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != A_OK) {
2314                ret = -EIO;
2315            }
2316
2317            break;
2318        }
2319
2320        /* Start a profiling bucket/bin at the specified address */
2321        case AR6000_XIOCTL_PROF_ADDR_SET:
2322        {
2323            A_UINT32 addr;
2324            if (get_user(addr, (unsigned int *)userdata)) {
2325                ret = -EFAULT;
2326                break;
2327            }
2328
2329            if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != A_OK) {
2330                ret = -EIO;
2331            }
2332
2333            break;
2334        }
2335
2336        /* START Target-side profiling */
2337        case AR6000_XIOCTL_PROF_START:
2338            wmi_prof_start_cmd(ar->arWmi);
2339            break;
2340
2341        /* STOP Target-side profiling */
2342        case AR6000_XIOCTL_PROF_STOP:
2343            wmi_prof_stop_cmd(ar->arWmi);
2344            break;
2345        case AR6000_XIOCTL_PROF_COUNT_GET:
2346        {
2347            if (ar->bIsDestroyProgress) {
2348                ret = -EBUSY;
2349                goto ioctl_done;
2350            }
2351            if (ar->arWmiReady == FALSE) {
2352                ret = -EIO;
2353                goto ioctl_done;
2354            }
2355            if (down_interruptible(&ar->arSem)) {
2356                ret = -ERESTARTSYS;
2357                goto ioctl_done;
2358            }
2359            if (ar->bIsDestroyProgress) {
2360                up(&ar->arSem);
2361                ret = -EBUSY;
2362                goto ioctl_done;
2363            }
2364
2365            prof_count_available = FALSE;
2366            ret = prof_count_get(dev);
2367            if (ret != A_OK) {
2368                up(&ar->arSem);
2369                ret = -EIO;
2370                goto ioctl_done;
2371            }
2372
2373            /* Wait for Target to respond. */
2374            wait_event_interruptible(arEvent, prof_count_available);
2375            if (signal_pending(current)) {
2376                ret = -EINTR;
2377            } else {
2378                if (copy_to_user(userdata, &prof_count_results,
2379                                 sizeof(prof_count_results)))
2380                {
2381                    ret = -EFAULT;
2382                }
2383            }
2384            up(&ar->arSem);
2385            break;
2386        }
2387#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
2388
2389        case AR6000_IOCTL_WMI_GETREV:
2390        {
2391            if (copy_to_user(rq->ifr_data, &ar->arVersion,
2392                             sizeof(ar->arVersion)))
2393            {
2394                ret = -EFAULT;
2395            }
2396            break;
2397        }
2398        case AR6000_IOCTL_WMI_SETPWR:
2399        {
2400            WMI_POWER_MODE_CMD pwrModeCmd;
2401
2402            if (ar->arWmiReady == FALSE) {
2403                ret = -EIO;
2404            } else if (copy_from_user(&pwrModeCmd, userdata,
2405                                   sizeof(pwrModeCmd)))
2406            {
2407                ret = -EFAULT;
2408            } else {
2409                if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
2410                       != A_OK)
2411                {
2412                    ret = -EIO;
2413                }
2414            }
2415            break;
2416        }
2417        case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
2418        {
2419            WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
2420
2421            if (ar->arWmiReady == FALSE) {
2422                ret = -EIO;
2423            } else if (copy_from_user(&ibssPmCaps, userdata,
2424                                   sizeof(ibssPmCaps)))
2425            {
2426                ret = -EFAULT;
2427            } else {
2428                if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl,
2429                    ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK)
2430                {
2431                    ret = -EIO;
2432                }
2433                AR6000_SPIN_LOCK(&ar->arLock, 0);
2434                ar->arIbssPsEnable = ibssPmCaps.power_saving;
2435                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2436            }
2437            break;
2438        }
2439        case AR6000_XIOCTL_WMI_SET_AP_PS:
2440        {
2441            WMI_AP_PS_CMD apPsCmd;
2442
2443            if (ar->arWmiReady == FALSE) {
2444                ret = -EIO;
2445            } else if (copy_from_user(&apPsCmd, userdata,
2446                                   sizeof(apPsCmd)))
2447            {
2448                ret = -EFAULT;
2449            } else {
2450                if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time,
2451                    apPsCmd.ps_period, apPsCmd.sleep_period) != A_OK)
2452                {
2453                    ret = -EIO;
2454                }
2455            }
2456            break;
2457        }
2458        case AR6000_IOCTL_WMI_SET_PMPARAMS:
2459        {
2460            WMI_POWER_PARAMS_CMD pmParams;
2461
2462            if (ar->arWmiReady == FALSE) {
2463                ret = -EIO;
2464            } else if (copy_from_user(&pmParams, userdata,
2465                                      sizeof(pmParams)))
2466            {
2467                ret = -EFAULT;
2468            } else {
2469                if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
2470                                     pmParams.pspoll_number,
2471                                     pmParams.dtim_policy,
2472                                     pmParams.tx_wakeup_policy,
2473                                     pmParams.num_tx_to_wakeup,
2474#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
2475                                     IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 
2476#else
2477                                     SEND_POWER_SAVE_FAIL_EVENT_ALWAYS
2478#endif
2479                                     ) != A_OK)
2480                {
2481                    ret = -EIO;
2482                }
2483            }
2484            break;
2485        }
2486        case AR6000_IOCTL_WMI_SETSCAN:
2487        {
2488            if (ar->arWmiReady == FALSE) {
2489                ret = -EIO;
2490            } else if (copy_from_user(&ar->scParams, userdata,
2491                                      sizeof(ar->scParams)))
2492            {
2493                ret = -EFAULT;
2494            } else {
2495                if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) {
2496                    ar->arSkipScan = FALSE;
2497                } else {
2498                    ar->arSkipScan = TRUE;
2499                }
2500
2501                if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period,
2502                                       ar->scParams.fg_end_period,
2503                                       ar->scParams.bg_period,
2504                                       ar->scParams.minact_chdwell_time,
2505                                       ar->scParams.maxact_chdwell_time,
2506                                       ar->scParams.pas_chdwell_time,
2507                                       ar->scParams.shortScanRatio,
2508                                       ar->scParams.scanCtrlFlags,
2509                                       ar->scParams.max_dfsch_act_time,
2510                                       ar->scParams.maxact_scan_per_ssid) != A_OK)
2511                {
2512                    ret = -EIO;
2513                }
2514            }
2515            break;
2516        }
2517        case AR6000_IOCTL_WMI_SETLISTENINT:
2518        {
2519            WMI_LISTEN_INT_CMD listenCmd;
2520
2521            if (ar->arWmiReady == FALSE) {
2522                ret = -EIO;
2523            } else if (copy_from_user(&listenCmd, userdata,
2524                                      sizeof(listenCmd)))
2525            {
2526                ret = -EFAULT;
2527            } else {
2528                    if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) {
2529                        ret = -EIO;
2530                    } else {
2531                        AR6000_SPIN_LOCK(&ar->arLock, 0);
2532                        ar->arListenIntervalT = listenCmd.listenInterval;
2533                        ar->arListenIntervalB = listenCmd.numBeacons;
2534                        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2535                    }
2536
2537                }
2538            break;
2539        }
2540        case AR6000_IOCTL_WMI_SET_BMISS_TIME:
2541        {
2542            WMI_BMISS_TIME_CMD bmissCmd;
2543
2544            if (ar->arWmiReady == FALSE) {
2545                ret = -EIO;
2546            } else if (copy_from_user(&bmissCmd, userdata,
2547                                      sizeof(bmissCmd)))
2548            {
2549                ret = -EFAULT;
2550            } else {
2551                if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) {
2552                    ret = -EIO;
2553                }
2554            }
2555            break;
2556        }
2557        case AR6000_IOCTL_WMI_SETBSSFILTER:
2558        {
2559            WMI_BSS_FILTER_CMD filt;
2560
2561            if (ar->arWmiReady == FALSE) {
2562                ret = -EIO;
2563            } else if (copy_from_user(&filt, userdata,
2564                                   sizeof(filt)))
2565            {
2566                ret = -EFAULT;
2567            } else {
2568                if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask)
2569                        != A_OK) {
2570                    ret = -EIO;
2571                } else {
2572                    ar->arUserBssFilter = param;
2573                }
2574            }
2575            break;
2576        }
2577
2578        case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD:
2579        {
2580            ret = ar6000_ioctl_set_snr_threshold(dev, rq);
2581            break;
2582        }
2583        case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD:
2584        {
2585            ret = ar6000_ioctl_set_rssi_threshold(dev, rq);
2586            break;
2587        }
2588        case AR6000_XIOCTL_WMI_CLR_RSSISNR:
2589        {
2590            if (ar->arWmiReady == FALSE) {
2591                ret = -EIO;
2592            }
2593            ret = wmi_clr_rssi_snr(ar->arWmi);
2594            break;
2595        }
2596        case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD:
2597        {
2598            ret = ar6000_ioctl_set_lq_threshold(dev, rq);
2599            break;
2600        }
2601        case AR6000_XIOCTL_WMI_SET_LPREAMBLE:
2602        {
2603            WMI_SET_LPREAMBLE_CMD setLpreambleCmd;
2604
2605            if (ar->arWmiReady == FALSE) {
2606                ret = -EIO;
2607            } else if (copy_from_user(&setLpreambleCmd, userdata,
2608                                   sizeof(setLpreambleCmd)))
2609            {
2610                ret = -EFAULT;
2611            } else {
2612                if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status,
2613#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 
2614                           WMI_DONOT_IGNORE_BARKER_IN_ERP
2615#else
2616                           WMI_IGNORE_BARKER_IN_ERP
2617#endif
2618                ) != A_OK)
2619                {
2620                    ret = -EIO;
2621                }
2622            }
2623
2624            break;
2625        }
2626        case AR6000_XIOCTL_WMI_SET_RTS:
2627        {
2628            WMI_SET_RTS_CMD rtsCmd;
2629            if (ar->arWmiReady == FALSE) {
2630                ret = -EIO;
2631            } else if (copy_from_user(&rtsCmd, userdata,
2632                                   sizeof(rtsCmd)))
2633            {
2634                ret = -EFAULT;
2635            } else {
2636                ar->arRTS = rtsCmd.threshold;
2637                if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold)
2638                       != A_OK)
2639                {
2640                    ret = -EIO;
2641                }
2642            }
2643
2644            break;
2645        }
2646        case AR6000_XIOCTL_WMI_SET_WMM:
2647        {
2648            ret = ar6000_ioctl_set_wmm(dev, rq);
2649            break;
2650        }
2651       case AR6000_XIOCTL_WMI_SET_QOS_SUPP:
2652        {
2653            ret = ar6000_ioctl_set_qos_supp(dev, rq);
2654            break;
2655        }
2656        case AR6000_XIOCTL_WMI_SET_TXOP:
2657        {
2658            ret = ar6000_ioctl_set_txop(dev, rq);
2659            break;
2660        }
2661        case AR6000_XIOCTL_WMI_GET_RD:
2662        {
2663            ret = ar6000_ioctl_get_rd(dev, rq);
2664            break;
2665        }
2666        case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
2667        {
2668            ret = ar6000_ioctl_set_channelParams(dev, rq);
2669            break;
2670        }
2671        case AR6000_IOCTL_WMI_SET_PROBEDSSID:
2672        {
2673            ret = ar6000_ioctl_set_probedSsid(dev, rq);
2674            break;
2675        }
2676        case AR6000_IOCTL_WMI_SET_BADAP:
2677        {
2678            ret = ar6000_ioctl_set_badAp(dev, rq);
2679            break;
2680        }
2681        case AR6000_IOCTL_WMI_CREATE_QOS:
2682        {
2683            ret = ar6000_ioctl_create_qos(dev, rq);
2684            break;
2685        }
2686        case AR6000_IOCTL_WMI_DELETE_QOS:
2687        {
2688            ret = ar6000_ioctl_delete_qos(dev, rq);
2689            break;
2690        }
2691        case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
2692        {
2693            ret = ar6000_ioctl_get_qos_queue(dev, rq);
2694            break;
2695        }
2696        case AR6000_IOCTL_WMI_GET_TARGET_STATS:
2697        {
2698            ret = ar6000_ioctl_get_target_stats(dev, rq);
2699            break;
2700        }
2701        case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
2702        {
2703            ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
2704            break;
2705        }
2706        case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
2707        {
2708            WMI_SET_ASSOC_INFO_CMD cmd;
2709            A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
2710
2711            if (ar->arWmiReady == FALSE) {
2712                ret = -EIO;
2713                break;
2714            }
2715
2716            if (get_user(cmd.ieType, userdata)) {
2717                ret = -EFAULT;
2718                break;
2719            }
2720            if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
2721                ret = -EIO;
2722                break;
2723            }
2724
2725            if (get_user(cmd.bufferSize, userdata + 1) ||
2726                (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) ||
2727                copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) {
2728                ret = -EFAULT;
2729                break;
2730            }
2731            if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
2732                                  cmd.bufferSize, assocInfo) != A_OK) {
2733                ret = -EIO;
2734                break;
2735            }
2736            break;
2737        }
2738        case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
2739        {
2740            ret = ar6000_ioctl_set_access_params(dev, rq);
2741            break;
2742        }
2743        case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
2744        {
2745            ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
2746            break;
2747        }
2748        case AR6000_XIOCTL_FORCE_TARGET_RESET:
2749        {
2750            if (ar->arHtcTarget)
2751            {
2752//                HTCForceReset(htcTarget);
2753            }
2754            else
2755            {
2756                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt reset.\n"));
2757            }
2758            break;
2759        }
2760        case AR6000_XIOCTL_TARGET_INFO:
2761        case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */
2762        {
2763            /* If we made it to here, then the Target exists and is ready. */
2764
2765            if (cmd == AR6000_XIOCTL_TARGET_INFO) {
2766                if (copy_to_user((A_UINT32 *)rq->ifr_data, &ar->arVersion.target_ver,
2767                                 sizeof(ar->arVersion.target_ver)))
2768                {
2769                    ret = -EFAULT;
2770                }
2771                if (copy_to_user(((A_UINT32 *)rq->ifr_data)+1, &ar->arTargetType,
2772                                 sizeof(ar->arTargetType)))
2773                {
2774                    ret = -EFAULT;
2775                }
2776            }
2777            break;
2778        }
2779        case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS:
2780        {
2781            WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam;
2782
2783            if (copy_from_user(&hbparam, userdata, sizeof(hbparam)))
2784            {
2785                ret = -EFAULT;
2786            } else {
2787                AR6000_SPIN_LOCK(&ar->arLock, 0);
2788                /* Start a cyclic timer with the parameters provided. */
2789                if (hbparam.frequency) {
2790                    ar->arHBChallengeResp.frequency = hbparam.frequency;
2791                }
2792                if (hbparam.threshold) {
2793                    ar->arHBChallengeResp.missThres = hbparam.threshold;
2794                }
2795
2796                /* Delete the pending timer and start a new one */
2797                if (timer_pending(&ar->arHBChallengeResp.timer)) {
2798                    A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
2799                }
2800                A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2801                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2802            }
2803            break;
2804        }
2805        case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP:
2806        {
2807            A_UINT32 cookie;
2808
2809            if (copy_from_user(&cookie, userdata, sizeof(cookie))) {
2810                ret = -EFAULT;
2811                goto ioctl_done;
2812            }
2813
2814            /* Send the challenge on the control channel */
2815            if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != A_OK) {
2816                ret = -EIO;
2817                goto ioctl_done;
2818            }
2819            break;
2820        }
2821#ifdef USER_KEYS
2822        case AR6000_XIOCTL_USER_SETKEYS:
2823        {
2824
2825            ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN;
2826
2827            if (copy_from_user(&ar->user_key_ctrl, userdata,
2828                               sizeof(ar->user_key_ctrl)))
2829            {
2830                ret = -EFAULT;
2831                goto ioctl_done;
2832            }
2833
2834            A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl);
2835            break;
2836        }
2837#endif /* USER_KEYS */
2838
2839#ifdef CONFIG_HOST_GPIO_SUPPORT
2840        case AR6000_XIOCTL_GPIO_OUTPUT_SET:
2841        {
2842            struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
2843
2844            if (ar->bIsDestroyProgress) {
2845                ret = -EBUSY;
2846                goto ioctl_done;
2847            }
2848            if (ar->arWmiReady == FALSE) {
2849                ret = -EIO;
2850                goto ioctl_done;
2851            }
2852            if (down_interruptible(&ar->arSem)) {
2853                ret = -ERESTARTSYS;
2854                goto ioctl_done;
2855            }
2856            if (ar->bIsDestroyProgress) {
2857                up(&ar->arSem);
2858                ret = -EBUSY;
2859                goto ioctl_done;
2860            }
2861
2862            if (copy_from_user(&gpio_output_set_cmd, userdata,
2863                                sizeof(gpio_output_set_cmd)))
2864            {
2865                ret = -EFAULT;
2866            } else {
2867                ret = ar6000_gpio_output_set(dev,
2868                                             gpio_output_set_cmd.set_mask,
2869                                             gpio_output_set_cmd.clear_mask,
2870                                             gpio_output_set_cmd.enable_mask,
2871                                             gpio_output_set_cmd.disable_mask);
2872                if (ret != A_OK) {
2873                    ret = EIO;
2874                }
2875            }
2876            up(&ar->arSem);
2877            break;
2878        }
2879        case AR6000_XIOCTL_GPIO_INPUT_GET:
2880        {
2881            if (ar->bIsDestroyProgress) {
2882                ret = -EBUSY;
2883                goto ioctl_done;
2884            }
2885            if (ar->arWmiReady == FALSE) {
2886                ret = -EIO;
2887                goto ioctl_done;
2888            }
2889            if (down_interruptible(&ar->arSem)) {
2890                ret = -ERESTARTSYS;
2891                goto ioctl_done;
2892            }
2893            if (ar->bIsDestroyProgress) {
2894                up(&ar->arSem);
2895                ret = -EBUSY;
2896                goto ioctl_done;
2897            }
2898
2899            ret = ar6000_gpio_input_get(dev);
2900            if (ret != A_OK) {
2901                up(&ar->arSem);
2902                ret = -EIO;
2903                goto ioctl_done;
2904            }
2905
2906            /* Wait for Target to respond. */
2907            wait_event_interruptible(arEvent, gpio_data_available);
2908            if (signal_pending(current)) {
2909                ret = -EINTR;
2910            } else {
2911                A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
2912
2913                if (copy_to_user(userdata, &gpio_reg_results.value,
2914                                 sizeof(gpio_reg_results.value)))
2915                {
2916                    ret = -EFAULT;
2917                }
2918            }
2919            up(&ar->arSem);
2920            break;
2921        }
2922        case AR6000_XIOCTL_GPIO_REGISTER_SET:
2923        {
2924            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2925
2926            if (ar->bIsDestroyProgress) {
2927                ret = -EBUSY;
2928                goto ioctl_done;
2929            }
2930            if (ar->arWmiReady == FALSE) {
2931                ret = -EIO;
2932                goto ioctl_done;
2933            }
2934            if (down_interruptible(&ar->arSem)) {
2935                ret = -ERESTARTSYS;
2936                goto ioctl_done;
2937            }
2938            if (ar->bIsDestroyProgress) {
2939                up(&ar->arSem);
2940                ret = -EBUSY;
2941                goto ioctl_done;
2942            }
2943
2944            if (copy_from_user(&gpio_register_cmd, userdata,
2945                                sizeof(gpio_register_cmd)))
2946            {
2947                ret = -EFAULT;
2948            } else {
2949                ret = ar6000_gpio_register_set(dev,
2950                                               gpio_register_cmd.gpioreg_id,
2951                                               gpio_register_cmd.value);
2952                if (ret != A_OK) {
2953                    ret = EIO;
2954                }
2955
2956                /* Wait for acknowledgement from Target */
2957                wait_event_interruptible(arEvent, gpio_ack_received);
2958                if (signal_pending(current)) {
2959                    ret = -EINTR;
2960                }
2961            }
2962            up(&ar->arSem);
2963            break;
2964        }
2965        case AR6000_XIOCTL_GPIO_REGISTER_GET:
2966        {
2967            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2968
2969            if (ar->bIsDestroyProgress) {
2970                ret = -EBUSY;
2971                goto ioctl_done;
2972            }
2973            if (ar->arWmiReady == FALSE) {
2974                ret = -EIO;
2975                goto ioctl_done;
2976            }
2977            if (down_interruptible(&ar->arSem)) {
2978                ret = -ERESTARTSYS;
2979                goto ioctl_done;
2980            }
2981            if (ar->bIsDestroyProgress) {
2982                up(&ar->arSem);
2983                ret = -EBUSY;
2984                goto ioctl_done;
2985            }
2986
2987            if (copy_from_user(&gpio_register_cmd, userdata,
2988                                sizeof(gpio_register_cmd)))
2989            {
2990                ret = -EFAULT;
2991            } else {
2992                ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id);
2993                if (ret != A_OK) {
2994                    up(&ar->arSem);
2995                    ret = -EIO;
2996                    goto ioctl_done;
2997                }
2998
2999                /* Wait for Target to respond. */
3000                wait_event_interruptible(arEvent, gpio_data_available);
3001                if (signal_pending(current)) {
3002                    ret = -EINTR;
3003                } else {
3004                    A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id);
3005                    if (copy_to_user(userdata, &gpio_reg_results,
3006                                     sizeof(gpio_reg_results)))
3007                    {
3008                        ret = -EFAULT;
3009                    }
3010                }
3011            }
3012            up(&ar->arSem);
3013            break;
3014        }
3015        case AR6000_XIOCTL_GPIO_INTR_ACK:
3016        {
3017            struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
3018
3019            if (ar->bIsDestroyProgress) {
3020                ret = -EBUSY;
3021                goto ioctl_done;
3022            }
3023            if (ar->arWmiReady == FALSE) {
3024                ret = -EIO;
3025                goto ioctl_done;
3026            }
3027            if (down_interruptible(&ar->arSem)) {
3028                ret = -ERESTARTSYS;
3029                goto ioctl_done;
3030            }
3031            if (ar->bIsDestroyProgress) {
3032                up(&ar->arSem);
3033                ret = -EBUSY;
3034                goto ioctl_done;
3035            }
3036
3037            if (copy_from_user(&gpio_intr_ack_cmd, userdata,
3038                                sizeof(gpio_intr_ack_cmd)))
3039            {
3040                ret = -EFAULT;
3041            } else {
3042                ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
3043                if (ret != A_OK) {
3044                    ret = EIO;
3045                }
3046            }
3047            up(&ar->arSem);
3048            break;
3049        }
3050        case AR6000_XIOCTL_GPIO_INTR_WAIT:
3051        {
3052            /* Wait for Target to report an interrupt. */
3053            wait_event_interruptible(arEvent, gpio_intr_available);
3054
3055            if (signal_pending(current)) {
3056                ret = -EINTR;
3057            } else {
3058                if (copy_to_user(userdata, &gpio_intr_results,
3059                                 sizeof(gpio_intr_results)))
3060                {
3061                    ret = -EFAULT;
3062                }
3063            }
3064            break;
3065        }
3066#endif /* CONFIG_HOST_GPIO_SUPPORT */
3067
3068        case AR6000_XIOCTL_DBGLOG_CFG_MODULE:
3069        {
3070            struct ar6000_dbglog_module_config_s config;
3071
3072            if (copy_from_user(&config, userdata, sizeof(config))) {
3073                ret = -EFAULT;
3074                goto ioctl_done;
3075            }
3076
3077            /* Send the challenge on the control channel */
3078            if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask,
3079                                            config.tsr, config.rep,
3080                                            config.size, config.valid) != A_OK)
3081            {
3082                ret = -EIO;
3083                goto ioctl_done;
3084            }
3085            break;
3086        }
3087
3088        case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS:
3089        {
3090            /* Send the challenge on the control channel */
3091            if (ar6000_dbglog_get_debug_logs(ar) != A_OK)
3092            {
3093                ret = -EIO;
3094                goto ioctl_done;
3095            }
3096            break;
3097        }
3098
3099        case AR6000_XIOCTL_SET_ADHOC_BSSID:
3100        {
3101            WMI_SET_ADHOC_BSSID_CMD adhocBssid;
3102
3103            if (ar->arWmiReady == FALSE) {
3104                ret = -EIO;
3105            } else if (copy_from_user(&adhocBssid, userdata,
3106                                      sizeof(adhocBssid)))
3107            {
3108                ret = -EFAULT;
3109            } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac,
3110                                AR6000_ETH_ADDR_LEN) == 0)
3111            {
3112                ret = -EFAULT;
3113            } else {
3114
3115                A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid));
3116        }
3117            break;
3118        }
3119
3120        case AR6000_XIOCTL_SET_OPT_MODE:
3121        {
3122        WMI_SET_OPT_MODE_CMD optModeCmd;
3123            AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3124
3125            if (ar->arWmiReady == FALSE) {
3126                ret = -EIO;
3127            } else if (copy_from_user(&optModeCmd, userdata,
3128                                      sizeof(optModeCmd)))
3129            {
3130                ret = -EFAULT;
3131            } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
3132                ret = -EFAULT;
3133
3134            } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
3135                       != A_OK)
3136            {
3137                ret = -EIO;
3138            }
3139            break;
3140        }
3141
3142        case AR6000_XIOCTL_OPT_SEND_FRAME:
3143        {
3144        WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
3145            A_UINT8 data[MAX_OPT_DATA_LEN];
3146
3147            if (ar->arWmiReady == FALSE) {
3148                ret = -EIO;
3149            } else if (copy_from_user(&optTxFrmCmd, userdata,
3150                                      sizeof(optTxFrmCmd)))
3151            {
3152                ret = -EFAULT;
3153            } else if (copy_from_user(data,
3154                                      userdata+sizeof(WMI_OPT_TX_FRAME_CMD)-1,
3155                                      optTxFrmCmd.optIEDataLen))
3156            {
3157                ret = -EFAULT;
3158            } else {
3159                ret = wmi_opt_tx_frame_cmd(ar->arWmi,
3160                                           optTxFrmCmd.frmType,
3161                                           optTxFrmCmd.dstAddr,
3162                                           optTxFrmCmd.bssid,
3163                                           optTxFrmCmd.optIEDataLen,
3164                                           data);
3165            }
3166
3167            break;
3168        }
3169        case AR6000_XIOCTL_WMI_SETRETRYLIMITS:
3170        {
3171            WMI_SET_RETRY_LIMITS_CMD setRetryParams;
3172
3173            if (ar->arWmiReady == FALSE) {
3174                ret = -EIO;
3175            } else if (copy_from_user(&setRetryParams, userdata,
3176                                      sizeof(setRetryParams)))
3177            {
3178                ret = -EFAULT;
3179            } else {
3180                if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType,
3181                                          setRetryParams.trafficClass,
3182                                          setRetryParams.maxRetries,
3183                                          setRetryParams.enableNotify) != A_OK)
3184                {
3185                    ret = -EIO;
3186                }
3187                AR6000_SPIN_LOCK(&ar->arLock, 0);
3188                ar->arMaxRetries = setRetryParams.maxRetries;
3189                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3190            }
3191            break;
3192        }
3193
3194        case AR6000_XIOCTL_SET_BEACON_INTVAL:
3195        {
3196            WMI_BEACON_INT_CMD bIntvlCmd;
3197
3198            if (ar->arWmiReady == FALSE) {
3199                ret = -EIO;
3200            } else if (copy_from_user(&bIntvlCmd, userdata,
3201                       sizeof(bIntvlCmd)))
3202            {
3203                ret = -EFAULT;
3204            } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval)
3205                        != A_OK)
3206            {
3207                ret = -EIO;
3208            }
3209            if(ret == 0) {
3210                ar->ap_beacon_interval = bIntvlCmd.beaconInterval;
3211                ar->ap_profile_flag = 1; /* There is a change in profile */
3212            }
3213            break;
3214        }
3215        case IEEE80211_IOCTL_SETAUTHALG:
3216        {
3217            AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3218            struct ieee80211req_authalg req;
3219
3220            if (ar->arWmiReady == FALSE) {
3221                ret = -EIO;
3222            } else if (copy_from_user(&req, userdata,
3223                       sizeof(struct ieee80211req_authalg)))
3224            {
3225                ret = -EFAULT;
3226            } else {
3227                if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) {
3228                    ar->arDot11AuthMode  |= OPEN_AUTH;
3229                    ar->arPairwiseCrypto  = NONE_CRYPT;
3230                    ar->arGroupCrypto     = NONE_CRYPT;
3231                }
3232                if (req.auth_alg & AUTH_ALG_SHARED_KEY) {
3233                    ar->arDot11AuthMode  |= SHARED_AUTH;
3234                    ar->arPairwiseCrypto  = WEP_CRYPT;
3235                    ar->arGroupCrypto     = WEP_CRYPT;
3236                    ar->arAuthMode        = NONE_AUTH;
3237                }
3238                if (req.auth_alg == AUTH_ALG_LEAP) {
3239                    ar->arDot11AuthMode   = LEAP_AUTH;
3240                }
3241            }
3242            break;
3243        }
3244
3245        case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
3246            ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
3247            break;
3248
3249        case AR6000_XIOCTL_SET_MAX_SP:
3250            ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
3251            break;
3252
3253        case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
3254            ret = ar6000_ioctl_get_roam_tbl(dev, rq);
3255            break;
3256        case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
3257            ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
3258            break;
3259        case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
3260            ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
3261            break;
3262        case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
3263            ret = ar6000_ioctl_get_power_mode(dev, rq);
3264            break;
3265        case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
3266        {
3267            AR6000_WLAN_STATE state;
3268            if (get_user(state, (unsigned int *)userdata))
3269                ret = -EFAULT;
3270            else if (ar6000_set_wlan_state(ar, state) != A_OK)
3271                ret = -EIO;
3272            break;
3273        }
3274        case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
3275            ret = ar6000_ioctl_get_roam_data(dev, rq);
3276            break;
3277
3278        case AR6000_XIOCTL_WMI_SET_BT_STATUS:
3279            ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata);
3280            break;
3281
3282        case AR6000_XIOCTL_WMI_SET_BT_PARAMS:
3283            ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata);
3284            break;
3285
3286                case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT:
3287                        ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata);
3288                        break;
3289
3290                case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV:
3291                        ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata);
3292                        break;
3293
3294                case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG:
3295                        ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(dev, userdata);
3296                        break;
3297
3298                case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG:
3299                        ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, userdata);
3300                        break;
3301
3302                case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG:
3303                        ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, userdata);
3304                        break;
3305
3306                case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG:
3307                        ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, userdata);
3308                        break;
3309
3310                case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG:
3311                        ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata);
3312                        break;
3313
3314                case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS:
3315                        ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(dev, userdata);
3316                        break;
3317
3318                case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG:
3319                        ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq);
3320                        break;
3321
3322                case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS:
3323                        ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq);
3324                        break;
3325
3326        case AR6000_XIOCTL_WMI_STARTSCAN:
3327        {
3328            WMI_START_SCAN_CMD setStartScanCmd, *cmdp;
3329
3330            if (ar->arWmiReady == FALSE) {
3331                    ret = -EIO;
3332                } else if (copy_from_user(&setStartScanCmd, userdata,
3333                                          sizeof(setStartScanCmd)))
3334                {
3335                    ret = -EFAULT;
3336                } else {
3337                    if (setStartScanCmd.numChannels > 1) {
3338                        cmdp = A_MALLOC(130);
3339                        if (copy_from_user(cmdp, userdata,
3340                                           sizeof (*cmdp) +
3341                                           ((setStartScanCmd.numChannels - 1) *
3342                                           sizeof(A_UINT16))))
3343                        {
3344                            kfree(cmdp);
3345                            ret = -EFAULT;
3346                            goto ioctl_done;
3347                        }
3348                    } else {
3349                        cmdp = &setStartScanCmd;
3350                    }
3351
3352                    if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType,
3353                                          cmdp->forceFgScan,
3354                                          cmdp->isLegacy,
3355                                          cmdp->homeDwellTime,
3356                                          cmdp->forceScanInterval,
3357                                          cmdp->numChannels,
3358                                          cmdp->channelList) != A_OK)
3359                    {
3360                        ret = -EIO;
3361                    }
3362                }
3363            break;
3364        }
3365        case AR6000_XIOCTL_WMI_SETFIXRATES:
3366        {
3367            WMI_FIX_RATES_CMD setFixRatesCmd;
3368            A_STATUS returnStatus;
3369
3370            if (ar->arWmiReady == FALSE) {
3371                    ret = -EIO;
3372                } else if (copy_from_user(&setFixRatesCmd, userdata,
3373                                          sizeof(setFixRatesCmd)))
3374                {
3375                    ret = -EFAULT;
3376                } else {
3377                    returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask);
3378                    if (returnStatus == A_EINVAL) {
3379                        ret = -EINVAL;
3380                    } else if(returnStatus != A_OK) {
3381                        ret = -EIO;
3382                    } else {
3383                        ar->ap_profile_flag = 1; /* There is a change in profile */
3384                    }
3385                }
3386            break;
3387        }
3388
3389        case AR6000_XIOCTL_WMI_GETFIXRATES:
3390        {
3391            WMI_FIX_RATES_CMD getFixRatesCmd;
3392            AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3393            int ret = 0;
3394
3395            if (ar->bIsDestroyProgress) {
3396                ret = -EBUSY;
3397                goto ioctl_done;
3398            }
3399            if (ar->arWmiReady == FALSE) {
3400                ret = -EIO;
3401                goto ioctl_done;
3402            }
3403
3404            if (down_interruptible(&ar->arSem)) {
3405                ret = -ERESTARTSYS;
3406                goto ioctl_done;
3407            }
3408            if (ar->bIsDestroyProgress) {
3409                up(&ar->arSem);
3410                ret = -EBUSY;
3411                goto ioctl_done;
3412            }
3413            /* Used copy_from_user/copy_to_user to access user space data */
3414            if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) {
3415                ret = -EFAULT;
3416            } else {
3417                ar->arRateMask = 0xFFFFFFFF;
3418
3419                if (wmi_get_ratemask_cmd(ar->arWmi) != A_OK) {
3420                    up(&ar->arSem);
3421                    ret = -EIO;
3422                    goto ioctl_done;
3423                }
3424
3425                wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFFFFFF, wmitimeout * HZ);
3426
3427                if (signal_pending(current)) {
3428                    ret = -EINTR;
3429                }
3430
3431                if (!ret) {
3432                    getFixRatesCmd.fixRateMask = ar->arRateMask;
3433                }
3434
3435                if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) {
3436                   ret = -EFAULT;
3437                }
3438
3439                up(&ar->arSem);
3440            }
3441            break;
3442        }
3443        case AR6000_XIOCTL_WMI_SET_AUTHMODE:
3444        {
3445            WMI_SET_AUTH_MODE_CMD setAuthMode;
3446
3447            if (ar->arWmiReady == FALSE) {
3448                ret = -EIO;
3449            } else if (copy_from_user(&setAuthMode, userdata,
3450                                      sizeof(setAuthMode)))
3451            {
3452                ret = -EFAULT;
3453            } else {
3454                if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != A_OK)
3455                {
3456                    ret = -EIO;
3457                }
3458            }
3459            break;
3460        }
3461        case AR6000_XIOCTL_WMI_SET_REASSOCMODE:
3462        {
3463            WMI_SET_REASSOC_MODE_CMD setReassocMode;
3464
3465            if (ar->arWmiReady == FALSE) {
3466                ret = -EIO;
3467            } else if (copy_from_user(&setReassocMode, userdata,
3468                                      sizeof(setReassocMode)))
3469            {
3470                ret = -EFAULT;
3471            } else {
3472                if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != A_OK)
3473                {
3474                    ret = -EIO;
3475                }
3476            }
3477            break;
3478        }
3479        case AR6000_XIOCTL_DIAG_READ:
3480        {
3481            A_UINT32 addr, data;
3482            if (get_user(addr, (unsigned int *)userdata)) {
3483                ret = -EFAULT;
3484                break;
3485            }
3486            addr = TARG_VTOP(ar->arTargetType, addr);
3487            if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
3488                ret = -EIO;
3489            }
3490            if (put_user(data, (unsigned int *)userdata + 1)) {
3491                ret = -EFAULT;
3492                break;
3493            }
3494            break;
3495        }
3496        case AR6000_XIOCTL_DIAG_WRITE:
3497        {
3498            A_UINT32 addr, data;
3499            if (get_user(addr, (unsigned int *)userdata) ||
3500                get_user(data, (unsigned int *)userdata + 1)) {
3501                ret = -EFAULT;
3502                break;
3503            }
3504            addr = TARG_VTOP(ar->arTargetType, addr);
3505            if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
3506                ret = -EIO;
3507            }
3508            break;
3509        }
3510        case AR6000_XIOCTL_WMI_SET_KEEPALIVE:
3511        {
3512             WMI_SET_KEEPALIVE_CMD setKeepAlive;
3513             if (ar->arWmiReady == FALSE) {
3514                 ret = -EIO;
3515                 goto ioctl_done;
3516             } else if (copy_from_user(&setKeepAlive, userdata,
3517                        sizeof(setKeepAlive))){
3518                 ret = -EFAULT;
3519             } else {
3520                 if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != A_OK) {
3521                     ret = -EIO;
3522               }
3523             }
3524             break;
3525        }
3526        case AR6000_XIOCTL_WMI_SET_PARAMS:
3527        {
3528             WMI_SET_PARAMS_CMD cmd;
3529             if (ar->arWmiReady == FALSE) {
3530                 ret = -EIO;
3531                 goto ioctl_done;
3532             } else if (copy_from_user(&cmd, userdata,
3533                        sizeof(cmd))){
3534                 ret = -EFAULT;
3535             } else if (copy_from_user(&cmd, userdata,
3536                        sizeof(cmd) + cmd.length))
3537            {
3538                ret = -EFAULT;
3539            } else {
3540                 if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != A_OK) {
3541                     ret = -EIO;
3542               }
3543             }
3544             break;
3545        }
3546        case AR6000_XIOCTL_WMI_SET_MCAST_FILTER:
3547        {
3548             WMI_SET_MCAST_FILTER_CMD cmd;
3549             if (ar->arWmiReady == FALSE) {
3550                 ret = -EIO;
3551                 goto ioctl_done;
3552             } else if (copy_from_user(&cmd, userdata,
3553                        sizeof(cmd))){
3554                 ret = -EFAULT;
3555             } else {
3556                 if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3557                                                                                     cmd.multicast_mac[1],
3558                                                                                     cmd.multicast_mac[2],
3559                                                                                     cmd.multicast_mac[3]) != A_OK) {
3560                     ret = -EIO;
3561               }
3562             }
3563             break;
3564        }
3565        case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER:
3566        {
3567             WMI_SET_MCAST_FILTER_CMD cmd;
3568             if (ar->arWmiReady == FALSE) {
3569                 ret = -EIO;
3570                 goto ioctl_done;
3571             } else if (copy_from_user(&cmd, userdata,
3572                        sizeof(cmd))){
3573                 ret = -EFAULT;
3574             } else {
3575                 if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3576                                                                                     cmd.multicast_mac[1],
3577                                                                                     cmd.multicast_mac[2],
3578                                                                                     cmd.multicast_mac[3]) != A_OK) {
3579                     ret = -EIO;
3580               }
3581             }
3582             break;
3583        }
3584        case AR6000_XIOCTL_WMI_MCAST_FILTER:
3585        {
3586             WMI_MCAST_FILTER_CMD cmd;
3587             if (ar->arWmiReady == FALSE) {
3588                 ret = -EIO;
3589                 goto ioctl_done;
3590             } else if (copy_from_user(&cmd, userdata,
3591                        sizeof(cmd))){
3592                 ret = -EFAULT;
3593             } else {
3594                 if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable)  != A_OK) {
3595                     ret = -EIO;
3596               }
3597             }
3598             break;
3599        }
3600        case AR6000_XIOCTL_WMI_GET_KEEPALIVE:
3601        {
3602            AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3603            WMI_GET_KEEPALIVE_CMD getKeepAlive;
3604            int ret = 0;
3605            if (ar->bIsDestroyProgress) {
3606                ret =-EBUSY;
3607                goto ioctl_done;
3608            }
3609            if (ar->arWmiReady == FALSE) {
3610               ret = -EIO;
3611               goto ioctl_done;
3612            }
3613            if (down_interruptible(&ar->arSem)) {
3614                ret = -ERESTARTSYS;
3615                goto ioctl_done;
3616            }
3617            if (ar->bIsDestroyProgress) {
3618                up(&ar->arSem);
3619                ret = -EBUSY;
3620                goto ioctl_done;
3621            }
3622            if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) {
3623               ret = -EFAULT;
3624            } else {
3625            getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi);
3626            ar->arKeepaliveConfigured = 0xFF;
3627            if (wmi_get_keepalive_configured(ar->arWmi) != A_OK){
3628                up(&ar->arSem);
3629                ret = -EIO;
3630                goto ioctl_done;
3631            }
3632            wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ);
3633            if (signal_pending(current)) {
3634                ret = -EINTR;
3635            }
3636
3637            if (!ret) {
3638                getKeepAlive.configured = ar->arKeepaliveConfigured;
3639            }
3640            if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) {
3641               ret = -EFAULT;
3642            }
3643            up(&ar->arSem);
3644            }
3645            break;
3646        }
3647        case AR6000_XIOCTL_WMI_SET_APPIE:
3648        {
3649            WMI_SET_APPIE_CMD appIEcmd;
3650            A_UINT8           appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN];
3651            A_UINT32            fType,ieLen;
3652
3653            if (ar->arWmiReady == FALSE) {
3654                ret = -EIO;
3655                goto ioctl_done;
3656            }
3657            if (get_user(fType, (A_UINT32 *)userdata)) {
3658                ret = -EFAULT;
3659                break;
3660            }
3661            appIEcmd.mgmtFrmType = fType;
3662            if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) {
3663                ret = -EIO;
3664            } else {
3665                if (get_user(ieLen, (A_UINT32 *)(userdata + 4))) {
3666                    ret = -EFAULT;
3667                    break;
3668                }
3669                appIEcmd.ieLen = ieLen;
3670                A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen);
3671                if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) {
3672                    ret = -EIO;
3673                    break;
3674                }
3675                if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) {
3676                    ret = -EFAULT;
3677                } else {
3678                    if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType,
3679                                          appIEcmd.ieLen,  appIeInfo) != A_OK)
3680                    {
3681                        ret = -EIO;
3682                    }
3683                }
3684            }
3685            break;
3686        }
3687        case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER:
3688        {
3689            WMI_BSS_FILTER_CMD cmd;
3690            A_UINT32    filterType;
3691
3692            if (copy_from_user(&filterType, userdata, sizeof(A_UINT32)))
3693            {
3694                ret = -EFAULT;
3695                goto ioctl_done;
3696            }
3697            if (filterType & (IEEE80211_FILTER_TYPE_BEACON |
3698                                    IEEE80211_FILTER_TYPE_PROBE_RESP))
3699            {
3700                cmd.bssFilter = ALL_BSS_FILTER;
3701            } else {
3702                cmd.bssFilter = NONE_BSS_FILTER;
3703            }
3704            if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != A_OK) {
3705                ret = -EIO;
3706            } else {
3707                ar->arUserBssFilter = cmd.bssFilter;
3708            }
3709
3710            AR6000_SPIN_LOCK(&ar->arLock, 0);
3711            ar->arMgmtFilter = filterType;
3712            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3713            break;
3714        }
3715        case AR6000_XIOCTL_WMI_SET_WSC_STATUS:
3716        {
3717            A_UINT32    wsc_status;
3718
3719            if (ar->arWmiReady == FALSE) {
3720                ret = -EIO;
3721                goto ioctl_done;
3722            } else if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32)))
3723            {
3724                ret = -EFAULT;
3725                goto ioctl_done;
3726            }
3727            if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != A_OK) {
3728                ret = -EIO;
3729            }
3730            break;
3731        }
3732        case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL:
3733        {
3734            A_UINT32 ROM_addr;
3735            A_UINT32 RAM_addr;
3736            A_UINT32 nbytes;
3737            A_UINT32 do_activate;
3738            A_UINT32 rompatch_id;
3739
3740            if (get_user(ROM_addr, (A_UINT32 *)userdata) ||
3741                get_user(RAM_addr, (A_UINT32 *)userdata + 1) ||
3742                get_user(nbytes, (A_UINT32 *)userdata + 2) ||
3743                get_user(do_activate, (A_UINT32 *)userdata + 3)) {
3744                ret = -EFAULT;
3745                break;
3746            }
3747            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x  length: %d\n",
3748                             ROM_addr, RAM_addr, nbytes));
3749            ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr,
3750                                        nbytes, do_activate, &rompatch_id);
3751            if (ret == A_OK) {
3752                /* return value */
3753                if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) {
3754                    ret = -EFAULT;
3755                    break;
3756                }
3757            }
3758            break;
3759        }
3760
3761        case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL:
3762        {
3763            A_UINT32 rompatch_id;
3764
3765            if (get_user(rompatch_id, (A_UINT32 *)userdata)) {
3766                ret = -EFAULT;
3767                break;
3768            }
3769            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id));
3770            ret = BMIrompatchUninstall(hifDevice, rompatch_id);
3771            break;
3772        }
3773
3774        case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE:
3775        case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE:
3776        {
3777            A_UINT32 rompatch_count;
3778
3779            if (get_user(rompatch_count, (A_UINT32 *)userdata)) {
3780                ret = -EFAULT;
3781                break;
3782            }
3783            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count));
3784            length = sizeof(A_UINT32) * rompatch_count;
3785            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
3786                A_MEMZERO(buffer, length);
3787                if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length))
3788                {
3789                    ret = -EFAULT;
3790                } else {
3791                    if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) {
3792                        ret = BMIrompatchActivate(hifDevice, rompatch_count, (A_UINT32 *)buffer);
3793                    } else {
3794                        ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (A_UINT32 *)buffer);
3795                    }
3796                }
3797                A_FREE(buffer);
3798            } else {
3799                ret = -ENOMEM;
3800            }
3801
3802            break;
3803        }
3804        case AR6000_XIOCTL_SET_IP:
3805        {
3806            WMI_SET_IP_CMD setIP;
3807
3808            if (ar->arWmiReady == FALSE) {
3809                ret = -EIO;
3810            } else if (copy_from_user(&setIP, userdata,
3811                                      sizeof(setIP)))
3812            {
3813                ret = -EFAULT;
3814            } else {
3815                if (wmi_set_ip_cmd(ar->arWmi,
3816                                &setIP) != A_OK)
3817                {
3818                    ret = -EIO;
3819                }
3820            }
3821            break;
3822        }
3823
3824        case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE:
3825        {
3826            WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode;
3827
3828            if (ar->arWmiReady == FALSE) {
3829                ret = -EIO;
3830            } else if (copy_from_user(&setHostSleepMode, userdata,
3831                                      sizeof(setHostSleepMode)))
3832            {
3833                ret = -EFAULT;
3834            } else {
3835                if (wmi_set_host_sleep_mode_cmd(ar->arWmi,
3836                                &setHostSleepMode) != A_OK)
3837                {
3838                    ret = -EIO;
3839                }
3840            }
3841            break;
3842        }
3843        case AR6000_XIOCTL_WMI_SET_WOW_MODE:
3844        {
3845            WMI_SET_WOW_MODE_CMD setWowMode;
3846
3847            if (ar->arWmiReady == FALSE) {
3848                ret = -EIO;
3849            } else if (copy_from_user(&setWowMode, userdata,
3850                                      sizeof(setWowMode)))
3851            {
3852                ret = -EFAULT;
3853            } else {
3854                if (wmi_set_wow_mode_cmd(ar->arWmi,
3855                                &setWowMode) != A_OK)
3856                {
3857                    ret = -EIO;
3858                }
3859            }
3860            break;
3861        }
3862        case AR6000_XIOCTL_WMI_GET_WOW_LIST:
3863        {
3864            WMI_GET_WOW_LIST_CMD getWowList;
3865
3866            if (ar->arWmiReady == FALSE) {
3867                ret = -EIO;
3868            } else if (copy_from_user(&getWowList, userdata,
3869                                      sizeof(getWowList)))
3870            {
3871                ret = -EFAULT;
3872            } else {
3873                if (wmi_get_wow_list_cmd(ar->arWmi,
3874                                &getWowList) != A_OK)
3875                {
3876                    ret = -EIO;
3877                }
3878            }
3879            break;
3880        }
3881        case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN:
3882        {
3883#define WOW_PATTERN_SIZE 64
3884#define WOW_MASK_SIZE 64
3885
3886            WMI_ADD_WOW_PATTERN_CMD cmd;
3887            A_UINT8 mask_data[WOW_PATTERN_SIZE]={0};
3888            A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0};
3889
3890            do {
3891                if (ar->arWmiReady == FALSE) {
3892                    ret = -EIO;
3893                    break;        
3894                } 
3895                if(copy_from_user(&cmd, userdata,
3896                            sizeof(WMI_ADD_WOW_PATTERN_CMD))) 
3897                {
3898                    ret = -EFAULT;
3899                    break;        
3900                }
3901                if (copy_from_user(pattern_data,
3902                                      userdata + 3,
3903                                      cmd.filter_size)) 
3904                {
3905                    ret = -EFAULT;
3906                    break;        
3907                }
3908                if (copy_from_user(mask_data,
3909                                  (userdata + 3 + cmd.filter_size),
3910                                  cmd.filter_size))
3911                {
3912                    ret = -EFAULT;
3913                    break;
3914                }
3915                if (wmi_add_wow_pattern_cmd(ar->arWmi,
3916                            &cmd, pattern_data, mask_data, cmd.filter_size) != A_OK)
3917                {
3918                    ret = -EIO;
3919                }
3920            } while(FALSE);
3921#undef WOW_PATTERN_SIZE
3922#undef WOW_MASK_SIZE
3923            break;
3924        }
3925        case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN:
3926        {
3927            WMI_DEL_WOW_PATTERN_CMD delWowPattern;
3928
3929            if (ar->arWmiReady == FALSE) {
3930                ret = -EIO;
3931            } else if (copy_from_user(&delWowPattern, userdata,
3932                                      sizeof(delWowPattern)))
3933            {
3934                ret = -EFAULT;
3935            } else {
3936                if (wmi_del_wow_pattern_cmd(ar->arWmi,
3937                                &delWowPattern) != A_OK)
3938                {
3939                    ret = -EIO;
3940                }
3941            }
3942            break;
3943        }
3944        case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE:
3945            if (ar->arHtcTarget != NULL) {
3946#ifdef ATH_DEBUG_MODULE
3947                HTCDumpCreditStates(ar->arHtcTarget);
3948#endif /* ATH_DEBUG_MODULE */
3949#ifdef HTC_EP_STAT_PROFILING
3950                {
3951                    HTC_ENDPOINT_STATS stats;
3952                    int i;
3953
3954                    for (i = 0; i < 5; i++) {
3955                        if (HTCGetEndpointStatistics(ar->arHtcTarget,
3956                                                     i,
3957                                                     HTC_EP_STAT_SAMPLE_AND_CLEAR,
3958                                                     &stats)) {
3959                            A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i);
3960                            A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications);
3961                            A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssued);
3962                            A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropped);
3963                            A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats.TxPacketsBundled);
3964                            A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBundles);
3965                            A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxCreditRpts);
3966                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", stats.TxCreditRptsFromRx);
3967                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther);
3968                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", stats.TxCreditRptsFromEp0);
3969                            A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats.TxCreditsFromRx);
3970                            A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", stats.TxCreditsFromOther);
3971                            A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats.TxCreditsFromEp0);
3972                            A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", stats.TxCreditsConsummed);
3973                            A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stats.TxCreditsReturned);
3974                            A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxReceived);
3975                            A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats.RxPacketsBundled);
3976                            A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxLookAheads);
3977                            A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", stats.RxBundleLookAheads);
3978                            A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", stats.RxBundleIndFromHdr);
3979                            A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats.RxAllocThreshHit);
3980                            A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", stats.RxAllocThreshBytes);
3981                            A_PRINTF(KERN_ALERT"---- \n");
3982
3983                        }
3984            }
3985                }
3986#endif
3987            }
3988            break;
3989        case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE:
3990            if (ar->arHtcTarget != NULL) {
3991                struct ar6000_traffic_activity_change data;
3992
3993                if (copy_from_user(&data, userdata, sizeof(data)))
3994                {
3995                    ret = -EFAULT;
3996                    goto ioctl_done;
3997                }
3998                    /* note, this is used for testing (mbox ping testing), indicate activity
3999                     * change using the stream ID as the traffic class */
4000                ar6000_indicate_tx_activity(ar,
4001                                            (A_UINT8)data.StreamID,
4002                                            data.Active ? TRUE : FALSE);
4003            }
4004            break;
4005        case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS:
4006            if (ar->arWmiReady == FALSE) {
4007                ret = -EIO;
4008            } else if (copy_from_user(&connectCtrlFlags, userdata,
4009                                      sizeof(connectCtrlFlags)))
4010            {
4011                ret = -EFAULT;
4012            } else {
4013                ar->arConnectCtrlFlags = connectCtrlFlags;
4014            }
4015            break;
4016        case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS:
4017            if (ar->arWmiReady == FALSE) {
4018                ret = -EIO;
4019            } else if (copy_from_user(&akmpParams, userdata,
4020                                      sizeof(WMI_SET_AKMP_PARAMS_CMD)))
4021            {
4022                ret = -EFAULT;
4023            } else {
4024                if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != A_OK) {
4025                    ret = -EIO;
4026                }
4027            }
4028            break;
4029        case AR6000_XIOCTL_WMI_SET_PMKID_LIST:
4030            if (ar->arWmiReady == FALSE) {
4031                ret = -EIO;
4032            } else {
4033                if (copy_from_user(&pmkidInfo.numPMKID, userdata,
4034                                      sizeof(pmkidInfo.numPMKID)))
4035                {
4036                    ret = -EFAULT;
4037                    break;
4038                }
4039                if (copy_from_user(&pmkidInfo.pmkidList,
4040                                   userdata + sizeof(pmkidInfo.numPMKID),
4041                                   pmkidInfo.numPMKID * sizeof(WMI_PMKID)))
4042                {
4043                    ret = -EFAULT;
4044                    break;
4045                }
4046                if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != A_OK) {
4047                    ret = -EIO;
4048                }
4049            }
4050            break;
4051        case AR6000_XIOCTL_WMI_GET_PMKID_LIST:
4052            if (ar->arWmiReady == FALSE) {
4053                ret = -EIO;
4054            } else  {
4055                if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) {
4056                    ret = -EIO;
4057                }
4058            }
4059            break;
4060        case AR6000_XIOCTL_WMI_ABORT_SCAN:
4061            if (ar->arWmiReady == FALSE) {
4062                ret = -EIO;
4063            }
4064            ret = wmi_abort_scan_cmd(ar->arWmi);
4065            break;
4066        case AR6000_XIOCTL_AP_HIDDEN_SSID:
4067        {
4068            A_UINT8    hidden_ssid;
4069            if (ar->arWmiReady == FALSE) {
4070                ret = -EIO;
4071            } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) {
4072                ret = -EFAULT;
4073            } else {
4074                wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid);
4075                ar->ap_hidden_ssid = hidden_ssid;
4076                ar->ap_profile_flag = 1; /* There is a change in profile */
4077            }
4078            break;
4079        }
4080        case AR6000_XIOCTL_AP_GET_STA_LIST:
4081        {
4082            if (ar->arWmiReady == FALSE) {
4083                ret = -EIO;
4084            } else {
4085                A_UINT8 i;
4086                ap_get_sta_t temp;
4087                A_MEMZERO(&temp, sizeof(temp));
4088                for(i=0;i<AP_MAX_NUM_STA;i++) {
4089                    A_MEMCPY(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN);
4090                    temp.sta[i].aid = ar->sta_list[i].aid;
4091                    temp.sta[i].keymgmt = ar->sta_list[i].keymgmt;
4092                    temp.sta[i].ucipher = ar->sta_list[i].ucipher;
4093                    temp.sta[i].auth = ar->sta_list[i].auth;
4094                }
4095                if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp,
4096                                 sizeof(ar->sta_list))) {
4097                    ret = -EFAULT;
4098                }
4099            }
4100            break;
4101        }
4102        case AR6000_XIOCTL_AP_SET_NUM_STA:
4103        {
4104            A_UINT8    num_sta;
4105            if (ar->arWmiReady == FALSE) {
4106                ret = -EIO;
4107            } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) {
4108                ret = -EFAULT;
4109            } else if(num_sta > AP_MAX_NUM_STA) {
4110                /* value out of range */
4111                ret = -EINVAL;
4112            } else {
4113                wmi_ap_set_num_sta(ar->arWmi, num_sta);
4114            }
4115            break;
4116        }
4117        case AR6000_XIOCTL_AP_SET_ACL_POLICY:
4118        {
4119            A_UINT8    policy;
4120            if (ar->arWmiReady == FALSE) {
4121                ret = -EIO;
4122            } else if (copy_from_user(&policy, userdata, sizeof(policy))) {
4123                ret = -EFAULT;
4124            } else if(policy == ar->g_acl.policy) {
4125                /* No change in policy */
4126            } else {
4127                if(!(policy & AP_ACL_RETAIN_LIST_MASK)) {
4128                    /* clear ACL list */
4129                    memset(&ar->g_acl,0,sizeof(WMI_AP_ACL));
4130                }
4131                ar->g_acl.policy = policy;
4132                wmi_ap_set_acl_policy(ar->arWmi, policy);
4133            }
4134            break;
4135        }
4136        case AR6000_XIOCTL_AP_SET_ACL_MAC:
4137        {
4138            WMI_AP_ACL_MAC_CMD    acl;
4139            if (ar->arWmiReady == FALSE) {
4140                ret = -EIO;
4141            } else if (copy_from_user(&acl, userdata, sizeof(acl))) {
4142                ret = -EFAULT;
4143            } else {
4144                if(acl_add_del_mac(&ar->g_acl, &acl)) {
4145                    wmi_ap_acl_mac_list(ar->arWmi, &acl);
4146                } else {
4147                    A_PRINTF("ACL list error\n");
4148                    ret = -EIO;
4149                }
4150            }
4151            break;
4152        }
4153        case AR6000_XIOCTL_AP_GET_ACL_LIST:
4154        {
4155            if (ar->arWmiReady == FALSE) {
4156                ret = -EIO;
4157            } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl,
4158                                 sizeof(WMI_AP_ACL))) {
4159                    ret = -EFAULT;
4160            }
4161            break;
4162        }
4163        case AR6000_XIOCTL_AP_COMMIT_CONFIG:
4164        {
4165            ret = ar6000_ap_mode_profile_commit(ar);
4166            break;
4167        }
4168        case IEEE80211_IOCTL_GETWPAIE:
4169        {
4170            struct ieee80211req_wpaie wpaie;
4171            if (ar->arWmiReady == FALSE) {
4172                ret = -EIO;
4173            } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) {
4174                ret = -EFAULT;
4175            } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) {
4176                ret = -EFAULT;
4177            } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) {
4178                ret = -EFAULT;
4179            }
4180            break;
4181        }
4182        case AR6000_XIOCTL_AP_CONN_INACT_TIME:
4183        {
4184            A_UINT32    period;
4185            if (ar->arWmiReady == FALSE) {
4186                ret = -EIO;
4187            } else if (copy_from_user(&period, userdata, sizeof(period))) {
4188                ret = -EFAULT;
4189            } else {
4190                wmi_ap_conn_inact_time(ar->arWmi, period);
4191            }
4192            break;
4193        }
4194        case AR6000_XIOCTL_AP_PROT_SCAN_TIME:
4195        {
4196            WMI_AP_PROT_SCAN_TIME_CMD  bgscan;
4197            if (ar->arWmiReady == FALSE) {
4198                ret = -EIO;
4199            } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) {
4200                ret = -EFAULT;
4201            } else {
4202                wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms);
4203            }
4204            break;
4205        }
4206        case AR6000_XIOCTL_AP_SET_COUNTRY:
4207        {
4208            ret = ar6000_ioctl_set_country(dev, rq);
4209            break;
4210        }
4211        case AR6000_XIOCTL_AP_SET_DTIM:
4212        {
4213            WMI_AP_SET_DTIM_CMD  d;
4214            if (ar->arWmiReady == FALSE) {
4215                ret = -EIO;
4216            } else if (copy_from_user(&d, userdata, sizeof(d))) {
4217                ret = -EFAULT;
4218            } else {
4219                if(d.dtim > 0 && d.dtim < 11) {
4220                    ar->ap_dtim_period = d.dtim;
4221                    wmi_ap_set_dtim(ar->arWmi, d.dtim);
4222                    ar->ap_profile_flag = 1; /* There is a change in profile */
4223                } else {
4224                    A_PRINTF("DTIM out of range. Valid range is [1-10]\n");
4225                    ret = -EIO;
4226                }
4227            }
4228            break;
4229        }
4230        case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT:
4231        {
4232            WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd;
4233
4234            if (ar->arWmiReady == FALSE) {
4235                ret = -EIO;
4236            }
4237            if (copy_from_user(&evtCfgCmd, userdata,
4238                               sizeof(evtCfgCmd))) {
4239                ret = -EFAULT;
4240                break;
4241            }
4242            ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd);
4243            break;
4244        }
4245        case AR6000_XIOCTL_AP_INTRA_BSS_COMM:
4246        {
4247            A_UINT8    intra=0;
4248            if (ar->arWmiReady == FALSE) {
4249                ret = -EIO;
4250            } else if (copy_from_user(&intra, userdata, sizeof(intra))) {
4251                ret = -EFAULT;
4252            } else {
4253                ar->intra_bss = (intra?1:0);
4254            }
4255            break;
4256        }
4257        case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO:
4258        {
4259            struct drv_debug_module_s moduleinfo;
4260
4261            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4262                ret = -EFAULT;
4263                break;
4264            }
4265
4266            a_dump_module_debug_info_by_name(moduleinfo.modulename);
4267            ret = 0;
4268            break;
4269        }
4270        case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK:
4271        {
4272            struct drv_debug_module_s moduleinfo;
4273
4274            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4275                ret = -EFAULT;
4276                break;
4277            }
4278
4279            if (A_FAILED(a_set_module_mask(moduleinfo.modulename, moduleinfo.mask))) {
4280                ret = -EFAULT;
4281            }
4282
4283            break;
4284        }
4285        case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK:
4286        {
4287            struct drv_debug_module_s moduleinfo;
4288
4289            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4290                ret = -EFAULT;
4291                break;
4292            }
4293
4294            if (A_FAILED(a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask))) {
4295                ret = -EFAULT;
4296                break;
4297            }
4298
4299            if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) {
4300                ret = -EFAULT;
4301                break;
4302            }
4303
4304            break;
4305        }
4306#ifdef ATH_AR6K_11N_SUPPORT
4307        case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS:
4308        {
4309            PACKET_LOG *copy_of_pkt_log;
4310
4311            aggr_dump_stats(ar->aggr_cntxt, &copy_of_pkt_log);
4312            if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) {
4313                ret = -EFAULT;
4314            }
4315            break;
4316        }
4317        case AR6000_XIOCTL_SETUP_AGGR:
4318        {
4319            WMI_ADDBA_REQ_CMD cmd;
4320
4321            if (ar->arWmiReady == FALSE) {
4322                ret = -EIO;
4323            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4324                ret = -EFAULT;
4325            } else {
4326                wmi_setup_aggr_cmd(ar->arWmi, cmd.tid);
4327            }
4328        }
4329        break;
4330
4331        case AR6000_XIOCTL_DELE_AGGR:
4332        {
4333            WMI_DELBA_REQ_CMD cmd;
4334
4335            if (ar->arWmiReady == FALSE) {
4336                ret = -EIO;
4337            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4338                ret = -EFAULT;
4339            } else {
4340                wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator);
4341            }
4342        }
4343        break;
4344
4345        case AR6000_XIOCTL_ALLOW_AGGR:
4346        {
4347            WMI_ALLOW_AGGR_CMD cmd;
4348
4349            if (ar->arWmiReady == FALSE) {
4350                ret = -EIO;
4351            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4352                ret = -EFAULT;
4353            } else {
4354                wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_aggr);
4355            }
4356        }
4357        break;
4358
4359        case AR6000_XIOCTL_SET_HT_CAP:
4360        {
4361            if (ar->arWmiReady == FALSE) {
4362                ret = -EIO;
4363            } else if (copy_from_user(&htCap, userdata,
4364                                      sizeof(htCap)))
4365            {
4366                ret = -EFAULT;
4367            } else {
4368
4369                if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != A_OK)
4370                {
4371                    ret = -EIO;
4372                }
4373            }
4374            break;
4375        }
4376        case AR6000_XIOCTL_SET_HT_OP:
4377        {
4378             if (ar->arWmiReady == FALSE) {
4379                ret = -EIO;
4380            } else if (copy_from_user(&htOp, userdata,
4381                                      sizeof(htOp)))
4382            {
4383                 ret = -EFAULT;
4384             } else {
4385
4386                if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != A_OK)
4387                {
4388                     ret = -EIO;
4389               }
4390             }
4391             break;
4392        }
4393#endif
4394        case AR6000_XIOCTL_ACL_DATA:
4395        {
4396            void *osbuf = NULL;
4397            if (ar->arWmiReady == FALSE) {
4398                ret = -EIO;
4399            } else if (ar6000_create_acl_data_osbuf(dev, (A_UINT8*)userdata, &osbuf) != A_OK) {
4400                     ret = -EIO;
4401            } else {
4402                if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) {
4403                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"));
4404                } else {
4405                    /* Send data buffer over HTC */
4406                    ar6000_acl_data_tx(osbuf, ar->arNetDev);
4407                }
4408            }
4409            break;
4410        }
4411        case AR6000_XIOCTL_HCI_CMD:
4412        {
4413            char tmp_buf[512];
4414            A_INT8 i;
4415            WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf;
4416            A_UINT8 size;
4417
4418            size = sizeof(cmd->cmd_buf_sz);
4419            if (ar->arWmiReady == FALSE) {
4420                ret = -EIO;
4421            } else if (copy_from_user(cmd, userdata, size)) {
4422                 ret = -EFAULT;
4423            } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) {
4424                    ret = -EFAULT;
4425            } else {
4426                if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != A_OK) {
4427                     ret = -EIO;
4428                }else if(loghci) {
4429                    A_PRINTF_LOG("HCI Command To PAL --> \n");
4430                    for(i = 0; i < cmd->cmd_buf_sz; i++) {
4431                        A_PRINTF_LOG("0x%02x ",cmd->buf[i]);
4432                        if((i % 10) == 0) {
4433                            A_PRINTF_LOG("\n");
4434                        }
4435                    }
4436                    A_PRINTF_LOG("\n");
4437                    A_PRINTF_LOG("==================================\n");
4438                }
4439            }
4440            break;
4441        }
4442        case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE:
4443        {
4444            WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd;
4445            if (ar->arWmiReady == FALSE) {
4446                ret = -EIO;
4447            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4448                ret = -EFAULT;
4449            } else {
4450                if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN ||
4451                            cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) {
4452                    if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != A_OK) {
4453                        ret = -EIO;
4454                    }
4455                } else {
4456                    ret = -EINVAL;
4457                }
4458            }
4459            break;
4460        }
4461        case AR6000_XIOCTL_AP_GET_STAT:
4462        {
4463            ret = ar6000_ioctl_get_ap_stats(dev, rq);
4464            break;
4465        }
4466        case AR6000_XIOCTL_SET_TX_SELECT_RATES:
4467        {
4468            WMI_SET_TX_SELECT_RATES_CMD masks;
4469
4470             if (ar->arWmiReady == FALSE) {
4471                ret = -EIO;
4472            } else if (copy_from_user(&masks, userdata,
4473                                      sizeof(masks)))
4474            {
4475                 ret = -EFAULT;
4476             } else {
4477
4478                if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != A_OK)
4479                {
4480                     ret = -EIO;
4481               }
4482             }
4483             break;
4484        }
4485        case AR6000_XIOCTL_AP_GET_HIDDEN_SSID:
4486        {
4487            WMI_AP_HIDDEN_SSID_CMD ssid;
4488            ssid.hidden_ssid = ar->ap_hidden_ssid;
4489
4490            if (ar->arWmiReady == FALSE) {
4491                ret = -EIO;
4492            } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data,
4493                                    &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) {
4494                    ret = -EFAULT;
4495            }
4496            break;
4497        }
4498        case AR6000_XIOCTL_AP_GET_COUNTRY:
4499        {
4500            WMI_AP_SET_COUNTRY_CMD cty;
4501            A_MEMCPY(cty.countryCode, ar->ap_country_code, 3);
4502
4503            if (ar->arWmiReady == FALSE) {
4504                ret = -EIO;
4505            } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data,
4506                                    &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) {
4507                    ret = -EFAULT;
4508            }
4509            break;
4510        }
4511        case AR6000_XIOCTL_AP_GET_WMODE:
4512        {
4513            if (ar->arWmiReady == FALSE) {
4514                ret = -EIO;
4515            } else if(copy_to_user((A_UINT8 *)rq->ifr_data,
4516                                    &ar->ap_wmode, sizeof(A_UINT8))) {
4517                    ret = -EFAULT;
4518            }
4519            break;
4520        }
4521        case AR6000_XIOCTL_AP_GET_DTIM:
4522        {
4523            WMI_AP_SET_DTIM_CMD dtim;
4524            dtim.dtim = ar->ap_dtim_period;
4525
4526            if (ar->arWmiReady == FALSE) {
4527                ret = -EIO;
4528            } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data,
4529                                    &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) {
4530                    ret = -EFAULT;
4531            }
4532            break;
4533        }
4534        case AR6000_XIOCTL_AP_GET_BINTVL:
4535        {
4536            WMI_BEACON_INT_CMD bi;
4537            bi.beaconInterval = ar->ap_beacon_interval;
4538
4539            if (ar->arWmiReady == FALSE) {
4540                ret = -EIO;
4541            } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data,
4542                                    &bi, sizeof(WMI_BEACON_INT_CMD))) {
4543                    ret = -EFAULT;
4544            }
4545            break;
4546        }
4547        case AR6000_XIOCTL_AP_GET_RTS:
4548        {
4549            WMI_SET_RTS_CMD rts;
4550            rts.threshold = ar->arRTS;
4551             
4552            if (ar->arWmiReady == FALSE) {
4553                ret = -EIO;
4554            } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data,
4555                                    &rts, sizeof(WMI_SET_RTS_CMD))) {
4556                    ret = -EFAULT;
4557            }
4558            break;
4559        }
4560        case AR6000_XIOCTL_FETCH_TARGET_REGS:
4561        {
4562            A_UINT32 targregs[AR6003_FETCH_TARG_REGS_COUNT];
4563
4564            if (ar->arTargetType == TARGET_TYPE_AR6003) {
4565                ar6k_FetchTargetRegs(hifDevice, targregs);
4566                if (copy_to_user((A_UINT32 *)rq->ifr_data, &targregs, sizeof(targregs)))
4567                {
4568                    ret = -EFAULT;
4569                }
4570            } else {
4571                ret = -EOPNOTSUPP;
4572            }
4573            break;
4574        }
4575        case AR6000_XIOCTL_AP_SET_11BG_RATESET:
4576        {
4577            WMI_AP_SET_11BG_RATESET_CMD  rate;
4578            if (ar->arWmiReady == FALSE) {
4579                ret = -EIO;
4580            } else if (copy_from_user(&rate, userdata, sizeof(rate))) {
4581                ret = -EFAULT;
4582            } else {
4583                wmi_ap_set_rateset(ar->arWmi, rate.rateset);
4584            }
4585            break;
4586        }
4587        case AR6000_XIOCTL_GET_WLAN_SLEEP_STATE:
4588        {
4589            WMI_REPORT_SLEEP_STATE_EVENT  wmiSleepEvent ;
4590
4591            if (ar->arWlanState == WLAN_ENABLED) {
4592                wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
4593            } else {
4594                wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
4595            }
4596            rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */
4597
4598            ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent,
4599                                     sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
4600            break;
4601        }
4602#ifdef CONFIG_PM
4603        case AR6000_XIOCTL_SET_BT_HW_POWER_STATE:
4604        {
4605            unsigned int state;
4606            if (get_user(state, (unsigned int *)userdata)) {
4607                ret = -EFAULT;
4608                break;
4609            }
4610            if (ar6000_set_bt_hw_state(ar, state)!=A_OK) {
4611                ret = -EIO;
4612            }       
4613        }
4614            break;
4615        case AR6000_XIOCTL_GET_BT_HW_POWER_STATE:
4616            rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */
4617            break;
4618#endif
4619
4620        case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM:
4621        {
4622             WMI_SET_TX_SGI_PARAM_CMD SGICmd;
4623
4624             if (ar->arWmiReady == FALSE) {
4625                 ret = -EIO;
4626             } else if (copy_from_user(&SGICmd, userdata,
4627                                       sizeof(SGICmd))){
4628                 ret = -EFAULT;
4629             } else{
4630                     if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != A_OK) {
4631                         ret = -EIO;
4632                     }
4633
4634             }
4635             break;
4636        }
4637
4638        case AR6000_XIOCTL_ADD_AP_INTERFACE:
4639#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
4640        {
4641            char ap_ifname[IFNAMSIZ] = {0,};
4642            if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) {
4643                ret = -EFAULT;
4644            } else {
4645                if (ar6000_add_ap_interface(ar, ap_ifname) != A_OK) {
4646                    ret = -EIO;
4647                } 
4648            }
4649        }
4650#else
4651            ret = -EOPNOTSUPP;
4652#endif
4653            break;
4654        case AR6000_XIOCTL_REMOVE_AP_INTERFACE:
4655#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
4656            if (ar6000_remove_ap_interface(ar) != A_OK) {
4657                ret = -EIO;
4658            } 
4659#else
4660            ret = -EOPNOTSUPP;
4661#endif
4662            break;
4663
4664        default:
4665            ret = -EOPNOTSUPP;
4666    }
4667
4668ioctl_done:
4669    rtnl_lock(); /* restore rtnl state */
4670    dev_put(dev);
4671
4672    return ret;
4673}
4674
4675A_UINT8 mac_cmp_wild(A_UINT8 *mac, A_UINT8 *new_mac, A_UINT8 wild, A_UINT8 new_wild)
4676{
4677    A_UINT8 i;
4678
4679    for(i=0;i<ATH_MAC_LEN;i++) {
4680        if((wild & 1<<i) && (new_wild & 1<<i)) continue;
4681        if(mac[i] != new_mac[i]) return 1;
4682    }
4683    if((A_MEMCMP(new_mac, null_mac, 6)==0) && new_wild &&
4684        (wild != new_wild)) {
4685        return 1;
4686    }
4687
4688    return 0;
4689}
4690
4691A_UINT8    acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl)
4692{
4693    A_INT8    already_avail=-1, free_slot=-1, i;
4694
4695    /* To check whether this mac is already there in our list */
4696    for(i=AP_ACL_SIZE-1;i>=0;i--)
4697    {
4698        if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i],
4699            acl->wildcard)==0)
4700                already_avail = i;
4701
4702        if(!((1 << i) & a->index))
4703            free_slot = i;
4704    }
4705
4706    if(acl->action == ADD_MAC_ADDR)
4707    {
4708        /* Dont add mac if it is already available */
4709        if((already_avail >= 0) || (free_slot == -1))
4710            return 0;
4711
4712        A_MEMCPY(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN);
4713        a->index = a->index | (1 << free_slot);
4714        acl->index = free_slot;
4715        a->wildcard[free_slot] = acl->wildcard;
4716        return 1;
4717    }
4718    else if(acl->action == DEL_MAC_ADDR)
4719    {
4720        if(acl->index > AP_ACL_SIZE)
4721            return 0;
4722
4723        if(!(a->index & (1 << acl->index)))
4724            return 0;
4725
4726        A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN);
4727        a->index = a->index & ~(1 << acl->index);
4728        a->wildcard[acl->index] = 0;
4729        return 1;
4730    }
4731
4732    return 0;
4733}
4734