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}