1f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho/* 2f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This file is part of wl1271 3f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 4f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Copyright (C) 2008-2009 Nokia Corporation 5f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 6f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 8f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This program is free software; you can redistribute it and/or 9f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * modify it under the terms of the GNU General Public License 10f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * version 2 as published by the Free Software Foundation. 11f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 12f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This program is distributed in the hope that it will be useful, but 13f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * WITHOUT ANY WARRANTY; without even the implied warranty of 14f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * General Public License for more details. 16f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 17f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * You should have received a copy of the GNU General Public License 18f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * along with this program; if not, write to the Free Software 19f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 02110-1301 USA 21f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 22f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho */ 23f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2400d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "acx.h" 25f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 26f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/module.h> 27f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/platform_device.h> 28f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/spi/spi.h> 295a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 30f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3100d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "wl12xx.h" 320f4e31222a2c0b93f25a87effd2033cb78c7a79cLuciano Coelho#include "debug.h" 33f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include "wl12xx_80211.h" 3400d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "reg.h" 3500d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "ps.h" 36f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 370603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif) 38f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 39f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_wake_up_condition *wake_up; 40f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 41f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 42f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx wake up conditions"); 43f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 44f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); 45f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!wake_up) { 46f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 47f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 48f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 49f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 500603d891c5b5153f667a79357d4652824c22b54eEliad Peller wake_up->role_id = wlvif->role_id; 5151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen wake_up->wake_up_event = wl->conf.conn.wake_up_event; 5251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen wake_up->listen_interval = wl->conf.conn.listen_interval; 53f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 54f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, 55f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wake_up, sizeof(*wake_up)); 56f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 57f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("could not set wake up conditions: %d", ret); 58f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 59f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 60f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 61f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wake_up); 63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 64f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 65f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 66f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) 67f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 68f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_sleep_auth *auth; 69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 71f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx sleep auth"); 72f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 73f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho auth = kzalloc(sizeof(*auth), GFP_KERNEL); 74f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!auth) { 75f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 76f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 79f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho auth->sleep_auth = sleep_auth; 80f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 81f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); 82f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(auth); 85f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 86f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 87f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 880603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, 890603d891c5b5153f667a79357d4652824c22b54eEliad Peller int power) 90f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 91f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_current_tx_power *acx; 92f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 93f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 94097f882153f0ec13617074fa3bdb683b8215e20cArik Nemtsov wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power); 95f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 96f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (power < 0 || power > 25) 97f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return -EINVAL; 98f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 99f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 100f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 101f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 102f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 103f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 104f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1050603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 1066f6b5d49105eba1be0b2ef0c04a4571f20793778Juuso Oikarinen acx->current_tx_power = power * 10; 107f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 108f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); 109f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 110f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("configure of tx power failed: %d", ret); 111f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 112f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 113f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 114f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 115f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 116f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 117f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 118f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1190603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif) 120f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 121f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_feature_config *feature; 122f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 123f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 124f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx feature cfg"); 125f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 126f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho feature = kzalloc(sizeof(*feature), GFP_KERNEL); 127f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!feature) { 128f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 129f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 130f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 131f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 132f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 1330603d891c5b5153f667a79357d4652824c22b54eEliad Peller feature->role_id = wlvif->role_id; 134f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho feature->data_flow_options = 0; 135f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho feature->options = 0; 136f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 137f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG, 138f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho feature, sizeof(*feature)); 139f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 140f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_error("Couldnt set HW encryption"); 141f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 142f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 143f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 144f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 145f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(feature); 146f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 147f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 148f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 149f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map, 150f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho size_t len) 151f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 152f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 153f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 154f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx mem map"); 155f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 156f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); 157f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 158f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 159f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 160f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 161f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 162f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1638793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinenint wl1271_acx_rx_msdu_life_time(struct wl1271 *wl) 164f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 165f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_rx_msdu_lifetime *acx; 166f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 167f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 168f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx rx msdu life time"); 169f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 170f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 171f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 172f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 173f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 174f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 175f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 176d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time); 177f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, 178f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx, sizeof(*acx)); 179f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 180f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set rx msdu life time: %d", ret); 181f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 182f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 183f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 184f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 185f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 186f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 187f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 188f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1890603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1900603d891c5b5153f667a79357d4652824c22b54eEliad Peller enum acx_slot_type slot_time) 191f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 192f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_slot *slot; 193f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 194f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 195f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx slot"); 196f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 197f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho slot = kzalloc(sizeof(*slot), GFP_KERNEL); 198f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!slot) { 199f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 200f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 201f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 202f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2030603d891c5b5153f667a79357d4652824c22b54eEliad Peller slot->role_id = wlvif->role_id; 204f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho slot->wone_index = STATION_WONE_INDEX; 205f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho slot->slot_time = slot_time; 206f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 207f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); 208f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 209f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set slot time: %d", ret); 210f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 211f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 212f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 213f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 214f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(slot); 215f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 216f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 217f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2180603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif, 2190603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable, void *mc_list, u32 mc_list_len) 220f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 221f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_dot11_grp_addr_tbl *acx; 222f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 223f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 224f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx group address tbl"); 225f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 226f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 227f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 228f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 229f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* MAC filtering */ 2330603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 234c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen acx->enabled = enable; 235c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen acx->num_groups = mc_list_len; 236c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN); 237f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, 239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx, sizeof(*acx)); 240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 241f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set group addr table: %d", ret); 242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 244f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 245f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2500603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_service_period_timeout(struct wl1271 *wl, 2510603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_rx_timeout *rx_timeout; 254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 256f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); 257f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!rx_timeout) { 258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx service period timeout"); 263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2640603d891c5b5153f667a79357d4652824c22b54eEliad Peller rx_timeout->role_id = wlvif->role_id; 265d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout); 266d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout); 267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 268f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, 269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho rx_timeout, sizeof(*rx_timeout)); 270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set service period timeout: %d", 272f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret); 273f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(rx_timeout); 278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2810603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif, 2820603d891c5b5153f667a79357d4652824c22b54eEliad Peller u32 rts_threshold) 283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 284f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_rts_threshold *rts; 285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2875f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov /* 2885f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov * If the RTS threshold is not configured or out of range, use the 2895f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov * default value. 2905f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov */ 2915f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD) 2925f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov rts_threshold = wl->conf.rx.rts_threshold; 2935f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov 2945f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold); 295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho rts = kzalloc(sizeof(*rts), GFP_KERNEL); 297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!rts) { 298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3020603d891c5b5153f667a79357d4652824c22b54eEliad Peller rts->role_id = wlvif->role_id; 3035f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov rts->threshold = cpu_to_le16((u16)rts_threshold); 304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); 306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set rts threshold: %d", ret); 308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 311f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(rts); 313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3166e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelhoint wl1271_acx_dco_itrim_params(struct wl1271 *wl) 3176e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho{ 3186e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho struct acx_dco_itrim_params *dco; 3196e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho struct conf_itrim_settings *c = &wl->conf.itrim; 3206e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho int ret; 3216e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3226e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho wl1271_debug(DEBUG_ACX, "acx dco itrim parameters"); 3236e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3246e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho dco = kzalloc(sizeof(*dco), GFP_KERNEL); 3256e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (!dco) { 3266e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = -ENOMEM; 3276e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out; 3286e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho } 3296e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3306e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho dco->enable = c->enable; 3316e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho dco->timeout = cpu_to_le32(c->timeout); 3326e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3336e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS, 3346e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho dco, sizeof(*dco)); 3356e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) { 3366e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho wl1271_warning("failed to set dco itrim parameters: %d", ret); 3376e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out; 3386e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho } 3396e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3406e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelhoout: 3416e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho kfree(dco); 3426e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho return ret; 3436e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho} 3446e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 3450603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif, 3460603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable_filter) 347f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 34851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen struct acx_beacon_filter_option *beacon_filter = NULL; 34951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen int ret = 0; 350f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 351f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); 352f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 35351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen if (enable_filter && 35451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) 35551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen goto out; 35651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen 357f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); 358f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!beacon_filter) { 359f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 360f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 361f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 362f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3630603d891c5b5153f667a79357d4652824c22b54eEliad Peller beacon_filter->role_id = wlvif->role_id; 3641922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen beacon_filter->enable = enable_filter; 36551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen 36651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen /* 36751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen * When set to zero, and the filter is enabled, beacons 36851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen * without the unicast TIM bit set are dropped. 36951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen */ 370f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho beacon_filter->max_num_beacons = 0; 371f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 372f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT, 373f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho beacon_filter, sizeof(*beacon_filter)); 374f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 375f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set beacon filter opt: %d", ret); 376f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 377f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 378f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 379f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 380f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(beacon_filter); 381f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 382f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 383f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3840603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_beacon_filter_table(struct wl1271 *wl, 3850603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 386f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 387f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_beacon_filter_ie_table *ie_table; 38851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen int i, idx = 0; 389f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 39051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen bool vendor_spec = false; 391f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 392f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx beacon filter table"); 393f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 394f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); 395f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!ie_table) { 396f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 397f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 398f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 399f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 4001922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen /* configure default beacon pass-through rules */ 4010603d891c5b5153f667a79357d4652824c22b54eEliad Peller ie_table->role_id = wlvif->role_id; 40251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen ie_table->num_ie = 0; 40351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) { 40451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]); 40551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen ie_table->table[idx++] = r->ie; 40651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen ie_table->table[idx++] = r->rule; 40751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen 40851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen if (r->ie == WLAN_EID_VENDOR_SPECIFIC) { 40951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen /* only one vendor specific ie allowed */ 41051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen if (vendor_spec) 41151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen continue; 41251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen 41351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen /* for vendor specific rules configure the 41451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen additional fields */ 41551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen memcpy(&(ie_table->table[idx]), r->oui, 41651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen CONF_BCN_IE_OUI_LEN); 41751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen idx += CONF_BCN_IE_OUI_LEN; 41851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen ie_table->table[idx++] = r->type; 41951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen memcpy(&(ie_table->table[idx]), r->version, 42051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen CONF_BCN_IE_VER_LEN); 42151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen idx += CONF_BCN_IE_VER_LEN; 42251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen vendor_spec = true; 42351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen } 42451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen 42551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen ie_table->num_ie++; 42651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen } 427f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 428f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, 429f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ie_table, sizeof(*ie_table)); 430f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 431f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set beacon filter table: %d", ret); 432f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 433f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 434f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 435f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 436f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(ie_table); 437f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 438f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 439f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 4406ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff 4416ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen 4420603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif, 4430603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable) 444344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen{ 445344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen struct acx_conn_monit_params *acx; 4466ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE; 4476ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE; 448344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen int ret; 449344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 4506ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s", 4516ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen enable ? "enabled" : "disabled"); 452344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 453344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 454344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen if (!acx) { 455344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen ret = -ENOMEM; 456344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen goto out; 457344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen } 458344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 4596ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen if (enable) { 4606ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen threshold = wl->conf.conn.synch_fail_thold; 4616ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen timeout = wl->conf.conn.bss_lose_timeout; 4626ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen } 4636ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen 4640603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 4656ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen acx->synch_fail_thold = cpu_to_le32(threshold); 4666ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen acx->bss_lose_timeout = cpu_to_le32(timeout); 467344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 468344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, 469344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen acx, sizeof(*acx)); 470344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen if (ret < 0) { 471344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl1271_warning("failed to set connection monitor " 472344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen "parameters: %d", ret); 473344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen goto out; 474344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen } 475344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 476344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinenout: 477344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen kfree(acx); 478344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen return ret; 479344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen} 480344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 481344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen 4827fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinenint wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) 483f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 484f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_bt_wlan_coex *pta; 485f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 486f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 487f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx sg enable"); 488f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 489f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho pta = kzalloc(sizeof(*pta), GFP_KERNEL); 490f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!pta) { 491f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 492f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 493f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 494f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 4957fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen if (enable) 4967fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen pta->enable = wl->conf.sg.state; 4977fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen else 4987fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen pta->enable = CONF_SG_DISABLE; 499f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 500f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); 501f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 502f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set softgemini enable: %d", ret); 503f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 504f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 505f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 506f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 507f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(pta); 508f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 509f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 510f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 5113be4112cb2c53fcda85fb408aea9a6f94075683bEliad Pellerint wl12xx_acx_sg_cfg(struct wl1271 *wl) 512f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 5133be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller struct acx_bt_wlan_coex_param *param; 5142b60100bf04aba28133ccb24efd85f72fb1a5494Juuso Oikarinen struct conf_sg_settings *c = &wl->conf.sg; 5151b00f546fc4271d94c1bccb1955ce64d9ace1000Juuso Oikarinen int i, ret; 516f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 5173be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller wl1271_debug(DEBUG_ACX, "acx sg cfg"); 518f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 519f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho param = kzalloc(sizeof(*param), GFP_KERNEL); 520f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!param) { 521f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 522f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 523f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 524f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 525f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* BT-WLAN coext parameters */ 5263be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller for (i = 0; i < CONF_SG_PARAMS_MAX; i++) 5273be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller param->params[i] = cpu_to_le32(c->params[i]); 5281b00f546fc4271d94c1bccb1955ce64d9ace1000Juuso Oikarinen param->param_idx = CONF_SG_PARAMS_ALL; 529f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 530f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 531f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 532f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set sg config: %d", ret); 533f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 534f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 535f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 536f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 537f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(param); 538f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 539f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 540f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 541f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_cca_threshold(struct wl1271 *wl) 542f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 543f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_energy_detection *detection; 544f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 545f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 546f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx cca threshold"); 547f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 548f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho detection = kzalloc(sizeof(*detection), GFP_KERNEL); 549f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!detection) { 550f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 551f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 552f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 553f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 554d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold); 55545b531a86f93c82d8e390e19a6258111b3627bb0Juuso Oikarinen detection->tx_energy_detection = wl->conf.tx.tx_energy_detection; 556f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 557f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, 558f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho detection, sizeof(*detection)); 559f8afdf481f0fef5e170c6c928cec42879d505654Julia Lawall if (ret < 0) 560f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set cca threshold: %d", ret); 561f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 562f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 563f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(detection); 564f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 565f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 566f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 5670603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif) 568f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 569f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_beacon_broadcast *bb; 570f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 571f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 572f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx bcn dtim options"); 573f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 574f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho bb = kzalloc(sizeof(*bb), GFP_KERNEL); 575f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!bb) { 576f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 577f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 578f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 579f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 5800603d891c5b5153f667a79357d4652824c22b54eEliad Peller bb->role_id = wlvif->role_id; 581d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout); 582d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout); 58351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps; 58451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold; 585f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 586f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); 587f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 588f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set rx config: %d", ret); 589f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 590f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 591f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 592f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 593f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(bb); 594f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 595f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 596f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 5970603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid) 598f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 599f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_aid *acx_aid; 600f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 601f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 602f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx aid"); 603f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 604f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); 605f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx_aid) { 606f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 607f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 608f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 609f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6100603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx_aid->role_id = wlvif->role_id; 611d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho acx_aid->aid = cpu_to_le16(aid); 612f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 613f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); 614f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 615f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set aid: %d", ret); 616f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 617f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 618f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 619f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 620f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx_aid); 621f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 622f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 623f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 624f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask) 625f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 626f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_event_mask *mask; 627f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 628f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 629f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx event mbox mask"); 630f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 631f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho mask = kzalloc(sizeof(*mask), GFP_KERNEL); 632f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!mask) { 633f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 634f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 635f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 636f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 637f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* high event mask is unused */ 638d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho mask->high_event_mask = cpu_to_le32(0xffffffff); 639d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho mask->event_mask = cpu_to_le32(event_mask); 640f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 641f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK, 642f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho mask, sizeof(*mask)); 643f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 644f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("failed to set acx_event_mbox_mask: %d", ret); 645f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 646f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 647f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 648f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 649f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(mask); 650f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 651f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 652f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6530603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif, 6540603d891c5b5153f667a79357d4652824c22b54eEliad Peller enum acx_preamble_type preamble) 655f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 656f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_preamble *acx; 657f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 658f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 659f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx_set_preamble"); 660f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 661f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 662f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 663f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 664f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 665f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 666f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6670603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 668f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx->preamble = preamble; 669f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 670f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); 671f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 672f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("Setting of preamble failed: %d", ret); 673f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 674f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 675f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 676f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 677f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 678f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 679f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 680f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6810603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif, 682f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho enum acx_ctsprotect_type ctsprotect) 683f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 684f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_ctsprotect *acx; 685f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 686f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 687f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect"); 688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 693f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6950603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 696f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx->ctsprotect = ctsprotect; 697f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 698f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); 699f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("Setting of ctsprotect failed: %d", ret); 701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 707f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) 710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx statistics"); 714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, 716f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof(*stats)); 717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("acx statistics failed: %d", ret); 719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return -ENOMEM; 720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 72530d0c8fd5b87d1c5486705d6420545a21533e115Eliad Pellerint wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) 726f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 7277f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller struct acx_rate_policy *acx; 7281e05a81888318752e9a6d2158a95ddd6442ae117Arik Nemtsov struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf; 729f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret = 0; 730f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 731f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx rate policies"); 732f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 733f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 734f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 735f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 736f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 737f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 738f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 739f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 7407f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x", 741d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller wlvif->basic_rate, wlvif->rate_set); 7427f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller 743830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen /* configure one basic rate class */ 744e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx); 745d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate); 7467f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.short_retry_limit = c->short_retry_limit; 7477f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.long_retry_limit = c->long_retry_limit; 7487f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.aflags = c->aflags; 7497f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller 7507f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 7517f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller if (ret < 0) { 7527f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller wl1271_warning("Setting of rate policies failed: %d", ret); 7537f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller goto out; 7547f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller } 755830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen 756830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen /* configure one AP supported rate class */ 757e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx); 75830d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set); 7597f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.short_retry_limit = c->short_retry_limit; 7607f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.long_retry_limit = c->long_retry_limit; 7617f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller acx->rate_policy.aflags = c->aflags; 762830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen 7634b29886feb072427df80ca6395b2b11a09245eafEliad Peller ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 7644b29886feb072427df80ca6395b2b11a09245eafEliad Peller if (ret < 0) { 7654b29886feb072427df80ca6395b2b11a09245eafEliad Peller wl1271_warning("Setting of rate policies failed: %d", ret); 7664b29886feb072427df80ca6395b2b11a09245eafEliad Peller goto out; 7674b29886feb072427df80ca6395b2b11a09245eafEliad Peller } 768f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 7694b29886feb072427df80ca6395b2b11a09245eafEliad Peller /* 7704b29886feb072427df80ca6395b2b11a09245eafEliad Peller * configure one rate class for basic p2p operations. 7714b29886feb072427df80ca6395b2b11a09245eafEliad Peller * (p2p packets should always go out with OFDM rates, even 7724b29886feb072427df80ca6395b2b11a09245eafEliad Peller * if we are currently connected to 11b AP) 7734b29886feb072427df80ca6395b2b11a09245eafEliad Peller */ 774e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx); 7754b29886feb072427df80ca6395b2b11a09245eafEliad Peller acx->rate_policy.enabled_rates = 7764b29886feb072427df80ca6395b2b11a09245eafEliad Peller cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P); 7774b29886feb072427df80ca6395b2b11a09245eafEliad Peller acx->rate_policy.short_retry_limit = c->short_retry_limit; 7784b29886feb072427df80ca6395b2b11a09245eafEliad Peller acx->rate_policy.long_retry_limit = c->long_retry_limit; 7794b29886feb072427df80ca6395b2b11a09245eafEliad Peller acx->rate_policy.aflags = c->aflags; 78072c2d9e511846a4f2759389b38ed8a5553579eb3Eliad Peller 781f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 782f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 783f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("Setting of rate policies failed: %d", ret); 784f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 785f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 786f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 787f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 788f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 789f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 790f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 791f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 79279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovint wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, 79379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov u8 idx) 79479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov{ 7957f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller struct acx_rate_policy *acx; 79679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov int ret = 0; 79779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 79870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x", 79970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov idx, c->enabled_rates); 80079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 80179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx = kzalloc(sizeof(*acx), GFP_KERNEL); 80279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov if (!acx) { 80379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov ret = -ENOMEM; 80479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov goto out; 80579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov } 80679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 80779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates); 80879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx->rate_policy.short_retry_limit = c->short_retry_limit; 80979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx->rate_policy.long_retry_limit = c->long_retry_limit; 81079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx->rate_policy.aflags = c->aflags; 81179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 8121d4801f2689dc2618fdb5e83d4cb7743747491edEliad Peller acx->rate_policy_idx = cpu_to_le32(idx); 81379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 81479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 81579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov if (ret < 0) { 81679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov wl1271_warning("Setting of ap rate policy failed: %d", ret); 81779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov goto out; 81879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov } 81979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 82079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovout: 82179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov kfree(acx); 82279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov return ret; 82379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov} 82479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 8250603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, 8260603d891c5b5153f667a79357d4652824c22b54eEliad Peller u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop) 827f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 828f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_ac_cfg *acx; 829243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo int ret = 0; 830f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 831243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " 832243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop); 833f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 834f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 835f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 836f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 837f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 838f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 839f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 840f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 8410603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 842243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo acx->ac = ac; 843243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo acx->cw_min = cw_min; 844243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo acx->cw_max = cpu_to_le16(cw_max); 845243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo acx->aifsn = aifsn; 846243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo acx->tx_op_limit = cpu_to_le16(txop); 847f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 848243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); 849243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo if (ret < 0) { 850243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo wl1271_warning("acx ac cfg failed: %d", ret); 851243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo goto out; 852f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 853f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 854f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 855f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 856f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 857f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 858f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 8590603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, 8600603d891c5b5153f667a79357d4652824c22b54eEliad Peller u8 queue_id, u8 channel_type, 861f2054df5170734eacd1db82138c70746ec8387deKalle Valo u8 tsid, u8 ps_scheme, u8 ack_policy, 862f2054df5170734eacd1db82138c70746ec8387deKalle Valo u32 apsd_conf0, u32 apsd_conf1) 863f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 864f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_tid_config *acx; 865f2054df5170734eacd1db82138c70746ec8387deKalle Valo int ret = 0; 866f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 867f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx tid config"); 868f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 869f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 870f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 871f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 872f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 873f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 874f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 875f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 8760603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 877f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->queue_id = queue_id; 878f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->channel_type = channel_type; 879f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->tsid = tsid; 880f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->ps_scheme = ps_scheme; 881f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->ack_policy = ack_policy; 882f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->apsd_conf[0] = cpu_to_le32(apsd_conf0); 883f2054df5170734eacd1db82138c70746ec8387deKalle Valo acx->apsd_conf[1] = cpu_to_le32(apsd_conf1); 884f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 885f2054df5170734eacd1db82138c70746ec8387deKalle Valo ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); 886f2054df5170734eacd1db82138c70746ec8387deKalle Valo if (ret < 0) { 887f2054df5170734eacd1db82138c70746ec8387deKalle Valo wl1271_warning("Setting of tid config failed: %d", ret); 888f2054df5170734eacd1db82138c70746ec8387deKalle Valo goto out; 889f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 890f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 891f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 892f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 893f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 894f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 895f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 8965f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsovint wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold) 897f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 898f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_frag_threshold *acx; 899f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret = 0; 900f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 9015f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov /* 9025f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov * If the fragmentation is not configured or out of range, use the 9035f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov * default value. 9045f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov */ 9055f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD) 9065f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov frag_threshold = wl->conf.tx.frag_threshold; 9075f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov 9085f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold); 909f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 910f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 911f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 912f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 913f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 914f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 915f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 916f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 9175f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov acx->frag_threshold = cpu_to_le16((u16)frag_threshold); 918f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); 919f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 920f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("Setting of frag threshold failed: %d", ret); 921f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 922f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 923f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 924f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 925f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 926f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 927f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 928f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 929f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_tx_config_options(struct wl1271 *wl) 930f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 931f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct acx_tx_config_options *acx; 932f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret = 0; 933f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 934f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "acx tx config options"); 935f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 936f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho acx = kzalloc(sizeof(*acx), GFP_KERNEL); 937f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 938f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!acx) { 939f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 940f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 941f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 942f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 943d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout); 944d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold); 945f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx)); 946f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 947f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("Setting of tx options failed: %d", ret); 948f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 949f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 950f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 951f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 952f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(acx); 953f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 954f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 955f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 9567f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Pellerint wl12xx_acx_mem_cfg(struct wl1271 *wl) 957f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 9587f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller struct wl12xx_acx_config_memory *mem_conf; 95913b107dd9808343d05627f0fba7fbc764c86738eShahar Levi struct conf_memory_settings *mem; 960f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 961f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 962c8bde243421d759844264cf11e4248e7862c2722Eliad Peller wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); 963c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 964c8bde243421d759844264cf11e4248e7862c2722Eliad Peller mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); 965c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (!mem_conf) { 966c8bde243421d759844264cf11e4248e7862c2722Eliad Peller ret = -ENOMEM; 967c8bde243421d759844264cf11e4248e7862c2722Eliad Peller goto out; 968c8bde243421d759844264cf11e4248e7862c2722Eliad Peller } 969c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 97013b107dd9808343d05627f0fba7fbc764c86738eShahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) 97113b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem = &wl->conf.mem_wl128x; 97213b107dd9808343d05627f0fba7fbc764c86738eShahar Levi else 97313b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem = &wl->conf.mem_wl127x; 97413b107dd9808343d05627f0fba7fbc764c86738eShahar Levi 975c8bde243421d759844264cf11e4248e7862c2722Eliad Peller /* memory config */ 97613b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->num_stations = mem->num_stations; 97713b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->rx_mem_block_num = mem->rx_block_num; 97813b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->tx_min_mem_block_num = mem->tx_min_block_num; 97913b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->num_ssid_profiles = mem->ssid_profiles; 980c8bde243421d759844264cf11e4248e7862c2722Eliad Peller mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); 98113b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->dyn_mem_enable = mem->dynamic_memory; 98213b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->tx_free_req = mem->min_req_tx_blocks; 98313b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->rx_free_req = mem->min_req_rx_blocks; 98413b107dd9808343d05627f0fba7fbc764c86738eShahar Levi mem_conf->tx_min = mem->tx_min; 98595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks; 986c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 987c8bde243421d759844264cf11e4248e7862c2722Eliad Peller ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, 988c8bde243421d759844264cf11e4248e7862c2722Eliad Peller sizeof(*mem_conf)); 989c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) { 990c8bde243421d759844264cf11e4248e7862c2722Eliad Peller wl1271_warning("wl1271 mem config failed: %d", ret); 991c8bde243421d759844264cf11e4248e7862c2722Eliad Peller goto out; 992c8bde243421d759844264cf11e4248e7862c2722Eliad Peller } 993c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 994c8bde243421d759844264cf11e4248e7862c2722Eliad Pellerout: 995c8bde243421d759844264cf11e4248e7862c2722Eliad Peller kfree(mem_conf); 996c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 997c8bde243421d759844264cf11e4248e7862c2722Eliad Peller} 998c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 99948a61477bdc04896bd96d259388a0c42a7019943Shahar Leviint wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap) 100048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi{ 100148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi struct wl1271_acx_host_config_bitmap *bitmap_conf; 100248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi int ret; 100348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 100448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); 100548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (!bitmap_conf) { 100648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = -ENOMEM; 100748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi goto out; 100848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi } 100948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 101048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap); 101148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 101248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP, 101348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi bitmap_conf, sizeof(*bitmap_conf)); 101448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) { 101548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi wl1271_warning("wl1271 bitmap config opt failed: %d", ret); 101648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi goto out; 101748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi } 101848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 101948a61477bdc04896bd96d259388a0c42a7019943Shahar Leviout: 102048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi kfree(bitmap_conf); 102148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 102248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 102348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi} 102448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 1025c8bde243421d759844264cf11e4248e7862c2722Eliad Pellerint wl1271_acx_init_mem_config(struct wl1271 *wl) 1026c8bde243421d759844264cf11e4248e7862c2722Eliad Peller{ 1027c8bde243421d759844264cf11e4248e7862c2722Eliad Peller int ret; 1028f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1029f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), 103045b531a86f93c82d8e390e19a6258111b3627bb0Juuso Oikarinen GFP_KERNEL); 1031f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!wl->target_mem_map) { 1032f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_error("couldn't allocate target memory map"); 1033f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return -ENOMEM; 1034f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 1035f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1036f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* we now ask for the firmware built memory map */ 1037f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map, 1038f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof(struct wl1271_acx_mem_map)); 1039f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 1040f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_error("couldn't retrieve firmware memory map"); 1041f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 1042f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl->target_mem_map = NULL; 1043f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 1044f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 1045f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1046f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* initialize TX block book keeping */ 1047d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho wl->tx_blocks_available = 1048d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks); 1049f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_TX, "available tx blocks: %d", 1050f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl->tx_blocks_available); 1051f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1052f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 1053f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 1054f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1055f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_init_rx_interrupt(struct wl1271 *wl) 1056f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 1057f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho struct wl1271_acx_rx_config_opt *rx_conf; 1058f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 1059f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1060f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config"); 1061f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1062f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL); 1063f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (!rx_conf) { 1064f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = -ENOMEM; 1065f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 1066f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 1067f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1068d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold); 1069d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout); 1070d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold); 10718793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinen rx_conf->queue_type = wl->conf.rx.queue_type; 1072f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1073f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf, 1074f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof(*rx_conf)); 1075f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) { 1076f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho wl1271_warning("wl1271 rx config opt failed: %d", ret); 1077f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out; 1078f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho } 1079f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1080f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout: 1081f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(rx_conf); 1082f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 1083f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 10843cfd6cf960b2b030ccae1144a5c0dcd91c7c56a8Juuso Oikarinen 10850603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif, 10860603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable) 108711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen{ 108811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen struct wl1271_acx_bet_enable *acx = NULL; 108911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen int ret = 0; 109011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 109111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen wl1271_debug(DEBUG_ACX, "acx bet enable"); 109211f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 109311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE) 109411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen goto out; 109511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 109611f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 109711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen if (!acx) { 109811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen ret = -ENOMEM; 109911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen goto out; 110011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen } 110111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 11020603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 110311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE; 110411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen acx->max_consecutive = wl->conf.conn.bet_max_consecutive; 110511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 110611f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx)); 110711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen if (ret < 0) { 110811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen wl1271_warning("acx bet enable failed: %d", ret); 110911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen goto out; 111011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen } 111111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen 111211f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinenout: 111311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen kfree(acx); 111411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen return ret; 111511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen} 111601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 11170603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif, 11180603d891c5b5153f667a79357d4652824c22b54eEliad Peller u8 enable, __be32 address) 111901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen{ 112001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen struct wl1271_acx_arp_filter *acx; 112101c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen int ret; 112201c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 1123ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); 112401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 112501c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 112601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen if (!acx) { 112701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen ret = -ENOMEM; 112801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen goto out; 112901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen } 113001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 11310603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 1132eb887dfd8837bf0a2538418c02b3992fb9ff1f28Juuso Oikarinen acx->version = ACX_IPV4_VERSION; 1133ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen acx->enable = enable; 113401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 1135c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller if (enable) 1136ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); 113701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 113801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, 113901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen acx, sizeof(*acx)); 114001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen if (ret < 0) { 114101c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen wl1271_warning("failed to set arp ip filter: %d", ret); 114201c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen goto out; 114301c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen } 114401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen 114501c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinenout: 114601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen kfree(acx); 114701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen return ret; 114801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen} 114938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 115038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinenint wl1271_acx_pm_config(struct wl1271 *wl) 115138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen{ 115238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen struct wl1271_acx_pm_config *acx = NULL; 115338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen struct conf_pm_config_settings *c = &wl->conf.pm_config; 115438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen int ret = 0; 115538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 115638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen wl1271_debug(DEBUG_ACX, "acx pm config"); 115738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 115838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 115938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (!acx) { 116038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = -ENOMEM; 116138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out; 116238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen } 116338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 116438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time); 116538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen acx->host_fast_wakeup_support = c->host_fast_wakeup_support; 116638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 116738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx)); 116838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) { 116938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen wl1271_warning("acx pm config failed: %d", ret); 117038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out; 117138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen } 117238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 117338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinenout: 117438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen kfree(acx); 117538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen return ret; 117638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen} 1177c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 11780603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 11790603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable) 1180c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen{ 1181c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen struct wl1271_acx_keep_alive_mode *acx = NULL; 1182c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen int ret = 0; 1183c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1184c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable); 1185c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1186c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1187c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen if (!acx) { 1188c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen ret = -ENOMEM; 1189c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen goto out; 1190c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen } 1191c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 11920603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 1193c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx->enabled = enable; 1194c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1195c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx)); 1196c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen if (ret < 0) { 1197c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen wl1271_warning("acx keep alive mode failed: %d", ret); 1198c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen goto out; 1199c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen } 1200c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1201c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinenout: 1202c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen kfree(acx); 1203c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen return ret; 1204c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen} 120500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 12060603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif, 12070603d891c5b5153f667a79357d4652824c22b54eEliad Peller u8 index, u8 tpl_valid) 1208c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen{ 1209c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen struct wl1271_acx_keep_alive_config *acx = NULL; 1210c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen int ret = 0; 1211c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1212c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen wl1271_debug(DEBUG_ACX, "acx keep alive config"); 1213c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1214c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1215c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen if (!acx) { 1216c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen ret = -ENOMEM; 1217c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen goto out; 1218c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen } 1219c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 12200603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 1221c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval); 1222c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx->index = index; 1223c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx->tpl_validation = tpl_valid; 1224c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx->trigger = ACX_KEEP_ALIVE_NO_TX; 1225c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1226c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG, 1227c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen acx, sizeof(*acx)); 1228c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen if (ret < 0) { 1229c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen wl1271_warning("acx keep alive config failed: %d", ret); 1230c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen goto out; 1231c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen } 1232c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 1233c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinenout: 1234c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen kfree(acx); 1235c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen return ret; 1236c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen} 123700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 12380603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif, 12390603d891c5b5153f667a79357d4652824c22b54eEliad Peller bool enable, s16 thold, u8 hyst) 124000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen{ 124100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen struct wl1271_acx_rssi_snr_trigger *acx = NULL; 124200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen int ret = 0; 124300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 124400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); 124500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 124600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 124700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (!acx) { 124800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen ret = -ENOMEM; 124900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen goto out; 125000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen } 125100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 125204324d99818d16da4f64e266b45cad2e5803b961Eliad Peller wlvif->last_rssi_event = -1; 125300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 12540603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 125500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing); 125600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON; 125700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->type = WL1271_ACX_TRIG_TYPE_EDGE; 125800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (enable) 125900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->enable = WL1271_ACX_TRIG_ENABLE; 126000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen else 126100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->enable = WL1271_ACX_TRIG_DISABLE; 126200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 126300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->index = WL1271_ACX_TRIG_IDX_RSSI; 126400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->dir = WL1271_ACX_TRIG_DIR_BIDIR; 126500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->threshold = cpu_to_le16(thold); 126600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->hysteresis = hyst; 126700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 126800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx)); 126900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (ret < 0) { 127000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen wl1271_warning("acx rssi snr trigger setting failed: %d", ret); 127100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen goto out; 127200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen } 127300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 127400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinenout: 127500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen kfree(acx); 127600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen return ret; 127700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen} 127800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 12790603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl, 12800603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 128100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen{ 128200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen struct wl1271_acx_rssi_snr_avg_weights *acx = NULL; 128300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger; 128400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen int ret = 0; 128500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 128600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); 128700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 128800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx = kzalloc(sizeof(*acx), GFP_KERNEL); 128900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (!acx) { 129000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen ret = -ENOMEM; 129100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen goto out; 129200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen } 129300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 12940603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 129500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->rssi_beacon = c->avg_weight_rssi_beacon; 129600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->rssi_data = c->avg_weight_rssi_data; 129700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->snr_beacon = c->avg_weight_snr_beacon; 129800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen acx->snr_data = c->avg_weight_snr_data; 129900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 130000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx)); 130100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (ret < 0) { 130200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen wl1271_warning("acx rssi snr trigger weights failed: %d", ret); 130300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen goto out; 130400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen } 130500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 130600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinenout: 130700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen kfree(acx); 130800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen return ret; 130900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen} 1310bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen 1311c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviint wl1271_acx_set_ht_capabilities(struct wl1271 *wl, 1312c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi struct ieee80211_sta_ht_cap *ht_cap, 13130b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov bool allow_ht_operation, u8 hlid) 1314c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi{ 1315c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi struct wl1271_acx_ht_capabilities *acx; 1316c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi int ret = 0; 13176177eaea277527e48753d050723cd138494c98a8Eliad Peller u32 ht_capabilites = 0; 1318c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 13190b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov wl1271_debug(DEBUG_ACX, "acx ht capabilities setting " 13200b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov "sta supp: %d sta cap: %d", ht_cap->ht_supported, 13210b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov ht_cap->cap); 1322c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1323c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1324c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi if (!acx) { 1325c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi ret = -ENOMEM; 1326c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi goto out; 1327c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi } 1328c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 13290b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov if (allow_ht_operation && ht_cap->ht_supported) { 13300f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* no need to translate capabilities - use the spec values */ 13310f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov ht_capabilites = ht_cap->cap; 13320f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov 13330f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* 13340f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov * this bit is not employed by the spec but only by FW to 13350f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov * indicate peer HT support 13360f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov */ 13370f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION; 1338c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1339c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi /* get data from A-MPDU parameters field */ 1340c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->ampdu_max_length = ht_cap->ampdu_factor; 1341c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->ampdu_min_spacing = ht_cap->ampdu_density; 1342c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi } 1343c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 13440b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov acx->hlid = hlid; 13456177eaea277527e48753d050723cd138494c98a8Eliad Peller acx->ht_capabilites = cpu_to_le32(ht_capabilites); 13466177eaea277527e48753d050723cd138494c98a8Eliad Peller 1347c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); 1348c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi if (ret < 0) { 1349c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi wl1271_warning("acx ht capabilities setting failed: %d", ret); 1350c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi goto out; 1351c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi } 1352c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1353c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviout: 1354c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi kfree(acx); 1355c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi return ret; 1356c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi} 1357c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1358c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviint wl1271_acx_set_ht_information(struct wl1271 *wl, 13590603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif, 1360c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi u16 ht_operation_mode) 1361c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi{ 1362c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi struct wl1271_acx_ht_information *acx; 1363c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi int ret = 0; 1364c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1365c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi wl1271_debug(DEBUG_ACX, "acx ht information setting"); 1366c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1367c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1368c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi if (!acx) { 1369c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi ret = -ENOMEM; 1370c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi goto out; 1371c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi } 1372c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 13730603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 1374c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->ht_protection = 1375c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); 1376c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->rifs_mode = 0; 137795a776107a131823c87147dff083696d8814c1b3Helmut Schaa acx->gf_protection = 137895a776107a131823c87147dff083696d8814c1b3Helmut Schaa !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 1379c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->ht_tx_burst_limit = 0; 1380c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi acx->dual_cts_protection = 0; 1381c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1382c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx)); 1383c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1384c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi if (ret < 0) { 1385c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi wl1271_warning("acx ht information setting failed: %d", ret); 1386c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi goto out; 1387c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi } 1388c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 1389c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviout: 1390c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi kfree(acx); 1391c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi return ret; 1392c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi} 1393c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi 13944b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar/* Configure BA session initiator/receiver parameters setting in the FW. */ 13950603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl, 13960603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 13974b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 13980f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov struct wl1271_acx_ba_initiator_policy *acx; 13994b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar int ret; 14004b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 14010f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl1271_debug(DEBUG_ACX, "acx ba initiator policy"); 14024b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 14034b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar acx = kzalloc(sizeof(*acx), GFP_KERNEL); 14044b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if (!acx) { 14054b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar ret = -ENOMEM; 14064b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar goto out; 14074b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar } 14084b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 14090f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* set for the current role */ 14100603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 14110f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov acx->tid_bitmap = wl->conf.ht.tx_ba_tid_bitmap; 14120f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov acx->win_size = wl->conf.ht.tx_ba_win_size; 14130f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov acx->inactivity_timeout = wl->conf.ht.inactivity_timeout; 14144b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 14154b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar ret = wl1271_cmd_configure(wl, 14160f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov ACX_BA_SESSION_INIT_POLICY, 14174b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar acx, 14184b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar sizeof(*acx)); 14194b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if (ret < 0) { 14200f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl1271_warning("acx ba initiator policy failed: %d", ret); 14214b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar goto out; 14224b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar } 14234b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 14244b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shaharout: 14254b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar kfree(acx); 14264b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar return ret; 14274b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 14284b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 1429bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar/* setup BA session receiver setting in the FW. */ 14300f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsovint wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, 14310f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov u16 ssn, bool enable, u8 peer_hlid) 1432bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar{ 1433bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar struct wl1271_acx_ba_receiver_setup *acx; 1434bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar int ret; 1435bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 1436bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar wl1271_debug(DEBUG_ACX, "acx ba receiver session setting"); 1437bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 1438bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1439bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar if (!acx) { 1440bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar ret = -ENOMEM; 1441bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar goto out; 1442bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar } 1443bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 14440f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov acx->hlid = peer_hlid; 1445bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar acx->tid = tid_index; 1446bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar acx->enable = enable; 14470f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov acx->win_size = wl->conf.ht.rx_ba_win_size; 1448bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar acx->ssn = ssn; 1449bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 1450bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx, 1451bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar sizeof(*acx)); 1452bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar if (ret < 0) { 1453bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar wl1271_warning("acx ba receiver session failed: %d", ret); 1454bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar goto out; 1455bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar } 1456bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 1457bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shaharout: 1458bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar kfree(acx); 1459bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar return ret; 1460bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar} 1461bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar 1462bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinenint wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) 1463bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen{ 1464bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen struct wl1271_acx_fw_tsf_information *tsf_info; 1465bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen int ret; 1466bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen 1467bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); 1468bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen if (!tsf_info) { 1469bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen ret = -ENOMEM; 1470bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen goto out; 1471bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen } 1472bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen 1473bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, 1474bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen tsf_info, sizeof(*tsf_info)); 1475bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen if (ret < 0) { 1476bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen wl1271_warning("acx tsf info interrogate failed"); 1477bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen goto out; 1478bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen } 1479bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen 1480bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen *mactime = le32_to_cpu(tsf_info->current_tsf_low) | 1481bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32); 1482bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen 1483bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinenout: 1484bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen kfree(tsf_info); 1485bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen return ret; 1486bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen} 148779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 14889eb599e9c62dcfd4efece1936c385381b366b684Eliad Pellerint wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, 14899eb599e9c62dcfd4efece1936c385381b366b684Eliad Peller bool enable) 1490f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller{ 1491f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller struct wl1271_acx_ps_rx_streaming *rx_streaming; 1492f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller u32 conf_queues, enable_queues; 1493f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller int i, ret = 0; 1494f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 1495f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller wl1271_debug(DEBUG_ACX, "acx ps rx streaming"); 1496f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 1497f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL); 1498f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller if (!rx_streaming) { 1499f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller ret = -ENOMEM; 1500f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller goto out; 1501f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller } 1502f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 1503f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller conf_queues = wl->conf.rx_streaming.queues; 1504f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller if (enable) 1505f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller enable_queues = conf_queues; 1506f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller else 1507f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller enable_queues = 0; 1508f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 1509f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller for (i = 0; i < 8; i++) { 1510f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller /* 1511f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller * Skip non-changed queues, to avoid redundant acxs. 1512f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller * this check assumes conf.rx_streaming.queues can't 1513f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller * be changed while rx_streaming is enabled. 1514f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller */ 1515f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller if (!(conf_queues & BIT(i))) 1516f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller continue; 1517f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 15180603d891c5b5153f667a79357d4652824c22b54eEliad Peller rx_streaming->role_id = wlvif->role_id; 1519f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming->tid = i; 1520f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming->enable = enable_queues & BIT(i); 1521f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming->period = wl->conf.rx_streaming.interval; 1522f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming->timeout = wl->conf.rx_streaming.interval; 1523f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 1524f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING, 1525f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller rx_streaming, 1526f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller sizeof(*rx_streaming)); 1527f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller if (ret < 0) { 1528f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller wl1271_warning("acx ps rx streaming failed: %d", ret); 1529f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller goto out; 1530f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller } 1531f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller } 1532f84673d59773ded6efab640c5ee5f44b34116b75Eliad Pellerout: 1533f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller kfree(rx_streaming); 1534f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller return ret; 1535f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller} 1536f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller 15370603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif) 153879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov{ 15393618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov struct wl1271_acx_ap_max_tx_retry *acx = NULL; 154079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov int ret; 154179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 15423618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov wl1271_debug(DEBUG_ACX, "acx ap max tx retry"); 154379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 154479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov acx = kzalloc(sizeof(*acx), GFP_KERNEL); 154579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov if (!acx) 154679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov return -ENOMEM; 154779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 15480603d891c5b5153f667a79357d4652824c22b54eEliad Peller acx->role_id = wlvif->role_id; 15493618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries); 155079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 155179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); 155279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov if (ret < 0) { 15533618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov wl1271_warning("acx ap max tx retry failed: %d", ret); 155479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov goto out; 155579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov } 155679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov 155779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovout: 155879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov kfree(acx); 155979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov return ret; 156079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov} 1561ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1562d2d66c56cf6c8727662aa321991f791604c22094Eliad Pellerint wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1563ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller{ 1564ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller struct wl1271_acx_config_ps *config_ps; 1565ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller int ret; 1566ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1567ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller wl1271_debug(DEBUG_ACX, "acx config ps"); 1568ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1569ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL); 1570ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller if (!config_ps) { 1571ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller ret = -ENOMEM; 1572ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller goto out; 1573ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller } 1574ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1575ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller config_ps->exit_retries = wl->conf.conn.psm_exit_retries; 1576ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller config_ps->enter_retries = wl->conf.conn.psm_entry_retries; 1577d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller config_ps->null_data_rate = cpu_to_le32(wlvif->basic_rate); 1578ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1579ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps, 1580ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller sizeof(*config_ps)); 1581ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1582ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller if (ret < 0) { 1583ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller wl1271_warning("acx config ps failed: %d", ret); 1584ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller goto out; 1585ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller } 1586ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller 1587ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Pellerout: 1588ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller kfree(config_ps); 1589ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller return ret; 1590ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller} 159199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 159299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsovint wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) 159399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov{ 159499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov struct wl1271_acx_inconnection_sta *acx = NULL; 159599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov int ret; 159699a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 159799a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr); 159899a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 159999a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov acx = kzalloc(sizeof(*acx), GFP_KERNEL); 160099a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov if (!acx) 160199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov return -ENOMEM; 160299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 160399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov memcpy(acx->addr, addr, ETH_ALEN); 160499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 160599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST, 160699a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov acx, sizeof(*acx)); 160799a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov if (ret < 0) { 160899a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov wl1271_warning("acx set inconnaction sta failed: %d", ret); 160999a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov goto out; 161099a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov } 161199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov 161299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsovout: 161399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov kfree(acx); 161499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov return ret; 161599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov} 1616ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1617ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Leviint wl1271_acx_fm_coex(struct wl1271 *wl) 1618ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi{ 1619ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi struct wl1271_acx_fm_coex *acx; 1620ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi int ret; 1621ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1622ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi wl1271_debug(DEBUG_ACX, "acx fm coex setting"); 1623ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1624ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1625ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (!acx) { 1626ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = -ENOMEM; 1627ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi goto out; 1628ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi } 1629ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1630ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->enable = wl->conf.fm_coex.enable; 1631ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->swallow_period = wl->conf.fm_coex.swallow_period; 1632ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1; 1633ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2; 1634ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->m_divider_fref_set_1 = 1635ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1); 1636ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->m_divider_fref_set_2 = 1637ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2); 1638ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->coex_pll_stabilization_time = 1639ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time); 1640ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->ldo_stabilization_time = 1641ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time); 1642ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->fm_disturbed_band_margin = 1643ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi wl->conf.fm_coex.fm_disturbed_band_margin; 1644ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff; 1645ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1646ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx)); 1647ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (ret < 0) { 1648ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi wl1271_warning("acx fm coex setting failed: %d", ret); 1649ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi goto out; 1650ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi } 1651ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 1652ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Leviout: 1653ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi kfree(acx); 1654ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi return ret; 1655ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi} 1656fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1657fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Pellerint wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl) 1658fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller{ 1659fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller struct wl12xx_acx_set_rate_mgmt_params *acx = NULL; 1660fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller struct conf_rate_policy_settings *conf = &wl->conf.rate; 1661fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller int ret; 1662fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1663fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller wl1271_debug(DEBUG_ACX, "acx set rate mgmt params"); 1664fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1665fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1666fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (!acx) 1667fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller return -ENOMEM; 1668fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1669fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->index = ACX_RATE_MGMT_ALL_PARAMS; 1670fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->rate_retry_score = cpu_to_le16(conf->rate_retry_score); 1671fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_add = cpu_to_le16(conf->per_add); 1672fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_th1 = cpu_to_le16(conf->per_th1); 1673fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_th2 = cpu_to_le16(conf->per_th2); 1674fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->max_per = cpu_to_le16(conf->max_per); 1675fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->inverse_curiosity_factor = conf->inverse_curiosity_factor; 1676fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->tx_fail_low_th = conf->tx_fail_low_th; 1677fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->tx_fail_high_th = conf->tx_fail_high_th; 1678fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_alpha_shift = conf->per_alpha_shift; 1679fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_add_shift = conf->per_add_shift; 1680fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_beta1_shift = conf->per_beta1_shift; 1681fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->per_beta2_shift = conf->per_beta2_shift; 1682fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->rate_check_up = conf->rate_check_up; 1683fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx->rate_check_down = conf->rate_check_down; 1684fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller memcpy(acx->rate_retry_policy, conf->rate_retry_policy, 1685fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller sizeof(acx->rate_retry_policy)); 1686fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1687fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller ret = wl1271_cmd_configure(wl, ACX_SET_RATE_MGMT_PARAMS, 1688fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller acx, sizeof(*acx)); 1689fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (ret < 0) { 1690fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller wl1271_warning("acx set rate mgmt params failed: %d", ret); 1691fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller goto out; 1692fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller } 1693fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 1694fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Pellerout: 1695fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller kfree(acx); 1696fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller return ret; 1697fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller} 16989487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 16999487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Pellerint wl12xx_acx_config_hangover(struct wl1271 *wl) 17009487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller{ 17019487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller struct wl12xx_acx_config_hangover *acx; 17029487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller struct conf_hangover_settings *conf = &wl->conf.hangover; 17039487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller int ret; 17049487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17059487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller wl1271_debug(DEBUG_ACX, "acx config hangover"); 17069487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17079487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx = kzalloc(sizeof(*acx), GFP_KERNEL); 17089487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (!acx) { 17099487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = -ENOMEM; 17109487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out; 17119487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller } 17129487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17139487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->recover_time = cpu_to_le32(conf->recover_time); 17149487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->hangover_period = conf->hangover_period; 17159487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->dynamic_mode = conf->dynamic_mode; 17169487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->early_termination_mode = conf->early_termination_mode; 17179487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->max_period = conf->max_period; 17189487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->min_period = conf->min_period; 17199487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->increase_delta = conf->increase_delta; 17209487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->decrease_delta = conf->decrease_delta; 17219487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->quiet_time = conf->quiet_time; 17229487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->increase_time = conf->increase_time; 17239487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller acx->window_size = acx->window_size; 17249487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17259487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx, 17269487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller sizeof(*acx)); 17279487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17289487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (ret < 0) { 17299487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller wl1271_warning("acx config hangover failed: %d", ret); 17309487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out; 17319487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller } 17329487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17339487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Pellerout: 17349487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller kfree(acx); 17359487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller return ret; 17369487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 17379487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller} 1738