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 44 int 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.channel->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 60 int 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.channel->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 84 int 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.channel->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 106 int 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.channel->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 136 int 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 171 int 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 257 static 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 275 int 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 285 int 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 301 int 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 u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | 309 AR9170_MAC_RX_CTRL_SHORT_FILTER; 310 u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; 311 int err = 0; 312 313 rcu_read_lock(); 314 vif = carl9170_get_main_vif(ar); 315 316 if (vif) { 317 mac_addr = common->macaddr; 318 bssid = common->curbssid; 319 320 switch (vif->type) { 321 case NL80211_IFTYPE_MESH_POINT: 322 case NL80211_IFTYPE_ADHOC: 323 cam_mode |= AR9170_MAC_CAM_IBSS; 324 break; 325 case NL80211_IFTYPE_AP: 326 cam_mode |= AR9170_MAC_CAM_AP; 327 328 /* iwlagn 802.11n STA Workaround */ 329 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 330 break; 331 case NL80211_IFTYPE_WDS: 332 cam_mode |= AR9170_MAC_CAM_AP_WDS; 333 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 334 break; 335 case NL80211_IFTYPE_STATION: 336 cam_mode |= AR9170_MAC_CAM_STA; 337 rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; 338 break; 339 default: 340 WARN(1, "Unsupported operation mode %x\n", vif->type); 341 err = -EOPNOTSUPP; 342 break; 343 } 344 } else { 345 mac_addr = NULL; 346 bssid = NULL; 347 } 348 rcu_read_unlock(); 349 350 if (err) 351 return err; 352 353 if (ar->rx_software_decryption) 354 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 355 356 if (ar->sniffer_enabled) { 357 rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; 358 sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; 359 enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; 360 } 361 362 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); 363 if (err) 364 return err; 365 366 err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); 367 if (err) 368 return err; 369 370 carl9170_regwrite_begin(ar); 371 carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); 372 carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); 373 carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); 374 carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); 375 carl9170_regwrite_finish(); 376 377 return carl9170_regwrite_result(); 378 } 379 380 int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) 381 { 382 u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); 383 384 return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); 385 } 386 387 int carl9170_set_beacon_timers(struct ar9170 *ar) 388 { 389 struct ieee80211_vif *vif; 390 u32 v = 0; 391 u32 pretbtt = 0; 392 393 rcu_read_lock(); 394 vif = carl9170_get_main_vif(ar); 395 396 if (vif) { 397 struct carl9170_vif_info *mvif; 398 mvif = (void *) vif->drv_priv; 399 400 if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { 401 ar->global_beacon_int = vif->bss_conf.beacon_int / 402 ar->beacon_enabled; 403 404 SET_VAL(AR9170_MAC_BCN_DTIM, v, 405 vif->bss_conf.dtim_period); 406 407 switch (vif->type) { 408 case NL80211_IFTYPE_MESH_POINT: 409 case NL80211_IFTYPE_ADHOC: 410 v |= AR9170_MAC_BCN_IBSS_MODE; 411 break; 412 case NL80211_IFTYPE_AP: 413 v |= AR9170_MAC_BCN_AP_MODE; 414 break; 415 default: 416 WARN_ON_ONCE(1); 417 break; 418 } 419 } else if (vif->type == NL80211_IFTYPE_STATION) { 420 ar->global_beacon_int = vif->bss_conf.beacon_int; 421 422 SET_VAL(AR9170_MAC_BCN_DTIM, v, 423 ar->hw->conf.ps_dtim_period); 424 425 v |= AR9170_MAC_BCN_STA_PS | 426 AR9170_MAC_BCN_PWR_MGT; 427 } 428 429 if (ar->global_beacon_int) { 430 if (ar->global_beacon_int < 15) { 431 rcu_read_unlock(); 432 return -ERANGE; 433 } 434 435 ar->global_pretbtt = ar->global_beacon_int - 436 CARL9170_PRETBTT_KUS; 437 } else { 438 ar->global_pretbtt = 0; 439 } 440 } else { 441 ar->global_beacon_int = 0; 442 ar->global_pretbtt = 0; 443 } 444 445 rcu_read_unlock(); 446 447 SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); 448 SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); 449 SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); 450 451 carl9170_regwrite_begin(ar); 452 carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); 453 carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); 454 carl9170_regwrite_finish(); 455 return carl9170_regwrite_result(); 456 } 457 458 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 459 const u8 ktype, const u8 keyidx, const u8 *keydata, 460 const int keylen) 461 { 462 struct carl9170_set_key_cmd key = { }; 463 static const u8 bcast[ETH_ALEN] = { 464 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 465 466 mac = mac ? : bcast; 467 468 key.user = cpu_to_le16(id); 469 key.keyId = cpu_to_le16(keyidx); 470 key.type = cpu_to_le16(ktype); 471 memcpy(&key.macAddr, mac, ETH_ALEN); 472 if (keydata) 473 memcpy(&key.key, keydata, keylen); 474 475 return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, 476 sizeof(key), (u8 *)&key, 0, NULL); 477 } 478 479 int carl9170_disable_key(struct ar9170 *ar, const u8 id) 480 { 481 struct carl9170_disable_key_cmd key = { }; 482 483 key.user = cpu_to_le16(id); 484 485 return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, 486 sizeof(key), (u8 *)&key, 0, NULL); 487 } 488