linux/drivers/staging/ath6kl/os/linux/ar6000_drv.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/*
  25 * This driver is a pseudo ethernet driver to access the Atheros AR6000
  26 * WLAN Device
  27 */
  28
  29#include "ar6000_drv.h"
  30#ifdef ATH6K_CONFIG_CFG80211
  31#include "cfg80211.h"
  32#endif /* ATH6K_CONFIG_CFG80211 */
  33#include "htc.h"
  34#include "wmi_filter_linux.h"
  35#include "epping_test.h"
  36#include "wlan_config.h"
  37#include "ar3kconfig.h"
  38#include "ar6k_pal.h"
  39#include "AR6002/addrs.h"
  40
  41
  42/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior.  When
  43 *  the meta data was added to the header it was found that linux did not correctly provide
  44 *  enough headroom.  However when more headroom was requested beyond what was truly needed
  45 *  Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
  46 *  the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
  47#define LINUX_HACK_FUDGE_FACTOR 16
  48#define BDATA_BDADDR_OFFSET     28
  49
  50A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  51A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  52
  53#ifdef DEBUG
  54
  55#define  ATH_DEBUG_DBG_LOG       ATH_DEBUG_MAKE_MODULE_MASK(0)
  56#define  ATH_DEBUG_WLAN_CONNECT  ATH_DEBUG_MAKE_MODULE_MASK(1)
  57#define  ATH_DEBUG_WLAN_SCAN     ATH_DEBUG_MAKE_MODULE_MASK(2)
  58#define  ATH_DEBUG_WLAN_TX       ATH_DEBUG_MAKE_MODULE_MASK(3)
  59#define  ATH_DEBUG_WLAN_RX       ATH_DEBUG_MAKE_MODULE_MASK(4)
  60#define  ATH_DEBUG_HTC_RAW       ATH_DEBUG_MAKE_MODULE_MASK(5)
  61#define  ATH_DEBUG_HCI_BRIDGE    ATH_DEBUG_MAKE_MODULE_MASK(6)
  62
  63static ATH_DEBUG_MASK_DESCRIPTION driver_debug_desc[] = {
  64    { ATH_DEBUG_DBG_LOG      , "Target Debug Logs"},
  65    { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
  66    { ATH_DEBUG_WLAN_SCAN    , "WLAN scan"},
  67    { ATH_DEBUG_WLAN_TX      , "WLAN Tx"},
  68    { ATH_DEBUG_WLAN_RX      , "WLAN Rx"},
  69    { ATH_DEBUG_HTC_RAW      , "HTC Raw IF tracing"},
  70    { ATH_DEBUG_HCI_BRIDGE   , "HCI Bridge Setup"},
  71    { ATH_DEBUG_HCI_RECV     , "HCI Recv tracing"},
  72    { ATH_DEBUG_HCI_DUMP     , "HCI Packet dumps"},
  73};
  74
  75ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
  76                                 "driver",
  77                                 "Linux Driver Interface",
  78                                 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
  79                                 ATH_DEBUG_HCI_BRIDGE,
  80                                 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
  81                                 driver_debug_desc);
  82
  83#endif
  84
  85
  86#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
  87#define IS_MAC_BCAST(mac) (*mac==0xff)
  88
  89#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
  90
  91MODULE_AUTHOR("Atheros Communications, Inc.");
  92MODULE_DESCRIPTION(DESCRIPTION);
  93MODULE_LICENSE("Dual BSD/GPL");
  94
  95#ifndef REORG_APTC_HEURISTICS
  96#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
  97#endif /* REORG_APTC_HEURISTICS */
  98
  99#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 100#define APTC_TRAFFIC_SAMPLING_INTERVAL     100  /* msec */
 101#define APTC_UPPER_THROUGHPUT_THRESHOLD    3000 /* Kbps */
 102#define APTC_LOWER_THROUGHPUT_THRESHOLD    2000 /* Kbps */
 103
 104typedef struct aptc_traffic_record {
 105    A_BOOL timerScheduled;
 106    struct timeval samplingTS;
 107    unsigned long bytesReceived;
 108    unsigned long bytesTransmitted;
 109} APTC_TRAFFIC_RECORD;
 110
 111A_TIMER aptcTimer;
 112APTC_TRAFFIC_RECORD aptcTR;
 113#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 114
 115#ifdef EXPORT_HCI_BRIDGE_INTERFACE
 116// callbacks registered by HCI transport driver
 117HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks = { NULL };
 118#endif
 119
 120unsigned int processDot11Hdr = 0;
 121int bmienable = BMIENABLE_DEFAULT;
 122
 123char ifname[IFNAMSIZ] = {0,};
 124
 125int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
 126unsigned int bypasswmi = 0;
 127unsigned int debuglevel = 0;
 128int tspecCompliance = ATHEROS_COMPLIANCE;
 129unsigned int busspeedlow = 0;
 130unsigned int onebitmode = 0;
 131unsigned int skipflash = 0;
 132unsigned int wmitimeout = 2;
 133unsigned int wlanNodeCaching = 1;
 134unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
 135unsigned int logWmiRawMsgs = 0;
 136unsigned int enabletimerwar = 0;
 137unsigned int fwmode = 1;
 138unsigned int mbox_yield_limit = 99;
 139unsigned int enablerssicompensation = 0;
 140int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
 141int allow_trace_signal = 0;
 142#ifdef CONFIG_HOST_TCMD_SUPPORT
 143unsigned int testmode =0;
 144#endif
 145
 146unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
 147unsigned int panic_on_assert = 1;
 148unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
 149
 150unsigned int setuphci = SETUPHCI_DEFAULT;
 151unsigned int setuphcipal = SETUPHCIPAL_DEFAULT;
 152unsigned int loghci = 0;
 153unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
 154#ifndef EXPORT_HCI_BRIDGE_INTERFACE
 155unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
 156unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
 157unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
 158#endif
 159#ifdef CONFIG_CHECKSUM_OFFLOAD
 160unsigned int csumOffload=0;
 161unsigned int csumOffloadTest=0;
 162#endif
 163unsigned int eppingtest=0;
 164
 165module_param_string(ifname, ifname, sizeof(ifname), 0644);
 166module_param(wlaninitmode, int, 0644);
 167module_param(bmienable, int, 0644);
 168module_param(bypasswmi, uint, 0644);
 169module_param(debuglevel, uint, 0644);
 170module_param(tspecCompliance, int, 0644);
 171module_param(onebitmode, uint, 0644);
 172module_param(busspeedlow, uint, 0644);
 173module_param(skipflash, uint, 0644);
 174module_param(wmitimeout, uint, 0644);
 175module_param(wlanNodeCaching, uint, 0644);
 176module_param(logWmiRawMsgs, uint, 0644);
 177module_param(enableuartprint, uint, 0644);
 178module_param(enabletimerwar, uint, 0644);
 179module_param(fwmode, uint, 0644);
 180module_param(mbox_yield_limit, uint, 0644);
 181module_param(reduce_credit_dribble, int, 0644);
 182module_param(allow_trace_signal, int, 0644);
 183module_param(enablerssicompensation, uint, 0644);
 184module_param(processDot11Hdr, uint, 0644);
 185#ifdef CONFIG_CHECKSUM_OFFLOAD
 186module_param(csumOffload, uint, 0644);
 187#endif
 188#ifdef CONFIG_HOST_TCMD_SUPPORT
 189module_param(testmode, uint, 0644);
 190#endif
 191module_param(irqprocmode, uint, 0644);
 192module_param(nohifscattersupport, uint, 0644);
 193module_param(panic_on_assert, uint, 0644);
 194module_param(setuphci, uint, 0644);
 195module_param(setuphcipal, uint, 0644);
 196module_param(loghci, uint, 0644);
 197module_param(setupbtdev, uint, 0644);
 198#ifndef EXPORT_HCI_BRIDGE_INTERFACE
 199module_param(ar3khcibaud, uint, 0644);
 200module_param(hciuartscale, uint, 0644);
 201module_param(hciuartstep, uint, 0644);
 202#endif
 203module_param(eppingtest, uint, 0644);
 204
 205/* in 2.6.10 and later this is now a pointer to a uint */
 206unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
 207#define mboxnum &_mboxnum
 208
 209#ifdef DEBUG
 210A_UINT32 g_dbg_flags = DBG_DEFAULTS;
 211unsigned int debugflags = 0;
 212int debugdriver = 0;
 213unsigned int debughtc = 0;
 214unsigned int debugbmi = 0;
 215unsigned int debughif = 0;
 216unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
 217unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
 218unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
 219unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
 220module_param(debugflags, uint, 0644);
 221module_param(debugdriver, int, 0644);
 222module_param(debughtc, uint, 0644);
 223module_param(debugbmi, uint, 0644);
 224module_param(debughif, uint, 0644);
 225module_param_array(txcreditsavailable, uint, mboxnum, 0644);
 226module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
 227module_param_array(txcreditintrenable, uint, mboxnum, 0644);
 228module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
 229
 230#endif /* DEBUG */
 231
 232unsigned int resetok = 1;
 233unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
 234unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
 235unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
 236unsigned int hifBusRequestNumMax = 40;
 237unsigned int war23838_disabled = 0;
 238#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 239unsigned int enableAPTCHeuristics = 1;
 240#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 241module_param_array(tx_attempt, uint, mboxnum, 0644);
 242module_param_array(tx_post, uint, mboxnum, 0644);
 243module_param_array(tx_complete, uint, mboxnum, 0644);
 244module_param(hifBusRequestNumMax, uint, 0644);
 245module_param(war23838_disabled, uint, 0644);
 246module_param(resetok, uint, 0644);
 247#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 248module_param(enableAPTCHeuristics, uint, 0644);
 249#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 250
 251#ifdef BLOCK_TX_PATH_FLAG
 252int blocktx = 0;
 253module_param(blocktx, int, 0644);
 254#endif /* BLOCK_TX_PATH_FLAG */
 255
 256typedef struct user_rssi_compensation_t {
 257    A_UINT16         customerID;
 258    union {
 259    A_UINT16         a_enable;
 260    A_UINT16         bg_enable;
 261    A_UINT16         enable;
 262    };
 263    A_INT16          bg_param_a;
 264    A_INT16          bg_param_b;
 265    A_INT16          a_param_a;
 266    A_INT16          a_param_b;
 267    A_UINT32         reserved;
 268} USER_RSSI_CPENSATION;
 269
 270static USER_RSSI_CPENSATION rssi_compensation_param;
 271
 272static A_INT16 rssi_compensation_table[96];
 273
 274int reconnect_flag = 0;
 275static ar6k_pal_config_t ar6k_pal_config_g;
 276
 277/* Function declarations */
 278static int ar6000_init_module(void);
 279static void ar6000_cleanup_module(void);
 280
 281int ar6000_init(struct net_device *dev);
 282static int ar6000_open(struct net_device *dev);
 283static int ar6000_close(struct net_device *dev);
 284static void ar6000_init_control_info(AR_SOFTC_T *ar);
 285static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
 286
 287void ar6000_destroy(struct net_device *dev, unsigned int unregister);
 288static void ar6000_detect_error(unsigned long ptr);
 289static void     ar6000_set_multicast_list(struct net_device *dev);
 290static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
 291static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev);
 292
 293static void disconnect_timer_handler(unsigned long ptr);
 294
 295void read_rssi_compensation_param(AR_SOFTC_T *ar);
 296
 297    /* for android builds we call external APIs that handle firmware download and configuration */
 298#ifdef ANDROID_ENV
 299/* !!!! Interim android support to make it easier to patch the default driver for
 300 * android use. You must define an external source file ar6000_android.c that handles the following
 301 * APIs */
 302extern void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks);
 303extern void android_module_exit(void);
 304#endif
 305/*
 306 * HTC service connection handlers
 307 */
 308static A_STATUS ar6000_avail_ev(void *context, void *hif_handle);
 309
 310static A_STATUS ar6000_unavail_ev(void *context, void *hif_handle);
 311
 312A_STATUS ar6000_configure_target(AR_SOFTC_T *ar);
 313
 314static void ar6000_target_failure(void *Instance, A_STATUS Status);
 315
 316static void ar6000_rx(void *Context, HTC_PACKET *pPacket);
 317
 318static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
 319
 320static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets);
 321
 322static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket);
 323
 324#ifdef ATH_AR6K_11N_SUPPORT
 325static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num);
 326#endif
 327static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
 328//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
 329
 330static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
 331
 332static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count);
 333
 334static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar);
 335
 336static ssize_t
 337ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
 338                      struct bin_attribute *bin_attr,
 339                      char *buf, loff_t pos, size_t count);
 340
 341static ssize_t
 342ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
 343                       struct bin_attribute *bin_attr,
 344                       char *buf, loff_t pos, size_t count);
 345
 346static A_STATUS
 347ar6000_sysfs_bmi_init(AR_SOFTC_T *ar);
 348
 349/* HCI PAL callback function declarations */
 350A_STATUS ar6k_setup_hci_pal(AR_SOFTC_T *ar);
 351void  ar6k_cleanup_hci_pal(AR_SOFTC_T *ar);
 352
 353static void
 354ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar);
 355
 356A_STATUS
 357ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode);
 358
 359/*
 360 * Static variables
 361 */
 362
 363struct net_device *ar6000_devices[MAX_AR6000];
 364static int is_netdev_registered;
 365extern struct iw_handler_def ath_iw_handler_def;
 366DECLARE_WAIT_QUEUE_HEAD(arEvent);
 367static void ar6000_cookie_init(AR_SOFTC_T *ar);
 368static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);
 369static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);
 370static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);
 371
 372#ifdef USER_KEYS
 373static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl);
 374#endif
 375
 376#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
 377struct net_device *arApNetDev;
 378#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
 379
 380static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
 381
 382#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
 383        (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
 384        (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
 385
 386
 387static struct net_device_ops ar6000_netdev_ops = {
 388    .ndo_init               = NULL,
 389    .ndo_open               = ar6000_open,
 390    .ndo_stop               = ar6000_close,
 391    .ndo_get_stats          = ar6000_get_stats,
 392    .ndo_do_ioctl           = ar6000_ioctl,
 393    .ndo_start_xmit         = ar6000_data_tx,
 394    .ndo_set_multicast_list = ar6000_set_multicast_list,
 395};
 396
 397/* Debug log support */
 398
 399/*
 400 * Flag to govern whether the debug logs should be parsed in the kernel
 401 * or reported to the application.
 402 */
 403#define REPORT_DEBUG_LOGS_TO_APP
 404
 405A_STATUS
 406ar6000_set_host_app_area(AR_SOFTC_T *ar)
 407{
 408    A_UINT32 address, data;
 409    struct host_app_area_s host_app_area;
 410
 411    /* Fetch the address of the host_app_area_s instance in the host interest area */
 412    address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
 413    if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) {
 414        return A_ERROR;
 415    }
 416    address = TARG_VTOP(ar->arTargetType, data);
 417    host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
 418    if (ar6000_WriteDataDiag(ar->arHifDevice, address,
 419                             (A_UCHAR *)&host_app_area,
 420                             sizeof(struct host_app_area_s)) != A_OK)
 421    {
 422        return A_ERROR;
 423    }
 424
 425    return A_OK;
 426}
 427
 428A_UINT32
 429dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar)
 430{
 431    A_UINT32 param;
 432    A_UINT32 address;
 433    A_STATUS status;
 434
 435    address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
 436    if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
 437                                      (A_UCHAR *)&param, 4)) != A_OK)
 438    {
 439        param = 0;
 440    }
 441
 442    return param;
 443}
 444
 445/*
 446 * The dbglog module has been initialized. Its ok to access the relevant
 447 * data stuctures over the diagnostic window.
 448 */
 449void
 450ar6000_dbglog_init_done(AR_SOFTC_T *ar)
 451{
 452    ar->dbglog_init_done = TRUE;
 453}
 454
 455A_UINT32
 456dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit)
 457{
 458    A_INT32 *buffer;
 459    A_UINT32 count;
 460    A_UINT32 numargs;
 461    A_UINT32 length;
 462    A_UINT32 fraglen;
 463
 464    count = fraglen = 0;
 465    buffer = (A_INT32 *)datap;
 466    length = (limit >> 2);
 467
 468    if (len <= limit) {
 469        fraglen = len;
 470    } else {
 471        while (count < length) {
 472            numargs = DBGLOG_GET_NUMARGS(buffer[count]);
 473            fraglen = (count << 2);
 474            count += numargs + 1;
 475        }
 476    }
 477
 478    return fraglen;
 479}
 480
 481void
 482dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len)
 483{
 484    A_INT32 *buffer;
 485    A_UINT32 count;
 486    A_UINT32 timestamp;
 487    A_UINT32 debugid;
 488    A_UINT32 moduleid;
 489    A_UINT32 numargs;
 490    A_UINT32 length;
 491
 492    count = 0;
 493    buffer = (A_INT32 *)datap;
 494    length = (len >> 2);
 495    while (count < length) {
 496        debugid = DBGLOG_GET_DBGID(buffer[count]);
 497        moduleid = DBGLOG_GET_MODULEID(buffer[count]);
 498        numargs = DBGLOG_GET_NUMARGS(buffer[count]);
 499        timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
 500        switch (numargs) {
 501            case 0:
 502            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
 503            break;
 504
 505            case 1:
 506            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
 507                            timestamp, buffer[count+1]));
 508            break;
 509
 510            case 2:
 511            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
 512                            timestamp, buffer[count+1], buffer[count+2]));
 513            break;
 514
 515            default:
 516            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
 517        }
 518        count += numargs + 1;
 519    }
 520}
 521
 522int
 523ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar)
 524{
 525    A_UINT32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */
 526    A_UINT32 address;
 527    A_UINT32 length;
 528    A_UINT32 dropped;
 529    A_UINT32 firstbuf;
 530    A_UINT32 debug_hdr_ptr;
 531
 532    if (!ar->dbglog_init_done) return A_ERROR;
 533
 534
 535    AR6000_SPIN_LOCK(&ar->arLock, 0);
 536
 537    if (ar->dbgLogFetchInProgress) {
 538        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 539        return A_EBUSY;
 540    }
 541
 542        /* block out others */
 543    ar->dbgLogFetchInProgress = TRUE;
 544
 545    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 546
 547    debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
 548    printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
 549
 550    /* Get the contents of the ring buffer */
 551    if (debug_hdr_ptr) {
 552        address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
 553        length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
 554        A_MEMZERO(data, sizeof(data));
 555        ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)data, length);
 556        address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
 557        firstbuf = address;
 558        dropped = data[1]; /* dropped */
 559        length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
 560        A_MEMZERO(data, sizeof(data));
 561        ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&data, length);
 562
 563        do {
 564            address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
 565            length = data[3]; /* length */
 566            if ((length) && (length <= data[2] /* bufsize*/)) {
 567                /* Rewind the index if it is about to overrun the buffer */
 568                if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
 569                    ar->log_cnt = 0;
 570                }
 571                if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
 572                                    (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length))
 573                {
 574                    break;
 575                }
 576                ar6000_dbglog_event(ar, dropped, (A_INT8*)&ar->log_buffer[ar->log_cnt], length);
 577                ar->log_cnt += length;
 578            } else {
 579                AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
 580                                data[3], data[2]));
 581            }
 582
 583            address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
 584            length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
 585            A_MEMZERO(data, sizeof(data));
 586            if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
 587                                (A_UCHAR *)&data, length))
 588            {
 589                break;
 590            }
 591
 592        } while (address != firstbuf);
 593    }
 594
 595    ar->dbgLogFetchInProgress = FALSE;
 596
 597    return A_OK;
 598}
 599
 600void
 601ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped,
 602                    A_INT8 *buffer, A_UINT32 length)
 603{
 604#ifdef REPORT_DEBUG_LOGS_TO_APP
 605    #define MAX_WIRELESS_EVENT_SIZE 252
 606    /*
 607     * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
 608     * There seems to be a limitation on the length of message that could be
 609     * transmitted to the user app via this mechanism.
 610     */
 611    A_UINT32 send, sent;
 612
 613    sent = 0;
 614    send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
 615                                     MAX_WIRELESS_EVENT_SIZE);
 616    while (send) {
 617        ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (A_UINT8*)&buffer[sent], send);
 618        sent += send;
 619        send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
 620                                         MAX_WIRELESS_EVENT_SIZE);
 621    }
 622#else
 623    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
 624                    dropped, length));
 625
 626    /* Interpret the debug logs */
 627    dbglog_parse_debug_logs((A_INT8*)buffer, length);
 628#endif /* REPORT_DEBUG_LOGS_TO_APP */
 629}
 630
 631
 632static int __init
 633ar6000_init_module(void)
 634{
 635    static int probed = 0;
 636    A_STATUS status;
 637    OSDRV_CALLBACKS osdrvCallbacks;
 638
 639    a_module_debug_support_init();
 640
 641#ifdef DEBUG
 642        /* check for debug mask overrides */
 643    if (debughtc != 0) {
 644        ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
 645    }
 646    if (debugbmi != 0) {
 647        ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
 648    }
 649    if (debughif != 0) {
 650        ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
 651    }
 652    if (debugdriver != 0) {
 653        ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
 654    }
 655
 656#endif
 657
 658    A_REGISTER_MODULE_DEBUG_INFO(driver);
 659
 660    A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
 661    osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
 662    osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
 663#ifdef CONFIG_PM
 664    osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
 665    osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
 666    osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
 667#endif
 668
 669    ar6000_pm_init();
 670
 671#ifdef ANDROID_ENV
 672    android_module_init(&osdrvCallbacks);
 673#endif
 674
 675#ifdef DEBUG
 676    /* Set the debug flags if specified at load time */
 677    if(debugflags != 0)
 678    {
 679        g_dbg_flags = debugflags;
 680    }
 681#endif
 682
 683    if (probed) {
 684        return -ENODEV;
 685    }
 686    probed++;
 687
 688#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 689    memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
 690#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 691
 692#ifdef CONFIG_HOST_GPIO_SUPPORT
 693    ar6000_gpio_init();
 694#endif /* CONFIG_HOST_GPIO_SUPPORT */
 695
 696    status = HIFInit(&osdrvCallbacks);
 697    if(status != A_OK)
 698        return -ENODEV;
 699
 700    return 0;
 701}
 702
 703static void __exit
 704ar6000_cleanup_module(void)
 705{
 706    int i = 0;
 707    struct net_device *ar6000_netdev;
 708
 709#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 710    /* Delete the Adaptive Power Control timer */
 711    if (timer_pending(&aptcTimer)) {
 712        del_timer_sync(&aptcTimer);
 713    }
 714#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 715
 716    for (i=0; i < MAX_AR6000; i++) {
 717        if (ar6000_devices[i] != NULL) {
 718            ar6000_netdev = ar6000_devices[i];
 719            ar6000_devices[i] = NULL;
 720            ar6000_destroy(ar6000_netdev, 1);
 721        }
 722    }
 723
 724    HIFShutDownDevice(NULL);
 725
 726    a_module_debug_support_cleanup();
 727
 728    ar6000_pm_exit();
 729
 730#ifdef ANDROID_ENV    
 731    android_module_exit();
 732#endif
 733
 734    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
 735}
 736
 737#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
 738void
 739aptcTimerHandler(unsigned long arg)
 740{
 741    A_UINT32 numbytes;
 742    A_UINT32 throughput;
 743    AR_SOFTC_T *ar;
 744    A_STATUS status;
 745
 746    ar = (AR_SOFTC_T *)arg;
 747    A_ASSERT(ar != NULL);
 748    A_ASSERT(!timer_pending(&aptcTimer));
 749
 750    AR6000_SPIN_LOCK(&ar->arLock, 0);
 751
 752    /* Get the number of bytes transferred */
 753    numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
 754    aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
 755
 756    /* Calculate and decide based on throughput thresholds */
 757    throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
 758    if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
 759        /* Enable Sleep and delete the timer */
 760        A_ASSERT(ar->arWmiReady == TRUE);
 761        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 762        status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
 763        AR6000_SPIN_LOCK(&ar->arLock, 0);
 764        A_ASSERT(status == A_OK);
 765        aptcTR.timerScheduled = FALSE;
 766    } else {
 767        A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
 768    }
 769
 770    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
 771}
 772#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 773
 774#ifdef ATH_AR6K_11N_SUPPORT
 775static void
 776ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num)
 777{
 778    void * osbuf;
 779
 780    while(num) {
 781        if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
 782            A_NETBUF_ENQUEUE(q, osbuf);
 783        } else {
 784            break;
 785        }
 786        num--;
 787    }
 788
 789    if(num) {
 790        A_PRINTF("%s(), allocation of netbuf failed", __func__);
 791    }
 792}
 793#endif
 794
 795static struct bin_attribute bmi_attr = {
 796    .attr = {.name = "bmi", .mode = 0600},
 797    .read = ar6000_sysfs_bmi_read,
 798    .write = ar6000_sysfs_bmi_write,
 799};
 800
 801static ssize_t
 802ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
 803                      struct bin_attribute *bin_attr,
 804                      char *buf, loff_t pos, size_t count)
 805{
 806    int index;
 807    AR_SOFTC_T *ar;
 808    HIF_DEVICE_OS_DEVICE_INFO   *osDevInfo;
 809
 810    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (A_UINT32)count));
 811    for (index=0; index < MAX_AR6000; index++) {
 812        ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
 813        osDevInfo = &ar->osDevInfo;
 814        if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
 815            break;
 816        }
 817    }
 818
 819    if (index == MAX_AR6000) return 0;
 820
 821    if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, TRUE)) != A_OK) {
 822        return 0;
 823    }
 824
 825    return count;
 826}
 827
 828static ssize_t
 829ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
 830                       struct bin_attribute *bin_attr,
 831                       char *buf, loff_t pos, size_t count)
 832{
 833    int index;
 834    AR_SOFTC_T *ar;
 835    HIF_DEVICE_OS_DEVICE_INFO   *osDevInfo;
 836
 837    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (A_UINT32)count));
 838    for (index=0; index < MAX_AR6000; index++) {
 839        ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
 840        osDevInfo = &ar->osDevInfo;
 841        if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
 842            break;
 843        }
 844    }
 845
 846    if (index == MAX_AR6000) return 0;
 847
 848    if ((BMIRawWrite(ar->arHifDevice, (A_UCHAR*)buf, count)) != A_OK) {
 849        return 0;
 850    }
 851
 852    return count;
 853}
 854
 855static A_STATUS
 856ar6000_sysfs_bmi_init(AR_SOFTC_T *ar)
 857{
 858    A_STATUS status;
 859
 860    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
 861    A_MEMZERO(&ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO));
 862
 863    /* Get the underlying OS device */
 864    status = HIFConfigureDevice(ar->arHifDevice,
 865                                HIF_DEVICE_GET_OS_DEVICE,
 866                                &ar->osDevInfo,
 867                                sizeof(HIF_DEVICE_OS_DEVICE_INFO));
 868
 869    if (A_FAILED(status)) {
 870        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
 871        return A_ERROR;
 872    }
 873
 874    /* Create a bmi entry in the sysfs filesystem */
 875    if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
 876    {
 877        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
 878        return A_ERROR;
 879    }
 880
 881    return A_OK;
 882}
 883
 884static void
 885ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar)
 886{
 887    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
 888
 889    sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
 890}
 891
 892#define bmifn(fn) do { \
 893    if ((fn) < A_OK) { \
 894        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
 895        return A_ERROR; \
 896    } \
 897} while(0)
 898
 899#ifdef INIT_MODE_DRV_ENABLED
 900
 901#ifdef SOFTMAC_FILE_USED
 902#define AR6002_MAC_ADDRESS_OFFSET     0x0A
 903#define AR6003_MAC_ADDRESS_OFFSET     0x16
 904static
 905void calculate_crc(A_UINT32 TargetType, A_UCHAR *eeprom_data)
 906{
 907    A_UINT16        *ptr_crc;
 908    A_UINT16        *ptr16_eeprom;
 909    A_UINT16        checksum;
 910    A_UINT32        i;
 911    A_UINT32        eeprom_size;
 912
 913    if (TargetType == TARGET_TYPE_AR6001)
 914    {
 915        eeprom_size = 512;
 916        ptr_crc = (A_UINT16 *)eeprom_data;
 917    }
 918    else if (TargetType == TARGET_TYPE_AR6003)
 919    {
 920        eeprom_size = 1024;
 921        ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04);
 922    }
 923    else
 924    {
 925        eeprom_size = 768;
 926        ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04);
 927    }
 928
 929
 930    // Clear the crc
 931    *ptr_crc = 0;
 932
 933    // Recalculate new CRC
 934    checksum = 0;
 935    ptr16_eeprom = (A_UINT16 *)eeprom_data;
 936    for (i = 0;i < eeprom_size; i += 2)
 937    {
 938        checksum = checksum ^ (*ptr16_eeprom);
 939        ptr16_eeprom++;
 940    }
 941    checksum = 0xFFFF ^ checksum;
 942    *ptr_crc = checksum;
 943}
 944
 945static void 
 946ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size)
 947{
 948    const char *source = "random generated";
 949    const struct firmware *softmac_entry;
 950    A_UCHAR *ptr_mac;
 951    switch (ar->arTargetType) {
 952    case TARGET_TYPE_AR6002:
 953        ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
 954        break;
 955    case TARGET_TYPE_AR6003:
 956        ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
 957        break;
 958    default:
 959        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n"));
 960        return;
 961    }
 962        printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac);
 963
 964    /* create a random MAC in case we cannot read file from system */
 965    ptr_mac[0] = 0;
 966    ptr_mac[1] = 0x03;
 967    ptr_mac[2] = 0x7F;
 968    ptr_mac[3] = random32() & 0xff; 
 969    ptr_mac[4] = random32() & 0xff; 
 970    ptr_mac[5] = random32() & 0xff; 
 971    if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
 972    {
 973        A_CHAR *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
 974        if (macbuf) {            
 975            unsigned int softmac[6];
 976            memcpy(macbuf, softmac_entry->data, softmac_entry->size);
 977            macbuf[softmac_entry->size] = '\0';
 978            if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x", 
 979                        &softmac[0], &softmac[1], &softmac[2],
 980                        &softmac[3], &softmac[4], &softmac[5])==6) {
 981                int i;
 982                for (i=0; i<6; ++i) {
 983                    ptr_mac[i] = softmac[i] & 0xff;
 984                }
 985                source = "softmac file";
 986            }
 987            A_FREE(macbuf);
 988        }
 989        A_RELEASE_FIRMWARE(softmac_entry);
 990    }
 991        printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac);
 992   calculate_crc(ar->arTargetType, eeprom_data);
 993}
 994#endif /* SOFTMAC_FILE_USED */
 995
 996static A_STATUS
 997ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A_BOOL compressed)
 998{
 999    A_STATUS status;
1000    const char *filename;
1001    const struct firmware *fw_entry;
1002    A_UINT32 fw_entry_size;
1003
1004    switch (file) {
1005        case AR6K_OTP_FILE:
1006            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1007                filename = AR6003_REV1_OTP_FILE;
1008            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1009                filename = AR6003_REV2_OTP_FILE;
1010            } else {
1011                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1012                return A_ERROR;
1013            }
1014            break;
1015
1016        case AR6K_FIRMWARE_FILE:
1017            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1018                filename = AR6003_REV1_FIRMWARE_FILE;
1019            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1020                filename = AR6003_REV2_FIRMWARE_FILE;
1021            } else {
1022                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1023                return A_ERROR;
1024            }
1025            
1026            if (eppingtest) {
1027                bypasswmi = TRUE;    
1028                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1029                    filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
1030                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1031                    filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
1032                } else {
1033                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n", 
1034                        ar->arVersion.target_ver));
1035                    return A_ERROR;
1036                }
1037                compressed = 0;
1038            }
1039            
1040#ifdef CONFIG_HOST_TCMD_SUPPORT
1041            if(testmode) {
1042                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1043                    filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
1044                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1045                    filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
1046                } else {
1047                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1048                    return A_ERROR;
1049                }
1050                compressed = 0;
1051            }
1052#endif 
1053#ifdef HTC_RAW_INTERFACE
1054            if (!eppingtest && bypasswmi) {
1055                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1056                    filename = AR6003_REV1_ART_FIRMWARE_FILE;
1057                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1058                    filename = AR6003_REV2_ART_FIRMWARE_FILE;
1059                } else {
1060                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1061                    return A_ERROR;
1062                }
1063                compressed = 0;                
1064            }
1065#endif 
1066            break;
1067
1068        case AR6K_PATCH_FILE:
1069            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1070                filename = AR6003_REV1_PATCH_FILE;
1071            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1072                filename = AR6003_REV2_PATCH_FILE;
1073            } else {
1074                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1075                return A_ERROR;
1076            }
1077            break;
1078
1079        case AR6K_BOARD_DATA_FILE:
1080            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1081                filename = AR6003_REV1_BOARD_DATA_FILE;
1082            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1083                filename = AR6003_REV2_BOARD_DATA_FILE;
1084            } else {
1085                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1086                return A_ERROR;
1087            }
1088            break;
1089
1090        default:
1091            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
1092            return A_ERROR;
1093    }
1094    if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
1095    {
1096        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
1097        return A_ENOENT;
1098    }
1099
1100#ifdef SOFTMAC_FILE_USED
1101    if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) {
1102        ar6000_softmac_update(ar, (A_UCHAR *)fw_entry->data, fw_entry->size);
1103    }
1104#endif 
1105
1106
1107    fw_entry_size = fw_entry->size;
1108
1109    /* Load extended board data for AR6003 */
1110    if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) {
1111        A_UINT32 board_ext_address;
1112        A_UINT32 board_ext_data_size;
1113        A_UINT32 board_data_size;
1114
1115        board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
1116                               (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
1117
1118        board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
1119                          (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
1120        
1121        /* Determine where in Target RAM to write Board Data */
1122        bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (A_UCHAR *)&board_ext_address, 4));
1123        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
1124
1125        /* check whether the target has allocated memory for extended board data and file contains extended board data */
1126        if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) {
1127            A_UINT32 param;
1128
1129            status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size);
1130
1131            if (status != A_OK) {
1132                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1133                A_RELEASE_FIRMWARE(fw_entry);
1134                return A_ERROR;
1135            }
1136
1137            /* Record the fact that extended board Data IS initialized */
1138            param = 1;
1139            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (A_UCHAR *)&param, 4));
1140        }
1141        fw_entry_size = board_data_size;
1142    }
1143
1144    if (compressed) {
1145        status = BMIFastDownload(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size);
1146    } else {
1147        status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size);
1148    }
1149
1150    if (status != A_OK) {
1151        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1152        A_RELEASE_FIRMWARE(fw_entry);
1153        return A_ERROR;
1154    }
1155    A_RELEASE_FIRMWARE(fw_entry);
1156    return A_OK;
1157}
1158#endif /* INIT_MODE_DRV_ENABLED */
1159
1160A_STATUS
1161ar6000_update_bdaddr(AR_SOFTC_T *ar)
1162{
1163
1164        if (setupbtdev != 0) {
1165            A_UINT32 address;
1166
1167           if (BMIReadMemory(ar->arHifDevice,
1168                HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != A_OK)
1169           {
1170                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
1171                return A_ERROR;
1172           }
1173
1174           if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (A_UCHAR *)ar->bdaddr, 6) != A_OK)
1175           {
1176                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
1177                return A_ERROR;
1178           }
1179           AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
1180                                                                ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
1181                                                                ar->bdaddr[4], ar->bdaddr[5]));
1182        }
1183
1184return A_OK;
1185}
1186
1187A_STATUS
1188ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode)
1189{
1190    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
1191
1192    if (mode == WLAN_INIT_MODE_UDEV) {
1193        A_CHAR version[16];
1194        const struct firmware *fw_entry;
1195
1196        /* Get config using udev through a script in user space */
1197        sprintf(version, "%2.2x", ar->arVersion.target_ver);
1198        if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
1199        {
1200            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
1201            return A_ERROR;
1202        }
1203
1204        A_RELEASE_FIRMWARE(fw_entry);
1205#ifdef INIT_MODE_DRV_ENABLED
1206    } else {
1207        /* The config is contained within the driver itself */
1208        A_STATUS status;
1209        A_UINT32 param, options, sleep, address;
1210
1211        /* Temporarily disable system sleep */
1212        address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1213        bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1214        options = param;
1215        param |= AR6K_OPTION_SLEEP_DISABLE;
1216        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1217
1218        address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1219        bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1220        sleep = param;
1221        param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
1222        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1223        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
1224
1225        if (ar->arTargetType == TARGET_TYPE_AR6003) {
1226            /* Program analog PLL register */
1227            bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
1228            /* Run at 80/88MHz by default */
1229            param = CPU_CLOCK_STANDARD_SET(1);
1230        } else {
1231            /* Run at 40/44MHz by default */
1232            param = CPU_CLOCK_STANDARD_SET(0);
1233        }
1234        address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1235        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1236
1237        param = 0;
1238        if (ar->arTargetType == TARGET_TYPE_AR6002) {
1239            bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)&param, 4));
1240        }
1241
1242        /* LPO_CAL.ENABLE = 1 if no external clk is detected */
1243        if (param != 1) {
1244            address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1245            param = LPO_CAL_ENABLE_SET(1);
1246            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1247        }
1248
1249        /* Venus2.0: Lower SDIO pad drive strength,
1250         * temporary WAR to avoid SDIO CRC error */
1251        if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1252            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
1253            param = 0x20;
1254            address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1255            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1256
1257            address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1258            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1259
1260            address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1261            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1262
1263            address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1264            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1265        }
1266
1267#ifdef FORCE_INTERNAL_CLOCK
1268        /* Ignore external clock, if any, and force use of internal clock */
1269        if (ar->arTargetType == TARGET_TYPE_AR6003) {
1270            /* hi_ext_clk_detected = 0 */
1271            param = 0;
1272            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)&param, 4));
1273
1274            /* CLOCK_CONTROL &= ~LF_CLK32 */
1275            address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
1276            bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1277            param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
1278            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1279        }
1280#endif /* FORCE_INTERNAL_CLOCK */
1281
1282        /* Transfer Board Data from Target EEPROM to Target RAM */
1283        if (ar->arTargetType == TARGET_TYPE_AR6003) {
1284            /* Determine where in Target RAM to write Board Data */
1285            bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4));
1286            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
1287
1288            /* Write EEPROM data to Target RAM */
1289            if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, FALSE)) != A_OK) {
1290                return A_ERROR;
1291            }
1292
1293            /* Record the fact that Board Data IS initialized */
1294            param = 1;
1295            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (A_UCHAR *)&param, 4));
1296
1297            /* Transfer One time Programmable data */
1298            AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
1299            status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, TRUE);
1300            if (status == A_OK) {
1301                /* Execute the OTP code */
1302                param = 0;
1303                AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1304                bmifn(BMIExecute(ar->arHifDevice, address, &param));
1305            } else if (status != A_ENOENT) {
1306                return A_ERROR;
1307            } 
1308        } else {
1309            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
1310            return A_ERROR;
1311        }
1312
1313        /* Download Target firmware */
1314        AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
1315        if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, TRUE)) != A_OK) {
1316            return A_ERROR;
1317        }
1318
1319        /* Set starting address for firmware */
1320        AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1321        bmifn(BMISetAppStart(ar->arHifDevice, address));
1322
1323        /* Apply the patches */
1324        AR6K_PATCH_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
1325        if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, FALSE)) != A_OK) {
1326            return A_ERROR;
1327        }
1328
1329        param = address;
1330        bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), (A_UCHAR *)&param, 4));
1331
1332        if (ar->arTargetType == TARGET_TYPE_AR6003) {
1333            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1334                /* Reserve 5.5K of RAM */
1335                param = 5632;
1336            } else { /* AR6003_REV2_VERSION */
1337                /* Reserve 6.5K of RAM */
1338                param = 6656;
1339            }
1340            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (A_UCHAR *)&param, 4));
1341        }
1342
1343        /* Restore system sleep */
1344        address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1345        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
1346
1347        address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1348        param = options | 0x20;
1349        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1350
1351        if (ar->arTargetType == TARGET_TYPE_AR6003) {
1352            /* Configure GPIO AR6003 UART */
1353#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
1354#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
1355#endif
1356            param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1357            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (A_UCHAR *)&param, 4));
1358
1359#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
1360            {
1361                address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
1362                bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1363                param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
1364                bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1365            }
1366#endif
1367
1368            /* Configure GPIO for BT Reset */
1369#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
1370#define CONFIG_AR600x_BT_RESET_PIN      0x16
1371            param = CONFIG_AR600x_BT_RESET_PIN;
1372            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (A_UCHAR *)&param, 4));
1373#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
1374
1375            /* Configure UART flow control polarity */
1376#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
1377#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
1378#endif
1379
1380#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
1381            if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1382                param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
1383                bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (A_UCHAR *)&param, 4));
1384            }
1385#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
1386        }
1387
1388#ifdef HTC_RAW_INTERFACE
1389        if (!eppingtest && bypasswmi) {
1390            /* Don't run BMIDone for ART mode and force resetok=0 */
1391            resetok = 0;
1392            msleep(1000);
1393        }
1394#endif /* HTC_RAW_INTERFACE */
1395
1396#endif /* INIT_MODE_DRV_ENABLED */
1397    }
1398
1399    return A_OK;
1400}
1401
1402A_STATUS
1403ar6000_configure_target(AR_SOFTC_T *ar)
1404{
1405    A_UINT32 param;
1406    if (enableuartprint) {
1407        param = 1;
1408        if (BMIWriteMemory(ar->arHifDevice,
1409                           HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
1410                           (A_UCHAR *)&param,
1411                           4)!= A_OK)
1412        {
1413             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
1414             return A_ERROR;
1415        }
1416        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
1417    }
1418
1419    /* Tell target which HTC version it is used*/
1420    param = HTC_PROTOCOL_VERSION;
1421    if (BMIWriteMemory(ar->arHifDevice,
1422                       HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
1423                       (A_UCHAR *)&param,
1424                       4)!= A_OK)
1425    {
1426         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
1427         return A_ERROR;
1428    }
1429
1430#ifdef CONFIG_HOST_TCMD_SUPPORT
1431    if(testmode) {
1432        ar->arTargetMode = AR6000_TCMD_MODE;
1433    }else {
1434        ar->arTargetMode = AR6000_WLAN_MODE;
1435    }
1436#endif
1437    if (enabletimerwar) {
1438        A_UINT32 param;
1439
1440        if (BMIReadMemory(ar->arHifDevice,
1441            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1442            (A_UCHAR *)&param,
1443            4)!= A_OK)
1444        {
1445            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
1446            return A_ERROR;
1447        }
1448
1449        param |= HI_OPTION_TIMER_WAR;
1450
1451        if (BMIWriteMemory(ar->arHifDevice,
1452            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1453            (A_UCHAR *)&param,
1454            4) != A_OK)
1455        {
1456            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
1457            return A_ERROR;
1458        }
1459        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
1460    }
1461
1462    /* set the firmware mode to STA/IBSS/AP */
1463    {
1464        A_UINT32 param;
1465
1466        if (BMIReadMemory(ar->arHifDevice,
1467            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1468            (A_UCHAR *)&param,
1469            4)!= A_OK)
1470        {
1471            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
1472            return A_ERROR;
1473        }
1474
1475        param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
1476
1477        if (BMIWriteMemory(ar->arHifDevice,
1478            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1479            (A_UCHAR *)&param,
1480            4) != A_OK)
1481        {
1482            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
1483            return A_ERROR;
1484        }
1485        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1486    }
1487
1488#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
1489    {
1490        A_UINT32 param;
1491
1492        if (BMIReadMemory(ar->arHifDevice,
1493            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1494            (A_UCHAR *)&param,
1495            4)!= A_OK)
1496        {
1497            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
1498            return A_ERROR;
1499        }
1500
1501        param |= HI_OPTION_DISABLE_DBGLOG;
1502
1503        if (BMIWriteMemory(ar->arHifDevice,
1504            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1505            (A_UCHAR *)&param,
1506            4) != A_OK)
1507        {
1508            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
1509            return A_ERROR;
1510        }
1511        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1512    }
1513#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
1514
1515    /* 
1516     * Hardcode the address use for the extended board data 
1517     * Ideally this should be pre-allocate by the OS at boot time
1518     * But since it is a new feature and board data is loaded 
1519     * at init time, we have to workaround this from host.
1520     * It is difficult to patch the firmware boot code,
1521     * but possible in theory.
1522     */
1523    if (ar->arTargetType == TARGET_TYPE_AR6003) {
1524        param = AR6003_BOARD_EXT_DATA_ADDRESS; 
1525        if (BMIWriteMemory(ar->arHifDevice,
1526            HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
1527            (A_UCHAR *)&param,
1528            4) != A_OK)
1529        {
1530            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n"));
1531            return A_ERROR;
1532        }
1533    }
1534
1535
1536        /* since BMIInit is called in the driver layer, we have to set the block
1537         * size here for the target */
1538
1539    if (A_FAILED(ar6000_set_htc_params(ar->arHifDevice,
1540                                       ar->arTargetType,
1541                                       mbox_yield_limit,
1542                                       0 /* use default number of control buffers */
1543                                       ))) {
1544        return A_ERROR;
1545    }
1546
1547    if (setupbtdev != 0) {
1548        if (A_FAILED(ar6000_set_hci_bridge_flags(ar->arHifDevice,
1549                                                 ar->arTargetType,
1550                                                 setupbtdev))) {
1551            return A_ERROR;
1552        }
1553    }
1554    return A_OK;
1555}
1556
1557static void
1558init_netdev(struct net_device *dev, char *name)
1559{
1560    dev->netdev_ops = &ar6000_netdev_ops;
1561    dev->watchdog_timeo = AR6000_TX_TIMEOUT;
1562    dev->wireless_handlers = &ath_iw_handler_def;
1563
1564    ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
1565
1566   /*
1567    * We need the OS to provide us with more headroom in order to
1568    * perform dix to 802.3, WMI header encap, and the HTC header
1569    */
1570    if (processDot11Hdr) {
1571        dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1572    } else {
1573        dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
1574            sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1575    }
1576
1577    if (name[0])
1578    {
1579        strcpy(dev->name, name);
1580    }
1581
1582#ifdef SET_MODULE_OWNER
1583    SET_MODULE_OWNER(dev);
1584#endif
1585
1586#ifdef CONFIG_CHECKSUM_OFFLOAD
1587    if(csumOffload){
1588        dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
1589    }
1590#endif
1591
1592    return;
1593}
1594
1595/*
1596 * HTC Event handlers
1597 */
1598static A_STATUS
1599ar6000_avail_ev(void *context, void *hif_handle)
1600{
1601    int i;
1602    struct net_device *dev;
1603    void *ar_netif;
1604    AR_SOFTC_T *ar;
1605    int device_index = 0;
1606    HTC_INIT_INFO  htcInfo;
1607#ifdef ATH6K_CONFIG_CFG80211
1608    struct wireless_dev *wdev;
1609#endif /* ATH6K_CONFIG_CFG80211 */
1610    A_STATUS init_status = A_OK;
1611
1612    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
1613
1614    for (i=0; i < MAX_AR6000; i++) {
1615        if (ar6000_devices[i] == NULL) {
1616            break;
1617        }
1618    }
1619
1620    if (i == MAX_AR6000) {
1621        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
1622        return A_ERROR;
1623    }
1624
1625    /* Save this. It gives a bit better readability especially since */
1626    /* we use another local "i" variable below.                      */
1627    device_index = i;
1628
1629#ifdef ATH6K_CONFIG_CFG80211
1630    wdev = ar6k_cfg80211_init(NULL);
1631    if (IS_ERR(wdev)) {
1632        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
1633        return A_ERROR;
1634    }
1635    ar_netif = wdev_priv(wdev);
1636#else
1637    dev = alloc_etherdev(sizeof(AR_SOFTC_T));
1638    if (dev == NULL) {
1639        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n"));
1640        return A_ERROR;
1641    }
1642    ether_setup(dev);
1643    ar_netif = ar6k_priv(dev);
1644#endif /* ATH6K_CONFIG_CFG80211 */
1645
1646    if (ar_netif == NULL) {
1647        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
1648        return A_ERROR;
1649    }
1650
1651    A_MEMZERO(ar_netif, sizeof(AR_SOFTC_T));
1652    ar = (AR_SOFTC_T *)ar_netif;
1653
1654#ifdef ATH6K_CONFIG_CFG80211
1655    ar->wdev = wdev;
1656    wdev->iftype = NL80211_IFTYPE_STATION;
1657
1658    dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
1659    if (!dev) {
1660        printk(KERN_CRIT "AR6K: no memory for network device instance\n");
1661        ar6k_cfg80211_deinit(ar);
1662        return A_ERROR;
1663    }
1664
1665    dev->ieee80211_ptr = wdev;
1666    SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1667    wdev->netdev = dev;
1668    ar->arNetworkType = INFRA_NETWORK;
1669#endif /* ATH6K_CONFIG_CFG80211 */
1670
1671    init_netdev(dev, ifname);
1672
1673#ifdef SET_NETDEV_DEV
1674    if (ar_netif) { 
1675        HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
1676        A_MEMZERO(&osDevInfo, sizeof(osDevInfo));
1677        if ( A_SUCCESS( HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
1678                        &osDevInfo, sizeof(osDevInfo))) ) {
1679            SET_NETDEV_DEV(dev, osDevInfo.pOSDevice);
1680        }
1681    }
1682#endif 
1683
1684    ar->arNetDev             = dev;
1685    ar->arHifDevice          = hif_handle;
1686    ar->arWlanState          = WLAN_ENABLED;
1687    ar->arDeviceIndex        = device_index;
1688
1689    ar->arWlanPowerState     = WLAN_POWER_STATE_ON;
1690    ar->arWlanOff            = FALSE;   /* We are in ON state */
1691#ifdef CONFIG_PM
1692    ar->arWowState           = WLAN_WOW_STATE_NONE;
1693    ar->arBTOff              = TRUE;   /* BT chip assumed to be OFF */
1694    ar->arBTSharing          = WLAN_CONFIG_BT_SHARING; 
1695    ar->arWlanOffConfig      = WLAN_CONFIG_WLAN_OFF;
1696    ar->arSuspendConfig      = WLAN_CONFIG_PM_SUSPEND;
1697    ar->arWow2Config         = WLAN_CONFIG_PM_WOW2;
1698#endif /* CONFIG_PM */
1699
1700    A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
1701    ar->arHBChallengeResp.seqNum = 0;
1702    ar->arHBChallengeResp.outstanding = FALSE;
1703    ar->arHBChallengeResp.missCnt = 0;
1704    ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
1705    ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
1706
1707    ar6000_init_control_info(ar);
1708    init_waitqueue_head(&arEvent);
1709    sema_init(&ar->arSem, 1);
1710    ar->bIsDestroyProgress = FALSE;
1711
1712    INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
1713
1714#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1715    A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
1716#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1717
1718    A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
1719
1720    BMIInit();
1721
1722    if (bmienable) {
1723        ar6000_sysfs_bmi_init(ar);
1724    }
1725
1726    {
1727        struct bmi_target_info targ_info;
1728
1729        if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) {
1730            init_status = A_ERROR;
1731            goto avail_ev_failed;
1732        }
1733
1734        ar->arVersion.target_ver = targ_info.target_ver;
1735        ar->arTargetType = targ_info.target_type;
1736
1737            /* do any target-specific preparation that can be done through BMI */
1738        if (ar6000_prepare_target(ar->arHifDevice,
1739                                  targ_info.target_type,
1740                                  targ_info.target_ver) != A_OK) {
1741            init_status = A_ERROR;
1742            goto avail_ev_failed;
1743        }
1744
1745    }
1746
1747    if (ar6000_configure_target(ar) != A_OK) {
1748            init_status = A_ERROR;
1749            goto avail_ev_failed;
1750    }
1751
1752    A_MEMZERO(&htcInfo,sizeof(htcInfo));
1753    htcInfo.pContext = ar;
1754    htcInfo.TargetFailure = ar6000_target_failure;
1755
1756    ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
1757
1758    if (ar->arHtcTarget == NULL) {
1759        init_status = A_ERROR;
1760        goto avail_ev_failed;
1761    }
1762
1763    spin_lock_init(&ar->arLock);
1764
1765#ifdef WAPI_ENABLE
1766    ar->arWapiEnable = 0;
1767#endif
1768
1769
1770#ifdef CONFIG_CHECKSUM_OFFLOAD
1771    if(csumOffload){
1772        /*if external frame work is also needed, change and use an extended rxMetaVerion*/
1773        ar->rxMetaVersion=WMI_META_VERSION_2;
1774    }
1775#endif
1776
1777#ifdef ATH_AR6K_11N_SUPPORT
1778    if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) {
1779            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
1780            init_status = A_ERROR;
1781            goto avail_ev_failed;
1782    }
1783
1784    aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
1785#endif
1786
1787    HIFClaimDevice(ar->arHifDevice, ar);
1788
1789    /* We only register the device in the global list if we succeed. */
1790    /* If the device is in the global list, it will be destroyed     */
1791    /* when the module is unloaded.                                  */
1792    ar6000_devices[device_index] = dev;
1793
1794    /* Don't install the init function if BMI is requested */
1795    if (!bmienable) {
1796        ar6000_netdev_ops.ndo_init = ar6000_init;
1797    } else {
1798        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
1799        if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
1800            (wlaninitmode == WLAN_INIT_MODE_DRV))
1801        {
1802            A_STATUS status = A_OK;
1803            do {
1804                if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK)
1805                {
1806                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
1807                    break;
1808                }
1809#ifdef HTC_RAW_INTERFACE
1810                break; /* Don't call ar6000_init for ART */
1811#endif 
1812                rtnl_lock();
1813                status = (ar6000_init(dev)==0) ? A_OK : A_ERROR;
1814                rtnl_unlock();
1815                if (status != A_OK) {
1816                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
1817                }
1818            } while (FALSE);
1819
1820            if (status != A_OK) {
1821                init_status = status;
1822                goto avail_ev_failed;
1823            }
1824        }
1825    }
1826
1827    /* This runs the init function if registered */
1828    if (register_netdev(dev)) {
1829        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
1830        ar6000_destroy(dev, 0);
1831        return A_ERROR;
1832    }
1833
1834        is_netdev_registered = 1;
1835
1836#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
1837    arApNetDev = NULL;
1838#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
1839    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
1840                    dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
1841                    (unsigned long)ar));
1842
1843avail_ev_failed :
1844    if (A_FAILED(init_status)) {
1845        if (bmienable) { 
1846            ar6000_sysfs_bmi_deinit(ar);  
1847        }
1848    }
1849
1850    return init_status;
1851}
1852
1853static void ar6000_target_failure(void *Instance, A_STATUS Status)
1854{
1855    AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
1856    WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1857    static A_BOOL sip = FALSE;
1858
1859    if (Status != A_OK) {
1860
1861        printk(KERN_ERR "ar6000_target_failure: target asserted \n");
1862
1863        if (timer_pending(&ar->arHBChallengeResp.timer)) {
1864            A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
1865        }
1866
1867        /* try dumping target assertion information (if any) */
1868        ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
1869
1870        /*
1871         * Fetch the logs from the target via the diagnostic
1872         * window.
1873         */
1874        ar6000_dbglog_get_debug_logs(ar);
1875
1876        /* Report the error only once */
1877        if (!sip) {
1878            sip = TRUE;
1879            errEvent.errorVal = WMI_TARGET_COM_ERR |
1880                                WMI_TARGET_FATAL_ERR;
1881            ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
1882                                     (A_UINT8 *)&errEvent,
1883                                     sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
1884        }
1885    }
1886}
1887
1888static A_STATUS
1889ar6000_unavail_ev(void *context, void *hif_handle)
1890{
1891    AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
1892        /* NULL out it's entry in the global list */
1893    ar6000_devices[ar->arDeviceIndex] = NULL;
1894    ar6000_destroy(ar->arNetDev, 1);
1895
1896    return A_OK;
1897}
1898
1899void
1900ar6000_restart_endpoint(struct net_device *dev)
1901{
1902    A_STATUS status = A_OK;
1903    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1904
1905    BMIInit();
1906    do {
1907        if ( (status=ar6000_configure_target(ar))!=A_OK)
1908            break;
1909        if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK)
1910        {
1911            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
1912            break;
1913        }
1914        rtnl_lock();
1915        status = (ar6000_init(dev)==0) ? A_OK : A_ERROR;
1916        rtnl_unlock();
1917
1918        if (status!=A_OK) {
1919            break;
1920        }
1921        if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
1922            ar6000_connect_to_ap(ar);
1923        }  
1924    } while (0);
1925
1926    if (status==A_OK) {
1927        return;
1928    }
1929
1930    ar6000_devices[ar->arDeviceIndex] = NULL;
1931    ar6000_destroy(ar->arNetDev, 1);
1932}
1933
1934void
1935ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs)
1936{
1937    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1938
1939    /* Stop the transmit queues */
1940    netif_stop_queue(dev);
1941
1942    /* Disable the target and the interrupts associated with it */
1943    if (ar->arWmiReady == TRUE)
1944    {
1945        if (!bypasswmi)
1946        {
1947            if (ar->arConnected == TRUE || ar->arConnectPending == TRUE)
1948            {
1949                AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__));
1950                if (!keepprofile) {
1951                    AR6000_SPIN_LOCK(&ar->arLock, 0);
1952                    ar6000_init_profile_info(ar);
1953                    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
1954                }
1955                wmi_disconnect_cmd(ar->arWmi);
1956            }
1957
1958            A_UNTIMEOUT(&ar->disconnect_timer);
1959
1960            if (getdbglogs) {
1961                ar6000_dbglog_get_debug_logs(ar);
1962            }
1963
1964            ar->arWmiReady  = FALSE;
1965            wmi_shutdown(ar->arWmi);
1966            ar->arWmiEnabled = FALSE;
1967            ar->arWmi = NULL;
1968            /* 
1969             * After wmi_shudown all WMI events will be dropped.
1970             * We need to cleanup the buffers allocated in AP mode
1971             * and give disconnect notification to stack, which usually
1972             * happens in the disconnect_event. 
1973             * Simulate the disconnect_event by calling the function directly.
1974             * Sometimes disconnect_event will be received when the debug logs 
1975             * are collected.
1976             */
1977            if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
1978                if(ar->arNetworkType & AP_NETWORK) {
1979                    ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
1980                } else {
1981                    ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
1982                }
1983                ar->arConnected = FALSE;
1984                ar->arConnectPending = FALSE;
1985            }
1986#ifdef USER_KEYS
1987            ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1988            ar->user_key_ctrl      = 0;
1989#endif
1990        }
1991
1992         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
1993    }
1994    else
1995    {
1996        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
1997            __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
1998
1999        /* Shut down WMI if we have started it */
2000        if(ar->arWmiEnabled == TRUE)
2001        {
2002            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
2003            wmi_shutdown(ar->arWmi);
2004            ar->arWmiEnabled = FALSE;
2005            ar->arWmi = NULL;
2006        }
2007    }
2008
2009    if (ar->arHtcTarget != NULL) {
2010#ifdef EXPORT_HCI_BRIDGE_INTERFACE
2011        if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
2012            ar6kHciTransCallbacks.cleanupTransport(NULL);
2013        }
2014#else
2015        // FIXME: workaround to reset BT's UART baud rate to default
2016        if (NULL != ar->exitCallback) {
2017            AR3K_CONFIG_INFO ar3kconfig;
2018            A_STATUS status;
2019
2020            A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
2021            ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
2022            status = ar->exitCallback(&ar3kconfig);
2023            if (A_OK != status) {
2024                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
2025            }
2026        }
2027        // END workaround
2028        if (setuphci)
2029                ar6000_cleanup_hci(ar);
2030#endif
2031#ifdef EXPORT_HCI_PAL_INTERFACE
2032        if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.cleanupTransport)) {
2033           ar6kHciPalCallbacks_g.cleanupTransport(ar);
2034        }
2035#else
2036                                /* cleanup hci pal driver data structures */
2037        if(setuphcipal)
2038          ar6k_cleanup_hci_pal(ar);
2039#endif
2040        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
2041        /* stop HTC */
2042        HTCStop(ar->arHtcTarget);
2043    }
2044
2045    if (resetok) {
2046        /* try to reset the device if we can
2047         * The driver may have been configure NOT to reset the target during
2048         * a debug session */
2049        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
2050        if (ar->arHifDevice != NULL) {
2051            A_BOOL coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? TRUE: FALSE;
2052            ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, coldReset);
2053        }
2054    } else {
2055        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
2056    }
2057       /* Done with cookies */
2058    ar6000_cookie_cleanup(ar);
2059}
2060/*
2061 * We need to differentiate between the surprise and planned removal of the
2062 * device because of the following consideration:
2063 * - In case of surprise removal, the hcd already frees up the pending
2064 *   for the device and hence there is no need to unregister the function
2065 *   driver inorder to get these requests. For planned removal, the function
2066 *   driver has to explictly unregister itself to have the hcd return all the
2067 *   pending requests before the data structures for the devices are freed up.
2068 *   Note that as per the current implementation, the function driver will
2069 *   end up releasing all the devices since there is no API to selectively
2070 *   release a particular device.
2071 * - Certain commands issued to the target can be skipped for surprise
2072 *   removal since they will anyway not go through.
2073 */
2074void
2075ar6000_destroy(struct net_device *dev, unsigned int unregister)
2076{
2077    AR_SOFTC_T *ar;
2078
2079    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
2080    
2081    if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
2082    {
2083        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
2084        return;
2085    }
2086
2087    ar->bIsDestroyProgress = TRUE;
2088
2089    if (down_interruptible(&ar->arSem)) {
2090        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
2091        return;
2092    }
2093
2094    if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
2095        /* only stop endpoint if we are not stop it in suspend_ev */
2096        ar6000_stop_endpoint(dev, FALSE, TRUE);
2097    } else {
2098        /* clear up the platform power state before rmmod */
2099        plat_setup_power(1,0);
2100    }
2101
2102    ar->arWlanState = WLAN_DISABLED;
2103    if (ar->arHtcTarget != NULL) {
2104        /* destroy HTC */
2105        HTCDestroy(ar->arHtcTarget);
2106    }
2107    if (ar->arHifDevice != NULL) {
2108        /*release the device so we do not get called back on remove incase we
2109         * we're explicity destroyed by module unload */
2110        HIFReleaseDevice(ar->arHifDevice);
2111        HIFShutDownDevice(ar->arHifDevice);
2112    }
2113#ifdef ATH_AR6K_11N_SUPPORT
2114    aggr_module_destroy(ar->aggr_cntxt);
2115#endif
2116
2117       /* Done with cookies */
2118    ar6000_cookie_cleanup(ar);
2119
2120        /* cleanup any allocated AMSDU buffers */
2121    ar6000_cleanup_amsdu_rxbufs(ar);
2122
2123    if (bmienable) {
2124        ar6000_sysfs_bmi_deinit(ar);
2125    }
2126
2127    /* Cleanup BMI */
2128    BMICleanup();
2129
2130    /* Clear the tx counters */
2131    memset(tx_attempt, 0, sizeof(tx_attempt));
2132    memset(tx_post, 0, sizeof(tx_post));
2133    memset(tx_complete, 0, sizeof(tx_complete));
2134
2135#ifdef HTC_RAW_INTERFACE
2136    if (ar->arRawHtc) {
2137        A_FREE(ar->arRawHtc);
2138        ar->arRawHtc = NULL;
2139    }
2140#endif 
2141    /* Free up the device data structure */
2142    if (unregister && is_netdev_registered) {           
2143        unregister_netdev(dev);
2144        is_netdev_registered = 0;
2145    }
2146    free_netdev(dev);
2147
2148#ifdef ATH6K_CONFIG_CFG80211
2149    ar6k_cfg80211_deinit(ar);
2150#endif /* ATH6K_CONFIG_CFG80211 */
2151
2152#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
2153    ar6000_remove_ap_interface();
2154#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
2155
2156    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
2157}
2158
2159static void disconnect_timer_handler(unsigned long ptr)
2160{
2161    struct net_device *dev = (struct net_device *)ptr;
2162    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2163
2164    A_UNTIMEOUT(&ar->disconnect_timer);
2165
2166    ar6000_init_profile_info(ar);
2167    wmi_disconnect_cmd(ar->arWmi);
2168}
2169
2170static void ar6000_detect_error(unsigned long ptr)
2171{
2172    struct net_device *dev = (struct net_device *)ptr;
2173    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2174    WMI_TARGET_ERROR_REPORT_EVENT errEvent;
2175
2176    AR6000_SPIN_LOCK(&ar->arLock, 0);
2177
2178    if (ar->arHBChallengeResp.outstanding) {
2179        ar->arHBChallengeResp.missCnt++;
2180    } else {
2181        ar->arHBChallengeResp.missCnt = 0;
2182    }
2183
2184    if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
2185        /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
2186        ar->arHBChallengeResp.missCnt = 0;
2187        ar->arHBChallengeResp.seqNum = 0;
2188        errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
2189        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2190        ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
2191                                 (A_UINT8 *)&errEvent,
2192                                 sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
2193        return;
2194    }
2195
2196    /* Generate the sequence number for the next challenge */
2197    ar->arHBChallengeResp.seqNum++;
2198    ar->arHBChallengeResp.outstanding = TRUE;
2199
2200    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2201
2202    /* Send the challenge on the control channel */
2203    if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != A_OK) {
2204        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
2205    }
2206
2207
2208    /* Reschedule the timer for the next challenge */
2209    A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2210}
2211
2212void ar6000_init_profile_info(AR_SOFTC_T *ar)
2213{
2214    ar->arSsidLen            = 0;
2215    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2216
2217    switch(fwmode) {
2218        case HI_OPTION_FW_MODE_IBSS:
2219            ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
2220            break;
2221        case HI_OPTION_FW_MODE_BSS_STA:
2222            ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
2223            break;
2224        case HI_OPTION_FW_MODE_AP:
2225            ar->arNetworkType = ar->arNextMode = AP_NETWORK;
2226            break;
2227    }
2228
2229    ar->arDot11AuthMode      = OPEN_AUTH;
2230    ar->arAuthMode           = NONE_AUTH;
2231    ar->arPairwiseCrypto     = NONE_CRYPT;
2232    ar->arPairwiseCryptoLen  = 0;
2233    ar->arGroupCrypto        = NONE_CRYPT;
2234    ar->arGroupCryptoLen     = 0;
2235    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2236    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2237    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2238    ar->arBssChannel = 0;
2239    ar->arConnected = FALSE;
2240}
2241
2242static void
2243ar6000_init_control_info(AR_SOFTC_T *ar)
2244{
2245    ar->arWmiEnabled         = FALSE;
2246    ar6000_init_profile_info(ar);
2247    ar->arDefTxKeyIndex      = 0;
2248    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2249    ar->arChannelHint        = 0;
2250    ar->arListenIntervalT    = A_DEFAULT_LISTEN_INTERVAL;
2251    ar->arListenIntervalB    = 0;
2252    ar->arVersion.host_ver   = AR6K_SW_VERSION;
2253    ar->arRssi               = 0;
2254    ar->arTxPwr              = 0;
2255    ar->arTxPwrSet           = FALSE;
2256    ar->arSkipScan           = 0;
2257    ar->arBeaconInterval     = 0;
2258    ar->arBitRate            = 0;
2259    ar->arMaxRetries         = 0;
2260    ar->arWmmEnabled         = TRUE;
2261    ar->intra_bss            = 1;
2262    ar->scan_triggered       = 0;
2263    A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
2264    ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
2265    ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
2266
2267    /* Initialize the AP mode state info */
2268    {
2269        A_UINT8 ctr;
2270        A_MEMZERO((A_UINT8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
2271
2272        /* init the Mutexes */
2273        A_MUTEX_INIT(&ar->mcastpsqLock);
2274
2275        /* Init the PS queues */
2276        for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
2277            A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
2278            A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
2279        }
2280
2281        ar->ap_profile_flag = 0;
2282        A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
2283
2284        A_MEMCPY(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2285        ar->ap_wmode = DEF_AP_WMODE_G;
2286        ar->ap_dtim_period = DEF_AP_DTIM;
2287        ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
2288    }
2289}
2290
2291static int
2292ar6000_open(struct net_device *dev)
2293{
2294    unsigned long  flags;
2295    AR_SOFTC_T    *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2296
2297    spin_lock_irqsave(&ar->arLock, flags);
2298
2299#ifdef ATH6K_CONFIG_CFG80211
2300    if(ar->arWlanState == WLAN_DISABLED) {
2301        ar->arWlanState = WLAN_ENABLED;
2302    }
2303#endif /* ATH6K_CONFIG_CFG80211 */
2304
2305    if( ar->arConnected || bypasswmi) {
2306        netif_carrier_on(dev);
2307        /* Wake up the queues */
2308        netif_wake_queue(dev);
2309    }
2310    else
2311        netif_carrier_off(dev);
2312
2313    spin_unlock_irqrestore(&ar->arLock, flags);
2314    return 0;
2315}
2316
2317static int
2318ar6000_close(struct net_device *dev)
2319{
2320#ifdef ATH6K_CONFIG_CFG80211
2321    AR_SOFTC_T    *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2322#endif /* ATH6K_CONFIG_CFG80211 */
2323    netif_stop_queue(dev);
2324
2325#ifdef ATH6K_CONFIG_CFG80211
2326    AR6000_SPIN_LOCK(&ar->arLock, 0);
2327    if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
2328        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2329        wmi_disconnect_cmd(ar->arWmi);
2330    } else {
2331        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2332    }
2333
2334    if(ar->arWmiReady == TRUE) {
2335        if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
2336                               0, 0, 0, 0, 0, 0, 0, 0) != A_OK) {
2337            return -EIO;
2338        }
2339        ar->arWlanState = WLAN_DISABLED;
2340    }
2341#endif /* ATH6K_CONFIG_CFG80211 */
2342
2343    return 0;
2344}
2345
2346/* connect to a service */
2347static A_STATUS ar6000_connectservice(AR_SOFTC_T               *ar,
2348                                      HTC_SERVICE_CONNECT_REQ  *pConnect,
2349                                      char                     *pDesc)
2350{
2351    A_STATUS                 status;
2352    HTC_SERVICE_CONNECT_RESP response;
2353
2354    do {
2355
2356        A_MEMZERO(&response,sizeof(response));
2357
2358        status = HTCConnectService(ar->arHtcTarget,
2359                                   pConnect,
2360                                   &response);
2361
2362        if (A_FAILED(status)) {
2363            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
2364                              pDesc, status));
2365            break;
2366        }
2367        switch (pConnect->ServiceID) {
2368            case WMI_CONTROL_SVC :
2369                if (ar->arWmiEnabled) {
2370                        /* set control endpoint for WMI use */
2371                    wmi_set_control_ep(ar->arWmi, response.Endpoint);
2372                }
2373                    /* save EP for fast lookup */
2374                ar->arControlEp = response.Endpoint;
2375                break;
2376            case WMI_DATA_BE_SVC :
2377                arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
2378                break;
2379            case WMI_DATA_BK_SVC :
2380                arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
2381                break;
2382            case WMI_DATA_VI_SVC :
2383                arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
2384                 break;
2385           case WMI_DATA_VO_SVC :
2386                arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
2387                break;
2388           default:
2389                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
2390                status = A_EINVAL;
2391            break;
2392        }
2393
2394    } while (FALSE);
2395
2396    return status;
2397}
2398
2399void ar6000_TxDataCleanup(AR_SOFTC_T *ar)
2400{
2401        /* flush all the data (non-control) streams
2402         * we only flush packets that are tagged as data, we leave any control packets that
2403         * were in the TX queues alone */
2404    HTCFlushEndpoint(ar->arHtcTarget,
2405                     arAc2EndpointID(ar, WMM_AC_BE),
2406                     AR6K_DATA_PKT_TAG);
2407    HTCFlushEndpoint(ar->arHtcTarget,
2408                     arAc2EndpointID(ar, WMM_AC_BK),
2409                     AR6K_DATA_PKT_TAG);
2410    HTCFlushEndpoint(ar->arHtcTarget,
2411                     arAc2EndpointID(ar, WMM_AC_VI),
2412                     AR6K_DATA_PKT_TAG);
2413    HTCFlushEndpoint(ar->arHtcTarget,
2414                     arAc2EndpointID(ar, WMM_AC_VO),
2415                     AR6K_DATA_PKT_TAG);
2416}
2417
2418HTC_ENDPOINT_ID
2419ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac)
2420{
2421    AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
2422    return(arAc2EndpointID(ar, ac));
2423}
2424
2425A_UINT8
2426ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
2427{
2428    AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
2429    return(arEndpoint2Ac(ar, ep ));
2430}
2431
2432/* This function does one time initialization for the lifetime of the device */
2433int ar6000_init(struct net_device *dev)
2434{
2435    AR_SOFTC_T *ar;
2436    A_STATUS    status;
2437    A_INT32     timeleft;
2438    A_INT16     i;
2439    int         ret = 0;
2440#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
2441    WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
2442    WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
2443#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
2444
2445    if((ar = ar6k_priv(dev)) == NULL)
2446    {
2447        return -EIO;
2448    }
2449
2450    if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
2451    
2452        ar6000_update_bdaddr(ar);
2453
2454        if (enablerssicompensation) {
2455            ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
2456            read_rssi_compensation_param(ar);
2457            for (i=-95; i<=0; i++) {
2458                rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
2459            }
2460        }
2461    }
2462
2463    dev_hold(dev);
2464    rtnl_unlock();
2465
2466    /* Do we need to finish the BMI phase */
2467    if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) && 
2468        (BMIDone(ar->arHifDevice) != A_OK))
2469    {
2470        ret = -EIO;
2471        goto ar6000_init_done;
2472    }
2473
2474    if (!bypasswmi)
2475    {
2476#if 0 /* TBDXXX */
2477        if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
2478            A_PRINTF("WARNING: Host version 0x%x does not match Target "
2479                    " version 0x%x!\n",
2480                    ar->arVersion.host_ver, ar->arVersion.target_ver);
2481        }
2482#endif
2483
2484        /* Indicate that WMI is enabled (although not ready yet) */
2485        ar->arWmiEnabled = TRUE;
2486        if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
2487        {
2488            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
2489            ret = -EIO;
2490            goto ar6000_init_done;
2491        }
2492
2493        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
2494            (unsigned long) ar->arWmi));
2495    }
2496
2497    do {
2498        HTC_SERVICE_CONNECT_REQ connect;
2499
2500            /* the reason we have to wait for the target here is that the driver layer
2501             * has to init BMI in order to set the host block size,
2502             */
2503        status = HTCWaitTarget(ar->arHtcTarget);
2504
2505        if (A_FAILED(status)) {
2506            break;
2507        }
2508
2509        A_MEMZERO(&connect,sizeof(connect));
2510            /* meta data is unused for now */
2511        connect.pMetaData = NULL;
2512        connect.MetaDataLength = 0;
2513            /* these fields are the same for all service endpoints */
2514        connect.EpCallbacks.pContext = ar;
2515        connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
2516        connect.EpCallbacks.EpRecv = ar6000_rx;
2517        connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
2518        connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
2519            /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
2520             * Linux has the peculiarity of not providing flow control between the
2521             * NIC and the network stack. There is no API to indicate that a TX packet
2522             * was sent which could provide some back pressure to the network stack.
2523             * Under linux you would have to wait till the network stack consumed all sk_buffs
2524             * before any back-flow kicked in. Which isn't very friendly.
2525             * So we have to manage this ourselves */
2526        connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
2527        connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
2528        if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
2529            connect.EpCallbacks.RecvRefillWaterMark++;
2530        }
2531            /* connect to control service */
2532        connect.ServiceID = WMI_CONTROL_SVC;
2533        status = ar6000_connectservice(ar,
2534                                       &connect,
2535                                       "WMI CONTROL");
2536        if (A_FAILED(status)) {
2537            break;
2538        }
2539
2540        connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
2541            /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
2542             * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
2543        connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
2544
2545            /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
2546             * mechanism for larger packets */
2547        connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
2548        connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
2549
2550            /* for the remaining data services set the connection flag to reduce dribbling,
2551             * if configured to do so */
2552        if (reduce_credit_dribble) {
2553            connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
2554            /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
2555             * of 0-3 */
2556            connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2557            connect.ConnectionFlags |=
2558                        ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2559        }
2560            /* connect to best-effort service */
2561        connect.ServiceID = WMI_DATA_BE_SVC;
2562
2563        status = ar6000_connectservice(ar,
2564                                       &connect,
2565                                       "WMI DATA BE");
2566        if (A_FAILED(status)) {
2567            break;
2568        }
2569
2570            /* connect to back-ground
2571             * map this to WMI LOW_PRI */
2572        connect.ServiceID = WMI_DATA_BK_SVC;
2573        status = ar6000_connectservice(ar,
2574                                       &connect,
2575                                       "WMI DATA BK");
2576        if (A_FAILED(status)) {
2577            break;
2578        }
2579
2580            /* connect to Video service, map this to
2581             * to HI PRI */
2582        connect.ServiceID = WMI_DATA_VI_SVC;
2583        status = ar6000_connectservice(ar,
2584                                       &connect,
2585                                       "WMI DATA VI");
2586        if (A_FAILED(status)) {
2587            break;
2588        }
2589
2590            /* connect to VO service, this is currently not
2591             * mapped to a WMI priority stream due to historical reasons.
2592             * WMI originally defined 3 priorities over 3 mailboxes
2593             * We can change this when WMI is reworked so that priorities are not
2594             * dependent on mailboxes */
2595        connect.ServiceID = WMI_DATA_VO_SVC;
2596        status = ar6000_connectservice(ar,
2597                                       &connect,
2598                                       "WMI DATA VO");
2599        if (A_FAILED(status)) {
2600            break;
2601        }
2602
2603        A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
2604        A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
2605        A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
2606        A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
2607
2608            /* setup access class priority mappings */
2609        ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest  */
2610        ar->arAcStreamPriMap[WMM_AC_BE] = 1; /*         */
2611        ar->arAcStreamPriMap[WMM_AC_VI] = 2; /*         */
2612        ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
2613
2614#ifdef EXPORT_HCI_BRIDGE_INTERFACE
2615        if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
2616            HCI_TRANSPORT_MISC_HANDLES hciHandles;
2617
2618            hciHandles.netDevice = ar->arNetDev;
2619            hciHandles.hifDevice = ar->arHifDevice;
2620            hciHandles.htcHandle = ar->arHtcTarget;
2621            status = (A_STATUS)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
2622        }
2623#else
2624        if (setuphci) {
2625                /* setup HCI */
2626            status = ar6000_setup_hci(ar);
2627        }
2628#endif
2629#ifdef EXPORT_HCI_PAL_INTERFACE
2630        if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.setupTransport))
2631          status = ar6kHciPalCallbacks_g.setupTransport(ar);
2632#else
2633        if(setuphcipal)
2634          status = ar6k_setup_hci_pal(ar);
2635#endif
2636
2637    } while (FALSE);
2638
2639    if (A_FAILED(status)) {
2640        ret = -EIO;
2641        goto ar6000_init_done;
2642    }
2643
2644    /*
2645     * give our connected endpoints some buffers
2646     */
2647
2648    ar6000_rx_refill(ar, ar->arControlEp);
2649    ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
2650
2651    /*
2652     * We will post the receive buffers only for SPE or endpoint ping testing so we are
2653     * making it conditional on the 'bypasswmi' flag.
2654     */
2655    if (bypasswmi) {
2656        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
2657        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
2658        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
2659    }
2660
2661    /* allocate some buffers that handle larger AMSDU frames */
2662    ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
2663
2664        /* setup credit distribution */
2665    ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
2666
2667    /* Since cookies are used for HTC transports, they should be */
2668    /* initialized prior to enabling HTC.                        */
2669    ar6000_cookie_init(ar);
2670
2671    /* start HTC */
2672    status = HTCStart(ar->arHtcTarget);
2673
2674    if (status != A_OK) {
2675        if (ar->arWmiEnabled == TRUE) {
2676            wmi_shutdown(ar->arWmi);
2677            ar->arWmiEnabled = FALSE;
2678            ar->arWmi = NULL;
2679        }
2680        ar6000_cookie_cleanup(ar);
2681        ret = -EIO;
2682        goto ar6000_init_done;
2683    }
2684
2685    if (!bypasswmi) {
2686        /* Wait for Wmi event to be ready */
2687        timeleft = wait_event_interruptible_timeout(arEvent,
2688            (ar->arWmiReady == TRUE), wmitimeout * HZ);
2689
2690        if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
2691            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
2692#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
2693            ret = -EIO;
2694            goto ar6000_init_done;
2695#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
2696        }
2697
2698        if(!timeleft || signal_pending(current))
2699        {
2700            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
2701            ret = -EIO;
2702            goto ar6000_init_done;
2703        }
2704
2705        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
2706
2707        /* Communicate the wmi protocol verision to the target */
2708        if ((ar6000_set_host_app_area(ar)) != A_OK) {
2709            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
2710        }
2711
2712        /* configure the device for rx dot11 header rules 0,0 are the default values
2713         * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
2714         if checksum offload is needed. Set RxMetaVersion to 2*/
2715        if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != A_OK) {
2716            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
2717        }
2718
2719#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
2720        /* Configure the type of BT collocated with WLAN */
2721        A_MEMZERO(&sbcb_cmd, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
2722#ifdef CONFIG_AR600x_BT_QCOM
2723        sbcb_cmd.btcoexCoLocatedBTdev = 1;
2724#elif defined(CONFIG_AR600x_BT_CSR)
2725        sbcb_cmd.btcoexCoLocatedBTdev = 2;
2726#elif defined(CONFIG_AR600x_BT_AR3001)
2727        sbcb_cmd.btcoexCoLocatedBTdev = 3;
2728#else
2729#error Unsupported Bluetooth Type
2730#endif /* Collocated Bluetooth Type */
2731
2732        if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != A_OK)
2733        {
2734            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n"));
2735        }
2736
2737        /* Configure the type of BT collocated with WLAN */
2738        A_MEMZERO(&sbfa_cmd, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
2739#ifdef CONFIG_AR600x_DUAL_ANTENNA
2740        sbfa_cmd.btcoexFeAntType = 2;
2741#elif defined(CONFIG_AR600x_SINGLE_ANTENNA)
2742        sbfa_cmd.btcoexFeAntType = 1;
2743#else
2744#error Unsupported Front-End Antenna Configuration
2745#endif /* AR600x Front-End Antenna Configuration */
2746
2747        if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != A_OK) {
2748            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n"));
2749        }
2750#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
2751    }
2752
2753    ar->arNumDataEndPts = 1;
2754
2755    if (bypasswmi) {
2756            /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
2757             * the data path through a raw socket is disabled */
2758        dev->dev_addr[0] = 0x00;
2759        dev->dev_addr[1] = 0x01;
2760        dev->dev_addr[2] = 0x02;
2761        dev->dev_addr[3] = 0xAA;
2762        dev->dev_addr[4] = 0xBB;
2763        dev->dev_addr[5] = 0xCC;
2764    }
2765
2766ar6000_init_done:
2767    rtnl_lock();
2768    dev_put(dev);
2769
2770    return ret;
2771}
2772
2773
2774void
2775ar6000_bitrate_rx(void *devt, A_INT32 rateKbps)
2776{
2777    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2778
2779    ar->arBitRate = rateKbps;
2780    wake_up(&arEvent);
2781}
2782
2783void
2784ar6000_ratemask_rx(void *devt, A_UINT32 ratemask)
2785{
2786    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2787
2788    ar->arRateMask = ratemask;
2789    wake_up(&arEvent);
2790}
2791
2792void
2793ar6000_txPwr_rx(void *devt, A_UINT8 txPwr)
2794{
2795    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2796
2797    ar->arTxPwr = txPwr;
2798    wake_up(&arEvent);
2799}
2800
2801
2802void
2803ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList)
2804{
2805    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
2806
2807    A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16));
2808    ar->arNumChannels = numChan;
2809
2810    wake_up(&arEvent);
2811}
2812
2813A_UINT8
2814ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo)
2815{
2816    AR_SOFTC_T      *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2817    A_UINT8         *datap;
2818    ATH_MAC_HDR     *macHdr;
2819    A_UINT32         i, eptMap;
2820
2821    (*mapNo) = 0;
2822    datap = A_NETBUF_DATA(skb);
2823    macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
2824    if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
2825        return ENDPOINT_2;
2826    }
2827
2828    eptMap = -1;
2829    for (i = 0; i < ar->arNodeNum; i ++) {
2830        if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
2831            (*mapNo) = i + 1;
2832            ar->arNodeMap[i].txPending ++;
2833            return ar->arNodeMap[i].epId;
2834        }
2835
2836        if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
2837            eptMap = i;
2838        }
2839    }
2840
2841    if (eptMap == -1) {
2842        eptMap = ar->arNodeNum;
2843        ar->arNodeNum ++;
2844        A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
2845    }
2846
2847    A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
2848
2849    for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
2850        if (!ar->arTxPending[i]) {
2851            ar->arNodeMap[eptMap].epId = i;
2852            break;
2853        }
2854        // No free endpoint is available, start redistribution on the inuse endpoints.
2855        if (i == ENDPOINT_5) {
2856            ar->arNodeMap[eptMap].epId = ar->arNexEpId;
2857            ar->arNexEpId ++;
2858            if (ar->arNexEpId > ENDPOINT_5) {
2859                ar->arNexEpId = ENDPOINT_2;
2860            }
2861        }
2862    }
2863
2864    (*mapNo) = eptMap + 1;
2865    ar->arNodeMap[eptMap].txPending ++;
2866
2867    return ar->arNodeMap[eptMap].epId;
2868}
2869
2870#ifdef DEBUG
2871static void ar6000_dump_skb(struct sk_buff *skb)
2872{
2873   u_char *ch;
2874   for (ch = A_NETBUF_DATA(skb);
2875        (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
2876        A_NETBUF_LEN(skb)); ch++)
2877    {
2878         AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
2879    }
2880    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
2881}
2882#endif
2883
2884#ifdef HTC_TEST_SEND_PKTS
2885static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
2886#endif
2887
2888static int
2889ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
2890{
2891#define AC_NOT_MAPPED   99
2892    AR_SOFTC_T        *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2893    A_UINT8            ac = AC_NOT_MAPPED;
2894    HTC_ENDPOINT_ID    eid = ENDPOINT_UNUSED;
2895    A_UINT32          mapNo = 0;
2896    int               len;
2897    struct ar_cookie *cookie;
2898    A_BOOL            checkAdHocPsMapping = FALSE,bMoreData = FALSE;
2899    HTC_TX_TAG        htc_tag = AR6K_DATA_PKT_TAG;
2900    A_UINT8           dot11Hdr = processDot11Hdr;
2901#ifdef CONFIG_PM
2902    if (ar->arWowState != WLAN_WOW_STATE_NONE) {
2903        A_NETBUF_FREE(skb);
2904        return 0;
2905    }
2906#endif /* CONFIG_PM */
2907
2908    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
2909                     (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
2910                     A_NETBUF_LEN(skb)));
2911
2912    /* If target is not associated */
2913    if( (!ar->arConnected && !bypasswmi)
2914#ifdef CONFIG_HOST_TCMD_SUPPORT
2915     /* TCMD doesnt support any data, free the buf and return */
2916    || (ar->arTargetMode == AR6000_TCMD_MODE)
2917#endif
2918                                            ) {
2919        A_NETBUF_FREE(skb);
2920        return 0;
2921    }
2922
2923    do {
2924
2925        if (ar->arWmiReady == FALSE && bypasswmi == 0) {
2926            break;
2927        }
2928
2929#ifdef BLOCK_TX_PATH_FLAG
2930        if (blocktx) {
2931            break;
2932        }
2933#endif /* BLOCK_TX_PATH_FLAG */
2934
2935        /* AP mode Power save processing */
2936        /* If the dst STA is in sleep state, queue the pkt in its PS queue */
2937
2938        if (ar->arNetworkType == AP_NETWORK) {
2939            ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
2940            sta_t *conn = NULL;
2941
2942            /* If the dstMac is a Multicast address & atleast one of the
2943             * associated STA is in PS mode, then queue the pkt to the
2944             * mcastq
2945             */
2946            if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
2947                A_UINT8 ctr=0;
2948                A_BOOL qMcast=FALSE;
2949
2950
2951                for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
2952                    if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
2953                        qMcast = TRUE;
2954                    }
2955                }
2956                if(qMcast) {
2957
2958                    /* If this transmit is not because of a Dtim Expiry q it */
2959                    if (ar->DTIMExpired == FALSE) {
2960                        A_BOOL isMcastqEmpty = FALSE;
2961
2962                        A_MUTEX_LOCK(&ar->mcastpsqLock);
2963                        isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
2964                        A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
2965                        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
2966
2967                        /* If this is the first Mcast pkt getting queued
2968                         * indicate to the target to set the BitmapControl LSB
2969                         * of the TIM IE.
2970                         */
2971                        if (isMcastqEmpty) {
2972                             wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
2973                        }
2974                        return 0;
2975                    } else {
2976                     /* This transmit is because of Dtim expiry. Determine if
2977                      * MoreData bit has to be set.
2978                      */
2979                         A_MUTEX_LOCK(&ar->mcastpsqLock);
2980                         if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
2981                             bMoreData = TRUE;
2982                         }
2983                         A_MUTEX_UNLOCK(&ar->mcastpsqLock);
2984                    }
2985                }
2986            } else {
2987                conn = ieee80211_find_conn(ar, datap->dstMac);
2988                if (conn) {
2989                    if (STA_IS_PWR_SLEEP(conn)) {
2990                        /* If this transmit is not because of a PsPoll q it*/
2991                        if (!STA_IS_PS_POLLED(conn)) {
2992                            A_BOOL isPsqEmpty = FALSE;
2993                            /* Queue the frames if the STA is sleeping */
2994                            A_MUTEX_LOCK(&conn->psqLock);
2995                            isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
2996                            A_NETBUF_ENQUEUE(&conn->psq, skb);
2997                            A_MUTEX_UNLOCK(&conn->psqLock);
2998
2999                            /* If this is the first pkt getting queued
3000                             * for this STA, update the PVB for this STA
3001                             */
3002                            if (isPsqEmpty) {
3003                                wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
3004                            }
3005
3006                            return 0;
3007                         } else {
3008                         /* This tx is because of a PsPoll. Determine if
3009                          * MoreData bit has to be set
3010                          */
3011                             A_MUTEX_LOCK(&conn->psqLock);
3012                             if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3013                                 bMoreData = TRUE;
3014                             }
3015                             A_MUTEX_UNLOCK(&conn->psqLock);
3016                         }
3017                    }
3018                } else {
3019
3020                    /* non existent STA. drop the frame */
3021                    A_NETBUF_FREE(skb);
3022                    return 0;
3023                }
3024            }
3025        }
3026
3027        if (ar->arWmiEnabled) {
3028#ifdef CONFIG_CHECKSUM_OFFLOAD
3029        A_UINT8 csumStart=0;
3030        A_UINT8 csumDest=0;
3031        A_UINT8 csum=skb->ip_summed;
3032        if(csumOffload && (csum==CHECKSUM_PARTIAL)){
3033            csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
3034                         sizeof(ATH_LLC_SNAP_HDR));
3035            csumDest=skb->csum_offset+csumStart;
3036        }
3037#endif
3038            if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
3039                struct sk_buff  *newbuf;
3040
3041                /*
3042                 * We really should have gotten enough headroom but sometimes
3043                 * we still get packets with not enough headroom.  Copy the packet.
3044                 */
3045                len = A_NETBUF_LEN(skb);
3046                newbuf = A_NETBUF_ALLOC(len);
3047                if (newbuf == NULL) {
3048                    break;
3049                }
3050                A_NETBUF_PUT(newbuf, len);
3051                A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
3052                A_NETBUF_FREE(skb);
3053                skb = newbuf;
3054                /* fall through and assemble header */
3055            }
3056
3057            if (dot11Hdr) {
3058                if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != A_OK) {
3059                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
3060                    break;
3061                }
3062            } else {
3063                if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) {
3064                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
3065                    break;
3066                }
3067            }
3068#ifdef CONFIG_CHECKSUM_OFFLOAD
3069            if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
3070                WMI_TX_META_V2  metaV2;
3071                metaV2.csumStart =csumStart;
3072                metaV2.csumDest = csumDest;
3073                metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
3074                if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
3075                                        WMI_META_VERSION_2,&metaV2) != A_OK) {
3076                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3077                    break;
3078                }
3079
3080            }
3081            else
3082#endif
3083            {
3084                if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != A_OK) {
3085                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3086                    break;
3087                }
3088            }
3089
3090
3091            if ((ar->arNetworkType == ADHOC_NETWORK) &&
3092                ar->arIbssPsEnable && ar->arConnected) {
3093                    /* flag to check adhoc mapping once we take the lock below: */
3094                checkAdHocPsMapping = TRUE;
3095
3096            } else {
3097                    /* get the stream mapping */
3098                ac  =  wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
3099            }
3100
3101        } else {
3102            EPPING_HEADER    *eppingHdr;
3103
3104            eppingHdr = A_NETBUF_DATA(skb);
3105
3106            if (IS_EPPING_PACKET(eppingHdr)) {
3107                    /* the stream ID is mapped to an access class */
3108                ac = eppingHdr->StreamNo_h;
3109                    /* some EPPING packets cannot be dropped no matter what access class it was
3110                     * sent on.  We can change the packet tag to guarantee it will not get dropped */
3111                if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
3112                    htc_tag = AR6K_CONTROL_PKT_TAG;
3113                }
3114
3115                if (ac == HCI_TRANSPORT_STREAM_NUM) {
3116                        /* pass this to HCI */
3117#ifndef EXPORT_HCI_BRIDGE_INTERFACE
3118                    if (A_SUCCESS(hci_test_send(ar,skb))) {
3119                        return 0;
3120                    }
3121#endif
3122                        /* set AC to discard this skb */
3123                    ac = AC_NOT_MAPPED;
3124                } else {
3125                    /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
3126                     * of the HTC header will mis-align the start of the HTC frame, so we add some
3127                     * padding which will be stripped off in the target */
3128                    if (EPPING_ALIGNMENT_PAD > 0) {
3129                        A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
3130                    }
3131                }
3132
3133            } else {
3134                    /* not a ping packet, drop it */
3135                ac = AC_NOT_MAPPED;
3136            }
3137        }
3138
3139    } while (FALSE);
3140
3141        /* did we succeed ? */
3142    if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
3143            /* cleanup and exit */
3144        A_NETBUF_FREE(skb);
3145        AR6000_STAT_INC(ar, tx_dropped);
3146        AR6000_STAT_INC(ar, tx_aborted_errors);
3147        return 0;
3148    }
3149
3150    cookie = NULL;
3151
3152        /* take the lock to protect driver data */
3153    AR6000_SPIN_LOCK(&ar->arLock, 0);
3154
3155    do {
3156
3157        if (checkAdHocPsMapping) {
3158            eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
3159        }else {
3160            eid = arAc2EndpointID (ar, ac);
3161        }
3162            /* validate that the endpoint is connected */
3163        if (eid == 0 || eid == ENDPOINT_UNUSED ) {
3164            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
3165            break;
3166        }
3167            /* allocate resource for this packet */
3168        cookie = ar6000_alloc_cookie(ar);
3169
3170        if (cookie != NULL) {
3171                /* update counts while the lock is held */
3172            ar->arTxPending[eid]++;
3173            ar->arTotalTxDataPending++;
3174        }
3175
3176    } while (FALSE);
3177
3178    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3179
3180    if (cookie != NULL) {
3181        cookie->arc_bp[0] = (unsigned long)skb;
3182        cookie->arc_bp[1] = mapNo;
3183        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3184                               cookie,
3185                               A_NETBUF_DATA(skb),
3186                               A_NETBUF_LEN(skb),
3187                               eid,
3188                               htc_tag);
3189
3190#ifdef DEBUG
3191        if (debugdriver >= 3) {
3192            ar6000_dump_skb(skb);
3193        }
3194#endif
3195#ifdef HTC_TEST_SEND_PKTS
3196        DoHTCSendPktsTest(ar,mapNo,eid,skb);
3197#endif
3198            /* HTC interface is asynchronous, if this fails, cleanup will happen in
3199             * the ar6000_tx_complete callback */
3200        HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3201    } else {
3202            /* no packet to send, cleanup */
3203        A_NETBUF_FREE(skb);
3204        AR6000_STAT_INC(ar, tx_dropped);
3205        AR6000_STAT_INC(ar, tx_aborted_errors);
3206    }
3207
3208    return 0;
3209}
3210
3211int
3212ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
3213{
3214    AR_SOFTC_T        *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3215    struct ar_cookie *cookie;
3216    HTC_ENDPOINT_ID    eid = ENDPOINT_UNUSED;
3217
3218    cookie = NULL;
3219    AR6000_SPIN_LOCK(&ar->arLock, 0);
3220
3221        /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
3222        eid = arAc2EndpointID (ar, 0);
3223        /* allocate resource for this packet */
3224        cookie = ar6000_alloc_cookie(ar);
3225
3226        if (cookie != NULL) {
3227            /* update counts while the lock is held */
3228            ar->arTxPending[eid]++;
3229            ar->arTotalTxDataPending++;
3230        }
3231
3232
3233    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3234
3235        if (cookie != NULL) {
3236            cookie->arc_bp[0] = (unsigned long)skb;
3237            cookie->arc_bp[1] = 0;
3238            SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3239                            cookie,
3240                            A_NETBUF_DATA(skb),
3241                            A_NETBUF_LEN(skb),
3242                            eid,
3243                            AR6K_DATA_PKT_TAG);
3244
3245            /* HTC interface is asynchronous, if this fails, cleanup will happen in
3246             * the ar6000_tx_complete callback */
3247            HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3248        } else {
3249            /* no packet to send, cleanup */
3250            A_NETBUF_FREE(skb);
3251            AR6000_STAT_INC(ar, tx_dropped);
3252            AR6000_STAT_INC(ar, tx_aborted_errors);
3253        }
3254    return 0;
3255}
3256
3257
3258#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3259static void
3260tvsub(register struct timeval *out, register struct timeval *in)
3261{
3262    if((out->tv_usec -= in->tv_usec) < 0) {
3263        out->tv_sec--;
3264        out->tv_usec += 1000000;
3265    }
3266    out->tv_sec -= in->tv_sec;
3267}
3268
3269void
3270applyAPTCHeuristics(AR_SOFTC_T *ar)
3271{
3272    A_UINT32 duration;
3273    A_UINT32 numbytes;
3274    A_UINT32 throughput;
3275    struct timeval ts;
3276    A_STATUS status;
3277
3278    AR6000_SPIN_LOCK(&ar->arLock, 0);
3279
3280    if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
3281        do_gettimeofday(&ts);
3282        tvsub(&ts, &aptcTR.samplingTS);
3283        duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
3284        numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
3285
3286        if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
3287            /* Initialize the time stamp and byte count */
3288            aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
3289            do_gettimeofday(&aptcTR.samplingTS);
3290
3291            /* Calculate and decide based on throughput thresholds */
3292            throughput = ((numbytes * 8) / duration);
3293            if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
3294                /* Disable Sleep and schedule a timer */
3295                A_ASSERT(ar->arWmiReady == TRUE);
3296                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3297                status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
3298                AR6000_SPIN_LOCK(&ar->arLock, 0);
3299                A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
3300                aptcTR.timerScheduled = TRUE;
3301            }
3302        }
3303    }
3304
3305    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3306}
3307#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3308
3309static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket)
3310{
3311    AR_SOFTC_T     *ar = (AR_SOFTC_T *)Context;
3312    HTC_SEND_FULL_ACTION    action = HTC_SEND_FULL_KEEP;
3313    A_BOOL                  stopNet = FALSE;
3314    HTC_ENDPOINT_ID         Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
3315
3316    do {
3317
3318        if (bypasswmi) {
3319            int accessClass;
3320
3321            if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3322                    /* don't drop special control packets */
3323                break;
3324            }
3325
3326            accessClass = arEndpoint2Ac(ar,Endpoint);
3327                /* for endpoint ping testing drop Best Effort and Background */
3328            if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
3329                action = HTC_SEND_FULL_DROP;
3330                stopNet = FALSE;
3331            } else {
3332                    /* keep but stop the netqueues */
3333                stopNet = TRUE;
3334            }
3335            break;
3336        }
3337
3338        if (Endpoint == ar->arControlEp) {
3339                /* under normal WMI if this is getting full, then something is running rampant
3340                 * the host should not be exhausting the WMI queue with too many commands
3341                 * the only exception to this is during testing using endpointping */
3342            AR6000_SPIN_LOCK(&ar->arLock, 0);
3343                /* set flag to handle subsequent messages */
3344            ar->arWMIControlEpFull = TRUE;
3345            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3346            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
3347                /* no need to stop the network */
3348            stopNet = FALSE;
3349            break;
3350        }
3351
3352        /* if we get here, we are dealing with data endpoints getting full */
3353
3354        if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3355            /* don't drop control packets issued on ANY data endpoint */
3356            break;
3357        }
3358
3359        if (ar->arNetworkType == ADHOC_NETWORK) {
3360            /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
3361             * continue, however we should stop the network */
3362            stopNet = TRUE;
3363            break;
3364        }
3365        /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
3366         * active stream */
3367        if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
3368            ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
3369                /* this stream's priority is less than the highest active priority, we
3370                 * give preference to the highest priority stream by directing
3371                 * HTC to drop the packet that overflowed */
3372            action = HTC_SEND_FULL_DROP;
3373                /* since we are dropping packets, no need to stop the network */
3374            stopNet = FALSE;
3375            break;
3376        }
3377
3378    } while (FALSE);
3379
3380    if (stopNet) {
3381        AR6000_SPIN_LOCK(&ar->arLock, 0);
3382        ar->arNetQueueStopped = TRUE;
3383        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3384        /* one of the data endpoints queues is getting full..need to stop network stack
3385         * the queue will resume in ar6000_tx_complete() */
3386        netif_stop_queue(ar->arNetDev);
3387    }
3388
3389    return action;
3390}
3391
3392
3393static void
3394ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue)
3395{
3396    AR_SOFTC_T     *ar = (AR_SOFTC_T *)Context;
3397    A_UINT32        mapNo = 0;
3398    A_STATUS        status;
3399    struct ar_cookie * ar_cookie;
3400    HTC_ENDPOINT_ID   eid;
3401    A_BOOL          wakeEvent = FALSE;
3402    struct sk_buff_head  skb_queue;
3403    HTC_PACKET      *pPacket;
3404    struct sk_buff  *pktSkb;
3405    A_BOOL          flushing = FALSE;
3406
3407    skb_queue_head_init(&skb_queue);
3408
3409        /* lock the driver as we update internal state */
3410    AR6000_SPIN_LOCK(&ar->arLock, 0);
3411
3412        /* reap completed packets */
3413    while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
3414
3415        pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
3416
3417        ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
3418        A_ASSERT(ar_cookie);
3419
3420        status = pPacket->Status;
3421        pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
3422        eid = pPacket->Endpoint;
3423        mapNo = ar_cookie->arc_bp[1];
3424
3425        A_ASSERT(pktSkb);
3426        A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
3427
3428            /* add this to the list, use faster non-lock API */
3429        __skb_queue_tail(&skb_queue,pktSkb);
3430
3431        if (A_SUCCESS(status)) {
3432            A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
3433        }
3434
3435        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
3436                         (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
3437                         pPacket->ActualLength,
3438                         eid));
3439
3440        ar->arTxPending[eid]--;
3441
3442        if ((eid  != ar->arControlEp) || bypasswmi) {
3443            ar->arTotalTxDataPending--;
3444        }
3445
3446        if (eid == ar->arControlEp)
3447        {
3448            if (ar->arWMIControlEpFull) {
3449                    /* since this packet completed, the WMI EP is no longer full */
3450                ar->arWMIControlEpFull = FALSE;
3451            }
3452
3453            if (ar->arTxPending[eid] == 0) {
3454                wakeEvent = TRUE;
3455            }
3456        }
3457
3458        if (A_FAILED(status)) {
3459            if (status == A_ECANCELED) {
3460                    /* a packet was flushed  */
3461                flushing = TRUE;
3462            }
3463            AR6000_STAT_INC(ar, tx_errors);
3464            if (status != A_NO_RESOURCE) {
3465                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
3466                            status));
3467            }
3468        } else {
3469            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
3470            flushing = FALSE;
3471            AR6000_STAT_INC(ar, tx_packets);
3472            ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
3473#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3474            aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
3475            applyAPTCHeuristics(ar);
3476#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3477        }
3478
3479        // TODO this needs to be looked at
3480        if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
3481            && (eid != ar->arControlEp) && mapNo)
3482        {
3483            mapNo --;
3484            ar->arNodeMap[mapNo].txPending --;
3485
3486            if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
3487                A_UINT32 i;
3488                for (i = ar->arNodeNum; i > 0; i --) {
3489                    if (!ar->arNodeMap[i - 1].txPending) {
3490                        A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
3491                        ar->arNodeNum --;
3492                    } else {
3493                        break;
3494                    }
3495                }
3496            }
3497        }
3498
3499        ar6000_free_cookie(ar, ar_cookie);
3500
3501        if (ar->arNetQueueStopped) {
3502            ar->arNetQueueStopped = FALSE;
3503        }
3504    }
3505
3506    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3507
3508    /* lock is released, we can freely call other kernel APIs */
3509
3510        /* free all skbs in our local list */
3511    while (!skb_queue_empty(&skb_queue)) {
3512            /* use non-lock version */
3513        pktSkb = __skb_dequeue(&skb_queue);
3514        A_NETBUF_FREE(pktSkb);
3515    }
3516
3517    if ((ar->arConnected == TRUE) || (bypasswmi)) {
3518        if (!flushing) {
3519                /* don't wake the queue if we are flushing, other wise it will just
3520                 * keep queueing packets, which will keep failing */
3521            netif_wake_queue(ar->arNetDev);
3522        }
3523    }
3524
3525    if (wakeEvent) {
3526        wake_up(&arEvent);
3527    }
3528
3529}
3530
3531sta_t *
3532ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr)
3533{
3534    sta_t *conn = NULL;
3535    A_UINT8 i, max_conn;
3536
3537    switch(ar->arNetworkType) {
3538        case AP_NETWORK:
3539            max_conn = AP_MAX_NUM_STA;
3540            break;
3541        default:
3542            max_conn=0;
3543            break;
3544    }
3545
3546    for (i = 0; i < max_conn; i++) {
3547        if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
3548            conn = &ar->sta_list[i];
3549            break;
3550        }
3551    }
3552
3553    return conn;
3554}
3555
3556sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid)
3557{
3558    sta_t *conn = NULL;
3559    A_UINT8 ctr;
3560
3561    for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
3562        if (ar->sta_list[ctr].aid == aid) {
3563            conn = &ar->sta_list[ctr];
3564            break;
3565        }
3566    }
3567    return conn;
3568}
3569
3570/*
3571 * Receive event handler.  This is called by HTC when a packet is received
3572 */
3573int pktcount;
3574static void
3575ar6000_rx(void *Context, HTC_PACKET *pPacket)
3576{
3577    AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
3578    struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
3579    int minHdrLen;
3580    A_UINT8 containsDot11Hdr = 0;
3581    A_STATUS        status = pPacket->Status;
3582    HTC_ENDPOINT_ID   ept = pPacket->Endpoint;
3583
3584    A_ASSERT((status != A_OK) ||
3585             (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
3586
3587    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
3588                    (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
3589                    pPacket->ActualLength, status));
3590    if (status != A_OK) {
3591        if (status != A_ECANCELED) {
3592            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
3593        }
3594    }
3595
3596        /* take lock to protect buffer counts
3597         * and adaptive power throughput state */
3598    AR6000_SPIN_LOCK(&ar->arLock, 0);
3599
3600    if (A_SUCCESS(status)) {
3601        AR6000_STAT_INC(ar, rx_packets);
3602        ar->arNetStats.rx_bytes += pPacket->ActualLength;
3603#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3604        aptcTR.bytesReceived += a_netbuf_to_len(skb);
3605        applyAPTCHeuristics(ar);
3606#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3607
3608        A_NETBUF_PUT(skb, pPacket->ActualLength +  HTC_HEADER_LEN);
3609        A_NETBUF_PULL(skb, HTC_HEADER_LEN);
3610
3611#ifdef DEBUG
3612        if (debugdriver >= 2) {
3613            ar6000_dump_skb(skb);
3614        }
3615#endif /* DEBUG */
3616    }
3617
3618    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3619
3620    skb->dev = ar->arNetDev;
3621    if (status != A_OK) {
3622        AR6000_STAT_INC(ar, rx_errors);
3623        A_NETBUF_FREE(skb);
3624    } else if (ar->arWmiEnabled == TRUE) {
3625        if (ept == ar->arControlEp) {
3626           /*
3627            * this is a wmi control msg
3628            */
3629#ifdef CONFIG_PM 
3630            ar6000_check_wow_status(ar, skb, TRUE);
3631#endif /* CONFIG_PM */
3632            wmi_control_rx(ar->arWmi, skb);
3633        } else {
3634                WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
3635                A_UINT8 is_amsdu, tid, is_acl_data_frame;
3636                is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL;
3637#ifdef CONFIG_PM 
3638                ar6000_check_wow_status(ar, NULL, FALSE);
3639#endif /* CONFIG_PM */
3640                /*
3641                 * this is a wmi data packet
3642                 */
3643                 // NWF
3644
3645                if (processDot11Hdr) {
3646                    minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
3647                } else {
3648                    minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
3649                          sizeof(ATH_LLC_SNAP_HDR);
3650                }
3651
3652                /* In the case of AP mode we may receive NULL data frames
3653                 * that do not have LLC hdr. They are 16 bytes in size.
3654                 * Allow these frames in the AP mode.
3655                 * ACL data frames don't follow ethernet frame bounds for
3656                 * min length
3657                 */
3658                if (ar->arNetworkType != AP_NETWORK &&  !is_acl_data_frame &&
3659                    ((pPacket->ActualLength < minHdrLen) ||
3660                    (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
3661                {
3662                    /*
3663                     * packet is too short or too long
3664                     */
3665                    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
3666                    AR6000_STAT_INC(ar, rx_errors);
3667                    AR6000_STAT_INC(ar, rx_length_errors);
3668                    A_NETBUF_FREE(skb);
3669                } else {
3670                    A_UINT16 seq_no;
3671                    A_UINT8 meta_type;
3672
3673#if 0
3674                    /* Access RSSI values here */
3675                    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
3676                        ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
3677#endif
3678                    /* Get the Power save state of the STA */
3679                    if (ar->arNetworkType == AP_NETWORK) {
3680                        sta_t *conn = NULL;
3681                        A_UINT8 psState=0,prevPsState;
3682                        ATH_MAC_HDR *datap=NULL;
3683                        A_UINT16 offset;
3684
3685                        meta_type = WMI_DATA_HDR_GET_META(dhdr);
3686
3687                        psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
3688                                     >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
3689
3690                        offset = sizeof(WMI_DATA_HDR);
3691
3692                        switch (meta_type) {
3693                            case 0:
3694                                break;
3695                            case WMI_META_VERSION_1:
3696                                offset += sizeof(WMI_RX_META_V1);
3697                                break;
3698#ifdef CONFIG_CHECKSUM_OFFLOAD
3699                            case WMI_META_VERSION_2:
3700                                offset += sizeof(WMI_RX_META_V2);
3701                                break;
3702#endif
3703                            default:
3704                                break;
3705                        }
3706
3707                        datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
3708                        conn = ieee80211_find_conn(ar, datap->srcMac);
3709
3710                        if (conn) {
3711                            /* if there is a change in PS state of the STA,
3712                             * take appropriate steps.
3713                             * 1. If Sleep-->Awake, flush the psq for the STA
3714                             *    Clear the PVB for the STA.
3715                             * 2. If Awake-->Sleep, Starting queueing frames
3716                             * the STA.
3717                             */
3718                            prevPsState = STA_IS_PWR_SLEEP(conn);
3719                            if (psState) {
3720                                STA_SET_PWR_SLEEP(conn);
3721                            } else {
3722                                STA_CLR_PWR_SLEEP(conn);
3723                            }
3724
3725                            if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
3726
3727                                if (!STA_IS_PWR_SLEEP(conn)) {
3728
3729                                    A_MUTEX_LOCK(&conn->psqLock);
3730                                    while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3731                                        struct sk_buff *skb=NULL;
3732
3733                                        skb = A_NETBUF_DEQUEUE(&conn->psq);
3734                                        A_MUTEX_UNLOCK(&conn->psqLock);
3735                                        ar6000_data_tx(skb,ar->arNetDev);
3736                                        A_MUTEX_LOCK(&conn->psqLock);
3737                                    }
3738                                    A_MUTEX_UNLOCK(&conn->psqLock);
3739                                    /* Clear the PVB for this STA */
3740                                    wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
3741                                }
3742                            }
3743                        } else {
3744                            /* This frame is from a STA that is not associated*/
3745                            A_ASSERT(FALSE);
3746                        }
3747
3748                        /* Drop NULL data frames here */
3749                        if((pPacket->ActualLength < minHdrLen) ||
3750                                (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
3751                            A_NETBUF_FREE(skb);
3752                            goto rx_done;
3753                        }
3754                    }
3755
3756                    is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr);
3757                    tid = WMI_DATA_HDR_GET_UP(dhdr);
3758                    seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
3759                    meta_type = WMI_DATA_HDR_GET_META(dhdr);
3760                    containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
3761
3762                    wmi_data_hdr_remove(ar->arWmi, skb);
3763
3764                    switch (meta_type) {
3765                        case WMI_META_VERSION_1:
3766                            {
3767                                WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
3768                                A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
3769                                A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
3770                                break;
3771                            }
3772#ifdef CONFIG_CHECKSUM_OFFLOAD
3773                        case WMI_META_VERSION_2:
3774                            {
3775                                WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
3776                                if(pMeta->csumFlags & 0x1){
3777                                    skb->ip_summed=CHECKSUM_COMPLETE;
3778                                    skb->csum=(pMeta->csum);
3779                                }
3780                                A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
3781                                break;
3782                            }
3783#endif
3784                        default:
3785                            break;
3786                    }
3787
3788                    A_ASSERT(status == A_OK);
3789
3790                    /* NWF: print the 802.11 hdr bytes */
3791                    if(containsDot11Hdr) {
3792                        status = wmi_dot11_hdr_remove(ar->arWmi,skb);
3793                    } else if(!is_amsdu && !is_acl_data_frame) {
3794                        status = wmi_dot3_2_dix(skb);
3795                    }
3796
3797                    if (status != A_OK) {
3798                        /* Drop frames that could not be processed (lack of memory, etc.) */
3799                        A_NETBUF_FREE(skb);
3800                        goto rx_done;
3801                    }
3802
3803                    if (is_acl_data_frame) {
3804                        A_NETBUF_PUSH(skb, sizeof(int));
3805                        *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID;
3806                        /* send the data packet to PAL driver */
3807                        if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) {
3808                                if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == TRUE)
3809                                        goto rx_done;
3810                        }
3811                    }
3812
3813                    if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
3814                        if (ar->arNetworkType == AP_NETWORK) {
3815                            struct sk_buff *skb1 = NULL;
3816                            ATH_MAC_HDR *datap;
3817
3818                            datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
3819                            if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
3820                                /* Bcast/Mcast frames should be sent to the OS
3821                                 * stack as well as on the air.
3822                                 */
3823                                skb1 = skb_copy(skb,GFP_ATOMIC);
3824                            } else {
3825                                /* Search for a connected STA with dstMac as
3826                                 * the Mac address. If found send the frame to
3827                                 * it on the air else send the frame up the
3828                                 * stack
3829                                 */
3830                                sta_t *conn = NULL;
3831                                conn = ieee80211_find_conn(ar, datap->dstMac);
3832
3833                                if (conn && ar->intra_bss) {
3834                                    skb1 = skb;
3835                                    skb = NULL;
3836                                } else if(conn && !ar->intra_bss) {
3837                                    A_NETBUF_FREE(skb);
3838                                    skb = NULL;
3839                                }
3840                            }
3841                            if (skb1) {
3842                                ar6000_data_tx(skb1, ar->arNetDev);
3843                            }
3844                        }
3845                    }
3846#ifdef ATH_AR6K_11N_SUPPORT
3847                    aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
3848#endif
3849                    ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
3850                }
3851            }
3852    } else {
3853        if (EPPING_ALIGNMENT_PAD > 0) {
3854            A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
3855        }
3856        ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
3857    }
3858
3859rx_done:
3860
3861    return;
3862}
3863
3864static void
3865ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
3866{
3867    struct sk_buff *skb = (struct sk_buff *)osbuf;
3868
3869    if(skb) {
3870        skb->dev = dev;
3871        if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3872#ifdef CONFIG_PM 
3873            ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, FALSE);   
3874#endif /* CONFIG_PM */
3875            skb->protocol = eth_type_trans(skb, skb->dev);
3876        /*
3877         * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
3878         * or tasklet use the netif_rx to deliver the packet to the stack
3879         * netif_rx will queue the packet onto the receive queue and mark
3880         * the softirq thread has a pending action to complete. Kernel will 
3881         * schedule the softIrq kernel thread after processing the DSR.
3882         *
3883         * If this routine is called on a process context, use netif_rx_ni
3884         * which will schedle the softIrq kernel thread after queuing the packet.
3885         */
3886            if (in_interrupt()) {
3887                netif_rx(skb);
3888            } else {
3889                netif_rx_ni(skb);
3890            }
3891        } else {
3892            A_NETBUF_FREE(skb);
3893        }
3894    }
3895}
3896
3897#if 0
3898static void
3899ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
3900{
3901    struct sk_buff *skb = (struct sk_buff *)osbuf;
3902
3903    if(skb) {
3904        skb->dev = dev;
3905        if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3906            skb->protocol = htons(ETH_P_CONTROL);
3907            netif_rx(skb);
3908        } else {
3909            A_NETBUF_FREE(skb);
3910        }
3911    }
3912}
3913#endif
3914
3915static void
3916ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
3917{
3918    AR_SOFTC_T  *ar = (AR_SOFTC_T *)Context;
3919    void        *osBuf;
3920    int         RxBuffers;
3921    int         buffersToRefill;
3922    HTC_PACKET  *pPacket;
3923    HTC_PACKET_QUEUE queue;
3924
3925    buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
3926                                    HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
3927
3928    if (buffersToRefill <= 0) {
3929            /* fast return, nothing to fill */
3930        return;
3931    }
3932
3933    INIT_HTC_PACKET_QUEUE(&queue);
3934
3935    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
3936                    buffersToRefill, Endpoint));
3937
3938    for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
3939        osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
3940        if (NULL == osBuf) {
3941            break;
3942        }
3943            /* the HTC packet wrapper is at the head of the reserved area
3944             * in the skb */
3945        pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
3946            /* set re-fill info */
3947        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
3948            /* add to queue */
3949        HTC_PACKET_ENQUEUE(&queue,pPacket);
3950    }
3951
3952    if (!HTC_QUEUE_EMPTY(&queue)) {
3953            /* add packets */
3954        HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
3955    }
3956
3957}
3958
3959  /* clean up our amsdu buffer list */
3960static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar)
3961{
3962    HTC_PACKET  *pPacket;
3963    void        *osBuf;
3964
3965        /* empty AMSDU buffer queue and free OS bufs */
3966    while (TRUE) {
3967
3968        AR6000_SPIN_LOCK(&ar->arLock, 0);
3969        pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
3970        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3971
3972        if (NULL == pPacket) {
3973            break;
3974        }
3975
3976        osBuf = pPacket->pPktContext;
3977        if (NULL == osBuf) {
3978            A_ASSERT(FALSE);
3979            break;
3980        }
3981
3982        A_NETBUF_FREE(osBuf);
3983    }
3984
3985}
3986
3987
3988    /* refill the amsdu buffer list */
3989static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count)
3990{
3991    HTC_PACKET  *pPacket;
3992    void        *osBuf;
3993
3994    while (Count > 0) {
3995        osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
3996        if (NULL == osBuf) {
3997            break;
3998        }
3999            /* the HTC packet wrapper is at the head of the reserved area
4000             * in the skb */
4001        pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
4002            /* set re-fill info */
4003        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
4004
4005        AR6000_SPIN_LOCK(&ar->arLock, 0);
4006            /* put it in the list */
4007        HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
4008        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4009        Count--;
4010    }
4011
4012}
4013
4014    /* callback to allocate a large receive buffer for a pending packet.  This function is called when
4015     * an HTC packet arrives whose length exceeds a threshold value
4016     *
4017     * We use a pre-allocated list of buffers of maximum AMSDU size (4K).  Under linux it is more optimal to
4018     * keep the allocation size the same to optimize cached-slab allocations.
4019     *
4020     * */
4021static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
4022{
4023    HTC_PACKET  *pPacket = NULL;
4024    AR_SOFTC_T  *ar = (AR_SOFTC_T *)Context;
4025    int         refillCount = 0;
4026
4027    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
4028
4029    do {
4030
4031        if (Length <= AR6000_BUFFER_SIZE) {
4032                /* shouldn't be getting called on normal sized packets */
4033            A_ASSERT(FALSE);
4034            break;
4035        }
4036
4037        if (Length > AR6000_AMSDU_BUFFER_SIZE) {
4038            A_ASSERT(FALSE);
4039            break;
4040        }
4041
4042        AR6000_SPIN_LOCK(&ar->arLock, 0);
4043            /* allocate a packet from the list */
4044        pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4045            /* see if we need to refill again */
4046        refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
4047        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4048
4049        if (NULL == pPacket) {
4050            break;
4051        }
4052            /* set actual endpoint ID */
4053        pPacket->Endpoint = Endpoint;
4054
4055    } while (FALSE);
4056
4057    if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
4058        ar6000_refill_amsdu_rxbufs(ar,refillCount);
4059    }
4060
4061    return pPacket;
4062}
4063
4064static void     
4065ar6000_set_multicast_list(struct net_device *dev)
4066{
4067    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
4068}
4069
4070static struct net_device_stats *
4071ar6000_get_stats(struct net_device *dev)
4072{
4073    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
4074    return &ar->arNetStats;
4075}
4076
4077static struct iw_statistics *
4078ar6000_get_iwstats(struct net_device * dev)
4079{
4080    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
4081    TARGET_STATS *pStats = &ar->arTargetStats;
4082    struct iw_statistics * pIwStats = &ar->arIwStats;
4083    int rtnllocked;
4084
4085    if (ar->bIsDestroyProgress || ar->arWmiReady == FALSE || ar->arWlanState == WLAN_DISABLED)
4086    {
4087        pIwStats->status = 0;
4088        pIwStats->qual.qual = 0;
4089        pIwStats->qual.level =0;
4090        pIwStats->qual.noise = 0;
4091        pIwStats->discard.code =0;
4092        pIwStats->discard.retries=0;
4093        pIwStats->miss.beacon =0;
4094        return pIwStats;
4095    }
4096
4097    /*
4098     * The in_atomic function is used to determine if the scheduling is
4099     * allowed in the current context or not. This was introduced in 2.6
4100     * From what I have read on the differences between 2.4 and 2.6, the
4101     * 2.4 kernel did not support preemption and so this check might not
4102     * be required for 2.4 kernels.
4103     */
4104    if (in_atomic())
4105    {
4106        wmi_get_stats_cmd(ar->arWmi);
4107
4108        pIwStats->status = 1 ;
4109        pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
4110        pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
4111        pIwStats->qual.noise = pStats->noise_floor_calibation;
4112        pIwStats->discard.code = pStats->rx_decrypt_err;
4113        pIwStats->discard.retries = pStats->tx_retry_cnt;
4114        pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
4115        return pIwStats;
4116    }
4117
4118    dev_hold(dev);   
4119    rtnllocked = rtnl_is_locked();
4120    if (rtnllocked) {
4121        rtnl_unlock();
4122    }
4123    pIwStats->status = 0;
4124
4125    if (down_interruptible(&ar->arSem)) {
4126        goto err_exit;
4127    }
4128    
4129    do {
4130
4131        if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
4132            break;
4133        }
4134    
4135        ar->statsUpdatePending = TRUE;
4136    
4137        if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
4138            break;
4139        }
4140    
4141        wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
4142        if (signal_pending(current)) {
4143            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n"));
4144            break;
4145        }
4146        pIwStats->status = 1 ;
4147        pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
4148        pIwStats->qual.level =pStats->cs_aveBeacon_rssi;  /* noise is -95 dBm */
4149        pIwStats->qual.noise = pStats->noise_floor_calibation;
4150        pIwStats->discard.code = pStats->rx_decrypt_err;
4151        pIwStats->discard.retries = pStats->tx_retry_cnt;
4152        pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
4153    } while (0);
4154    up(&ar->arSem);
4155
4156err_exit:
4157    if (rtnllocked) {
4158        rtnl_lock();
4159    }
4160    dev_put(dev);
4161    return pIwStats;
4162}
4163
4164void
4165ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver)
4166{
4167    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
4168    struct net_device *dev = ar->arNetDev;
4169
4170    A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
4171    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
4172        dev->dev_addr[0], dev->dev_addr[1],
4173        dev->dev_addr[2], dev->dev_addr[3],
4174        dev->dev_addr[4], dev->dev_addr[5]));
4175
4176    ar->arPhyCapability = phyCap;
4177    ar->arVersion.wlan_ver = sw_ver;
4178    ar->arVersion.abi_ver = abi_ver;
4179
4180    /* Indicate to the waiting thread that the ready event was received */
4181    ar->arWmiReady = TRUE;
4182    wake_up(&arEvent);
4183
4184#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
4185    wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN);
4186#endif
4187#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
4188    wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP);
4189#endif
4190    wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL);
4191#if WLAN_CONFIG_DISABLE_11N
4192    {
4193        WMI_SET_HT_CAP_CMD htCap;
4194
4195        A_MEMZERO(&htCap, sizeof(WMI_SET_HT_CAP_CMD));
4196        htCap.band = 0;
4197        wmi_set_ht_cap_cmd(ar->arWmi, &htCap);
4198
4199        htCap.band = 1;
4200        wmi_set_ht_cap_cmd(ar->arWmi, &htCap);
4201    }
4202#endif /* WLAN_CONFIG_DISABLE_11N */
4203
4204#ifdef ATH6K_CONFIG_OTA_MODE
4205    wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
4206#endif
4207    wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT);
4208}
4209
4210void
4211add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie,
4212            A_UINT8 ielen, A_UINT8 keymgmt, A_UINT8 ucipher, A_UINT8 auth)
4213{
4214    A_UINT8    free_slot=aid-1;
4215
4216        A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
4217        A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
4218        ar->sta_list[free_slot].aid = aid;
4219        ar->sta_list[free_slot].keymgmt = keymgmt;
4220        ar->sta_list[free_slot].ucipher = ucipher;
4221        ar->sta_list[free_slot].auth = auth;
4222        ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
4223    ar->arAPStats.sta[free_slot].aid = aid;
4224}
4225
4226void
4227ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
4228                     A_UINT16 listenInterval, A_UINT16 beaconInterval,
4229                     NETWORK_TYPE networkType, A_UINT8 beaconIeLen,
4230                     A_UINT8 assocReqLen, A_UINT8 assocRespLen,
4231                     A_UINT8 *assocInfo)
4232{
4233    union iwreq_data wrqu;
4234    int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
4235    static const char *tag1 = "ASSOCINFO(ReqIEs=";
4236    static const char *tag2 = "ASSOCRESPIE=";
4237    static const char *beaconIetag = "BEACONIE=";
4238    char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
4239    char *pos;
4240    A_UINT8 key_op_ctrl;
4241    unsigned long flags;
4242    struct ieee80211req_key *ik;
4243    CRYPTO_TYPE keyType = NONE_CRYPT;
4244
4245    if(ar->arNetworkType & AP_NETWORK) {
4246        struct net_device *dev = ar->arNetDev;
4247        if(A_MEMCMP(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
4248            ar->arACS = channel;
4249            ik = &ar->ap_mode_bkey;
4250
4251            switch(ar->arAuthMode) {
4252            case NONE_AUTH:
4253                if(ar->arPairwiseCrypto == WEP_CRYPT) {
4254                    ar6000_install_static_wep_keys(ar);
4255                }
4256#ifdef WAPI_ENABLE
4257                else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
4258                    ap_set_wapi_key(ar, ik);
4259                }
4260#endif
4261                break;
4262            case WPA_PSK_AUTH:
4263            case WPA2_PSK_AUTH:
4264            case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
4265                switch (ik->ik_type) {
4266                    case IEEE80211_CIPHER_TKIP:
4267                        keyType = TKIP_CRYPT;
4268                        break;
4269                    case IEEE80211_CIPHER_AES_CCM:
4270                        keyType = AES_CRYPT;
4271                        break;
4272                    default:
4273                       goto skip_key;
4274                }
4275                wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
4276                                ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
4277                                ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
4278                                SYNC_BOTH_WMIFLAG);
4279
4280                break;
4281            }
4282skip_key:
4283            ar->arConnected  = TRUE;
4284            return;
4285        }
4286
4287        A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
4288            " AID=%d \n", bssid[0], bssid[1], bssid[2],
4289             bssid[3], bssid[4], bssid[5], channel);
4290        switch ((listenInterval>>8)&0xFF) {
4291            case OPEN_AUTH:
4292                A_PRINTF("AUTH: OPEN\n");
4293                break;
4294            case SHARED_AUTH:
4295                A_PRINTF("AUTH: SHARED\n");
4296                break;
4297            default:
4298                A_PRINTF("AUTH: Unknown\n");
4299                break;
4300        };
4301        switch (listenInterval&0xFF) {
4302            case WPA_PSK_AUTH:
4303                A_PRINTF("KeyMgmt: WPA-PSK\n");
4304                break;
4305            case WPA2_PSK_AUTH:
4306                A_PRINTF("KeyMgmt: WPA2-PSK\n");
4307                break;
4308            default:
4309                A_PRINTF("KeyMgmt: NONE\n");
4310                break;
4311        };
4312        switch (beaconInterval) {
4313            case AES_CRYPT:
4314                A_PRINTF("Cipher: AES\n");
4315                break;
4316            case TKIP_CRYPT:
4317                A_PRINTF("Cipher: TKIP\n");
4318                break;
4319            case WEP_CRYPT:
4320                A_PRINTF("Cipher: WEP\n");
4321                break;
4322#ifdef WAPI_ENABLE
4323            case WAPI_CRYPT:
4324                A_PRINTF("Cipher: WAPI\n");
4325                break;
4326#endif
4327            default:
4328                A_PRINTF("Cipher: NONE\n");
4329                break;
4330        };
4331
4332        add_new_sta(ar, bssid, channel /*aid*/,
4333            assocInfo /* WPA IE */, assocRespLen /* IE len */,
4334            listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
4335            (listenInterval>>8)&0xFF /* auth alg */);
4336
4337        /* Send event to application */
4338        A_MEMZERO(&wrqu, sizeof(wrqu));
4339        A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4340        wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
4341        /* In case the queue is stopped when we switch modes, this will
4342         * wake it up
4343         */
4344        netif_wake_queue(ar->arNetDev);
4345        return;
4346    }
4347
4348#ifdef ATH6K_CONFIG_CFG80211
4349    ar6k_cfg80211_connect_event(ar, channel, bssid,
4350                                listenInterval, beaconInterval,
4351                                networkType, beaconIeLen,
4352                                assocReqLen, assocRespLen,
4353                                assocInfo);
4354#endif /* ATH6K_CONFIG_CFG80211 */
4355
4356    A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid));
4357    ar->arBssChannel = channel;
4358
4359    A_PRINTF("AR6000 connected event on freq %d ", channel);
4360    A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4361            " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
4362            " assocRespLen =%d\n",
4363             bssid[0], bssid[1], bssid[2],
4364             bssid[3], bssid[4], bssid[5],
4365             listenInterval, beaconInterval,
4366             beaconIeLen, assocReqLen, assocRespLen);
4367    if (networkType & ADHOC_NETWORK) {
4368        if (networkType & ADHOC_CREATOR) {
4369            A_PRINTF("Network: Adhoc (Creator)\n");
4370        } else {
4371            A_PRINTF("Network: Adhoc (Joiner)\n");
4372        }
4373    } else {
4374        A_PRINTF("Network: Infrastructure\n");
4375    }
4376
4377    if ((ar->arNetworkType == INFRA_NETWORK)) {
4378        wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
4379    }
4380
4381    if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
4382        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
4383
4384        beacon_ie_pos = 0;
4385        A_MEMZERO(buf, sizeof(buf));
4386        sprintf(buf, "%s", beaconIetag);
4387        pos = buf + 9;
4388        for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
4389            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4390            sprintf(pos, "%2.2x", assocInfo[i]);
4391            pos += 2;
4392        }
4393        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4394
4395        A_MEMZERO(&wrqu, sizeof(wrqu));
4396        wrqu.data.length = strlen(buf);
4397        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4398    }
4399
4400    if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
4401    {
4402        assoc_resp_ie_pos = beaconIeLen + assocReqLen +
4403                            sizeof(A_UINT16)  +  /* capinfo*/
4404                            sizeof(A_UINT16)  +  /* status Code */
4405                            sizeof(A_UINT16)  ;  /* associd */
4406        A_MEMZERO(buf, sizeof(buf));
4407        sprintf(buf, "%s", tag2);
4408        pos = buf + 12;
4409        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
4410        /*
4411         * The Association Response Frame w.o. the WLAN header is delivered to
4412         * the host, so skip over to the IEs
4413         */
4414        for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
4415        {
4416            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4417            sprintf(pos, "%2.2x", assocInfo[i]);
4418            pos += 2;
4419        }
4420        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4421
4422        A_MEMZERO(&wrqu, sizeof(wrqu));
4423        wrqu.data.length = strlen(buf);
4424        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4425    }
4426
4427    if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
4428        /*
4429         * assoc Request includes capability and listen interval. Skip these.
4430         */
4431        assoc_req_ie_pos =  beaconIeLen +
4432                            sizeof(A_UINT16)  +  /* capinfo*/
4433                            sizeof(A_UINT16);    /* listen interval */
4434
4435        A_MEMZERO(buf, sizeof(buf));
4436        sprintf(buf, "%s", tag1);
4437        pos = buf + 17;
4438        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
4439        for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
4440            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4441            sprintf(pos, "%2.2x", assocInfo[i]);
4442            pos += 2;
4443        }
4444        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4445
4446        A_MEMZERO(&wrqu, sizeof(wrqu));
4447        wrqu.data.length = strlen(buf);
4448        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4449    }
4450
4451#ifdef USER_KEYS
4452    if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
4453        ar->user_saved_keys.keyOk == TRUE)
4454    {
4455        key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
4456
4457        if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
4458            key_op_ctrl &= ~KEY_OP_INIT_RSC;
4459        } else {
4460            key_op_ctrl |= KEY_OP_INIT_RSC;
4461        }
4462        ar6000_reinstall_keys(ar, key_op_ctrl);
4463    }
4464#endif /* USER_KEYS */
4465
4466    netif_wake_queue(ar->arNetDev);
4467
4468    /* For CFG80211 the key configuration and the default key comes in after connect so no point in plumbing invalid keys */
4469#ifndef ATH6K_CONFIG_CFG80211
4470    if ((networkType & ADHOC_NETWORK)      &&
4471        (OPEN_AUTH == ar->arDot11AuthMode) &&
4472        (NONE_AUTH == ar->arAuthMode)      &&
4473        (WEP_CRYPT == ar->arPairwiseCrypto))
4474    {
4475        if (!ar->arConnected) {
4476            wmi_addKey_cmd(ar->arWmi,
4477                           ar->arDefTxKeyIndex,
4478                           WEP_CRYPT,
4479                           GROUP_USAGE | TX_USAGE,
4480                           ar->arWepKeyList[ar->arDefTxKeyIndex].arKeyLen,
4481                           NULL,
4482                           ar->arWepKeyList[ar->arDefTxKeyIndex].arKey, KEY_OP_INIT_VAL, NULL,
4483                           NO_SYNC_WMIFLAG);
4484        }
4485    }
4486#endif /* ATH6K_CONFIG_CFG80211 */
4487
4488    /* Update connect & link status atomically */
4489    spin_lock_irqsave(&ar->arLock, flags);
4490    ar->arConnected  = TRUE;
4491    ar->arConnectPending = FALSE;
4492    netif_carrier_on(ar->arNetDev);
4493    spin_unlock_irqrestore(&ar->arLock, flags);
4494    /* reset the rx aggr state */
4495    aggr_reset_state(ar->aggr_cntxt);
4496    reconnect_flag = 0;
4497
4498    A_MEMZERO(&wrqu, sizeof(wrqu));
4499    A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
4500    wrqu.addr.sa_family = ARPHRD_ETHER;
4501    wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4502    if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
4503        A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
4504        ar->arNodeNum = 0;
4505        ar->arNexEpId = ENDPOINT_2;
4506    }
4507   if (!ar->arUserBssFilter) {
4508        wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4509   }
4510
4511}
4512
4513void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num)
4514{
4515    A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
4516    ar->arNumDataEndPts = num;
4517}
4518
4519void
4520sta_cleanup(AR_SOFTC_T *ar, A_UINT8 i)
4521{
4522    struct sk_buff *skb;
4523
4524    /* empty the queued pkts in the PS queue if any */
4525    A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
4526    while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
4527        skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
4528        A_NETBUF_FREE(skb);
4529    }
4530    A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
4531
4532    /* Zero out the state fields */
4533    A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
4534    A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
4535    A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
4536    ar->sta_list[i].aid = 0;
4537    ar->sta_list[i].flags = 0;
4538
4539    ar->sta_list_index = ar->sta_list_index & ~(1 << i);
4540
4541}
4542
4543A_UINT8
4544remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason)
4545{
4546    A_UINT8 i, removed=0;
4547
4548    if(IS_MAC_NULL(mac)) {
4549        return removed;
4550    }
4551
4552    if(IS_MAC_BCAST(mac)) {
4553        A_PRINTF("DEL ALL STA\n");
4554        for(i=0; i < AP_MAX_NUM_STA; i++) {
4555            if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
4556                sta_cleanup(ar, i);
4557                removed = 1;
4558            }
4559        }
4560    } else {
4561        for(i=0; i < AP_MAX_NUM_STA; i++) {
4562            if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
4563                A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4564                " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
4565                 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
4566
4567                sta_cleanup(ar, i);
4568                removed = 1;
4569                break;
4570            }
4571        }
4572    }
4573    return removed;
4574}
4575
4576void
4577ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid,
4578                        A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
4579{
4580    A_UINT8 i;
4581    unsigned long flags;
4582    union iwreq_data wrqu;
4583
4584    if(ar->arNetworkType & AP_NETWORK) {
4585        union iwreq_data wrqu;
4586        struct sk_buff *skb;
4587
4588        if(!remove_sta(ar, bssid, protocolReasonStatus)) {
4589            return;
4590        }
4591
4592        /* If there are no more associated STAs, empty the mcast PS q */
4593        if (ar->sta_list_index == 0) {
4594            A_MUTEX_LOCK(&ar->mcastpsqLock);
4595            while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
4596                skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
4597                A_NETBUF_FREE(skb);
4598            }
4599            A_MUTEX_UNLOCK(&ar->mcastpsqLock);
4600
4601            /* Clear the LSB of the BitMapCtl field of the TIM IE */
4602            if (ar->arWmiReady) {
4603                wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
4604            }
4605        }
4606
4607        if(!IS_MAC_BCAST(bssid)) {
4608            /* Send event to application */
4609            A_MEMZERO(&wrqu, sizeof(wrqu));
4610            A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4611            wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
4612        }
4613        return;
4614    }
4615
4616#ifdef ATH6K_CONFIG_CFG80211
4617    ar6k_cfg80211_disconnect_event(ar, reason, bssid,
4618                                   assocRespLen, assocInfo,
4619                                   protocolReasonStatus);
4620#endif /* ATH6K_CONFIG_CFG80211 */
4621
4622    /* Send disconnect event to supplicant */
4623    A_MEMZERO(&wrqu, sizeof(wrqu));
4624    wrqu.addr.sa_family = ARPHRD_ETHER;
4625    wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4626
4627    /* it is necessary to clear the host-side rx aggregation state */
4628    aggr_reset_state(ar->aggr_cntxt);
4629
4630    A_UNTIMEOUT(&ar->disconnect_timer);
4631
4632    A_PRINTF("AR6000 disconnected");
4633    if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
4634        A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4635                 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
4636    }
4637
4638    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
4639    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
4640    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
4641                    assocRespLen ? " " : "NULL"));
4642    for (i = 0; i < assocRespLen; i++) {
4643        if (!(i % 0x10)) {
4644            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4645        }
4646        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4647    }
4648    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4649    /*
4650     * If the event is due to disconnect cmd from the host, only they the target
4651     * would stop trying to connect. Under any other condition, target would
4652     * keep trying to connect.
4653     *
4654     */
4655    if( reason == DISCONNECT_CMD)
4656    {
4657        ar->arConnectPending = FALSE;
4658        if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
4659            wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4660        }
4661    } else {
4662        ar->arConnectPending = TRUE;
4663        if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
4664            ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
4665            ar->arConnected = TRUE;
4666            return;
4667        }
4668    }
4669
4670    if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady)) 
4671    {
4672        bss_t *pWmiSsidnode = NULL;
4673
4674        /* remove the current associated bssid node */
4675        wmi_free_node (ar->arWmi, bssid);
4676
4677        /*
4678         * In case any other same SSID nodes are present
4679         * remove it, since those nodes also not available now
4680         */
4681        do
4682        {
4683            /*
4684             * Find the nodes based on SSID and remove it
4685             * NOTE :: This case will not work out for Hidden-SSID
4686             */
4687            pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, FALSE, TRUE);
4688
4689            if (pWmiSsidnode)
4690            {
4691                wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
4692            }
4693
4694        } while (pWmiSsidnode);
4695    }
4696
4697    /* Update connect & link status atomically */
4698    spin_lock_irqsave(&ar->arLock, flags);
4699    ar->arConnected = FALSE;
4700    netif_carrier_off(ar->arNetDev);
4701    spin_unlock_irqrestore(&ar->arLock, flags);
4702
4703    if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
4704        reconnect_flag = 0;
4705    }
4706
4707#ifdef USER_KEYS
4708    if (reason != CSERV_DISCONNECT)
4709    {
4710        ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
4711        ar->user_key_ctrl      = 0;
4712    }
4713#endif /* USER_KEYS */
4714
4715    netif_stop_queue(ar->arNetDev);
4716    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
4717    ar->arBssChannel = 0;
4718    ar->arBeaconInterval = 0;
4719
4720    ar6000_TxDataCleanup(ar);
4721}
4722
4723void
4724ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode)
4725{
4726    A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
4727    ar->arRegCode = regCode;
4728}
4729
4730#ifdef ATH_AR6K_11N_SUPPORT
4731void
4732ar6000_aggr_rcv_addba_req_evt(AR_SOFTC_T *ar, WMI_ADDBA_REQ_EVENT *evt)
4733{
4734    if(evt->status == 0) {
4735        aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
4736    }
4737}
4738
4739void
4740ar6000_aggr_rcv_addba_resp_evt(AR_SOFTC_T *ar, WMI_ADDBA_RESP_EVENT *evt)
4741{
4742    A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
4743    if(evt->status == 0) {
4744    }
4745}
4746
4747void
4748ar6000_aggr_rcv_delba_req_evt(AR_SOFTC_T *ar, WMI_DELBA_EVENT *evt)
4749{
4750    aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
4751}
4752#endif
4753
4754void register_pal_cb(ar6k_pal_config_t *palConfig_p)
4755{
4756  ar6k_pal_config_g = *palConfig_p;
4757}
4758
4759void
4760ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
4761{
4762    void *osbuf = NULL;
4763    A_INT8 i;
4764    A_UINT8 size, *buf;
4765    A_STATUS ret = A_OK;
4766
4767    size = cmd->evt_buf_sz + 4;
4768    osbuf = A_NETBUF_ALLOC(size);
4769    if (osbuf == NULL) {
4770       ret = A_NO_MEMORY;
4771       A_PRINTF("Error in allocating netbuf \n");
4772       return;
4773    }
4774
4775    A_NETBUF_PUT(osbuf, size);
4776    buf = (A_UINT8 *)A_NETBUF_DATA(osbuf);
4777    /* First 2-bytes carry HCI event/ACL data type
4778     * the next 2 are free
4779     */
4780    *((short *)buf) = WMI_HCI_EVENT_EVENTID;
4781    buf += sizeof(int);
4782    A_MEMCPY(buf, cmd->buf, cmd->evt_buf_sz);
4783
4784    if(ar6k_pal_config_g.fpar6k_pal_recv_pkt)
4785    {
4786      /* pass the cmd packet to PAL driver */
4787      if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == TRUE)
4788        return;
4789    }
4790    ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
4791    if(loghci) {
4792        A_PRINTF_LOG("HCI Event From PAL <-- \n");
4793        for(i = 0; i < cmd->evt_buf_sz; i++) {
4794           A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
4795           if((i % 10) == 0) {
4796               A_PRINTF_LOG("\n");
4797           }
4798        }
4799        A_PRINTF_LOG("\n");
4800        A_PRINTF_LOG("==================================\n");
4801    }
4802}
4803
4804void
4805ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info)
4806{
4807#if WIRELESS_EXT >= 18
4808    struct iw_pmkid_cand *pmkcand;
4809#else /* WIRELESS_EXT >= 18 */
4810    static const char *tag = "PRE-AUTH";
4811    char buf[128];
4812#endif /* WIRELESS_EXT >= 18 */
4813
4814    union iwreq_data wrqu;
4815    int i;
4816
4817    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
4818    for (i=0; i < numAps; info++, i++) {
4819        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4820            info->bssid[0], info->bssid[1], info->bssid[2],
4821            info->bssid[3], info->bssid[4], info->bssid[5]));
4822        if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
4823            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
4824        }
4825        if (info->bssFlags & WMI_PMKID_VALID_BSS) {
4826            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
4827            continue;           /* we skip bss if the pmkid is already valid */
4828        }
4829        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
4830        A_MEMZERO(&wrqu, sizeof(wrqu));
4831#if WIRELESS_EXT >= 18
4832        pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
4833        A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
4834        pmkcand->index = i;
4835        pmkcand->flags = info->bssFlags;
4836        A_MEMCPY(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
4837        wrqu.data.length = sizeof(struct iw_pmkid_cand);
4838        wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
4839        A_FREE(pmkcand);
4840#else /* WIRELESS_EXT >= 18 */
4841        snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
4842                 tag,
4843                 info->bssid[0], info->bssid[1], info->bssid[2],
4844                 info->bssid[3], info->bssid[4], info->bssid[5],
4845                 i, info->bssFlags);
4846        wrqu.data.length = strlen(buf);
4847        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4848#endif /* WIRELESS_EXT >= 18 */
4849    }
4850}
4851
4852void
4853ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
4854{
4855    static const char *tag = "MLME-MICHAELMICFAILURE.indication";
4856    char buf[128];
4857    union iwreq_data wrqu;
4858
4859    /*
4860     * For AP case, keyid will have aid of STA which sent pkt with
4861     * MIC error. Use this aid to get MAC & send it to hostapd.
4862     */
4863    if (ar->arNetworkType == AP_NETWORK) {
4864        sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
4865        if(!s){
4866            A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
4867            return;
4868        }
4869        A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
4870        snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4871            tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
4872    } else {
4873
4874#ifdef ATH6K_CONFIG_CFG80211
4875    ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
4876#endif /* ATH6K_CONFIG_CFG80211 */
4877
4878        A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
4879             keyid & 0x3, ismcast ? "multi": "uni");
4880        snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
4881             ismcast ? "mult" : "un");
4882    }
4883
4884    memset(&wrqu, 0, sizeof(wrqu));
4885    wrqu.data.length = strlen(buf);
4886    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4887}
4888
4889void
4890ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
4891{
4892
4893#ifdef ATH6K_CONFIG_CFG80211
4894    ar6k_cfg80211_scanComplete_event(ar, status);
4895#endif /* ATH6K_CONFIG_CFG80211 */
4896
4897    if (!ar->arUserBssFilter) {
4898        wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4899    }
4900    if (ar->scan_triggered) {
4901        if (status==A_OK) {
4902            union iwreq_data wrqu;
4903            A_MEMZERO(&wrqu, sizeof(wrqu));
4904            wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
4905        }
4906        ar->scan_triggered = 0;
4907    }
4908
4909    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
4910}
4911
4912void
4913ar6000_targetStats_event(AR_SOFTC_T *ar,  A_UINT8 *ptr, A_UINT32 len)
4914{
4915    A_UINT8 ac;
4916
4917    if(ar->arNetworkType == AP_NETWORK) {
4918        WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
4919        WMI_AP_MODE_STAT *ap = &ar->arAPStats;
4920
4921        if (len < sizeof(*p)) {
4922            return;
4923        }
4924
4925        for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
4926            ap->sta[ac].tx_bytes   += p->sta[ac].tx_bytes;
4927            ap->sta[ac].tx_pkts    += p->sta[ac].tx_pkts;
4928            ap->sta[ac].tx_error   += p->sta[ac].tx_error;
4929            ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
4930            ap->sta[ac].rx_bytes   += p->sta[ac].rx_bytes;
4931            ap->sta[ac].rx_pkts    += p->sta[ac].rx_pkts;
4932            ap->sta[ac].rx_error   += p->sta[ac].rx_error;
4933            ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
4934        }
4935
4936    } else {
4937        WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
4938         TARGET_STATS *pStats = &ar->arTargetStats;
4939
4940        if (len < sizeof(*pTarget)) {
4941            return;
4942        }
4943
4944        // Update the RSSI of the connected bss.
4945        if (ar->arConnected) {
4946            bss_t *pConnBss = NULL;
4947
4948            pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
4949            if (pConnBss)
4950            {
4951                pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4952                pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
4953                wmi_node_return(ar->arWmi, pConnBss);
4954            }
4955        }
4956
4957        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
4958        pStats->tx_packets          += pTarget->txrxStats.tx_stats.tx_packets;
4959        pStats->tx_bytes            += pTarget->txrxStats.tx_stats.tx_bytes;
4960        pStats->tx_unicast_pkts     += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
4961        pStats->tx_unicast_bytes    += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
4962        pStats->tx_multicast_pkts   += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
4963        pStats->tx_multicast_bytes  += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
4964        pStats->tx_broadcast_pkts   += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
4965        pStats->tx_broadcast_bytes  += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
4966        pStats->tx_rts_success_cnt  += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
4967        for(ac = 0; ac < WMM_NUM_AC; ac++)
4968            pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
4969        pStats->tx_errors           += pTarget->txrxStats.tx_stats.tx_errors;
4970        pStats->tx_failed_cnt       += pTarget->txrxStats.tx_stats.tx_failed_cnt;
4971        pStats->tx_retry_cnt        += pTarget->txrxStats.tx_stats.tx_retry_cnt;
4972        pStats->tx_mult_retry_cnt   += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
4973        pStats->tx_rts_fail_cnt     += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
4974        pStats->tx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
4975
4976        pStats->rx_packets          += pTarget->txrxStats.rx_stats.rx_packets;
4977        pStats->rx_bytes            += pTarget->txrxStats.rx_stats.rx_bytes;
4978        pStats->rx_unicast_pkts     += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
4979        pStats->rx_unicast_bytes    += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
4980        pStats->rx_multicast_pkts   += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
4981        pStats->rx_multicast_bytes  += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
4982        pStats->rx_broadcast_pkts   += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
4983        pStats->rx_broadcast_bytes  += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
4984        pStats->rx_fragment_pkt     += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
4985        pStats->rx_errors           += pTarget->txrxStats.rx_stats.rx_errors;
4986        pStats->rx_crcerr           += pTarget->txrxStats.rx_stats.rx_crcerr;
4987        pStats->rx_key_cache_miss   += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
4988        pStats->rx_decrypt_err      += pTarget->txrxStats.rx_stats.rx_decrypt_err;
4989        pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
4990        pStats->rx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
4991
4992
4993        pStats->tkip_local_mic_failure
4994                                += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
4995        pStats->tkip_counter_measures_invoked
4996                                += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
4997        pStats->tkip_replays        += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
4998        pStats->tkip_format_errors  += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
4999        pStats->ccmp_format_errors  += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
5000        pStats->ccmp_replays        += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
5001
5002        pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
5003        pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
5004
5005        pStats->cs_bmiss_cnt        += pTarget->cservStats.cs_bmiss_cnt;
5006        pStats->cs_lowRssi_cnt      += pTarget->cservStats.cs_lowRssi_cnt;
5007        pStats->cs_connect_cnt      += pTarget->cservStats.cs_connect_cnt;
5008        pStats->cs_disconnect_cnt   += pTarget->cservStats.cs_disconnect_cnt;
5009        pStats->cs_aveBeacon_snr    = pTarget->cservStats.cs_aveBeacon_snr;
5010        pStats->cs_aveBeacon_rssi   = pTarget->cservStats.cs_aveBeacon_rssi;
5011
5012        if (enablerssicompensation) {
5013            pStats->cs_aveBeacon_rssi =
5014                    rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
5015        }
5016        pStats->cs_lastRoam_msec    = pTarget->cservStats.cs_lastRoam_msec;
5017        pStats->cs_snr              = pTarget->cservStats.cs_snr;
5018        pStats->cs_rssi             = pTarget->cservStats.cs_rssi;
5019
5020        pStats->lq_val              = pTarget->lqVal;
5021
5022        pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
5023        pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
5024        pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
5025        pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
5026        pStats->arp_received += pTarget->arpStats.arp_received;
5027        pStats->arp_matched  += pTarget->arpStats.arp_matched;
5028        pStats->arp_replied  += pTarget->arpStats.arp_replied;
5029
5030        if (ar->statsUpdatePending) {
5031            ar->statsUpdatePending = FALSE;
5032            wake_up(&arEvent);
5033        }
5034    }
5035}
5036
5037void
5038ar6000_rssiThreshold_event(AR_SOFTC_T *ar,  WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi)
5039{
5040    USER_RSSI_THOLD userRssiThold;
5041
5042    rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
5043
5044    if (enablerssicompensation) {
5045        rssi = rssi_compensation_calc(ar, rssi);
5046    }
5047
5048    /* Send an event to the app */
5049    userRssiThold.tag = ar->rssi_map[newThreshold].tag;
5050    userRssiThold.rssi = rssi;
5051    A_PRINTF("rssi Threshold range = %d tag = %d  rssi = %d\n", newThreshold,
5052             userRssiThold.tag, userRssiThold.rssi);
5053
5054    ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssiThold, sizeof(USER_RSSI_THOLD));
5055}
5056
5057
5058void
5059ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source)
5060{
5061    if (source == APP_HB_CHALLENGE) {
5062        /* Report it to the app in case it wants a positive acknowledgement */
5063        ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID,
5064                                 (A_UINT8 *)&cookie, sizeof(cookie));
5065    } else {
5066        /* This would ignore the replys that come in after their due time */
5067        if (cookie == ar->arHBChallengeResp.seqNum) {
5068            ar->arHBChallengeResp.outstanding = FALSE;
5069        }
5070    }
5071}
5072
5073
5074void
5075ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal)
5076{
5077        static const char * const errString[] = {
5078                [WMI_TARGET_PM_ERR_FAIL]    "WMI_TARGET_PM_ERR_FAIL",
5079                [WMI_TARGET_KEY_NOT_FOUND]  "WMI_TARGET_KEY_NOT_FOUND",
5080                [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
5081                [WMI_TARGET_BMISS]          "WMI_TARGET_BMISS",
5082                [WMI_PSDISABLE_NODE_JOIN]   "WMI_PSDISABLE_NODE_JOIN"
5083        };
5084
5085    A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
5086
5087    /* One error is reported at a time, and errorval is a bitmask */
5088    if(errorVal & (errorVal - 1))
5089       return;
5090
5091    A_PRINTF("AR6000 Error type = ");
5092    switch(errorVal)
5093    {
5094        case WMI_TARGET_PM_ERR_FAIL:
5095        case WMI_TARGET_KEY_NOT_FOUND:
5096        case WMI_TARGET_DECRYPTION_ERR:
5097        case WMI_TARGET_BMISS:
5098        case WMI_PSDISABLE_NODE_JOIN:
5099            A_PRINTF("%s\n", errString[errorVal]);
5100            break;
5101        default:
5102            A_PRINTF("INVALID\n");
5103            break;
5104    }
5105
5106}
5107
5108
5109void
5110ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication,
5111                 A_UINT8 statusCode, A_UINT8 *tspecSuggestion)
5112{
5113    WMM_TSPEC_IE    *tspecIe;
5114
5115    /*
5116     * This is the TSPEC IE suggestion from AP.
5117     * Suggestion provided by AP under some error
5118     * cases, could be helpful for the host app.
5119     * Check documentation.
5120     */
5121    tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
5122
5123    /*
5124     * What do we do, if we get TSPEC rejection? One thought
5125     * that comes to mind is implictly delete the pstream...
5126     */
5127    A_PRINTF("AR6000 CAC notification. "
5128                "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
5129                 ac, cacIndication, statusCode);
5130}
5131
5132void
5133ar6000_channel_change_event(AR_SOFTC_T *ar, A_UINT16 oldChannel,
5134                            A_UINT16 newChannel)
5135{
5136    A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
5137             oldChannel, newChannel);
5138}
5139
5140#define AR6000_PRINT_BSSID(_pBss)  do {     \
5141        A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
5142                 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
5143                 (_pBss)[4],(_pBss)[5]);  \
5144} while(0)
5145
5146void
5147ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl)
5148{
5149    A_UINT8 i;
5150
5151    A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
5152              pTbl->numEntries, pTbl->roamMode);
5153    for (i= 0; i < pTbl->numEntries; i++) {
5154        A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
5155            pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
5156            pTbl->bssRoamInfo[i].bssid[2],
5157            pTbl->bssRoamInfo[i].bssid[3],
5158            pTbl->bssRoamInfo[i].bssid[4],
5159            pTbl->bssRoamInfo[i].bssid[5]);
5160        A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
5161                 " BIAS %d\n",
5162            pTbl->bssRoamInfo[i].rssi,
5163            pTbl->bssRoamInfo[i].rssidt,
5164            pTbl->bssRoamInfo[i].last_rssi,
5165            pTbl->bssRoamInfo[i].util,
5166            pTbl->bssRoamInfo[i].roam_util,
5167            pTbl->bssRoamInfo[i].bias);
5168    }
5169}
5170
5171void
5172ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
5173{
5174    A_UINT8 i,j;
5175
5176    /*Each event now contains exactly one filter, see bug 26613*/
5177    A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num,                 wow_reply->num_filters);
5178    A_PRINTF("wow mode = %s host mode = %s\n",
5179            (wow_reply->wow_mode == 0? "disabled":"enabled"),
5180            (wow_reply->host_mode == 1 ? "awake":"asleep"));
5181
5182
5183    /*If there are no patterns, the reply will only contain generic
5184      WoW information. Pattern information will exist only if there are
5185      patterns present. Bug 26716*/
5186
5187   /* If this event contains pattern information, display it*/
5188    if (wow_reply->this_filter_num) {
5189        i=0;
5190        A_PRINTF("id=%d size=%d offset=%d\n",
5191                    wow_reply->wow_filters[i].wow_filter_id,
5192                    wow_reply->wow_filters[i].wow_filter_size,
5193                    wow_reply->wow_filters[i].wow_filter_offset);
5194       A_PRINTF("wow pattern = ");
5195       for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5196             A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
5197        }
5198
5199        A_PRINTF("\nwow mask = ");
5200        for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5201            A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
5202        }
5203        A_PRINTF("\n");
5204    }
5205}
5206
5207/*
5208 * Report the Roaming related data collected on the target
5209 */
5210void
5211ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
5212{
5213    A_PRINTF("Disconnect Data : BSSID: ");
5214    AR6000_PRINT_BSSID(p->disassoc_bssid);
5215    A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
5216             p->disassoc_bss_rssi,p->disassoc_time,
5217             p->no_txrx_time);
5218    A_PRINTF("Connect Data: BSSID: ");
5219    AR6000_PRINT_BSSID(p->assoc_bssid);
5220    A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
5221             p->assoc_bss_rssi,p->assoc_time,
5222             p->allow_txrx_time);
5223}
5224
5225void
5226ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p)
5227{
5228    switch (p->roamDataType) {
5229        case ROAM_DATA_TIME:
5230            ar6000_display_roam_time(&p->u.roamTime);
5231            break;
5232        default:
5233            break;
5234    }
5235}
5236
5237void
5238ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len)
5239{
5240    struct sk_buff *skb;
5241    WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
5242
5243
5244    if (!ar->arMgmtFilter) {
5245        return;
5246    }
5247    if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
5248        (bih->frameType != BEACON_FTYPE))  ||
5249        ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
5250        (bih->frameType != PROBERESP_FTYPE)))
5251    {
5252        return;
5253    }
5254
5255    if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
5256
5257        A_NETBUF_PUT(skb, len);
5258        A_MEMCPY(A_NETBUF_DATA(skb), datap, len);
5259        skb->dev = ar->arNetDev;
5260        A_MEMCPY(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
5261        skb->ip_summed = CHECKSUM_NONE;
5262        skb->pkt_type = PACKET_OTHERHOST;
5263        skb->protocol = __constant_htons(0x0019);
5264        netif_rx(skb);
5265    }
5266}
5267
5268A_UINT32 wmiSendCmdNum;
5269
5270A_STATUS
5271ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
5272{
5273    AR_SOFTC_T       *ar = (AR_SOFTC_T *)devt;
5274    A_STATUS         status = A_OK;
5275    struct ar_cookie *cookie = NULL;
5276    int i;
5277#ifdef CONFIG_PM
5278    if (ar->arWowState != WLAN_WOW_STATE_NONE) {
5279        A_NETBUF_FREE(osbuf);
5280        return A_EACCES;
5281    }
5282#endif /* CONFIG_PM */
5283        /* take lock to protect ar6000_alloc_cookie() */
5284    AR6000_SPIN_LOCK(&ar->arLock, 0);
5285
5286    do {
5287
5288        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
5289                         (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
5290
5291        if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
5292                /* control endpoint is full, don't allocate resources, we
5293                 * are just going to drop this packet */
5294            cookie = NULL;
5295            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
5296                    (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
5297        } else {
5298            cookie = ar6000_alloc_cookie(ar);
5299        }
5300
5301        if (cookie == NULL) {
5302            status = A_NO_MEMORY;
5303            break;
5304        }
5305
5306        if(logWmiRawMsgs) {
5307            A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
5308            for(i = 0; i < a_netbuf_to_len(osbuf); i++)
5309                A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]);
5310            A_PRINTF("\n");
5311        }
5312
5313        wmiSendCmdNum++;
5314
5315    } while (FALSE);
5316
5317    if (cookie != NULL) {
5318            /* got a structure to send it out on */
5319        ar->arTxPending[eid]++;
5320
5321        if (eid != ar->arControlEp) {
5322            ar->arTotalTxDataPending++;
5323        }
5324    }
5325
5326    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5327
5328    if (cookie != NULL) {
5329        cookie->arc_bp[0] = (unsigned long)osbuf;
5330        cookie->arc_bp[1] = 0;
5331        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
5332                               cookie,
5333                               A_NETBUF_DATA(osbuf),
5334                               A_NETBUF_LEN(osbuf),
5335                               eid,
5336                               AR6K_CONTROL_PKT_TAG);
5337            /* this interface is asynchronous, if there is an error, cleanup will happen in the
5338             * TX completion callback */
5339        HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
5340        status = A_OK;
5341    }
5342
5343    if (status != A_OK) {
5344        A_NETBUF_FREE(osbuf);
5345    }
5346    return status;
5347}
5348
5349/* indicate tx activity or inactivity on a WMI stream */
5350void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active)
5351{
5352    AR_SOFTC_T  *ar = (AR_SOFTC_T *)devt;
5353    HTC_ENDPOINT_ID eid ;
5354    int i;
5355
5356    if (ar->arWmiEnabled) {
5357        eid = arAc2EndpointID(ar, TrafficClass);
5358
5359        AR6000_SPIN_LOCK(&ar->arLock, 0);
5360
5361        ar->arAcStreamActive[TrafficClass] = Active;
5362
5363        if (Active) {
5364            /* when a stream goes active, keep track of the active stream with the highest priority */
5365
5366            if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
5367                    /* set the new highest active priority */
5368                ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
5369            }
5370
5371        } else {
5372            /* when a stream goes inactive, we may have to search for the next active stream
5373             * that is the highest priority */
5374
5375            if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
5376
5377                /* the highest priority stream just went inactive */
5378
5379                    /* reset and search for the "next" highest "active" priority stream */
5380                ar->arHiAcStreamActivePri = 0;
5381                for (i = 0; i < WMM_NUM_AC; i++) {
5382                    if (ar->arAcStreamActive[i]) {
5383                        if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
5384                            /* set the new highest active priority */
5385                            ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
5386                        }
5387                    }
5388                }
5389            }
5390        }
5391
5392        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5393
5394    } else {
5395            /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
5396             * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
5397             * convert the stream ID to a endpoint */
5398        eid = arAc2EndpointID(ar, TrafficClass);
5399    }
5400
5401        /* notify HTC, this may cause credit distribution changes */
5402
5403    HTCIndicateActivityChange(ar->arHtcTarget,
5404                              eid,
5405                              Active);
5406
5407}
5408
5409void
5410ar6000_btcoex_config_event(struct ar6_softc *ar,  A_UINT8 *ptr, A_UINT32 len)
5411{
5412
5413    WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
5414    WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
5415
5416    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5417
5418    A_PRINTF("received config event\n");
5419    pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
5420    pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
5421
5422    switch (pBtcoexConfig->btProfileType) {
5423        case WMI_BTCOEX_BT_PROFILE_SCO:
5424            A_MEMCPY(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
5425                                        sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5426            break;
5427        case WMI_BTCOEX_BT_PROFILE_A2DP:
5428            A_MEMCPY(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
5429                                        sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5430            break;
5431        case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
5432            A_MEMCPY(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
5433                                        sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5434            break;
5435        case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
5436           A_MEMCPY(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
5437                                        sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5438            break;
5439    }
5440    if (ar->statsUpdatePending) {
5441         ar->statsUpdatePending = FALSE;
5442          wake_up(&arEvent);
5443    }
5444}
5445
5446void
5447ar6000_btcoex_stats_event(struct ar6_softc *ar,  A_UINT8 *ptr, A_UINT32 len)
5448{
5449    WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
5450
5451    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5452
5453    A_MEMCPY(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
5454
5455    if (ar->statsUpdatePending) {
5456         ar->statsUpdatePending = FALSE;
5457        wake_up(&arEvent);
5458    }
5459
5460}
5461module_init(ar6000_init_module);
5462module_exit(ar6000_cleanup_module);
5463
5464/* Init cookie queue */
5465static void
5466ar6000_cookie_init(AR_SOFTC_T *ar)
5467{
5468    A_UINT32    i;
5469
5470    ar->arCookieList = NULL;
5471    ar->arCookieCount = 0;
5472
5473    A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
5474
5475    for (i = 0; i < MAX_COOKIE_NUM; i++) {
5476        ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
5477    }
5478}
5479
5480/* cleanup cookie queue */
5481static void
5482ar6000_cookie_cleanup(AR_SOFTC_T *ar)
5483{
5484    /* It is gone .... */
5485    ar->arCookieList = NULL;
5486    ar->arCookieCount = 0;
5487}
5488
5489/* Init cookie queue */
5490static void
5491ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie)
5492{
5493    /* Insert first */
5494    A_ASSERT(ar != NULL);
5495    A_ASSERT(cookie != NULL);
5496
5497    cookie->arc_list_next = ar->arCookieList;
5498    ar->arCookieList = cookie;
5499    ar->arCookieCount++;
5500}
5501
5502/* cleanup cookie queue */
5503static struct ar_cookie *
5504ar6000_alloc_cookie(AR_SOFTC_T  *ar)
5505{
5506    struct ar_cookie   *cookie;
5507
5508    cookie = ar->arCookieList;
5509    if(cookie != NULL)
5510    {
5511        ar->arCookieList = cookie->arc_list_next;
5512        ar->arCookieCount--;
5513    }
5514
5515    return cookie;
5516}
5517
5518#ifdef SEND_EVENT_TO_APP
5519/*
5520 * This function is used to send event which come from taget to
5521 * the application. The buf which send to application is include
5522 * the event ID and event content.
5523 */
5524#define EVENT_ID_LEN   2
5525void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
5526                              A_UINT8 *datap, int len)
5527{
5528
5529#if (WIRELESS_EXT >= 15)
5530
5531/* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
5532
5533    char *buf;
5534    A_UINT16 size;
5535    union iwreq_data wrqu;
5536
5537    size = len + EVENT_ID_LEN;
5538
5539    if (size > IW_CUSTOM_MAX) {
5540        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
5541                eventId, size, IW_CUSTOM_MAX));
5542        return;
5543    }
5544
5545    buf = A_MALLOC_NOWAIT(size);
5546    if (NULL == buf){
5547        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
5548        return;
5549    }
5550
5551    A_MEMZERO(buf, size);
5552    A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
5553    A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
5554
5555    //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(A_UINT16*)buf, size));
5556    A_MEMZERO(&wrqu, sizeof(wrqu));
5557    wrqu.data.length = size;
5558    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5559    A_FREE(buf);
5560#endif
5561
5562
5563}
5564
5565/*
5566 * This function is used to send events larger than 256 bytes
5567 * to the application. The buf which is sent to application
5568 * includes the event ID and event content.
5569 */
5570void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
5571                                      A_UINT8 *datap, int len)
5572{
5573
5574#if (WIRELESS_EXT >= 18)
5575
5576/* IWEVGENIE exists in wireless extensions version 18 onwards */
5577
5578    char *buf;
5579    A_UINT16 size;
5580    union iwreq_data wrqu;
5581
5582    size = len + EVENT_ID_LEN;
5583
5584    if (size > IW_GENERIC_IE_MAX) {
5585        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVGENIE (max=%d) \n",
5586                        eventId, size, IW_GENERIC_IE_MAX));
5587        return;
5588    }
5589
5590    buf = A_MALLOC_NOWAIT(size);
5591    if (NULL == buf){
5592        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
5593        return;
5594    }
5595
5596    A_MEMZERO(buf, size);
5597    A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
5598    A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
5599
5600    A_MEMZERO(&wrqu, sizeof(wrqu));
5601    wrqu.data.length = size;
5602    wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf);
5603
5604    A_FREE(buf);
5605
5606#endif /* (WIRELESS_EXT >= 18) */
5607
5608}
5609#endif /* SEND_EVENT_TO_APP */
5610
5611
5612void
5613ar6000_tx_retry_err_event(void *devt)
5614{
5615    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
5616}
5617
5618void
5619ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UINT8 snr)
5620{
5621    WMI_SNR_THRESHOLD_EVENT event;
5622    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
5623
5624    event.range = newThreshold;
5625    event.snr = snr;
5626
5627    ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (A_UINT8 *)&event,
5628                             sizeof(WMI_SNR_THRESHOLD_EVENT));
5629}
5630
5631void
5632ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT8 lq)
5633{
5634    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
5635}
5636
5637
5638
5639A_UINT32
5640a_copy_to_user(void *to, const void *from, A_UINT32 n)
5641{
5642    return(copy_to_user(to, from, n));
5643}
5644
5645A_UINT32
5646a_copy_from_user(void *to, const void *from, A_UINT32 n)
5647{
5648    return(copy_from_user(to, from, n));
5649}
5650
5651
5652A_STATUS
5653ar6000_get_driver_cfg(struct net_device *dev,
5654                        A_UINT16 cfgParam,
5655                        void *result)
5656{
5657
5658    A_STATUS    ret = 0;
5659
5660    switch(cfgParam)
5661    {
5662        case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
5663           *((A_UINT32 *)result) = wlanNodeCaching;
5664           break;
5665        case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
5666           *((A_UINT32 *)result) = logWmiRawMsgs;
5667            break;
5668        default:
5669           ret = EINVAL;
5670           break;
5671    }
5672
5673    return ret;
5674}
5675
5676void
5677ar6000_keepalive_rx(void *devt, A_UINT8 configured)
5678{
5679    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
5680
5681    ar->arKeepaliveConfigured = configured;
5682    wake_up(&arEvent);
5683}
5684
5685void
5686ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList,
5687                        A_UINT8 *bssidList)
5688{
5689    A_UINT8 i, j;
5690
5691    A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
5692
5693    for (i = 0; i < numPMKID; i++) {
5694        A_PRINTF("\nBSSID %d ", i);
5695            for (j = 0; j < ATH_MAC_LEN; j++) {
5696                A_PRINTF("%2.2x", bssidList[j]);
5697            }
5698        bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
5699        A_PRINTF("\nPMKID %d ", i);
5700            for (j = 0; j < WMI_PMKID_LEN; j++) {
5701                A_PRINTF("%2.2x", pmkidList->pmkid[j]);
5702            }
5703        pmkidList = (WMI_PMKID *)((A_UINT8 *)pmkidList + ATH_MAC_LEN +
5704                                  WMI_PMKID_LEN);
5705    }
5706}
5707
5708void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid)
5709{
5710    sta_t *conn=NULL;
5711    A_BOOL isPsqEmpty = FALSE;
5712
5713    conn = ieee80211_find_conn_for_aid(ar, aid);
5714
5715    /* If the PS q for this STA is not empty, dequeue and send a pkt from
5716     * the head of the q. Also update the More data bit in the WMI_DATA_HDR
5717     * if there are more pkts for this STA in the PS q. If there are no more
5718     * pkts for this STA, update the PVB for this STA.
5719     */
5720    A_MUTEX_LOCK(&conn->psqLock);
5721    isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5722    A_MUTEX_UNLOCK(&conn->psqLock);
5723
5724    if (isPsqEmpty) {
5725        /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
5726    } else {
5727        struct sk_buff *skb = NULL;
5728
5729        A_MUTEX_LOCK(&conn->psqLock);
5730        skb = A_NETBUF_DEQUEUE(&conn->psq);
5731        A_MUTEX_UNLOCK(&conn->psqLock);
5732        /* Set the STA flag to PSPolled, so that the frame will go out */
5733        STA_SET_PS_POLLED(conn);
5734        ar6000_data_tx(skb, ar->arNetDev);
5735        STA_CLR_PS_POLLED(conn);
5736
5737        /* Clear the PVB for this STA if the queue has become empty */
5738        A_MUTEX_LOCK(&conn->psqLock);
5739        isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5740        A_MUTEX_UNLOCK(&conn->psqLock);
5741
5742        if (isPsqEmpty) {
5743            wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
5744        }
5745    }
5746}
5747
5748void ar6000_dtimexpiry_event(AR_SOFTC_T *ar)
5749{
5750    A_BOOL isMcastQueued = FALSE;
5751    struct sk_buff *skb = NULL;
5752
5753    /* If there are no associated STAs, ignore the DTIM expiry event.
5754     * There can be potential race conditions where the last associated
5755     * STA may disconnect & before the host could clear the 'Indicate DTIM'
5756     * request to the firmware, the firmware would have just indicated a DTIM
5757     * expiry event. The race is between 'clear DTIM expiry cmd' going
5758     * from the host to the firmware & the DTIM expiry event happening from
5759     * the firmware to the host.
5760     */
5761    if (ar->sta_list_index == 0) {
5762        return;
5763    }
5764
5765    A_MUTEX_LOCK(&ar->mcastpsqLock);
5766    isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
5767    A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5768
5769    A_ASSERT(isMcastQueued == FALSE);
5770
5771    /* Flush the mcast psq to the target */
5772    /* Set the STA flag to DTIMExpired, so that the frame will go out */
5773    ar->DTIMExpired = TRUE;
5774
5775    A_MUTEX_LOCK(&ar->mcastpsqLock);
5776    while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
5777        skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
5778        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5779
5780        ar6000_data_tx(skb, ar->arNetDev);
5781
5782        A_MUTEX_LOCK(&ar->mcastpsqLock);
5783    }
5784    A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5785
5786    /* Reset the DTIMExpired flag back to 0 */
5787    ar->DTIMExpired = FALSE;
5788
5789    /* Clear the LSB of the BitMapCtl field of the TIM IE */
5790    wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
5791}
5792
5793void
5794read_rssi_compensation_param(AR_SOFTC_T *ar)
5795{
5796    A_UINT8 *cust_data_ptr;
5797
5798//#define RSSICOMPENSATION_PRINT
5799
5800#ifdef RSSICOMPENSATION_PRINT
5801    A_INT16 i;
5802    cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5803    for (i=0; i<16; i++) {
5804        A_PRINTF("cust_data_%d = %x \n", i, *(A_UINT8 *)cust_data_ptr);
5805        cust_data_ptr += 1;
5806    }
5807#endif
5808
5809    cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5810
5811    rssi_compensation_param.customerID = *(A_UINT16 *)cust_data_ptr & 0xffff;
5812    rssi_compensation_param.enable = *(A_UINT16 *)(cust_data_ptr+2) & 0xffff;
5813    rssi_compensation_param.bg_param_a = *(A_UINT16 *)(cust_data_ptr+4) & 0xffff;
5814    rssi_compensation_param.bg_param_b = *(A_UINT16 *)(cust_data_ptr+6) & 0xffff;
5815    rssi_compensation_param.a_param_a = *(A_UINT16 *)(cust_data_ptr+8) & 0xffff;
5816    rssi_compensation_param.a_param_b = *(A_UINT16 *)(cust_data_ptr+10) &0xffff;
5817    rssi_compensation_param.reserved = *(A_UINT32 *)(cust_data_ptr+12);
5818
5819#ifdef RSSICOMPENSATION_PRINT
5820    A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
5821    A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
5822    A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
5823    A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
5824    A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
5825    A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
5826    A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
5827#endif
5828
5829    if (rssi_compensation_param.enable != 0x1) {
5830        rssi_compensation_param.enable = 0;
5831    }
5832
5833   return;
5834}
5835
5836A_INT32
5837rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt)
5838{
5839
5840    if (freq > 5000)
5841    {
5842        if (rssi_compensation_param.enable)
5843        {
5844            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5845            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d, totalPkt = %d\n", rssi,totalPkt));
5846            rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
5847            rssi = (rssi-50) /100;
5848            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5849        }
5850    }
5851    else
5852    {
5853        if (rssi_compensation_param.enable)
5854        {
5855            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5856            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d, totalPkt = %d\n", rssi,totalPkt));
5857            rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
5858            rssi = (rssi-50) /100;
5859            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5860        }
5861    }
5862
5863    return rssi;
5864}
5865
5866A_INT16
5867rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi)
5868{
5869    if (ar->arBssChannel > 5000)
5870    {
5871        if (rssi_compensation_param.enable)
5872        {
5873            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5874            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d\n", rssi));
5875            rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
5876            rssi = (rssi-50) /100;
5877            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5878        }
5879    }
5880    else
5881    {
5882        if (rssi_compensation_param.enable)
5883        {
5884            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5885            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d\n", rssi));
5886            rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
5887            rssi = (rssi-50) /100;
5888            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5889        }
5890    }
5891
5892    return rssi;
5893}
5894
5895A_INT16
5896rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, A_BOOL Above)
5897{
5898    A_INT16 i;
5899
5900    if (ar->arBssChannel > 5000)
5901    {
5902        if (rssi_compensation_param.enable)
5903        {
5904            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5905            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation  = %d\n", rssi));
5906            rssi = rssi * 100;
5907            rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
5908            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5909        }
5910    }
5911    else
5912    {
5913        if (rssi_compensation_param.enable)
5914        {
5915            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5916            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation  = %d\n", rssi));
5917
5918            if (Above) {
5919                for (i=95; i>=0; i--) {
5920                    if (rssi <=  rssi_compensation_table[i]) {
5921                        rssi = 0 - i;
5922                        break;
5923                    }
5924                }
5925            } else {
5926                for (i=0; i<=95; i++) {
5927                    if (rssi >=  rssi_compensation_table[i]) {
5928                        rssi = 0 - i;
5929                        break;
5930                    }
5931                }
5932            }
5933            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5934        }
5935    }
5936
5937    return rssi;
5938}
5939
5940#ifdef WAPI_ENABLE
5941void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac)
5942{
5943    union iwreq_data wrqu;
5944    A_CHAR buf[20];
5945
5946    A_MEMZERO(buf, sizeof(buf));
5947
5948    strcpy(buf, "WAPI_REKEY");
5949    buf[10] = type;
5950    A_MEMCPY(&buf[11], mac, ATH_MAC_LEN);
5951
5952    A_MEMZERO(&wrqu, sizeof(wrqu));
5953    wrqu.data.length = 10+1+ATH_MAC_LEN;
5954    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5955
5956    A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
5957}
5958#endif
5959
5960#ifdef USER_KEYS
5961static A_STATUS
5962
5963ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl)
5964{
5965    A_STATUS status = A_OK;
5966    struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
5967    struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
5968    CRYPTO_TYPE  keyType = ar->user_saved_keys.keyType;
5969
5970    if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
5971        if (NONE_CRYPT == keyType) {
5972            goto _reinstall_keys_out;
5973        }
5974
5975        if (uik->ik_keylen) {
5976            status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
5977                    ar->user_saved_keys.keyType, PAIRWISE_USAGE,
5978                    uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc,
5979                    uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
5980        }
5981
5982    } else {
5983        status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
5984    }
5985
5986    if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
5987        if (NONE_CRYPT == keyType) {
5988            goto _reinstall_keys_out;
5989        }
5990
5991        if (bik->ik_keylen) {
5992            status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
5993                    ar->user_saved_keys.keyType, GROUP_USAGE,
5994                    bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc,
5995                    bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
5996        }
5997    } else {
5998        status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
5999    }
6000
6001_reinstall_keys_out:
6002    ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
6003    ar->user_key_ctrl      = 0;
6004
6005    return status;
6006}
6007#endif /* USER_KEYS */
6008
6009
6010void
6011ar6000_dset_open_req(
6012    void *context,
6013    A_UINT32 id,
6014    A_UINT32 targHandle,
6015    A_UINT32 targReplyFn,
6016    A_UINT32 targReplyArg)
6017{
6018}
6019
6020void
6021ar6000_dset_close(
6022    void *context,
6023    A_UINT32 access_cookie)
6024{
6025    return;
6026}
6027
6028void
6029ar6000_dset_data_req(
6030   void *context,
6031   A_UINT32 accessCookie,
6032   A_UINT32 offset,
6033   A_UINT32 length,
6034   A_UINT32 targBuf,
6035   A_UINT32 targReplyFn,
6036   A_UINT32 targReplyArg)
6037{
6038}
6039
6040int
6041ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
6042{
6043    WMI_CONNECT_CMD p;
6044    unsigned long  flags;
6045
6046    /* No change in AP's profile configuration */
6047    if(ar->ap_profile_flag==0) {
6048        A_PRINTF("COMMIT: No change in profile!!!\n");
6049        return -ENODATA;
6050    }
6051
6052    if(!ar->arSsidLen) {
6053        A_PRINTF("SSID not set!!!\n");
6054        return -ECHRNG;
6055    }
6056
6057    switch(ar->arAuthMode) {
6058    case NONE_AUTH:
6059        if((ar->arPairwiseCrypto != NONE_CRYPT) &&
6060#ifdef WAPI_ENABLE
6061           (ar->arPairwiseCrypto != WAPI_CRYPT) &&
6062#endif
6063           (ar->arPairwiseCrypto != WEP_CRYPT)) {
6064            A_PRINTF("Cipher not supported in AP mode Open auth\n");
6065            return -EOPNOTSUPP;
6066        }
6067        break;
6068    case WPA_PSK_AUTH:
6069    case WPA2_PSK_AUTH:
6070    case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
6071        break;
6072    default:
6073        A_PRINTF("This key mgmt type not supported in AP mode\n");
6074        return -EOPNOTSUPP;
6075    }
6076
6077    /* Update the arNetworkType */
6078    ar->arNetworkType = ar->arNextMode;
6079
6080    A_MEMZERO(&p,sizeof(p));
6081    p.ssidLength = ar->arSsidLen;
6082    A_MEMCPY(p.ssid,ar->arSsid,p.ssidLength);
6083    p.channel = ar->arChannelHint;
6084    p.networkType = ar->arNetworkType;
6085
6086    p.dot11AuthMode = ar->arDot11AuthMode;
6087    p.authMode = ar->arAuthMode;
6088    p.pairwiseCryptoType = ar->arPairwiseCrypto;
6089    p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
6090    p.groupCryptoType = ar->arGroupCrypto;
6091    p.groupCryptoLen = ar->arGroupCryptoLen;
6092    p.ctrl_flags = ar->arConnectCtrlFlags;
6093
6094    ar->arConnected = FALSE;
6095
6096    wmi_ap_profile_commit(ar->arWmi, &p);
6097    spin_lock_irqsave(&ar->arLock, flags);
6098    ar->arConnected  = TRUE;
6099    netif_carrier_on(ar->arNetDev);
6100    spin_unlock_irqrestore(&ar->arLock, flags);
6101    ar->ap_profile_flag = 0;
6102    return 0;
6103}
6104
6105A_STATUS
6106ar6000_connect_to_ap(struct ar6_softc *ar)
6107{
6108    /* The ssid length check prevents second "essid off" from the user,
6109       to be treated as a connect cmd. The second "essid off" is ignored.
6110    */
6111    if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
6112    {
6113        A_STATUS status;
6114        if((ADHOC_NETWORK != ar->arNetworkType) &&
6115           (NONE_AUTH==ar->arAuthMode)          &&
6116           (WEP_CRYPT==ar->arPairwiseCrypto)) {
6117                ar6000_install_static_wep_keys(ar);
6118        }
6119
6120        if (!ar->arUserBssFilter) {
6121            if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
6122                return -EIO;
6123            }
6124        }
6125#ifdef WAPI_ENABLE
6126        if (ar->arWapiEnable)  {
6127            ar->arPairwiseCrypto = WAPI_CRYPT;
6128            ar->arPairwiseCryptoLen = 0;
6129            ar->arGroupCrypto = WAPI_CRYPT;
6130            ar->arGroupCryptoLen = 0;
6131            ar->arAuthMode = NONE_AUTH;
6132            ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
6133        }
6134#endif
6135        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
6136                        " PW crypto %d PW crypto Len %d GRP crypto %d"\
6137                        " GRP crypto Len %d\n",
6138                        ar->arAuthMode, ar->arDot11AuthMode,
6139                        ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
6140                        ar->arGroupCrypto, ar->arGroupCryptoLen));
6141        reconnect_flag = 0;
6142        /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
6143           later set it back locally at the STA to 100/1000 TUs depending on the power mode */
6144        if ((ar->arNetworkType == INFRA_NETWORK)) {
6145            wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (A_UINT16)A_MAX_WOW_LISTEN_INTERVAL), 0);
6146        }
6147        status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
6148                                 ar->arDot11AuthMode, ar->arAuthMode,
6149                                 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
6150                                 ar->arGroupCrypto,ar->arGroupCryptoLen,
6151                                 ar->arSsidLen, ar->arSsid,
6152                                 ar->arReqBssid, ar->arChannelHint,
6153                                 ar->arConnectCtrlFlags);
6154        if (status != A_OK) {
6155            wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
6156            if (!ar->arUserBssFilter) {
6157                wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
6158            }
6159            return status;
6160        }
6161
6162        if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
6163            ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
6164        {
6165            A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
6166        }
6167
6168        ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
6169        
6170        ar->arConnectPending = TRUE;
6171        return status;    
6172    }
6173    return A_ERROR;
6174}
6175
6176A_STATUS
6177ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
6178{
6179    sta_t *conn = NULL;
6180    conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
6181
6182    A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
6183    A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
6184
6185    if(conn) {
6186        A_MEMCPY(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
6187    }
6188
6189    return 0;
6190}
6191
6192A_STATUS
6193is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd)
6194{
6195    if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
6196        cmd -= SIOCSIWCOMMIT;
6197        if(sioctl_filter[cmd] == 0xFF) return A_OK;
6198        if(sioctl_filter[cmd] & mode) return A_OK;
6199    } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
6200        cmd -= SIOCIWFIRSTPRIV;
6201        if(pioctl_filter[cmd] == 0xFF) return A_OK;
6202        if(pioctl_filter[cmd] & mode) return A_OK;
6203    } else {
6204        return A_ERROR;
6205    }
6206    return A_ENOTSUP;
6207}
6208
6209A_STATUS
6210is_xioctl_allowed(A_UINT8 mode, int cmd)
6211{
6212    if(sizeof(xioctl_filter)-1 < cmd) {
6213        A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
6214        return 0;
6215    }
6216    if(xioctl_filter[cmd] == 0xFF) return A_OK;
6217    if(xioctl_filter[cmd] & mode) return A_OK;
6218    return A_ERROR;
6219}
6220
6221#ifdef WAPI_ENABLE
6222int
6223ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
6224{
6225    struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
6226    KEY_USAGE   keyUsage = 0;
6227    A_STATUS    status;
6228
6229    if (A_MEMCMP(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
6230        keyUsage = GROUP_USAGE;
6231    } else {
6232        keyUsage = PAIRWISE_USAGE;
6233    }
6234    A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
6235        keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
6236        ik->ik_keylen);
6237
6238    status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
6239                            ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
6240                            ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
6241                            SYNC_BOTH_WMIFLAG);
6242
6243    if (A_OK != status) {
6244        return -EIO;
6245    }
6246    return 0;
6247}
6248#endif
6249
6250void ar6000_peer_event(
6251    void *context,
6252    A_UINT8 eventCode,
6253    A_UINT8 *macAddr)
6254{
6255    A_UINT8 pos;
6256
6257    for (pos=0;pos<6;pos++)
6258        printk("%02x: ",*(macAddr+pos));
6259    printk("\n");
6260}
6261
6262#ifdef HTC_TEST_SEND_PKTS
6263#define HTC_TEST_DUPLICATE 8
6264static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
6265{
6266    struct ar_cookie *cookie;
6267    struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
6268    struct sk_buff   *new_skb;
6269    int    i;
6270    int    pkts = 0;
6271    HTC_PACKET_QUEUE pktQueue;
6272    EPPING_HEADER    *eppingHdr;
6273
6274    eppingHdr = A_NETBUF_DATA(dupskb);
6275
6276    if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
6277        /* skip test if this is already a tx perf test */
6278        return;
6279    }
6280
6281    for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
6282        AR6000_SPIN_LOCK(&ar->arLock, 0);
6283        cookie = ar6000_alloc_cookie(ar);
6284        if (cookie != NULL) {
6285            ar->arTxPending[eid]++;
6286            ar->arTotalTxDataPending++;
6287        }
6288
6289        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6290
6291        if (NULL == cookie) {
6292            break;
6293        }
6294
6295        new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
6296
6297        if (new_skb == NULL) {
6298            AR6000_SPIN_LOCK(&ar->arLock, 0);
6299            ar6000_free_cookie(ar,cookie);
6300            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6301            break;
6302        }
6303
6304        A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
6305        cookie->arc_bp[0] = (unsigned long)new_skb;
6306        cookie->arc_bp[1] = MapNo;
6307        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
6308                               cookie,
6309                               A_NETBUF_DATA(new_skb),
6310                               A_NETBUF_LEN(new_skb),
6311                               eid,
6312                               AR6K_DATA_PKT_TAG);
6313
6314        cookieArray[i] = cookie;
6315
6316        {
6317            EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
6318            pHdr->Cmd_h = EPPING_CMD_NO_ECHO;  /* do not echo the packet */
6319        }
6320    }
6321
6322    if (pkts == 0) {
6323        return;
6324    }
6325
6326    INIT_HTC_PACKET_QUEUE(&pktQueue);
6327
6328    for (i = 0; i < pkts; i++) {
6329        HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
6330    }
6331
6332    HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
6333
6334}
6335#endif
6336
6337#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
6338/*
6339 * Add support for adding and removing a virtual adapter for soft AP.
6340 * Some OS requires different adapters names for station and soft AP mode.
6341 * To support these requirement, create and destory a netdevice  instance
6342 * when the AP mode is operational. A full fledged support for virual device
6343 * is not implemented. Rather a virtual interface is created and is linked
6344 * with the existing physical device instance during the operation of the 
6345 * AP mode.
6346 */
6347
6348A_STATUS ar6000_start_ap_interface(AR_SOFTC_T *ar)
6349{
6350    AR_VIRTUAL_INTERFACE_T *arApDev;
6351
6352    /* Change net_device to point to AP instance */
6353    arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev;
6354    ar->arNetDev = arApDev->arNetDev;
6355
6356    return A_OK;
6357}
6358
6359A_STATUS ar6000_stop_ap_interface(AR_SOFTC_T *ar)
6360{
6361    AR_VIRTUAL_INTERFACE_T *arApDev;
6362
6363    /* Change net_device to point to sta instance */
6364    arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev;
6365    if (arApDev) {
6366        ar->arNetDev = arApDev->arStaNetDev;
6367    }
6368
6369    return A_OK;
6370}
6371
6372
6373A_STATUS ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) 
6374{
6375    struct net_device *dev;
6376    AR_VIRTUAL_INTERFACE_T *arApDev;
6377
6378    dev = alloc_etherdev(sizeof(AR_VIRTUAL_INTERFACE_T));
6379    if (dev == NULL) {
6380        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
6381        return A_ERROR;
6382    } 
6383    
6384    ether_setup(dev);
6385    init_netdev(dev, ap_ifname);
6386
6387    if (register_netdev(dev)) {
6388        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
6389        return A_ERROR;
6390    }
6391
6392    arApDev = netdev_priv(dev);
6393    arApDev->arDev = ar;
6394    arApDev->arNetDev = dev;
6395    arApDev->arStaNetDev = ar->arNetDev;
6396
6397    ar->arApDev = arApDev;
6398    arApNetDev = dev;
6399
6400    /* Copy the MAC address */
6401    A_MEMCPY(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
6402
6403    return A_OK;
6404}
6405
6406A_STATUS ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) 
6407{
6408    /* Interface already added, need not proceed further */
6409    if (ar->arApDev != NULL) {
6410        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
6411        return A_OK;
6412    }
6413
6414    if (ar6000_create_ap_interface(ar, ap_ifname) != A_OK) {
6415        return A_ERROR;
6416    }
6417
6418    A_PRINTF("Add AP interface %s \n",ap_ifname);
6419
6420    return ar6000_start_ap_interface(ar);
6421}
6422
6423A_STATUS ar6000_remove_ap_interface(AR_SOFTC_T *ar)
6424{
6425    if (arApNetDev) {
6426        ar6000_stop_ap_interface(ar);
6427
6428        unregister_netdev(arApNetDev);
6429        free_netdev(apApNetDev);
6430
6431        A_PRINTF("Remove AP interface\n");
6432    }
6433    ar->arApDev = NULL;
6434    arApNetDev = NULL;
6435
6436    
6437    return A_OK;
6438}
6439#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
6440
6441
6442#ifdef EXPORT_HCI_BRIDGE_INTERFACE
6443EXPORT_SYMBOL(setupbtdev);
6444#endif
6445