cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

acx.c (7217B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * This file is part of wl18xx
      4 *
      5 * Copyright (C) 2011 Texas Instruments Inc.
      6 */
      7
      8#include "../wlcore/cmd.h"
      9#include "../wlcore/debug.h"
     10#include "../wlcore/acx.h"
     11
     12#include "acx.h"
     13#include "wl18xx.h"
     14
     15int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
     16				  u32 sdio_blk_size, u32 extra_mem_blks,
     17				  u32 len_field_size)
     18{
     19	struct wl18xx_acx_host_config_bitmap *bitmap_conf;
     20	int ret;
     21
     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,
     24		     len_field_size);
     25
     26	bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
     27	if (!bitmap_conf) {
     28		ret = -ENOMEM;
     29		goto out;
     30	}
     31
     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);
     36
     37	ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
     38				   bitmap_conf, sizeof(*bitmap_conf));
     39	if (ret < 0) {
     40		wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
     41		goto out;
     42	}
     43
     44out:
     45	kfree(bitmap_conf);
     46
     47	return ret;
     48}
     49
     50int wl18xx_acx_set_checksum_state(struct wl1271 *wl)
     51{
     52	struct wl18xx_acx_checksum_state *acx;
     53	int ret;
     54
     55	wl1271_debug(DEBUG_ACX, "acx checksum state");
     56
     57	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
     58	if (!acx) {
     59		ret = -ENOMEM;
     60		goto out;
     61	}
     62
     63	acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED;
     64
     65	ret = wl1271_cmd_configure(wl, ACX_CSUM_CONFIG, acx, sizeof(*acx));
     66	if (ret < 0) {
     67		wl1271_warning("failed to set Tx checksum state: %d", ret);
     68		goto out;
     69	}
     70
     71out:
     72	kfree(acx);
     73	return ret;
     74}
     75
     76int wl18xx_acx_clear_statistics(struct wl1271 *wl)
     77{
     78	struct wl18xx_acx_clear_statistics *acx;
     79	int ret = 0;
     80
     81	wl1271_debug(DEBUG_ACX, "acx clear statistics");
     82
     83	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
     84	if (!acx) {
     85		ret = -ENOMEM;
     86		goto out;
     87	}
     88
     89	ret = wl1271_cmd_configure(wl, ACX_CLEAR_STATISTICS, acx, sizeof(*acx));
     90	if (ret < 0) {
     91		wl1271_warning("failed to clear firmware statistics: %d", ret);
     92		goto out;
     93	}
     94
     95out:
     96	kfree(acx);
     97	return ret;
     98}
     99
    100int wl18xx_acx_peer_ht_operation_mode(struct wl1271 *wl, u8 hlid, bool wide)
    101{
    102	struct wlcore_peer_ht_operation_mode *acx;
    103	int ret;
    104
    105	wl1271_debug(DEBUG_ACX, "acx peer ht operation mode hlid %d bw %d",
    106		     hlid, wide);
    107
    108	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    109	if (!acx) {
    110		ret = -ENOMEM;
    111		goto out;
    112	}
    113
    114	acx->hlid = hlid;
    115	acx->bandwidth = wide ? WLCORE_BANDWIDTH_40MHZ : WLCORE_BANDWIDTH_20MHZ;
    116
    117	ret = wl1271_cmd_configure(wl, ACX_PEER_HT_OPERATION_MODE_CFG, acx,
    118				   sizeof(*acx));
    119
    120	if (ret < 0) {
    121		wl1271_warning("acx peer ht operation mode failed: %d", ret);
    122		goto out;
    123	}
    124
    125out:
    126	kfree(acx);
    127	return ret;
    128
    129}
    130
    131/*
    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
    135 */
    136int 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)
    140{
    141	struct wlcore_acx_peer_cap *acx;
    142	int ret = 0;
    143	u32 ht_capabilites = 0;
    144
    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);
    148
    149	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    150	if (!acx) {
    151		ret = -ENOMEM;
    152		goto out;
    153	}
    154
    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;
    158
    159		/*
    160		 * this bit is not employed by the spec but only by FW to
    161		 * indicate peer HT support
    162		 */
    163		ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
    164
    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;
    168	}
    169
    170	acx->hlid = hlid;
    171	acx->ht_capabilites = cpu_to_le32(ht_capabilites);
    172	acx->supported_rates = cpu_to_le32(rate_set);
    173
    174	ret = wl1271_cmd_configure(wl, ACX_PEER_CAP, acx, sizeof(*acx));
    175	if (ret < 0) {
    176		wl1271_warning("acx ht capabilities setting failed: %d", ret);
    177		goto out;
    178	}
    179
    180out:
    181	kfree(acx);
    182	return ret;
    183}
    184
    185/*
    186 * When the host is suspended, we don't want to get any fast-link/PSM
    187 * notifications
    188 */
    189int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl,
    190				       bool action)
    191{
    192	struct wl18xx_acx_interrupt_notify *acx;
    193	int ret = 0;
    194
    195	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    196	if (!acx) {
    197		ret = -ENOMEM;
    198		goto out;
    199	}
    200
    201	acx->enable = action;
    202	ret = wl1271_cmd_configure(wl, ACX_INTERRUPT_NOTIFY, acx, sizeof(*acx));
    203	if (ret < 0) {
    204		wl1271_warning("acx interrupt notify setting failed: %d", ret);
    205		goto out;
    206	}
    207
    208out:
    209	kfree(acx);
    210	return ret;
    211}
    212
    213/*
    214 * When the host is suspended, we can configure the FW to disable RX BA
    215 * notifications.
    216 */
    217int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action)
    218{
    219	struct wl18xx_acx_rx_ba_filter *acx;
    220	int ret = 0;
    221
    222	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    223	if (!acx) {
    224		ret = -ENOMEM;
    225		goto out;
    226	}
    227
    228	acx->enable = (u32)action;
    229	ret = wl1271_cmd_configure(wl, ACX_RX_BA_FILTER, acx, sizeof(*acx));
    230	if (ret < 0) {
    231		wl1271_warning("acx rx ba activity filter setting failed: %d",
    232			       ret);
    233		goto out;
    234	}
    235
    236out:
    237	kfree(acx);
    238	return ret;
    239}
    240
    241int wl18xx_acx_ap_sleep(struct wl1271 *wl)
    242{
    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;
    246	int ret;
    247
    248	wl1271_debug(DEBUG_ACX, "acx config ap sleep");
    249
    250	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    251	if (!acx) {
    252		ret = -ENOMEM;
    253		goto out;
    254	}
    255
    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;
    260
    261	ret = wl1271_cmd_configure(wl, ACX_AP_SLEEP_CFG, acx, sizeof(*acx));
    262	if (ret < 0) {
    263		wl1271_warning("acx config ap-sleep failed: %d", ret);
    264		goto out;
    265	}
    266
    267out:
    268	kfree(acx);
    269	return ret;
    270}
    271
    272int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl)
    273{
    274	struct acx_dynamic_fw_traces_cfg *acx;
    275	int ret;
    276
    277	wl1271_debug(DEBUG_ACX, "acx dynamic fw traces config %d",
    278		     wl->dynamic_fw_traces);
    279
    280	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    281	if (!acx) {
    282		ret = -ENOMEM;
    283		goto out;
    284	}
    285
    286	acx->dynamic_fw_traces = cpu_to_le32(wl->dynamic_fw_traces);
    287
    288	ret = wl1271_cmd_configure(wl, ACX_DYNAMIC_TRACES_CFG,
    289				   acx, sizeof(*acx));
    290	if (ret < 0) {
    291		wl1271_warning("acx config dynamic fw traces failed: %d", ret);
    292		goto out;
    293	}
    294out:
    295	kfree(acx);
    296	return ret;
    297}
    298
    299int wl18xx_acx_time_sync_cfg(struct wl1271 *wl)
    300{
    301	struct acx_time_sync_cfg *acx;
    302	int ret;
    303
    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);
    307
    308	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
    309	if (!acx) {
    310		ret = -ENOMEM;
    311		goto out;
    312	}
    313
    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);
    316
    317	ret = wl1271_cmd_configure(wl, ACX_TIME_SYNC_CFG,
    318				   acx, sizeof(*acx));
    319	if (ret < 0) {
    320		wl1271_warning("acx time sync cfg failed: %d", ret);
    321		goto out;
    322	}
    323out:
    324	kfree(acx);
    325	return ret;
    326}