cachepc-linux

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

mac.c (14441B)


      1/*
      2 * Atheros CARL9170 driver
      3 *
      4 * MAC programming
      5 *
      6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
      7 *
      8 * This program is free software; you can redistribute it and/or modify
      9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation; either version 2 of the License, or
     11 * (at your option) any later version.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License
     19 * along with this program; see the file COPYING.  If not, see
     20 * http://www.gnu.org/licenses/.
     21 *
     22 * This file incorporates work covered by the following copyright and
     23 * permission notice:
     24 *    Copyright (c) 2007-2008 Atheros Communications, Inc.
     25 *
     26 *    Permission to use, copy, modify, and/or distribute this software for any
     27 *    purpose with or without fee is hereby granted, provided that the above
     28 *    copyright notice and this permission notice appear in all copies.
     29 *
     30 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     31 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     32 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     33 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     34 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     35 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     36 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     37 */
     38
     39#include <asm/unaligned.h>
     40
     41#include "carl9170.h"
     42#include "cmd.h"
     43
     44int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
     45{
     46	u32 val;
     47
     48	if (conf_is_ht40(&ar->hw->conf))
     49		val = 0x010a;
     50	else {
     51		if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
     52			val = 0x105;
     53		else
     54			val = 0x104;
     55	}
     56
     57	return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
     58}
     59
     60int carl9170_set_rts_cts_rate(struct ar9170 *ar)
     61{
     62	u32 rts_rate, cts_rate;
     63
     64	if (conf_is_ht(&ar->hw->conf)) {
     65		/* 12 mbit OFDM */
     66		rts_rate = 0x1da;
     67		cts_rate = 0x10a;
     68	} else {
     69		if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
     70			/* 11 mbit CCK */
     71			rts_rate = 033;
     72			cts_rate = 003;
     73		} else {
     74			/* 6 mbit OFDM */
     75			rts_rate = 0x1bb;
     76			cts_rate = 0x10b;
     77		}
     78	}
     79
     80	return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
     81				  rts_rate | (cts_rate) << 16);
     82}
     83
     84int carl9170_set_slot_time(struct ar9170 *ar)
     85{
     86	struct ieee80211_vif *vif;
     87	u32 slottime = 20;
     88
     89	rcu_read_lock();
     90	vif = carl9170_get_main_vif(ar);
     91	if (!vif) {
     92		rcu_read_unlock();
     93		return 0;
     94	}
     95
     96	if ((ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) ||
     97	    vif->bss_conf.use_short_slot)
     98		slottime = 9;
     99
    100	rcu_read_unlock();
    101
    102	return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
    103				  slottime << 10);
    104}
    105
    106int carl9170_set_mac_rates(struct ar9170 *ar)
    107{
    108	struct ieee80211_vif *vif;
    109	u32 basic, mandatory;
    110
    111	rcu_read_lock();
    112	vif = carl9170_get_main_vif(ar);
    113
    114	if (!vif) {
    115		rcu_read_unlock();
    116		return 0;
    117	}
    118
    119	basic = (vif->bss_conf.basic_rates & 0xf);
    120	basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
    121	rcu_read_unlock();
    122
    123	if (ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
    124		mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
    125	else
    126		mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
    127
    128	carl9170_regwrite_begin(ar);
    129	carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
    130	carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
    131	carl9170_regwrite_finish();
    132
    133	return carl9170_regwrite_result();
    134}
    135
    136int carl9170_set_qos(struct ar9170 *ar)
    137{
    138	carl9170_regwrite_begin(ar);
    139
    140	carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
    141			  (ar->edcf[0].cw_max << 16));
    142	carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
    143			  (ar->edcf[1].cw_max << 16));
    144	carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
    145			  (ar->edcf[2].cw_max << 16));
    146	carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
    147			  (ar->edcf[3].cw_max << 16));
    148	carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
    149			  (ar->edcf[4].cw_max << 16));
    150
    151	carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
    152			  ((ar->edcf[0].aifs * 9 + 10)) |
    153			  ((ar->edcf[1].aifs * 9 + 10) << 12) |
    154			  ((ar->edcf[2].aifs * 9 + 10) << 24));
    155	carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
    156			  ((ar->edcf[2].aifs * 9 + 10) >> 8) |
    157			  ((ar->edcf[3].aifs * 9 + 10) << 4) |
    158			  ((ar->edcf[4].aifs * 9 + 10) << 16));
    159
    160	carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
    161			  ar->edcf[0].txop | ar->edcf[1].txop << 16);
    162	carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
    163			  ar->edcf[2].txop | ar->edcf[3].txop << 16 |
    164			  ar->edcf[4].txop << 24);
    165
    166	carl9170_regwrite_finish();
    167
    168	return carl9170_regwrite_result();
    169}
    170
    171int carl9170_init_mac(struct ar9170 *ar)
    172{
    173	carl9170_regwrite_begin(ar);
    174
    175	/* switch MAC to OTUS interface */
    176	carl9170_regwrite(0x1c3600, 0x3);
    177
    178	carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
    179
    180	carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
    181
    182	carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
    183			  AR9170_MAC_FTF_MONITOR);
    184
    185	/* enable MMIC */
    186	carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
    187			AR9170_MAC_SNIFFER_DEFAULTS);
    188
    189	carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
    190
    191	carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
    192	carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
    193	carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
    194
    195	/* CF-END & CF-ACK rate => 24M OFDM */
    196	carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
    197
    198	/* NAV protects ACK only (in TXOP) */
    199	carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
    200
    201	/* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
    202	/* OTUS set AM to 0x1 */
    203	carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
    204
    205	carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
    206
    207	/* Aggregation MAX number and timeout */
    208	carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
    209	carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
    210
    211	carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
    212			  AR9170_MAC_FTF_DEFAULTS);
    213
    214	carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
    215			  AR9170_MAC_RX_CTRL_DEAGG |
    216			  AR9170_MAC_RX_CTRL_SHORT_FILTER);
    217
    218	/* rate sets */
    219	carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
    220	carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
    221	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
    222
    223	/* MIMO response control */
    224	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
    225
    226	carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
    227
    228	/* set PHY register read timeout (??) */
    229	carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
    230
    231	/* Disable Rx TimeOut, workaround for BB. */
    232	carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
    233
    234	/* Set WLAN DMA interrupt mode: generate int per packet */
    235	carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
    236
    237	carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
    238			AR9170_MAC_FCS_FIFO_PROT);
    239
    240	/* Disables the CF_END frame, undocumented register */
    241	carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
    242			0x141e0f48);
    243
    244	/* reset group hash table */
    245	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
    246	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
    247
    248	/* disable PRETBTT interrupt */
    249	carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
    250	carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
    251
    252	carl9170_regwrite_finish();
    253
    254	return carl9170_regwrite_result();
    255}
    256
    257static int carl9170_set_mac_reg(struct ar9170 *ar,
    258				const u32 reg, const u8 *mac)
    259{
    260	static const u8 zero[ETH_ALEN] = { 0 };
    261
    262	if (!mac)
    263		mac = zero;
    264
    265	carl9170_regwrite_begin(ar);
    266
    267	carl9170_regwrite(reg, get_unaligned_le32(mac));
    268	carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
    269
    270	carl9170_regwrite_finish();
    271
    272	return carl9170_regwrite_result();
    273}
    274
    275int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
    276			     const u8 *mac)
    277{
    278	if (WARN_ON(id >= ar->fw.vif_num))
    279		return -EINVAL;
    280
    281	return carl9170_set_mac_reg(ar,
    282		AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
    283}
    284
    285int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
    286{
    287	int err;
    288
    289	carl9170_regwrite_begin(ar);
    290	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
    291	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
    292	carl9170_regwrite_finish();
    293	err = carl9170_regwrite_result();
    294	if (err)
    295		return err;
    296
    297	ar->cur_mc_hash = mc_hash;
    298	return 0;
    299}
    300
    301int carl9170_set_operating_mode(struct ar9170 *ar)
    302{
    303	struct ieee80211_vif *vif;
    304	struct ath_common *common = &ar->common;
    305	u8 *mac_addr, *bssid;
    306	u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
    307	u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS |
    308		AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE;
    309	u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
    310		      AR9170_MAC_RX_CTRL_SHORT_FILTER;
    311	u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
    312	int err = 0;
    313
    314	rcu_read_lock();
    315	vif = carl9170_get_main_vif(ar);
    316
    317	if (vif) {
    318		mac_addr = common->macaddr;
    319		bssid = common->curbssid;
    320
    321		switch (vif->type) {
    322		case NL80211_IFTYPE_ADHOC:
    323			cam_mode |= AR9170_MAC_CAM_IBSS;
    324			break;
    325		case NL80211_IFTYPE_MESH_POINT:
    326		case NL80211_IFTYPE_AP:
    327			cam_mode |= AR9170_MAC_CAM_AP;
    328
    329			/* iwlagn 802.11n STA Workaround */
    330			rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
    331			break;
    332		case NL80211_IFTYPE_STATION:
    333			cam_mode |= AR9170_MAC_CAM_STA;
    334			rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
    335			break;
    336		default:
    337			WARN(1, "Unsupported operation mode %x\n", vif->type);
    338			err = -EOPNOTSUPP;
    339			break;
    340		}
    341	} else {
    342		/*
    343		 * Enable monitor mode
    344		 *
    345		 * rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
    346		 * sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
    347		 *
    348		 * When the hardware is in SNIFFER_PROMISC mode,
    349		 * it generates spurious ACKs for every incoming
    350		 * frame. This confuses every peer in the
    351		 * vicinity and the network throughput will suffer
    352		 * badly.
    353		 *
    354		 * Hence, the hardware will be put into station
    355		 * mode and just the rx filters are disabled.
    356		 */
    357		cam_mode |= AR9170_MAC_CAM_STA;
    358		rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
    359		mac_addr = common->macaddr;
    360		bssid = NULL;
    361	}
    362	rcu_read_unlock();
    363
    364	if (err)
    365		return err;
    366
    367	if (ar->rx_software_decryption)
    368		enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
    369
    370	if (ar->sniffer_enabled) {
    371		enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
    372	}
    373
    374	err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
    375	if (err)
    376		return err;
    377
    378	err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
    379	if (err)
    380		return err;
    381
    382	carl9170_regwrite_begin(ar);
    383	carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
    384	carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
    385	carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
    386	carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
    387	carl9170_regwrite_finish();
    388
    389	return carl9170_regwrite_result();
    390}
    391
    392int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
    393{
    394	u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
    395
    396	return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
    397}
    398
    399int carl9170_set_beacon_timers(struct ar9170 *ar)
    400{
    401	struct ieee80211_vif *vif;
    402	u32 v = 0;
    403	u32 pretbtt = 0;
    404
    405	rcu_read_lock();
    406	vif = carl9170_get_main_vif(ar);
    407
    408	if (vif) {
    409		struct carl9170_vif_info *mvif;
    410		mvif = (void *) vif->drv_priv;
    411
    412		if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
    413			ar->global_beacon_int = vif->bss_conf.beacon_int /
    414						ar->beacon_enabled;
    415
    416			SET_VAL(AR9170_MAC_BCN_DTIM, v,
    417				vif->bss_conf.dtim_period);
    418
    419			switch (vif->type) {
    420			case NL80211_IFTYPE_MESH_POINT:
    421			case NL80211_IFTYPE_ADHOC:
    422				v |= AR9170_MAC_BCN_IBSS_MODE;
    423				break;
    424			case NL80211_IFTYPE_AP:
    425				v |= AR9170_MAC_BCN_AP_MODE;
    426				break;
    427			default:
    428				WARN_ON_ONCE(1);
    429				break;
    430			}
    431		} else if (vif->type == NL80211_IFTYPE_STATION) {
    432			ar->global_beacon_int = vif->bss_conf.beacon_int;
    433
    434			SET_VAL(AR9170_MAC_BCN_DTIM, v,
    435				ar->hw->conf.ps_dtim_period);
    436
    437			v |= AR9170_MAC_BCN_STA_PS |
    438			     AR9170_MAC_BCN_PWR_MGT;
    439		}
    440
    441		if (ar->global_beacon_int) {
    442			if (ar->global_beacon_int < 15) {
    443				rcu_read_unlock();
    444				return -ERANGE;
    445			}
    446
    447			ar->global_pretbtt = ar->global_beacon_int -
    448					CARL9170_PRETBTT_KUS;
    449		} else {
    450			ar->global_pretbtt = 0;
    451		}
    452	} else {
    453		ar->global_beacon_int = 0;
    454		ar->global_pretbtt = 0;
    455	}
    456
    457	rcu_read_unlock();
    458
    459	SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
    460	SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
    461	SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
    462
    463	carl9170_regwrite_begin(ar);
    464	carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
    465	carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
    466	carl9170_regwrite_finish();
    467	return carl9170_regwrite_result();
    468}
    469
    470int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
    471			const u8 ktype, const u8 keyidx, const u8 *keydata,
    472			const int keylen)
    473{
    474	struct carl9170_set_key_cmd key = { };
    475	static const u8 bcast[ETH_ALEN] = {
    476		0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    477
    478	mac = mac ? : bcast;
    479
    480	key.user = cpu_to_le16(id);
    481	key.keyId = cpu_to_le16(keyidx);
    482	key.type = cpu_to_le16(ktype);
    483	memcpy(&key.macAddr, mac, ETH_ALEN);
    484	if (keydata)
    485		memcpy(&key.key, keydata, keylen);
    486
    487	return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
    488		sizeof(key), (u8 *)&key, 0, NULL);
    489}
    490
    491int carl9170_disable_key(struct ar9170 *ar, const u8 id)
    492{
    493	struct carl9170_disable_key_cmd key = { };
    494
    495	key.user = cpu_to_le16(id);
    496
    497	return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
    498		sizeof(key), (u8 *)&key, 0, NULL);
    499}
    500
    501int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
    502{
    503	unsigned int power, chains;
    504
    505	if (ar->eeprom.tx_mask != 1)
    506		chains = AR9170_TX_PHY_TXCHAIN_2;
    507	else
    508		chains = AR9170_TX_PHY_TXCHAIN_1;
    509
    510	switch (channel->band) {
    511	case NL80211_BAND_2GHZ:
    512		power = ar->power_2G_ofdm[0] & 0x3f;
    513		break;
    514	case NL80211_BAND_5GHZ:
    515		power = ar->power_5G_leg[0] & 0x3f;
    516		break;
    517	default:
    518		BUG();
    519	}
    520
    521	power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
    522
    523	carl9170_regwrite_begin(ar);
    524	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
    525			  0x3c1e | power << 20 | chains << 26);
    526	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
    527			  power << 5 | chains << 11 |
    528			  power << 21 | chains << 27);
    529	carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
    530			  power << 5 | chains << 11 |
    531			  power << 21 | chains << 27);
    532	carl9170_regwrite_finish();
    533	return carl9170_regwrite_result();
    534}