2 * This file is part of wl18xx
4 * Copyright (C) 2011 Texas Instruments Inc.
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.
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.
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
22 #include "../wlcore/cmd.h"
23 #include "../wlcore/debug.h"
24 #include "../wlcore/acx.h"
29 int wl18xx_acx_host_if_cfg_bitmap(struct wl1271
*wl
, u32 host_cfg_bitmap
,
30 u32 sdio_blk_size
, u32 extra_mem_blks
,
33 struct wl18xx_acx_host_config_bitmap
*bitmap_conf
;
36 wl1271_debug(DEBUG_ACX
, "acx cfg bitmap %d blk %d spare %d field %d",
37 host_cfg_bitmap
, sdio_blk_size
, extra_mem_blks
,
40 bitmap_conf
= kzalloc(sizeof(*bitmap_conf
), GFP_KERNEL
);
46 bitmap_conf
->host_cfg_bitmap
= cpu_to_le32(host_cfg_bitmap
);
47 bitmap_conf
->host_sdio_block_size
= cpu_to_le32(sdio_blk_size
);
48 bitmap_conf
->extra_mem_blocks
= cpu_to_le32(extra_mem_blks
);
49 bitmap_conf
->length_field_size
= cpu_to_le32(len_field_size
);
51 ret
= wl1271_cmd_configure(wl
, ACX_HOST_IF_CFG_BITMAP
,
52 bitmap_conf
, sizeof(*bitmap_conf
));
54 wl1271_warning("wl1271 bitmap config opt failed: %d", ret
);
64 int wl18xx_acx_set_checksum_state(struct wl1271
*wl
)
66 struct wl18xx_acx_checksum_state
*acx
;
69 wl1271_debug(DEBUG_ACX
, "acx checksum state");
71 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
77 acx
->checksum_state
= CHECKSUM_OFFLOAD_ENABLED
;
79 ret
= wl1271_cmd_configure(wl
, ACX_CSUM_CONFIG
, acx
, sizeof(*acx
));
81 wl1271_warning("failed to set Tx checksum state: %d", ret
);
90 int wl18xx_acx_clear_statistics(struct wl1271
*wl
)
92 struct wl18xx_acx_clear_statistics
*acx
;
95 wl1271_debug(DEBUG_ACX
, "acx clear statistics");
97 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
103 ret
= wl1271_cmd_configure(wl
, ACX_CLEAR_STATISTICS
, acx
, sizeof(*acx
));
105 wl1271_warning("failed to clear firmware statistics: %d", ret
);
114 int wl18xx_acx_peer_ht_operation_mode(struct wl1271
*wl
, u8 hlid
, bool wide
)
116 struct wlcore_peer_ht_operation_mode
*acx
;
119 wl1271_debug(DEBUG_ACX
, "acx peer ht operation mode hlid %d bw %d",
122 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
129 acx
->bandwidth
= wide
? WLCORE_BANDWIDTH_40MHZ
: WLCORE_BANDWIDTH_20MHZ
;
131 ret
= wl1271_cmd_configure(wl
, ACX_PEER_HT_OPERATION_MODE_CFG
, acx
,
135 wl1271_warning("acx peer ht operation mode failed: %d", ret
);
146 * this command is basically the same as wl1271_acx_ht_capabilities,
147 * with the addition of supported rates. they should be unified in
148 * the next fw api change
150 int wl18xx_acx_set_peer_cap(struct wl1271
*wl
,
151 struct ieee80211_sta_ht_cap
*ht_cap
,
152 bool allow_ht_operation
,
153 u32 rate_set
, u8 hlid
)
155 struct wlcore_acx_peer_cap
*acx
;
157 u32 ht_capabilites
= 0;
159 wl1271_debug(DEBUG_ACX
,
160 "acx set cap ht_supp: %d ht_cap: %d rates: 0x%x",
161 ht_cap
->ht_supported
, ht_cap
->cap
, rate_set
);
163 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
169 if (allow_ht_operation
&& ht_cap
->ht_supported
) {
170 /* no need to translate capabilities - use the spec values */
171 ht_capabilites
= ht_cap
->cap
;
174 * this bit is not employed by the spec but only by FW to
175 * indicate peer HT support
177 ht_capabilites
|= WL12XX_HT_CAP_HT_OPERATION
;
179 /* get data from A-MPDU parameters field */
180 acx
->ampdu_max_length
= ht_cap
->ampdu_factor
;
181 acx
->ampdu_min_spacing
= ht_cap
->ampdu_density
;
185 acx
->ht_capabilites
= cpu_to_le32(ht_capabilites
);
186 acx
->supported_rates
= cpu_to_le32(rate_set
);
188 ret
= wl1271_cmd_configure(wl
, ACX_PEER_CAP
, acx
, sizeof(*acx
));
190 wl1271_warning("acx ht capabilities setting failed: %d", ret
);
200 * When the host is suspended, we don't want to get any fast-link/PSM
203 int wl18xx_acx_interrupt_notify_config(struct wl1271
*wl
,
206 struct wl18xx_acx_interrupt_notify
*acx
;
209 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
215 acx
->enable
= action
;
216 ret
= wl1271_cmd_configure(wl
, ACX_INTERRUPT_NOTIFY
, acx
, sizeof(*acx
));
218 wl1271_warning("acx interrupt notify setting failed: %d", ret
);
228 * When the host is suspended, we can configure the FW to disable RX BA
231 int wl18xx_acx_rx_ba_filter(struct wl1271
*wl
, bool action
)
233 struct wl18xx_acx_rx_ba_filter
*acx
;
236 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
242 acx
->enable
= (u32
)action
;
243 ret
= wl1271_cmd_configure(wl
, ACX_RX_BA_FILTER
, acx
, sizeof(*acx
));
245 wl1271_warning("acx rx ba activity filter setting failed: %d",
255 int wl18xx_acx_ap_sleep(struct wl1271
*wl
)
257 struct wl18xx_priv
*priv
= wl
->priv
;
258 struct acx_ap_sleep_cfg
*acx
;
259 struct conf_ap_sleep_settings
*conf
= &priv
->conf
.ap_sleep
;
262 wl1271_debug(DEBUG_ACX
, "acx config ap sleep");
264 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
270 acx
->idle_duty_cycle
= conf
->idle_duty_cycle
;
271 acx
->connected_duty_cycle
= conf
->connected_duty_cycle
;
272 acx
->max_stations_thresh
= conf
->max_stations_thresh
;
273 acx
->idle_conn_thresh
= conf
->idle_conn_thresh
;
275 ret
= wl1271_cmd_configure(wl
, ACX_AP_SLEEP_CFG
, acx
, sizeof(*acx
));
277 wl1271_warning("acx config ap-sleep failed: %d", ret
);
286 int wl18xx_acx_dynamic_fw_traces(struct wl1271
*wl
)
288 struct acx_dynamic_fw_traces_cfg
*acx
;
291 wl1271_debug(DEBUG_ACX
, "acx dynamic fw traces config %d",
292 wl
->dynamic_fw_traces
);
294 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
300 acx
->dynamic_fw_traces
= cpu_to_le32(wl
->dynamic_fw_traces
);
302 ret
= wl1271_cmd_configure(wl
, ACX_DYNAMIC_TRACES_CFG
,
305 wl1271_warning("acx config dynamic fw traces failed: %d", ret
);