1 /*- 2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 3 * Copyright (c) 2004-2005 Atheros Communications, Inc. 4 * Copyright (c) 2006 Devicescape Software, Inc. 5 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> 7 * Copyright (c) 2010 Bruno Randolf <br1@einfach.org> 8 * 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 19 * redistribution must be conditioned upon including a substantially 20 * similar Disclaimer requirement for further binary redistribution. 21 * 3. Neither the names of the above-listed copyright holders nor the names 22 * of any contributors may be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * Alternatively, this software may be distributed under the terms of the 26 * GNU General Public License ("GPL") version 2 as published by the Free 27 * Software Foundation. 28 * 29 * NO WARRANTY 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 33 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 34 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 35 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 40 * THE POSSIBILITY OF SUCH DAMAGES. 41 * 42 */ 43 44 #include <net/mac80211.h> 45 #include <asm/unaligned.h> 46 47 #include "ath5k.h" 48 #include "base.h" 49 #include "reg.h" 50 51 /********************\ 52 * Mac80211 functions * 53 \********************/ 54 55 static void 56 ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 57 { 58 struct ath5k_hw *ah = hw->priv; 59 u16 qnum = skb_get_queue_mapping(skb); 60 61 if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) { 62 dev_kfree_skb_any(skb); 63 return; 64 } 65 66 ath5k_tx_queue(hw, skb, &ah->txqs[qnum]); 67 } 68 69 70 static int 71 ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 72 { 73 struct ath5k_hw *ah = hw->priv; 74 int ret; 75 struct ath5k_vif *avf = (void *)vif->drv_priv; 76 77 mutex_lock(&ah->lock); 78 79 if ((vif->type == NL80211_IFTYPE_AP || 80 vif->type == NL80211_IFTYPE_ADHOC) 81 && (ah->num_ap_vifs + ah->num_adhoc_vifs) >= ATH_BCBUF) { 82 ret = -ELNRNG; 83 goto end; 84 } 85 86 /* Don't allow other interfaces if one ad-hoc is configured. 87 * TODO: Fix the problems with ad-hoc and multiple other interfaces. 88 * We would need to operate the HW in ad-hoc mode to allow TSF updates 89 * for the IBSS, but this breaks with additional AP or STA interfaces 90 * at the moment. */ 91 if (ah->num_adhoc_vifs || 92 (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { 93 ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); 94 ret = -ELNRNG; 95 goto end; 96 } 97 98 switch (vif->type) { 99 case NL80211_IFTYPE_AP: 100 case NL80211_IFTYPE_STATION: 101 case NL80211_IFTYPE_ADHOC: 102 case NL80211_IFTYPE_MESH_POINT: 103 avf->opmode = vif->type; 104 break; 105 default: 106 ret = -EOPNOTSUPP; 107 goto end; 108 } 109 110 ah->nvifs++; 111 ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); 112 113 /* Assign the vap/adhoc to a beacon xmit slot. */ 114 if ((avf->opmode == NL80211_IFTYPE_AP) || 115 (avf->opmode == NL80211_IFTYPE_ADHOC) || 116 (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { 117 int slot; 118 119 WARN_ON(list_empty(&ah->bcbuf)); 120 avf->bbuf = list_first_entry(&ah->bcbuf, struct ath5k_buf, 121 list); 122 list_del(&avf->bbuf->list); 123 124 avf->bslot = 0; 125 for (slot = 0; slot < ATH_BCBUF; slot++) { 126 if (!ah->bslot[slot]) { 127 avf->bslot = slot; 128 break; 129 } 130 } 131 BUG_ON(ah->bslot[avf->bslot] != NULL); 132 ah->bslot[avf->bslot] = vif; 133 if (avf->opmode == NL80211_IFTYPE_AP) 134 ah->num_ap_vifs++; 135 else if (avf->opmode == NL80211_IFTYPE_ADHOC) 136 ah->num_adhoc_vifs++; 137 else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) 138 ah->num_mesh_vifs++; 139 } 140 141 /* Any MAC address is fine, all others are included through the 142 * filter. 143 */ 144 ath5k_hw_set_lladdr(ah, vif->addr); 145 146 ath5k_update_bssid_mask_and_opmode(ah, vif); 147 ret = 0; 148 end: 149 mutex_unlock(&ah->lock); 150 return ret; 151 } 152 153 154 static void 155 ath5k_remove_interface(struct ieee80211_hw *hw, 156 struct ieee80211_vif *vif) 157 { 158 struct ath5k_hw *ah = hw->priv; 159 struct ath5k_vif *avf = (void *)vif->drv_priv; 160 unsigned int i; 161 162 mutex_lock(&ah->lock); 163 ah->nvifs--; 164 165 if (avf->bbuf) { 166 ath5k_txbuf_free_skb(ah, avf->bbuf); 167 list_add_tail(&avf->bbuf->list, &ah->bcbuf); 168 for (i = 0; i < ATH_BCBUF; i++) { 169 if (ah->bslot[i] == vif) { 170 ah->bslot[i] = NULL; 171 break; 172 } 173 } 174 avf->bbuf = NULL; 175 } 176 if (avf->opmode == NL80211_IFTYPE_AP) 177 ah->num_ap_vifs--; 178 else if (avf->opmode == NL80211_IFTYPE_ADHOC) 179 ah->num_adhoc_vifs--; 180 else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) 181 ah->num_mesh_vifs--; 182 183 ath5k_update_bssid_mask_and_opmode(ah, NULL); 184 mutex_unlock(&ah->lock); 185 } 186 187 188 /* 189 * TODO: Phy disable/diversity etc 190 */ 191 static int 192 ath5k_config(struct ieee80211_hw *hw, u32 changed) 193 { 194 struct ath5k_hw *ah = hw->priv; 195 struct ieee80211_conf *conf = &hw->conf; 196 int ret = 0; 197 int i; 198 199 mutex_lock(&ah->lock); 200 201 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 202 ret = ath5k_chan_set(ah, conf->channel); 203 if (ret < 0) 204 goto unlock; 205 } 206 207 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 208 (ah->power_level != conf->power_level)) { 209 ah->power_level = conf->power_level; 210 211 /* Half dB steps */ 212 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); 213 } 214 215 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { 216 ah->ah_retry_long = conf->long_frame_max_tx_count; 217 ah->ah_retry_short = conf->short_frame_max_tx_count; 218 219 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) 220 ath5k_hw_set_tx_retry_limits(ah, i); 221 } 222 223 /* TODO: 224 * 1) Move this on config_interface and handle each case 225 * separately eg. when we have only one STA vif, use 226 * AR5K_ANTMODE_SINGLE_AP 227 * 228 * 2) Allow the user to change antenna mode eg. when only 229 * one antenna is present 230 * 231 * 3) Allow the user to set default/tx antenna when possible 232 * 233 * 4) Default mode should handle 90% of the cases, together 234 * with fixed a/b and single AP modes we should be able to 235 * handle 99%. Sectored modes are extreme cases and i still 236 * haven't found a usage for them. If we decide to support them, 237 * then we must allow the user to set how many tx antennas we 238 * have available 239 */ 240 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 241 242 unlock: 243 mutex_unlock(&ah->lock); 244 return ret; 245 } 246 247 248 static void 249 ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 250 struct ieee80211_bss_conf *bss_conf, u32 changes) 251 { 252 struct ath5k_vif *avf = (void *)vif->drv_priv; 253 struct ath5k_hw *ah = hw->priv; 254 struct ath_common *common = ath5k_hw_common(ah); 255 unsigned long flags; 256 257 mutex_lock(&ah->lock); 258 259 if (changes & BSS_CHANGED_BSSID) { 260 /* Cache for later use during resets */ 261 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 262 common->curaid = 0; 263 ath5k_hw_set_bssid(ah); 264 mmiowb(); 265 } 266 267 if (changes & BSS_CHANGED_BEACON_INT) 268 ah->bintval = bss_conf->beacon_int; 269 270 if (changes & BSS_CHANGED_ERP_SLOT) { 271 int slot_time; 272 273 ah->ah_short_slot = bss_conf->use_short_slot; 274 slot_time = ath5k_hw_get_default_slottime(ah) + 275 3 * ah->ah_coverage_class; 276 ath5k_hw_set_ifs_intervals(ah, slot_time); 277 } 278 279 if (changes & BSS_CHANGED_ASSOC) { 280 avf->assoc = bss_conf->assoc; 281 if (bss_conf->assoc) 282 ah->assoc = bss_conf->assoc; 283 else 284 ah->assoc = ath5k_any_vif_assoc(ah); 285 286 if (ah->opmode == NL80211_IFTYPE_STATION) 287 ath5k_set_beacon_filter(hw, ah->assoc); 288 ath5k_hw_set_ledstate(ah, ah->assoc ? 289 AR5K_LED_ASSOC : AR5K_LED_INIT); 290 if (bss_conf->assoc) { 291 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, 292 "Bss Info ASSOC %d, bssid: %pM\n", 293 bss_conf->aid, common->curbssid); 294 common->curaid = bss_conf->aid; 295 ath5k_hw_set_bssid(ah); 296 /* Once ANI is available you would start it here */ 297 } 298 } 299 300 if (changes & BSS_CHANGED_BEACON) { 301 spin_lock_irqsave(&ah->block, flags); 302 ath5k_beacon_update(hw, vif); 303 spin_unlock_irqrestore(&ah->block, flags); 304 } 305 306 if (changes & BSS_CHANGED_BEACON_ENABLED) 307 ah->enable_beacon = bss_conf->enable_beacon; 308 309 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | 310 BSS_CHANGED_BEACON_INT)) 311 ath5k_beacon_config(ah); 312 313 mutex_unlock(&ah->lock); 314 } 315 316 317 static u64 318 ath5k_prepare_multicast(struct ieee80211_hw *hw, 319 struct netdev_hw_addr_list *mc_list) 320 { 321 u32 mfilt[2], val; 322 u8 pos; 323 struct netdev_hw_addr *ha; 324 325 mfilt[0] = 0; 326 mfilt[1] = 1; 327 328 netdev_hw_addr_list_for_each(ha, mc_list) { 329 /* calculate XOR of eight 6-bit values */ 330 val = get_unaligned_le32(ha->addr + 0); 331 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 332 val = get_unaligned_le32(ha->addr + 3); 333 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 334 pos &= 0x3f; 335 mfilt[pos / 32] |= (1 << (pos % 32)); 336 /* XXX: we might be able to just do this instead, 337 * but not sure, needs testing, if we do use this we'd 338 * need to inform below not to reset the mcast */ 339 /* ath5k_hw_set_mcast_filterindex(ah, 340 * ha->addr[5]); */ 341 } 342 343 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 344 } 345 346 347 /* 348 * o always accept unicast, broadcast, and multicast traffic 349 * o multicast traffic for all BSSIDs will be enabled if mac80211 350 * says it should be 351 * o maintain current state of phy ofdm or phy cck error reception. 352 * If the hardware detects any of these type of errors then 353 * ath5k_hw_get_rx_filter() will pass to us the respective 354 * hardware filters to be able to receive these type of frames. 355 * o probe request frames are accepted only when operating in 356 * hostap, adhoc, or monitor modes 357 * o enable promiscuous mode according to the interface state 358 * o accept beacons: 359 * - when operating in adhoc mode so the 802.11 layer creates 360 * node table entries for peers, 361 * - when operating in station mode for collecting rssi data when 362 * the station is otherwise quiet, or 363 * - when scanning 364 */ 365 static void 366 ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, 367 unsigned int *new_flags, u64 multicast) 368 { 369 #define SUPPORTED_FIF_FLAGS \ 370 (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 371 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 372 FIF_BCN_PRBRESP_PROMISC) 373 374 struct ath5k_hw *ah = hw->priv; 375 u32 mfilt[2], rfilt; 376 struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ 377 378 mutex_lock(&ah->lock); 379 380 mfilt[0] = multicast; 381 mfilt[1] = multicast >> 32; 382 383 /* Only deal with supported flags */ 384 changed_flags &= SUPPORTED_FIF_FLAGS; 385 *new_flags &= SUPPORTED_FIF_FLAGS; 386 387 /* If HW detects any phy or radar errors, leave those filters on. 388 * Also, always enable Unicast, Broadcasts and Multicast 389 * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ 390 rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | 391 (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | 392 AR5K_RX_FILTER_MCAST); 393 394 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { 395 if (*new_flags & FIF_PROMISC_IN_BSS) 396 __set_bit(ATH_STAT_PROMISC, ah->status); 397 else 398 __clear_bit(ATH_STAT_PROMISC, ah->status); 399 } 400 401 if (test_bit(ATH_STAT_PROMISC, ah->status)) 402 rfilt |= AR5K_RX_FILTER_PROM; 403 404 /* Note, AR5K_RX_FILTER_MCAST is already enabled */ 405 if (*new_flags & FIF_ALLMULTI) { 406 mfilt[0] = ~0; 407 mfilt[1] = ~0; 408 } 409 410 /* This is the best we can do */ 411 if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) 412 rfilt |= AR5K_RX_FILTER_PHYERR; 413 414 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons 415 * and probes for any BSSID */ 416 if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1)) 417 rfilt |= AR5K_RX_FILTER_BEACON; 418 419 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not 420 * set we should only pass on control frames for this 421 * station. This needs testing. I believe right now this 422 * enables *all* control frames, which is OK.. but 423 * but we should see if we can improve on granularity */ 424 if (*new_flags & FIF_CONTROL) 425 rfilt |= AR5K_RX_FILTER_CONTROL; 426 427 /* Additional settings per mode -- this is per ath5k */ 428 429 /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ 430 431 switch (ah->opmode) { 432 case NL80211_IFTYPE_MESH_POINT: 433 rfilt |= AR5K_RX_FILTER_CONTROL | 434 AR5K_RX_FILTER_BEACON | 435 AR5K_RX_FILTER_PROBEREQ | 436 AR5K_RX_FILTER_PROM; 437 break; 438 case NL80211_IFTYPE_AP: 439 case NL80211_IFTYPE_ADHOC: 440 rfilt |= AR5K_RX_FILTER_PROBEREQ | 441 AR5K_RX_FILTER_BEACON; 442 break; 443 case NL80211_IFTYPE_STATION: 444 if (ah->assoc) 445 rfilt |= AR5K_RX_FILTER_BEACON; 446 default: 447 break; 448 } 449 450 iter_data.hw_macaddr = NULL; 451 iter_data.n_stas = 0; 452 iter_data.need_set_hw_addr = false; 453 ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, 454 &iter_data); 455 456 /* Set up RX Filter */ 457 if (iter_data.n_stas > 1) { 458 /* If you have multiple STA interfaces connected to 459 * different APs, ARPs are not received (most of the time?) 460 * Enabling PROMISC appears to fix that problem. 461 */ 462 rfilt |= AR5K_RX_FILTER_PROM; 463 } 464 465 /* Set filters */ 466 ath5k_hw_set_rx_filter(ah, rfilt); 467 468 /* Set multicast bits */ 469 ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); 470 /* Set the cached hw filter flags, this will later actually 471 * be set in HW */ 472 ah->filter_flags = rfilt; 473 474 mutex_unlock(&ah->lock); 475 } 476 477 478 static int 479 ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 480 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 481 struct ieee80211_key_conf *key) 482 { 483 struct ath5k_hw *ah = hw->priv; 484 struct ath_common *common = ath5k_hw_common(ah); 485 int ret = 0; 486 487 if (ath5k_modparam_nohwcrypt) 488 return -EOPNOTSUPP; 489 490 if (vif->type == NL80211_IFTYPE_ADHOC && 491 (key->cipher == WLAN_CIPHER_SUITE_TKIP || 492 key->cipher == WLAN_CIPHER_SUITE_CCMP) && 493 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { 494 /* don't program group keys when using IBSS_RSN */ 495 return -EOPNOTSUPP; 496 } 497 498 switch (key->cipher) { 499 case WLAN_CIPHER_SUITE_WEP40: 500 case WLAN_CIPHER_SUITE_WEP104: 501 case WLAN_CIPHER_SUITE_TKIP: 502 break; 503 case WLAN_CIPHER_SUITE_CCMP: 504 if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) 505 break; 506 return -EOPNOTSUPP; 507 default: 508 WARN_ON(1); 509 return -EINVAL; 510 } 511 512 mutex_lock(&ah->lock); 513 514 switch (cmd) { 515 case SET_KEY: 516 ret = ath_key_config(common, vif, sta, key); 517 if (ret >= 0) { 518 key->hw_key_idx = ret; 519 /* push IV and Michael MIC generation to stack */ 520 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 521 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 522 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; 523 if (key->cipher == WLAN_CIPHER_SUITE_CCMP) 524 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; 525 ret = 0; 526 } 527 break; 528 case DISABLE_KEY: 529 ath_key_delete(common, key); 530 break; 531 default: 532 ret = -EINVAL; 533 } 534 535 mmiowb(); 536 mutex_unlock(&ah->lock); 537 return ret; 538 } 539 540 541 static void 542 ath5k_sw_scan_start(struct ieee80211_hw *hw) 543 { 544 struct ath5k_hw *ah = hw->priv; 545 if (!ah->assoc) 546 ath5k_hw_set_ledstate(ah, AR5K_LED_SCAN); 547 } 548 549 550 static void 551 ath5k_sw_scan_complete(struct ieee80211_hw *hw) 552 { 553 struct ath5k_hw *ah = hw->priv; 554 ath5k_hw_set_ledstate(ah, ah->assoc ? 555 AR5K_LED_ASSOC : AR5K_LED_INIT); 556 } 557 558 559 static int 560 ath5k_get_stats(struct ieee80211_hw *hw, 561 struct ieee80211_low_level_stats *stats) 562 { 563 struct ath5k_hw *ah = hw->priv; 564 565 /* Force update */ 566 ath5k_hw_update_mib_counters(ah); 567 568 stats->dot11ACKFailureCount = ah->stats.ack_fail; 569 stats->dot11RTSFailureCount = ah->stats.rts_fail; 570 stats->dot11RTSSuccessCount = ah->stats.rts_ok; 571 stats->dot11FCSErrorCount = ah->stats.fcs_error; 572 573 return 0; 574 } 575 576 577 static int 578 ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, 579 const struct ieee80211_tx_queue_params *params) 580 { 581 struct ath5k_hw *ah = hw->priv; 582 struct ath5k_txq_info qi; 583 int ret = 0; 584 585 if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) 586 return 0; 587 588 mutex_lock(&ah->lock); 589 590 ath5k_hw_get_tx_queueprops(ah, queue, &qi); 591 592 qi.tqi_aifs = params->aifs; 593 qi.tqi_cw_min = params->cw_min; 594 qi.tqi_cw_max = params->cw_max; 595 qi.tqi_burst_time = params->txop; 596 597 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, 598 "Configure tx [queue %d], " 599 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", 600 queue, params->aifs, params->cw_min, 601 params->cw_max, params->txop); 602 603 if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { 604 ATH5K_ERR(ah, 605 "Unable to update hardware queue %u!\n", queue); 606 ret = -EIO; 607 } else 608 ath5k_hw_reset_tx_queue(ah, queue); 609 610 mutex_unlock(&ah->lock); 611 612 return ret; 613 } 614 615 616 static u64 617 ath5k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 618 { 619 struct ath5k_hw *ah = hw->priv; 620 621 return ath5k_hw_get_tsf64(ah); 622 } 623 624 625 static void 626 ath5k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf) 627 { 628 struct ath5k_hw *ah = hw->priv; 629 630 ath5k_hw_set_tsf64(ah, tsf); 631 } 632 633 634 static void 635 ath5k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 636 { 637 struct ath5k_hw *ah = hw->priv; 638 639 /* 640 * in IBSS mode we need to update the beacon timers too. 641 * this will also reset the TSF if we call it with 0 642 */ 643 if (ah->opmode == NL80211_IFTYPE_ADHOC) 644 ath5k_beacon_update_timers(ah, 0); 645 else 646 ath5k_hw_reset_tsf(ah); 647 } 648 649 650 static int 651 ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) 652 { 653 struct ath5k_hw *ah = hw->priv; 654 struct ieee80211_conf *conf = &hw->conf; 655 struct ath_common *common = ath5k_hw_common(ah); 656 struct ath_cycle_counters *cc = &common->cc_survey; 657 unsigned int div = common->clockrate * 1000; 658 659 if (idx != 0) 660 return -ENOENT; 661 662 spin_lock_bh(&common->cc_lock); 663 ath_hw_cycle_counters_update(common); 664 if (cc->cycles > 0) { 665 ah->survey.channel_time += cc->cycles / div; 666 ah->survey.channel_time_busy += cc->rx_busy / div; 667 ah->survey.channel_time_rx += cc->rx_frame / div; 668 ah->survey.channel_time_tx += cc->tx_frame / div; 669 } 670 memset(cc, 0, sizeof(*cc)); 671 spin_unlock_bh(&common->cc_lock); 672 673 memcpy(survey, &ah->survey, sizeof(*survey)); 674 675 survey->channel = conf->channel; 676 survey->noise = ah->ah_noise_floor; 677 survey->filled = SURVEY_INFO_NOISE_DBM | 678 SURVEY_INFO_CHANNEL_TIME | 679 SURVEY_INFO_CHANNEL_TIME_BUSY | 680 SURVEY_INFO_CHANNEL_TIME_RX | 681 SURVEY_INFO_CHANNEL_TIME_TX; 682 683 return 0; 684 } 685 686 687 /** 688 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class 689 * 690 * @hw: struct ieee80211_hw pointer 691 * @coverage_class: IEEE 802.11 coverage class number 692 * 693 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given 694 * coverage class. The values are persistent, they are restored after device 695 * reset. 696 */ 697 static void 698 ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) 699 { 700 struct ath5k_hw *ah = hw->priv; 701 702 mutex_lock(&ah->lock); 703 ath5k_hw_set_coverage_class(ah, coverage_class); 704 mutex_unlock(&ah->lock); 705 } 706 707 708 static int 709 ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 710 { 711 struct ath5k_hw *ah = hw->priv; 712 713 if (tx_ant == 1 && rx_ant == 1) 714 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A); 715 else if (tx_ant == 2 && rx_ant == 2) 716 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B); 717 else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) 718 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 719 else 720 return -EINVAL; 721 return 0; 722 } 723 724 725 static int 726 ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 727 { 728 struct ath5k_hw *ah = hw->priv; 729 730 switch (ah->ah_ant_mode) { 731 case AR5K_ANTMODE_FIXED_A: 732 *tx_ant = 1; *rx_ant = 1; break; 733 case AR5K_ANTMODE_FIXED_B: 734 *tx_ant = 2; *rx_ant = 2; break; 735 case AR5K_ANTMODE_DEFAULT: 736 *tx_ant = 3; *rx_ant = 3; break; 737 } 738 return 0; 739 } 740 741 742 static void ath5k_get_ringparam(struct ieee80211_hw *hw, 743 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 744 { 745 struct ath5k_hw *ah = hw->priv; 746 747 *tx = ah->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max; 748 749 *tx_max = ATH5K_TXQ_LEN_MAX; 750 *rx = *rx_max = ATH_RXBUF; 751 } 752 753 754 static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx) 755 { 756 struct ath5k_hw *ah = hw->priv; 757 u16 qnum; 758 759 /* only support setting tx ring size for now */ 760 if (rx != ATH_RXBUF) 761 return -EINVAL; 762 763 /* restrict tx ring size min/max */ 764 if (!tx || tx > ATH5K_TXQ_LEN_MAX) 765 return -EINVAL; 766 767 for (qnum = 0; qnum < ARRAY_SIZE(ah->txqs); qnum++) { 768 if (!ah->txqs[qnum].setup) 769 continue; 770 if (ah->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN || 771 ah->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX) 772 continue; 773 774 ah->txqs[qnum].txq_max = tx; 775 if (ah->txqs[qnum].txq_len >= ah->txqs[qnum].txq_max) 776 ieee80211_stop_queue(hw, ah->txqs[qnum].qnum); 777 } 778 779 return 0; 780 } 781 782 783 const struct ieee80211_ops ath5k_hw_ops = { 784 .tx = ath5k_tx, 785 .start = ath5k_start, 786 .stop = ath5k_stop, 787 .add_interface = ath5k_add_interface, 788 /* .change_interface = not implemented */ 789 .remove_interface = ath5k_remove_interface, 790 .config = ath5k_config, 791 .bss_info_changed = ath5k_bss_info_changed, 792 .prepare_multicast = ath5k_prepare_multicast, 793 .configure_filter = ath5k_configure_filter, 794 /* .set_tim = not implemented */ 795 .set_key = ath5k_set_key, 796 /* .update_tkip_key = not implemented */ 797 /* .hw_scan = not implemented */ 798 .sw_scan_start = ath5k_sw_scan_start, 799 .sw_scan_complete = ath5k_sw_scan_complete, 800 .get_stats = ath5k_get_stats, 801 /* .get_tkip_seq = not implemented */ 802 /* .set_frag_threshold = not implemented */ 803 /* .set_rts_threshold = not implemented */ 804 /* .sta_add = not implemented */ 805 /* .sta_remove = not implemented */ 806 /* .sta_notify = not implemented */ 807 .conf_tx = ath5k_conf_tx, 808 .get_tsf = ath5k_get_tsf, 809 .set_tsf = ath5k_set_tsf, 810 .reset_tsf = ath5k_reset_tsf, 811 /* .tx_last_beacon = not implemented */ 812 /* .ampdu_action = not needed */ 813 .get_survey = ath5k_get_survey, 814 .set_coverage_class = ath5k_set_coverage_class, 815 /* .rfkill_poll = not implemented */ 816 /* .flush = not implemented */ 817 /* .channel_switch = not implemented */ 818 /* .napi_poll = not implemented */ 819 .set_antenna = ath5k_set_antenna, 820 .get_antenna = ath5k_get_antenna, 821 .set_ringparam = ath5k_set_ringparam, 822 .get_ringparam = ath5k_get_ringparam, 823 }; 824