linux/drivers/net/wireless/ti/wl18xx/acx.c
<<
>>
Prefs
   1/*
   2 * This file is part of wl18xx
   3 *
   4 * Copyright (C) 2011 Texas Instruments Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  18 * 02110-1301 USA
  19 *
  20 */
  21
  22#include "../wlcore/cmd.h"
  23#include "../wlcore/debug.h"
  24#include "../wlcore/acx.h"
  25
  26#include "acx.h"
  27
  28int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
  29                                  u32 sdio_blk_size, u32 extra_mem_blks,
  30                                  u32 len_field_size)
  31{
  32        struct wl18xx_acx_host_config_bitmap *bitmap_conf;
  33        int ret;
  34
  35        wl1271_debug(DEBUG_ACX, "acx cfg bitmap %d blk %d spare %d field %d",
  36                     host_cfg_bitmap, sdio_blk_size, extra_mem_blks,
  37                     len_field_size);
  38
  39        bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
  40        if (!bitmap_conf) {
  41                ret = -ENOMEM;
  42                goto out;
  43        }
  44
  45        bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
  46        bitmap_conf->host_sdio_block_size = cpu_to_le32(sdio_blk_size);
  47        bitmap_conf->extra_mem_blocks = cpu_to_le32(extra_mem_blks);
  48        bitmap_conf->length_field_size = cpu_to_le32(len_field_size);
  49
  50        ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
  51                                   bitmap_conf, sizeof(*bitmap_conf));
  52        if (ret < 0) {
  53                wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
  54                goto out;
  55        }
  56
  57out:
  58        kfree(bitmap_conf);
  59
  60        return ret;
  61}
  62
  63int wl18xx_acx_set_checksum_state(struct wl1271 *wl)
  64{
  65        struct wl18xx_acx_checksum_state *acx;
  66        int ret;
  67
  68        wl1271_debug(DEBUG_ACX, "acx checksum state");
  69
  70        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  71        if (!acx) {
  72                ret = -ENOMEM;
  73                goto out;
  74        }
  75
  76        acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED;
  77
  78        ret = wl1271_cmd_configure(wl, ACX_CSUM_CONFIG, acx, sizeof(*acx));
  79        if (ret < 0) {
  80                wl1271_warning("failed to set Tx checksum state: %d", ret);
  81                goto out;
  82        }
  83
  84out:
  85        kfree(acx);
  86        return ret;
  87}
  88
  89int wl18xx_acx_clear_statistics(struct wl1271 *wl)
  90{
  91        struct wl18xx_acx_clear_statistics *acx;
  92        int ret = 0;
  93
  94        wl1271_debug(DEBUG_ACX, "acx clear statistics");
  95
  96        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  97        if (!acx) {
  98                ret = -ENOMEM;
  99                goto out;
 100        }
 101
 102        ret = wl1271_cmd_configure(wl, ACX_CLEAR_STATISTICS, acx, sizeof(*acx));
 103        if (ret < 0) {
 104                wl1271_warning("failed to clear firmware statistics: %d", ret);
 105                goto out;
 106        }
 107
 108out:
 109        kfree(acx);
 110        return ret;
 111}
 112
 113int wl18xx_acx_peer_ht_operation_mode(struct wl1271 *wl, u8 hlid, bool wide)
 114{
 115        struct wlcore_peer_ht_operation_mode *acx;
 116        int ret;
 117
 118        wl1271_debug(DEBUG_ACX, "acx peer ht operation mode hlid %d bw %d",
 119                     hlid, wide);
 120
 121        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 122        if (!acx) {
 123                ret = -ENOMEM;
 124                goto out;
 125        }
 126
 127        acx->hlid = hlid;
 128        acx->bandwidth = wide ? WLCORE_BANDWIDTH_40MHZ : WLCORE_BANDWIDTH_20MHZ;
 129
 130        ret = wl1271_cmd_configure(wl, ACX_PEER_HT_OPERATION_MODE_CFG, acx,
 131                                   sizeof(*acx));
 132
 133        if (ret < 0) {
 134                wl1271_warning("acx peer ht operation mode failed: %d", ret);
 135                goto out;
 136        }
 137
 138out:
 139        kfree(acx);
 140        return ret;
 141
 142}
 143
 144/*
 145 * this command is basically the same as wl1271_acx_ht_capabilities,
 146 * with the addition of supported rates. they should be unified in
 147 * the next fw api change
 148 */
 149int wl18xx_acx_set_peer_cap(struct wl1271 *wl,
 150                            struct ieee80211_sta_ht_cap *ht_cap,
 151                            bool allow_ht_operation,
 152                            u32 rate_set, u8 hlid)
 153{
 154        struct wlcore_acx_peer_cap *acx;
 155        int ret = 0;
 156        u32 ht_capabilites = 0;
 157
 158        wl1271_debug(DEBUG_ACX,
 159                     "acx set cap ht_supp: %d ht_cap: %d rates: 0x%x",
 160                     ht_cap->ht_supported, ht_cap->cap, rate_set);
 161
 162        acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 163        if (!acx) {
 164                ret = -ENOMEM;
 165                goto out;
 166        }
 167
 168        if (allow_ht_operation && ht_cap->ht_supported) {
 169                /* no need to translate capabilities - use the spec values */
 170                ht_capabilites = ht_cap->cap;
 171
 172                /*
 173                 * this bit is not employed by the spec but only by FW to
 174                 * indicate peer HT support
 175                 */
 176                ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
 177
 178                /* get data from A-MPDU parameters field */
 179                acx->ampdu_max_length = ht_cap->ampdu_factor;
 180                acx->ampdu_min_spacing = ht_cap->ampdu_density;
 181        }
 182
 183        acx->hlid = hlid;
 184        acx->ht_capabilites = cpu_to_le32(ht_capabilites);
 185        acx->supported_rates = cpu_to_le32(rate_set);
 186
 187        ret = wl1271_cmd_configure(wl, ACX_PEER_CAP, acx, sizeof(*acx));
 188        if (ret < 0) {
 189                wl1271_warning("acx ht capabilities setting failed: %d", ret);
 190                goto out;
 191        }
 192
 193out:
 194        kfree(acx);
 195        return ret;
 196}
 197