commit 91203cbfafc7eb3d4baec9cb50d12bb396a18a78 Author: Jiri Slaby Date: Mon Jul 16 08:41:21 2007 +0200 remove further unneeded stuff from old ath/if_ath.c diff --git a/ath/if_ath.c b/ath/if_ath.c index 960e48a..57f48ac 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -2,19 +2,6 @@ #define LE_READ_2(_p) (le16_to_cpu(get_unaligned((__le16 *)(_p)))) #define LE_READ_4(_p) (le32_to_cpu(get_unaligned((__le32 *)(_p)))) -static const char *hal_status_desc[] = { - "Everything went O.K.", - "Unable to allocate memory for ath_hal", - "Hardware I/O Error", - "Unable to access EEPROM", - "Invalid EEPROM checksum", - "Unable to get device caps from EEPROM", - "Unable to read MAC address from EEPROM", - "Invalid parameter to function", - "Hardware revision not supported", - "Unexpected error ocured during process" -}; - static int ath_dwelltime = 200; /* 5 channels/second */ static int ath_calinterval = 30; /* calibrate every 30 secs */ static int ath_countrycode = CTRY_DEFAULT; /* country code */ @@ -38,18 +25,6 @@ static void ath_printrxbuf(struct ath_buf *bf, int); #define KEYPRINTF(sc, k, ix, mac) #endif -static int countrycode = -1; -static int outdoor = -1; -static int xchanmode = -1; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52)) -MODULE_PARM(countrycode, "i"); -MODULE_PARM(outdoor, "i"); -MODULE_PARM(xchanmode, "i"); -#else -module_param(countrycode, int, 0); -module_param(outdoor, int, 0); -module_param(xchanmode, int, 0); -#endif MODULE_PARM_DESC(countrycode, "Override default country code"); MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use"); MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode"); @@ -105,15 +80,6 @@ struct wlan_ng_prism2_header { }; static void -ath_fatal_tasklet(unsigned long data) -{ - struct ieee80211_hw *hw = (void *)data; - - printk(KERN_ERR "hardware error; resetting\n"); - ath_reset(hw); -} - -static void ath_radar_tasklet(unsigned long data) { struct ieee80211_hw *hw = (void *)data; @@ -260,522 +226,6 @@ static u_int8_t *rt_el_offset(struct ieee80211_radiotap_header *th, u_int32_t el return offset; } -/* - * ath_start for raw 802.11 packets. - */ -static int -ath_start_raw(struct sk_buff *skb, struct net_device *dev) -{ -#define CTS_DURATION \ - ath_hal_computetxtime(ah, rt, IEEE80211_ACK_LEN, cix, true) -/*#define updateCTSForBursting(_ah, _ds, _txq) \ - ath_hal_updateCTSForBursting(_ah, _ds, \ - _txq->axq_linkbuf != NULL ? _txq->axq_linkbuf->bf_desc : NULL, \ - _txq->axq_lastdsWithCTS, _txq->axq_gatingds, \ - txopLimit, CTS_DURATION)*/ - struct ath_softc *sc = dev->priv; -// struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc->sc_ah; -// const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; - struct ath_txq *txq; - struct ath_buf *bf; - AR5K_PKT_TYPE atype; - int pktlen, hdrlen, try0, pri, dot11_rate, txpower; - u_int8_t ctsrate, ctsduration, txrate; -// u_int8_t cix = 0xff; /* NB: silence compiler */ - u_int flags = 0; - struct ieee80211_frame *wh; - struct ath_desc *ds; - const struct ath5k_rate_table *rt; - uint8_t testmac[ETH_ALEN]; - - if ((sc->sc_dev.flags & IFF_RUNNING) == 0 || sc->sc_invalid) { - /* device is not up... silently discard packet */ - dev_kfree_skb(skb); - return 0; - } - - /* - * Grab a TX buffer and associated resources. - */ - ATH_TXBUF_LOCK_BH(sc); - bf = STAILQ_FIRST(&sc->sc_txbuf); - if (bf != NULL) - STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list); - /* XXX use a counter and leave at least one for mgmt frames */ - if (STAILQ_EMPTY(&sc->sc_txbuf)) { - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__); - sc->sc_stats.ast_tx_qstop++; - netif_stop_queue(&sc->sc_dev); - netif_stop_queue(&sc->sc_rawdev); - } - ATH_TXBUF_UNLOCK_BH(sc); - - if (bf == NULL) { /* NB: should not happen */ - DPRINTF(sc, ATH_DEBUG_ANY, "%s: out of xmit buffers\n", - __func__); - sc->sc_stats.ast_tx_nobuf++; - dev_kfree_skb(skb); - return 0; - } - - rt = sc->sc_currates; - KASSERT(rt != NULL, "no rate table, mode %u", sc->sc_curmode); - flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; - try0 = ATH_TXMAXTRY; - dot11_rate = 0; - ctsrate = 0; - ctsduration = 0; - pri = 0; - txpower = 60; - txq = sc->sc_ac2q[pri]; - txrate = rt->rates[0].rate_code; - atype = AR5K_PKT_TYPE_NORMAL; - - /* - * strip any physical layer header off the skb, if it is - * present, and read out any settings we can, like what txrate - * to send this packet at. - */ - switch(dev->type) { - case ARPHRD_IEEE80211: - break; - case ARPHRD_IEEE80211_PRISM: { - wlan_ng_prism2_header *ph = NULL; - ph = (wlan_ng_prism2_header *) skb->data; - /* does it look like there is a prism header here? */ - if (skb->len > sizeof (wlan_ng_prism2_header) && - ph->msgcode == DIDmsg_lnxind_wlansniffrm && - ph->rate.did == DIDmsg_lnxind_wlansniffrm_rate) { - dot11_rate = ph->rate.data; - skb_pull(skb, sizeof(wlan_ng_prism2_header)); - } - break; - } - case ARPHRD_IEEE80211_RADIOTAP: { - struct ieee80211_radiotap_header *th = (struct ieee80211_radiotap_header *) skb->data; - if (rt_check_header(th, skb->len)) { - if (rt_el_present(th, IEEE80211_RADIOTAP_RATE)) { - dot11_rate = *((u_int8_t *) rt_el_offset(th, - IEEE80211_RADIOTAP_RATE)); - } - if (rt_el_present(th, IEEE80211_RADIOTAP_DATA_RETRIES)) { - try0 = 1 + *((u_int8_t *) rt_el_offset(th, - IEEE80211_RADIOTAP_DATA_RETRIES)); - } - if (rt_el_present(th, IEEE80211_RADIOTAP_DBM_TX_POWER)) { - txpower = *((u_int8_t *) rt_el_offset(th, - IEEE80211_RADIOTAP_DBM_TX_POWER)); - if (txpower > 60) - txpower = 60; - - } - - skb_pull(skb, le16_to_cpu(th->it_len)); - } - break; - } - default: - /* nothing */ - break; - } - - if (dot11_rate != 0) { - int index = sc->sc_rixmap[dot11_rate & IEEE80211_RATE_VAL]; - if (index >= 0 && index < rt->rate_count) { - txrate = rt->rates[index].rate_code; - } - } - - wh = (struct ieee80211_frame *) skb->data; - pktlen = skb->len + IEEE80211_CRC_LEN; - hdrlen = sizeof(struct ieee80211_frame); - - if (hdrlen < pktlen) - hdrlen = pktlen; - - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= AR5K_TXDESC_NOACK; /* no ack on broad/multicast */ - sc->sc_stats.ast_tx_noack++; - } - - testmac[0] = 0x41; /* A */ - testmac[1] = 0x54; /* T */ - testmac[2] = 0x48; /* H */ - testmac[3] = 0x54; /* T */ - testmac[4] = 0x53; /* S */ - testmac[5] = 0x54; /* T */ - - if (IEEE80211_ADDR_EQ(wh->i_addr1, testmac)) { - flags |= AR5K_TXDESC_NOACK; /* no ack for test packets */ - sc->sc_stats.ast_tx_noack++; - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: output testpacket (len %i)\n", - __func__, skb->len); - } - - if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT)) - ieee80211_dump_pkt(skb->data, skb->len, - sc->sc_hwmap[txrate].ieeerate, -1); - - /* - * Load the DMA map so any coalescing is done. This - * also calculates the number of descriptors we need. - */ - bf->bf_skbaddr = bus_map_single(sc->sc_bdev, - skb->data, pktlen, BUS_DMA_TODEVICE); - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: skb %p [data %p len %u] skbaddr %lx\n", - __func__, skb, skb->data, skb->len, (long unsigned int) bf->bf_skbaddr); - if (BUS_DMA_MAP_ERROR(bf->bf_skbaddr)) { - if_printf(dev, "%s: DMA mapping failed\n", __func__); - dev_kfree_skb(skb); - bf->bf_skb = NULL; - sc->sc_stats.ast_tx_busdma++; - - ATH_TXBUF_LOCK_BH(sc); - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK_BH(sc); - return -EIO; - } - bf->bf_skb = skb; - bf->bf_node = NULL; - - /* setup descriptors */ - ds = bf->bf_desc; - rt = sc->sc_currates; - KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - - /* - * Formulate first tx descriptor with tx controls. - */ - /* XXX check return value? */ - ah->ah_setup_tx_desc(ah, ds - , pktlen /* packet length */ - , hdrlen /* header length */ - , atype /* Atheros packet type */ - , txpower /* txpower */ - , txrate, try0 /* series 0 rate/tries */ - , AR5K_TXKEYIX_INVALID /* key cache index */ - , sc->sc_txantenna /* antenna mode */ - , flags /* flags */ - , ctsrate /* rts/cts rate */ - , ctsduration /* rts/cts duration */ - ); - - /* - * Fillin the remainder of the descriptor info. - */ - ds->ds_link = 0; - ds->ds_data = bf->bf_skbaddr; - ah->ah_fill_tx_desc(ah, ds - , skb->len /* segment length */ - , true /* first segment */ - , true /* last segment */ - , ds /* first descriptor */ - ); - - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: Q%d: %08x %08x %08x %08x %08x %08x\n", - __func__, txq->axq_qnum, ds->ds_link, ds->ds_data, - ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]); - /* - * Insert the frame on the outbound list and - * pass it on to the hardware. - */ - ATH_TXQ_LOCK_BH(txq); -// if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { -// u_int32_t txopLimit = IEEE80211_TXOP_TO_US( -// cap->cap_wmeParams[pri].wmep_txopLimit); - /* - * When bursting, potentially extend the CTS duration - * of a previously queued frame to cover this frame - * and not exceed the txopLimit. If that can be done - * then disable RTS/CTS on this frame since it's now - * covered (burst extension). Otherwise we must terminate - * the burst before this frame goes out so as not to - * violate the WME parameters. All this is complicated - * as we need to update the state of packets on the - * (live) hardware queue. The logic is buried in the hal - * because it's highly chip-specific. - */ -// if (txopLimit != 0) { -// sc->sc_stats.ast_tx_ctsburst++; -// if (updateCTSForBursting(ah, ds, txq) == 0) { - /* - * This frame was not covered by RTS/CTS from - * the previous frame in the burst; update the - * descriptor pointers so this frame is now - * treated as the last frame for extending a - * burst. - */ -// txq->axq_lastdsWithCTS = ds; - /* set gating Desc to final desc */ -// txq->axq_gatingds = -// (struct ath_desc *)txq->axq_link; -// } else -// sc->sc_stats.ast_tx_ctsext++; -// } -// } - ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); - DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: txq depth = %d\n", - __func__, txq->axq_depth); - if (txq->axq_link == NULL) { - ath5k_hw_put_tx_buf(ah, txq->axq_qnum, bf->bf_daddr); - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: TXDP[%u] = %llx (%p) depth %d\n", __func__, - txq->axq_qnum, (unsigned long long)bf->bf_daddr, - bf->bf_desc, txq->axq_depth); - } else { - *txq->axq_link = bf->bf_daddr; - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: link[%u](%p)=%llx (%p) depth %d\n", __func__, - txq->axq_qnum, txq->axq_link, - (unsigned long long)bf->bf_daddr, bf->bf_desc, - txq->axq_depth); - } - txq->axq_link = &bf->bf_desc->ds_link; - /* - * The CAB queue is started from the SWBA handler since - * frames only go out on DTIM and to avoid possible races. - */ - if (txq != sc->sc_cabq) - ath5k_hw_tx_start(ah, txq->axq_qnum); - ATH_TXQ_UNLOCK_BH(txq); - - sc->sc_devstats.tx_packets++; - sc->sc_devstats.tx_bytes += skb->len; - sc->sc_dev.trans_start = jiffies; - sc->sc_rawdev.trans_start = jiffies; - - return 0; -//#undef updateCTSForBursting -#undef CTS_DURATION -} - -static int -ath_start(struct sk_buff *skb, struct net_device *dev) -{ -#define CLEANUP() \ - do{ \ - ATH_TXBUF_LOCK_BH(sc); \ - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); \ - ATH_TXBUF_UNLOCK_BH(sc); \ - if (ni != NULL) \ - ieee80211_free_node(ni); \ - } while (0) - - struct ath_softc *sc = dev->priv; - struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni; - struct ath_buf *bf; - struct ieee80211_cb *cb; - struct sk_buff *skb0; - struct ieee80211_frame *wh; - struct ether_header *eh; - - int ret = 0; - int counter = 0; - - if ((dev->flags & IFF_RUNNING) == 0 || sc->sc_invalid) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: discard, invalid %d flags %x\n", - __func__, sc->sc_invalid, dev->flags); - sc->sc_stats.ast_tx_invalid++; - return -ENETDOWN; - } - - for (;;) { - /* - * Grab a TX buffer and associated resources. - */ - ATH_TXBUF_LOCK_BH(sc); - bf = STAILQ_FIRST(&sc->sc_txbuf); - if (bf != NULL) - STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list); - /* XXX use a counter and leave at least one for mgmt frames */ - if (STAILQ_EMPTY(&sc->sc_txbuf)) { - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__); - sc->sc_stats.ast_tx_qstop++; - netif_stop_queue(dev); - if (sc->sc_rawdev_enabled) - netif_stop_queue(&sc->sc_rawdev); - } - ATH_TXBUF_UNLOCK_BH(sc); - - if (bf == NULL) { /* NB: should not happen */ - DPRINTF(sc, ATH_DEBUG_ANY, "%s: out of xmit buffers\n", - __func__); - sc->sc_stats.ast_tx_nobuf++; - break; - } - - /* - * Poll the management queue for frames; they - * have priority over normal data frames. - */ - IF_DEQUEUE(&ic->ic_mgtq, skb0); - - if (skb0 == NULL) { - /* - * data frames - */ - if (counter++ > 200) - DPRINTF(sc, ATH_DEBUG_FATAL, "%s (%s): endlessloop (data) (counter=%i)\n", __func__, dev->name, counter); - - if (!skb) { /* NB: no data (called for mgmt) */ - ATH_TXBUF_LOCK_BH(sc); - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK_BH(sc); - break; - } - /* - * No data frames go out unless we're associated; this - * should not happen as the 802.11 layer does not enable - * the xmit queue until we enter the RUN state. - */ - if (ic->ic_state != IEEE80211_S_RUN) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: ignore data packet, state %u\n", - __func__, ic->ic_state); - sc->sc_stats.ast_tx_discard++; - ATH_TXBUF_LOCK_BH(sc); - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK_BH(sc); - break; - } - /* - * Find the node for the destination so we can do - * things like power save and fast frames aggregation. - */ - if (skb->len < sizeof(struct ether_header)) { - ic->ic_stats.is_tx_nobuf++; /* XXX */ - ni = NULL; - - ret = 0; /* error return */ - CLEANUP(); - break; - } - eh = (struct ether_header *)skb->data; - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - /* NB: ieee80211_find_txnode does stat+msg */ - - ret = 0; /* error return */ - CLEANUP(); - break; - } - cb = (struct ieee80211_cb *)skb->cb; - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && - (cb->flags & M_PWR_SAV) == 0) { - /* - * Station in power save mode; pass the frame - * to the 802.11 layer and continue. We'll get - * the frame back when the time is right. - */ - ieee80211_pwrsave(ic, ni, skb); - /* don't free this on function exit point */ - skb = NULL; - CLEANUP(); - break; - } - /* calculate priority so we can find the tx queue */ - if (ieee80211_classify(ic, skb, ni)) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: discard, classification failure\n", - __func__); - - ret = 0; /* error return */ - CLEANUP(); - break; - } - sc->sc_devstats.tx_packets++; - sc->sc_devstats.tx_bytes += skb->len; - - /* - * Encapsulate the packet for transmission. - */ - skb = ieee80211_encap(ic, skb, ni); - if (skb == NULL) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: encapsulation failure\n", - __func__); - sc->sc_stats.ast_tx_encap++; - - ret = 0; /* error return */ - CLEANUP(); - break; - } - - /* - * using unified sk_buff for transmit data and management frames - */ - skb0 = skb; - } else { - /* - * management frames - */ - cb = (struct ieee80211_cb *)skb0->cb; - ni = cb->ni; - - if (counter++ > 200) - DPRINTF(sc, ATH_DEBUG_FATAL, "%s (%s): endlessloop (mgnt) (counter=%i)\n", __func__, dev->name, counter); - - wh = (struct ieee80211_frame *) skb0->data; - if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == - IEEE80211_FC0_SUBTYPE_PROBE_RESP) { - /* fill time stamp */ - u_int64_t tsf; - __le32 *tstamp; - - tsf = ath5k_hw_get_tsf64(ah); - /* XXX: adjust 100us delay to xmit */ - tsf += 100; - tstamp = (__le32 *)&wh[1]; - tstamp[0] = htole32(tsf & 0xffffffff); - tstamp[1] = htole32(tsf >> 32); - } - sc->sc_stats.ast_tx_mgmt++; - } - - if (ath_tx_start(dev, ni, bf, skb0)) { - ret = 0; /* TODO: error value */ - skb = NULL; /* ath_tx_start() already freed this */ - CLEANUP(); - continue; - } - /* - * the data frame is last - */ - if (skb0 == skb) { - skb = NULL; /* will be released by tx_processq */ - break; - } - sc->sc_tx_timer = 5; - mod_timer(&ic->ic_slowtimo, jiffies + HZ); - } - if (skb) - dev_kfree_skb(skb); - return ret; /* NB: return !0 only in a ``hard error condition'' */ -#undef CLEANUP -} - -static int -ath_media_change(struct net_device *dev) -{ -#define IS_UP(dev) \ - ((dev->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) - int error; - - error = ieee80211_media_change(dev); - if (error == ENETRESET) { - if (IS_UP(dev)) - error = ath_init(dev); - else - error = 0; - } - return error; -#undef IS_UP -} - #ifdef AR_DEBUG static void ath_keyprint(const char *tag, u_int ix, @@ -1110,20 +560,6 @@ ath_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) } /* - * Set the key cache contents for the specified key. Key cache - * slot(s) must already have been allocated by ath_key_alloc. - */ -static int -ath_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, - const u_int8_t mac[IEEE80211_ADDR_LEN]) -{ - struct net_device *dev = ic->ic_dev; - struct ath_softc *sc = dev->priv; - - return ath_keyset(sc, k, mac, ic->ic_bss); -} - -/* * Block/unblock tx+rx processing while a key change is done. * We assume the caller serializes key management operations * so we only need to worry about synchronization with other @@ -1768,71 +1204,7 @@ ath_beacon_config(struct ath_softc *sc) } #undef TSF_TO_TU } -#endif - -#ifdef BLE -static struct ieee80211_node * -ath_node_alloc(struct ieee80211_node_table *nt) -{ - struct ieee80211com *ic = nt->nt_ic; - struct ath_softc *sc = ic->ic_dev->priv; - const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space; - struct ath_node *an; - an = kmalloc(space, GFP_ATOMIC); - if (an == NULL) { - /* XXX stat+msg */ - return NULL; - } - memset(an, 0, space); - an->an_avgrssi = ATH_RSSI_DUMMY_MARKER; - an->an_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; - an->an_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; - an->an_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; - ath_rate_node_init(sc, an); - - DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an); - return &an->an_node; -} - -static void -ath_node_free(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_dev->priv; - DPRINTF(sc, ATH_DEBUG_NODE, "%s: ni %p\n", __func__, ni); -/* - for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) // TODO: seems we need this still - if (ATH_TXQ_SETUP(sc, i)) - ath_tx_cleanq(&sc->sc_txq[i], ni); -*/ - ath_rate_node_cleanup(sc, ATH_NODE(ni)); - sc->sc_node_free(ni); -} - -static u_int8_t -ath_node_getrssi(const struct ieee80211_node *ni) -{ -#define AR5K_EP_RND(x, mul) \ - ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) - u_int32_t avgrssi = ATH_NODE_CONST(ni)->an_avgrssi; - int32_t rssi; - - /* - * When only one frame is received there will be no state in - * avgrssi so fallback on the value recorded by the 802.11 layer. - */ - if (avgrssi != ATH_RSSI_DUMMY_MARKER) - rssi = AR5K_EP_RND(avgrssi, AR5K_RSSI_EP_MULTIPLIER); - else - rssi = ni->ni_rssi; - /* NB: theoretically we shouldn't need this, but be paranoid */ - return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi; -#undef AR5K_EP_RND -} -#endif - -#ifdef BLE /* * Add additional headers to a transmitted frame and netif_rx it on * a monitor or raw device @@ -2236,365 +1608,8 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna) sc->sc_rxotherant = 0; } -static void -ath_rx_tasklet(unsigned long data) -{ -#define PA2DESC(_sc, _pa) \ - ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \ - ((_pa) - (_sc)->sc_desc_daddr))) - struct net_device *dev = (struct net_device *)data; - struct ath_buf *bf; - struct ath_softc *sc = dev->priv; - struct ath_hal *ah = sc->sc_ah; - struct ath_desc *ds; - struct sk_buff *skb; -// struct ath_node *an; - int len;//, type; - u_int phyerr; - enum ath5k_status status; - - DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__); - do { -// bf = STAILQ_FIRST(&sc->sc_rxbuf); - bf = NULL; - if (bf == NULL) { /* XXX ??? can this happen */ - printk(KERN_ERR "%s: no buffer!\n", __func__); - break; - } - ds = bf->bf_desc; - if (ds->ds_link == bf->bf_daddr) { - /* NB: never process the self-linked entry at the end */ - break; - } - skb = bf->bf_skb; - if (skb == NULL) { /* XXX ??? can this happen */ - printk(KERN_ERR "%s: no skbuff!\n", __func__); - continue; - } - /* XXX sync descriptor memory */ - /* - * Must provide the virtual address of the current - * descriptor, the physical address, and the virtual - * address of the next descriptor in the h/w chain. - * This allows the HAL to look ahead to see if the - * hardware is done with a descriptor by checking the - * done bit in the following descriptor and the address - * of the current descriptor the DMA engine is working - * on. All this is necessary because of our use of - * a self-linked list to avoid rx overruns. - */ - status = ah->ah_proc_rx_desc(ah, ds, - bf->bf_daddr, PA2DESC(sc, ds->ds_link)); -#ifdef AR_DEBUG - if (sc->sc_debug & ATH_DEBUG_RECV_DESC) - ath_printrxbuf(bf, status == AR5K_OK); -#endif - if (status == AR5K_EINPROGRESS) - break; -// STAILQ_REMOVE_HEAD(&sc->sc_rxbuf, bf_list); - if (ds->ds_rxstat.rs_more) { - /* - * Frame spans multiple descriptors; this - * cannot happen yet as we don't support - * jumbograms. If not in monitor mode, - * discard the frame. - */ -#ifndef ERROR_FRAMES - /* - * Enable this if you want to see - * error frames in Monitor mode. - */ - if (sc->sc_opmode != IEEE80211_IF_TYPE_MNTR) { - sc->sc_stats.ast_rx_toobig++; - goto rx_next; - } -#endif - /* fall thru for monitor mode handling... */ - } else if (ds->ds_rxstat.rs_status != 0) { - if (ds->ds_rxstat.rs_status & AR5K_RXERR_CRC) - sc->sc_stats.ast_rx_crcerr++; - if (ds->ds_rxstat.rs_status & AR5K_RXERR_FIFO) - sc->sc_stats.ast_rx_fifoerr++; - if (ds->ds_rxstat.rs_status & AR5K_RXERR_PHY) { - sc->sc_stats.ast_rx_phyerr++; - phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; - sc->sc_stats.ast_rx_phy[phyerr]++; -/* - if (phyerr == AR5K_PHYERR_RADAR && ic->ic_opmode == IEEE80211_M_HOSTAP) - { - tasklet_schedule(&sc->sc_radartq); - } -*/ - goto rx_next; - } - if (ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) { - /* - * Decrypt error. If the error occurred - * because there was no hardware key, then - * let the frame through so the upper layers - * can process it. This is necessary for 5210 - * parts which have no way to setup a ``clear'' - * key cache entry. - * - * XXX do key cache faulting - */ - if (ds->ds_rxstat.rs_keyix == AR5K_RXKEYIX_INVALID) - goto rx_accept; - sc->sc_stats.ast_rx_badcrypt++; - } - if (ds->ds_rxstat.rs_status & AR5K_RXERR_MIC) { - sc->sc_stats.ast_rx_badmic++; - /* - * Do minimal work required to hand off - * the 802.11 header for notifcation. - */ - /* XXX frag's and qos frames */ -#ifdef BLE - len = ds->ds_rxstat.rs_datalen; - if (len >= sizeof (struct ieee80211_frame)) { - bus_dma_sync_single(sc->sc_bdev, - bf->bf_skbaddr, len, - BUS_DMA_FROMDEVICE); - ieee80211_notify_michael_failure(ic, - (struct ieee80211_frame *) skb->data, - sc->sc_splitmic ? - ds->ds_rxstat.rs_keyix-32 : - ds->ds_rxstat.rs_keyix - ); - } -#endif - } - - // TODO: correct? -// ic->ic_devstats->rx_errors++; - - /* - * accept error frames on the raw device - * or in monitor mode if we ask for them. - * we'll explicity drop them after capture. - */ - if (sc->sc_rxfilter & AR5K_RX_FILTER_PHYERROR) - goto rx_accept; - - /* - * Reject error frames, we normally don't want - * to see them in monitor mode (in monitor mode - * allow through packets that have crypto problems). - */ - if ((ds->ds_rxstat.rs_status &~ - (AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || - sc->sc_opmode != IEEE80211_IF_TYPE_MNTR) - goto rx_next; - } -rx_accept: - /* - * Sync and unmap the frame. At this point we're - * committed to passing the sk_buff somewhere so - * clear buf_skb; this means a new sk_buff must be - * allocated when the rx descriptor is setup again - * to receive another frame. - */ - len = ds->ds_rxstat.rs_datalen; - bus_dma_sync_single(sc->sc_bdev, - bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE); - bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr, - sc->sc_rxbufsize, BUS_DMA_FROMDEVICE); - bf->bf_skb = NULL; - - sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++; -#ifdef BLE - if (len < IEEE80211_ACK_LEN) { - DPRINTF(sc, ATH_DEBUG_RECV, - "%s: runt packet %d\n", __func__, len); - sc->sc_stats.ast_rx_tooshort++; - dev_kfree_skb(skb); - goto rx_next; - } -#endif - KASSERT(len <= skb_tailroom(skb), "not enough tailroom " - "(%d vs %d)", len, skb_tailroom(skb)); - - skb_put(skb, len); - skb->protocol = __constant_htons(ETH_P_CONTROL); -#ifdef BLE - if (sc->sc_rawdev_enabled && - (sc->sc_rawdev.flags & IFF_UP)) { - struct sk_buff *skb2; - skb2 = skb_copy(skb, GFP_ATOMIC); - if (skb2) { - ath_rx_capture(&sc->sc_rawdev, ds, skb2); - } - } -#endif - if (sc->sc_opmode == IEEE80211_IF_TYPE_MNTR) { - /* - * Monitor mode: discard anything shorter than - * an ack or cts, clean the skbuff, fabricate - * the Prism header existing tools expect, - * and dispatch. - */ - /* XXX TSF */ - - ath_rx_capture(dev, ds, skb); - goto rx_next; - } - - - /* - * At this point we have no need for error frames - * that aren't crypto problems since we're done - * with capture. - */ - if (ds->ds_rxstat.rs_status &~ - (AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) { - dev_kfree_skb(skb); - goto rx_next; - } - /* - * From this point on we assume the frame is at least - * as large as ieee80211_frame_min; verify that. - */ -#ifdef BLE - if (len < IEEE80211_MIN_LEN) { - DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n", - __func__, len); - sc->sc_stats.ast_rx_tooshort++; - dev_kfree_skb(skb); - goto rx_next; - } - - /* - * Normal receive. - */ - if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) { - ieee80211_dump_pkt(skb->data, len, - sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate, - ds->ds_rxstat.rs_rssi); - } - - skb_trim(skb, skb->len - IEEE80211_CRC_LEN); - - /* - * Locate the node for sender, track state, and then - * pass the (referenced) node up to the 802.11 layer - * for its use. If the sender is unknown spam the - * frame; it'll be dropped where it's not wanted. - */ - if (ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID && - (ni = sc->sc_keyixmap[ds->ds_rxstat.rs_keyix]) != NULL) { - /* - * Fast path: node is present in the key map; - * grab a reference for processing the frame. - */ - DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: node %s in keymap\n", - __func__, ether_sprintf(ni->ni_macaddr)); - - an = ATH_NODE(ieee80211_ref_node(ni)); - ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi); - type = ieee80211_input(ic, skb, ni, - ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp); - } else { - /* - * Locate the node for sender, track state, and then - * pass the (referenced) node up to the 802.11 layer - * for its use. - */ - ni = ieee80211_find_rxnode(ic, - (struct ieee80211_frame_min *)skb->data); - /* - * Track rx rssi and do any rx antenna management. - */ - an = ATH_NODE(ni); - ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi); - /* - * Send frame up for processing. - */ - type = ieee80211_input(ic, skb, ni, - ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp); - if (ni != ic->ic_bss) { - u_int16_t keyix; - /* - * If the station has a key cache slot assigned - * update the key->node mapping table. - */ - keyix = ni->ni_ucastkey.wk_keyix; - if (keyix != IEEE80211_KEYIX_NONE && - sc->sc_keyixmap[keyix] == NULL) - sc->sc_keyixmap[keyix] = - ieee80211_ref_node(ni); - } - } - ieee80211_free_node(ni); - if (sc->sc_diversity) { - /* - * When using fast diversity, change the default rx - * antenna if diversity chooses the other antenna 3 - * times in a row. - */ - if (sc->sc_defant != ds->ds_rxstat.rs_antenna) { - if (++sc->sc_rxotherant >= 3) - ath_setdefantenna(sc, - ds->ds_rxstat.rs_antenna); - } else - sc->sc_rxotherant = 0; - } - - if (sc->sc_softled) { - /* - * Blink for any data frame. Otherwise do a - * heartbeat-style blink when idle. The latter - * is mainly for station mode where we depend on - * periodic beacon frames to trigger the poll event. - */ - if (type == IEEE80211_FC0_TYPE_DATA) { - sc->sc_rxrate = ds->ds_rxstat.rs_rate; - ath_led_event(sc, ATH_LED_RX); - } else if (jiffies - sc->sc_ledevent >= sc->sc_ledidle) - ath_led_event(sc, ATH_LED_POLL); - } -#endif -rx_next: -// STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); - ; - } while (ath_rxbuf_init(sc, bf) == 0); - - /* rx signal state monitoring */ -// ath5k_hw_set_rx_signal(ah, &ATH_NODE(ic->ic_bss)->an_halstats); - -#undef PA2DESC -} - #ifdef BLE /* - * Setup a hardware data transmit queue for the specified - * access control. The hal may not support all requested - * queues in which case it will return a reference to a - * previously setup queue. We record the mapping from ac's - * to h/w queues for use by ath_tx_start and also track - * the set of h/w queues being used to optimize work in the - * transmit interrupt handler and related routines. - */ -static int -ath_tx_setup(struct ath_softc *sc, int ac, int haltype) -{ -#define N(a) (sizeof(a)/sizeof(a[0])) - struct ath_txq *txq; - - if (ac >= N(sc->sc_ac2q)) { - printk("%s: AC %u out of range, max %u!\n", - sc->sc_dev.name, ac, (unsigned int) N(sc->sc_ac2q)); - return 0; - } - txq = ath_txq_setup(sc, AR5K_TX_QUEUE_DATA, haltype); - if (txq != NULL) { - sc->sc_ac2q[ac] = txq; - return 1; - } else - return 0; -#undef N -} - -/* * Update WME parameters for a transmit queue. */ static int @@ -2640,595 +1655,6 @@ ath_wme_update(struct ieee80211com *ic) !ath_txq_update(sc, WME_AC_VO) ? EIO : 0; } -static int -ath_tx_start(struct net_device *dev, struct ieee80211_node *ni, struct ath_buf *bf, - struct sk_buff *skb) -{ -#define CTS_DURATION \ - ath_hal_computetxtime(ah, rt, IEEE80211_ACK_LEN, cix, true) -/*#define updateCTSForBursting(_ah, _ds, _txq) \ - ath_hal_updateCTSForBursting(_ah, _ds, \ - _txq->axq_linkbuf != NULL ? _txq->axq_linkbuf->bf_desc : NULL, \ - _txq->axq_lastdsWithCTS, _txq->axq_gatingds, \ - txopLimit, CTS_DURATION)*/ - struct ath_softc *sc = dev->priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc->sc_ah; - const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; - int iswep, ismcast, keyix, hdrlen, pktlen, try0; - u_int8_t rix, txrate, ctsrate; - u_int8_t cix = 0xff; /* NB: silence compiler */ - struct ath_desc *ds; - struct ath_txq *txq; - struct ieee80211_frame *wh; - u_int subtype, flags, ctsduration; - AR5K_PKT_TYPE atype; - const struct ath5k_rate_table *rt; - bool short_preamble; - struct ath_node *an; - struct llc *llc; - int eapol; - u_int pri; - - wh = (struct ieee80211_frame *) skb->data; - iswep = wh->i_fc[1] & IEEE80211_FC1_WEP; - ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); - hdrlen = ieee80211_anyhdrsize(wh); - // TODO: not so correct (WDS) - llc = (struct llc *) (skb->data + sizeof(struct ieee80211_frame)); - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: ether_type: 0x%x\n", - __func__, ntohs(llc->llc_snap.ether_type)); - if (llc->llc_snap.ether_type == __constant_htons(ETHERTYPE_PAE)) - eapol = 1; - else - eapol = 0; - llc = NULL; - - /* - * Packet length must not include any - * pad bytes; deduct them here. - */ - //TODO: ??? pktlen = m0->m_pkthdr.len - (hdrlen & 3); - pktlen = skb->len - (hdrlen & 3); - - if (iswep) { - const struct ieee80211_cipher *cip; - struct ieee80211_key *k; - - /* - * Construct the 802.11 header+trailer for an encrypted - * frame. The only reason this can fail is because of an - * unknown or unsupported cipher/key type. - */ - k = ieee80211_crypto_encap(ic, ni, skb); - if (k == NULL) { - /* - * This can happen when the key is yanked after the - * frame was queued. Just discard the frame; the - * 802.11 layer counts failures and provides - * debugging/diagnostics. - */ - dev_kfree_skb(skb); - return -EIO; - } - /* - * Adjust the packet + header lengths for the crypto - * additions and calculate the h/w key index. When - * a s/w mic is done the frame will have had any mic - * added to it prior to entry so skb->len above will - * account for it. Otherwise we need to add it to the - * packet length. - */ - cip = k->wk_cipher; - hdrlen += cip->ic_header; - pktlen += cip->ic_header + cip->ic_trailer; - if ((k->wk_flags & IEEE80211_KEY_SWMIC) == 0) - pktlen += cip->ic_miclen; - keyix = k->wk_keyix; - - /* packet header may have moved, reset our local pointer */ - wh = (struct ieee80211_frame *) skb->data; - } else if (ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) { - /* - * Use station key cache slot, if assigned. - */ - keyix = ni->ni_ucastkey.wk_keyix; - if (keyix == IEEE80211_KEYIX_NONE) - keyix = AR5K_TXKEYIX_INVALID; - } else - keyix = AR5K_TXKEYIX_INVALID; - - pktlen += IEEE80211_CRC_LEN; - - /* - * Load the DMA map so any coalescing is done. This - * also calculates the number of descriptors we need. - */ - bf->bf_skbaddr = bus_map_single(sc->sc_bdev, - skb->data, pktlen, BUS_DMA_TODEVICE); - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: skb %p [data %p len %u] skbaddr %lx\n", - __func__, skb, skb->data, skb->len, (long unsigned int) bf->bf_skbaddr); - if (BUS_DMA_MAP_ERROR(bf->bf_skbaddr)) { - if_printf(dev, "%s: DMA mapping failed\n", __func__); - dev_kfree_skb(skb); - bf->bf_skb = NULL; - sc->sc_stats.ast_tx_busdma++; - return -EIO; - } - bf->bf_skb = skb; - bf->bf_node = ni; - - /* setup descriptors */ - ds = bf->bf_desc; - rt = sc->sc_currates; - KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - - /* - * NB: the 802.11 layer marks whether or not we should - * use short preamble based on the current mode and - * negotiated parameters. - */ - if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && - (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { - short_preamble = true; - sc->sc_stats.ast_tx_shortpre++; - } else { - short_preamble = false; - } - - an = ATH_NODE(ni); - flags = AR5K_TXDESC_CLRDMASK; /* XXX needed for crypto errs */ - /* - * Calculate Atheros packet type from IEEE80211 packet header, - * setup for rate calculations, and select h/w transmit queue. - */ - switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { - case IEEE80211_FC0_TYPE_MGT: - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) - atype = AR5K_PKT_TYPE_BEACON; - else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) - atype = AR5K_PKT_TYPE_PROBE_RESP; - else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM) - atype = AR5K_PKT_TYPE_ATIM; - else - atype = AR5K_PKT_TYPE_NORMAL; /* XXX */ - rix = 0; /* XXX lowest rate */ - try0 = ATH_TXMAXTRY; - if (short_preamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; - /* NB: force all management frames to highest queue */ - if (ni->ni_flags & IEEE80211_NODE_QOS) { - pri = WME_AC_VO; - } else - pri = WME_AC_BE; - flags |= AR5K_TXDESC_INTREQ; /* force interrupt */ - break; - case IEEE80211_FC0_TYPE_CTL: - atype = AR5K_PKT_TYPE_PSPOLL; /* stop setting of duration */ - rix = 0; /* XXX lowest rate */ - try0 = ATH_TXMAXTRY; - if (short_preamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; - /* NB: force all ctl frames to highest queue */ - if (ni->ni_flags & IEEE80211_NODE_QOS) { - pri = WME_AC_VO; - } else - pri = WME_AC_BE; - flags |= AR5K_TXDESC_INTREQ; /* force interrupt */ - break; - case IEEE80211_FC0_TYPE_DATA: - atype = AR5K_PKT_TYPE_NORMAL; /* default */ - if (ismcast) { - rix = 0; /* XXX lowest rate */ - try0 = 0; - if (short_preamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; - } - else if (eapol) { - rix = 0; /* XXX lowest rate */ - try0 = 0; // TODO: userspace or hardware retry? - if (short_preamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; - flags |= AR5K_TXDESC_INTREQ; /* force interrupt */ - } else { - if (ic->ic_fixed_rate == -1) { - /* - * Data frames; consult the rate control module. - */ - ath_rate_findrate(sc, an, short_preamble, pktlen, - &rix, &try0, &txrate); - } - else { - rix = ic->ic_fixed_rate; - try0 = ATH_TXMAXTRY; //XXX: should be configurabe - if (short_preamble) - txrate = rt->rates[rix].rate_code | SHPREAMBLE_FLAG(rix); - else - txrate = rt->rates[rix].rate_code; - } - } - sc->sc_txrate = txrate; /* for LED blinking */ - /* - * Default all non-QoS traffic to the background queue. - */ - if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { - pri = M_WME_GETAC(skb); - if (cap->cap_wmeParams[pri].wmep_noackPolicy) { - flags |= AR5K_TXDESC_NOACK; - sc->sc_stats.ast_tx_noack++; - } - } else - pri = WME_AC_BE; - break; - default: - if_printf(dev, "bogus frame type 0x%x (%s)\n", - wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); - /* XXX statistic */ - DPRINTF(sc, ATH_DEBUG_FATAL, "%s: kfree_skb: skb %p [data %p len %u] skbaddr %lx\n", - __func__, skb, skb->data, skb->len, (long unsigned int) bf->bf_skbaddr); - dev_kfree_skb(skb); - bf->bf_skb = NULL; - return -EIO; - } - txq = sc->sc_ac2q[pri]; - - DPRINTF(sc, ATH_DEBUG_RATE, "%s: [%s] rix %d, try %d, txrate %d (rs_nrates %d)\n", - __func__, ether_sprintf(ni->ni_macaddr), - rix, try0, txrate, ni->ni_rates.rs_nrates); - - /* - * When servicing one or more stations in power-save mode - * multicast frames must be buffered until after the beacon. - * We use the CAB queue for that. - */ - if (ismcast && ic->ic_ps_sta) { - txq = sc->sc_cabq; - /* XXX? more bit in 802.11 frame header */ - } - - /* - * Calculate miscellaneous flags. - */ - if (ismcast) { - flags |= AR5K_TXDESC_NOACK; /* no ack on broad/multicast */ - sc->sc_stats.ast_tx_noack++; - } else if (pktlen > ic->ic_rtsthreshold) { - flags |= AR5K_TXDESC_RTSENA; /* RTS based on frame length */ - cix = rt->rates[rix].control_rate; - sc->sc_stats.ast_tx_rts++; - } - - /* - * If 802.11g protection is enabled, determine whether - * to use RTS/CTS or just CTS. Note that this is only - * done for OFDM unicast frames. - */ - if ((ic->ic_flags & IEEE80211_F_USEPROT) && - rt->rates[rix].modulation == MODULATION_OFDM && - (flags & AR5K_TXDESC_NOACK) == 0) { - /* XXX fragments must use CCK rates w/ protection */ - if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) - flags |= AR5K_TXDESC_RTSENA; - else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) - flags |= AR5K_TXDESC_CTSENA; - cix = rt->rates[sc->sc_protrix].control_rate; - sc->sc_stats.ast_tx_protect++; - } - - /* - * Calculate duration. This logically belongs in the 802.11 - * layer but it lacks sufficient information to calculate it. - */ - if ((flags & AR5K_TXDESC_NOACK) == 0 && - (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) { - u_int16_t dur; - /* - * XXX not right with fragmentation. - */ - if (short_preamble) - dur = rt->rates[rix].sp_ack_duration; - else - dur = rt->rates[rix].lp_ack_duration; - wh->i_dur = htole16(dur); - } - - /* - * Calculate RTS/CTS rate and duration if needed. - */ - ctsduration = 0; - if (flags & (AR5K_TXDESC_RTSENA|AR5K_TXDESC_CTSENA)) { - /* - * CTS transmit rate is derived from the transmit rate - * by looking in the h/w rate table. We must also factor - * in whether or not a short preamble is to be used. - */ - /* NB: cix is set above where RTS/CTS is enabled */ - KASSERT(cix != 0xff, ("cix not setup")); - ctsrate = rt->rates[cix].rate_code; - /* - * Compute the transmit duration based on the frame - * size and the size of an ACK frame. We call into the - * HAL to do the computation since it depends on the - * characteristics of the actual PHY being used. - * - * NB: CTS is assumed the same size as an ACK so we can - * use the precalculated ACK durations. - */ - if (short_preamble) { - ctsrate |= SHPREAMBLE_FLAG(cix); - if (flags & AR5K_TXDESC_RTSENA) /* SIFS + CTS */ - ctsduration += rt->rates[cix].sp_ack_duration; - ctsduration += ath_hal_computetxtime(ah, - rt, pktlen, rix, true); - if ((flags & AR5K_TXDESC_NOACK) == 0) /* SIFS + ACK */ - ctsduration += rt->rates[cix].sp_ack_duration; - } else { - if (flags & AR5K_TXDESC_RTSENA) /* SIFS + CTS */ - ctsduration += rt->rates[cix].lp_ack_duration; - ctsduration += ath_hal_computetxtime(ah, - rt, pktlen, rix, false); - if ((flags & AR5K_TXDESC_NOACK) == 0) /* SIFS + ACK */ - ctsduration += rt->rates[cix].lp_ack_duration; - } - /* - * Must disable multi-rate retry when using RTS/CTS. - */ - try0 = ATH_TXMAXTRY; - } else - ctsrate = 0; - - if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT)) - ieee80211_dump_pkt(skb->data, skb->len, - sc->sc_hwmap[txrate].ieeerate, -1); - - /* - * Determine if a tx interrupt should be generated for - * this descriptor. We take a tx interrupt to reap - * descriptors when the h/w hits an EOL condition or - * when the descriptor is specifically marked to generate - * an interrupt. We periodically mark descriptors in this - * way to insure timely replenishing of the supply needed - * for sending frames. Defering interrupts reduces system - * load and potentially allows more concurrent work to be - * done but if done to aggressively can cause senders to - * backup. - * - * NB: use >= to deal with sc_txintrperiod changing - * dynamically through sysctl. - */ - if (flags & AR5K_TXDESC_INTREQ) { - txq->axq_intrcnt = 0; - } else if (++txq->axq_intrcnt >= sc->sc_txintrperiod) { - flags |= AR5K_TXDESC_INTREQ; - txq->axq_intrcnt = 0; - } - - /* - * Formulate first tx descriptor with tx controls. - */ - /* XXX check return value? */ - ah->ah_setup_tx_desc(ah, ds - , pktlen /* packet length */ - , hdrlen /* header length */ - , atype /* Atheros packet type */ - , ni->ni_txpower /* txpower */ - , txrate, try0 /* series 0 rate/tries */ - , keyix /* key cache index */ - , sc->sc_txantenna /* antenna mode */ - , flags /* flags */ - , ctsrate /* rts/cts rate */ - , ctsduration /* rts/cts duration */ - ); - bf->bf_flags = flags; - /* - * Setup the multi-rate retry state only when we're - * going to use it. This assumes ath_hal_setuptxdesc - * initializes the descriptors (so we don't have to) - * when the hardware supports multi-rate retry and - * we don't use it. - */ - if (try0 != ATH_TXMAXTRY) - ath_rate_setupxtxdesc(sc, an, ds, short_preamble, rix); - - /* - * Fillin the remainder of the descriptor info. - */ - ds->ds_link = 0; - ds->ds_data = bf->bf_skbaddr; - ah->ah_fill_tx_desc(ah, ds - , skb->len /* segment length */ - , true /* first segment */ - , true /* last segment */ - , ds /* first descriptor */ - ); - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: Q%d: %08x %08x %08x %08x %08x %08x\n", - __func__, txq->axq_qnum, ds->ds_link, ds->ds_data, - ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]); - /* - * Insert the frame on the outbound list and - * pass it on to the hardware. - */ - ATH_TXQ_LOCK_BH(txq); - if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { -// u_int32_t txopLimit = IEEE80211_TXOP_TO_US( -// cap->cap_wmeParams[pri].wmep_txopLimit); - /* - * When bursting, potentially extend the CTS duration - * of a previously queued frame to cover this frame - * and not exceed the txopLimit. If that can be done - * then disable RTS/CTS on this frame since it's now - * covered (burst extension). Otherwise we must terminate - * the burst before this frame goes out so as not to - * violate the WME parameters. All this is complicated - * as we need to update the state of packets on the - * (live) hardware queue. The logic is buried in the hal - * because it's highly chip-specific. - */ -// if (txopLimit != 0) { -// sc->sc_stats.ast_tx_ctsburst++; -// if (updateCTSForBursting(ah, ds, txq) == 0) { - /* - * This frame was not covered by RTS/CTS from - * the previous frame in the burst; update the - * descriptor pointers so this frame is now - * treated as the last frame for extending a - * burst. - */ -// txq->axq_lastdsWithCTS = ds; - /* set gating Desc to final desc */ -// txq->axq_gatingds = -// (struct ath_desc *)txq->axq_link; -// } else -// sc->sc_stats.ast_tx_ctsext++; -// } - } - ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); - DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: txq depth = %d\n", - __func__, txq->axq_depth); - if (txq->axq_link == NULL) { - ath5k_hw_put_tx_buf(ah, txq->axq_qnum, bf->bf_daddr); - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: TXDP[%u] = %llx (%p) depth %d\n", __func__, - txq->axq_qnum, (unsigned long long)bf->bf_daddr, - bf->bf_desc, txq->axq_depth); - } else { - *txq->axq_link = bf->bf_daddr; - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: link[%u](%p)=%llx (%p) depth %d\n", __func__, - txq->axq_qnum, txq->axq_link, - (unsigned long long)bf->bf_daddr, bf->bf_desc, - txq->axq_depth); - } - txq->axq_link = &bf->bf_desc->ds_link; - /* - * The CAB queue is started from the SWBA handler since - * frames only go out on DTIM and to avoid possible races. - */ - if (txq != sc->sc_cabq) - ath5k_hw_tx_start(ah, txq->axq_qnum); - ATH_TXQ_UNLOCK_BH(txq); - - dev->trans_start = jiffies; - sc->sc_rawdev.trans_start = jiffies; - return 0; -//#undef updateCTSForBursting -#undef CTS_DURATION -} - -/* - * Process completed xmit descriptors from the specified queue. - */ -static void -ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) -{ - struct ath_hal *ah = sc->sc_ah; - struct ath_buf *bf; - struct ath_desc *ds; -// struct ieee80211_node *ni; -// struct ath_node *an; -// int sr, lr, pri; - enum ath5k_status status; - - DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %x link %p\n", - __func__, txq->axq_qnum, - ath5k_hw_get_tx_buf(sc->sc_ah, txq->axq_qnum), txq->axq_link); - for (;;) { - ATH_TXQ_LOCK(txq); - txq->axq_intrcnt = 0; /* reset periodic desc intr count */ -// bf = STAILQ_FIRST(&txq->axq_q); - if (bf == NULL) { - txq->axq_link = NULL; - ATH_TXQ_UNLOCK(txq); - break; - } - ds = bf->bf_desc; /* NB: last decriptor */ - status = ah->ah_proc_tx_desc(ah, ds); -#ifdef AR_DEBUG - if (sc->sc_debug & ATH_DEBUG_XMIT_DESC) - ath_printtxbuf(bf, status == AR5K_OK); -#endif - if (status == AR5K_EINPROGRESS) { - ATH_TXQ_UNLOCK(txq); - break; - } - if (ds == txq->axq_lastdsWithCTS) - txq->axq_lastdsWithCTS = NULL; - if (ds == txq->axq_gatingds) - txq->axq_gatingds = NULL; -// ATH_TXQ_REMOVE_HEAD(txq, bf_list); - ATH_TXQ_UNLOCK(txq); -#ifdef BLE - ni = bf->bf_node; - if (ni != NULL) { - an = ATH_NODE(ni); - if (ds->ds_txstat.ts_status == 0) { - u_int8_t txant = ds->ds_txstat.ts_antenna; - sc->sc_stats.ast_ant_tx[txant]++; - sc->sc_ant_tx[txant]++; - if (ds->ds_txstat.ts_rate & AR5K_TXSTAT_ALTRATE) - sc->sc_stats.ast_tx_altrate++; - sc->sc_stats.ast_tx_rssi = - ds->ds_txstat.ts_rssi; - ATH_RSSI_LPF(an->an_halstats.ns_avgtxrssi, - ds->ds_txstat.ts_rssi); - pri = M_WME_GETAC(bf->bf_skb); - if (pri >= WME_AC_VO) - ic->ic_wme.wme_hipri_traffic++; - ni->ni_inact = ni->ni_inact_reload; - } else { - if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY) - sc->sc_stats.ast_tx_xretries++; - if (ds->ds_txstat.ts_status & AR5K_TXERR_FIFO) - sc->sc_stats.ast_tx_fifoerr++; - if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT) - sc->sc_stats.ast_tx_filtered++; - } - sr = ds->ds_txstat.ts_shortretry; - lr = ds->ds_txstat.ts_longretry; - sc->sc_stats.ast_tx_shortretry += sr; - sc->sc_stats.ast_tx_longretry += lr; - /* - * Hand the descriptor to the rate control algorithm. - */ - if ((ds->ds_txstat.ts_status & AR5K_TXERR_FILT) == 0 && - (bf->bf_flags & AR5K_TXDESC_NOACK) == 0) - ath_rate_tx_complete(sc, an, ds); - /* - * Reclaim reference to node. - * - * NB: the node may be reclaimed here if, for example - * this is a DEAUTH message that was sent and the - * node was timed out due to inactivity. - */ - ieee80211_free_node(ni); - } -#endif - bus_unmap_single(sc->sc_bdev, - bf->bf_skbaddr, bf->bf_skb->len, BUS_DMA_TODEVICE); - - if (sc->sc_rawdev_enabled) { - ath_tx_capture(&sc->sc_rawdev, ds, bf->bf_skb); - } else { - dev_kfree_skb(bf->bf_skb); - } - bf->bf_skb = NULL; -// bf->bf_node = NULL; - - ATH_TXBUF_LOCK(sc); -// STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK(sc); - } -} - /* * Deferred processing of transmit interrupt; special-cased * for a single hardware transmit queue (e.g. 5210 and 5211). @@ -3538,75 +1964,6 @@ ath_newassoc(struct ieee80211_node *ni, int isnew) } } -static int -ath_rawdev_attach(struct ath_softc *sc) -{ - struct net_device *rawdev; - unsigned t; - rawdev = &sc->sc_rawdev; - strcpy(rawdev->name, sc->sc_dev.name); - strcat(rawdev->name, "raw"); - rawdev->priv = sc; - - /* ether_setup clobbers type, so save it */ - t = rawdev->type; - ether_setup(rawdev); - rawdev->type = t; - - rawdev->stop = NULL; - rawdev->hard_start_xmit = ath_start_raw; - rawdev->set_multicast_list = NULL; - rawdev->get_stats = ath_getstats; - rawdev->tx_queue_len = ATH_TXBUF; - rawdev->flags |= IFF_NOARP; - rawdev->flags &= ~IFF_MULTICAST; - rawdev->mtu = IEEE80211_MAX_LEN; - - if (register_netdev(rawdev)) { - goto bad; - } - - if ((sc->sc_dev.flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) - netif_start_queue(&sc->sc_rawdev); - - sc->sc_rawdev_enabled = 1; - - return 0; - bad: - return -1; -} - -static void -ath_rawdev_detach(struct ath_softc *sc) -{ - if (sc->sc_rawdev_enabled) { - sc->sc_rawdev_enabled = 0; - netif_stop_queue(&sc->sc_rawdev); - unregister_netdev(&sc->sc_rawdev); - } -} - -#if IEEE80211_VLAN_TAG_USED -static void -ath_vlan_register(struct net_device *dev, struct vlan_group *grp) -{ - struct ath_softc *sc = dev->priv; - struct ieee80211com *ic = &sc->sc_ic; - - ieee80211_vlan_register(ic, grp); -} - -static void -ath_vlan_kill_vid(struct net_device *dev, unsigned short vid) -{ - struct ath_softc *sc = dev->priv; - struct ieee80211com *ic = &sc->sc_ic; - - ieee80211_vlan_kill_vid(ic, vid); -} -#endif /* IEEE80211_VLAN_TAG_USED */ -#endif -#ifdef BLE /* * Return netdevice statistics. */ @@ -3662,257 +2019,6 @@ ath_iw_getstats(struct net_device *dev) } /* - * Bounce functions to get to the 802.11 code. These are - * necessary for now because wireless extensions operations - * are done on the underlying device and not the 802.11 instance. - * This will change when there can be multiple 802.11 instances - * associated with a device and we must have a net_device for - * each so we can manipulate them individually. - */ -#define ATH_CHAR_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - char *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_POINT_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - struct iw_point *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_PARAM_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - struct iw_param *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_SOCKADDR_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - struct sockaddr *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_FREQ_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - struct iw_freq *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_U32_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - __u32 *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} -#define ATH_VOID_BOUNCE(name) \ -static int \ -ath_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \ - void *erq, char *extra) \ -{ \ - struct ath_softc *sc = dev->priv; \ - return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \ -} - -ATH_CHAR_BOUNCE(giwname) -ATH_POINT_BOUNCE(siwencode) -ATH_POINT_BOUNCE(giwencode) -ATH_PARAM_BOUNCE(siwrate) -ATH_PARAM_BOUNCE(giwrate) -ATH_PARAM_BOUNCE(siwsens) -ATH_PARAM_BOUNCE(giwsens) -ATH_PARAM_BOUNCE(siwrts) -ATH_PARAM_BOUNCE(giwrts) -ATH_PARAM_BOUNCE(siwfrag) -ATH_PARAM_BOUNCE(giwfrag) -ATH_SOCKADDR_BOUNCE(siwap) -ATH_SOCKADDR_BOUNCE(giwap) -ATH_POINT_BOUNCE(siwnickn) -ATH_POINT_BOUNCE(giwnickn) -ATH_FREQ_BOUNCE(siwfreqx) -ATH_FREQ_BOUNCE(giwfreq) -ATH_POINT_BOUNCE(siwessid) -ATH_POINT_BOUNCE(giwessid) -ATH_POINT_BOUNCE(giwrange) -ATH_U32_BOUNCE(siwmode) -ATH_U32_BOUNCE(giwmode) -ATH_PARAM_BOUNCE(siwpower) -ATH_PARAM_BOUNCE(giwpower) -ATH_PARAM_BOUNCE(siwretry) -ATH_PARAM_BOUNCE(giwretry) -ATH_PARAM_BOUNCE(siwtxpow) -ATH_PARAM_BOUNCE(giwtxpow) -ATH_POINT_BOUNCE(iwaplist) -#ifdef SIOCGIWSCAN -ATH_POINT_BOUNCE(siwscan) -ATH_POINT_BOUNCE(giwscan) -#endif -ATH_VOID_BOUNCE(setparam) -ATH_VOID_BOUNCE(getparam) -ATH_VOID_BOUNCE(setkey) -ATH_VOID_BOUNCE(delkey) -ATH_VOID_BOUNCE(setmlme) -ATH_VOID_BOUNCE(setoptie) -ATH_VOID_BOUNCE(getoptie) -ATH_VOID_BOUNCE(addmac) -ATH_VOID_BOUNCE(delmac) -ATH_VOID_BOUNCE(chanlist) - -/* Structures to export the Wireless Handlers */ -static const iw_handler ath_handlers[] = { - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) ath_ioctl_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) ath_ioctl_siwfreqx, /* SIOCSIWFREQ */ - (iw_handler) ath_ioctl_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) ath_ioctl_siwmode, /* SIOCSIWMODE */ - (iw_handler) ath_ioctl_giwmode, /* SIOCGIWMODE */ - (iw_handler) ath_ioctl_siwsens, /* SIOCSIWSENS */ - (iw_handler) ath_ioctl_giwsens, /* SIOCGIWSENS */ - (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ - (iw_handler) ath_ioctl_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) ath_ioctl_siwap, /* SIOCSIWAP */ - (iw_handler) ath_ioctl_giwap, /* SIOCGIWAP */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) ath_ioctl_iwaplist, /* SIOCGIWAPLIST */ -#ifdef SIOCGIWSCAN - (iw_handler) ath_ioctl_siwscan, /* SIOCSIWSCAN */ - (iw_handler) ath_ioctl_giwscan, /* SIOCGIWSCAN */ -#else - (iw_handler) NULL, /* SIOCSIWSCAN */ - (iw_handler) NULL, /* SIOCGIWSCAN */ -#endif /* SIOCGIWSCAN */ - (iw_handler) ath_ioctl_siwessid, /* SIOCSIWESSID */ - (iw_handler) ath_ioctl_giwessid, /* SIOCGIWESSID */ - (iw_handler) ath_ioctl_siwnickn, /* SIOCSIWNICKN */ - (iw_handler) ath_ioctl_giwnickn, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) ath_ioctl_siwrate, /* SIOCSIWRATE */ - (iw_handler) ath_ioctl_giwrate, /* SIOCGIWRATE */ - (iw_handler) ath_ioctl_siwrts, /* SIOCSIWRTS */ - (iw_handler) ath_ioctl_giwrts, /* SIOCGIWRTS */ - (iw_handler) ath_ioctl_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) ath_ioctl_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) ath_ioctl_siwtxpow, /* SIOCSIWTXPOW */ - (iw_handler) ath_ioctl_giwtxpow, /* SIOCGIWTXPOW */ - (iw_handler) ath_ioctl_siwretry, /* SIOCSIWRETRY */ - (iw_handler) ath_ioctl_giwretry, /* SIOCGIWRETRY */ - (iw_handler) ath_ioctl_siwencode, /* SIOCSIWENCODE */ - (iw_handler) ath_ioctl_giwencode, /* SIOCGIWENCODE */ - (iw_handler) ath_ioctl_siwpower, /* SIOCSIWPOWER */ - (iw_handler) ath_ioctl_giwpower, /* SIOCGIWPOWER */ -}; -static const iw_handler ath_priv_handlers[] = { - (iw_handler) ath_ioctl_setparam, /* SIOCWFIRSTPRIV+0 */ - (iw_handler) ath_ioctl_getparam, /* SIOCWFIRSTPRIV+1 */ - (iw_handler) ath_ioctl_setkey, /* SIOCWFIRSTPRIV+2 */ - (iw_handler) NULL, /* SIOCWFIRSTPRIV+3 */ - (iw_handler) ath_ioctl_delkey, /* SIOCWFIRSTPRIV+4 */ - (iw_handler) NULL, /* SIOCWFIRSTPRIV+5 */ - (iw_handler) ath_ioctl_setmlme, /* SIOCWFIRSTPRIV+6 */ - (iw_handler) NULL, /* SIOCWFIRSTPRIV+7 */ - (iw_handler) ath_ioctl_setoptie, /* SIOCWFIRSTPRIV+8 */ - (iw_handler) ath_ioctl_getoptie, /* SIOCWFIRSTPRIV+9 */ - (iw_handler) ath_ioctl_addmac, /* SIOCWFIRSTPRIV+10 */ - (iw_handler) NULL, /* SIOCWFIRSTPRIV+11 */ - (iw_handler) ath_ioctl_delmac, /* SIOCWFIRSTPRIV+12 */ - (iw_handler) NULL, /* SIOCWFIRSTPRIV+13 */ - (iw_handler) ath_ioctl_chanlist, /* SIOCWFIRSTPRIV+14 */ -}; - -static struct iw_handler_def ath_iw_handler_def = { -#define N(a) (sizeof (a) / sizeof (a[0])) -/*get_wireless_stats moved from net_device to iw_handler_def*/ -# if IW_HANDLER_VERSION >= 7 - .get_wireless_stats = ath_iw_getstats, -# endif - .standard = (iw_handler *) ath_handlers, - .num_standard = N(ath_handlers), - .private = (iw_handler *) ath_priv_handlers, - .num_private = N(ath_priv_handlers), -#undef N -}; - -static int -ath_set_mac_address(struct net_device *dev, void *addr) -{ - struct ath_softc *sc = dev->priv; - struct ath_hal *ah = sc->sc_ah; - struct sockaddr *mac = addr; - int error = 0; - - if (netif_running(dev)) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: cannot set address; device running\n", __func__); - return -EBUSY; - } - DPRINTF(sc, ATH_DEBUG_ANY, "%s: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - __func__, - mac->sa_data[0], mac->sa_data[1], mac->sa_data[2], - mac->sa_data[3], mac->sa_data[4], mac->sa_data[5]); - - ATH_LOCK(sc); - /* XXX not right for multiple vap's */ -// IEEE80211_ADDR_COPY(ic->ic_myaddr, mac->sa_data); - memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); - ath5k_hw_set_lladdr(ah, dev->dev_addr); - if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { - error = -ath_reset(dev); - } - ATH_UNLOCK(sc); - - return error; -} - -static int -ath_change_mtu(struct net_device *dev, int mtu) -{ - struct ath_softc *sc = dev->priv; - int error = 0; - - if (!(ATH_MIN_MTU < mtu && mtu <= ATH_MAX_MTU)) { - DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %d, min %u, max %u\n", - __func__, mtu, ATH_MIN_MTU, ATH_MAX_MTU); - return -EINVAL; - } - DPRINTF(sc, ATH_DEBUG_ANY, "%s: %d\n", __func__, mtu); - - ATH_LOCK(sc); - dev->mtu = mtu; - if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { - /* NB: the rx buffers may need to be reallocated */ - tasklet_disable(&sc->sc_rxtq); - error = -ath_reset(dev); - tasklet_enable(&sc->sc_rxtq); - } - ATH_UNLOCK(sc); - - return error; -} - -/* * Diagnostic interface to the HAL. This is used by various * tools to do things like retrieve register contents for * debugging. The mechanism is intentionally opaque so that @@ -4494,56 +2600,3 @@ ath_dynamic_sysctl_unregister(struct ath_softc *sc) sc->sc_sysctls = NULL; } } - -/* - * Announce various information on device/driver attach. - */ -static void -ath_announce(struct ath_softc *sc) -{ -#define AR5K_MODE_DUALBAND (AR5K_MODE_11A|AR5K_MODE_11B) -// struct net_device *dev = &sc->sc_dev; - struct ath_hal *ah = sc->sc_ah; - u_int modes, cc; -// int i; - - printk(KERN_INFO "mac %d.%d phy %d.%d", - ah->ah_mac_version, ah->ah_mac_version, - ah->ah_phy_revision >> 4, ah->ah_phy_revision & 0xf); - /* - * Print radio revision(s). We check the wireless modes - * to avoid falsely printing revs for inoperable parts. - * Dual-band radio revs are returned in the 5Ghz rev number. - */ - cc = ah->ah_country_code; - modes = ath_hal_getwirelessmodes(ah, cc); - if ((modes & AR5K_MODE_DUALBAND) == AR5K_MODE_DUALBAND) { - if (ah->ah_radio_5ghz_revision && ah->ah_radio_2ghz_revision) - printk(" 5ghz radio %d.%d 2ghz radio %d.%d", - ah->ah_radio_5ghz_revision >> 4, - ah->ah_radio_5ghz_revision & 0xf, - ah->ah_radio_2ghz_revision >> 4, - ah->ah_radio_2ghz_revision & 0xf); - else - printk(" radio %d.%d", ah->ah_radio_5ghz_revision >> 4, - ah->ah_radio_5ghz_revision & 0xf); - } else - printk(" radio %d.%d", ah->ah_radio_5ghz_revision >> 4, - ah->ah_radio_5ghz_revision & 0xf); - printk("\n"); -#ifdef BLE - for (i = 0; i <= WME_AC_VO; i++) { - struct ath_txq *txq = sc->sc_ac2q[i]; - printk(KERN_INFO "Use hw queue %u for %s traffic\n", - txq->axq_qnum, ieee80211_wme_acnames[i]); - } -#endif - printk(KERN_INFO "Use hw queue %u for CAB traffic\n", - sc->sc_cabq->axq_qnum); - printk(KERN_INFO "Use hw queue %u for beacons\n", sc->sc_bhalq); - -#ifdef AR_DEBUG - printk("Debugging version (ATH)\n"); -#endif -#undef AR5K_MODE_DUALBAND -}