init.c revision 70f474241b3d5fb633635a2ce39ea9da4afeea6c
1f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho/* 2f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This file is part of wl1271 3f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 4f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Copyright (C) 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 24f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/kernel.h> 25f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/module.h> 265a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 27f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2800d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "init.h" 29f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include "wl12xx_80211.h" 3000d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "acx.h" 3100d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "cmd.h" 3200d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "reg.h" 33e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov#include "tx.h" 3448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi#include "io.h" 35f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 36e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovint wl1271_sta_init_templates_config(struct wl1271 *wl) 37f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 38bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen int ret, i; 39f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 40f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* send empty templates for fw memory reservation */ 41f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 42ea559b460509b241cc1a3f36eebe0b2b634b3cf2Guy Eilam WL1271_CMD_TEMPL_MAX_SIZE, 43606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 44f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 45f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 46f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 4711eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 48ea559b460509b241cc1a3f36eebe0b2b634b3cf2Guy Eilam NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, 4911eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen WL1271_RATE_AUTOMATIC); 5011eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen if (ret < 0) 5111eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen return ret; 52abb0b3bfb2d2411034b721df21c31964265b851eTeemu Paasikivi 53f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 54bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_null_data_template), 55606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 56f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 57f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 58f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 59f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 60bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_ps_poll_template), 61606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 64f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 65f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 66f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 67bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen (struct wl12xx_qos_null_data_template), 68606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 71f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 72f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 73f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 74bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen (struct wl12xx_probe_resp_template), 75606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 76f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 79f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 80f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 81bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen (struct wl12xx_beacon_template), 82606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 85f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 86c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL, 87c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller sizeof 88c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller (struct wl12xx_arp_rsp_template), 89c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 0, WL1271_RATE_AUTOMATIC); 90c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller if (ret < 0) 91c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller return ret; 92c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 93bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 94bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, 95606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen WL1271_CMD_TEMPL_MAX_SIZE, i, 96606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen WL1271_RATE_AUTOMATIC); 97bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen if (ret < 0) 98bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen return ret; 99bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen } 100bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen 101f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 102f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 103f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 104e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl) 105e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 106e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct wl12xx_disconn_template *tmpl; 107e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 108e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 109e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); 110e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!tmpl) { 111e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 112e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 113e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 114e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 115e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 116e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_DEAUTH); 117e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 118e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, 119e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl, sizeof(*tmpl), 0, 120e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov wl1271_tx_min_rate_get(wl)); 121e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 122e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 123e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(tmpl); 124e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 125e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 126e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 127e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_null_template(struct wl1271 *wl) 128e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 129e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_hdr_3addr *nullfunc; 130e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 131e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 132e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); 133e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!nullfunc) { 134e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 135e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 136e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 137e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 138e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 139e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_NULLFUNC | 140e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 141e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 142e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* nullfunc->addr1 is filled by FW */ 143e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 144e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); 145e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); 146e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 147e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, 148e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof(*nullfunc), 0, 149e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov wl1271_tx_min_rate_get(wl)); 150e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 151e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 152e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(nullfunc); 153e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 154e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 155e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 156e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_qos_null_template(struct wl1271 *wl) 157e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 158e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_qos_hdr *qosnull; 159e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 161e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); 162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!qosnull) { 163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 166e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 167e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 168e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_QOS_NULLFUNC | 169e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 170e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 171e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* qosnull->addr1 is filled by FW */ 172e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 173e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); 174e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); 175e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, 177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof(*qosnull), 0, 178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov wl1271_tx_min_rate_get(wl)); 179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 180e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 181e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(qosnull); 182e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 183e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 184e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 185e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_templates_config(struct wl1271 *wl) 186e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 187e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 188e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 189e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* 190e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov * Put very large empty placeholders for all templates. These 191e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov * reserve memory for later. 192e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov */ 193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL, 194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof 195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov (struct wl12xx_probe_resp_template), 196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 0, WL1271_RATE_AUTOMATIC); 197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 199e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 200e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL, 201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof 202e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov (struct wl12xx_beacon_template), 203e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 0, WL1271_RATE_AUTOMATIC); 204e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 205e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 206e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 207e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL, 208e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof 209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov (struct wl12xx_disconn_template), 210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 0, WL1271_RATE_AUTOMATIC); 211e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 214e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 215e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof(struct wl12xx_null_data_template), 216e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 0, WL1271_RATE_AUTOMATIC); 217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 218e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 219e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 220e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 221e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov sizeof 222e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov (struct wl12xx_qos_null_data_template), 223e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 0, WL1271_RATE_AUTOMATIC); 224e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 225e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 226e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 227e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 228e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 229e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) 231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 233f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2348793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinen ret = wl1271_acx_rx_msdu_life_time(wl); 235f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 236f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 237f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_rx_config(wl, config, filter); 239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 241f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 244f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 24512419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_phy_config(struct wl1271 *wl) 246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_pd_threshold(wl); 250f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 251f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME); 254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 256f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 257f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_service_period_timeout(wl); 258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2615f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold); 262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 264f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 266f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 268f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_filter(struct wl1271 *wl) 269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2721922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen /* disable beacon filtering at this stage */ 2731922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen ret = wl1271_acx_beacon_filter_opt(wl, false); 274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_beacon_filter_table(wl); 278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 281f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 28412419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl) 285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 287f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 288801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (wl->bss_type == BSS_TYPE_AP_BSS) 289801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_acx_ap_sg_cfg(wl); 290801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov else 291801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_acx_sta_sg_cfg(wl); 292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2957fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); 296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 30212419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl) 303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_cca_threshold(wl); 307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 311f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_broadcast(struct wl1271 *wl) 314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 316f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 317f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_bcn_dtim_options(wl); 318f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 319f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 320f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 321f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 322f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 323f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 324e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init(struct wl1271 *wl) 325e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 326e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 327e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 32849d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id != CHIP_ID_1283_PG20) { 32949d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_ext_radio_parms(wl); 33049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (ret < 0) 33149d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi return ret; 33249d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi } 333e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 334c8bde243421d759844264cf11e4248e7862c2722Eliad Peller /* PS config */ 335c8bde243421d759844264cf11e4248e7862c2722Eliad Peller ret = wl1271_acx_config_ps(wl); 336c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 337c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 338c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 339e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_sta_init_templates_config(wl); 340e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 341e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 342e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 343e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); 344e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 345e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 346e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 347e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Initialize connection monitoring thresholds */ 348e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_conn_monit_params(wl, false); 349e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Beacon filtering */ 353e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_init_beacon_filter(wl); 354e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 355e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 356e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 357ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi /* FM WLAN coexistence */ 358ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = wl1271_acx_fm_coex(wl); 359ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (ret < 0) 360ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi return ret; 361ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 362e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Beacons and broadcast settings */ 363e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_init_beacon_broadcast(wl); 364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Configure for ELP power saving */ 368e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 369e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 370e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 371e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 372e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Configure rssi/snr averaging weights */ 373e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_rssi_snr_avg_weights(wl); 374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 375e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 376e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 377e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_sta_rate_policies(wl); 378e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 38147684808fd89d6809c0886e06f8ac324252499d8Arik Nemtsov ret = wl1271_acx_sta_max_tx_retry(wl); 38247684808fd89d6809c0886e06f8ac324252499d8Arik Nemtsov if (ret < 0) 38347684808fd89d6809c0886e06f8ac324252499d8Arik Nemtsov return ret; 38447684808fd89d6809c0886e06f8ac324252499d8Arik Nemtsov 385c8bde243421d759844264cf11e4248e7862c2722Eliad Peller ret = wl1271_acx_sta_mem_cfg(wl); 386c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 387c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 388c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 389e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 392e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl) 393e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret, i; 395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 396e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key); 397e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) { 398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov wl1271_warning("couldn't set default key"); 399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 401e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable all keep-alive templates */ 403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 404e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_keep_alive_config(wl, i, 405e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ACX_KEEP_ALIVE_TPL_INVALID); 406e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 407e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 408e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 409e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 410e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable the keep-alive feature */ 411e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_keep_alive_mode(wl, false); 412e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 413e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 415e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 416e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 417e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 418e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_hw_init(struct wl1271 *wl) 419e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 42070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int ret; 421e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 422e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_init_templates_config(wl); 423e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 424e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 425e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 426e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Configure for power always on */ 427e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 428e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 429e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 430e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 43170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_init_ap_rates(wl); 432e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 433e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 434e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 43547684808fd89d6809c0886e06f8ac324252499d8Arik Nemtsov ret = wl1271_acx_ap_max_tx_retry(wl); 436e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 437e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 438e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 439c8bde243421d759844264cf11e4248e7862c2722Eliad Peller ret = wl1271_acx_ap_mem_cfg(wl); 440c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 441c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 442c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 443e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 444e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 445e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 446e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl) 447e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 448e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 449e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 450e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_init_deauth_template(wl); 451e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 452e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 453e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 454e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_init_null_template(wl); 455e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 456e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 457e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 458e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_init_qos_null_template(wl); 459e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 460e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 461e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 462521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov /* 463521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * when operating as AP we want to receive external beacons for 464521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * configuring ERP protection. 465521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov */ 466521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov ret = wl1271_acx_set_ap_beacon_filter(wl, false); 467521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov if (ret < 0) 468521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov return ret; 469521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov 470e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 471e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 472e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 47370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsovint wl1271_init_ap_rates(struct wl1271 *wl) 47470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{ 47570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int i, ret; 47670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov struct conf_tx_rate_class rc; 47770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov u32 supported_rates; 47870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 47970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set); 48070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 48170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (wl->basic_rate_set == 0) 48270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return -EINVAL; 48370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 48470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = wl->basic_rate_set; 48570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 48670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 48770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 48870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE); 48970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 49070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 49170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 49270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* use the min basic rate for AP broadcast/multicast */ 49370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = wl1271_tx_min_rate_get(wl); 49470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 49570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 49670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 49770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE); 49870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 49970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 50070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 50170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* 50270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * If the basic rates contain OFDM rates, use OFDM only 50370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * rates for unicast TX as well. Else use all supported rates. 50470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov */ 50570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if ((wl->basic_rate_set & CONF_TX_OFDM_RATES)) 50670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_OFDM_RATES; 50770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov else 50870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_AP_ENABLED_RATES; 50970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 51070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* configure unicast TX rate classes */ 51170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 51270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = supported_rates; 51370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 51470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 51570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 51670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, i); 51770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 51870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 51970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov } 52070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 52170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return 0; 52270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov} 52370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 5244b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shaharstatic void wl1271_check_ba_support(struct wl1271 *wl) 5254b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 5264b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* validate FW cose ver x.x.x.50-60.x */ 5274b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) && 5284b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) { 5294b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar wl->ba_support = true; 5304b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar return; 5314b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar } 5324b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5334b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar wl->ba_support = false; 5344b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 5354b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5364b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shaharstatic int wl1271_set_ba_policies(struct wl1271 *wl) 5374b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 5384b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar u8 tid_index; 53903c5a9cf49999ca3431eb9199c9bb831b0020be2Dan Carpenter int ret = 0; 5404b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5414b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Reset the BA RX indicators */ 5424b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar wl->ba_rx_bitmap = 0; 5434b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5444b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* validate that FW support BA */ 5454b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar wl1271_check_ba_support(wl); 5464b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5474b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if (wl->ba_support) 5484b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* 802.11n initiator BA session setting */ 5494b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT; 5504b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar ++tid_index) { 5514b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR, 5524b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar tid_index, true); 5534b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if (ret < 0) 5544b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar break; 5554b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar } 5564b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5574b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar return ret; 5584b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 5594b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 56048a61477bdc04896bd96d259388a0c42a7019943Shahar Leviint wl1271_chip_specific_init(struct wl1271 *wl) 56148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi{ 56248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi int ret = 0; 56348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 56448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) { 56548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; 56648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 5670da13da767cd568c1fe2a7b5b936e86e521b5ae7Ido Yariv if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT) 56848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Enable SDIO padding */ 56948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; 57048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 57148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Must be before wl1271_acx_init_mem_config() */ 57248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap); 57348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 57448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi goto out; 57548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi } 57648a61477bdc04896bd96d259388a0c42a7019943Shahar Leviout: 57748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 57848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi} 57948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 58048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 581f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_hw_init(struct wl1271 *wl) 582f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 583243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo struct conf_tx_ac_category *conf_ac; 584f2054df5170734eacd1db82138c70746ec8387deKalle Valo struct conf_tx_tid *conf_tid; 585243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo int ret, i; 586e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); 587f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 58849d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) 58949d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl128x_cmd_general_parms(wl); 59049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi else 59149d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_general_parms(wl); 5924a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho if (ret < 0) 593f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 594f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 59549d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) 59649d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl128x_cmd_radio_parms(wl); 59749d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi else 59849d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_radio_parms(wl); 5994a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho if (ret < 0) 600f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 601f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 60248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Chip-specific init */ 60348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = wl1271_chip_specific_init(wl); 60448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 60548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 60648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 607e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Mode specific init */ 608e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (is_ap) 609e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_hw_init(wl); 610e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov else 611e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_sta_hw_init(wl); 612644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen 613f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 614f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 615f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 616801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov /* Bluetooth WLAN coexistence */ 617801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_init_pta(wl); 618801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (ret < 0) 619801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov return ret; 620801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov 621f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default memory configuration */ 622f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_mem_config(wl); 623f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 624f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 625f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 626f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX config */ 627f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_rx_config(wl, 628eb5b28d021a1b96050f7af46e9140eb0051cc6d8Juuso Oikarinen RX_CFG_PROMISCUOUS | RX_CFG_TSF, 629eb5b28d021a1b96050f7af46e9140eb0051cc6d8Juuso Oikarinen RX_FILTER_OPTION_DEF); 630f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS, 631f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho RX_FILTER_OPTION_FILTER_ALL); */ 632f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 633f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 634f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 635f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* PHY layer config */ 636f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_phy_config(wl); 637f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 638f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 639f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6406e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_acx_dco_itrim_params(wl); 6416e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) 6426e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out_free_memmap; 6436e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 644f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure TX patch complete interrupt behavior */ 645f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_tx_config_options(wl); 646f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 647f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 648f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 649f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX complete interrupt pacing */ 650f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_rx_interrupt(wl); 651f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 652f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 653f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 654f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Energy detection */ 655f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_energy_detection(wl); 656f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 657f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 658f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 659f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default fragmentation threshold */ 6605f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold); 661f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 662f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 663f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6649987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen /* Default TID/AC configuration */ 6659987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); 666f2054df5170734eacd1db82138c70746ec8387deKalle Valo for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 6679987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen conf_ac = &wl->conf.tx.ac_conf[i]; 6689987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, 6699987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen conf_ac->cw_max, conf_ac->aifsn, 6709987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen conf_ac->tx_op_limit); 6719987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen if (ret < 0) 6729987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen goto out_free_memmap; 6739987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen 674f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid = &wl->conf.tx.tid_conf[i]; 675f2054df5170734eacd1db82138c70746ec8387deKalle Valo ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, 676f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->channel_type, 677f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->tsid, 678f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->ps_scheme, 679f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->ack_policy, 680f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->apsd_conf[0], 681f2054df5170734eacd1db82138c70746ec8387deKalle Valo conf_tid->apsd_conf[1]); 682f2054df5170734eacd1db82138c70746ec8387deKalle Valo if (ret < 0) 683f2054df5170734eacd1db82138c70746ec8387deKalle Valo goto out_free_memmap; 684f2054df5170734eacd1db82138c70746ec8387deKalle Valo } 685f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 686f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Enable data path */ 68794210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho ret = wl1271_cmd_data_path(wl, 1); 688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure HW encryption */ 692e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_acx_feature_cfg(wl); 693f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 695f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 69638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen /* configure PM */ 69738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_acx_pm_config(wl); 69838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) 69938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out_free_memmap; 70038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 701e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* Mode specific init - post mem init */ 702e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (is_ap) 703e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_ap_hw_init_post_mem(wl); 704e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov else 705e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_sta_hw_init_post_mem(wl); 706c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen 70700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen if (ret < 0) 70800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen goto out_free_memmap; 70900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen 7104b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Configure initiator BA sessions policies */ 7114b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar ret = wl1271_set_ba_policies(wl); 7124b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar if (ret < 0) 7134b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar goto out_free_memmap; 7144b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 716f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap: 718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 719344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl->target_mem_map = NULL; 720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 723