linux/drivers/staging/ath6kl/os/linux/cfg80211.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 <linux/wireless.h>
  25#include <linux/ieee80211.h>
  26#include <net/cfg80211.h>
  27
  28#include "ar6000_drv.h"
  29
  30
  31extern A_WAITQUEUE_HEAD arEvent;
  32extern unsigned int wmitimeout;
  33extern int reconnect_flag;
  34
  35
  36#define RATETAB_ENT(_rate, _rateid, _flags) {   \
  37    .bitrate    = (_rate),                  \
  38    .flags      = (_flags),                 \
  39    .hw_value   = (_rateid),                \
  40}
  41
  42#define CHAN2G(_channel, _freq, _flags) {   \
  43    .band           = IEEE80211_BAND_2GHZ,  \
  44    .hw_value       = (_channel),           \
  45    .center_freq    = (_freq),              \
  46    .flags          = (_flags),             \
  47    .max_antenna_gain   = 0,                \
  48    .max_power      = 30,                   \
  49}
  50
  51#define CHAN5G(_channel, _flags) {              \
  52    .band           = IEEE80211_BAND_5GHZ,      \
  53    .hw_value       = (_channel),               \
  54    .center_freq    = 5000 + (5 * (_channel)),  \
  55    .flags          = (_flags),                 \
  56    .max_antenna_gain   = 0,                    \
  57    .max_power      = 30,                       \
  58}
  59
  60static struct
  61ieee80211_rate ar6k_rates[] = {
  62    RATETAB_ENT(10,  0x1,   0),
  63    RATETAB_ENT(20,  0x2,   0),
  64    RATETAB_ENT(55,  0x4,   0),
  65    RATETAB_ENT(110, 0x8,   0),
  66    RATETAB_ENT(60,  0x10,  0),
  67    RATETAB_ENT(90,  0x20,  0),
  68    RATETAB_ENT(120, 0x40,  0),
  69    RATETAB_ENT(180, 0x80,  0),
  70    RATETAB_ENT(240, 0x100, 0),
  71    RATETAB_ENT(360, 0x200, 0),
  72    RATETAB_ENT(480, 0x400, 0),
  73    RATETAB_ENT(540, 0x800, 0),
  74};
  75
  76#define ar6k_a_rates     (ar6k_rates + 4)
  77#define ar6k_a_rates_size    8
  78#define ar6k_g_rates     (ar6k_rates + 0)
  79#define ar6k_g_rates_size    12
  80
  81static struct
  82ieee80211_channel ar6k_2ghz_channels[] = {
  83    CHAN2G(1, 2412, 0),
  84    CHAN2G(2, 2417, 0),
  85    CHAN2G(3, 2422, 0),
  86    CHAN2G(4, 2427, 0),
  87    CHAN2G(5, 2432, 0),
  88    CHAN2G(6, 2437, 0),
  89    CHAN2G(7, 2442, 0),
  90    CHAN2G(8, 2447, 0),
  91    CHAN2G(9, 2452, 0),
  92    CHAN2G(10, 2457, 0),
  93    CHAN2G(11, 2462, 0),
  94    CHAN2G(12, 2467, 0),
  95    CHAN2G(13, 2472, 0),
  96    CHAN2G(14, 2484, 0),
  97};
  98
  99static struct
 100ieee80211_channel ar6k_5ghz_a_channels[] = {
 101    CHAN5G(34, 0),      CHAN5G(36, 0),
 102    CHAN5G(38, 0),      CHAN5G(40, 0),
 103    CHAN5G(42, 0),      CHAN5G(44, 0),
 104    CHAN5G(46, 0),      CHAN5G(48, 0),
 105    CHAN5G(52, 0),      CHAN5G(56, 0),
 106    CHAN5G(60, 0),      CHAN5G(64, 0),
 107    CHAN5G(100, 0),     CHAN5G(104, 0),
 108    CHAN5G(108, 0),     CHAN5G(112, 0),
 109    CHAN5G(116, 0),     CHAN5G(120, 0),
 110    CHAN5G(124, 0),     CHAN5G(128, 0),
 111    CHAN5G(132, 0),     CHAN5G(136, 0),
 112    CHAN5G(140, 0),     CHAN5G(149, 0),
 113    CHAN5G(153, 0),     CHAN5G(157, 0),
 114    CHAN5G(161, 0),     CHAN5G(165, 0),
 115    CHAN5G(184, 0),     CHAN5G(188, 0),
 116    CHAN5G(192, 0),     CHAN5G(196, 0),
 117    CHAN5G(200, 0),     CHAN5G(204, 0),
 118    CHAN5G(208, 0),     CHAN5G(212, 0),
 119    CHAN5G(216, 0),
 120};
 121
 122static struct
 123ieee80211_supported_band ar6k_band_2ghz = {
 124    .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
 125    .channels = ar6k_2ghz_channels,
 126    .n_bitrates = ar6k_g_rates_size,
 127    .bitrates = ar6k_g_rates,
 128};
 129
 130static struct
 131ieee80211_supported_band ar6k_band_5ghz = {
 132    .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
 133    .channels = ar6k_5ghz_a_channels,
 134    .n_bitrates = ar6k_a_rates_size,
 135    .bitrates = ar6k_a_rates,
 136};
 137
 138static int
 139ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version)
 140{
 141
 142    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
 143
 144    if (!wpa_version) {
 145        ar->arAuthMode = NONE_AUTH;
 146    } else if (wpa_version & NL80211_WPA_VERSION_1) {
 147        ar->arAuthMode = WPA_AUTH;
 148    } else if (wpa_version & NL80211_WPA_VERSION_2) {
 149        ar->arAuthMode = WPA2_AUTH;
 150    } else {
 151        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 152                        ("%s: %u not spported\n", __func__, wpa_version));
 153        return -ENOTSUPP;
 154    }
 155
 156    return A_OK;
 157}
 158
 159static int
 160ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type)
 161{
 162
 163    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
 164
 165    switch (auth_type) {
 166    case NL80211_AUTHTYPE_OPEN_SYSTEM:
 167        ar->arDot11AuthMode = OPEN_AUTH;
 168        break;
 169    case NL80211_AUTHTYPE_SHARED_KEY:
 170        ar->arDot11AuthMode = SHARED_AUTH;
 171        break;
 172    case NL80211_AUTHTYPE_NETWORK_EAP:
 173        ar->arDot11AuthMode = LEAP_AUTH;
 174        break;
 175    default:
 176        ar->arDot11AuthMode = OPEN_AUTH;
 177        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 178                        ("%s: 0x%x not spported\n", __func__, auth_type));
 179        return -ENOTSUPP;
 180    }
 181
 182    return A_OK;
 183}
 184
 185static int
 186ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, A_BOOL ucast)
 187{
 188    A_UINT8  *ar_cipher = ucast ? &ar->arPairwiseCrypto :
 189                                &ar->arGroupCrypto;
 190    A_UINT8  *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
 191                                    &ar->arGroupCryptoLen;
 192
 193    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 194                    ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
 195
 196    switch (cipher) {
 197    case 0:
 198    case IW_AUTH_CIPHER_NONE:
 199        *ar_cipher = NONE_CRYPT;
 200        *ar_cipher_len = 0;
 201        break;
 202    case WLAN_CIPHER_SUITE_WEP40:
 203        *ar_cipher = WEP_CRYPT;
 204        *ar_cipher_len = 5;
 205        break;
 206    case WLAN_CIPHER_SUITE_WEP104:
 207        *ar_cipher = WEP_CRYPT;
 208        *ar_cipher_len = 13;
 209        break;
 210    case WLAN_CIPHER_SUITE_TKIP:
 211        *ar_cipher = TKIP_CRYPT;
 212        *ar_cipher_len = 0;
 213        break;
 214    case WLAN_CIPHER_SUITE_CCMP:
 215        *ar_cipher = AES_CRYPT;
 216        *ar_cipher_len = 0;
 217        break;
 218    default:
 219        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 220                        ("%s: cipher 0x%x not supported\n", __func__, cipher));
 221        return -ENOTSUPP;
 222    }
 223
 224    return A_OK;
 225}
 226
 227static void
 228ar6k_set_key_mgmt(AR_SOFTC_T *ar, A_UINT32 key_mgmt)
 229{
 230    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
 231
 232    if (WLAN_AKM_SUITE_PSK == key_mgmt) {
 233        if (WPA_AUTH == ar->arAuthMode) {
 234            ar->arAuthMode = WPA_PSK_AUTH;
 235        } else if (WPA2_AUTH == ar->arAuthMode) {
 236            ar->arAuthMode = WPA2_PSK_AUTH;
 237        }
 238    } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
 239        ar->arAuthMode = NONE_AUTH;
 240    }
 241}
 242
 243static int
 244ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 245                      struct cfg80211_connect_params *sme)
 246{
 247    AR_SOFTC_T *ar = ar6k_priv(dev);
 248    A_STATUS status;
 249
 250    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
 251
 252    if(ar->arWmiReady == FALSE) {
 253        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
 254        return -EIO;
 255    }
 256
 257    if(ar->arWlanState == WLAN_DISABLED) {
 258        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 259        return -EIO;
 260    }
 261
 262    if(ar->bIsDestroyProgress) {
 263        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
 264        return -EBUSY;
 265    }
 266
 267    if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
 268        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
 269        return -EINVAL;
 270    }
 271
 272    if(ar->arSkipScan == TRUE &&
 273       ((sme->channel && sme->channel->center_freq == 0) ||
 274        (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
 275         !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
 276    {
 277        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
 278        return -EINVAL;
 279    }
 280
 281    if(down_interruptible(&ar->arSem)) {
 282        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
 283        return -ERESTARTSYS;
 284    }
 285
 286    if(ar->bIsDestroyProgress) {
 287        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
 288        up(&ar->arSem);
 289        return -EBUSY;
 290    }
 291
 292    if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
 293        /*
 294        * sleep until the command queue drains
 295        */
 296        wait_event_interruptible_timeout(arEvent,
 297        ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
 298        if (signal_pending(current)) {
 299            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
 300            up(&ar->arSem);
 301            return -EINTR;
 302        }
 303    }
 304
 305    if(ar->arConnected == TRUE &&
 306       ar->arSsidLen == sme->ssid_len &&
 307       !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
 308        reconnect_flag = TRUE;
 309        status = wmi_reconnect_cmd(ar->arWmi,
 310                                   ar->arReqBssid,
 311                                   ar->arChannelHint);
 312
 313        up(&ar->arSem);
 314        if (status != A_OK) {
 315            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
 316            return -EIO;
 317        }
 318        return 0;
 319    } else if(ar->arSsidLen == sme->ssid_len &&
 320              !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
 321            wmi_disconnect_cmd(ar->arWmi);
 322    }
 323
 324    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
 325    ar->arSsidLen = sme->ssid_len;
 326    A_MEMCPY(ar->arSsid, sme->ssid, sme->ssid_len);
 327
 328    if(sme->channel){
 329        ar->arChannelHint = sme->channel->center_freq;
 330    }
 331
 332    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
 333    if(sme->bssid){
 334        if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
 335            A_MEMCPY(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
 336        }
 337    }
 338
 339    ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
 340    ar6k_set_auth_type(ar, sme->auth_type);
 341
 342    if(sme->crypto.n_ciphers_pairwise) {
 343        ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
 344    } else {
 345        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
 346    }
 347    ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
 348
 349    if(sme->crypto.n_akm_suites) {
 350        ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
 351    }
 352
 353    if((sme->key_len) &&
 354       (NONE_AUTH == ar->arAuthMode) &&
 355        (WEP_CRYPT == ar->arPairwiseCrypto)) {
 356        struct ar_key *key = NULL;
 357
 358        if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
 359            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 360                            ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
 361            up(&ar->arSem);
 362            return -ENOENT;
 363        }
 364
 365        key = &ar->keys[sme->key_idx];
 366        key->key_len = sme->key_len;
 367        A_MEMCPY(key->key, sme->key, key->key_len);
 368        key->cipher = ar->arPairwiseCrypto;
 369        ar->arDefTxKeyIndex = sme->key_idx;
 370
 371        wmi_addKey_cmd(ar->arWmi, sme->key_idx,
 372                    ar->arPairwiseCrypto,
 373                    GROUP_USAGE | TX_USAGE,
 374                    key->key_len,
 375                    NULL,
 376                    key->key, KEY_OP_INIT_VAL, NULL,
 377                    NO_SYNC_WMIFLAG);
 378    }
 379
 380    if (!ar->arUserBssFilter) {
 381        if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
 382            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
 383            up(&ar->arSem);
 384            return -EIO;
 385        }
 386    }
 387
 388    ar->arNetworkType = ar->arNextMode;
 389
 390    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
 391                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
 392                    " GRP crypto Len %d channel hint %u\n",
 393                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
 394                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
 395                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
 396
 397    reconnect_flag = 0;
 398    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
 399                            ar->arDot11AuthMode, ar->arAuthMode,
 400                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
 401                            ar->arGroupCrypto,ar->arGroupCryptoLen,
 402                            ar->arSsidLen, ar->arSsid,
 403                            ar->arReqBssid, ar->arChannelHint,
 404                            ar->arConnectCtrlFlags);
 405
 406    up(&ar->arSem);
 407
 408    if (A_EINVAL == status) {
 409        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
 410        ar->arSsidLen = 0;
 411        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
 412        return -ENOENT;
 413    } else if (status != A_OK) {
 414        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
 415        return -EIO;
 416    }
 417
 418    if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
 419        ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
 420    {
 421        A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
 422    }
 423
 424    ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
 425    ar->arConnectPending = TRUE;
 426
 427    return 0;
 428}
 429
 430void
 431ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel,
 432                A_UINT8 *bssid, A_UINT16 listenInterval,
 433                A_UINT16 beaconInterval,NETWORK_TYPE networkType,
 434                A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
 435                A_UINT8 assocRespLen, A_UINT8 *assocInfo)
 436{
 437    A_UINT16 size = 0;
 438    A_UINT16 capability = 0;
 439    struct cfg80211_bss *bss = NULL;
 440    struct ieee80211_mgmt *mgmt = NULL;
 441    struct ieee80211_channel *ibss_channel = NULL;
 442    s32 signal = 50 * 100;
 443    A_UINT8 ie_buf_len = 0;
 444    unsigned char ie_buf[256];
 445    unsigned char *ptr_ie_buf = ie_buf;
 446    unsigned char *ieeemgmtbuf = NULL;
 447    A_UINT8 source_mac[ATH_MAC_LEN];
 448
 449    A_UINT8 assocReqIeOffset = sizeof(A_UINT16)  +  /* capinfo*/
 450                               sizeof(A_UINT16);    /* listen interval */
 451    A_UINT8 assocRespIeOffset = sizeof(A_UINT16) +  /* capinfo*/
 452                                sizeof(A_UINT16) +  /* status Code */
 453                                sizeof(A_UINT16);   /* associd */
 454    A_UINT8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
 455    A_UINT8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
 456
 457    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
 458
 459    assocReqLen -= assocReqIeOffset;
 460    assocRespLen -= assocRespIeOffset;
 461
 462    if((ADHOC_NETWORK & networkType)) {
 463        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
 464            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 465                            ("%s: ath6k not in ibss mode\n", __func__));
 466            return;
 467        }
 468    }
 469
 470    if((INFRA_NETWORK & networkType)) {
 471        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
 472            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 473                            ("%s: ath6k not in station mode\n", __func__));
 474            return;
 475        }
 476    }
 477
 478    /* Before informing the join/connect event, make sure that
 479     * bss entry is present in scan list, if it not present
 480     * construct and insert into scan list, otherwise that
 481     * event will be dropped on the way by cfg80211, due to
 482     * this keys will not be plumbed in case of WEP and
 483     * application will not be aware of join/connect status. */
 484    bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
 485                           ar->wdev->ssid, ar->wdev->ssid_len,
 486                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
 487                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
 488
 489    if(!bss) {
 490        if (ADHOC_NETWORK & networkType) {
 491            /* construct 802.11 mgmt beacon */
 492            if(ptr_ie_buf) {
 493                *ptr_ie_buf++ = WLAN_EID_SSID;
 494                *ptr_ie_buf++ = ar->arSsidLen;
 495                A_MEMCPY(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
 496                ptr_ie_buf +=ar->arSsidLen;
 497
 498                *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
 499                *ptr_ie_buf++ = 2; /* length */
 500                *ptr_ie_buf++ = 0; /* ATIM window */
 501                *ptr_ie_buf++ = 0; /* ATIM window */
 502
 503                /* TODO: update ibss params and include supported rates,
 504                 * DS param set, extened support rates, wmm. */
 505
 506                ie_buf_len = ptr_ie_buf - ie_buf;
 507            }
 508
 509            capability |= IEEE80211_CAPINFO_IBSS;
 510            if(WEP_CRYPT == ar->arPairwiseCrypto) {
 511                capability |= IEEE80211_CAPINFO_PRIVACY;
 512            }
 513            A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
 514            ptr_ie_buf = ie_buf;
 515        } else {
 516            capability = *(A_UINT16 *)(&assocInfo[beaconIeLen]);
 517            A_MEMCPY(source_mac, bssid, ATH_MAC_LEN);
 518            ptr_ie_buf = assocReqIe;
 519            ie_buf_len = assocReqLen;
 520        }
 521
 522        size = offsetof(struct ieee80211_mgmt, u)
 523             + sizeof(mgmt->u.beacon)
 524             + ie_buf_len;
 525
 526        ieeemgmtbuf = A_MALLOC_NOWAIT(size);
 527        if(!ieeemgmtbuf) {
 528            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 529                            ("%s: ieeeMgmtbuf alloc error\n", __func__));
 530            return;
 531        }
 532
 533        A_MEMZERO(ieeemgmtbuf, size);
 534        mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
 535        mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
 536        A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
 537        A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN);
 538        A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN);
 539        mgmt->u.beacon.beacon_int = beaconInterval;
 540        mgmt->u.beacon.capab_info = capability;
 541        A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
 542
 543        ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
 544
 545        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 546                ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
 547                        "capability 0x%x\n", __func__, mgmt->bssid,
 548                        ibss_channel->hw_value, beaconInterval, capability));
 549
 550        bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
 551                                        ibss_channel, mgmt,
 552                                        le16_to_cpu(size),
 553                                        signal, GFP_KERNEL);
 554        A_FREE(ieeemgmtbuf);
 555        cfg80211_put_bss(bss);
 556    }
 557
 558    if((ADHOC_NETWORK & networkType)) {
 559        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
 560        return;
 561    }
 562
 563    if (FALSE == ar->arConnected) {
 564        /* inform connect result to cfg80211 */
 565        cfg80211_connect_result(ar->arNetDev, bssid,
 566                                assocReqIe, assocReqLen,
 567                                assocRespIe, assocRespLen,
 568                                WLAN_STATUS_SUCCESS, GFP_KERNEL);
 569    } else {
 570        /* inform roam event to cfg80211 */
 571        cfg80211_roamed(ar->arNetDev, bssid,
 572                        assocReqIe, assocReqLen,
 573                        assocRespIe, assocRespLen,
 574                        GFP_KERNEL);
 575    }
 576}
 577
 578static int
 579ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
 580                        A_UINT16 reason_code)
 581{
 582    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
 583
 584    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
 585
 586    if(ar->arWmiReady == FALSE) {
 587        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 588        return -EIO;
 589    }
 590
 591    if(ar->arWlanState == WLAN_DISABLED) {
 592        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 593        return -EIO;
 594    }
 595
 596    if(ar->bIsDestroyProgress) {
 597        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
 598        return -EBUSY;
 599    }
 600
 601    if(down_interruptible(&ar->arSem)) {
 602        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
 603        return -ERESTARTSYS;
 604    }
 605
 606    reconnect_flag = 0;
 607    wmi_disconnect_cmd(ar->arWmi);
 608    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
 609    ar->arSsidLen = 0;
 610
 611    if (ar->arSkipScan == FALSE) {
 612        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
 613    }
 614
 615    up(&ar->arSem);
 616
 617    return 0;
 618}
 619
 620void
 621ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason,
 622                               A_UINT8 *bssid, A_UINT8 assocRespLen,
 623                               A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
 624{
 625
 626    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
 627
 628    if((ADHOC_NETWORK & ar->arNetworkType)) {
 629        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
 630            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 631                            ("%s: ath6k not in ibss mode\n", __func__));
 632            return;
 633        }
 634        A_MEMZERO(bssid, ETH_ALEN);
 635        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
 636        return;
 637    }
 638
 639    if((INFRA_NETWORK & ar->arNetworkType)) {
 640        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
 641            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 642                            ("%s: ath6k not in station mode\n", __func__));
 643            return;
 644        }
 645    }
 646
 647    if(FALSE == ar->arConnected) {
 648        if(NO_NETWORK_AVAIL == reason) {
 649            /* connect cmd failed */
 650            cfg80211_connect_result(ar->arNetDev, bssid,
 651                                    NULL, 0,
 652                                    NULL, 0,
 653                                    WLAN_STATUS_UNSPECIFIED_FAILURE,
 654                                    GFP_KERNEL);
 655        }
 656    } else {
 657        /* connection loss due to disconnect cmd or low rssi */
 658        cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
 659    }
 660}
 661
 662void
 663ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
 664{
 665    struct wiphy *wiphy = (struct wiphy *)arg;
 666    A_UINT16 size;
 667    unsigned char *ieeemgmtbuf = NULL;
 668    struct ieee80211_mgmt *mgmt;
 669    struct ieee80211_channel *channel;
 670    struct ieee80211_supported_band *band;
 671    struct ieee80211_common_ie  *cie;
 672    s32 signal;
 673    int freq;
 674
 675    cie = &ni->ni_cie;
 676
 677#define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
 678    if(CHAN_IS_11A(cie->ie_chan)) {
 679        /* 11a */
 680        band = wiphy->bands[IEEE80211_BAND_5GHZ];
 681    } else if((cie->ie_erp) || (cie->ie_xrates)) {
 682        /* 11g */
 683        band = wiphy->bands[IEEE80211_BAND_2GHZ];
 684    } else {
 685        /* 11b */
 686        band = wiphy->bands[IEEE80211_BAND_2GHZ];
 687    }
 688
 689    size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
 690    ieeemgmtbuf = A_MALLOC_NOWAIT(size);
 691    if(!ieeemgmtbuf)
 692    {
 693        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
 694        return;
 695    }
 696
 697    /* Note:
 698       TODO: Update target to include 802.11 mac header while sending bss info.
 699       Target removes 802.11 mac header while sending the bss info to host,
 700       cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
 701    */
 702    mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
 703    A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
 704    A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
 705    A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
 706    A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
 707             ni->ni_buf, ni->ni_framelen);
 708
 709    freq    = cie->ie_chan;
 710    channel = ieee80211_get_channel(wiphy, freq);
 711    signal  = ni->ni_snr * 100;
 712
 713        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 714                ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
 715                        mgmt->bssid, channel->hw_value, freq, size));
 716    cfg80211_inform_bss_frame(wiphy, channel, mgmt,
 717                              le16_to_cpu(size),
 718                              signal, GFP_KERNEL);
 719
 720    A_FREE (ieeemgmtbuf);
 721}
 722
 723static int
 724ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 725                   struct cfg80211_scan_request *request)
 726{
 727    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 728    int ret = 0;
 729    A_BOOL forceFgScan = FALSE;
 730
 731    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
 732
 733    if(ar->arWmiReady == FALSE) {
 734        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 735        return -EIO;
 736    }
 737
 738    if(ar->arWlanState == WLAN_DISABLED) {
 739        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 740        return -EIO;
 741    }
 742
 743    if (!ar->arUserBssFilter) {
 744        if (wmi_bssfilter_cmd(ar->arWmi,
 745                             (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
 746                             0) != A_OK) {
 747            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
 748            return -EIO;
 749        }
 750    }
 751
 752    if(request->n_ssids &&
 753       request->ssids[0].ssid_len) {
 754        A_UINT8 i;
 755
 756        if(request->n_ssids > MAX_PROBED_SSID_INDEX) {
 757            request->n_ssids = MAX_PROBED_SSID_INDEX;
 758        }
 759
 760        for (i = 0; i < request->n_ssids; i++) {
 761            wmi_probedSsid_cmd(ar->arWmi, i, SPECIFIC_SSID_FLAG,
 762                               request->ssids[i].ssid_len,
 763                               request->ssids[i].ssid);
 764        }
 765    }
 766
 767    if(ar->arConnected) {
 768        forceFgScan = TRUE;
 769    }
 770
 771    if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \
 772                         0, 0, 0, NULL) != A_OK) {
 773        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
 774        ret = -EIO;
 775    }
 776
 777    ar->scan_request = request;
 778
 779    return ret;
 780}
 781
 782void
 783ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
 784{
 785
 786    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
 787
 788    if(ar->scan_request)
 789    {
 790        /* Translate data to cfg80211 mgmt format */
 791        wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
 792
 793        cfg80211_scan_done(ar->scan_request,
 794                          (status & A_ECANCELED) ? true : false);
 795
 796        if(ar->scan_request->n_ssids &&
 797           ar->scan_request->ssids[0].ssid_len) {
 798            A_UINT8 i;
 799
 800            for (i = 0; i < ar->scan_request->n_ssids; i++) {
 801                wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG,
 802                                   0, NULL);
 803            }
 804        }
 805        ar->scan_request = NULL;
 806    }
 807}
 808
 809static int
 810ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 811                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
 812                      struct key_params *params)
 813{
 814    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 815    struct ar_key *key = NULL;
 816    A_UINT8 key_usage;
 817    A_UINT8 key_type;
 818    A_STATUS status = 0;
 819
 820    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
 821
 822    if(ar->arWmiReady == FALSE) {
 823        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 824        return -EIO;
 825    }
 826
 827    if(ar->arWlanState == WLAN_DISABLED) {
 828        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 829        return -EIO;
 830    }
 831
 832    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
 833        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 834                        ("%s: key index %d out of bounds\n", __func__, key_index));
 835        return -ENOENT;
 836    }
 837
 838    key = &ar->keys[key_index];
 839    A_MEMZERO(key, sizeof(struct ar_key));
 840
 841    if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
 842        key_usage = GROUP_USAGE;
 843    } else {
 844        key_usage = PAIRWISE_USAGE;
 845    }
 846
 847    if(params) {
 848        if(params->key_len > WLAN_MAX_KEY_LEN ||
 849            params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
 850            return -EINVAL;
 851
 852        key->key_len = params->key_len;
 853        A_MEMCPY(key->key, params->key, key->key_len);
 854        key->seq_len = params->seq_len;
 855        A_MEMCPY(key->seq, params->seq, key->seq_len);
 856        key->cipher = params->cipher;
 857    }
 858
 859    switch (key->cipher) {
 860    case WLAN_CIPHER_SUITE_WEP40:
 861    case WLAN_CIPHER_SUITE_WEP104:
 862        key_type = WEP_CRYPT;
 863        break;
 864
 865    case WLAN_CIPHER_SUITE_TKIP:
 866        key_type = TKIP_CRYPT;
 867        break;
 868
 869    case WLAN_CIPHER_SUITE_CCMP:
 870        key_type = AES_CRYPT;
 871        break;
 872
 873    default:
 874        return -ENOTSUPP;
 875    }
 876
 877    if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
 878        (GROUP_USAGE & key_usage))
 879    {
 880        A_UNTIMEOUT(&ar->disconnect_timer);
 881    }
 882
 883    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 884                    ("%s: index %d, key_len %d, key_type 0x%x,"\
 885                    " key_usage 0x%x, seq_len %d\n",
 886                    __func__, key_index, key->key_len, key_type,
 887                    key_usage, key->seq_len));
 888
 889    ar->arDefTxKeyIndex = key_index;
 890    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
 891                    key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
 892                    (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG);
 893
 894
 895    if(status != A_OK) {
 896        return -EIO;
 897    }
 898
 899    return 0;
 900}
 901
 902static int
 903ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
 904                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr)
 905{
 906    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 907
 908    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
 909
 910    if(ar->arWmiReady == FALSE) {
 911        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 912        return -EIO;
 913    }
 914
 915    if(ar->arWlanState == WLAN_DISABLED) {
 916        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 917        return -EIO;
 918    }
 919
 920    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
 921        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 922                        ("%s: key index %d out of bounds\n", __func__, key_index));
 923        return -ENOENT;
 924    }
 925
 926    if(!ar->keys[key_index].key_len) {
 927        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
 928        return 0;
 929    }
 930
 931    ar->keys[key_index].key_len = 0;
 932
 933    return wmi_deleteKey_cmd(ar->arWmi, key_index);
 934}
 935
 936
 937static int
 938ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
 939                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
 940                      void *cookie,
 941                      void (*callback)(void *cookie, struct key_params*))
 942{
 943    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 944    struct ar_key *key = NULL;
 945    struct key_params params;
 946
 947    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
 948
 949    if(ar->arWmiReady == FALSE) {
 950        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 951        return -EIO;
 952    }
 953
 954    if(ar->arWlanState == WLAN_DISABLED) {
 955        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 956        return -EIO;
 957    }
 958
 959    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
 960        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
 961                        ("%s: key index %d out of bounds\n", __func__, key_index));
 962        return -ENOENT;
 963    }
 964
 965    key = &ar->keys[key_index];
 966    A_MEMZERO(&params, sizeof(params));
 967    params.cipher = key->cipher;
 968    params.key_len = key->key_len;
 969    params.seq_len = key->seq_len;
 970    params.seq = key->seq;
 971    params.key = key->key;
 972
 973    callback(cookie, &params);
 974
 975    return key->key_len ? 0 : -ENOENT;
 976}
 977
 978
 979static int
 980ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
 981                              A_UINT8 key_index)
 982{
 983    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 984    struct ar_key *key = NULL;
 985    A_STATUS status = A_OK;
 986
 987    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
 988
 989    if(ar->arWmiReady == FALSE) {
 990        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
 991        return -EIO;
 992    }
 993
 994    if(ar->arWlanState == WLAN_DISABLED) {
 995        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
 996        return -EIO;
 997    }
 998
 999    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1000        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1001                        ("%s: key index %d out of bounds\n",
1002                        __func__, key_index));
1003        return -ENOENT;
1004    }
1005
1006    if(!ar->keys[key_index].key_len) {
1007        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1008                        __func__, key_index));
1009        return -EINVAL;
1010    }
1011
1012    ar->arDefTxKeyIndex = key_index;
1013    key = &ar->keys[ar->arDefTxKeyIndex];
1014    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1015                            ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
1016                            key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1017                            NULL, SYNC_BOTH_WMIFLAG);
1018    if (status != A_OK) {
1019        return -EIO;
1020    }
1021
1022    return 0;
1023}
1024
1025static int
1026ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1027                                   A_UINT8 key_index)
1028{
1029    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
1030
1031    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1032
1033    if(ar->arWmiReady == FALSE) {
1034        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1035        return -EIO;
1036    }
1037
1038    if(ar->arWlanState == WLAN_DISABLED) {
1039        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1040        return -EIO;
1041    }
1042
1043    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1044    return -ENOTSUPP;
1045}
1046
1047void
1048ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
1049{
1050    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1051                    ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1052
1053    cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1054                                 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1055                                 keyid, NULL, GFP_KERNEL);
1056}
1057
1058static int
1059ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed)
1060{
1061    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1062
1063    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1064
1065    if(ar->arWmiReady == FALSE) {
1066        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1067        return -EIO;
1068    }
1069
1070    if(ar->arWlanState == WLAN_DISABLED) {
1071        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1072        return -EIO;
1073    }
1074
1075    if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1076        if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != A_OK){
1077            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1078            return -EIO;
1079        }
1080    }
1081
1082    return 0;
1083}
1084
1085static int
1086ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1087                               const A_UINT8 *peer,
1088                               const struct cfg80211_bitrate_mask *mask)
1089{
1090    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1091    return -EIO;
1092}
1093
1094/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1095static int
1096ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1097{
1098    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1099    A_UINT8 ar_dbm;
1100
1101    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1102
1103    if(ar->arWmiReady == FALSE) {
1104        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1105        return -EIO;
1106    }
1107
1108    if(ar->arWlanState == WLAN_DISABLED) {
1109        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1110        return -EIO;
1111    }
1112
1113    ar->arTxPwrSet = FALSE;
1114    switch(type) {
1115    case NL80211_TX_POWER_AUTOMATIC:
1116        return 0;
1117    case NL80211_TX_POWER_LIMITED:
1118        ar->arTxPwr = ar_dbm = dbm;
1119        ar->arTxPwrSet = TRUE;
1120        break;
1121    default:
1122        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1123        return -EOPNOTSUPP;
1124    }
1125
1126    wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1127
1128    return 0;
1129}
1130
1131static int
1132ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1133{
1134    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1135
1136    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1137
1138    if(ar->arWmiReady == FALSE) {
1139        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1140        return -EIO;
1141    }
1142
1143    if(ar->arWlanState == WLAN_DISABLED) {
1144        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1145        return -EIO;
1146    }
1147
1148    if((ar->arConnected == TRUE)) {
1149        ar->arTxPwr = 0;
1150
1151        if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
1152            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1153            return -EIO;
1154        }
1155
1156        wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1157
1158        if(signal_pending(current)) {
1159            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1160            return -EINTR;
1161        }
1162    }
1163
1164    *dbm = ar->arTxPwr;
1165    return 0;
1166}
1167
1168static int
1169ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1170                             struct net_device *dev,
1171                             bool pmgmt, int timeout)
1172{
1173    AR_SOFTC_T *ar = ar6k_priv(dev);
1174    WMI_POWER_MODE_CMD pwrMode;
1175
1176    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1177
1178    if(ar->arWmiReady == FALSE) {
1179        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1180        return -EIO;
1181    }
1182
1183    if(ar->arWlanState == WLAN_DISABLED) {
1184        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1185        return -EIO;
1186    }
1187
1188    if(pmgmt) {
1189        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1190        pwrMode.powerMode = MAX_PERF_POWER;
1191    } else {
1192        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1193        pwrMode.powerMode = REC_POWER;
1194    }
1195
1196    if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != A_OK) {
1197        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1198        return -EIO;
1199    }
1200
1201    return 0;
1202}
1203
1204static int
1205ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1206                                            enum nl80211_iftype type, u32 *flags,
1207                                            struct vif_params *params)
1208{
1209
1210    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1211
1212    /* Multiple virtual interface is not supported.
1213     * The default interface supports STA and IBSS type
1214     */
1215    return -EOPNOTSUPP;
1216}
1217
1218static int
1219ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1220{
1221
1222    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1223
1224    /* Multiple virtual interface is not supported.
1225     * The default interface supports STA and IBSS type
1226     */
1227    return -EOPNOTSUPP;
1228}
1229
1230static int
1231ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1232                           enum nl80211_iftype type, u32 *flags,
1233                           struct vif_params *params)
1234{
1235    AR_SOFTC_T *ar = ar6k_priv(ndev);
1236    struct wireless_dev *wdev = ar->wdev;
1237
1238    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1239
1240    if(ar->arWmiReady == FALSE) {
1241        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1242        return -EIO;
1243    }
1244
1245    if(ar->arWlanState == WLAN_DISABLED) {
1246        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1247        return -EIO;
1248    }
1249
1250    switch (type) {
1251    case NL80211_IFTYPE_STATION:
1252        ar->arNextMode = INFRA_NETWORK;
1253        break;
1254    case NL80211_IFTYPE_ADHOC:
1255        ar->arNextMode = ADHOC_NETWORK;
1256        break;
1257    default:
1258        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1259        return -EOPNOTSUPP;
1260    }
1261
1262    wdev->iftype = type;
1263
1264    return 0;
1265}
1266
1267static int
1268ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1269                        struct cfg80211_ibss_params *ibss_param)
1270{
1271    AR_SOFTC_T *ar = ar6k_priv(dev);
1272    A_STATUS status;
1273
1274    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1275
1276    if(ar->arWmiReady == FALSE) {
1277        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1278        return -EIO;
1279    }
1280
1281    if(ar->arWlanState == WLAN_DISABLED) {
1282        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1283        return -EIO;
1284    }
1285
1286    if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1287        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1288        return -EINVAL;
1289    }
1290
1291    ar->arSsidLen = ibss_param->ssid_len;
1292    A_MEMCPY(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1293
1294    if(ibss_param->channel) {
1295        ar->arChannelHint = ibss_param->channel->center_freq;
1296    }
1297
1298    if(ibss_param->channel_fixed) {
1299        /* TODO: channel_fixed: The channel should be fixed, do not search for
1300         * IBSSs to join on other channels. Target firmware does not support this
1301         * feature, needs to be updated.*/
1302    }
1303
1304    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1305    if(ibss_param->bssid) {
1306        if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1307            A_MEMCPY(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1308        }
1309    }
1310
1311    ar6k_set_wpa_version(ar, 0);
1312    ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1313
1314    if(ibss_param->privacy) {
1315        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1316        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1317    } else {
1318        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1319        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1320    }
1321
1322    ar->arNetworkType = ar->arNextMode;
1323
1324    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1325                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
1326                    " GRP crypto Len %d channel hint %u\n",
1327                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
1328                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1329                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1330
1331    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1332                            ar->arDot11AuthMode, ar->arAuthMode,
1333                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1334                            ar->arGroupCrypto,ar->arGroupCryptoLen,
1335                            ar->arSsidLen, ar->arSsid,
1336                            ar->arReqBssid, ar->arChannelHint,
1337                            ar->arConnectCtrlFlags);
1338
1339    return 0;
1340}
1341
1342static int
1343ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1344{
1345    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1346
1347    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1348
1349    if(ar->arWmiReady == FALSE) {
1350        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1351        return -EIO;
1352    }
1353
1354    if(ar->arWlanState == WLAN_DISABLED) {
1355        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1356        return -EIO;
1357    }
1358
1359    wmi_disconnect_cmd(ar->arWmi);
1360    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1361    ar->arSsidLen = 0;
1362
1363    return 0;
1364}
1365
1366
1367static const
1368A_UINT32 cipher_suites[] = {
1369    WLAN_CIPHER_SUITE_WEP40,
1370    WLAN_CIPHER_SUITE_WEP104,
1371    WLAN_CIPHER_SUITE_TKIP,
1372    WLAN_CIPHER_SUITE_CCMP,
1373};
1374
1375static struct
1376cfg80211_ops ar6k_cfg80211_ops = {
1377    .change_virtual_intf = ar6k_cfg80211_change_iface,
1378    .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1379    .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1380    .scan = ar6k_cfg80211_scan,
1381    .connect = ar6k_cfg80211_connect,
1382    .disconnect = ar6k_cfg80211_disconnect,
1383    .add_key = ar6k_cfg80211_add_key,
1384    .get_key = ar6k_cfg80211_get_key,
1385    .del_key = ar6k_cfg80211_del_key,
1386    .set_default_key = ar6k_cfg80211_set_default_key,
1387    .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1388    .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1389    .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1390    .set_tx_power = ar6k_cfg80211_set_txpower,
1391    .get_tx_power = ar6k_cfg80211_get_txpower,
1392    .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1393    .join_ibss = ar6k_cfg80211_join_ibss,
1394    .leave_ibss = ar6k_cfg80211_leave_ibss,
1395};
1396
1397struct wireless_dev *
1398ar6k_cfg80211_init(struct device *dev)
1399{
1400    int ret = 0;
1401    struct wireless_dev *wdev;
1402
1403    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1404
1405    wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1406    if(!wdev) {
1407        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1408                        ("%s: Couldn't allocate wireless device\n", __func__));
1409        return ERR_PTR(-ENOMEM);
1410    }
1411
1412    /* create a new wiphy for use with cfg80211 */
1413    wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(AR_SOFTC_T));
1414    if(!wdev->wiphy) {
1415        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1416                        ("%s: Couldn't allocate wiphy device\n", __func__));
1417        kfree(wdev);
1418        return ERR_PTR(-ENOMEM);
1419    }
1420
1421    /* set device pointer for wiphy */
1422    set_wiphy_dev(wdev->wiphy, dev);
1423
1424    wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1425                                   BIT(NL80211_IFTYPE_ADHOC);
1426    /* max num of ssids that can be probed during scanning */
1427    wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1428    wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1429    wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1430    wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1431
1432    wdev->wiphy->cipher_suites = cipher_suites;
1433    wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1434
1435    ret = wiphy_register(wdev->wiphy);
1436    if(ret < 0) {
1437        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1438                        ("%s: Couldn't register wiphy device\n", __func__));
1439        wiphy_free(wdev->wiphy);
1440        return ERR_PTR(ret);
1441    }
1442
1443    return wdev;
1444}
1445
1446void
1447ar6k_cfg80211_deinit(AR_SOFTC_T *ar)
1448{
1449    struct wireless_dev *wdev = ar->wdev;
1450
1451    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1452
1453    if(ar->scan_request) {
1454        cfg80211_scan_done(ar->scan_request, true);
1455        ar->scan_request = NULL;
1456    }
1457
1458    if(!wdev)
1459        return;
1460
1461    wiphy_unregister(wdev->wiphy);
1462    wiphy_free(wdev->wiphy);
1463    kfree(wdev);
1464}
1465
1466
1467
1468
1469
1470
1471
1472