iPXE
ath9k_recv.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008-2011 Atheros Communications Inc.
00003  *
00004  * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
00005  * Original from Linux kernel 3.0.1
00006  *
00007  * Permission to use, copy, modify, and/or distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00012  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00013  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00014  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00015  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00016  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00017  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00018  */
00019 
00020 #include <ipxe/io.h>
00021 
00022 #include "ath9k.h"
00023 #include "ar9003_mac.h"
00024 
00025 /*
00026  * Setup and link descriptors.
00027  *
00028  * 11N: we can no longer afford to self link the last descriptor.
00029  * MAC acknowledges BA status as long as it copies frames to host
00030  * buffer (or rx fifo). This can incorrectly acknowledge packets
00031  * to a sender if last desc is self-linked.
00032  */
00033 static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
00034 {
00035         struct ath_hw *ah = sc->sc_ah;
00036         struct ath_common *common = ath9k_hw_common(ah);
00037         struct ath_desc *ds;
00038 //      struct io_buffer *iob;
00039 
00040         ATH_RXBUF_RESET(bf);
00041 
00042         ds = bf->bf_desc;
00043         ds->ds_link = 0; /* link to null */
00044         ds->ds_data = bf->bf_buf_addr;
00045 
00046 //      /* virtual addr of the beginning of the buffer. */
00047 //      iob = bf->bf_mpdu;
00048 //      ds->ds_vdata = iob->data;
00049 
00050         /*
00051          * setup rx descriptors. The rx_bufsize here tells the hardware
00052          * how much data it can DMA to us and that we are prepared
00053          * to process
00054          */
00055         ath9k_hw_setuprxdesc(ah, ds,
00056                              common->rx_bufsize,
00057                              0);
00058 
00059         if (sc->rx.rxlink == NULL)
00060                 ath9k_hw_putrxbuf(ah, bf->bf_daddr);
00061         else
00062                 *sc->rx.rxlink = bf->bf_daddr;
00063 
00064         sc->rx.rxlink = &ds->ds_link;
00065 }
00066 
00067 static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
00068 {
00069         /* XXX block beacon interrupts */
00070         ath9k_hw_setantenna(sc->sc_ah, antenna);
00071         sc->rx.defant = antenna;
00072         sc->rx.rxotherant = 0;
00073 }
00074 
00075 static void ath_opmode_init(struct ath_softc *sc)
00076 {
00077         struct ath_hw *ah = sc->sc_ah;
00078         struct ath_common *common = ath9k_hw_common(ah);
00079 
00080         u32 rfilt, mfilt[2];
00081 
00082         /* configure rx filter */
00083         rfilt = ath_calcrxfilter(sc);
00084         ath9k_hw_setrxfilter(ah, rfilt);
00085 
00086         /* configure bssid mask */
00087         ath_hw_setbssidmask(common);
00088 
00089         /* configure operational mode */
00090         ath9k_hw_setopmode(ah);
00091 
00092         /* calculate and install multicast filter */
00093         mfilt[0] = mfilt[1] = ~0;
00094         ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
00095 }
00096 
00097 int ath_rx_init(struct ath_softc *sc, int nbufs)
00098 {
00099         struct ath_common *common = ath9k_hw_common(sc->sc_ah);
00100         struct io_buffer *iob;
00101         struct ath_buf *bf;
00102         int error = 0;
00103 
00104         sc->sc_flags &= ~SC_OP_RXFLUSH;
00105 
00106         common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
00107                              sc->sc_ah->caps.rx_status_len;
00108 
00109         DBG2("ath9k: cachelsz %d rxbufsize %d\n",
00110                 common->cachelsz, common->rx_bufsize);
00111 
00112         /* Initialize rx descriptors */
00113 
00114         error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
00115                         "rx", nbufs, 1, 0);
00116         if (error != 0) {
00117                 DBG("ath9k: "
00118                         "failed to allocate rx descriptors: %d\n",
00119                         error);
00120                 goto err;
00121         }
00122 
00123         list_for_each_entry(bf, &sc->rx.rxbuf, list) {
00124                 iob = alloc_iob_raw ( common->rx_bufsize, common->cachelsz, 0 );
00125                 if (iob == NULL) {
00126                         error = -ENOMEM;
00127                         goto err;
00128                 }
00129 
00130                 bf->bf_mpdu = iob;
00131                 bf->bf_buf_addr = virt_to_bus ( iob->data );
00132         }
00133         sc->rx.rxlink = NULL;
00134 
00135 err:
00136         if (error)
00137                 ath_rx_cleanup(sc);
00138 
00139         return error;
00140 }
00141 
00142 void ath_rx_cleanup(struct ath_softc *sc)
00143 {
00144         struct io_buffer *iob;
00145         struct ath_buf *bf;
00146 
00147         list_for_each_entry(bf, &sc->rx.rxbuf, list) {
00148                 iob = bf->bf_mpdu;
00149                 if (iob) {
00150                         free_iob(iob);
00151                         bf->bf_buf_addr = 0;
00152                         bf->bf_mpdu = NULL;
00153                 }
00154         }
00155 
00156         if (sc->rx.rxdma.dd_desc_len != 0)
00157                 ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
00158 }
00159 
00160 /*
00161  * Calculate the receive filter according to the
00162  * operating mode and state:
00163  *
00164  * o always accept unicast, broadcast, and multicast traffic
00165  * o maintain current state of phy error reception (the hal
00166  *   may enable phy error frames for noise immunity work)
00167  * o probe request frames are accepted only when operating in
00168  *   hostap, adhoc, or monitor modes
00169  * o enable promiscuous mode according to the interface state
00170  * o accept beacons:
00171  *   - when operating in adhoc mode so the 802.11 layer creates
00172  *     node table entries for peers,
00173  *   - when operating in station mode for collecting rssi data when
00174  *     the station is otherwise quiet, or
00175  *   - when operating as a repeater so we see repeater-sta beacons
00176  *   - when scanning
00177  */
00178 
00179 u32 ath_calcrxfilter(struct ath_softc *sc)
00180 {
00181 #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
00182 
00183         u32 rfilt;
00184 
00185         rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
00186                 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
00187                 | ATH9K_RX_FILTER_MCAST | ATH9K_RX_FILTER_BEACON;
00188 
00189         return rfilt;
00190 
00191 #undef RX_FILTER_PRESERVE
00192 }
00193 
00194 int ath_startrecv(struct ath_softc *sc)
00195 {
00196         struct ath_hw *ah = sc->sc_ah;
00197         struct ath_buf *bf, *tbf;
00198 
00199         if (list_empty(&sc->rx.rxbuf))
00200                 goto start_recv;
00201 
00202         sc->rx.rxlink = NULL;
00203         list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
00204                 ath_rx_buf_link(sc, bf);
00205         }
00206 
00207         /* We could have deleted elements so the list may be empty now */
00208         if (list_empty(&sc->rx.rxbuf))
00209                 goto start_recv;
00210 
00211         bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
00212         ath9k_hw_putrxbuf(ah, bf->bf_daddr);
00213         ath9k_hw_rxena(ah);
00214 
00215 start_recv:
00216         ath_opmode_init(sc);
00217         ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
00218 
00219         return 0;
00220 }
00221 
00222 int ath_stoprecv(struct ath_softc *sc)
00223 {
00224         struct ath_hw *ah = sc->sc_ah;
00225         int stopped, reset = 0;
00226 
00227         ath9k_hw_abortpcurecv(ah);
00228         ath9k_hw_setrxfilter(ah, 0);
00229         stopped = ath9k_hw_stopdmarecv(ah, &reset);
00230 
00231         sc->rx.rxlink = NULL;
00232 
00233         if (!(ah->ah_flags & AH_UNPLUGGED) &&
00234             !stopped) {
00235                 DBG("ath9k: "
00236                         "Could not stop RX, we could be "
00237                         "confusing the DMA engine when we start RX up\n");
00238         }
00239         return stopped && !reset;
00240 }
00241 
00242 void ath_flushrecv(struct ath_softc *sc)
00243 {
00244         sc->sc_flags |= SC_OP_RXFLUSH;
00245         ath_rx_tasklet(sc, 1, 0);
00246         sc->sc_flags &= ~SC_OP_RXFLUSH;
00247 }
00248 
00249 static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
00250                                            struct ath_rx_status *rs)
00251 {
00252         struct ath_hw *ah = sc->sc_ah;
00253         struct ath_desc *ds;
00254         struct ath_buf *bf;
00255         int ret;
00256 
00257         if (list_empty(&sc->rx.rxbuf)) {
00258                 sc->rx.rxlink = NULL;
00259                 return NULL;
00260         }
00261 
00262         bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
00263         ds = bf->bf_desc;
00264 
00265         /*
00266          * Must provide the virtual address of the current
00267          * descriptor, the physical address, and the virtual
00268          * address of the next descriptor in the h/w chain.
00269          * This allows the HAL to look ahead to see if the
00270          * hardware is done with a descriptor by checking the
00271          * done bit in the following descriptor and the address
00272          * of the current descriptor the DMA engine is working
00273          * on.  All this is necessary because of our use of
00274          * a self-linked list to avoid rx overruns.
00275          */
00276         ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
00277         if (ret == -EINPROGRESS) {
00278                 struct ath_rx_status trs;
00279                 struct ath_buf *tbf;
00280                 struct ath_desc *tds;
00281 
00282                 memset(&trs, 0, sizeof(trs));
00283                 if ((&bf->list)->next == &sc->rx.rxbuf) {
00284                         sc->rx.rxlink = NULL;
00285                         return NULL;
00286                 }
00287 
00288                 tbf = list_entry(bf->list.next, struct ath_buf, list);
00289 
00290                 /*
00291                  * On some hardware the descriptor status words could
00292                  * get corrupted, including the done bit. Because of
00293                  * this, check if the next descriptor's done bit is
00294                  * set or not.
00295                  *
00296                  * If the next descriptor's done bit is set, the current
00297                  * descriptor has been corrupted. Force s/w to discard
00298                  * this descriptor and continue...
00299                  */
00300 
00301                 tds = tbf->bf_desc;
00302                 ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
00303                 if (ret == -EINPROGRESS)
00304                         return NULL;
00305         }
00306 
00307         if (!bf->bf_mpdu)
00308                 return bf;
00309 
00310         return bf;
00311 }
00312 
00313 /* Assumes you've already done the endian to CPU conversion */
00314 static int ath9k_rx_accept(struct ath_common *common,
00315                             struct ath_rx_status *rx_stats,
00316                             int *decrypt_error)
00317 {
00318         struct ath_hw *ah = common->ah;
00319         u8 rx_status_len = ah->caps.rx_status_len;
00320 
00321 
00322         if (!rx_stats->rs_datalen)
00323                 return 0;
00324         /*
00325          * rs_status follows rs_datalen so if rs_datalen is too large
00326          * we can take a hint that hardware corrupted it, so ignore
00327          * those frames.
00328          */
00329         if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
00330                 return 0;
00331 
00332         /* Only use error bits from the last fragment */
00333         if (rx_stats->rs_more)
00334                 return 1;
00335 
00336         /*
00337          * The rx_stats->rs_status will not be set until the end of the
00338          * chained descriptors so it can be ignored if rs_more is set. The
00339          * rs_more will be false at the last element of the chained
00340          * descriptors.
00341          */
00342         if (rx_stats->rs_status != 0) {
00343                 if (rx_stats->rs_status & ATH9K_RXERR_PHY)
00344                         return 0;
00345 
00346                 if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
00347                         *decrypt_error = 1;
00348                 }
00349                 /*
00350                  * Reject error frames with the exception of
00351                  * decryption and MIC failures. For monitor mode,
00352                  * we also ignore the CRC error.
00353                  */
00354                 if (ah->is_monitoring) {
00355                         if (rx_stats->rs_status &
00356                             ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
00357                               ATH9K_RXERR_CRC))
00358                                 return 0;
00359                 } else {
00360                         if (rx_stats->rs_status &
00361                             ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
00362                                 return 0;
00363                         }
00364                 }
00365         }
00366         return 1;
00367 }
00368 
00369 static int ath9k_process_rate(struct ath_common *common __unused,
00370                               struct net80211_device *dev,
00371                               struct ath_rx_status *rx_stats,
00372                               int *rix)
00373 {
00374         struct ath_softc *sc = (struct ath_softc *)dev->priv;
00375         int band;
00376         int i = 0;
00377 
00378         band = (dev->channels + sc->dev->channel)->band;
00379 
00380         for (i = 0; i < sc->hwinfo->nr_rates[band]; i++) {
00381                 if (sc->rates[i].hw_value == rx_stats->rs_rate) {
00382                         *rix = i;
00383                         return 0;
00384                 }
00385                 if (sc->rates[i].hw_value_short == rx_stats->rs_rate) {
00386                         *rix = i;
00387                         return 0;
00388                 }
00389         }
00390 
00391         /*
00392          * No valid hardware bitrate found -- we should not get here
00393          * because hardware has already validated this frame as OK.
00394          */
00395         DBG("ath9k: "
00396                 "unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
00397                 rx_stats->rs_rate);
00398 
00399         return -EINVAL;
00400 }
00401 
00402 /*
00403  * For Decrypt or Demic errors, we only mark packet status here and always push
00404  * up the frame up to let mac80211 handle the actual error case, be it no
00405  * decryption key or real decryption error. This let us keep statistics there.
00406  */
00407 static int ath9k_rx_iob_preprocess(struct ath_common *common,
00408                                    struct net80211_device *dev,
00409                                    struct ath_rx_status *rx_stats,
00410                                    int *rix,
00411                                    int *decrypt_error)
00412 {
00413         /*
00414          * everything but the rate is checked here, the rate check is done
00415          * separately to avoid doing two lookups for a rate for each frame.
00416          */
00417         if (!ath9k_rx_accept(common, rx_stats, decrypt_error))
00418                 return -EINVAL;
00419 
00420         /* Only use status info from the last fragment */
00421         if (rx_stats->rs_more)
00422                 return 0;
00423 
00424         if (ath9k_process_rate(common, dev, rx_stats, rix))
00425                 return -EINVAL;
00426 
00427         return 0;
00428 }
00429 
00430 int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
00431 {
00432         struct ath_buf *bf;
00433         struct io_buffer *iob = NULL, *requeue_iob;
00434         struct ath_hw *ah = sc->sc_ah;
00435         struct ath_common *common = ath9k_hw_common(ah);
00436         /*
00437          * The hw can technically differ from common->hw when using ath9k
00438          * virtual wiphy so to account for that we iterate over the active
00439          * wiphys and find the appropriate wiphy and therefore hw.
00440          */
00441         struct net80211_device *dev = sc->dev;
00442         int retval;
00443         int decrypt_error = 0;
00444         struct ath_rx_status rs;
00445         int rix = 0;
00446 
00447         do {
00448                 /* If handling rx interrupt and flush is in progress => exit */
00449                 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
00450                         break;
00451 
00452                 memset(&rs, 0, sizeof(rs));
00453                 bf = ath_get_next_rx_buf(sc, &rs);
00454 
00455                 if (!bf)
00456                         break;
00457 
00458                 iob = bf->bf_mpdu;
00459                 if (!iob)
00460                         continue;
00461 
00462                 /*
00463                  * If we're asked to flush receive queue, directly
00464                  * chain it back at the queue without processing it.
00465                  */
00466                 if (flush)
00467                         goto requeue_drop_frag;
00468 
00469                 retval = ath9k_rx_iob_preprocess(common, dev, &rs,
00470                                                  &rix, &decrypt_error);
00471                 if (retval)
00472                         goto requeue_drop_frag;
00473 
00474                 /* Ensure we always have an iob to requeue once we are done
00475                  * processing the current buffer's iob */
00476                 requeue_iob = alloc_iob_raw ( common->rx_bufsize,
00477                                               common->cachelsz, 0 );
00478 
00479                 /* If there is no memory we ignore the current RX'd frame,
00480                  * tell hardware it can give us a new frame using the old
00481                  * iob and put it at the tail of the sc->rx.rxbuf list for
00482                  * processing. */
00483                 if (!requeue_iob)
00484                         goto requeue_drop_frag;
00485 
00486                 iob_put(iob, rs.rs_datalen + ah->caps.rx_status_len);
00487                 if (ah->caps.rx_status_len)
00488                         iob_pull(iob, ah->caps.rx_status_len);
00489 
00490                 /* We will now give hardware our shiny new allocated iob */
00491                 bf->bf_mpdu = requeue_iob;
00492                 bf->bf_buf_addr = virt_to_bus ( requeue_iob->data );
00493 
00494                 /*
00495                  * change the default rx antenna if rx diversity chooses the
00496                  * other antenna 3 times in a row.
00497                  */
00498                 if (sc->rx.defant != rs.rs_antenna) {
00499                         if (++sc->rx.rxotherant >= 3)
00500                                 ath_setdefantenna(sc, rs.rs_antenna);
00501                 } else {
00502                         sc->rx.rxotherant = 0;
00503                 }
00504 
00505                 DBGIO("ath9k: rx %d bytes, signal %d, bitrate %d, hw_value %d\n", rs.rs_datalen,
00506                                                 rs.rs_rssi, sc->rates[rix].bitrate, rs.rs_rate);
00507 
00508                 net80211_rx(dev, iob, rs.rs_rssi,
00509                                 sc->rates[rix].bitrate);
00510 
00511 requeue_drop_frag:
00512                 list_del(&bf->list);
00513                 list_add_tail(&bf->list, &sc->rx.rxbuf);
00514                 ath_rx_buf_link(sc, bf);
00515                 ath9k_hw_rxena(ah);
00516         } while (1);
00517 
00518         return 0;
00519 }