1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of wl18xx
5 * Copyright (C) 2011 Texas Instruments Inc.
8 #include "../wlcore/cmd.h"
9 #include "../wlcore/debug.h"
10 #include "../wlcore/acx.h"
15 int wl18xx_acx_host_if_cfg_bitmap(struct wl1271
*wl
, u32 host_cfg_bitmap
,
16 u32 sdio_blk_size
, u32 extra_mem_blks
,
19 struct wl18xx_acx_host_config_bitmap
*bitmap_conf
;
22 wl1271_debug(DEBUG_ACX
, "acx cfg bitmap %d blk %d spare %d field %d",
23 host_cfg_bitmap
, sdio_blk_size
, extra_mem_blks
,
26 bitmap_conf
= kzalloc(sizeof(*bitmap_conf
), GFP_KERNEL
);
32 bitmap_conf
->host_cfg_bitmap
= cpu_to_le32(host_cfg_bitmap
);
33 bitmap_conf
->host_sdio_block_size
= cpu_to_le32(sdio_blk_size
);
34 bitmap_conf
->extra_mem_blocks
= cpu_to_le32(extra_mem_blks
);
35 bitmap_conf
->length_field_size
= cpu_to_le32(len_field_size
);
37 ret
= wl1271_cmd_configure(wl
, ACX_HOST_IF_CFG_BITMAP
,
38 bitmap_conf
, sizeof(*bitmap_conf
));
40 wl1271_warning("wl1271 bitmap config opt failed: %d", ret
);
50 int wl18xx_acx_set_checksum_state(struct wl1271
*wl
)
52 struct wl18xx_acx_checksum_state
*acx
;
55 wl1271_debug(DEBUG_ACX
, "acx checksum state");
57 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
63 acx
->checksum_state
= CHECKSUM_OFFLOAD_ENABLED
;
65 ret
= wl1271_cmd_configure(wl
, ACX_CSUM_CONFIG
, acx
, sizeof(*acx
));
67 wl1271_warning("failed to set Tx checksum state: %d", ret
);
76 int wl18xx_acx_clear_statistics(struct wl1271
*wl
)
78 struct wl18xx_acx_clear_statistics
*acx
;
81 wl1271_debug(DEBUG_ACX
, "acx clear statistics");
83 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
89 ret
= wl1271_cmd_configure(wl
, ACX_CLEAR_STATISTICS
, acx
, sizeof(*acx
));
91 wl1271_warning("failed to clear firmware statistics: %d", ret
);
100 int wl18xx_acx_peer_ht_operation_mode(struct wl1271
*wl
, u8 hlid
, bool wide
)
102 struct wlcore_peer_ht_operation_mode
*acx
;
105 wl1271_debug(DEBUG_ACX
, "acx peer ht operation mode hlid %d bw %d",
108 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
115 acx
->bandwidth
= wide
? WLCORE_BANDWIDTH_40MHZ
: WLCORE_BANDWIDTH_20MHZ
;
117 ret
= wl1271_cmd_configure(wl
, ACX_PEER_HT_OPERATION_MODE_CFG
, acx
,
121 wl1271_warning("acx peer ht operation mode failed: %d", ret
);
132 * this command is basically the same as wl1271_acx_ht_capabilities,
133 * with the addition of supported rates. they should be unified in
134 * the next fw api change
136 int wl18xx_acx_set_peer_cap(struct wl1271
*wl
,
137 struct ieee80211_sta_ht_cap
*ht_cap
,
138 bool allow_ht_operation
,
139 u32 rate_set
, u8 hlid
)
141 struct wlcore_acx_peer_cap
*acx
;
143 u32 ht_capabilites
= 0;
145 wl1271_debug(DEBUG_ACX
,
146 "acx set cap ht_supp: %d ht_cap: %d rates: 0x%x",
147 ht_cap
->ht_supported
, ht_cap
->cap
, rate_set
);
149 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
155 if (allow_ht_operation
&& ht_cap
->ht_supported
) {
156 /* no need to translate capabilities - use the spec values */
157 ht_capabilites
= ht_cap
->cap
;
160 * this bit is not employed by the spec but only by FW to
161 * indicate peer HT support
163 ht_capabilites
|= WL12XX_HT_CAP_HT_OPERATION
;
165 /* get data from A-MPDU parameters field */
166 acx
->ampdu_max_length
= ht_cap
->ampdu_factor
;
167 acx
->ampdu_min_spacing
= ht_cap
->ampdu_density
;
171 acx
->ht_capabilites
= cpu_to_le32(ht_capabilites
);
172 acx
->supported_rates
= cpu_to_le32(rate_set
);
174 ret
= wl1271_cmd_configure(wl
, ACX_PEER_CAP
, acx
, sizeof(*acx
));
176 wl1271_warning("acx ht capabilities setting failed: %d", ret
);
186 * When the host is suspended, we don't want to get any fast-link/PSM
189 int wl18xx_acx_interrupt_notify_config(struct wl1271
*wl
,
192 struct wl18xx_acx_interrupt_notify
*acx
;
195 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
201 acx
->enable
= action
;
202 ret
= wl1271_cmd_configure(wl
, ACX_INTERRUPT_NOTIFY
, acx
, sizeof(*acx
));
204 wl1271_warning("acx interrupt notify setting failed: %d", ret
);
214 * When the host is suspended, we can configure the FW to disable RX BA
217 int wl18xx_acx_rx_ba_filter(struct wl1271
*wl
, bool action
)
219 struct wl18xx_acx_rx_ba_filter
*acx
;
222 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
228 acx
->enable
= (u32
)action
;
229 ret
= wl1271_cmd_configure(wl
, ACX_RX_BA_FILTER
, acx
, sizeof(*acx
));
231 wl1271_warning("acx rx ba activity filter setting failed: %d",
241 int wl18xx_acx_ap_sleep(struct wl1271
*wl
)
243 struct wl18xx_priv
*priv
= wl
->priv
;
244 struct acx_ap_sleep_cfg
*acx
;
245 struct conf_ap_sleep_settings
*conf
= &priv
->conf
.ap_sleep
;
248 wl1271_debug(DEBUG_ACX
, "acx config ap sleep");
250 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
256 acx
->idle_duty_cycle
= conf
->idle_duty_cycle
;
257 acx
->connected_duty_cycle
= conf
->connected_duty_cycle
;
258 acx
->max_stations_thresh
= conf
->max_stations_thresh
;
259 acx
->idle_conn_thresh
= conf
->idle_conn_thresh
;
261 ret
= wl1271_cmd_configure(wl
, ACX_AP_SLEEP_CFG
, acx
, sizeof(*acx
));
263 wl1271_warning("acx config ap-sleep failed: %d", ret
);
272 int wl18xx_acx_dynamic_fw_traces(struct wl1271
*wl
)
274 struct acx_dynamic_fw_traces_cfg
*acx
;
277 wl1271_debug(DEBUG_ACX
, "acx dynamic fw traces config %d",
278 wl
->dynamic_fw_traces
);
280 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
286 acx
->dynamic_fw_traces
= cpu_to_le32(wl
->dynamic_fw_traces
);
288 ret
= wl1271_cmd_configure(wl
, ACX_DYNAMIC_TRACES_CFG
,
291 wl1271_warning("acx config dynamic fw traces failed: %d", ret
);
299 int wl18xx_acx_time_sync_cfg(struct wl1271
*wl
)
301 struct acx_time_sync_cfg
*acx
;
304 wl1271_debug(DEBUG_ACX
, "acx time sync cfg: mode %d, addr: %pM",
305 wl
->conf
.sg
.params
[WL18XX_CONF_SG_TIME_SYNC
],
306 wl
->zone_master_mac_addr
);
308 acx
= kzalloc(sizeof(*acx
), GFP_KERNEL
);
314 acx
->sync_mode
= wl
->conf
.sg
.params
[WL18XX_CONF_SG_TIME_SYNC
];
315 memcpy(acx
->zone_mac_addr
, wl
->zone_master_mac_addr
, ETH_ALEN
);
317 ret
= wl1271_cmd_configure(wl
, ACX_TIME_SYNC_CFG
,
320 wl1271_warning("acx time sync cfg failed: %d", ret
);