linux/drivers/net/wireless/ti/wlcore/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/spi/spi.h>
  29#include <linux/slab.h>
  30
  31#include "wlcore.h"
  32#include "debug.h"
  33#include "wl12xx_80211.h"
  34#include "ps.h"
  35#include "hw_ops.h"
  36
  37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
  38                                  u8 wake_up_event, u8 listen_interval)
  39{
  40        struct acx_wake_up_condition *wake_up;
  41        int ret;
  42
  43        wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)",
  44                     wake_up_event, listen_interval);
  45
  46        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
  47        if (!wake_up) {
  48                ret = -ENOMEM;
  49                goto out;
  50        }
  51
  52        wake_up->role_id = wlvif->role_id;
  53        wake_up->wake_up_event = wake_up_event;
  54        wake_up->listen_interval = listen_interval;
  55
  56        ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
  57                                   wake_up, sizeof(*wake_up));
  58        if (ret < 0) {
  59                wl1271_warning("could not set wake up conditions: %d", ret);
  60                goto out;
  61        }
  62
  63out:
  64        kfree(wake_up);
  65        return ret;
  66}
  67
  68int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
  69{
  70        struct acx_sleep_auth *auth;
  71        int ret;
  72
  73        wl1271_debug(DEBUG_ACX, "acx sleep auth %d", sleep_auth);
  74
  75        auth = kzalloc(sizeof(*auth), GFP_KERNEL);
  76        if (!auth) {
  77                ret = -ENOMEM;
  78                goto out;
  79        }
  80
  81        auth->sleep_auth = sleep_auth;
  82
  83        ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
  84        if (ret < 0) {
  85                wl1271_error("could not configure sleep_auth to %d: %d",
  86                             sleep_auth, ret);
  87                goto out;
  88        }
  89
  90        wl->sleep_auth = sleep_auth;
  91out:
  92        kfree(auth);
  93        return ret;
  94}
  95EXPORT_SYMBOL_GPL(wl1271_acx_sleep_auth);
  96
  97int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
  98                        int power)
  99{
 100        struct acx_current_tx_power *acx;
 101        int ret;
 102
 103        wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power);
 104
 105        if (power < 0 || power > 25)
 106                return -EINVAL;
 107
 108        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 109        if (!acx) {
 110                ret = -ENOMEM;
 111                goto out;
 112        }
 113
 114        acx->role_id = wlvif->role_id;
 115        acx->current_tx_power = power * 10;
 116
 117        ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
 118        if (ret < 0) {
 119                wl1271_warning("configure of tx power failed: %d", ret);
 120                goto out;
 121        }
 122
 123out:
 124        kfree(acx);
 125        return ret;
 126}
 127
 128int wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 129{
 130        struct acx_feature_config *feature;
 131        int ret;
 132
 133        wl1271_debug(DEBUG_ACX, "acx feature cfg");
 134
 135        feature = kzalloc(sizeof(*feature), GFP_KERNEL);
 136        if (!feature) {
 137                ret = -ENOMEM;
 138                goto out;
 139        }
 140
 141        /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
 142        feature->role_id = wlvif->role_id;
 143        feature->data_flow_options = 0;
 144        feature->options = 0;
 145
 146        ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
 147                                   feature, sizeof(*feature));
 148        if (ret < 0) {
 149                wl1271_error("Couldnt set HW encryption");
 150                goto out;
 151        }
 152
 153out:
 154        kfree(feature);
 155        return ret;
 156}
 157
 158int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
 159                       size_t len)
 160{
 161        int ret;
 162
 163        wl1271_debug(DEBUG_ACX, "acx mem map");
 164
 165        ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
 166        if (ret < 0)
 167                return ret;
 168
 169        return 0;
 170}
 171
 172int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
 173{
 174        struct acx_rx_msdu_lifetime *acx;
 175        int ret;
 176
 177        wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
 178
 179        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 180        if (!acx) {
 181                ret = -ENOMEM;
 182                goto out;
 183        }
 184
 185        acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
 186        ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
 187                                   acx, sizeof(*acx));
 188        if (ret < 0) {
 189                wl1271_warning("failed to set rx msdu life time: %d", ret);
 190                goto out;
 191        }
 192
 193out:
 194        kfree(acx);
 195        return ret;
 196}
 197
 198int wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 199                    enum acx_slot_type slot_time)
 200{
 201        struct acx_slot *slot;
 202        int ret;
 203
 204        wl1271_debug(DEBUG_ACX, "acx slot");
 205
 206        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 207        if (!slot) {
 208                ret = -ENOMEM;
 209                goto out;
 210        }
 211
 212        slot->role_id = wlvif->role_id;
 213        slot->wone_index = STATION_WONE_INDEX;
 214        slot->slot_time = slot_time;
 215
 216        ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
 217        if (ret < 0) {
 218                wl1271_warning("failed to set slot time: %d", ret);
 219                goto out;
 220        }
 221
 222out:
 223        kfree(slot);
 224        return ret;
 225}
 226
 227int wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 228                                 bool enable, void *mc_list, u32 mc_list_len)
 229{
 230        struct acx_dot11_grp_addr_tbl *acx;
 231        int ret;
 232
 233        wl1271_debug(DEBUG_ACX, "acx group address tbl");
 234
 235        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 236        if (!acx) {
 237                ret = -ENOMEM;
 238                goto out;
 239        }
 240
 241        /* MAC filtering */
 242        acx->role_id = wlvif->role_id;
 243        acx->enabled = enable;
 244        acx->num_groups = mc_list_len;
 245        memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
 246
 247        ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
 248                                   acx, sizeof(*acx));
 249        if (ret < 0) {
 250                wl1271_warning("failed to set group addr table: %d", ret);
 251                goto out;
 252        }
 253
 254out:
 255        kfree(acx);
 256        return ret;
 257}
 258
 259int wl1271_acx_service_period_timeout(struct wl1271 *wl,
 260                                      struct wl12xx_vif *wlvif)
 261{
 262        struct acx_rx_timeout *rx_timeout;
 263        int ret;
 264
 265        rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
 266        if (!rx_timeout) {
 267                ret = -ENOMEM;
 268                goto out;
 269        }
 270
 271        wl1271_debug(DEBUG_ACX, "acx service period timeout");
 272
 273        rx_timeout->role_id = wlvif->role_id;
 274        rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
 275        rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
 276
 277        ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
 278                                   rx_timeout, sizeof(*rx_timeout));
 279        if (ret < 0) {
 280                wl1271_warning("failed to set service period timeout: %d",
 281                               ret);
 282                goto out;
 283        }
 284
 285out:
 286        kfree(rx_timeout);
 287        return ret;
 288}
 289
 290int wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 291                             u32 rts_threshold)
 292{
 293        struct acx_rts_threshold *rts;
 294        int ret;
 295
 296        /*
 297         * If the RTS threshold is not configured or out of range, use the
 298         * default value.
 299         */
 300        if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
 301                rts_threshold = wl->conf.rx.rts_threshold;
 302
 303        wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
 304
 305        rts = kzalloc(sizeof(*rts), GFP_KERNEL);
 306        if (!rts) {
 307                ret = -ENOMEM;
 308                goto out;
 309        }
 310
 311        rts->role_id = wlvif->role_id;
 312        rts->threshold = cpu_to_le16((u16)rts_threshold);
 313
 314        ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 315        if (ret < 0) {
 316                wl1271_warning("failed to set rts threshold: %d", ret);
 317                goto out;
 318        }
 319
 320out:
 321        kfree(rts);
 322        return ret;
 323}
 324
 325int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
 326{
 327        struct acx_dco_itrim_params *dco;
 328        struct conf_itrim_settings *c = &wl->conf.itrim;
 329        int ret;
 330
 331        wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
 332
 333        dco = kzalloc(sizeof(*dco), GFP_KERNEL);
 334        if (!dco) {
 335                ret = -ENOMEM;
 336                goto out;
 337        }
 338
 339        dco->enable = c->enable;
 340        dco->timeout = cpu_to_le32(c->timeout);
 341
 342        ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
 343                                   dco, sizeof(*dco));
 344        if (ret < 0) {
 345                wl1271_warning("failed to set dco itrim parameters: %d", ret);
 346                goto out;
 347        }
 348
 349out:
 350        kfree(dco);
 351        return ret;
 352}
 353
 354int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 355                                 bool enable_filter)
 356{
 357        struct acx_beacon_filter_option *beacon_filter = NULL;
 358        int ret = 0;
 359
 360        wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
 361
 362        if (enable_filter &&
 363            wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
 364                goto out;
 365
 366        beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
 367        if (!beacon_filter) {
 368                ret = -ENOMEM;
 369                goto out;
 370        }
 371
 372        beacon_filter->role_id = wlvif->role_id;
 373        beacon_filter->enable = enable_filter;
 374
 375        /*
 376         * When set to zero, and the filter is enabled, beacons
 377         * without the unicast TIM bit set are dropped.
 378         */
 379        beacon_filter->max_num_beacons = 0;
 380
 381        ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
 382                                   beacon_filter, sizeof(*beacon_filter));
 383        if (ret < 0) {
 384                wl1271_warning("failed to set beacon filter opt: %d", ret);
 385                goto out;
 386        }
 387
 388out:
 389        kfree(beacon_filter);
 390        return ret;
 391}
 392
 393int wl1271_acx_beacon_filter_table(struct wl1271 *wl,
 394                                   struct wl12xx_vif *wlvif)
 395{
 396        struct acx_beacon_filter_ie_table *ie_table;
 397        int i, idx = 0;
 398        int ret;
 399        bool vendor_spec = false;
 400
 401        wl1271_debug(DEBUG_ACX, "acx beacon filter table");
 402
 403        ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
 404        if (!ie_table) {
 405                ret = -ENOMEM;
 406                goto out;
 407        }
 408
 409        /* configure default beacon pass-through rules */
 410        ie_table->role_id = wlvif->role_id;
 411        ie_table->num_ie = 0;
 412        for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
 413                struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
 414                ie_table->table[idx++] = r->ie;
 415                ie_table->table[idx++] = r->rule;
 416
 417                if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
 418                        /* only one vendor specific ie allowed */
 419                        if (vendor_spec)
 420                                continue;
 421
 422                        /* for vendor specific rules configure the
 423                           additional fields */
 424                        memcpy(&(ie_table->table[idx]), r->oui,
 425                               CONF_BCN_IE_OUI_LEN);
 426                        idx += CONF_BCN_IE_OUI_LEN;
 427                        ie_table->table[idx++] = r->type;
 428                        memcpy(&(ie_table->table[idx]), r->version,
 429                               CONF_BCN_IE_VER_LEN);
 430                        idx += CONF_BCN_IE_VER_LEN;
 431                        vendor_spec = true;
 432                }
 433
 434                ie_table->num_ie++;
 435        }
 436
 437        ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 438                                   ie_table, sizeof(*ie_table));
 439        if (ret < 0) {
 440                wl1271_warning("failed to set beacon filter table: %d", ret);
 441                goto out;
 442        }
 443
 444out:
 445        kfree(ie_table);
 446        return ret;
 447}
 448
 449#define ACX_CONN_MONIT_DISABLE_VALUE  0xffffffff
 450
 451int wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 452                                 bool enable)
 453{
 454        struct acx_conn_monit_params *acx;
 455        u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
 456        u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
 457        int ret;
 458
 459        wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
 460                     enable ? "enabled" : "disabled");
 461
 462        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 463        if (!acx) {
 464                ret = -ENOMEM;
 465                goto out;
 466        }
 467
 468        if (enable) {
 469                threshold = wl->conf.conn.synch_fail_thold;
 470                timeout = wl->conf.conn.bss_lose_timeout;
 471        }
 472
 473        acx->role_id = wlvif->role_id;
 474        acx->synch_fail_thold = cpu_to_le32(threshold);
 475        acx->bss_lose_timeout = cpu_to_le32(timeout);
 476
 477        ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
 478                                   acx, sizeof(*acx));
 479        if (ret < 0) {
 480                wl1271_warning("failed to set connection monitor "
 481                               "parameters: %d", ret);
 482                goto out;
 483        }
 484
 485out:
 486        kfree(acx);
 487        return ret;
 488}
 489
 490
 491int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
 492{
 493        struct acx_bt_wlan_coex *pta;
 494        int ret;
 495
 496        wl1271_debug(DEBUG_ACX, "acx sg enable");
 497
 498        pta = kzalloc(sizeof(*pta), GFP_KERNEL);
 499        if (!pta) {
 500                ret = -ENOMEM;
 501                goto out;
 502        }
 503
 504        if (enable)
 505                pta->enable = wl->conf.sg.state;
 506        else
 507                pta->enable = CONF_SG_DISABLE;
 508
 509        ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
 510        if (ret < 0) {
 511                wl1271_warning("failed to set softgemini enable: %d", ret);
 512                goto out;
 513        }
 514
 515out:
 516        kfree(pta);
 517        return ret;
 518}
 519
 520int wl12xx_acx_sg_cfg(struct wl1271 *wl)
 521{
 522        struct acx_bt_wlan_coex_param *param;
 523        struct conf_sg_settings *c = &wl->conf.sg;
 524        int i, ret;
 525
 526        wl1271_debug(DEBUG_ACX, "acx sg cfg");
 527
 528        param = kzalloc(sizeof(*param), GFP_KERNEL);
 529        if (!param) {
 530                ret = -ENOMEM;
 531                goto out;
 532        }
 533
 534        /* BT-WLAN coext parameters */
 535        for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
 536                param->params[i] = cpu_to_le32(c->params[i]);
 537        param->param_idx = CONF_SG_PARAMS_ALL;
 538
 539        ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
 540        if (ret < 0) {
 541                wl1271_warning("failed to set sg config: %d", ret);
 542                goto out;
 543        }
 544
 545out:
 546        kfree(param);
 547        return ret;
 548}
 549
 550int wl1271_acx_cca_threshold(struct wl1271 *wl)
 551{
 552        struct acx_energy_detection *detection;
 553        int ret;
 554
 555        wl1271_debug(DEBUG_ACX, "acx cca threshold");
 556
 557        detection = kzalloc(sizeof(*detection), GFP_KERNEL);
 558        if (!detection) {
 559                ret = -ENOMEM;
 560                goto out;
 561        }
 562
 563        detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
 564        detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
 565
 566        ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
 567                                   detection, sizeof(*detection));
 568        if (ret < 0)
 569                wl1271_warning("failed to set cca threshold: %d", ret);
 570
 571out:
 572        kfree(detection);
 573        return ret;
 574}
 575
 576int wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 577{
 578        struct acx_beacon_broadcast *bb;
 579        int ret;
 580
 581        wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
 582
 583        bb = kzalloc(sizeof(*bb), GFP_KERNEL);
 584        if (!bb) {
 585                ret = -ENOMEM;
 586                goto out;
 587        }
 588
 589        bb->role_id = wlvif->role_id;
 590        bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
 591        bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
 592        bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
 593        bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
 594
 595        ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
 596        if (ret < 0) {
 597                wl1271_warning("failed to set rx config: %d", ret);
 598                goto out;
 599        }
 600
 601out:
 602        kfree(bb);
 603        return ret;
 604}
 605
 606int wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid)
 607{
 608        struct acx_aid *acx_aid;
 609        int ret;
 610
 611        wl1271_debug(DEBUG_ACX, "acx aid");
 612
 613        acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
 614        if (!acx_aid) {
 615                ret = -ENOMEM;
 616                goto out;
 617        }
 618
 619        acx_aid->role_id = wlvif->role_id;
 620        acx_aid->aid = cpu_to_le16(aid);
 621
 622        ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
 623        if (ret < 0) {
 624                wl1271_warning("failed to set aid: %d", ret);
 625                goto out;
 626        }
 627
 628out:
 629        kfree(acx_aid);
 630        return ret;
 631}
 632
 633int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
 634{
 635        struct acx_event_mask *mask;
 636        int ret;
 637
 638        wl1271_debug(DEBUG_ACX, "acx event mbox mask");
 639
 640        mask = kzalloc(sizeof(*mask), GFP_KERNEL);
 641        if (!mask) {
 642                ret = -ENOMEM;
 643                goto out;
 644        }
 645
 646        /* high event mask is unused */
 647        mask->high_event_mask = cpu_to_le32(0xffffffff);
 648        mask->event_mask = cpu_to_le32(event_mask);
 649
 650        ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
 651                                   mask, sizeof(*mask));
 652        if (ret < 0) {
 653                wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
 654                goto out;
 655        }
 656
 657out:
 658        kfree(mask);
 659        return ret;
 660}
 661
 662int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 663                            enum acx_preamble_type preamble)
 664{
 665        struct acx_preamble *acx;
 666        int ret;
 667
 668        wl1271_debug(DEBUG_ACX, "acx_set_preamble");
 669
 670        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 671        if (!acx) {
 672                ret = -ENOMEM;
 673                goto out;
 674        }
 675
 676        acx->role_id = wlvif->role_id;
 677        acx->preamble = preamble;
 678
 679        ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
 680        if (ret < 0) {
 681                wl1271_warning("Setting of preamble failed: %d", ret);
 682                goto out;
 683        }
 684
 685out:
 686        kfree(acx);
 687        return ret;
 688}
 689
 690int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 691                           enum acx_ctsprotect_type ctsprotect)
 692{
 693        struct acx_ctsprotect *acx;
 694        int ret;
 695
 696        wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
 697
 698        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 699        if (!acx) {
 700                ret = -ENOMEM;
 701                goto out;
 702        }
 703
 704        acx->role_id = wlvif->role_id;
 705        acx->ctsprotect = ctsprotect;
 706
 707        ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
 708        if (ret < 0) {
 709                wl1271_warning("Setting of ctsprotect failed: %d", ret);
 710                goto out;
 711        }
 712
 713out:
 714        kfree(acx);
 715        return ret;
 716}
 717
 718int wl1271_acx_statistics(struct wl1271 *wl, void *stats)
 719{
 720        int ret;
 721
 722        wl1271_debug(DEBUG_ACX, "acx statistics");
 723
 724        ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
 725                                     wl->stats.fw_stats_len);
 726        if (ret < 0) {
 727                wl1271_warning("acx statistics failed: %d", ret);
 728                return -ENOMEM;
 729        }
 730
 731        return 0;
 732}
 733
 734int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 735{
 736        struct acx_rate_policy *acx;
 737        struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf;
 738        int ret = 0;
 739
 740        wl1271_debug(DEBUG_ACX, "acx rate policies");
 741
 742        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 743
 744        if (!acx) {
 745                ret = -ENOMEM;
 746                goto out;
 747        }
 748
 749        wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
 750                wlvif->basic_rate, wlvif->rate_set);
 751
 752        /* configure one basic rate class */
 753        acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx);
 754        acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate);
 755        acx->rate_policy.short_retry_limit = c->short_retry_limit;
 756        acx->rate_policy.long_retry_limit = c->long_retry_limit;
 757        acx->rate_policy.aflags = c->aflags;
 758
 759        ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 760        if (ret < 0) {
 761                wl1271_warning("Setting of rate policies failed: %d", ret);
 762                goto out;
 763        }
 764
 765        /* configure one AP supported rate class */
 766        acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
 767
 768        /* the AP policy is HW specific */
 769        acx->rate_policy.enabled_rates =
 770                cpu_to_le32(wlcore_hw_sta_get_ap_rate_mask(wl, wlvif));
 771        acx->rate_policy.short_retry_limit = c->short_retry_limit;
 772        acx->rate_policy.long_retry_limit = c->long_retry_limit;
 773        acx->rate_policy.aflags = c->aflags;
 774
 775        ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 776        if (ret < 0) {
 777                wl1271_warning("Setting of rate policies failed: %d", ret);
 778                goto out;
 779        }
 780
 781        /*
 782         * configure one rate class for basic p2p operations.
 783         * (p2p packets should always go out with OFDM rates, even
 784         * if we are currently connected to 11b AP)
 785         */
 786        acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx);
 787        acx->rate_policy.enabled_rates =
 788                                cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);
 789        acx->rate_policy.short_retry_limit = c->short_retry_limit;
 790        acx->rate_policy.long_retry_limit = c->long_retry_limit;
 791        acx->rate_policy.aflags = c->aflags;
 792
 793        ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 794        if (ret < 0) {
 795                wl1271_warning("Setting of rate policies failed: %d", ret);
 796                goto out;
 797        }
 798
 799out:
 800        kfree(acx);
 801        return ret;
 802}
 803
 804int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
 805                      u8 idx)
 806{
 807        struct acx_rate_policy *acx;
 808        int ret = 0;
 809
 810        wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
 811                     idx, c->enabled_rates);
 812
 813        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 814        if (!acx) {
 815                ret = -ENOMEM;
 816                goto out;
 817        }
 818
 819        acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates);
 820        acx->rate_policy.short_retry_limit = c->short_retry_limit;
 821        acx->rate_policy.long_retry_limit = c->long_retry_limit;
 822        acx->rate_policy.aflags = c->aflags;
 823
 824        acx->rate_policy_idx = cpu_to_le32(idx);
 825
 826        ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 827        if (ret < 0) {
 828                wl1271_warning("Setting of ap rate policy failed: %d", ret);
 829                goto out;
 830        }
 831
 832out:
 833        kfree(acx);
 834        return ret;
 835}
 836
 837int wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 838                      u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop)
 839{
 840        struct acx_ac_cfg *acx;
 841        int ret = 0;
 842
 843        wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
 844                     "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
 845
 846        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 847
 848        if (!acx) {
 849                ret = -ENOMEM;
 850                goto out;
 851        }
 852
 853        acx->role_id = wlvif->role_id;
 854        acx->ac = ac;
 855        acx->cw_min = cw_min;
 856        acx->cw_max = cpu_to_le16(cw_max);
 857        acx->aifsn = aifsn;
 858        acx->tx_op_limit = cpu_to_le16(txop);
 859
 860        ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
 861        if (ret < 0) {
 862                wl1271_warning("acx ac cfg failed: %d", ret);
 863                goto out;
 864        }
 865
 866out:
 867        kfree(acx);
 868        return ret;
 869}
 870
 871int wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 872                       u8 queue_id, u8 channel_type,
 873                       u8 tsid, u8 ps_scheme, u8 ack_policy,
 874                       u32 apsd_conf0, u32 apsd_conf1)
 875{
 876        struct acx_tid_config *acx;
 877        int ret = 0;
 878
 879        wl1271_debug(DEBUG_ACX, "acx tid config");
 880
 881        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 882
 883        if (!acx) {
 884                ret = -ENOMEM;
 885                goto out;
 886        }
 887
 888        acx->role_id = wlvif->role_id;
 889        acx->queue_id = queue_id;
 890        acx->channel_type = channel_type;
 891        acx->tsid = tsid;
 892        acx->ps_scheme = ps_scheme;
 893        acx->ack_policy = ack_policy;
 894        acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
 895        acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
 896
 897        ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
 898        if (ret < 0) {
 899                wl1271_warning("Setting of tid config failed: %d", ret);
 900                goto out;
 901        }
 902
 903out:
 904        kfree(acx);
 905        return ret;
 906}
 907
 908int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
 909{
 910        struct acx_frag_threshold *acx;
 911        int ret = 0;
 912
 913        /*
 914         * If the fragmentation is not configured or out of range, use the
 915         * default value.
 916         */
 917        if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
 918                frag_threshold = wl->conf.tx.frag_threshold;
 919
 920        wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
 921
 922        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 923
 924        if (!acx) {
 925                ret = -ENOMEM;
 926                goto out;
 927        }
 928
 929        acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
 930        ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
 931        if (ret < 0) {
 932                wl1271_warning("Setting of frag threshold failed: %d", ret);
 933                goto out;
 934        }
 935
 936out:
 937        kfree(acx);
 938        return ret;
 939}
 940
 941int wl1271_acx_tx_config_options(struct wl1271 *wl)
 942{
 943        struct acx_tx_config_options *acx;
 944        int ret = 0;
 945
 946        wl1271_debug(DEBUG_ACX, "acx tx config options");
 947
 948        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 949
 950        if (!acx) {
 951                ret = -ENOMEM;
 952                goto out;
 953        }
 954
 955        acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
 956        acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
 957        ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
 958        if (ret < 0) {
 959                wl1271_warning("Setting of tx options failed: %d", ret);
 960                goto out;
 961        }
 962
 963out:
 964        kfree(acx);
 965        return ret;
 966}
 967
 968int wl12xx_acx_mem_cfg(struct wl1271 *wl)
 969{
 970        struct wl12xx_acx_config_memory *mem_conf;
 971        struct conf_memory_settings *mem;
 972        int ret;
 973
 974        wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
 975
 976        mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
 977        if (!mem_conf) {
 978                ret = -ENOMEM;
 979                goto out;
 980        }
 981
 982        mem = &wl->conf.mem;
 983
 984        /* memory config */
 985        mem_conf->num_stations = mem->num_stations;
 986        mem_conf->rx_mem_block_num = mem->rx_block_num;
 987        mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
 988        mem_conf->num_ssid_profiles = mem->ssid_profiles;
 989        mem_conf->total_tx_descriptors = cpu_to_le32(wl->num_tx_desc);
 990        mem_conf->dyn_mem_enable = mem->dynamic_memory;
 991        mem_conf->tx_free_req = mem->min_req_tx_blocks;
 992        mem_conf->rx_free_req = mem->min_req_rx_blocks;
 993        mem_conf->tx_min = mem->tx_min;
 994        mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks;
 995
 996        ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 997                                   sizeof(*mem_conf));
 998        if (ret < 0) {
 999                wl1271_warning("wl1271 mem config failed: %d", ret);
1000                goto out;
1001        }
1002
1003out:
1004        kfree(mem_conf);
1005        return ret;
1006}
1007EXPORT_SYMBOL_GPL(wl12xx_acx_mem_cfg);
1008
1009int wl1271_acx_init_mem_config(struct wl1271 *wl)
1010{
1011        int ret;
1012
1013        wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
1014                                     GFP_KERNEL);
1015        if (!wl->target_mem_map) {
1016                wl1271_error("couldn't allocate target memory map");
1017                return -ENOMEM;
1018        }
1019
1020        /* we now ask for the firmware built memory map */
1021        ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
1022                                 sizeof(struct wl1271_acx_mem_map));
1023        if (ret < 0) {
1024                wl1271_error("couldn't retrieve firmware memory map");
1025                kfree(wl->target_mem_map);
1026                wl->target_mem_map = NULL;
1027                return ret;
1028        }
1029
1030        /* initialize TX block book keeping */
1031        wl->tx_blocks_available =
1032                le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
1033        wl1271_debug(DEBUG_TX, "available tx blocks: %d",
1034                     wl->tx_blocks_available);
1035
1036        return 0;
1037}
1038EXPORT_SYMBOL_GPL(wl1271_acx_init_mem_config);
1039
1040int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
1041{
1042        struct wl1271_acx_rx_config_opt *rx_conf;
1043        int ret;
1044
1045        wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
1046
1047        rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
1048        if (!rx_conf) {
1049                ret = -ENOMEM;
1050                goto out;
1051        }
1052
1053        rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
1054        rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
1055        rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
1056        rx_conf->queue_type = wl->conf.rx.queue_type;
1057
1058        ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
1059                                   sizeof(*rx_conf));
1060        if (ret < 0) {
1061                wl1271_warning("wl1271 rx config opt failed: %d", ret);
1062                goto out;
1063        }
1064
1065out:
1066        kfree(rx_conf);
1067        return ret;
1068}
1069
1070int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1071                          bool enable)
1072{
1073        struct wl1271_acx_bet_enable *acx = NULL;
1074        int ret = 0;
1075
1076        wl1271_debug(DEBUG_ACX, "acx bet enable");
1077
1078        if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
1079                goto out;
1080
1081        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1082        if (!acx) {
1083                ret = -ENOMEM;
1084                goto out;
1085        }
1086
1087        acx->role_id = wlvif->role_id;
1088        acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
1089        acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
1090
1091        ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1092        if (ret < 0) {
1093                wl1271_warning("acx bet enable failed: %d", ret);
1094                goto out;
1095        }
1096
1097out:
1098        kfree(acx);
1099        return ret;
1100}
1101
1102int wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1103                             u8 enable, __be32 address)
1104{
1105        struct wl1271_acx_arp_filter *acx;
1106        int ret;
1107
1108        wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
1109
1110        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1111        if (!acx) {
1112                ret = -ENOMEM;
1113                goto out;
1114        }
1115
1116        acx->role_id = wlvif->role_id;
1117        acx->version = ACX_IPV4_VERSION;
1118        acx->enable = enable;
1119
1120        if (enable)
1121                memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
1122
1123        ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
1124                                   acx, sizeof(*acx));
1125        if (ret < 0) {
1126                wl1271_warning("failed to set arp ip filter: %d", ret);
1127                goto out;
1128        }
1129
1130out:
1131        kfree(acx);
1132        return ret;
1133}
1134
1135int wl1271_acx_pm_config(struct wl1271 *wl)
1136{
1137        struct wl1271_acx_pm_config *acx = NULL;
1138        struct  conf_pm_config_settings *c = &wl->conf.pm_config;
1139        int ret = 0;
1140
1141        wl1271_debug(DEBUG_ACX, "acx pm config");
1142
1143        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1144        if (!acx) {
1145                ret = -ENOMEM;
1146                goto out;
1147        }
1148
1149        acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
1150        acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
1151
1152        ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
1153        if (ret < 0) {
1154                wl1271_warning("acx pm config failed: %d", ret);
1155                goto out;
1156        }
1157
1158out:
1159        kfree(acx);
1160        return ret;
1161}
1162EXPORT_SYMBOL_GPL(wl1271_acx_pm_config);
1163
1164int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1165                               bool enable)
1166{
1167        struct wl1271_acx_keep_alive_mode *acx = NULL;
1168        int ret = 0;
1169
1170        wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1171
1172        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1173        if (!acx) {
1174                ret = -ENOMEM;
1175                goto out;
1176        }
1177
1178        acx->role_id = wlvif->role_id;
1179        acx->enabled = enable;
1180
1181        ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1182        if (ret < 0) {
1183                wl1271_warning("acx keep alive mode failed: %d", ret);
1184                goto out;
1185        }
1186
1187out:
1188        kfree(acx);
1189        return ret;
1190}
1191
1192int wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1193                                 u8 index, u8 tpl_valid)
1194{
1195        struct wl1271_acx_keep_alive_config *acx = NULL;
1196        int ret = 0;
1197
1198        wl1271_debug(DEBUG_ACX, "acx keep alive config");
1199
1200        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1201        if (!acx) {
1202                ret = -ENOMEM;
1203                goto out;
1204        }
1205
1206        acx->role_id = wlvif->role_id;
1207        acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1208        acx->index = index;
1209        acx->tpl_validation = tpl_valid;
1210        acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1211
1212        ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1213                                   acx, sizeof(*acx));
1214        if (ret < 0) {
1215                wl1271_warning("acx keep alive config failed: %d", ret);
1216                goto out;
1217        }
1218
1219out:
1220        kfree(acx);
1221        return ret;
1222}
1223
1224int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1225                                bool enable, s16 thold, u8 hyst)
1226{
1227        struct wl1271_acx_rssi_snr_trigger *acx = NULL;
1228        int ret = 0;
1229
1230        wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
1231
1232        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1233        if (!acx) {
1234                ret = -ENOMEM;
1235                goto out;
1236        }
1237
1238        wlvif->last_rssi_event = -1;
1239
1240        acx->role_id = wlvif->role_id;
1241        acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
1242        acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
1243        acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
1244        if (enable)
1245                acx->enable = WL1271_ACX_TRIG_ENABLE;
1246        else
1247                acx->enable = WL1271_ACX_TRIG_DISABLE;
1248
1249        acx->index = WL1271_ACX_TRIG_IDX_RSSI;
1250        acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
1251        acx->threshold = cpu_to_le16(thold);
1252        acx->hysteresis = hyst;
1253
1254        ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
1255        if (ret < 0) {
1256                wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
1257                goto out;
1258        }
1259
1260out:
1261        kfree(acx);
1262        return ret;
1263}
1264
1265int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl,
1266                                    struct wl12xx_vif *wlvif)
1267{
1268        struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
1269        struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
1270        int ret = 0;
1271
1272        wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
1273
1274        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1275        if (!acx) {
1276                ret = -ENOMEM;
1277                goto out;
1278        }
1279
1280        acx->role_id = wlvif->role_id;
1281        acx->rssi_beacon = c->avg_weight_rssi_beacon;
1282        acx->rssi_data = c->avg_weight_rssi_data;
1283        acx->snr_beacon = c->avg_weight_snr_beacon;
1284        acx->snr_data = c->avg_weight_snr_data;
1285
1286        ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
1287        if (ret < 0) {
1288                wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
1289                goto out;
1290        }
1291
1292out:
1293        kfree(acx);
1294        return ret;
1295}
1296
1297int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1298                                    struct ieee80211_sta_ht_cap *ht_cap,
1299                                    bool allow_ht_operation, u8 hlid)
1300{
1301        struct wl1271_acx_ht_capabilities *acx;
1302        int ret = 0;
1303        u32 ht_capabilites = 0;
1304
1305        wl1271_debug(DEBUG_ACX, "acx ht capabilities setting "
1306                     "sta supp: %d sta cap: %d", ht_cap->ht_supported,
1307                     ht_cap->cap);
1308
1309        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1310        if (!acx) {
1311                ret = -ENOMEM;
1312                goto out;
1313        }
1314
1315        if (allow_ht_operation && ht_cap->ht_supported) {
1316                /* no need to translate capabilities - use the spec values */
1317                ht_capabilites = ht_cap->cap;
1318
1319                /*
1320                 * this bit is not employed by the spec but only by FW to
1321                 * indicate peer HT support
1322                 */
1323                ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
1324
1325                /* get data from A-MPDU parameters field */
1326                acx->ampdu_max_length = ht_cap->ampdu_factor;
1327                acx->ampdu_min_spacing = ht_cap->ampdu_density;
1328        }
1329
1330        acx->hlid = hlid;
1331        acx->ht_capabilites = cpu_to_le32(ht_capabilites);
1332
1333        ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
1334        if (ret < 0) {
1335                wl1271_warning("acx ht capabilities setting failed: %d", ret);
1336                goto out;
1337        }
1338
1339out:
1340        kfree(acx);
1341        return ret;
1342}
1343EXPORT_SYMBOL_GPL(wl1271_acx_set_ht_capabilities);
1344
1345
1346int wl1271_acx_set_ht_information(struct wl1271 *wl,
1347                                   struct wl12xx_vif *wlvif,
1348                                   u16 ht_operation_mode)
1349{
1350        struct wl1271_acx_ht_information *acx;
1351        int ret = 0;
1352
1353        wl1271_debug(DEBUG_ACX, "acx ht information setting");
1354
1355        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1356        if (!acx) {
1357                ret = -ENOMEM;
1358                goto out;
1359        }
1360
1361        acx->role_id = wlvif->role_id;
1362        acx->ht_protection =
1363                (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
1364        acx->rifs_mode = 0;
1365        acx->gf_protection =
1366                !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1367        acx->ht_tx_burst_limit = 0;
1368        acx->dual_cts_protection = 0;
1369
1370        ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
1371
1372        if (ret < 0) {
1373                wl1271_warning("acx ht information setting failed: %d", ret);
1374                goto out;
1375        }
1376
1377out:
1378        kfree(acx);
1379        return ret;
1380}
1381
1382/* Configure BA session initiator/receiver parameters setting in the FW. */
1383int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
1384                                       struct wl12xx_vif *wlvif)
1385{
1386        struct wl1271_acx_ba_initiator_policy *acx;
1387        int ret;
1388
1389        wl1271_debug(DEBUG_ACX, "acx ba initiator policy");
1390
1391        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1392        if (!acx) {
1393                ret = -ENOMEM;
1394                goto out;
1395        }
1396
1397        /* set for the current role */
1398        acx->role_id = wlvif->role_id;
1399        acx->tid_bitmap = wl->conf.ht.tx_ba_tid_bitmap;
1400        acx->win_size = wl->conf.ht.tx_ba_win_size;
1401        acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
1402
1403        ret = wl1271_cmd_configure(wl,
1404                                   ACX_BA_SESSION_INIT_POLICY,
1405                                   acx,
1406                                   sizeof(*acx));
1407        if (ret < 0) {
1408                wl1271_warning("acx ba initiator policy failed: %d", ret);
1409                goto out;
1410        }
1411
1412out:
1413        kfree(acx);
1414        return ret;
1415}
1416
1417/* setup BA session receiver setting in the FW. */
1418int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
1419                                       u16 ssn, bool enable, u8 peer_hlid)
1420{
1421        struct wl1271_acx_ba_receiver_setup *acx;
1422        int ret;
1423
1424        wl1271_debug(DEBUG_ACX, "acx ba receiver session setting");
1425
1426        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1427        if (!acx) {
1428                ret = -ENOMEM;
1429                goto out;
1430        }
1431
1432        acx->hlid = peer_hlid;
1433        acx->tid = tid_index;
1434        acx->enable = enable;
1435        acx->win_size = wl->conf.ht.rx_ba_win_size;
1436        acx->ssn = ssn;
1437
1438        ret = wlcore_cmd_configure_failsafe(wl, ACX_BA_SESSION_RX_SETUP, acx,
1439                                            sizeof(*acx),
1440                                            BIT(CMD_STATUS_NO_RX_BA_SESSION));
1441        if (ret < 0) {
1442                wl1271_warning("acx ba receiver session failed: %d", ret);
1443                goto out;
1444        }
1445
1446        /* sometimes we can't start the session */
1447        if (ret == CMD_STATUS_NO_RX_BA_SESSION) {
1448                wl1271_warning("no fw rx ba on tid %d", tid_index);
1449                ret = -EBUSY;
1450                goto out;
1451        }
1452
1453        ret = 0;
1454out:
1455        kfree(acx);
1456        return ret;
1457}
1458
1459int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1460                        u64 *mactime)
1461{
1462        struct wl12xx_acx_fw_tsf_information *tsf_info;
1463        int ret;
1464
1465        tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
1466        if (!tsf_info) {
1467                ret = -ENOMEM;
1468                goto out;
1469        }
1470
1471        tsf_info->role_id = wlvif->role_id;
1472
1473        ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
1474                                     tsf_info, sizeof(*tsf_info));
1475        if (ret < 0) {
1476                wl1271_warning("acx tsf info interrogate failed");
1477                goto out;
1478        }
1479
1480        *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
1481                ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
1482
1483out:
1484        kfree(tsf_info);
1485        return ret;
1486}
1487
1488int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1489                               bool enable)
1490{
1491        struct wl1271_acx_ps_rx_streaming *rx_streaming;
1492        u32 conf_queues, enable_queues;
1493        int i, ret = 0;
1494
1495        wl1271_debug(DEBUG_ACX, "acx ps rx streaming");
1496
1497        rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL);
1498        if (!rx_streaming) {
1499                ret = -ENOMEM;
1500                goto out;
1501        }
1502
1503        conf_queues = wl->conf.rx_streaming.queues;
1504        if (enable)
1505                enable_queues = conf_queues;
1506        else
1507                enable_queues = 0;
1508
1509        for (i = 0; i < 8; i++) {
1510                /*
1511                 * Skip non-changed queues, to avoid redundant acxs.
1512                 * this check assumes conf.rx_streaming.queues can't
1513                 * be changed while rx_streaming is enabled.
1514                 */
1515                if (!(conf_queues & BIT(i)))
1516                        continue;
1517
1518                rx_streaming->role_id = wlvif->role_id;
1519                rx_streaming->tid = i;
1520                rx_streaming->enable = enable_queues & BIT(i);
1521                rx_streaming->period = wl->conf.rx_streaming.interval;
1522                rx_streaming->timeout = wl->conf.rx_streaming.interval;
1523
1524                ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING,
1525                                           rx_streaming,
1526                                           sizeof(*rx_streaming));
1527                if (ret < 0) {
1528                        wl1271_warning("acx ps rx streaming failed: %d", ret);
1529                        goto out;
1530                }
1531        }
1532out:
1533        kfree(rx_streaming);
1534        return ret;
1535}
1536
1537int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1538{
1539        struct wl1271_acx_ap_max_tx_retry *acx = NULL;
1540        int ret;
1541
1542        wl1271_debug(DEBUG_ACX, "acx ap max tx retry");
1543
1544        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1545        if (!acx)
1546                return -ENOMEM;
1547
1548        acx->role_id = wlvif->role_id;
1549        acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);
1550
1551        ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
1552        if (ret < 0) {
1553                wl1271_warning("acx ap max tx retry failed: %d", ret);
1554                goto out;
1555        }
1556
1557out:
1558        kfree(acx);
1559        return ret;
1560}
1561
1562int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1563{
1564        struct wl1271_acx_config_ps *config_ps;
1565        int ret;
1566
1567        wl1271_debug(DEBUG_ACX, "acx config ps");
1568
1569        config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
1570        if (!config_ps) {
1571                ret = -ENOMEM;
1572                goto out;
1573        }
1574
1575        config_ps->exit_retries = wl->conf.conn.psm_exit_retries;
1576        config_ps->enter_retries = wl->conf.conn.psm_entry_retries;
1577        config_ps->null_data_rate = cpu_to_le32(wlvif->basic_rate);
1578
1579        ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps,
1580                                   sizeof(*config_ps));
1581
1582        if (ret < 0) {
1583                wl1271_warning("acx config ps failed: %d", ret);
1584                goto out;
1585        }
1586
1587out:
1588        kfree(config_ps);
1589        return ret;
1590}
1591
1592int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
1593{
1594        struct wl1271_acx_inconnection_sta *acx = NULL;
1595        int ret;
1596
1597        wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr);
1598
1599        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1600        if (!acx)
1601                return -ENOMEM;
1602
1603        memcpy(acx->addr, addr, ETH_ALEN);
1604
1605        ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
1606                                   acx, sizeof(*acx));
1607        if (ret < 0) {
1608                wl1271_warning("acx set inconnaction sta failed: %d", ret);
1609                goto out;
1610        }
1611
1612out:
1613        kfree(acx);
1614        return ret;
1615}
1616
1617int wl1271_acx_fm_coex(struct wl1271 *wl)
1618{
1619        struct wl1271_acx_fm_coex *acx;
1620        int ret;
1621
1622        wl1271_debug(DEBUG_ACX, "acx fm coex setting");
1623
1624        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1625        if (!acx) {
1626                ret = -ENOMEM;
1627                goto out;
1628        }
1629
1630        acx->enable = wl->conf.fm_coex.enable;
1631        acx->swallow_period = wl->conf.fm_coex.swallow_period;
1632        acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
1633        acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
1634        acx->m_divider_fref_set_1 =
1635                cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
1636        acx->m_divider_fref_set_2 =
1637                cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
1638        acx->coex_pll_stabilization_time =
1639                cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
1640        acx->ldo_stabilization_time =
1641                cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
1642        acx->fm_disturbed_band_margin =
1643                wl->conf.fm_coex.fm_disturbed_band_margin;
1644        acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
1645
1646        ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
1647        if (ret < 0) {
1648                wl1271_warning("acx fm coex setting failed: %d", ret);
1649                goto out;
1650        }
1651
1652out:
1653        kfree(acx);
1654        return ret;
1655}
1656
1657int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl)
1658{
1659        struct wl12xx_acx_set_rate_mgmt_params *acx = NULL;
1660        struct conf_rate_policy_settings *conf = &wl->conf.rate;
1661        int ret;
1662
1663        wl1271_debug(DEBUG_ACX, "acx set rate mgmt params");
1664
1665        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1666        if (!acx)
1667                return -ENOMEM;
1668
1669        acx->index = ACX_RATE_MGMT_ALL_PARAMS;
1670        acx->rate_retry_score = cpu_to_le16(conf->rate_retry_score);
1671        acx->per_add = cpu_to_le16(conf->per_add);
1672        acx->per_th1 = cpu_to_le16(conf->per_th1);
1673        acx->per_th2 = cpu_to_le16(conf->per_th2);
1674        acx->max_per = cpu_to_le16(conf->max_per);
1675        acx->inverse_curiosity_factor = conf->inverse_curiosity_factor;
1676        acx->tx_fail_low_th = conf->tx_fail_low_th;
1677        acx->tx_fail_high_th = conf->tx_fail_high_th;
1678        acx->per_alpha_shift = conf->per_alpha_shift;
1679        acx->per_add_shift = conf->per_add_shift;
1680        acx->per_beta1_shift = conf->per_beta1_shift;
1681        acx->per_beta2_shift = conf->per_beta2_shift;
1682        acx->rate_check_up = conf->rate_check_up;
1683        acx->rate_check_down = conf->rate_check_down;
1684        memcpy(acx->rate_retry_policy, conf->rate_retry_policy,
1685               sizeof(acx->rate_retry_policy));
1686
1687        ret = wl1271_cmd_configure(wl, ACX_SET_RATE_MGMT_PARAMS,
1688                                   acx, sizeof(*acx));
1689        if (ret < 0) {
1690                wl1271_warning("acx set rate mgmt params failed: %d", ret);
1691                goto out;
1692        }
1693
1694out:
1695        kfree(acx);
1696        return ret;
1697}
1698
1699int wl12xx_acx_config_hangover(struct wl1271 *wl)
1700{
1701        struct wl12xx_acx_config_hangover *acx;
1702        struct conf_hangover_settings *conf = &wl->conf.hangover;
1703        int ret;
1704
1705        wl1271_debug(DEBUG_ACX, "acx config hangover");
1706
1707        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1708        if (!acx) {
1709                ret = -ENOMEM;
1710                goto out;
1711        }
1712
1713        acx->recover_time = cpu_to_le32(conf->recover_time);
1714        acx->hangover_period = conf->hangover_period;
1715        acx->dynamic_mode = conf->dynamic_mode;
1716        acx->early_termination_mode = conf->early_termination_mode;
1717        acx->max_period = conf->max_period;
1718        acx->min_period = conf->min_period;
1719        acx->increase_delta = conf->increase_delta;
1720        acx->decrease_delta = conf->decrease_delta;
1721        acx->quiet_time = conf->quiet_time;
1722        acx->increase_time = conf->increase_time;
1723        acx->window_size = acx->window_size;
1724
1725        ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
1726                                   sizeof(*acx));
1727
1728        if (ret < 0) {
1729                wl1271_warning("acx config hangover failed: %d", ret);
1730                goto out;
1731        }
1732
1733out:
1734        kfree(acx);
1735        return ret;
1736
1737}
1738
1739int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1740                            s8 *avg_rssi)
1741{
1742        struct acx_roaming_stats *acx;
1743        int ret = 0;
1744
1745        wl1271_debug(DEBUG_ACX, "acx roaming statistics");
1746
1747        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1748        if (!acx) {
1749                ret = -ENOMEM;
1750                goto out;
1751        }
1752
1753        acx->role_id = wlvif->role_id;
1754        ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
1755                                     acx, sizeof(*acx));
1756        if (ret < 0) {
1757                wl1271_warning("acx roaming statistics failed: %d", ret);
1758                ret = -ENOMEM;
1759                goto out;
1760        }
1761
1762        *avg_rssi = acx->rssi_beacon;
1763out:
1764        kfree(acx);
1765        return ret;
1766}
1767
1768#ifdef CONFIG_PM
1769/* Set the global behaviour of RX filters - On/Off + default action */
1770int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
1771                                        enum rx_filter_action action)
1772{
1773        struct acx_default_rx_filter *acx;
1774        int ret;
1775
1776        wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d",
1777                     enable, action);
1778
1779        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1780        if (!acx)
1781                return -ENOMEM;
1782
1783        acx->enable = enable;
1784        acx->default_action = action;
1785
1786        ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx,
1787                                   sizeof(*acx));
1788        if (ret < 0) {
1789                wl1271_warning("acx default rx filter enable failed: %d", ret);
1790                goto out;
1791        }
1792
1793out:
1794        kfree(acx);
1795        return ret;
1796}
1797
1798/* Configure or disable a specific RX filter pattern */
1799int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
1800                             struct wl12xx_rx_filter *filter)
1801{
1802        struct acx_rx_filter_cfg *acx;
1803        int fields_size = 0;
1804        int acx_size;
1805        int ret;
1806
1807        WARN_ON(enable && !filter);
1808        WARN_ON(index >= WL1271_MAX_RX_FILTERS);
1809
1810        wl1271_debug(DEBUG_ACX,
1811                     "acx set rx filter idx: %d enable: %d filter: %p",
1812                     index, enable, filter);
1813
1814        if (enable) {
1815                fields_size = wl1271_rx_filter_get_fields_size(filter);
1816
1817                wl1271_debug(DEBUG_ACX, "act: %d num_fields: %d field_size: %d",
1818                      filter->action, filter->num_fields, fields_size);
1819        }
1820
1821        acx_size = ALIGN(sizeof(*acx) + fields_size, 4);
1822        acx = kzalloc(acx_size, GFP_KERNEL);
1823
1824        if (!acx)
1825                return -ENOMEM;
1826
1827        acx->enable = enable;
1828        acx->index = index;
1829
1830        if (enable) {
1831                acx->num_fields = filter->num_fields;
1832                acx->action = filter->action;
1833                wl1271_rx_filter_flatten_fields(filter, acx->fields);
1834        }
1835
1836        wl1271_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size);
1837
1838        ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx, acx_size);
1839        if (ret < 0) {
1840                wl1271_warning("setting rx filter failed: %d", ret);
1841                goto out;
1842        }
1843
1844out:
1845        kfree(acx);
1846        return ret;
1847}
1848#endif /* CONFIG_PM */
1849