linux/drivers/net/wireless/wl1251/acx.c
<<
>>
Prefs
   1#include "acx.h"
   2
   3#include <linux/module.h>
   4#include <linux/slab.h>
   5#include <linux/crc7.h>
   6
   7#include "wl1251.h"
   8#include "reg.h"
   9#include "cmd.h"
  10#include "ps.h"
  11
  12int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
  13                           u8 mgt_rate, u8 mgt_mod)
  14{
  15        struct acx_fw_gen_frame_rates *rates;
  16        int ret;
  17
  18        wl1251_debug(DEBUG_ACX, "acx frame rates");
  19
  20        rates = kzalloc(sizeof(*rates), GFP_KERNEL);
  21        if (!rates) {
  22                ret = -ENOMEM;
  23                goto out;
  24        }
  25
  26        rates->tx_ctrl_frame_rate = ctrl_rate;
  27        rates->tx_ctrl_frame_mod = ctrl_mod;
  28        rates->tx_mgt_frame_rate = mgt_rate;
  29        rates->tx_mgt_frame_mod = mgt_mod;
  30
  31        ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
  32                                   rates, sizeof(*rates));
  33        if (ret < 0) {
  34                wl1251_error("Failed to set FW rates and modulation");
  35                goto out;
  36        }
  37
  38out:
  39        kfree(rates);
  40        return ret;
  41}
  42
  43
  44int wl1251_acx_station_id(struct wl1251 *wl)
  45{
  46        struct acx_dot11_station_id *mac;
  47        int ret, i;
  48
  49        wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
  50
  51        mac = kzalloc(sizeof(*mac), GFP_KERNEL);
  52        if (!mac) {
  53                ret = -ENOMEM;
  54                goto out;
  55        }
  56
  57        for (i = 0; i < ETH_ALEN; i++)
  58                mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
  59
  60        ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
  61        if (ret < 0)
  62                goto out;
  63
  64out:
  65        kfree(mac);
  66        return ret;
  67}
  68
  69int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
  70{
  71        struct acx_dot11_default_key *default_key;
  72        int ret;
  73
  74        wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
  75
  76        default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
  77        if (!default_key) {
  78                ret = -ENOMEM;
  79                goto out;
  80        }
  81
  82        default_key->id = key_id;
  83
  84        ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
  85                                   default_key, sizeof(*default_key));
  86        if (ret < 0) {
  87                wl1251_error("Couldn't set default key");
  88                goto out;
  89        }
  90
  91        wl->default_key = key_id;
  92
  93out:
  94        kfree(default_key);
  95        return ret;
  96}
  97
  98int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
  99                                  u8 listen_interval)
 100{
 101        struct acx_wake_up_condition *wake_up;
 102        int ret;
 103
 104        wl1251_debug(DEBUG_ACX, "acx wake up conditions");
 105
 106        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
 107        if (!wake_up) {
 108                ret = -ENOMEM;
 109                goto out;
 110        }
 111
 112        wake_up->wake_up_event = wake_up_event;
 113        wake_up->listen_interval = listen_interval;
 114
 115        ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
 116                                   wake_up, sizeof(*wake_up));
 117        if (ret < 0) {
 118                wl1251_warning("could not set wake up conditions: %d", ret);
 119                goto out;
 120        }
 121
 122out:
 123        kfree(wake_up);
 124        return ret;
 125}
 126
 127int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
 128{
 129        struct acx_sleep_auth *auth;
 130        int ret;
 131
 132        wl1251_debug(DEBUG_ACX, "acx sleep auth");
 133
 134        auth = kzalloc(sizeof(*auth), GFP_KERNEL);
 135        if (!auth) {
 136                ret = -ENOMEM;
 137                goto out;
 138        }
 139
 140        auth->sleep_auth = sleep_auth;
 141
 142        ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
 143
 144out:
 145        kfree(auth);
 146        return ret;
 147}
 148
 149int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
 150{
 151        struct acx_revision *rev;
 152        int ret;
 153
 154        wl1251_debug(DEBUG_ACX, "acx fw rev");
 155
 156        rev = kzalloc(sizeof(*rev), GFP_KERNEL);
 157        if (!rev) {
 158                ret = -ENOMEM;
 159                goto out;
 160        }
 161
 162        ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
 163        if (ret < 0) {
 164                wl1251_warning("ACX_FW_REV interrogate failed");
 165                goto out;
 166        }
 167
 168        /* be careful with the buffer sizes */
 169        strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
 170
 171        /*
 172         * if the firmware version string is exactly
 173         * sizeof(rev->fw_version) long or fw_len is less than
 174         * sizeof(rev->fw_version) it won't be null terminated
 175         */
 176        buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
 177
 178out:
 179        kfree(rev);
 180        return ret;
 181}
 182
 183int wl1251_acx_tx_power(struct wl1251 *wl, int power)
 184{
 185        struct acx_current_tx_power *acx;
 186        int ret;
 187
 188        wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
 189
 190        if (power < 0 || power > 25)
 191                return -EINVAL;
 192
 193        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 194        if (!acx) {
 195                ret = -ENOMEM;
 196                goto out;
 197        }
 198
 199        acx->current_tx_power = power * 10;
 200
 201        ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
 202        if (ret < 0) {
 203                wl1251_warning("configure of tx power failed: %d", ret);
 204                goto out;
 205        }
 206
 207out:
 208        kfree(acx);
 209        return ret;
 210}
 211
 212int wl1251_acx_feature_cfg(struct wl1251 *wl)
 213{
 214        struct acx_feature_config *feature;
 215        int ret;
 216
 217        wl1251_debug(DEBUG_ACX, "acx feature cfg");
 218
 219        feature = kzalloc(sizeof(*feature), GFP_KERNEL);
 220        if (!feature) {
 221                ret = -ENOMEM;
 222                goto out;
 223        }
 224
 225        /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
 226        feature->data_flow_options = 0;
 227        feature->options = 0;
 228
 229        ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
 230                                   feature, sizeof(*feature));
 231        if (ret < 0) {
 232                wl1251_error("Couldn't set HW encryption");
 233                goto out;
 234        }
 235
 236out:
 237        kfree(feature);
 238        return ret;
 239}
 240
 241int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
 242                       size_t len)
 243{
 244        int ret;
 245
 246        wl1251_debug(DEBUG_ACX, "acx mem map");
 247
 248        ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
 249        if (ret < 0)
 250                return ret;
 251
 252        return 0;
 253}
 254
 255int wl1251_acx_data_path_params(struct wl1251 *wl,
 256                                struct acx_data_path_params_resp *resp)
 257{
 258        struct acx_data_path_params *params;
 259        int ret;
 260
 261        wl1251_debug(DEBUG_ACX, "acx data path params");
 262
 263        params = kzalloc(sizeof(*params), GFP_KERNEL);
 264        if (!params) {
 265                ret = -ENOMEM;
 266                goto out;
 267        }
 268
 269        params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
 270        params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
 271
 272        params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
 273        params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
 274
 275        params->tx_complete_threshold = 1;
 276
 277        params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
 278
 279        params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
 280
 281        ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
 282                                   params, sizeof(*params));
 283        if (ret < 0)
 284                goto out;
 285
 286        /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
 287        ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
 288                                     resp, sizeof(*resp));
 289
 290        if (ret < 0) {
 291                wl1251_warning("failed to read data path parameters: %d", ret);
 292                goto out;
 293        } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
 294                wl1251_warning("data path parameter acx status failed");
 295                ret = -EIO;
 296                goto out;
 297        }
 298
 299out:
 300        kfree(params);
 301        return ret;
 302}
 303
 304int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
 305{
 306        struct acx_rx_msdu_lifetime *acx;
 307        int ret;
 308
 309        wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
 310
 311        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 312        if (!acx) {
 313                ret = -ENOMEM;
 314                goto out;
 315        }
 316
 317        acx->lifetime = life_time;
 318        ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
 319                                   acx, sizeof(*acx));
 320        if (ret < 0) {
 321                wl1251_warning("failed to set rx msdu life time: %d", ret);
 322                goto out;
 323        }
 324
 325out:
 326        kfree(acx);
 327        return ret;
 328}
 329
 330int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
 331{
 332        struct acx_rx_config *rx_config;
 333        int ret;
 334
 335        wl1251_debug(DEBUG_ACX, "acx rx config");
 336
 337        rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
 338        if (!rx_config) {
 339                ret = -ENOMEM;
 340                goto out;
 341        }
 342
 343        rx_config->config_options = config;
 344        rx_config->filter_options = filter;
 345
 346        ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
 347                                   rx_config, sizeof(*rx_config));
 348        if (ret < 0) {
 349                wl1251_warning("failed to set rx config: %d", ret);
 350                goto out;
 351        }
 352
 353out:
 354        kfree(rx_config);
 355        return ret;
 356}
 357
 358int wl1251_acx_pd_threshold(struct wl1251 *wl)
 359{
 360        struct acx_packet_detection *pd;
 361        int ret;
 362
 363        wl1251_debug(DEBUG_ACX, "acx data pd threshold");
 364
 365        pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 366        if (!pd) {
 367                ret = -ENOMEM;
 368                goto out;
 369        }
 370
 371        /* FIXME: threshold value not set */
 372
 373        ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
 374        if (ret < 0) {
 375                wl1251_warning("failed to set pd threshold: %d", ret);
 376                goto out;
 377        }
 378
 379out:
 380        kfree(pd);
 381        return ret;
 382}
 383
 384int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
 385{
 386        struct acx_slot *slot;
 387        int ret;
 388
 389        wl1251_debug(DEBUG_ACX, "acx slot");
 390
 391        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 392        if (!slot) {
 393                ret = -ENOMEM;
 394                goto out;
 395        }
 396
 397        slot->wone_index = STATION_WONE_INDEX;
 398        slot->slot_time = slot_time;
 399
 400        ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
 401        if (ret < 0) {
 402                wl1251_warning("failed to set slot time: %d", ret);
 403                goto out;
 404        }
 405
 406out:
 407        kfree(slot);
 408        return ret;
 409}
 410
 411int wl1251_acx_group_address_tbl(struct wl1251 *wl)
 412{
 413        struct acx_dot11_grp_addr_tbl *acx;
 414        int ret;
 415
 416        wl1251_debug(DEBUG_ACX, "acx group address tbl");
 417
 418        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 419        if (!acx) {
 420                ret = -ENOMEM;
 421                goto out;
 422        }
 423
 424        /* MAC filtering */
 425        acx->enabled = 0;
 426        acx->num_groups = 0;
 427        memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
 428
 429        ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
 430                                   acx, sizeof(*acx));
 431        if (ret < 0) {
 432                wl1251_warning("failed to set group addr table: %d", ret);
 433                goto out;
 434        }
 435
 436out:
 437        kfree(acx);
 438        return ret;
 439}
 440
 441int wl1251_acx_service_period_timeout(struct wl1251 *wl)
 442{
 443        struct acx_rx_timeout *rx_timeout;
 444        int ret;
 445
 446        rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
 447        if (!rx_timeout) {
 448                ret = -ENOMEM;
 449                goto out;
 450        }
 451
 452        wl1251_debug(DEBUG_ACX, "acx service period timeout");
 453
 454        rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
 455        rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
 456
 457        ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
 458                                   rx_timeout, sizeof(*rx_timeout));
 459        if (ret < 0) {
 460                wl1251_warning("failed to set service period timeout: %d",
 461                               ret);
 462                goto out;
 463        }
 464
 465out:
 466        kfree(rx_timeout);
 467        return ret;
 468}
 469
 470int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
 471{
 472        struct acx_rts_threshold *rts;
 473        int ret;
 474
 475        wl1251_debug(DEBUG_ACX, "acx rts threshold");
 476
 477        rts = kzalloc(sizeof(*rts), GFP_KERNEL);
 478        if (!rts) {
 479                ret = -ENOMEM;
 480                goto out;
 481        }
 482
 483        rts->threshold = rts_threshold;
 484
 485        ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 486        if (ret < 0) {
 487                wl1251_warning("failed to set rts threshold: %d", ret);
 488                goto out;
 489        }
 490
 491out:
 492        kfree(rts);
 493        return ret;
 494}
 495
 496int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
 497{
 498        struct acx_beacon_filter_option *beacon_filter;
 499        int ret;
 500
 501        wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
 502
 503        beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
 504        if (!beacon_filter) {
 505                ret = -ENOMEM;
 506                goto out;
 507        }
 508
 509        beacon_filter->enable = enable_filter;
 510        beacon_filter->max_num_beacons = 0;
 511
 512        ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
 513                                   beacon_filter, sizeof(*beacon_filter));
 514        if (ret < 0) {
 515                wl1251_warning("failed to set beacon filter opt: %d", ret);
 516                goto out;
 517        }
 518
 519out:
 520        kfree(beacon_filter);
 521        return ret;
 522}
 523
 524int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
 525{
 526        struct acx_beacon_filter_ie_table *ie_table;
 527        int idx = 0;
 528        int ret;
 529
 530        wl1251_debug(DEBUG_ACX, "acx beacon filter table");
 531
 532        ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
 533        if (!ie_table) {
 534                ret = -ENOMEM;
 535                goto out;
 536        }
 537
 538        /* configure default beacon pass-through rules */
 539        ie_table->num_ie = 1;
 540        ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
 541        ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
 542
 543        ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 544                                   ie_table, sizeof(*ie_table));
 545        if (ret < 0) {
 546                wl1251_warning("failed to set beacon filter table: %d", ret);
 547                goto out;
 548        }
 549
 550out:
 551        kfree(ie_table);
 552        return ret;
 553}
 554
 555int wl1251_acx_conn_monit_params(struct wl1251 *wl)
 556{
 557        struct acx_conn_monit_params *acx;
 558        int ret;
 559
 560        wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
 561
 562        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 563        if (!acx) {
 564                ret = -ENOMEM;
 565                goto out;
 566        }
 567
 568        acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
 569        acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
 570
 571        ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
 572                                   acx, sizeof(*acx));
 573        if (ret < 0) {
 574                wl1251_warning("failed to set connection monitor "
 575                               "parameters: %d", ret);
 576                goto out;
 577        }
 578
 579out:
 580        kfree(acx);
 581        return ret;
 582}
 583
 584int wl1251_acx_sg_enable(struct wl1251 *wl)
 585{
 586        struct acx_bt_wlan_coex *pta;
 587        int ret;
 588
 589        wl1251_debug(DEBUG_ACX, "acx sg enable");
 590
 591        pta = kzalloc(sizeof(*pta), GFP_KERNEL);
 592        if (!pta) {
 593                ret = -ENOMEM;
 594                goto out;
 595        }
 596
 597        pta->enable = SG_ENABLE;
 598
 599        ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
 600        if (ret < 0) {
 601                wl1251_warning("failed to set softgemini enable: %d", ret);
 602                goto out;
 603        }
 604
 605out:
 606        kfree(pta);
 607        return ret;
 608}
 609
 610int wl1251_acx_sg_cfg(struct wl1251 *wl)
 611{
 612        struct acx_bt_wlan_coex_param *param;
 613        int ret;
 614
 615        wl1251_debug(DEBUG_ACX, "acx sg cfg");
 616
 617        param = kzalloc(sizeof(*param), GFP_KERNEL);
 618        if (!param) {
 619                ret = -ENOMEM;
 620                goto out;
 621        }
 622
 623        /* BT-WLAN coext parameters */
 624        param->min_rate = RATE_INDEX_24MBPS;
 625        param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
 626        param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
 627        param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
 628        param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
 629        param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
 630        param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
 631        param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
 632        param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
 633        param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
 634        param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
 635        param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
 636        param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
 637        param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
 638        param->antenna_type = PTA_ANTENNA_TYPE_DEF;
 639        param->signal_type = PTA_SIGNALING_TYPE_DEF;
 640        param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
 641        param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
 642        param->max_cts = PTA_MAX_NUM_CTS_DEF;
 643        param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
 644        param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
 645        param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
 646        param->wlan_elp_hp = PTA_ELP_HP_DEF;
 647        param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
 648        param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
 649        param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
 650        param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
 651        param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
 652
 653        ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
 654        if (ret < 0) {
 655                wl1251_warning("failed to set sg config: %d", ret);
 656                goto out;
 657        }
 658
 659out:
 660        kfree(param);
 661        return ret;
 662}
 663
 664int wl1251_acx_cca_threshold(struct wl1251 *wl)
 665{
 666        struct acx_energy_detection *detection;
 667        int ret;
 668
 669        wl1251_debug(DEBUG_ACX, "acx cca threshold");
 670
 671        detection = kzalloc(sizeof(*detection), GFP_KERNEL);
 672        if (!detection) {
 673                ret = -ENOMEM;
 674                goto out;
 675        }
 676
 677        detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
 678        detection->tx_energy_detection = 0;
 679
 680        ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
 681                                   detection, sizeof(*detection));
 682        if (ret < 0)
 683                wl1251_warning("failed to set cca threshold: %d", ret);
 684
 685out:
 686        kfree(detection);
 687        return ret;
 688}
 689
 690int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
 691{
 692        struct acx_beacon_broadcast *bb;
 693        int ret;
 694
 695        wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
 696
 697        bb = kzalloc(sizeof(*bb), GFP_KERNEL);
 698        if (!bb) {
 699                ret = -ENOMEM;
 700                goto out;
 701        }
 702
 703        bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
 704        bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
 705        bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
 706        bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
 707
 708        ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
 709        if (ret < 0) {
 710                wl1251_warning("failed to set rx config: %d", ret);
 711                goto out;
 712        }
 713
 714out:
 715        kfree(bb);
 716        return ret;
 717}
 718
 719int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
 720{
 721        struct acx_aid *acx_aid;
 722        int ret;
 723
 724        wl1251_debug(DEBUG_ACX, "acx aid");
 725
 726        acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
 727        if (!acx_aid) {
 728                ret = -ENOMEM;
 729                goto out;
 730        }
 731
 732        acx_aid->aid = aid;
 733
 734        ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
 735        if (ret < 0) {
 736                wl1251_warning("failed to set aid: %d", ret);
 737                goto out;
 738        }
 739
 740out:
 741        kfree(acx_aid);
 742        return ret;
 743}
 744
 745int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
 746{
 747        struct acx_event_mask *mask;
 748        int ret;
 749
 750        wl1251_debug(DEBUG_ACX, "acx event mbox mask");
 751
 752        mask = kzalloc(sizeof(*mask), GFP_KERNEL);
 753        if (!mask) {
 754                ret = -ENOMEM;
 755                goto out;
 756        }
 757
 758        /* high event mask is unused */
 759        mask->high_event_mask = 0xffffffff;
 760
 761        mask->event_mask = event_mask;
 762
 763        ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
 764                                   mask, sizeof(*mask));
 765        if (ret < 0) {
 766                wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
 767                goto out;
 768        }
 769
 770out:
 771        kfree(mask);
 772        return ret;
 773}
 774
 775int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight,
 776                        u8 depth, enum wl1251_acx_low_rssi_type type)
 777{
 778        struct acx_low_rssi *rssi;
 779        int ret;
 780
 781        wl1251_debug(DEBUG_ACX, "acx low rssi");
 782
 783        rssi = kzalloc(sizeof(*rssi), GFP_KERNEL);
 784        if (!rssi)
 785                return -ENOMEM;
 786
 787        rssi->threshold = threshold;
 788        rssi->weight = weight;
 789        rssi->depth = depth;
 790        rssi->type = type;
 791
 792        ret = wl1251_cmd_configure(wl, ACX_LOW_RSSI, rssi, sizeof(*rssi));
 793        if (ret < 0)
 794                wl1251_warning("failed to set low rssi threshold: %d", ret);
 795
 796        kfree(rssi);
 797        return ret;
 798}
 799
 800int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
 801{
 802        struct acx_preamble *acx;
 803        int ret;
 804
 805        wl1251_debug(DEBUG_ACX, "acx_set_preamble");
 806
 807        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 808        if (!acx) {
 809                ret = -ENOMEM;
 810                goto out;
 811        }
 812
 813        acx->preamble = preamble;
 814
 815        ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
 816        if (ret < 0) {
 817                wl1251_warning("Setting of preamble failed: %d", ret);
 818                goto out;
 819        }
 820
 821out:
 822        kfree(acx);
 823        return ret;
 824}
 825
 826int wl1251_acx_cts_protect(struct wl1251 *wl,
 827                           enum acx_ctsprotect_type ctsprotect)
 828{
 829        struct acx_ctsprotect *acx;
 830        int ret;
 831
 832        wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
 833
 834        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 835        if (!acx) {
 836                ret = -ENOMEM;
 837                goto out;
 838        }
 839
 840        acx->ctsprotect = ctsprotect;
 841
 842        ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
 843        if (ret < 0) {
 844                wl1251_warning("Setting of ctsprotect failed: %d", ret);
 845                goto out;
 846        }
 847
 848out:
 849        kfree(acx);
 850        return ret;
 851}
 852
 853int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
 854{
 855        struct acx_tsf_info *tsf_info;
 856        int ret;
 857
 858        tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
 859        if (!tsf_info) {
 860                ret = -ENOMEM;
 861                goto out;
 862        }
 863
 864        ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
 865                                     tsf_info, sizeof(*tsf_info));
 866        if (ret < 0) {
 867                wl1251_warning("ACX_FW_REV interrogate failed");
 868                goto out;
 869        }
 870
 871        *mactime = tsf_info->current_tsf_lsb |
 872                (tsf_info->current_tsf_msb << 31);
 873
 874out:
 875        kfree(tsf_info);
 876        return ret;
 877}
 878
 879int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
 880{
 881        int ret;
 882
 883        wl1251_debug(DEBUG_ACX, "acx statistics");
 884
 885        ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
 886                                     sizeof(*stats));
 887        if (ret < 0) {
 888                wl1251_warning("acx statistics failed: %d", ret);
 889                return -ENOMEM;
 890        }
 891
 892        return 0;
 893}
 894
 895int wl1251_acx_rate_policies(struct wl1251 *wl)
 896{
 897        struct acx_rate_policy *acx;
 898        int ret = 0;
 899
 900        wl1251_debug(DEBUG_ACX, "acx rate policies");
 901
 902        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 903
 904        if (!acx) {
 905                ret = -ENOMEM;
 906                goto out;
 907        }
 908
 909        /* configure one default (one-size-fits-all) rate class */
 910        acx->rate_class_cnt = 1;
 911        acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
 912        acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
 913        acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
 914        acx->rate_class[0].aflags = 0;
 915
 916        ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 917        if (ret < 0) {
 918                wl1251_warning("Setting of rate policies failed: %d", ret);
 919                goto out;
 920        }
 921
 922out:
 923        kfree(acx);
 924        return ret;
 925}
 926
 927int wl1251_acx_mem_cfg(struct wl1251 *wl)
 928{
 929        struct wl1251_acx_config_memory *mem_conf;
 930        int ret, i;
 931
 932        wl1251_debug(DEBUG_ACX, "acx mem cfg");
 933
 934        mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
 935        if (!mem_conf) {
 936                ret = -ENOMEM;
 937                goto out;
 938        }
 939
 940        /* memory config */
 941        mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
 942        mem_conf->mem_config.rx_mem_block_num = 35;
 943        mem_conf->mem_config.tx_min_mem_block_num = 64;
 944        mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
 945        mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
 946        mem_conf->mem_config.num_ssid_profiles = 1;
 947        mem_conf->mem_config.debug_buffer_size =
 948                cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
 949
 950        /* RX queue config */
 951        mem_conf->rx_queue_config.dma_address = 0;
 952        mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
 953        mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
 954        mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
 955
 956        /* TX queue config */
 957        for (i = 0; i < MAX_TX_QUEUES; i++) {
 958                mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
 959                mem_conf->tx_queue_config[i].attributes = i;
 960        }
 961
 962        ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 963                                   sizeof(*mem_conf));
 964        if (ret < 0) {
 965                wl1251_warning("wl1251 mem config failed: %d", ret);
 966                goto out;
 967        }
 968
 969out:
 970        kfree(mem_conf);
 971        return ret;
 972}
 973
 974int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
 975{
 976        struct wl1251_acx_wr_tbtt_and_dtim *acx;
 977        int ret;
 978
 979        wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
 980
 981        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 982        if (!acx) {
 983                ret = -ENOMEM;
 984                goto out;
 985        }
 986
 987        acx->tbtt = tbtt;
 988        acx->dtim = dtim;
 989
 990        ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
 991                                   acx, sizeof(*acx));
 992        if (ret < 0) {
 993                wl1251_warning("failed to set tbtt and dtim: %d", ret);
 994                goto out;
 995        }
 996
 997out:
 998        kfree(acx);
 999        return ret;
