0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <asm/unaligned.h>
0040
0041 #include "carl9170.h"
0042 #include "cmd.h"
0043
0044 int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
0045 {
0046 u32 val;
0047
0048 if (conf_is_ht40(&ar->hw->conf))
0049 val = 0x010a;
0050 else {
0051 if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
0052 val = 0x105;
0053 else
0054 val = 0x104;
0055 }
0056
0057 return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
0058 }
0059
0060 int carl9170_set_rts_cts_rate(struct ar9170 *ar)
0061 {
0062 u32 rts_rate, cts_rate;
0063
0064 if (conf_is_ht(&ar->hw->conf)) {
0065
0066 rts_rate = 0x1da;
0067 cts_rate = 0x10a;
0068 } else {
0069 if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
0070
0071 rts_rate = 033;
0072 cts_rate = 003;
0073 } else {
0074
0075 rts_rate = 0x1bb;
0076 cts_rate = 0x10b;
0077 }
0078 }
0079
0080 return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
0081 rts_rate | (cts_rate) << 16);
0082 }
0083
0084 int carl9170_set_slot_time(struct ar9170 *ar)
0085 {
0086 struct ieee80211_vif *vif;
0087 u32 slottime = 20;
0088
0089 rcu_read_lock();
0090 vif = carl9170_get_main_vif(ar);
0091 if (!vif) {
0092 rcu_read_unlock();
0093 return 0;
0094 }
0095
0096 if ((ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) ||
0097 vif->bss_conf.use_short_slot)
0098 slottime = 9;
0099
0100 rcu_read_unlock();
0101
0102 return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
0103 slottime << 10);
0104 }
0105
0106 int carl9170_set_mac_rates(struct ar9170 *ar)
0107 {
0108 struct ieee80211_vif *vif;
0109 u32 basic, mandatory;
0110
0111 rcu_read_lock();
0112 vif = carl9170_get_main_vif(ar);
0113
0114 if (!vif) {
0115 rcu_read_unlock();
0116 return 0;
0117 }
0118
0119 basic = (vif->bss_conf.basic_rates & 0xf);
0120 basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
0121 rcu_read_unlock();
0122
0123 if (ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
0124 mandatory = 0xff00;
0125 else
0126 mandatory = 0xff0f;
0127
0128 carl9170_regwrite_begin(ar);
0129 carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
0130 carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
0131 carl9170_regwrite_finish();
0132
0133 return carl9170_regwrite_result();
0134 }
0135
0136 int carl9170_set_qos(struct ar9170 *ar)
0137 {
0138 carl9170_regwrite_begin(ar);
0139
0140 carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
0141 (ar->edcf[0].cw_max << 16));
0142 carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
0143 (ar->edcf[1].cw_max << 16));
0144 carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
0145 (ar->edcf[2].cw_max << 16));
0146 carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
0147 (ar->edcf[3].cw_max << 16));
0148 carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
0149 (ar->edcf[4].cw_max << 16));
0150
0151 carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
0152 ((ar->edcf[0].aifs * 9 + 10)) |
0153 ((ar->edcf[1].aifs * 9 + 10) << 12) |
0154 ((ar->edcf[2].aifs * 9 + 10) << 24));
0155 carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
0156 ((ar->edcf[2].aifs * 9 + 10) >> 8) |
0157 ((ar->edcf[3].aifs * 9 + 10) << 4) |
0158 ((ar->edcf[4].aifs * 9 + 10) << 16));
0159
0160 carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
0161 ar->edcf[0].txop | ar->edcf[1].txop << 16);
0162 carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
0163 ar->edcf[2].txop | ar->edcf[3].txop << 16 |
0164 ar->edcf[4].txop << 24);
0165
0166 carl9170_regwrite_finish();
0167
0168 return carl9170_regwrite_result();
0169 }
0170
0171 int carl9170_init_mac(struct ar9170 *ar)
0172 {
0173 carl9170_regwrite_begin(ar);
0174
0175
0176 carl9170_regwrite(0x1c3600, 0x3);
0177
0178 carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
0179
0180 carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
0181
0182 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
0183 AR9170_MAC_FTF_MONITOR);
0184
0185
0186 carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
0187 AR9170_MAC_SNIFFER_DEFAULTS);
0188
0189 carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
0190
0191 carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
0192 carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
0193 carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
0194
0195
0196 carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
0197
0198
0199 carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
0200
0201
0202
0203 carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
0204
0205 carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
0206
0207
0208 carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
0209 carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
0210
0211 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
0212 AR9170_MAC_FTF_DEFAULTS);
0213
0214 carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
0215 AR9170_MAC_RX_CTRL_DEAGG |
0216 AR9170_MAC_RX_CTRL_SHORT_FILTER);
0217
0218
0219 carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
0220 carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
0221 carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
0222
0223
0224 carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
0225
0226 carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
0227
0228
0229 carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
0230
0231
0232 carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
0233
0234
0235 carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
0236
0237 carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
0238 AR9170_MAC_FCS_FIFO_PROT);
0239
0240
0241 carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
0242 0x141e0f48);
0243
0244
0245 carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
0246 carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
0247
0248
0249 carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
0250 carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
0251
0252 carl9170_regwrite_finish();
0253
0254 return carl9170_regwrite_result();
0255 }
0256
0257 static int carl9170_set_mac_reg(struct ar9170 *ar,
0258 const u32 reg, const u8 *mac)
0259 {
0260 static const u8 zero[ETH_ALEN] = { 0 };
0261
0262 if (!mac)
0263 mac = zero;
0264
0265 carl9170_regwrite_begin(ar);
0266
0267 carl9170_regwrite(reg, get_unaligned_le32(mac));
0268 carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
0269
0270 carl9170_regwrite_finish();
0271
0272 return carl9170_regwrite_result();
0273 }
0274
0275 int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
0276 const u8 *mac)
0277 {
0278 if (WARN_ON(id >= ar->fw.vif_num))
0279 return -EINVAL;
0280
0281 return carl9170_set_mac_reg(ar,
0282 AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
0283 }
0284
0285 int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
0286 {
0287 int err;
0288
0289 carl9170_regwrite_begin(ar);
0290 carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
0291 carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
0292 carl9170_regwrite_finish();
0293 err = carl9170_regwrite_result();
0294 if (err)
0295 return err;
0296
0297 ar->cur_mc_hash = mc_hash;
0298 return 0;
0299 }
0300
0301 int carl9170_set_operating_mode(struct ar9170 *ar)
0302 {
0303 struct ieee80211_vif *vif;
0304 struct ath_common *common = &ar->common;
0305 u8 *mac_addr, *bssid;
0306 u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
0307 u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS |
0308 AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE;
0309 u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
0310 AR9170_MAC_RX_CTRL_SHORT_FILTER;
0311 u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
0312 int err = 0;
0313
0314 rcu_read_lock();
0315 vif = carl9170_get_main_vif(ar);
0316
0317 if (vif) {
0318 mac_addr = common->macaddr;
0319 bssid = common->curbssid;
0320
0321 switch (vif->type) {
0322 case NL80211_IFTYPE_ADHOC:
0323 cam_mode |= AR9170_MAC_CAM_IBSS;
0324 break;
0325 case NL80211_IFTYPE_MESH_POINT:
0326 case NL80211_IFTYPE_AP:
0327 cam_mode |= AR9170_MAC_CAM_AP;
0328
0329
0330 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0331 break;
0332 case NL80211_IFTYPE_STATION:
0333 cam_mode |= AR9170_MAC_CAM_STA;
0334 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0335 break;
0336 default:
0337 WARN(1, "Unsupported operation mode %x\n", vif->type);
0338 err = -EOPNOTSUPP;
0339 break;
0340 }
0341 } else {
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 cam_mode |= AR9170_MAC_CAM_STA;
0358 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0359 mac_addr = common->macaddr;
0360 bssid = NULL;
0361 }
0362 rcu_read_unlock();
0363
0364 if (err)
0365 return err;
0366
0367 if (ar->rx_software_decryption)
0368 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
0369
0370 if (ar->sniffer_enabled) {
0371 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
0372 }
0373
0374 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
0375 if (err)
0376 return err;
0377
0378 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
0379 if (err)
0380 return err;
0381
0382 carl9170_regwrite_begin(ar);
0383 carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
0384 carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
0385 carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
0386 carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
0387 carl9170_regwrite_finish();
0388
0389 return carl9170_regwrite_result();
0390 }
0391
0392 int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
0393 {
0394 u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
0395
0396 return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
0397 }
0398
0399 int carl9170_set_beacon_timers(struct ar9170 *ar)
0400 {
0401 struct ieee80211_vif *vif;
0402 u32 v = 0;
0403 u32 pretbtt = 0;
0404
0405 rcu_read_lock();
0406 vif = carl9170_get_main_vif(ar);
0407
0408 if (vif) {
0409 struct carl9170_vif_info *mvif;
0410 mvif = (void *) vif->drv_priv;
0411
0412 if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
0413 ar->global_beacon_int = vif->bss_conf.beacon_int /
0414 ar->beacon_enabled;
0415
0416 SET_VAL(AR9170_MAC_BCN_DTIM, v,
0417 vif->bss_conf.dtim_period);
0418
0419 switch (vif->type) {
0420 case NL80211_IFTYPE_MESH_POINT:
0421 case NL80211_IFTYPE_ADHOC:
0422 v |= AR9170_MAC_BCN_IBSS_MODE;
0423 break;
0424 case NL80211_IFTYPE_AP:
0425 v |= AR9170_MAC_BCN_AP_MODE;
0426 break;
0427 default:
0428 WARN_ON_ONCE(1);
0429 break;
0430 }
0431 } else if (vif->type == NL80211_IFTYPE_STATION) {
0432 ar->global_beacon_int = vif->bss_conf.beacon_int;
0433
0434 SET_VAL(AR9170_MAC_BCN_DTIM, v,
0435 ar->hw->conf.ps_dtim_period);
0436
0437 v |= AR9170_MAC_BCN_STA_PS |
0438 AR9170_MAC_BCN_PWR_MGT;
0439 }
0440
0441 if (ar->global_beacon_int) {
0442 if (ar->global_beacon_int < 15) {
0443 rcu_read_unlock();
0444 return -ERANGE;
0445 }
0446
0447 ar->global_pretbtt = ar->global_beacon_int -
0448 CARL9170_PRETBTT_KUS;
0449 } else {
0450 ar->global_pretbtt = 0;
0451 }
0452 } else {
0453 ar->global_beacon_int = 0;
0454 ar->global_pretbtt = 0;
0455 }
0456
0457 rcu_read_unlock();
0458
0459 SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
0460 SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
0461 SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
0462
0463 carl9170_regwrite_begin(ar);
0464 carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
0465 carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
0466 carl9170_regwrite_finish();
0467 return carl9170_regwrite_result();
0468 }
0469
0470 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
0471 const u8 ktype, const u8 keyidx, const u8 *keydata,
0472 const int keylen)
0473 {
0474 struct carl9170_set_key_cmd key = { };
0475 static const u8 bcast[ETH_ALEN] = {
0476 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0477
0478 mac = mac ? : bcast;
0479
0480 key.user = cpu_to_le16(id);
0481 key.keyId = cpu_to_le16(keyidx);
0482 key.type = cpu_to_le16(ktype);
0483 memcpy(&key.macAddr, mac, ETH_ALEN);
0484 if (keydata)
0485 memcpy(&key.key, keydata, keylen);
0486
0487 return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
0488 sizeof(key), (u8 *)&key, 0, NULL);
0489 }
0490
0491 int carl9170_disable_key(struct ar9170 *ar, const u8 id)
0492 {
0493 struct carl9170_disable_key_cmd key = { };
0494
0495 key.user = cpu_to_le16(id);
0496
0497 return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
0498 sizeof(key), (u8 *)&key, 0, NULL);
0499 }
0500
0501 int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
0502 {
0503 unsigned int power, chains;
0504
0505 if (ar->eeprom.tx_mask != 1)
0506 chains = AR9170_TX_PHY_TXCHAIN_2;
0507 else
0508 chains = AR9170_TX_PHY_TXCHAIN_1;
0509
0510 switch (channel->band) {
0511 case NL80211_BAND_2GHZ:
0512 power = ar->power_2G_ofdm[0] & 0x3f;
0513 break;
0514 case NL80211_BAND_5GHZ:
0515 power = ar->power_5G_leg[0] & 0x3f;
0516 break;
0517 default:
0518 BUG();
0519 }
0520
0521 power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
0522
0523 carl9170_regwrite_begin(ar);
0524 carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
0525 0x3c1e | power << 20 | chains << 26);
0526 carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
0527 power << 5 | chains << 11 |
0528 power << 21 | chains << 27);
0529 carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
0530 power << 5 | chains << 11 |
0531 power << 21 | chains << 27);
0532 carl9170_regwrite_finish();
0533 return carl9170_regwrite_result();
0534 }