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


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