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 } 138 139 /* Any MAC address is fine, all others are included through the 140 * filter. 141 */ 142 ath5k_hw_set_lladdr(ah, vif->addr); 143 144 ath5k_update_bssid_mask_and_opmode(ah, vif); 145 ret = 0; 146 end: 147 mutex_unlock(&ah->lock); 148 return ret; 149 } 150 151 152 static void 153 ath5k_remove_interface(struct ieee80211_hw *hw, 154 struct ieee80211_vif *vif) 155 { 156 struct ath5k_hw *ah = hw->priv; 157 struct ath5k_vif *avf = (void *)vif->drv_priv; 158 unsigned int i; 159 160 mutex_lock(&ah->lock); 161 ah->nvifs--; 162 163 if (avf->bbuf) { 164 ath5k_txbuf_free_skb(ah, avf->bbuf); 165 list_add_tail(&avf->bbuf->list, &ah->bcbuf); 166 for (i = 0; i < ATH_BCBUF; i++) { 167 if (ah->bslot[i] == vif) { 168 ah->bslot[i] = NULL; 169 break; 170 } 171 } 172 avf->bbuf = NULL; 173 } 174 if (avf->opmode == NL80211_IFTYPE_AP) 175 ah->num_ap_vifs--; 176 else if (avf->opmode == NL80211_IFTYPE_ADHOC) 177 ah->num_adhoc_vifs--; 178 179 ath5k_update_bssid_mask_and_opmode(ah, NULL); 180 mutex_unlock(&ah->lock); 181 } 182 183 184 /* 185 * TODO: Phy disable/diversity etc 186 */ 187 static int 188 ath5k_config(struct ieee80211_hw *hw, u32 changed) 189 { 190 struct ath5k_hw *ah = hw->priv; 191 struct ieee80211_conf *conf = &hw->conf; 192 int ret = 0; 193 int i; 194 195 mutex_lock(&ah->lock); 196 197 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 198 ret = ath5k_chan_set(ah, conf->channel); 199 if (ret < 0) 200 goto unlock; 201 } 202 203 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 204 (ah->power_level != conf->power_level)) { 205 ah->power_level = conf->power_level; 206 207 /* Half dB steps */ 208 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); 209 } 210 211 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { 212 ah->ah_retry_long = conf->long_frame_max_tx_count; 213 ah->ah_retry_short = conf->short_frame_max_tx_count; 214 215 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) 216 ath5k_hw_set_tx_retry_limits(ah, i); 217 } 218 219 /* TODO: 220 * 1) Move this on config_interface and handle each case 221 * separately eg. when we have only one STA vif, use 222 * AR5K_ANTMODE_SINGLE_AP 223 * 224 * 2) Allow the user to change antenna mode eg. when only 225 * one antenna is present 226 * 227 * 3) Allow the user to set default/tx antenna when possible 228 * 229 * 4) Default mode should handle 90% of the cases, together 230 * with fixed a/b and single AP modes we should be able to 231 * handle 99%. Sectored modes are extreme cases and i still 232 * haven't found a usage for them. If we decide to support them, 233 * then we must allow the user to set how many tx antennas we 234 * have available 235 */ 236 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 237 238 unlock: 239 mutex_unlock(&ah->lock); 240 return ret; 241 } 242 243 244 static void 245 ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 246 struct ieee80211_bss_conf *bss_conf, u32 changes) 247 { 248 struct ath5k_vif *avf = (void *)vif->drv_priv; 249 struct ath5k_hw *ah = hw->priv; 250 struct ath_common *common = ath5k_hw_common(ah); 251 unsigned long flags; 252 253 mutex_lock(&ah->lock); 254 255 if (changes & BSS_CHANGED_BSSID) { 256 /* Cache for later use during resets */ 257 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 258 common->curaid = 0; 259 ath5k_hw_set_bssid(ah); 260 mmiowb(); 261 } 262 263 if (changes & BSS_CHANGED_BEACON_INT) 264 ah->bintval = bss_conf->beacon_int; 265 266 if (changes & BSS_CHANGED_ERP_SLOT) { 267 int slot_time; 268 269 ah->ah_short_slot = bss_conf->use_short_slot; 270 slot_time = ath5k_hw_get_default_slottime(ah) + 271 3 * ah->ah_coverage_class; 272 ath5k_hw_set_ifs_intervals(ah, slot_time); 273 } 274 275 if (changes & BSS_CHANGED_ASSOC) { 276 avf->assoc = bss_conf->assoc; 277 if (bss_conf->assoc) 278 ah->assoc = bss_conf->assoc; 279 else 280 ah->assoc = ath5k_any_vif_assoc(ah); 281 282 if (ah->opmode == NL80211_IFTYPE_STATION) 283 ath5k_set_beacon_filter(hw, ah->assoc); 284 ath5k_hw_set_ledstate(ah, ah->assoc ? 285 AR5K_LED_ASSOC : AR5K_LED_INIT); 286 if (bss_conf->assoc) { 287 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, 288 "Bss Info ASSOC %d, bssid: %pM\n", 289 bss_conf->aid, common->curbssid); 290 common->curaid = bss_conf->aid; 291 ath5k_hw_set_bssid(ah); 292 /* Once ANI is available you would start it here */ 293 } 294 } 295 296 if (changes & BSS_CHANGED_BEACON) { 297 spin_lock_irqsave(&ah->block, flags); 298 ath5k_beacon_update(hw, vif); 299 spin_unlock_irqrestore(&ah->block, flags); 300 } 301 302 if (changes & BSS_CHANGED_BEACON_ENABLED) 303 ah->enable_beacon = bss_conf->enable_beacon; 304 305 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | 306 BSS_CHANGED_BEACON_INT)) 307 ath5k_beacon_config(ah); 308 309 mutex_unlock(&ah->lock); 310 } 311 312 313 static u64 314 ath5k_prepare_multicast(struct ieee80211_hw *hw, 315 struct netdev_hw_addr_list *mc_list) 316 { 317 u32 mfilt[2], val; 318 u8 pos; 319 struct netdev_hw_addr *ha; 320 321 mfilt[0] = 0; 322 mfilt[1] = 1; 323 324 netdev_hw_addr_list_for_each(ha, mc_list) { 325 /* calculate XOR of eight 6-bit values */ 326 val = get_unaligned_le32(ha->addr + 0); 327 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 328 val = get_unaligned_le32(ha->addr + 3); 329 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 330 pos &= 0x3f; 331 mfilt[pos / 32] |= (1 << (pos % 32)); 332 /* XXX: we might be able to just do this instead, 333 * but not sure, needs testing, if we do use this we'd 334 * need to inform below not to reset the mcast */ 335 /* ath5k_hw_set_mcast_filterindex(ah, 336 * ha->addr[5]); */ 337 } 338 339 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 340 } 341 342 343 /* 344 * o always accept unicast, broadcast, and multicast traffic 345 * o multicast traffic for all BSSIDs will be enabled if mac80211 346 * says it should be 347 * o maintain current state of phy ofdm or phy cck error reception. 348 * If the hardware detects any of these type of errors then 349 * ath5k_hw_get_rx_filter() will pass to us the respective 350 * hardware filters to be able to receive these type of frames. 351 * o probe request frames are accepted only when operating in 352 * hostap, adhoc, or monitor modes 353 * o enable promiscuous mode according to the interface state 354 * o accept beacons: 355 * - when operating in adhoc mode so the 802.11 layer creates 356 * node table entries for peers, 357 * - when operating in station mode for collecting rssi data when 358 * the station is otherwise quiet, or 359 * - when scanning 360 */ 361 static void 362 ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, 363 unsigned int *new_flags, u64 multicast) 364 { 365 #define SUPPORTED_FIF_FLAGS \ 366 (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 367 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 368 FIF_BCN_PRBRESP_PROMISC) 369 370 struct ath5k_hw *ah = hw->priv; 371 u32 mfilt[2], rfilt; 372 struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ 373 374 mutex_lock(&ah->lock); 375 376 mfilt[0] = multicast; 377 mfilt[1] = multicast >> 32; 378 379 /* Only deal with supported flags */ 380 changed_flags &= SUPPORTED_FIF_FLAGS; 381 *new_flags &= SUPPORTED_FIF_FLAGS; 382 383 /* If HW detects any phy or radar errors, leave those filters on. 384 * Also, always enable Unicast, Broadcasts and Multicast 385 * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ 386 rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | 387 (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | 388 AR5K_RX_FILTER_MCAST); 389 390 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { 391 if (*new_flags & FIF_PROMISC_IN_BSS) 392 __set_bit(ATH_STAT_PROMISC, ah->status); 393 else 394 __clear_bit(ATH_STAT_PROMISC, ah->status); 395 } 396 397 if (test_bit(ATH_STAT_PROMISC, ah->status)) 398 rfilt |= AR5K_RX_FILTER_PROM; 399 400 /* Note, AR5K_RX_FILTER_MCAST is already enabled */ 401 if (*new_flags & FIF_ALLMULTI) { 402 mfilt[0] = ~0; 403 mfilt[1] = ~0; 404 } 405 406 /* This is the best we can do */ 407 if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) 408 rfilt |= AR5K_RX_FILTER_PHYERR; 409 410 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons 411 * and probes for any BSSID */ 412 if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1)) 413 rfilt |= AR5K_RX_FILTER_BEACON; 414 415 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not 416 * set we should only pass on control frames for this 417 * station. This needs testing. I believe right now this 418 * enables *all* control frames, which is OK.. but 419 * but we should see if we can improve on granularity */ 420 if (*new_flags & FIF_CONTROL) 421 rfilt |= AR5K_RX_FILTER_CONTROL; 422 423 /* Additional settings per mode -- this is per ath5k */ 424 425 /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ 426 427 switch (ah->opmode) { 428 case NL80211_IFTYPE_MESH_POINT: 429 rfilt |= AR5K_RX_FILTER_CONTROL | 430 AR5K_RX_FILTER_BEACON | 431 AR5K_RX_FILTER_PROBEREQ | 432 AR5K_RX_FILTER_PROM; 433 break; 434 case NL80211_IFTYPE_AP: 435 case NL80211_IFTYPE_ADHOC: 436 rfilt |= AR5K_RX_FILTER_PROBEREQ | 437 AR5K_RX_FILTER_BEACON; 438 break; 439 case NL80211_IFTYPE_STATION: 440 if (ah->assoc) 441 rfilt |= AR5K_RX_FILTER_BEACON; 442 default: 443 break; 444 } 445 446 iter_data.hw_macaddr = NULL; 447 iter_data.n_stas = 0; 448 iter_data.need_set_hw_addr = false; 449 ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, 450 &iter_data); 451 452 /* Set up RX Filter */ 453 if (iter_data.n_stas > 1) { 454 /* If you have multiple STA interfaces connected to 455 * different APs, ARPs are not received (most of the time?) 456 * Enabling PROMISC appears to fix that problem. 457 */ 458 rfilt |= AR5K_RX_FILTER_PROM; 459 } 460 461 /* Set filters */ 462 ath5k_hw_set_rx_filter(ah, rfilt); 463 464 /* Set multicast bits */ 465 ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); 466 /* Set the cached hw filter flags, this will later actually 467 * be set in HW */ 468 ah->filter_flags = rfilt; 469 470 mutex_unlock(&ah->lock); 471 } 472 473 474 static int 475 ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 476 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 477 struct ieee80211_key_conf *key) 478 { 479 struct ath5k_hw *ah = hw->priv; 480 struct ath_common *common = ath5k_hw_common(ah); 481 int ret = 0; 482 483 if (ath5k_modparam_nohwcrypt) 484 return -EOPNOTSUPP; 485 486 switch (key->cipher) { 487 case WLAN_CIPHER_SUITE_WEP40: 488 case WLAN_CIPHER_SUITE_WEP104: 489 case WLAN_CIPHER_SUITE_TKIP: 490 break; 491 case WLAN_CIPHER_SUITE_CCMP: 492 if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) 493 break; 494 return -EOPNOTSUPP; 495 default: 496 WARN_ON(1); 497 return -EINVAL; 498 } 499 500 mutex_lock(&ah->lock); 501 502 switch (cmd) { 503 case SET_KEY: 504 ret = ath_key_config(common, vif, sta, key); 505 if (ret >= 0) { 506 key->hw_key_idx = ret; 507 /* push IV and Michael MIC generation to stack */ 508 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 509 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 510 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; 511 if (key->cipher == WLAN_CIPHER_SUITE_CCMP) 512 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; 513 ret = 0; 514 } 515 break; 516 case DISABLE_KEY: 517 ath_key_delete(common, key); 518 break; 519 default: 520 ret = -EINVAL; 521 } 522 523 mmiowb(); 524 mutex_unlock(&ah->lock); 525 return ret; 526 } 527 528 529 static void 530 ath5k_sw_scan_start(struct ieee80211_hw *hw) 531 { 532 struct ath5k_hw *ah = hw->priv; 533 if (!ah->assoc) 534 ath5k_hw_set_ledstate(ah, AR5K_LED_SCAN); 535 } 536 537 538 static void 539 ath5k_sw_scan_complete(struct ieee80211_hw *hw) 540 { 541 struct ath5k_hw *ah = hw->priv; 542 ath5k_hw_set_ledstate(ah, ah->assoc ? 543 AR5K_LED_ASSOC : AR5K_LED_INIT); 544 } 545 546 547 static int 548 ath5k_get_stats(struct ieee80211_hw *hw, 549 struct ieee80211_low_level_stats *stats) 550 { 551 struct ath5k_hw *ah = hw->priv; 552 553 /* Force update */ 554 ath5k_hw_update_mib_counters(ah); 555 556 stats->dot11ACKFailureCount = ah->stats.ack_fail; 557 stats->dot11RTSFailureCount = ah->stats.rts_fail; 558 stats->dot11RTSSuccessCount = ah->stats.rts_ok; 559 stats->dot11FCSErrorCount = ah->stats.fcs_error; 560 561 return 0; 562 } 563 564 565 static int 566 ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, 567 const struct ieee80211_tx_queue_params *params) 568 { 569 struct ath5k_hw *ah = hw->priv; 570 struct ath5k_txq_info qi; 571 int ret = 0; 572 573 if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) 574 return 0; 575 576 mutex_lock(&ah->lock); 577 578 ath5k_hw_get_tx_queueprops(ah, queue, &qi); 579 580 qi.tqi_aifs = params->aifs; 581 qi.tqi_cw_min = params->cw_min; 582 qi.tqi_cw_max = params->cw_max; 583 qi.tqi_burst_time = params->txop; 584 585 ATH5K_DBG(ah, ATH5K_DEBUG_ANY, 586 "Configure tx [queue %d], " 587 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", 588 queue, params->aifs, params->cw_min, 589 params->cw_max, params->txop); 590 591 if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { 592 ATH5K_ERR(ah, 593 "Unable to update hardware queue %u!\n", queue); 594 ret = -EIO; 595 } else 596 ath5k_hw_reset_tx_queue(ah, queue); 597 598 mutex_unlock(&ah->lock); 599 600 return ret; 601 } 602 603 604 static u64 605 ath5k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 606 { 607 struct ath5k_hw *ah = hw->priv; 608 609 return ath5k_hw_get_tsf64(ah); 610 } 611 612 613 static void 614 ath5k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf) 615 { 616 struct ath5k_hw *ah = hw->priv; 617 618 ath5k_hw_set_tsf64(ah, tsf); 619 } 620 621 622 static void 623 ath5k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 624 { 625 struct ath5k_hw *ah = hw->priv; 626 627 /* 628 * in IBSS mode we need to update the beacon timers too. 629 * this will also reset the TSF if we call it with 0 630 */ 631 if (ah->opmode == NL80211_IFTYPE_ADHOC) 632 ath5k_beacon_update_timers(ah, 0); 633 else 634 ath5k_hw_reset_tsf(ah); 635 } 636 637 638 static int 639 ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) 640 { 641 struct ath5k_hw *ah = hw->priv; 642 struct ieee80211_conf *conf = &hw->conf; 643 struct ath_common *common = ath5k_hw_common(ah); 644 struct ath_cycle_counters *cc = &common->cc_survey; 645 unsigned int div = common->clockrate * 1000; 646 647 if (idx != 0) 648 return -ENOENT; 649 650 spin_lock_bh(&common->cc_lock); 651 ath_hw_cycle_counters_update(common); 652 if (cc->cycles > 0) { 653 ah->survey.channel_time += cc->cycles / div; 654 ah->survey.channel_time_busy += cc->rx_busy / div; 655 ah->survey.channel_time_rx += cc->rx_frame / div; 656 ah->survey.channel_time_tx += cc->tx_frame / div; 657 } 658 memset(cc, 0, sizeof(*cc)); 659 spin_unlock_bh(&common->cc_lock); 660 661 memcpy(survey, &ah->survey, sizeof(*survey)); 662 663 survey->channel = conf->channel; 664 survey->noise = ah->ah_noise_floor; 665 survey->filled = SURVEY_INFO_NOISE_DBM | 666 SURVEY_INFO_CHANNEL_TIME | 667 SURVEY_INFO_CHANNEL_TIME_BUSY | 668 SURVEY_INFO_CHANNEL_TIME_RX | 669 SURVEY_INFO_CHANNEL_TIME_TX; 670 671 return 0; 672 } 673 674 675 /** 676 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class 677 * 678 * @hw: struct ieee80211_hw pointer 679 * @coverage_class: IEEE 802.11 coverage class number 680 * 681 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given 682 * coverage class. The values are persistent, they are restored after device 683 * reset. 684 */ 685 static void 686 ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) 687 { 688 struct ath5k_hw *ah = hw->priv; 689 690 mutex_lock(&ah->lock); 691 ath5k_hw_set_coverage_class(ah, coverage_class); 692 mutex_unlock(&ah->lock); 693 } 694 695 696 static int 697 ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 698 { 699 struct ath5k_hw *ah = hw->priv; 700 701 if (tx_ant == 1 && rx_ant == 1) 702 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A); 703 else if (tx_ant == 2 && rx_ant == 2) 704 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B); 705 else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) 706 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 707 else 708 return -EINVAL; 709 return 0; 710 } 711 712 713 static int 714 ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 715 { 716 struct ath5k_hw *ah = hw->priv; 717 718 switch (ah->ah_ant_mode) { 719 case AR5K_ANTMODE_FIXED_A: 720 *tx_ant = 1; *rx_ant = 1; break; 721 case AR5K_ANTMODE_FIXED_B: 722 *tx_ant = 2; *rx_ant = 2; break; 723 case AR5K_ANTMODE_DEFAULT: 724 *tx_ant = 3; *rx_ant = 3; break; 725 } 726 return 0; 727 } 728 729 730 static void ath5k_get_ringparam(struct ieee80211_hw *hw, 731 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 732 { 733 struct ath5k_hw *ah = hw->priv; 734 735 *tx = ah->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max; 736 737 *tx_max = ATH5K_TXQ_LEN_MAX; 738 *rx = *rx_max = ATH_RXBUF; 739 } 740 741 742 static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx) 743 { 744 struct ath5k_hw *ah = hw->priv; 745 u16 qnum; 746 747 /* only support setting tx ring size for now */ 748 if (rx != ATH_RXBUF) 749 return -EINVAL; 750 751 /* restrict tx ring size min/max */ 752 if (!tx || tx > ATH5K_TXQ_LEN_MAX) 753 return -EINVAL; 754 755 for (qnum = 0; qnum < ARRAY_SIZE(ah->txqs); qnum++) { 756 if (!ah->txqs[qnum].setup) 757 continue; 758 if (ah->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN || 759 ah->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX) 760 continue; 761 762 ah->txqs[qnum].txq_max = tx; 763 if (ah->txqs[qnum].txq_len >= ah->txqs[qnum].txq_max) 764 ieee80211_stop_queue(hw, ah->txqs[qnum].qnum); 765 } 766 767 return 0; 768 } 769 770 771 const struct ieee80211_ops ath5k_hw_ops = { 772 .tx = ath5k_tx, 773 .start = ath5k_start, 774 .stop = ath5k_stop, 775 .add_interface = ath5k_add_interface, 776 /* .change_interface = not implemented */ 777 .remove_interface = ath5k_remove_interface, 778 .config = ath5k_config, 779 .bss_info_changed = ath5k_bss_info_changed, 780 .prepare_multicast = ath5k_prepare_multicast, 781 .configure_filter = ath5k_configure_filter, 782 /* .set_tim = not implemented */ 783 .set_key = ath5k_set_key, 784 /* .update_tkip_key = not implemented */ 785 /* .hw_scan = not implemented */ 786 .sw_scan_start = ath5k_sw_scan_start, 787 .sw_scan_complete = ath5k_sw_scan_complete, 788 .get_stats = ath5k_get_stats, 789 /* .get_tkip_seq = not implemented */ 790 /* .set_frag_threshold = not implemented */ 791 /* .set_rts_threshold = not implemented */ 792 /* .sta_add = not implemented */ 793 /* .sta_remove = not implemented */ 794 /* .sta_notify = not implemented */ 795 .conf_tx = ath5k_conf_tx, 796 .get_tsf = ath5k_get_tsf, 797 .set_tsf = ath5k_set_tsf, 798 .reset_tsf = ath5k_reset_tsf, 799 /* .tx_last_beacon = not implemented */ 800 /* .ampdu_action = not needed */ 801 .get_survey = ath5k_get_survey, 802 .set_coverage_class = ath5k_set_coverage_class, 803 /* .rfkill_poll = not implemented */ 804 /* .flush = not implemented */ 805 /* .channel_switch = not implemented */ 806 /* .napi_poll = not implemented */ 807 .set_antenna = ath5k_set_antenna, 808 .get_antenna = ath5k_get_antenna, 809 .set_ringparam = ath5k_set_ringparam, 810 .get_ringparam = ath5k_get_ringparam, 811 }; 812