linux/drivers/net/wireless/wl12xx/acx.c
<<
>>
Prefs
   1/*
   2 * This file is part of wl1271
   3 *
   4 * Copyright (C) 2008-2009 Nokia Corporation
   5 *
   6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * version 2 as published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful, but
  13 * WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 * 02110-1301 USA
  21 *
  22 */
  23
  24#include "acx.h"
  25
  26#include <linux/module.h>
  27#include <linux/platform_device.h>
  28#include <linux/crc7.h>
  29#include <linux/spi/spi.h>
  30#include <linux/slab.h>
  31
  32#include "wl12xx.h"
  33#include "wl12xx_80211.h"
  34#include "reg.h"
  35#include "ps.h"
  36
  37int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
  38{
  39        struct acx_wake_up_condition *wake_up;
  40        int ret;
  41
  42        wl1271_debug(DEBUG_ACX, "acx wake up conditions");
  43
  44        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
  45        if (!wake_up) {
  46                ret = -ENOMEM;
  47                goto out;
  48        }
  49
  50        wake_up->wake_up_event = wl->conf.conn.wake_up_event;
  51        wake_up->listen_interval = wl->conf.conn.listen_interval;
  52
  53        ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
  54                                   wake_up, sizeof(*wake_up));
  55        if (ret < 0) {
  56                wl1271_warning("could not set wake up conditions: %d", ret);
  57                goto out;
  58        }
  59
  60out:
  61        kfree(wake_up);
  62        return ret;
  63}
  64
  65int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
  66{
  67        struct acx_sleep_auth *auth;
  68        int ret;
  69
  70        wl1271_debug(DEBUG_ACX, "acx sleep auth");
  71
  72        auth = kzalloc(sizeof(*auth), GFP_KERNEL);
  73        if (!auth) {
  74                ret = -ENOMEM;
  75                goto out;
  76        }
  77
  78        auth->sleep_auth = sleep_auth;
  79
  80        ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
  81        if (ret < 0)
  82                return ret;
  83
  84out:
  85        kfree(auth);
  86        return ret;
  87}
  88
  89int wl1271_acx_tx_power(struct wl1271 *wl, int power)
  90{
  91        struct acx_current_tx_power *acx;
  92        int ret;
  93
  94        wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
  95
  96        if (power < 0 || power > 25)
  97                return -EINVAL;
  98
  99        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 100        if (!acx) {
 101                ret = -ENOMEM;
 102                goto out;
 103        }
 104
 105        acx->current_tx_power = power * 10;
 106
 107        ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
 108        if (ret < 0) {
 109                wl1271_warning("configure of tx power failed: %d", ret);
 110                goto out;
 111        }
 112
 113out:
 114        kfree(acx);
 115        return ret;
 116}
 117
 118int wl1271_acx_feature_cfg(struct wl1271 *wl)
 119{
 120        struct acx_feature_config *feature;
 121        int ret;
 122
 123        wl1271_debug(DEBUG_ACX, "acx feature cfg");
 124
 125        feature = kzalloc(sizeof(*feature), GFP_KERNEL);
 126        if (!feature) {
 127                ret = -ENOMEM;
 128                goto out;
 129        }
 130
 131        /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
 132        feature->data_flow_options = 0;
 133        feature->options = 0;
 134
 135        ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
 136                                   feature, sizeof(*feature));
 137        if (ret < 0) {
 138                wl1271_error("Couldnt set HW encryption");
 139                goto out;
 140        }
 141
 142out:
 143        kfree(feature);
 144        return ret;
 145}
 146
 147int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
 148                       size_t len)
 149{
 150        int ret;
 151
 152        wl1271_debug(DEBUG_ACX, "acx mem map");
 153
 154        ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
 155        if (ret < 0)
 156                return ret;
 157
 158        return 0;
 159}
 160
 161int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
 162{
 163        struct acx_rx_msdu_lifetime *acx;
 164        int ret;
 165
 166        wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
 167
 168        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 169        if (!acx) {
 170                ret = -ENOMEM;
 171                goto out;
 172        }
 173
 174        acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
 175        ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
 176                                   acx, sizeof(*acx));
 177        if (ret < 0) {
 178                wl1271_warning("failed to set rx msdu life time: %d", ret);
 179                goto out;
 180        }
 181
 182out:
 183        kfree(acx);
 184        return ret;
 185}
 186
 187int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
 188{
 189        struct acx_rx_config *rx_config;
 190        int ret;
 191
 192        wl1271_debug(DEBUG_ACX, "acx rx config");
 193
 194        rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
 195        if (!rx_config) {
 196                ret = -ENOMEM;
 197                goto out;
 198        }
 199
 200        rx_config->config_options = cpu_to_le32(config);
 201        rx_config->filter_options = cpu_to_le32(filter);
 202
 203        ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
 204                                   rx_config, sizeof(*rx_config));
 205        if (ret < 0) {
 206                wl1271_warning("failed to set rx config: %d", ret);
 207                goto out;
 208        }
 209
 210out:
 211        kfree(rx_config);
 212        return ret;
 213}
 214
 215int wl1271_acx_pd_threshold(struct wl1271 *wl)
 216{
 217        struct acx_packet_detection *pd;
 218        int ret;
 219
 220        wl1271_debug(DEBUG_ACX, "acx data pd threshold");
 221
 222        pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 223        if (!pd) {
 224                ret = -ENOMEM;
 225                goto out;
 226        }
 227
 228        pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold);
 229
 230        ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
 231        if (ret < 0) {
 232                wl1271_warning("failed to set pd threshold: %d", ret);
 233                goto out;
 234        }
 235
 236out:
 237        kfree(pd);
 238        return ret;
 239}
 240
 241int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
 242{
 243        struct acx_slot *slot;
 244        int ret;
 245
 246        wl1271_debug(DEBUG_ACX, "acx slot");
 247
 248        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 249        if (!slot) {
 250                ret = -ENOMEM;
 251                goto out;
 252        }
 253
 254        slot->wone_index = STATION_WONE_INDEX;
 255        slot->slot_time = slot_time;
 256
 257        ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
 258        if (ret < 0) {
 259                wl1271_warning("failed to set slot time: %d", ret);
 260                goto out;
 261        }
 262
 263out:
 264        kfree(slot);
 265        return ret;
 266}
 267
 268int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
 269                                 void *mc_list, u32 mc_list_len)
 270{
 271        struct acx_dot11_grp_addr_tbl *acx;
 272        int ret;
 273
 274        wl1271_debug(DEBUG_ACX, "acx group address tbl");
 275
 276        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 277        if (!acx) {
 278                ret = -ENOMEM;
 279                goto out;
 280        }
 281
 282        /* MAC filtering */
 283        acx->enabled = enable;
 284        acx->num_groups = mc_list_len;
 285        memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
 286
 287        ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
 288                                   acx, sizeof(*acx));
 289        if (ret < 0) {
 290                wl1271_warning("failed to set group addr table: %d", ret);
 291                goto out;
 292        }
 293
 294out:
 295        kfree(acx);
 296        return ret;
 297}
 298
 299int wl1271_acx_service_period_timeout(struct wl1271 *wl)
 300{
 301        struct acx_rx_timeout *rx_timeout;
 302        int ret;
 303
 304        rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
 305        if (!rx_timeout) {
 306                ret = -ENOMEM;
 307                goto out;
 308        }
 309
 310        wl1271_debug(DEBUG_ACX, "acx service period timeout");
 311
 312        rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
 313        rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
 314
 315        ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
 316                                   rx_timeout, sizeof(*rx_timeout));
 317        if (ret < 0) {
 318                wl1271_warning("failed to set service period timeout: %d",
 319                               ret);
 320                goto out;
 321        }
 322
 323out:
 324        kfree(rx_timeout);
 325        return ret;
 326}
 327
 328int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
 329{
 330        struct acx_rts_threshold *rts;
 331        int ret;
 332
 333        wl1271_debug(DEBUG_ACX, "acx rts threshold");
 334
 335        rts = kzalloc(sizeof(*rts), GFP_KERNEL);
 336        if (!rts) {
 337                ret = -ENOMEM;
 338                goto out;
 339        }
 340
 341        rts->threshold = cpu_to_le16(rts_threshold);
 342
 343        ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 344        if (ret < 0) {
 345                wl1271_warning("failed to set rts threshold: %d", ret);
 346                goto out;
 347        }
 348
 349out:
 350        kfree(rts);
 351        return ret;
 352}
 353
 354int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
 355{
 356        struct acx_dco_itrim_params *dco;
 357        struct conf_itrim_settings *c = &wl->conf.itrim;
 358        int ret;
 359
 360        wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
 361
 362        dco = kzalloc(sizeof(*dco), GFP_KERNEL);
 363        if (!dco) {
 364                ret = -ENOMEM;
 365                goto out;
 366        }
 367
 368        dco->enable = c->enable;
 369        dco->timeout = cpu_to_le32(c->timeout);
 370
 371        ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
 372                                   dco, sizeof(*dco));
 373        if (ret < 0) {
 374                wl1271_warning("failed to set dco itrim parameters: %d", ret);
 375                goto out;
 376        }
 377
 378out:
 379        kfree(dco);
 380        return ret;
 381}
 382
 383int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
 384{
 385        struct acx_beacon_filter_option *beacon_filter = NULL;
 386        int ret = 0;
 387
 388        wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
 389
 390        if (enable_filter &&
 391            wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
 392                goto out;
 393
 394        beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
 395        if (!beacon_filter) {
 396                ret = -ENOMEM;
 397                goto out;
 398        }
 399
 400        beacon_filter->enable = enable_filter;
 401
 402        /*
 403         * When set to zero, and the filter is enabled, beacons
 404         * without the unicast TIM bit set are dropped.
 405         */
 406        beacon_filter->max_num_beacons = 0;
 407
 408        ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
 409                                   beacon_filter, sizeof(*beacon_filter));
 410        if (ret < 0) {
 411                wl1271_warning("failed to set beacon filter opt: %d", ret);
 412                goto out;
 413        }
 414
 415out:
 416        kfree(beacon_filter);
 417        return ret;
 418}
 419
 420int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
 421{
 422        struct acx_beacon_filter_ie_table *ie_table;
 423        int i, idx = 0;
 424        int ret;
 425        bool vendor_spec = false;
 426
 427        wl1271_debug(DEBUG_ACX, "acx beacon filter table");
 428
 429        ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
 430        if (!ie_table) {
 431                ret = -ENOMEM;
 432                goto out;
 433        }
 434
 435        /* configure default beacon pass-through rules */
 436        ie_table->num_ie = 0;
 437        for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
 438                struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
 439                ie_table->table[idx++] = r->ie;
 440                ie_table->table[idx++] = r->rule;
 441
 442                if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
 443                        /* only one vendor specific ie allowed */
 444                        if (vendor_spec)
 445                                continue;
 446
 447                        /* for vendor specific rules configure the
 448                           additional fields */
 449                        memcpy(&(ie_table->table[idx]), r->oui,
 450                               CONF_BCN_IE_OUI_LEN);
 451                        idx += CONF_BCN_IE_OUI_LEN;
 452                        ie_table->table[idx++] = r->type;
 453                        memcpy(&(ie_table->table[idx]), r->version,
 454                               CONF_BCN_IE_VER_LEN);
 455                        idx += CONF_BCN_IE_VER_LEN;
 456                        vendor_spec = true;
 457                }
 458
 459                ie_table->num_ie++;
 460        }
 461
 462        ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 463                                   ie_table, sizeof(*ie_table));
 464        if (ret < 0) {
 465                wl1271_warning("failed to set beacon filter table: %d", ret);
 466                goto out;
 467        }
 468
 469out:
 470        kfree(ie_table);
 471        return ret;
 472}
 473
 474#define ACX_CONN_MONIT_DISABLE_VALUE  0xffffffff
 475
 476int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
 477{
 478        struct acx_conn_monit_params *acx;
 479        u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
 480        u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
 481        int ret;
 482
 483        wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
 484                     enable ? "enabled" : "disabled");
 485
 486        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 487        if (!acx) {
 488                ret = -ENOMEM;
 489                goto out;
 490        }
 491
 492        if (enable) {
 493                threshold = wl->conf.conn.synch_fail_thold;
 494                timeout = wl->conf.conn.bss_lose_timeout;
 495        }
 496
 497        acx->synch_fail_thold = cpu_to_le32(threshold);
 498        acx->bss_lose_timeout = cpu_to_le32(timeout);
 499
 500        ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
 501                                   acx, sizeof(*acx));
 502        if (ret < 0) {
 503                wl1271_warning("failed to set connection monitor "
 504                               "parameters: %d", ret);
 505                goto out;
 506        }
 507
 508out:
 509        kfree(acx);
 510        return ret;
 511}
 512
 513
 514int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
 515{
 516        struct acx_bt_wlan_coex *pta;
 517        int ret;
 518
 519        wl1271_debug(DEBUG_ACX, "acx sg enable");
 520
 521        pta = kzalloc(sizeof(*pta), GFP_KERNEL);
 522        if (!pta) {
 523                ret = -ENOMEM;
 524                goto out;
 525        }
 526
 527        if (enable)
 528                pta->enable = wl->conf.sg.state;
 529        else
 530                pta->enable = CONF_SG_DISABLE;
 531
 532        ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
 533        if (ret < 0) {
 534                wl1271_warning("failed to set softgemini enable: %d", ret);
 535                goto out;
 536        }
 537
 538out:
 539        kfree(pta);
 540        return ret;
 541}
 542
 543int wl1271_acx_sg_cfg(struct wl1271 *wl)
 544{
 545        struct acx_bt_wlan_coex_param *param;
 546        struct conf_sg_settings *c = &wl->conf.sg;
 547        int i, ret;
 548
 549        wl1271_debug(DEBUG_ACX, "acx sg cfg");
 550
 551        param = kzalloc(sizeof(*param), GFP_KERNEL);
 552        if (!param) {
 553                ret = -ENOMEM;
 554                goto out;
 555        }
 556
 557        /* BT-WLAN coext parameters */
 558        for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
 559                param->params[i] = cpu_to_le32(c->params[i]);
 560        param->param_idx = CONF_SG_PARAMS_ALL;
 561
 562        ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
 563        if (ret < 0) {
 564                wl1271_warning("failed to set sg config: %d", ret);
 565                goto out;
 566        }
 567
 568out:
 569        kfree(param);
 570        return ret;
 571}
 572
 573int wl1271_acx_cca_threshold(struct wl1271 *wl)
 574{
 575        struct acx_energy_detection *detection;
 576        int ret;
 577
 578        wl1271_debug(DEBUG_ACX, "acx cca threshold");
 579
 580        detection = kzalloc(sizeof(*detection), GFP_KERNEL);
 581        if (!detection) {
 582                ret = -ENOMEM;
 583                goto out;
 584        }
 585
 586        detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
 587        detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
 588
 589        ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
 590                                   detection, sizeof(*detection));
 591        if (ret < 0) {
 592                wl1271_warning("failed to set cca threshold: %d", ret);
 593                return ret;
 594        }
 595
 596out:
 597        kfree(detection);
 598        return ret;
 599}
 600
 601int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
 602{
 603        struct acx_beacon_broadcast *bb;
 604        int ret;
 605
 606        wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
 607
 608        bb = kzalloc(sizeof(*bb), GFP_KERNEL);
 609        if (!bb) {
 610                ret = -ENOMEM;
 611                goto out;
 612        }
 613
 614        bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
 615        bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
 616        bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
 617        bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
 618
 619        ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
 620        if (ret < 0) {
 621                wl1271_warning("failed to set rx config: %d", ret);
 622                goto out;
 623        }
 624
 625out:
 626        kfree(bb);
 627        return ret;
 628}
 629
 630int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
 631{
 632        struct acx_aid *acx_aid;
 633        int ret;
 634
 635        wl1271_debug(DEBUG_ACX, "acx aid");
 636
 637        acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
 638        if (!acx_aid) {
 639                ret = -ENOMEM;
 640                goto out;
 641        }
 642
 643        acx_aid->aid = cpu_to_le16(aid);
 644
 645        ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
 646        if (ret < 0) {
 647                wl1271_warning("failed to set aid: %d", ret);
 648                goto out;
 649        }
 650
 651out:
 652        kfree(acx_aid);
 653        return ret;
 654}
 655
 656int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
 657{
 658        struct acx_event_mask *mask;
 659        int ret;
 660
 661        wl1271_debug(DEBUG_ACX, "acx event mbox mask");
 662
 663        mask = kzalloc(sizeof(*mask), GFP_KERNEL);
 664        if (!mask) {
 665                ret = -ENOMEM;
 666                goto out;
 667        }
 668
 669        /* high event mask is unused */
 670        mask->high_event_mask = cpu_to_le32(0xffffffff);
 671        mask->event_mask = cpu_to_le32(event_mask);
 672
 673        ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
 674                                   mask, sizeof(*mask));
 675        if (ret < 0) {
 676                wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
 677                goto out;
 678        }
 679
 680out:
 681        kfree(mask);
 682        return ret;
 683}
 684
 685int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
 686{
 687        struct acx_preamble *acx;
 688        int ret;
 689
 690        wl1271_debug(DEBUG_ACX, "acx_set_preamble");
 691
 692        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 693        if (!acx) {
 694                ret = -ENOMEM;
 695                goto out;
 696        }
 697
 698        acx->preamble = preamble;
 699
 700        ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
 701        if (ret < 0) {
 702                wl1271_warning("Setting of preamble failed: %d", ret);
 703                goto out;
 704        }
 705
 706out:
 707        kfree(acx);
 708        return ret;
 709}
 710
 711int wl1271_acx_cts_protect(struct wl1271 *wl,
 712                           enum acx_ctsprotect_type ctsprotect)
 713{
 714        struct acx_ctsprotect *acx;
 715        int ret;
 716
 717        wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
 718
 719        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 720        if (!acx) {
 721                ret = -ENOMEM;
 722                goto out;
 723        }
 724
 725        acx->ctsprotect = ctsprotect;
 726
 727        ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
 728        if (ret < 0) {
 729                wl1271_warning("Setting of ctsprotect failed: %d", ret);
 730                goto out;
 731        }
 732
 733out:
 734        kfree(acx);
 735        return ret;
 736}
 737
 738int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
 739{
 740        int ret;
 741
 742        wl1271_debug(DEBUG_ACX, "acx statistics");
 743
 744        ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
 745                                     sizeof(*stats));
 746        if (ret < 0) {
 747                wl1271_warning("acx statistics failed: %d", ret);
 748                return -ENOMEM;
 749        }
 750
 751        return 0;
 752}
 753
 754int wl1271_acx_rate_policies(struct wl1271 *wl)
 755{
 756        struct acx_rate_policy *acx;
 757        struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
 758        int idx = 0;
 759        int ret = 0;
 760
 761        wl1271_debug(DEBUG_ACX, "acx rate policies");
 762
 763        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 764
 765        if (!acx) {
 766                ret = -ENOMEM;
 767                goto out;
 768        }
 769
 770        /* configure one basic rate class */
 771        idx = ACX_TX_BASIC_RATE;
 772        acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
 773        acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
 774        acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
 775        acx->rate_class[idx].aflags = c->aflags;
 776
 777        /* configure one AP supported rate class */
 778        idx = ACX_TX_AP_FULL_RATE;
 779        acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
 780        acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
 781        acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
 782        acx->rate_class[idx].aflags = c->aflags;
 783
 784        acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
 785
 786        ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 787        if (ret < 0) {
 788                wl1271_warning("Setting of rate policies failed: %d", ret);
 789                goto out;
 790        }
 791
 792out:
 793        kfree(acx);
 794        return ret;
 795}
 796
 797int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
 798                      u8 aifsn, u16 txop)
 799{
 800        struct acx_ac_cfg *acx;
 801        int ret = 0;
 802
 803        wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
 804                     "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
 805
 806        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 807
 808        if (!acx) {
 809                ret = -ENOMEM;
 810                goto out;
 811        }
 812
 813        acx->ac = ac;
 814        acx->cw_min = cw_min;
 815        acx->cw_max = cpu_to_le16(cw_max);
 816        acx->aifsn = aifsn;
 817        acx->tx_op_limit = cpu_to_le16(txop);
 818
 819        ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
 820        if (ret < 0) {
 821                wl1271_warning("acx ac cfg failed: %d", ret);
 822                goto out;
 823        }
 824
 825out:
 826        kfree(acx);
 827        return ret;
 828}
 829
 830int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
 831                       u8 tsid, u8 ps_scheme, u8 ack_policy,
 832                       u32 apsd_conf0, u32 apsd_conf1)
 833{
 834        struct acx_tid_config *acx;
 835        int ret = 0;
 836
 837        wl1271_debug(DEBUG_ACX, "acx tid config");
 838
 839        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 840
 841        if (!acx) {
 842                ret = -ENOMEM;
 843                goto out;
 844        }
 845
 846        acx->queue_id = queue_id;
 847        acx->channel_type = channel_type;
 848        acx->tsid = tsid;
 849        acx->ps_scheme = ps_scheme;
 850        acx->ack_policy = ack_policy;
 851        acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
 852        acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
 853
 854        ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
 855        if (ret < 0) {
 856                wl1271_warning("Setting of tid config failed: %d", ret);
 857                goto out;
 858        }
 859
 860out:
 861        kfree(acx);
 862        return ret;
 863}
 864
 865int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
 866{
 867        struct acx_frag_threshold *acx;
 868        int ret = 0;
 869
 870        wl1271_debug(DEBUG_ACX, "acx frag threshold");
 871
 872        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 873
 874        if (!acx) {
 875                ret = -ENOMEM;
 876                goto out;
 877        }
 878
 879        acx->frag_threshold = cpu_to_le16(frag_threshold);
 880        ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
 881        if (ret < 0) {
 882                wl1271_warning("Setting of frag threshold failed: %d", ret);
 883                goto out;
 884        }
 885
 886out:
 887        kfree(acx);
 888        return ret;
 889}
 890
 891int wl1271_acx_tx_config_options(struct wl1271 *wl)
 892{
 893        struct acx_tx_config_options *acx;
 894        int ret = 0;
 895
 896        wl1271_debug(DEBUG_ACX, "acx tx config options");
 897
 898        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 899
 900        if (!acx) {
 901                ret = -ENOMEM;
 902                goto out;
 903        }
 904
 905        acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
 906        acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
 907        ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
 908        if (ret < 0) {
 909                wl1271_warning("Setting of tx options failed: %d", ret);
 910                goto out;
 911        }
 912
 913out:
 914        kfree(acx);
 915        return ret;
 916}
 917
 918int wl1271_acx_mem_cfg(struct wl1271 *wl)
 919{
 920        struct wl1271_acx_config_memory *mem_conf;
 921        int ret;
 922
 923        wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
 924
 925        mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
 926        if (!mem_conf) {
 927                ret = -ENOMEM;
 928                goto out;
 929        }
 930
 931        /* memory config */
 932        mem_conf->num_stations = DEFAULT_NUM_STATIONS;
 933        mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
 934        mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
 935        mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
 936        mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
 937
 938        ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 939                                   sizeof(*mem_conf));
 940        if (ret < 0) {
 941                wl1271_warning("wl1271 mem config failed: %d", ret);
 942                goto out;
 943        }
 944
 945out:
 946        kfree(mem_conf);
 947        return ret;
 948}
 949
 950int wl1271_acx_init_mem_config(struct wl1271 *wl)
 951{
 952        int ret;
 953
 954        ret = wl1271_acx_mem_cfg(wl);
 955        if (ret < 0)
 956                return ret;
 957
 958        wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
 959                                     GFP_KERNEL);
 960        if (!wl->target_mem_map) {
 961                wl1271_error("couldn't allocate target memory map");
 962                return -ENOMEM;
 963        }
 964
 965        /* we now ask for the firmware built memory map */
 966        ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
 967                                 sizeof(struct wl1271_acx_mem_map));
 968        if (ret < 0) {
 969                wl1271_error("couldn't retrieve firmware memory map");
 970                kfree(wl->target_mem_map);
 971                wl->target_mem_map = NULL;
 972                return ret;
 973        }
 974
 975        /* initialize TX block book keeping */
 976        wl->tx_blocks_available =
 977                le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
 978        wl1271_debug(DEBUG_TX, "available tx blocks: %d",
 979                     wl->tx_blocks_available);
 980
 981        return 0;
 982}
 983
 984int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
 985{
 986        struct wl1271_acx_rx_config_opt *rx_conf;
 987        int ret;
 988
 989        wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
 990
 991        rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
 992        if (!rx_conf) {
 993                ret = -ENOMEM;
 994                goto out;
 995        }
 996
 997        rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
 998        rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
 999        rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
1000        rx_conf->queue_type = wl->conf.rx.queue_type;
1001
1002        ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
1003                                   sizeof(*rx_conf));
1004        if (ret < 0) {
1005                wl1271_warning("wl1271 rx config opt failed: %d", ret);
1006                goto out;
1007        }
1008
1009out:
1010        kfree(rx_conf);
1011        return ret;
1012}
1013
1014int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
1015{
1016        struct wl1271_acx_bet_enable *acx = NULL;
1017        int ret = 0;
1018
1019        wl1271_debug(DEBUG_ACX, "acx bet enable");
1020
1021        if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
1022                goto out;
1023
1024        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1025        if (!acx) {
1026                ret = -ENOMEM;
1027                goto out;
1028        }
1029
1030        acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
1031        acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
1032
1033        ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1034        if (ret < 0) {
1035                wl1271_warning("acx bet enable failed: %d", ret);
1036                goto out;
1037        }
1038
1039out:
1040        kfree(acx);
1041        return ret;
1042}
1043
1044int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
1045{
1046        struct wl1271_acx_arp_filter *acx;
1047        int ret;
1048
1049        wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
1050
1051        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1052        if (!acx) {
1053                ret = -ENOMEM;
1054                goto out;
1055        }
1056
1057        acx->version = ACX_IPV4_VERSION;
1058        acx->enable = enable;
1059
1060        if (enable)
1061                memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
1062
1063        ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
1064                                   acx, sizeof(*acx));
1065        if (ret < 0) {
1066                wl1271_warning("failed to set arp ip filter: %d", ret);
1067                goto out;
1068        }
1069
1070out:
1071        kfree(acx);
1072        return ret;
1073}
1074
1075int wl1271_acx_pm_config(struct wl1271 *wl)
1076{
1077        struct wl1271_acx_pm_config *acx = NULL;
1078        struct  conf_pm_config_settings *c = &wl->conf.pm_config;
1079        int ret = 0;
1080
1081        wl1271_debug(DEBUG_ACX, "acx pm config");
1082
1083        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1084        if (!acx) {
1085                ret = -ENOMEM;
1086                goto out;
1087        }
1088
1089        acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
1090        acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
1091
1092        ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
1093        if (ret < 0) {
1094                wl1271_warning("acx pm config failed: %d", ret);
1095                goto out;
1096        }
1097
1098out:
1099        kfree(acx);
1100        return ret;
1101}
1102
1103int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
1104{
1105        struct wl1271_acx_keep_alive_mode *acx = NULL;
1106        int ret = 0;
1107
1108        wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1109
1110        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1111        if (!acx) {
1112                ret = -ENOMEM;
1113                goto out;
1114        }
1115
1116        acx->enabled = enable;
1117
1118        ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1119        if (ret < 0) {
1120                wl1271_warning("acx keep alive mode failed: %d", ret);
1121                goto out;
1122        }
1123
1124out:
1125        kfree(acx);
1126        return ret;
1127}
1128
1129int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
1130{
1131        struct wl1271_acx_keep_alive_config *acx = NULL;
1132        int ret = 0;
1133
1134        wl1271_debug(DEBUG_ACX, "acx keep alive config");
1135
1136        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1137        if (!acx) {
1138                ret = -ENOMEM;
1139                goto out;
1140        }
1141
1142        acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1143        acx->index = index;
1144        acx->tpl_validation = tpl_valid;
1145        acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1146
1147        ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1148                                   acx, sizeof(*acx));
1149        if (ret < 0) {
1150                wl1271_warning("acx keep alive config failed: %d", ret);
1151                goto out;
1152        }
1153
1154out:
1155        kfree(acx);
1156        return ret;
1157}
1158
1159int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1160                                s16 thold, u8 hyst)
1161{
1162        struct wl1271_acx_rssi_snr_trigger *acx = NULL;
1163        int ret = 0;
1164
1165        wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
1166
1167        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1168        if (!acx) {
1169                ret = -ENOMEM;
1170                goto out;
1171        }
1172
1173        wl->last_rssi_event = -1;
1174
1175        acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
1176        acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
1177        acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
1178        if (enable)
1179                acx->enable = WL1271_ACX_TRIG_ENABLE;
1180        else
1181                acx->enable = WL1271_ACX_TRIG_DISABLE;
1182
1183        acx->index = WL1271_ACX_TRIG_IDX_RSSI;
1184        acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
1185        acx->threshold = cpu_to_le16(thold);
1186        acx->hysteresis = hyst;
1187
1188        ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
1189        if (ret < 0) {
1190                wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
1191                goto out;
1192        }
1193
1194out:
1195        kfree(acx);
1196        return ret;
1197}
1198
1199int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
1200{
1201        struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
1202        struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
1203        int ret = 0;
1204
1205        wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
1206
1207        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1208        if (!acx) {
1209                ret = -ENOMEM;
1210                goto out;
1211        }
1212
1213        acx->rssi_beacon = c->avg_weight_rssi_beacon;
1214        acx->rssi_data = c->avg_weight_rssi_data;
1215        acx->snr_beacon = c->avg_weight_snr_beacon;
1216        acx->snr_data = c->avg_weight_snr_data;
1217
1218        ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
1219        if (ret < 0) {
1220                wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
1221                goto out;
1222        }
1223
1224out:
1225        kfree(acx);
1226        return ret;
1227}
1228
1229int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1230                                    struct ieee80211_sta_ht_cap *ht_cap,
1231                                    bool allow_ht_operation)
1232{
1233        struct wl1271_acx_ht_capabilities *acx;
1234        u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1235        int ret = 0;
1236
1237        wl1271_debug(DEBUG_ACX, "acx ht capabilities setting");
1238
1239        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1240        if (!acx) {
1241                ret = -ENOMEM;
1242                goto out;
1243        }
1244
1245        /* Allow HT Operation ? */
1246        if (allow_ht_operation) {
1247                acx->ht_capabilites =
1248                        WL1271_ACX_FW_CAP_HT_OPERATION;
1249                if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
1250                        acx->ht_capabilites |=
1251                                WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
1252                if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
1253                        acx->ht_capabilites |=
1254                                WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
1255                if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
1256                        acx->ht_capabilites |=
1257                                WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
1258
1259                /* get data from A-MPDU parameters field */
1260                acx->ampdu_max_length = ht_cap->ampdu_factor;
1261                acx->ampdu_min_spacing = ht_cap->ampdu_density;
1262
1263                memcpy(acx->mac_address, mac_address, ETH_ALEN);
1264        } else { /* HT operations are not allowed */
1265                acx->ht_capabilites = 0;
1266        }
1267
1268        ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
1269        if (ret < 0) {
1270                wl1271_warning("acx ht capabilities setting failed: %d", ret);
1271                goto out;
1272        }
1273
1274out:
1275        kfree(acx);
1276        return ret;
1277}
1278
1279int wl1271_acx_set_ht_information(struct wl1271 *wl,
1280                                   u16 ht_operation_mode)
1281{
1282        struct wl1271_acx_ht_information *acx;
1283        int ret = 0;
1284
1285        wl1271_debug(DEBUG_ACX, "acx ht information setting");
1286
1287        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1288        if (!acx) {
1289                ret = -ENOMEM;
1290                goto out;
1291        }
1292
1293        acx->ht_protection =
1294                (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
1295        acx->rifs_mode = 0;
1296        acx->gf_protection = 0;
1297        acx->ht_tx_burst_limit = 0;
1298        acx->dual_cts_protection = 0;
1299
1300        ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
1301
1302        if (ret < 0) {
1303                wl1271_warning("acx ht information setting failed: %d", ret);
1304                goto out;
1305        }
1306
1307out:
1308        kfree(acx);
1309        return ret;
1310}
1311
1312int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1313{
1314        struct wl1271_acx_fw_tsf_information *tsf_info;
1315        int ret;
1316
1317        tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
1318        if (!tsf_info) {
1319                ret = -ENOMEM;
1320                goto out;
1321        }
1322
1323        ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
1324                                     tsf_info, sizeof(*tsf_info));
1325        if (ret < 0) {
1326                wl1271_warning("acx tsf info interrogate failed");
1327                goto out;
1328        }
1329
1330        *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
1331                ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
1332
1333out:
1334        kfree(tsf_info);
1335        return ret;
1336}
1337