desc.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
00003  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
00004  * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
00005  *
00006  * Permission to use, copy, modify, and distribute this software for any
00007  * purpose with or without fee is hereby granted, provided that the above
00008  * copyright notice and this permission notice appear in all copies.
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00017  *
00018  */
00019 
00020 /******************************\
00021  Hardware Descriptor Functions
00022 \******************************/
00023 
00024 #include "ath5k.h"
00025 #include "reg.h"
00026 #include "debug.h"
00027 #include "base.h"
00028 
00029 /*
00030  * TX Descriptors
00031  */
00032 
00033 /*
00034  * Initialize the 2-word tx control descriptor on 5210/5211
00035  */
00036 static int
00037 ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
00038         unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
00039         unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
00040         unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
00041         unsigned int rtscts_rate, unsigned int rtscts_duration)
00042 {
00043         u32 frame_type;
00044         struct ath5k_hw_2w_tx_ctl *tx_ctl;
00045         unsigned int frame_len;
00046 
00047         tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
00048 
00049         /*
00050          * Validate input
00051          * - Zero retries don't make sense.
00052          * - A zero rate will put the HW into a mode where it continously sends
00053          *   noise on the channel, so it is important to avoid this.
00054          */
00055         if (unlikely(tx_tries0 == 0)) {
00056                 ATH5K_ERR(ah->ah_sc, "zero retries\n");
00057                 WARN_ON(1);
00058                 return -EINVAL;
00059         }
00060         if (unlikely(tx_rate0 == 0)) {
00061                 ATH5K_ERR(ah->ah_sc, "zero rate\n");
00062                 WARN_ON(1);
00063                 return -EINVAL;
00064         }
00065 
00066         /* Clear descriptor */
00067         memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
00068 
00069         /* Setup control descriptor */
00070 
00071         /* Verify and set frame length */
00072 
00073         /* remove padding we might have added before */
00074         frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
00075 
00076         if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
00077                 return -EINVAL;
00078 
00079         tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
00080 
00081         /* Verify and set buffer length */
00082 
00083         /* NB: beacon's BufLen must be a multiple of 4 bytes */
00084         if (type == AR5K_PKT_TYPE_BEACON)
00085                 pkt_len = roundup(pkt_len, 4);
00086 
00087         if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
00088                 return -EINVAL;
00089 
00090         tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
00091 
00092         /*
00093          * Verify and set header length
00094          * XXX: I only found that on 5210 code, does it work on 5211 ?
00095          */
00096         if (ah->ah_version == AR5K_AR5210) {
00097                 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
00098                         return -EINVAL;
00099                 tx_ctl->tx_control_0 |=
00100                         AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
00101         }
00102 
00103         /*Diferences between 5210-5211*/
00104         if (ah->ah_version == AR5K_AR5210) {
00105                 switch (type) {
00106                 case AR5K_PKT_TYPE_BEACON:
00107                 case AR5K_PKT_TYPE_PROBE_RESP:
00108                         frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
00109                 case AR5K_PKT_TYPE_PIFS:
00110                         frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
00111                 default:
00112                         frame_type = type /*<< 2 ?*/;
00113                 }
00114 
00115                 tx_ctl->tx_control_0 |=
00116                 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
00117                 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
00118 
00119         } else {
00120                 tx_ctl->tx_control_0 |=
00121                         AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
00122                         AR5K_REG_SM(antenna_mode,
00123                                 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
00124                 tx_ctl->tx_control_1 |=
00125                         AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
00126         }
00127 #define _TX_FLAGS(_c, _flag)                                    \
00128         if (flags & AR5K_TXDESC_##_flag) {                      \
00129                 tx_ctl->tx_control_##_c |=                      \
00130                         AR5K_2W_TX_DESC_CTL##_c##_##_flag;      \
00131         }
00132 
00133         _TX_FLAGS(0, CLRDMASK);
00134         _TX_FLAGS(0, VEOL);
00135         _TX_FLAGS(0, INTREQ);
00136         _TX_FLAGS(0, RTSENA);
00137         _TX_FLAGS(1, NOACK);
00138 
00139 #undef _TX_FLAGS
00140 
00141         /*
00142          * WEP crap
00143          */
00144         if (key_index != AR5K_TXKEYIX_INVALID) {
00145                 tx_ctl->tx_control_0 |=
00146                         AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
00147                 tx_ctl->tx_control_1 |=
00148                         AR5K_REG_SM(key_index,
00149                         AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
00150         }
00151 
00152         /*
00153          * RTS/CTS Duration [5210 ?]
00154          */
00155         if ((ah->ah_version == AR5K_AR5210) &&
00156                         (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
00157                 tx_ctl->tx_control_1 |= rtscts_duration &
00158                                 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
00159 
00160         return 0;
00161 }
00162 
00163 /*
00164  * Initialize the 4-word tx control descriptor on 5212
00165  */
00166 static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
00167         struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
00168         enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
00169         unsigned int tx_tries0, unsigned int key_index,
00170         unsigned int antenna_mode, unsigned int flags,
00171         unsigned int rtscts_rate,
00172         unsigned int rtscts_duration)
00173 {
00174         struct ath5k_hw_4w_tx_ctl *tx_ctl;
00175         unsigned int frame_len;
00176 
00177         ATH5K_TRACE(ah->ah_sc);
00178         tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
00179 
00180         /*
00181          * Validate input
00182          * - Zero retries don't make sense.
00183          * - A zero rate will put the HW into a mode where it continously sends
00184          *   noise on the channel, so it is important to avoid this.
00185          */
00186         if (unlikely(tx_tries0 == 0)) {
00187                 ATH5K_ERR(ah->ah_sc, "zero retries\n");
00188                 WARN_ON(1);
00189                 return -EINVAL;
00190         }
00191         if (unlikely(tx_rate0 == 0)) {
00192                 ATH5K_ERR(ah->ah_sc, "zero rate\n");
00193                 WARN_ON(1);
00194                 return -EINVAL;
00195         }
00196 
00197         tx_power += ah->ah_txpower.txp_offset;
00198         if (tx_power > AR5K_TUNE_MAX_TXPOWER)
00199                 tx_power = AR5K_TUNE_MAX_TXPOWER;
00200 
00201         /* Clear descriptor */
00202         memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
00203 
00204         /* Setup control descriptor */
00205 
00206         /* Verify and set frame length */
00207 
00208         /* remove padding we might have added before */
00209         frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
00210 
00211         if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
00212                 return -EINVAL;
00213 
00214         tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
00215 
00216         /* Verify and set buffer length */
00217 
00218         /* NB: beacon's BufLen must be a multiple of 4 bytes */
00219         if (type == AR5K_PKT_TYPE_BEACON)
00220                 pkt_len = roundup(pkt_len, 4);
00221 
00222         if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
00223                 return -EINVAL;
00224 
00225         tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
00226 
00227         tx_ctl->tx_control_0 |=
00228                 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
00229                 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
00230         tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
00231                                         AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
00232         tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
00233                                         AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
00234         tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
00235 
00236 #define _TX_FLAGS(_c, _flag)                                    \
00237         if (flags & AR5K_TXDESC_##_flag) {                      \
00238                 tx_ctl->tx_control_##_c |=                      \
00239                         AR5K_4W_TX_DESC_CTL##_c##_##_flag;      \
00240         }
00241 
00242         _TX_FLAGS(0, CLRDMASK);
00243         _TX_FLAGS(0, VEOL);
00244         _TX_FLAGS(0, INTREQ);
00245         _TX_FLAGS(0, RTSENA);
00246         _TX_FLAGS(0, CTSENA);
00247         _TX_FLAGS(1, NOACK);
00248 
00249 #undef _TX_FLAGS
00250 
00251         /*
00252          * WEP crap
00253          */
00254         if (key_index != AR5K_TXKEYIX_INVALID) {
00255                 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
00256                 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
00257                                 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
00258         }
00259 
00260         /*
00261          * RTS/CTS
00262          */
00263         if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
00264                 if ((flags & AR5K_TXDESC_RTSENA) &&
00265                                 (flags & AR5K_TXDESC_CTSENA))
00266                         return -EINVAL;
00267                 tx_ctl->tx_control_2 |= rtscts_duration &
00268                                 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
00269                 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
00270                                 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
00271         }
00272 
00273         return 0;
00274 }
00275 
00276 /*
00277  * Initialize a 4-word multi rate retry tx control descriptor on 5212
00278  */
00279 static int
00280 ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
00281         unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
00282         u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
00283 {
00284         struct ath5k_hw_4w_tx_ctl *tx_ctl;
00285 
00286         /*
00287          * Rates can be 0 as long as the retry count is 0 too.
00288          * A zero rate and nonzero retry count will put the HW into a mode where
00289          * it continously sends noise on the channel, so it is important to
00290          * avoid this.
00291          */
00292         if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
00293                      (tx_rate2 == 0 && tx_tries2 != 0) ||
00294                      (tx_rate3 == 0 && tx_tries3 != 0))) {
00295                 ATH5K_ERR(ah->ah_sc, "zero rate\n");
00296                 WARN_ON(1);
00297                 return -EINVAL;
00298         }
00299 
00300         if (ah->ah_version == AR5K_AR5212) {
00301                 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
00302 
00303 #define _XTX_TRIES(_n)                                                  \
00304         if (tx_tries##_n) {                                             \
00305                 tx_ctl->tx_control_2 |=                                 \
00306                     AR5K_REG_SM(tx_tries##_n,                           \
00307                     AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
00308                 tx_ctl->tx_control_3 |=                                 \
00309                     AR5K_REG_SM(tx_rate##_n,                            \
00310                     AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);                \
00311         }
00312 
00313                 _XTX_TRIES(1);
00314                 _XTX_TRIES(2);
00315                 _XTX_TRIES(3);
00316 
00317 #undef _XTX_TRIES
00318 
00319                 return 1;
00320         }
00321 
00322         return 0;
00323 }
00324 
00325 /* no mrr support for cards older than 5212 */
00326 static int
00327 ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
00328         unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
00329         u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
00330 {
00331         return 0;
00332 }
00333 
00334 /*
00335  * Proccess the tx status descriptor on 5210/5211
00336  */
00337 static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
00338                 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
00339 {
00340         struct ath5k_hw_2w_tx_ctl *tx_ctl;
00341         struct ath5k_hw_tx_status *tx_status;
00342 
00343         ATH5K_TRACE(ah->ah_sc);
00344 
00345         tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
00346         tx_status = &desc->ud.ds_tx5210.tx_stat;
00347 
00348         /* No frame has been send or error */
00349         if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
00350                 return -EINPROGRESS;
00351 
00352         /*
00353          * Get descriptor status
00354          */
00355         ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
00356                 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
00357         ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
00358                 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
00359         ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
00360                 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
00361         /*TODO: ts->ts_virtcol + test*/
00362         ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
00363                 AR5K_DESC_TX_STATUS1_SEQ_NUM);
00364         ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
00365                 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
00366         ts->ts_antenna = 1;
00367         ts->ts_status = 0;
00368         ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
00369                 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
00370         ts->ts_retry[0] = ts->ts_longretry;
00371         ts->ts_final_idx = 0;
00372 
00373         if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
00374                 if (tx_status->tx_status_0 &
00375                                 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
00376                         ts->ts_status |= AR5K_TXERR_XRETRY;
00377 
00378                 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
00379                         ts->ts_status |= AR5K_TXERR_FIFO;
00380 
00381                 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
00382                         ts->ts_status |= AR5K_TXERR_FILT;
00383         }
00384 
00385         return 0;
00386 }
00387 
00388 /*
00389  * Proccess a tx status descriptor on 5212
00390  */
00391 static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
00392                 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
00393 {
00394         struct ath5k_hw_4w_tx_ctl *tx_ctl;
00395         struct ath5k_hw_tx_status *tx_status;
00396 
00397         ATH5K_TRACE(ah->ah_sc);
00398 
00399         tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
00400         tx_status = &desc->ud.ds_tx5212.tx_stat;
00401 
00402         /* No frame has been send or error */
00403         if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
00404                 return -EINPROGRESS;
00405 
00406         /*
00407          * Get descriptor status
00408          */
00409         ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
00410                 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
00411         ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
00412                 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
00413         ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
00414                 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
00415         ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
00416                 AR5K_DESC_TX_STATUS1_SEQ_NUM);
00417         ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
00418                 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
00419         ts->ts_antenna = (tx_status->tx_status_1 &
00420                 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
00421         ts->ts_status = 0;
00422 
00423         ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
00424                         AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
00425 
00426         /* The longretry counter has the number of un-acked retries
00427          * for the final rate. To get the total number of retries
00428          * we have to add the retry counters for the other rates
00429          * as well
00430          */
00431         ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
00432         switch (ts->ts_final_idx) {
00433         case 3:
00434                 ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
00435                         AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
00436 
00437                 ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
00438                         AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
00439                 ts->ts_longretry += ts->ts_retry[2];
00440                 /* fall through */
00441         case 2:
00442                 ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
00443                         AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
00444 
00445                 ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
00446                         AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
00447                 ts->ts_longretry += ts->ts_retry[1];
00448                 /* fall through */
00449         case 1:
00450                 ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
00451                         AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
00452 
00453                 ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
00454                         AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
00455                 ts->ts_longretry += ts->ts_retry[0];
00456                 /* fall through */
00457         case 0:
00458                 ts->ts_rate[0] = tx_ctl->tx_control_3 &
00459                         AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
00460                 break;
00461         }
00462 
00463         /* TX error */
00464         if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
00465                 if (tx_status->tx_status_0 &
00466                                 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
00467                         ts->ts_status |= AR5K_TXERR_XRETRY;
00468 
00469                 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
00470                         ts->ts_status |= AR5K_TXERR_FIFO;
00471 
00472                 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
00473                         ts->ts_status |= AR5K_TXERR_FILT;
00474         }
00475 
00476         return 0;
00477 }
00478 
00479 /*
00480  * RX Descriptors
00481  */
00482 
00483 /*
00484  * Initialize an rx control descriptor
00485  */
00486 static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
00487                         u32 size, unsigned int flags)
00488 {
00489         struct ath5k_hw_rx_ctl *rx_ctl;
00490 
00491         ATH5K_TRACE(ah->ah_sc);
00492         rx_ctl = &desc->ud.ds_rx.rx_ctl;
00493 
00494         /*
00495          * Clear the descriptor
00496          * If we don't clean the status descriptor,
00497          * while scanning we get too many results,
00498          * most of them virtual, after some secs
00499          * of scanning system hangs. M.F.
00500         */
00501         memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
00502 
00503         /* Setup descriptor */
00504         rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
00505         if (unlikely(rx_ctl->rx_control_1 != size))
00506                 return -EINVAL;
00507 
00508         if (flags & AR5K_RXDESC_INTREQ)
00509                 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
00510 
00511         return 0;
00512 }
00513 
00514 /*
00515  * Proccess the rx status descriptor on 5210/5211
00516  */
00517 static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
00518                 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
00519 {
00520         struct ath5k_hw_rx_status *rx_status;
00521 
00522         rx_status = &desc->ud.ds_rx.u.rx_stat;
00523 
00524         /* No frame received / not ready */
00525         if (unlikely(!(rx_status->rx_status_1 &
00526         AR5K_5210_RX_DESC_STATUS1_DONE)))
00527                 return -EINPROGRESS;
00528 
00529         /*
00530          * Frame receive status
00531          */
00532         rs->rs_datalen = rx_status->rx_status_0 &
00533                 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
00534         rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
00535                 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
00536         rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
00537                 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
00538         rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
00539                 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
00540         rs->rs_more = !!(rx_status->rx_status_0 &
00541                 AR5K_5210_RX_DESC_STATUS0_MORE);
00542         /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
00543         rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
00544                 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
00545         rs->rs_status = 0;
00546         rs->rs_phyerr = 0;
00547 
00548         /*
00549          * Key table status
00550          */
00551         if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
00552                 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
00553                         AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
00554         else
00555                 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
00556 
00557         /*
00558          * Receive/descriptor errors
00559          */
00560         if (!(rx_status->rx_status_1 &
00561         AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
00562                 if (rx_status->rx_status_1 &
00563                                 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
00564                         rs->rs_status |= AR5K_RXERR_CRC;
00565 
00566                 if (rx_status->rx_status_1 &
00567                                 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
00568                         rs->rs_status |= AR5K_RXERR_FIFO;
00569 
00570                 if (rx_status->rx_status_1 &
00571                                 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
00572                         rs->rs_status |= AR5K_RXERR_PHY;
00573                         rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
00574                                 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
00575                 }
00576 
00577                 if (rx_status->rx_status_1 &
00578                                 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
00579                         rs->rs_status |= AR5K_RXERR_DECRYPT;
00580         }
00581 
00582         return 0;
00583 }
00584 
00585 /*
00586  * Proccess the rx status descriptor on 5212
00587  */
00588 static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
00589                 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
00590 {
00591         struct ath5k_hw_rx_status *rx_status;
00592         struct ath5k_hw_rx_error *rx_err;
00593 
00594         ATH5K_TRACE(ah->ah_sc);
00595         rx_status = &desc->ud.ds_rx.u.rx_stat;
00596 
00597         /* Overlay on error */
00598         rx_err = &desc->ud.ds_rx.u.rx_err;
00599 
00600         /* No frame received / not ready */
00601         if (unlikely(!(rx_status->rx_status_1 &
00602         AR5K_5212_RX_DESC_STATUS1_DONE)))
00603                 return -EINPROGRESS;
00604 
00605         /*
00606          * Frame receive status
00607          */
00608         rs->rs_datalen = rx_status->rx_status_0 &
00609                 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
00610         rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
00611                 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
00612         rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
00613                 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
00614         rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
00615                 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
00616         rs->rs_more = !!(rx_status->rx_status_0 &
00617                 AR5K_5212_RX_DESC_STATUS0_MORE);
00618         rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
00619                 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
00620         rs->rs_status = 0;
00621         rs->rs_phyerr = 0;
00622 
00623         /*
00624          * Key table status
00625          */
00626         if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
00627                 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
00628                                 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
00629         else
00630                 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
00631 
00632         /*
00633          * Receive/descriptor errors
00634          */
00635         if (!(rx_status->rx_status_1 &
00636         AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
00637                 if (rx_status->rx_status_1 &
00638                                 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
00639                         rs->rs_status |= AR5K_RXERR_CRC;
00640 
00641                 if (rx_status->rx_status_1 &
00642                                 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
00643                         rs->rs_status |= AR5K_RXERR_PHY;
00644                         rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
00645                                            AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
00646                 }
00647 
00648                 if (rx_status->rx_status_1 &
00649                                 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
00650                         rs->rs_status |= AR5K_RXERR_DECRYPT;
00651 
00652                 if (rx_status->rx_status_1 &
00653                                 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
00654                         rs->rs_status |= AR5K_RXERR_MIC;
00655         }
00656 
00657         return 0;
00658 }
00659 
00660 /*
00661  * Init function pointers inside ath5k_hw struct
00662  */
00663 int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
00664 {
00665 
00666         if (ah->ah_version != AR5K_AR5210 &&
00667                 ah->ah_version != AR5K_AR5211 &&
00668                 ah->ah_version != AR5K_AR5212)
00669                         return -ENOTSUPP;
00670 
00671         /* XXX: What is this magic value and where is it used ? */
00672         if (ah->ah_version == AR5K_AR5212)
00673                 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
00674         else if (ah->ah_version == AR5K_AR5211)
00675                 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
00676 
00677         if (ah->ah_version == AR5K_AR5212) {
00678                 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
00679                 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
00680                 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
00681                 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
00682         } else {
00683                 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
00684                 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
00685                 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
00686                 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
00687         }
00688 
00689         if (ah->ah_version == AR5K_AR5212)
00690                 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
00691         else if (ah->ah_version <= AR5K_AR5211)
00692                 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
00693 
00694         return 0;
00695 }
00696 


ros_rt_wmp
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Mon Oct 6 2014 08:27:09