1000}
1001
1002int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1003                          u8 max_consecutive)
1004{
1005        struct wl1251_acx_bet_enable *acx;
1006        int ret;
1007
1008        wl1251_debug(DEBUG_ACX, "acx bet enable");
1009
1010        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1011        if (!acx) {
1012                ret = -ENOMEM;
1013                goto out;
1014        }
1015
1016        acx->enable = mode;
1017        acx->max_consecutive = max_consecutive;
1018
1019        ret = wl1251_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
1020        if (ret < 0) {
1021                wl1251_warning("wl1251 acx bet enable failed: %d", ret);
1022                goto out;
1023        }
1024
1025out:
1026        kfree(acx);
1027        return ret;
1028}
1029
1030int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1031                      u8 aifs, u16 txop)
1032{
1033        struct wl1251_acx_ac_cfg *acx;
1034        int ret = 0;
1035
1036        wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
1037                     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
1038
1039        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1040
1041        if (!acx) {
1042                ret = -ENOMEM;
1043                goto out;
1044        }
1045
1046        acx->ac = ac;
1047        acx->cw_min = cw_min;
1048        acx->cw_max = cw_max;
1049        acx->aifsn = aifs;
1050        acx->txop_limit = txop;
1051
1052        ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
1053        if (ret < 0) {
1054                wl1251_warning("acx ac cfg failed: %d", ret);
1055                goto out;
1056        }
1057
1058out:
1059        kfree(acx);
1060        return ret;
1061}
1062
1063int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1064                       enum wl1251_acx_channel_type type,
1065                       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1066                       enum wl1251_acx_ack_policy ack_policy)
1067{
1068        struct wl1251_acx_tid_cfg *acx;
1069        int ret = 0;
1070
1071        wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
1072                     "ps_scheme %d ack_policy %d", queue, type, tsid,
1073                     ps_scheme, ack_policy);
1074
1075        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1076
1077        if (!acx) {
1078                ret = -ENOMEM;
1079                goto out;
1080        }
1081
1082        acx->queue = queue;
1083        acx->type = type;
1084        acx->tsid = tsid;
1085        acx->ps_scheme = ps_scheme;
1086        acx->ack_policy = ack_policy;
1087
1088        ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
1089        if (ret < 0) {
1090                wl1251_warning("acx tid cfg failed: %d", ret);
1091                goto out;
1092        }
1093
1094out:
1095        kfree(acx);
1096        return ret;
1097}
1098