00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ath5k.h"
00024 #include "reg.h"
00025 #include "debug.h"
00026 #include "base.h"
00027
00028
00029
00030
00031 int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
00032 struct ath5k_txq_info *queue_info)
00033 {
00034 ATH5K_TRACE(ah->ah_sc);
00035 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
00036 return 0;
00037 }
00038
00039
00040
00041
00042 int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
00043 const struct ath5k_txq_info *queue_info)
00044 {
00045 ATH5K_TRACE(ah->ah_sc);
00046 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
00047
00048 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
00049 return -EIO;
00050
00051 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
00052
00053
00054 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
00055 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
00056 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
00057 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
00058 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
00059
00060 return 0;
00061 }
00062
00063
00064
00065
00066 int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
00067 struct ath5k_txq_info *queue_info)
00068 {
00069 unsigned int queue;
00070 int ret;
00071
00072 ATH5K_TRACE(ah->ah_sc);
00073
00074
00075
00076
00077
00078 if (ah->ah_version == AR5K_AR5210) {
00079 switch (queue_type) {
00080 case AR5K_TX_QUEUE_DATA:
00081 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
00082 break;
00083 case AR5K_TX_QUEUE_BEACON:
00084 case AR5K_TX_QUEUE_CAB:
00085 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
00086 break;
00087 default:
00088 return -EINVAL;
00089 }
00090 } else {
00091 switch (queue_type) {
00092 case AR5K_TX_QUEUE_DATA:
00093 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
00094 ah->ah_txq[queue].tqi_type !=
00095 AR5K_TX_QUEUE_INACTIVE; queue++) {
00096
00097 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
00098 return -EINVAL;
00099 }
00100 break;
00101 case AR5K_TX_QUEUE_UAPSD:
00102 queue = AR5K_TX_QUEUE_ID_UAPSD;
00103 break;
00104 case AR5K_TX_QUEUE_BEACON:
00105 queue = AR5K_TX_QUEUE_ID_BEACON;
00106 break;
00107 case AR5K_TX_QUEUE_CAB:
00108 queue = AR5K_TX_QUEUE_ID_CAB;
00109 break;
00110 case AR5K_TX_QUEUE_XR_DATA:
00111 if (ah->ah_version != AR5K_AR5212)
00112 ATH5K_ERR(ah->ah_sc,
00113 "XR data queues only supported in"
00114 " 5212!\n");
00115 queue = AR5K_TX_QUEUE_ID_XR_DATA;
00116 break;
00117 default:
00118 return -EINVAL;
00119 }
00120 }
00121
00122
00123
00124
00125 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
00126 ah->ah_txq[queue].tqi_type = queue_type;
00127
00128 if (queue_info != NULL) {
00129 queue_info->tqi_type = queue_type;
00130 ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
00131 if (ret)
00132 return ret;
00133 }
00134
00135
00136
00137
00138
00139
00140 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
00141
00142 return queue;
00143 }
00144
00145
00146
00147
00148
00149 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
00150 {
00151 u32 pending;
00152 ATH5K_TRACE(ah->ah_sc);
00153 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
00154
00155
00156 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
00157 return false;
00158
00159
00160 if (ah->ah_version == AR5K_AR5210)
00161 return false;
00162
00163 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
00164 pending &= AR5K_QCU_STS_FRMPENDCNT;
00165
00166
00167
00168
00169 if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
00170 return true;
00171
00172 return pending;
00173 }
00174
00175
00176
00177
00178 void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
00179 {
00180 ATH5K_TRACE(ah->ah_sc);
00181 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
00182 return;
00183
00184
00185 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
00186
00187 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
00188 }
00189
00190
00191
00192
00193 int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
00194 {
00195 u32 cw_min, cw_max, retry_lg, retry_sh;
00196 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
00197
00198 ATH5K_TRACE(ah->ah_sc);
00199 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
00200
00201 tq = &ah->ah_txq[queue];
00202
00203 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
00204 return 0;
00205
00206 if (ah->ah_version == AR5K_AR5210) {
00207
00208 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
00209 return 0;
00210
00211
00212 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00213 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
00214 AR5K_SLOT_TIME);
00215
00216 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00217 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
00218 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
00219
00220 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00221 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
00222 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
00223
00224
00225 if (ah->ah_turbo) {
00226 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
00227 (ah->ah_aifs + tq->tqi_aifs) *
00228 AR5K_INIT_SLOT_TIME_TURBO) <<
00229 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
00230 AR5K_IFS0);
00231 } else {
00232 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
00233 (ah->ah_aifs + tq->tqi_aifs) *
00234 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
00235 AR5K_INIT_SIFS, AR5K_IFS0);
00236 }
00237
00238
00239 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00240 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
00241 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
00242
00243 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00244 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
00245 | 0x38 :
00246 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
00247 | 0x1C,
00248 AR5K_PHY_SETTLING);
00249
00250 ath5k_hw_reg_write(ah, ah->ah_turbo ?
00251 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
00252 AR5K_PHY_TURBO_SHORT | 0x2020) :
00253 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
00254 AR5K_PHY_FRAME_CTL_5210);
00255 }
00256
00257
00258
00259
00260 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
00261 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
00262 ah->ah_aifs = AR5K_TUNE_AIFS;
00263
00264 if (IS_CHAN_XR(ah->ah_current_channel) &&
00265 ah->ah_version == AR5K_AR5212) {
00266 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
00267 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
00268 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
00269
00270 } else if (IS_CHAN_B(ah->ah_current_channel) &&
00271 ah->ah_version != AR5K_AR5210) {
00272 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
00273 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
00274 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
00275 }
00276
00277 cw_min = 1;
00278 while (cw_min < ah->ah_cw_min)
00279 cw_min = (cw_min << 1) | 1;
00280
00281 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
00282 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
00283 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
00284 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
00285
00286
00287
00288
00289 if (ah->ah_software_retry) {
00290
00291 retry_lg = ah->ah_limit_tx_retries;
00292 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
00293 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
00294 } else {
00295 retry_lg = AR5K_INIT_LG_RETRY;
00296 retry_sh = AR5K_INIT_SH_RETRY;
00297 }
00298
00299
00300 if (ah->ah_version == AR5K_AR5210) {
00301 ath5k_hw_reg_write(ah,
00302 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
00303 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
00304 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
00305 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
00306 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
00307 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
00308 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
00309 AR5K_NODCU_RETRY_LMT);
00310 } else {
00311
00312 ath5k_hw_reg_write(ah,
00313 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
00314 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
00315 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
00316 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
00317 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
00318 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
00319 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
00320
00321
00322
00323
00324
00325
00326
00327 ath5k_hw_reg_write(ah,
00328 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
00329 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
00330 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
00331 AR5K_DCU_LCL_IFS_AIFS),
00332 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
00333
00334
00335
00336
00337
00338 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
00339 AR5K_QCU_MISC_DCU_EARLY);
00340
00341
00342 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
00343 AR5K_DCU_MISC_FRAG_WAIT);
00344
00345
00346 if (ah->ah_mac_version < AR5K_SREV_AR5211)
00347 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
00348 AR5K_DCU_MISC_SEQNUM_CTL);
00349
00350 if (tq->tqi_cbr_period) {
00351 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
00352 AR5K_QCU_CBRCFG_INTVAL) |
00353 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
00354 AR5K_QCU_CBRCFG_ORN_THRES),
00355 AR5K_QUEUE_CBRCFG(queue));
00356 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
00357 AR5K_QCU_MISC_FRSHED_CBR);
00358 if (tq->tqi_cbr_overflow_limit)
00359 AR5K_REG_ENABLE_BITS(ah,
00360 AR5K_QUEUE_MISC(queue),
00361 AR5K_QCU_MISC_CBR_THRES_ENABLE);
00362 }
00363
00364 if (tq->tqi_ready_time &&
00365 (tq->tqi_type != AR5K_TX_QUEUE_CAB))
00366 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
00367 AR5K_QCU_RDYTIMECFG_INTVAL) |
00368 AR5K_QCU_RDYTIMECFG_ENABLE,
00369 AR5K_QUEUE_RDYTIMECFG(queue));
00370
00371 if (tq->tqi_burst_time) {
00372 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
00373 AR5K_DCU_CHAN_TIME_DUR) |
00374 AR5K_DCU_CHAN_TIME_ENABLE,
00375 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
00376
00377 if (tq->tqi_flags
00378 & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
00379 AR5K_REG_ENABLE_BITS(ah,
00380 AR5K_QUEUE_MISC(queue),
00381 AR5K_QCU_MISC_RDY_VEOL_POLICY);
00382 }
00383
00384 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
00385 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
00386 AR5K_QUEUE_DFS_MISC(queue));
00387
00388 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
00389 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
00390 AR5K_QUEUE_DFS_MISC(queue));
00391
00392
00393
00394
00395 switch (tq->tqi_type) {
00396 case AR5K_TX_QUEUE_BEACON:
00397 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
00398 AR5K_QCU_MISC_FRSHED_DBA_GT |
00399 AR5K_QCU_MISC_CBREXP_BCN_DIS |
00400 AR5K_QCU_MISC_BCN_ENABLE);
00401
00402 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
00403 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
00404 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
00405 AR5K_DCU_MISC_ARBLOCK_IGNORE |
00406 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
00407 AR5K_DCU_MISC_BCN_ENABLE);
00408 break;
00409
00410 case AR5K_TX_QUEUE_CAB:
00411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
00412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
00413 AR5K_QCU_MISC_CBREXP_DIS |
00414 AR5K_QCU_MISC_CBREXP_BCN_DIS);
00415
00416 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
00417 (AR5K_TUNE_SW_BEACON_RESP -
00418 AR5K_TUNE_DMA_BEACON_RESP) -
00419 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
00420 AR5K_QCU_RDYTIMECFG_ENABLE,
00421 AR5K_QUEUE_RDYTIMECFG(queue));
00422
00423 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
00424 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
00425 AR5K_DCU_MISC_ARBLOCK_CTL_S));
00426 break;
00427
00428 case AR5K_TX_QUEUE_UAPSD:
00429 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
00430 AR5K_QCU_MISC_CBREXP_DIS);
00431 break;
00432
00433 case AR5K_TX_QUEUE_DATA:
00434 default:
00435 break;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
00445 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
00446
00447 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
00448 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
00449
00450 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
00451 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
00452
00453 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
00454 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
00455
00456 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
00457 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
00458
00459 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
00460 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
00461
00462 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
00463 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
00464
00465 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
00466 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
00467
00468 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
00469 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
00470
00471
00472
00473
00474 ah->ah_txq_imr_txok &= ah->ah_txq_status;
00475 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
00476 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
00477 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
00478 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
00479 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
00480 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
00481 ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
00482 ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
00483
00484 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
00485 AR5K_SIMR0_QCU_TXOK) |
00486 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
00487 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
00488 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
00489 AR5K_SIMR1_QCU_TXERR) |
00490 AR5K_REG_SM(ah->ah_txq_imr_txeol,
00491 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
00492
00493 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
00494 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
00495 AR5K_REG_SM(ah->ah_txq_imr_txurn,
00496 AR5K_SIMR2_QCU_TXURN));
00497 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
00498 AR5K_SIMR3_QCBRORN) |
00499 AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
00500 AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
00501 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
00502 AR5K_SIMR4_QTRIG), AR5K_SIMR4);
00503
00504 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
00505 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
00506
00507
00508 if (ah->ah_txq_imr_nofrm == 0)
00509 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
00510
00511
00512 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
00513 }
00514
00515 return 0;
00516 }
00517
00518
00519
00520
00521 unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
00522 {
00523 ATH5K_TRACE(ah->ah_sc);
00524 if (ah->ah_version == AR5K_AR5210)
00525 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
00526 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
00527 else
00528 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
00529 }
00530
00531
00532
00533
00534 int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
00535 {
00536 ATH5K_TRACE(ah->ah_sc);
00537 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
00538 return -EINVAL;
00539
00540 if (ah->ah_version == AR5K_AR5210)
00541 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
00542 ah->ah_turbo), AR5K_SLOT_TIME);
00543 else
00544 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
00545
00546 return 0;
00547 }
00548