1319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter/* 2319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * Atheros CARL9170 driver 3319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 4319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * MAC programming 5319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 6319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 7319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 8319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * This program is free software; you can redistribute it and/or modify 9319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * it under the terms of the GNU General Public License as published by 10319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * the Free Software Foundation; either version 2 of the License, or 11319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * (at your option) any later version. 12319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 13319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * This program is distributed in the hope that it will be useful, 14319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * but WITHOUT ANY WARRANTY; without even the implied warranty of 15319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * GNU General Public License for more details. 17319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 18319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * You should have received a copy of the GNU General Public License 19319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * along with this program; see the file COPYING. If not, see 20319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * http://www.gnu.org/licenses/. 21319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 22319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * This file incorporates work covered by the following copyright and 23319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * permission notice: 24319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * Copyright (c) 2007-2008 Atheros Communications, Inc. 25319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 26319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * Permission to use, copy, modify, and/or distribute this software for any 27319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * purpose with or without fee is hereby granted, provided that the above 28319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * copyright notice and this permission notice appear in all copies. 29319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * 30319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 31319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 32319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 33319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 34319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 35319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 36319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter */ 38319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 39319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter#include <asm/unaligned.h> 40319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 41319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter#include "carl9170.h" 42319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter#include "cmd.h" 43319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 44319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_dyn_sifs_ack(struct ar9170 *ar) 45319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 46319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 val; 47319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 48319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (conf_is_ht40(&ar->hw->conf)) 49319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter val = 0x010a; 50319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter else { 51319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) 52319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter val = 0x105; 53319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter else 54319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter val = 0x104; 55319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 56319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 57319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); 58319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 59319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 60319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_rts_cts_rate(struct ar9170 *ar) 61319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 62319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 rts_rate, cts_rate; 63319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 64319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (conf_is_ht(&ar->hw->conf)) { 65319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* 12 mbit OFDM */ 66319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rts_rate = 0x1da; 67319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cts_rate = 0x10a; 68319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else { 69319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { 70319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* 11 mbit CCK */ 71319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rts_rate = 033; 72319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cts_rate = 003; 73319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else { 74319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* 6 mbit OFDM */ 75319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rts_rate = 0x1bb; 76319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cts_rate = 0x10b; 77319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 78319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 79319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 80319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE, 81319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rts_rate | (cts_rate) << 16); 82319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 83319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 84319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_slot_time(struct ar9170 *ar) 85319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 86319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct ieee80211_vif *vif; 87319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 slottime = 20; 88319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 89319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_lock(); 90319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif = carl9170_get_main_vif(ar); 91319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (!vif) { 92319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 93319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return 0; 94319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 95319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 96319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || 97319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif->bss_conf.use_short_slot) 98319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter slottime = 9; 99319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 100319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 101319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 102319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, 103319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter slottime << 10); 104319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 105319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 106319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_mac_rates(struct ar9170 *ar) 107319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 108319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct ieee80211_vif *vif; 109319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 basic, mandatory; 110319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 111319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_lock(); 112319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif = carl9170_get_main_vif(ar); 113319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 114319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (!vif) { 115319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 116319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return 0; 117319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 118319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 119319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter basic = (vif->bss_conf.basic_rates & 0xf); 120319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; 121319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 122319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 123319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) 124319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ 125319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter else 126319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ 127319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 128319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 129319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic); 130319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory); 131319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 132319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 133319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 134319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 135319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 136319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_qos(struct ar9170 *ar) 137319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 138319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 139319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 140319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | 141319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter (ar->edcf[0].cw_max << 16)); 142319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | 143319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter (ar->edcf[1].cw_max << 16)); 144319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | 145319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter (ar->edcf[2].cw_max << 16)); 146319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | 147319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter (ar->edcf[3].cw_max << 16)); 148319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | 149319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter (ar->edcf[4].cw_max << 16)); 150319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 151319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS, 152319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[0].aifs * 9 + 10)) | 153319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[1].aifs * 9 + 10) << 12) | 154319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[2].aifs * 9 + 10) << 24)); 155319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS, 156319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[2].aifs * 9 + 10) >> 8) | 157319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[3].aifs * 9 + 10) << 4) | 158319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ((ar->edcf[4].aifs * 9 + 10) << 16)); 159319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 160319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, 161319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->edcf[0].txop | ar->edcf[1].txop << 16); 162319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, 163319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->edcf[2].txop | ar->edcf[3].txop << 16 | 164319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->edcf[4].txop << 24); 165319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 166319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 167319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 168319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 169319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 170319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 171319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_init_mac(struct ar9170 *ar) 172319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 173319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 174319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 175319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* switch MAC to OTUS interface */ 176319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(0x1c3600, 0x3); 177319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 178319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); 179319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 180319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0); 181319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 182319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, 183319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_FTF_MONITOR); 184319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 185319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* enable MMIC */ 186319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_SNIFFER, 187319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_SNIFFER_DEFAULTS); 188319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 189319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); 190319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 191319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); 192319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); 193319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); 194319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 195319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* CF-END & CF-ACK rate => 24M OFDM */ 196319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000); 197319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 198319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* NAV protects ACK only (in TXOP) */ 199319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201); 200319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 201319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ 202319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* OTUS set AM to 0x1 */ 203319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); 204319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 205319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); 206319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 207319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* Aggregation MAX number and timeout */ 208e27769059ccb15273a7eb69ed31b8e08f9b0eda8Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a); 209e27769059ccb15273a7eb69ed31b8e08f9b0eda8Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07); 210319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 211319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, 212319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_FTF_DEFAULTS); 213319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 214319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, 215319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_RX_CTRL_DEAGG | 216319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_RX_CTRL_SHORT_FILTER); 217319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 218319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* rate sets */ 219319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); 220319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); 221319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033); 222319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 223319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* MIMO response control */ 224319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e); 225319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 226319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); 227319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 228319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* set PHY register read timeout (??) */ 229319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); 230319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 231319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* Disable Rx TimeOut, workaround for BB. */ 232319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); 233319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 234319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* Set WLAN DMA interrupt mode: generate int per packet */ 235319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); 236319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 237319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT, 238319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_FCS_FIFO_PROT); 239319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 240319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* Disables the CF_END frame, undocumented register */ 241319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, 242319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 0x141e0f48); 243319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 244319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* reset group hash table */ 245319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff); 246319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff); 247319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 248319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* disable PRETBTT interrupt */ 249319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0); 250319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0); 251319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 252319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 253319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 254319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 255319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 256319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 257319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterstatic int carl9170_set_mac_reg(struct ar9170 *ar, 258319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter const u32 reg, const u8 *mac) 259319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 260319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter static const u8 zero[ETH_ALEN] = { 0 }; 261319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 262319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (!mac) 263319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mac = zero; 264319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 265319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 266319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 267319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(reg, get_unaligned_le32(mac)); 268319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); 269319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 270319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 271319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 272319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 273319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 274319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 275319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, 276319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter const u8 *mac) 277319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 278319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (WARN_ON(id >= ar->fw.vif_num)) 279319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return -EINVAL; 280319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 281319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_set_mac_reg(ar, 282319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac); 283319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 284319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 285319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) 286319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 287319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter int err; 288319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 289319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 290319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); 291319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); 292319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 293319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter err = carl9170_regwrite_result(); 294319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (err) 295319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return err; 296319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 297319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->cur_mc_hash = mc_hash; 298319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return 0; 299319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 300319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 301319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_operating_mode(struct ar9170 *ar) 302319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 303319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct ieee80211_vif *vif; 304319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct ath_common *common = &ar->common; 305319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u8 *mac_addr, *bssid; 306319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 cam_mode = AR9170_MAC_CAM_DEFAULTS; 307319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS; 308319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | 309319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_RX_CTRL_SHORT_FILTER; 310319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; 311319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter int err = 0; 312319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 313319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_lock(); 314319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif = carl9170_get_main_vif(ar); 315319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 316319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (vif) { 317319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mac_addr = common->macaddr; 318319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter bssid = common->curbssid; 319319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 320319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter switch (vif->type) { 321319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_MESH_POINT: 322319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_ADHOC: 323319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cam_mode |= AR9170_MAC_CAM_IBSS; 324319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 325319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_AP: 326319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cam_mode |= AR9170_MAC_CAM_AP; 327319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 328319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter /* iwlagn 802.11n STA Workaround */ 329319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 330319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 331319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_WDS: 332319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cam_mode |= AR9170_MAC_CAM_AP_WDS; 333319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 334319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 335319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_STATION: 336319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter cam_mode |= AR9170_MAC_CAM_STA; 337319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 338319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 339319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter default: 340319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter WARN(1, "Unsupported operation mode %x\n", vif->type); 341319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter err = -EOPNOTSUPP; 342319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 343319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 344319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else { 345319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mac_addr = NULL; 346319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter bssid = NULL; 347319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 348319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 349319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 350319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (err) 351319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return err; 352319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 353319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->rx_software_decryption) 354319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 355319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 356319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->sniffer_enabled) { 357319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; 358319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; 359319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 360319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 361319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 362319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); 363319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (err) 364319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return err; 365319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 366319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); 367319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (err) 368319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return err; 369319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 370319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 371319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); 372319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); 373319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); 374319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); 375319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 376319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 377319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 378319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 379319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 380319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) 381319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 382319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); 383319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 384319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); 385319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 386319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 387319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_set_beacon_timers(struct ar9170 *ar) 388319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 389319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct ieee80211_vif *vif; 390319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 v = 0; 391319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter u32 pretbtt = 0; 392319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 393319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_lock(); 394319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif = carl9170_get_main_vif(ar); 395319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 396319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (vif) { 397319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct carl9170_vif_info *mvif; 398319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mvif = (void *) vif->drv_priv; 399319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 400319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { 401319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_beacon_int = vif->bss_conf.beacon_int / 402319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->beacon_enabled; 403319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 404319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter SET_VAL(AR9170_MAC_BCN_DTIM, v, 405319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter vif->bss_conf.dtim_period); 406319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 407319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter switch (vif->type) { 408319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_MESH_POINT: 409319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_ADHOC: 410319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter v |= AR9170_MAC_BCN_IBSS_MODE; 411319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 412319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter case NL80211_IFTYPE_AP: 413319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter v |= AR9170_MAC_BCN_AP_MODE; 414319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 415319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter default: 416319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter WARN_ON_ONCE(1); 417319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter break; 418319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 419319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else if (vif->type == NL80211_IFTYPE_STATION) { 420319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_beacon_int = vif->bss_conf.beacon_int; 421319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 422319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter SET_VAL(AR9170_MAC_BCN_DTIM, v, 423319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->hw->conf.ps_dtim_period); 424319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 425319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter v |= AR9170_MAC_BCN_STA_PS | 426319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter AR9170_MAC_BCN_PWR_MGT; 427319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 428319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 429319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->global_beacon_int) { 430319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (ar->global_beacon_int < 15) { 431319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 432319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return -ERANGE; 433319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 434319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 435319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_pretbtt = ar->global_beacon_int - 436319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter CARL9170_PRETBTT_KUS; 437319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else { 438319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_pretbtt = 0; 439319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 440319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } else { 441319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_beacon_int = 0; 442319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter ar->global_pretbtt = 0; 443319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter } 444319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 445319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter rcu_read_unlock(); 446319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 447319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); 448319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); 449319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); 450319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 451319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_begin(ar); 452319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); 453319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); 454319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter carl9170_regwrite_finish(); 455319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_regwrite_result(); 456319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 457319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 458319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 459319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter const u8 ktype, const u8 keyidx, const u8 *keydata, 460319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter const int keylen) 461319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 462319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct carl9170_set_key_cmd key = { }; 463319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter static const u8 bcast[ETH_ALEN] = { 464319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 465319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 466319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter mac = mac ? : bcast; 467319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 468319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter key.user = cpu_to_le16(id); 469319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter key.keyId = cpu_to_le16(keyidx); 470319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter key.type = cpu_to_le16(ktype); 471319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter memcpy(&key.macAddr, mac, ETH_ALEN); 472319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter if (keydata) 473319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter memcpy(&key.key, keydata, keylen); 474319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 475319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, 476319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter sizeof(key), (u8 *)&key, 0, NULL); 477319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 478319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 479319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparterint carl9170_disable_key(struct ar9170 *ar, const u8 id) 480319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter{ 481319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter struct carl9170_disable_key_cmd key = { }; 482319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 483319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter key.user = cpu_to_le16(id); 484319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter 485319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, 486319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter sizeof(key), (u8 *)&key, 0, NULL); 487319da621d5c4e9bd8c34feeb200e864e87d91fe7Christian Lamparter} 48867e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 48967e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparterint carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) 49067e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter{ 49167e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter unsigned int power, chains; 49267e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 49367e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter if (ar->eeprom.tx_mask != 1) 49467e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter chains = AR9170_TX_PHY_TXCHAIN_2; 49567e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter else 49667e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter chains = AR9170_TX_PHY_TXCHAIN_1; 49767e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 49867e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter switch (channel->band) { 49967e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter case IEEE80211_BAND_2GHZ: 50067e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power = ar->power_2G_ofdm[0] & 0x3f; 50167e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter break; 50267e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter case IEEE80211_BAND_5GHZ: 50367e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power = ar->power_5G_leg[0] & 0x3f; 50467e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter break; 50567e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter default: 50667e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter BUG_ON(1); 50767e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter } 50867e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 50967e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); 51067e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 51167e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter carl9170_regwrite_begin(ar); 51267e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 51367e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter 0x3c1e | power << 20 | chains << 26); 51467e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, 51567e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power << 5 | chains << 11 | 51667e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power << 21 | chains << 27); 51767e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, 51867e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power << 5 | chains << 11 | 51967e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter power << 21 | chains << 27); 52067e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter carl9170_regwrite_finish(); 52167e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter return carl9170_regwrite_result(); 52267e43de6dbc9caf52fa7bcf4c813fd088ba6fbfcChristian Lamparter} 523