Home | History | Annotate | Download | only in ath5k

Lines Matching refs:sc

177 static int ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan);
178 static int ath5k_reset_wake(struct ath5k_softc *sc);
206 static int ath5k_chan_set(struct ath5k_softc *sc,
208 static void ath5k_setcurmode(struct ath5k_softc *sc,
210 static void ath5k_mode_setup(struct ath5k_softc *sc);
213 static int ath5k_desc_alloc(struct ath5k_softc *sc);
214 static void ath5k_desc_free(struct ath5k_softc *sc);
216 static int ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf);
217 static int ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf);
219 static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
225 net80211_tx_complete(sc->dev, bf->iob, 0, ECANCELED);
229 static inline void ath5k_rxbuf_free(struct ath5k_softc *sc __unused,
237 static int ath5k_txq_setup(struct ath5k_softc *sc,
239 static void ath5k_txq_drainq(struct ath5k_softc *sc,
241 static void ath5k_txq_cleanup(struct ath5k_softc *sc);
242 static void ath5k_txq_release(struct ath5k_softc *sc);
244 static int ath5k_rx_start(struct ath5k_softc *sc);
245 static void ath5k_rx_stop(struct ath5k_softc *sc);
247 static void ath5k_tx_processq(struct ath5k_softc *sc,
251 static int ath5k_init(struct ath5k_softc *sc);
252 static int ath5k_stop_hw(struct ath5k_softc *sc);
254 static void ath5k_calibrate(struct ath5k_softc *sc);
257 static void ath5k_configure_filter(struct ath5k_softc *sc);
291 struct ath5k_softc *sc;
336 dev = net80211_alloc(sizeof(*sc));
344 sc = dev->priv;
345 sc->dev = dev;
346 sc->pdev = pdev;
348 sc->hwinfo = zalloc(sizeof(*sc->hwinfo));
349 if (!sc->hwinfo) {
355 sc->hwinfo->flags = NET80211_HW_RX_HAS_FCS;
356 sc->hwinfo->signal_type = NET80211_SIGNAL_DB;
357 sc->hwinfo->signal_max = 40; /* 35dB should give perfect 54Mbps */
358 sc->hwinfo->channel_change_time = 5000;
361 sc->status |= ATH_STAT_INVALID;
363 sc->iobase = mem;
364 sc->cachelsz = csz * 4; /* convert to bytes */
366 DBG("ath5k: register base at %p (%08lx)\n", sc->iobase, pdev->membase);
367 DBG("ath5k: cache line size %d\n", sc->cachelsz);
374 ret = ath5k_hw_attach(sc, id->driver_data, &sc->ah);
385 ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
386 sc->ah->ah_mac_srev, sc->ah->ah_phy_revision);
388 if (!sc->ah->ah_single_chip) {
390 if (sc->ah->ah_radio_5ghz_revision &&
391 !sc->ah->ah_radio_2ghz_revision) {
393 if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A)) {
396 sc->ah->ah_radio_5ghz_revision),
397 sc->ah->ah_radio_5ghz_revision);
400 } else if (!(sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B)) {
403 sc->ah->ah_radio_5ghz_revision),
404 sc->ah->ah_radio_5ghz_revision);
409 sc->ah->ah_radio_5ghz_revision),
410 sc->ah->ah_radio_5ghz_revision);
415 else if (sc->ah->ah_radio_5ghz_revision &&
416 sc->ah->ah_radio_2ghz_revision) {
419 sc->ah->ah_radio_5ghz_revision),
420 sc->ah->ah_radio_5ghz_revision);
423 sc->ah->ah_radio_2ghz_revision),
424 sc->ah->ah_radio_2ghz_revision);
430 sc->status &= ~ATH_STAT_INVALID;
434 ath5k_hw_detach(sc->ah);
436 free(sc->hwinfo);
448 struct ath5k_softc *sc = dev->priv;
451 ath5k_hw_detach(sc->ah);
452 iounmap(sc->iobase);
453 free(sc->hwinfo);
465 struct ath5k_softc *sc = dev->priv;
466 struct ath5k_hw *ah = sc->ah;
483 ath5k_setcurmode(sc, AR5K_MODE_11A);
485 ath5k_setcurmode(sc, AR5K_MODE_11B);
490 ret = ath5k_desc_alloc(sc);
500 ret = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
506 sc->last_calib_ticks = currticks();
508 ret = ath5k_eeprom_read_mac(ah, sc->hwinfo->hwaddr);
511 sc->pdev->device);
515 memset(sc->bssidmask, 0xff, ETH_ALEN);
516 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
518 ret = net80211_register(sc->dev, &ath5k_ops, sc->hwinfo);
526 ath5k_txq_release(sc);
528 ath5k_desc_free(sc);
536 struct ath5k_softc *sc = dev->priv;
539 ath5k_desc_free(sc);
540 ath5k_txq_release(sc);
629 struct ath5k_softc *sc = dev->priv;
630 struct ath5k_hw *ah = sc->ah;
635 max_c = sizeof(sc->hwinfo->channels) / sizeof(sc->hwinfo->channels[0]);
638 if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11G) {
641 sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ;
642 sc->hwinfo->modes = (NET80211_MODE_G | NET80211_MODE_B);
645 sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate;
646 sc->hwinfo->nr_rates[band] = 12;
648 sc->hwinfo->nr_channels =
649 ath5k_copy_channels(ah, sc->hwinfo->channels,
651 count_c = sc->hwinfo->nr_channels;
653 } else if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11B) {
656 sc->hwinfo->bands = NET80211_BAND_BIT_2GHZ;
657 sc->hwinfo->modes = NET80211_MODE_B;
660 sc->hwinfo->rates[band][i] = ath5k_rates[i].bitrate;
661 sc->hwinfo->nr_rates[band] = 4;
663 sc->hwinfo->nr_channels =
664 ath5k_copy_channels(ah, sc->hwinfo->channels,
666 count_c = sc->hwinfo->nr_channels;
671 if (sc->ah->ah_capabilities.cap_mode & AR5K_MODE_BIT_11A) {
673 sc->hwinfo->bands |= NET80211_BAND_BIT_5GHZ;
674 sc->hwinfo->modes |= NET80211_MODE_A;
677 sc->hwinfo->rates[band][i] = ath5k_rates[i+4].bitrate;
678 sc->hwinfo->nr_rates[band] = 8;
680 sc->hwinfo->nr_channels =
681 ath5k_copy_channels(ah, sc->hwinfo->channels,
683 count_c = sc->hwinfo->nr_channels;
697 ath5k_chan_set(struct ath5k_softc *sc, struct net80211_channel *chan)
699 if (chan->center_freq != sc->curchan->center_freq ||
700 chan->hw_value != sc->curchan->hw_value) {
708 sc->curchan->center_freq, chan->center_freq);
709 return ath5k_reset(sc, chan);
716 ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
718 sc->curmode = mode;
721 sc->curband = NET80211_BAND_5GHZ;
723 sc->curband = NET80211_BAND_2GHZ;
728 ath5k_mode_setup(struct ath5k_softc *sc)
730 struct ath5k_hw *ah = sc->ah;
734 rfilt = sc->filter_flags;
738 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
778 ath5k_rx_iob_alloc(struct ath5k_softc *sc, u32 *iob_addr)
787 iob = alloc_iob(sc->rxbufsize + sc->cachelsz - 1);
791 sc->rxbufsize + sc->cachelsz - 1);
802 off = *iob_addr % sc->cachelsz;
804 iob_reserve(iob, sc->cachelsz - off);
805 *iob_addr += sc->cachelsz - off;
812 ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
814 struct ath5k_hw *ah = sc->ah;
819 iob = ath5k_rx_iob_alloc(sc, &bf->iobaddr);
850 if (sc->rxlink != NULL)
851 *sc->rxlink = bf->daddr;
852 sc->rxlink = &ds->ds_link;
857 ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
859 struct ath5k_hw *ah = sc->ah;
860 struct ath5k_txq *txq = &sc->txq;
875 if (sc->dev->phy_flags & NET80211_PHY_USE_PROTECTION) {
876 struct net80211_device *dev = sc->dev;
879 cts_rate = sc->hw_rtscts_rate;
884 AR5K_PKT_TYPE_NORMAL, sc->power_level * 2,
885 sc->hw_rate, ATH5K_RETRIES,
912 ath5k_desc_alloc(struct ath5k_softc *sc)
921 sc->desc_len = sizeof(struct ath5k_desc) * (ATH_TXBUF + ATH_RXBUF + 1);
922 sc->desc = malloc_dma(sc->desc_len, ATH5K_DESC_ALIGN);
923 if (sc->desc == NULL) {
928 memset(sc->desc, 0, sc->desc_len);
929 sc->desc_daddr = virt_to_bus(sc->desc);
931 ds = sc->desc;
932 da = sc->desc_daddr;
940 sc->bufptr = bf;
942 INIT_LIST_HEAD(&sc->rxbuf);
946 list_add_tail(&bf->list, &sc->rxbuf);
949 INIT_LIST_HEAD(&sc->txbuf);
950 sc->txbuf_len = ATH_TXBUF;
954 list_add_tail(&bf->list, &sc->txbuf);
960 free_dma(sc->desc, sc->desc_len);
962 sc->desc = NULL;
967 ath5k_desc_free(struct ath5k_softc *sc)
971 list_for_each_entry(bf, &sc->txbuf, list)
972 ath5k_txbuf_free(sc, bf);
973 list_for_each_entry(bf, &sc->rxbuf, list)
974 ath5k_rxbuf_free(sc, bf);
977 free_dma(sc->desc, sc->desc_len);
979 free(sc->bufptr);
980 sc->bufptr = NULL;
992 ath5k_txq_setup(struct ath5k_softc *sc, int qtype, int subtype)
994 struct ath5k_hw *ah = sc->ah;
1024 txq = &sc->txq;
1035 ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1040 ath5k_txbuf_free(sc, bf);
1043 list_add_tail(&bf->list, &sc->txbuf);
1044 sc->txbuf_len++;
1053 ath5k_txq_cleanup(struct ath5k_softc *sc)
1055 struct ath5k_hw *ah = sc->ah;
1057 if (!(sc->status & ATH_STAT_INVALID)) {
1059 if (sc->txq.setup) {
1060 ath5k_hw_stop_tx_dma(ah, sc->txq.qnum);
1062 sc->txq.qnum,
1063 ath5k_hw_get_txdp(ah, sc->txq.qnum),
1064 sc->txq.link);
1068 if (sc->txq.setup)
1069 ath5k_txq_drainq(sc, &sc->txq);
1073 ath5k_txq_release(struct ath5k_softc *sc)
1075 if (sc->txq.setup) {
1076 ath5k_hw_release_tx_queue(sc->ah);
1077 sc->txq.setup = 0;
1092 ath5k_rx_start(struct ath5k_softc *sc)
1094 struct ath5k_hw *ah = sc->ah;
1098 sc->rxbufsize = IEEE80211_MAX_LEN;
1099 if (sc->rxbufsize % sc->cachelsz != 0)
1100 sc->rxbufsize += sc->cachelsz - (sc->rxbufsize % sc->cachelsz);
1102 sc->rxlink = NULL;
1104 list_for_each_entry(bf, &sc->rxbuf, list) {
1105 ret = ath5k_rxbuf_setup(sc, bf);
1110 bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list);
1114 ath5k_mode_setup(sc); /* set filters, etc. */
1124 ath5k_rx_stop(struct ath5k_softc *sc)
1126 struct ath5k_hw *ah = sc->ah;
1132 sc->rxlink = NULL; /* just in case */
1136 ath5k_handle_rx(struct ath5k_softc *sc)
1147 if (list_empty(&sc->rxbuf)) {
1152 bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
1155 bf = list_entry(sc->rxbuf.next, struct ath5k_buf, list);
1170 ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
1179 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
1184 net80211_rx_err(sc->dev, NULL, -ret);
1200 net80211_rx_err(sc->dev, NULL, EIO);
1228 next_iob = ath5k_rx_iob_alloc(sc, &next_iob_addr);
1250 net80211_rx(sc->dev, iob, rs.rs_rssi,
1257 list_add_tail(&bf->list, &sc->rxbuf);
1258 } while (ath5k_rxbuf_setup(sc, bf) == 0);
1269 ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1282 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
1299 net80211_tx_complete(sc->dev, iob, ts.ts_retry[0],
1303 list_add_tail(&bf->list, &sc->txbuf);
1304 sc->txbuf_len++;
1312 ath5k_handle_tx(struct ath5k_softc *sc)
1314 ath5k_tx_processq(sc, &sc->txq);
1325 struct ath5k_softc *sc = dev->priv;
1326 struct ath5k_hw *ah = sc->ah;
1328 sc->irq_ena = enable;
1332 ath5k_hw_set_imr(ah, sc->imask);
1336 ath5k_init(struct ath5k_softc *sc)
1338 struct ath5k_hw *ah = sc->ah;
1345 ath5k_stop_hw(sc);
1354 sc->curchan = sc->dev->channels + sc->dev->channel;
1355 sc->curband = sc->curchan->band;
1356 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
1359 ret = ath5k_reset(sc, NULL);
1382 ath5k_stop_hw(struct ath5k_softc *sc)
1384 struct ath5k_hw *ah = sc->ah;
1402 if (!(sc->status & ATH_STAT_INVALID)) {
1405 ath5k_txq_cleanup(sc);
1406 if (!(sc->status & ATH_STAT_INVALID)) {
1407 ath5k_rx_stop(sc);
1410 sc->rxlink = NULL;
1412 ath5k_rfkill_hw_stop(sc->ah);
1420 struct ath5k_softc *sc = dev->priv;
1421 struct ath5k_hw *ah = sc->ah;
1425 if (currticks() - sc->last_calib_ticks >
1427 ath5k_calibrate(sc);
1428 sc->last_calib_ticks = currticks();
1431 if ((sc->status & ATH_STAT_INVALID) ||
1432 (sc->irq_ena && !ath5k_hw_is_intr_pending(ah)))
1437 DBGP("ath5k: status %#x/%#x\n", status, sc->imask);
1444 ath5k_reset_wake(sc);
1447 ath5k_reset_wake(sc);
1456 sc->rxlink = NULL;
1464 ath5k_handle_rx(sc);
1467 ath5k_handle_tx(sc);
1480 ath5k_calibrate(struct ath5k_softc *sc)
1482 struct ath5k_hw *ah = sc->ah;
1490 ath5k_reset_wake(sc);
1492 if (ath5k_hw_phy_calibrate(ah, sc->curchan))
1494 sc->curchan->channel_nr);
1505 struct ath5k_softc *sc = dev->priv;
1514 if (list_empty(&sc->txbuf)) {
1519 bf = list_entry(sc->txbuf.next, struct ath5k_buf, list);
1521 sc->txbuf_len--;
1525 if ((rc = ath5k_txbuf_setup(sc, bf)) != 0) {
1527 list_add_tail(&bf->list, &sc->txbuf);
1528 sc->txbuf_len++;
1539 ath5k_reset(struct ath5k_softc *sc, struct net80211_channel *chan)
1541 struct ath5k_hw *ah = sc->ah;
1546 ath5k_txq_cleanup(sc);
1547 ath5k_rx_stop(sc);
1549 sc->curchan = chan;
1550 sc->curband = chan->band;
1553 ret = ath5k_hw_reset(ah, sc->curchan, 1);
1559 ret = ath5k_rx_start(sc);
1574 /* ath5k_chan_change(sc, c); */
1577 ath5k_irq(sc->dev, sc->irq_ena);
1582 static int ath5k_reset_wake(struct ath5k_softc *sc)
1584 return ath5k_reset(sc, sc->curchan);
1589 struct ath5k_softc *sc = dev->priv;
1592 if ((ret = ath5k_init(sc)) != 0)
1595 sc->assoc = 0;
1596 ath5k_configure_filter(sc);
1597 ath5k_hw_set_lladdr(sc->ah, dev->netdev->ll_addr);
1604 struct ath5k_softc *sc = dev->priv;
1607 ath5k_hw_set_lladdr(sc->ah, mac);
1609 ath5k_stop_hw(sc);
1615 struct ath5k_softc *sc = dev->priv;
1616 struct ath5k_hw *ah = sc->ah;
1621 sc->power_level = chan->maxpower;
1622 if ((ret = ath5k_chan_set(sc, chan)) != 0)
1639 sc->hw_rate = ath5k_rates[i].hw_code;
1643 sc->hw_rtscts_rate = ath5k_rates[i].hw_code;
1648 sc->assoc = !!(dev->state & NET80211_ASSOCIATED);
1649 if (sc->assoc) {
1678 static void ath5k_configure_filter(struct ath5k_softc *sc)
1680 struct ath5k_hw *ah = sc->ah;
1699 sc->filter_flags = rfilt;