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 == IEEE80211_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 == IEEE80211_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 == IEEE80211_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 == IEEE80211_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_WDS: 333 cam_mode |= AR9170_MAC_CAM_AP_WDS; 334 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 335 break; 336 case NL80211_IFTYPE_STATION: 337 cam_mode |= AR9170_MAC_CAM_STA; 338 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 339 break; 340 default: 341 WARN(1, "Unsupported operation mode %x\n", vif->type); 342 err = -EOPNOTSUPP; 343 break; 344 } 345 } else { 346 /* 347 * Enable monitor mode 348 * 349 * rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; 350 * sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; 351 * 352 * When the hardware is in SNIFFER_PROMISC mode, 353 * it generates spurious ACKs for every incoming 354 * frame. This confuses every peer in the 355 * vicinity and the network throughput will suffer 356 * badly. 357 * 358 * Hence, the hardware will be put into station 359 * mode and just the rx filters are disabled. 360 */ 361 cam_mode |= AR9170_MAC_CAM_STA; 362 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 363 mac_addr = common->macaddr; 364 bssid = NULL; 365 } 366 rcu_read_unlock(); 367 368 if (err) 369 return err; 370 371 if (ar->rx_software_decryption) 372 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 373 374 if (ar->sniffer_enabled) { 375 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 376 } 377 378 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); 379 if (err) 380 return err; 381 382 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); 383 if (err) 384 return err; 385 386 carl9170_regwrite_begin(ar); 387 carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); 388 carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); 389 carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); 390 carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); 391 carl9170_regwrite_finish(); 392 393 return carl9170_regwrite_result(); 394} 395 396int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) 397{ 398 u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); 399 400 return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); 401} 402 403int carl9170_set_beacon_timers(struct ar9170 *ar) 404{ 405 struct ieee80211_vif *vif; 406 u32 v = 0; 407 u32 pretbtt = 0; 408 409 rcu_read_lock(); 410 vif = carl9170_get_main_vif(ar); 411 412 if (vif) { 413 struct carl9170_vif_info *mvif; 414 mvif = (void *) vif->drv_priv; 415 416 if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { 417 ar->global_beacon_int = vif->bss_conf.beacon_int / 418 ar->beacon_enabled; 419 420 SET_VAL(AR9170_MAC_BCN_DTIM, v, 421 vif->bss_conf.dtim_period); 422 423 switch (vif->type) { 424 case NL80211_IFTYPE_MESH_POINT: 425 case NL80211_IFTYPE_ADHOC: 426 v |= AR9170_MAC_BCN_IBSS_MODE; 427 break; 428 case NL80211_IFTYPE_AP: 429 v |= AR9170_MAC_BCN_AP_MODE; 430 break; 431 default: 432 WARN_ON_ONCE(1); 433 break; 434 } 435 } else if (vif->type == NL80211_IFTYPE_STATION) { 436 ar->global_beacon_int = vif->bss_conf.beacon_int; 437 438 SET_VAL(AR9170_MAC_BCN_DTIM, v, 439 ar->hw->conf.ps_dtim_period); 440 441 v |= AR9170_MAC_BCN_STA_PS | 442 AR9170_MAC_BCN_PWR_MGT; 443 } 444 445 if (ar->global_beacon_int) { 446 if (ar->global_beacon_int < 15) { 447 rcu_read_unlock(); 448 return -ERANGE; 449 } 450 451 ar->global_pretbtt = ar->global_beacon_int - 452 CARL9170_PRETBTT_KUS; 453 } else { 454 ar->global_pretbtt = 0; 455 } 456 } else { 457 ar->global_beacon_int = 0; 458 ar->global_pretbtt = 0; 459 } 460 461 rcu_read_unlock(); 462 463 SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); 464 SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); 465 SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); 466 467 carl9170_regwrite_begin(ar); 468 carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); 469 carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); 470 carl9170_regwrite_finish(); 471 return carl9170_regwrite_result(); 472} 473 474int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 475 const u8 ktype, const u8 keyidx, const u8 *keydata, 476 const int keylen) 477{ 478 struct carl9170_set_key_cmd key = { }; 479 static const u8 bcast[ETH_ALEN] = { 480 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 481 482 mac = mac ? : bcast; 483 484 key.user = cpu_to_le16(id); 485 key.keyId = cpu_to_le16(keyidx); 486 key.type = cpu_to_le16(ktype); 487 memcpy(&key.macAddr, mac, ETH_ALEN); 488 if (keydata) 489 memcpy(&key.key, keydata, keylen); 490 491 return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, 492 sizeof(key), (u8 *)&key, 0, NULL); 493} 494 495int carl9170_disable_key(struct ar9170 *ar, const u8 id) 496{ 497 struct carl9170_disable_key_cmd key = { }; 498 499 key.user = cpu_to_le16(id); 500 501 return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, 502 sizeof(key), (u8 *)&key, 0, NULL); 503} 504 505int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) 506{ 507 unsigned int power, chains; 508 509 if (ar->eeprom.tx_mask != 1) 510 chains = AR9170_TX_PHY_TXCHAIN_2; 511 else 512 chains = AR9170_TX_PHY_TXCHAIN_1; 513 514 switch (channel->band) { 515 case IEEE80211_BAND_2GHZ: 516 power = ar->power_2G_ofdm[0] & 0x3f; 517 break; 518 case IEEE80211_BAND_5GHZ: 519 power = ar->power_5G_leg[0] & 0x3f; 520 break; 521 default: 522 BUG_ON(1); 523 } 524 525 power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); 526 527 carl9170_regwrite_begin(ar); 528 carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 529 0x3c1e | power << 20 | chains << 26); 530 carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, 531 power << 5 | chains << 11 | 532 power << 21 | chains << 27); 533 carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, 534 power << 5 | chains << 11 | 535 power << 21 | chains << 27); 536 carl9170_regwrite_finish(); 537 return carl9170_regwrite_result(); 538} 539