commit 673bad75e34fec11259a42bccb1cc7e0a2d575a3 Author: Jiri Slaby Date: Mon Jun 25 12:26:16 2007 +0200 alloc dma_descs diff --git a/ath/if_ath.c b/ath/if_ath.c index ed978b0..f8bb32a 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -2963,35 +2963,6 @@ ath_beacon_config(struct ath_softc *sc) } #endif -static void -ath_descdma_cleanup(struct ath_softc *sc, struct list_head *head) -{ -#ifdef BLE - struct ath_buf *bf; - struct ieee80211_node *ni; - - STAILQ_FOREACH(bf, head, bf_list){ - if (bf->bf_skb) { - bus_unmap_single(sc->sc_bdev, - bf->bf_skbaddr, sc->sc_rxbufsize, - BUS_DMA_FROMDEVICE); - dev_kfree_skb(bf->bf_skb); - bf->bf_skb = NULL; - } - ni = bf->bf_node; - bf->bf_node = NULL; - if (ni != NULL) { - /* - * Reclaim node reference. - */ - ieee80211_free_node(ni); - } - } - - STAILQ_INIT(head); -#endif -} - #ifdef BLE static struct ieee80211_node * ath_node_alloc(struct ieee80211_node_table *nt) diff --git a/ath/if_ath_pci.c b/ath/if_ath_pci.c index 6435a29..e32e3eb 100644 --- a/ath/if_ath_pci.c +++ b/ath/if_ath_pci.c @@ -35,7 +35,6 @@ #include #include "if_athvar.h" -#include "if_ath_pci.h" #define ATH_DEBUG_MODES 0 /* Show found modes in the log? */ @@ -47,7 +46,7 @@ } while (0) #define DPRINTF(sc, _m, _fmt...) do { \ - if (sc->sc_debug & (_m) && printk_ratelimit()) \ + if (sc->debug & (_m) && printk_ratelimit()) \ printk(_fmt); \ } while (0) enum { @@ -135,7 +134,7 @@ static irqreturn_t ath_intr(int irq, void *dev_id) enum ath5k_int status; unsigned int counter = 1000; - if (sc->sc_invalid || !ath5k_hw_is_intr_pending(ah)) + if (sc->invalid || !ath5k_hw_is_intr_pending(ah)) return IRQ_NONE; return IRQ_HANDLED; @@ -148,7 +147,7 @@ return IRQ_HANDLED; */ ath5k_hw_get_isr(ah, &status); /* NB: clears ISR too */ DPRINTF(sc, ATH_DEBUG_INTR, "%s: status 0x%x\n", __func__, status); - status &= sc->sc_imask; /* discard unasked for bits */ + status &= sc->imask; /* discard unasked for bits */ if (status & AR5K_INT_FATAL) { /* * Fatal errors are unrecoverable. Typically @@ -156,13 +155,13 @@ return IRQ_HANDLED; * the exact reason is not (presently) returned * by the hal. */ - sc->sc_stats.ast_hardware++; + sc->stats.ast_hardware++; ath5k_hw_set_intr(ah, 0); /* disable intrs until rst */ - tasklet_schedule(&sc->sc_fataltq); + tasklet_schedule(&sc->fataltq); } else if (status & AR5K_INT_RXORN) { - sc->sc_stats.ast_rxorn++; + sc->stats.ast_rxorn++; ath5k_hw_set_intr(ah, 0); /* disable intrs until rst */ - tasklet_schedule(&sc->sc_rxorntq); + tasklet_schedule(&sc->rxorntq); } else { if (status & AR5K_INT_SWBA) { /* @@ -179,24 +178,24 @@ return IRQ_HANDLED; * RXE bit is written, but it doesn't work at * least on older hardware revs. */ - sc->sc_stats.ast_rxeol++; - sc->sc_rxlink = NULL; + sc->stats.ast_rxeol++; + sc->rxlink = NULL; } if (status & AR5K_INT_TXURN) { - sc->sc_stats.ast_txurn++; + sc->stats.ast_txurn++; /* bump tx trigger level */ ath5k_hw_update_tx_triglevel(ah, true); } if (status & AR5K_INT_RX) - tasklet_schedule(&sc->sc_rxtq); + tasklet_schedule(&sc->rxtq); if (status & AR5K_INT_TX) - tasklet_schedule(&sc->sc_txtq); + tasklet_schedule(&sc->txtq); if (status & AR5K_INT_BMISS) { - sc->sc_stats.ast_bmiss++; - tasklet_schedule(&sc->sc_bmisstq); + sc->stats.ast_bmiss++; + tasklet_schedule(&sc->bmisstq); } if (status & AR5K_INT_MIB) { - sc->sc_stats.ast_mib++; + sc->stats.ast_mib++; /* * Disable interrupts until we service the MIB * interrupt; otherwise it will continue to fire. @@ -210,7 +209,7 @@ return IRQ_HANDLED; ath5k_hw_proc_mib_event(ah, &ATH_NODE(sc->sc_ic.ic_bss)->an_halstats); #endif - ath5k_hw_set_intr(ah, sc->sc_imask); + ath5k_hw_set_intr(ah, sc->imask); } } } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); @@ -479,83 +478,101 @@ static void ath_setcurmode(struct ath_softc *sc, unsigned int mode) sc->curmode = mode; } -#if 0 -static int ath_desc_alloc(struct ath_softc *sc) + +static int ath_desc_alloc(struct ath_softc *sc, struct pci_dev *pdev) { -#define DS2PHYS(_sc, _ds) \ - ((_sc)->sc_desc_daddr + ((caddr_t)(_ds) - (caddr_t)(_sc)->sc_desc)) - int bsize; struct ath_desc *ds; struct ath_buf *bf; - int i; + dma_addr_t da; + unsigned int i; + int ret; /* allocate descriptors */ - sc->sc_desc_len = sizeof(struct ath_desc) * - (ATH_TXBUF * ATH_TXDESC + ATH_RXBUF + ATH_BCBUF + 1); - barrier(); /* get_order() rounds down constants before Linux 2.6.21 */ - sc->sc_desc = bus_alloc_consistent(sc->sc_bdev, - sc->sc_desc_len, &sc->sc_desc_daddr); - if (sc->sc_desc == NULL) { - printk(KERN_ERR "%s, could not allocate descriptors\n", __func__); - return ENOMEM; + sc->desc_len = sizeof(struct ath_desc) * + (ATH_TXBUF * ATH_TXDESC + ATH_RXBUF + ATH_BCBUF + 1); + sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); + if (sc->desc == NULL) { + dev_err(&pdev->dev, "can't allocate descriptors\n"); + ret = -ENOMEM; + goto err; + } + ds = sc->desc; + da = sc->desc_daddr; + DPRINTF(sc, ATH_DEBUG_ANY, "%s: DMA map: %p (%zu) -> %llx\n", + __func__, ds, sc->desc_len, (unsigned long long)sc->desc_daddr); + + bf = kcalloc(ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1, + sizeof(struct ath_buf), GFP_KERNEL); + if (bf == NULL) { + dev_err(&pdev->dev, "can't allocate bufptr\n"); + ret = -ENOMEM; + goto err_free; } - ds = sc->sc_desc; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: DMA map: %p (%u) -> %llx\n", - __func__, ds, (unsigned int) sc->sc_desc_len, - (unsigned long long)sc->sc_desc_daddr); - - /* allocate buffers */ - bsize = sizeof(struct ath_buf) * (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); - bf = kmalloc(bsize, GFP_KERNEL); - if (bf == NULL) - goto bad; - memset(bf, 0, bsize); - sc->sc_bufptr = bf; - -// STAILQ_INIT(&sc->sc_rxbuf); - for (i = 0; i < ATH_RXBUF; i++, bf++, ds++) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(sc, ds); -// STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); + sc->bufptr = bf; + + INIT_LIST_HEAD(&sc->rxbuf); + for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->rxbuf); } -// STAILQ_INIT(&sc->sc_txbuf); - for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(sc, ds); -// STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); + INIT_LIST_HEAD(&sc->txbuf); + for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC, + da += ATH_TXDESC * sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->txbuf); } -// STAILQ_INIT(&sc->sc_bbuf); - for (i = 0; i < ATH_BCBUF; i++, bf++, ds++) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(sc, ds); -// STAILQ_INSERT_TAIL(&sc->sc_bbuf, bf, bf_list); + INIT_LIST_HEAD(&sc->bbuf); + for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->bbuf); } return 0; -bad: - bus_free_consistent(sc->sc_bdev, sc->sc_desc_len, - sc->sc_desc, sc->sc_desc_daddr); - sc->sc_desc = NULL; - return -ENOMEM; -#undef DS2PHYS +err_free: + pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); +err: + sc->desc = NULL; + return ret; } - -static void ath_desc_free(struct ath_softc *sc) +#if 0 +static void ath_descdma_cleanup(struct ath_softc *sc, struct pci_dev *pdev, + struct list_head *head) { - ath_descdma_cleanup(sc, sc->sc_bbuf); - ath_descdma_cleanup(sc, sc->sc_txbuf); - ath_descdma_cleanup(sc, sc->sc_rxbuf); + struct list_head *pos; + struct ath_buf *bf; - /* Free memory associated with all descriptors */ - bus_free_consistent(sc->sc_bdev, sc->sc_desc_len, - sc->sc_desc, sc->sc_desc_daddr); + list_for_each(pos, head, bf_list){ + bf = list_entry(pos, struct ath_buf, list); + if (bf->skb) { + pci_unmap_single(pdev, bf->skbaddr, sc->rxbufsize, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(bf->skb); + bf->skb = NULL; + } + } - kfree(sc->sc_bufptr); - sc->sc_bufptr = NULL; + INIT_LIST_HEAD(head); } #endif +static void ath_desc_free(struct ath_softc *sc, struct pci_dev *pdev) +{ +#ifdef BLE + ath_descdma_cleanup(sc, pdev, sc->bbuf); + ath_descdma_cleanup(sc, pdev, sc->txbuf); + ath_descdma_cleanup(sc, pdev, sc->rxbuf); +#endif + /* Free memory associated with all descriptors */ + pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); + + kfree(sc->bufptr); + sc->bufptr = NULL; +} + static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; @@ -572,18 +589,18 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) * return false w/o doing anything. MAC's that do * support it will return true w/o doing anything. */ - sc->sc_mrretry = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + sc->mrretry = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); /* * Get the hardware key cache size. */ - sc->sc_keymax = AR5K_KEYCACHE_SIZE; + sc->keymax = AR5K_KEYCACHE_SIZE; /* * Reset the key cache since some parts do not * reset the contents on initial power up. */ - for (i = 0; i < sc->sc_keymax; i++) + for (i = 0; i < sc->keymax; i++) ath5k_hw_reset_key(ah, i); /* * Mark key cache slots associated with global keys @@ -616,16 +633,16 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ath_setcurmode(sc, MODE_IEEE80211A); else ath_setcurmode(sc, MODE_IEEE80211B); -#ifdef BLE /* * Allocate tx+rx descriptors and populate the lists. */ - ret = ath_desc_alloc(sc); + ret = ath_desc_alloc(sc, pdev); if (ret) { - printk(KERN_ERR "failed to allocate descriptors: %d\n", error); - goto bad; + dev_err(&pdev->dev, "can't allocate descriptors\n"); + goto err; } +#ifdef BLE /* * Allocate hardware transmit queues: one queue for @@ -908,9 +925,9 @@ err: return ret; } -static void ath_detach(struct ieee80211_hw *hw) +static void ath_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) { -// struct ath_softc *sc = hw->priv; + struct ath_softc *sc = hw->priv; // ath_stop(hw); /* @@ -927,7 +944,7 @@ static void ath_detach(struct ieee80211_hw *hw) */ // ieee80211_ifdetach(ic); // ath_rate_detach(sc->sc_rc); -// ath_desc_free(sc); + ath_desc_free(sc, pdev); // ath_tx_cleanup(sc); /* @@ -1033,11 +1050,11 @@ static int __devinit ath_pci_probe(struct pci_dev *pdev, * Mark the device as detached to avoid processing * interrupts until setup is complete. */ - sc->sc_invalid = 1; + sc->invalid = 1; sc->iobase = mem; - sc->sc_cachelsz = csz * sizeof(u32); /* convert to bytes */ + sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ mutex_init(&sc->lock); - spin_lock_init(&sc->sc_txbuflock); + spin_lock_init(&sc->txbuflock); /* tasklet_init(&sc->sc_rxtq, ath_rx_tasklet, (unsigned long)hw); tasklet_init(&sc->sc_rxorntq, ath_rxorn_tasklet, (unsigned long)hw); @@ -1067,7 +1084,7 @@ static int __devinit ath_pci_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "%s chip found\n", ath_chip_name(id->driver_data)); /* ready to process interrupts */ - sc->sc_invalid = 0; + sc->invalid = 0; return 0; err_ah: @@ -1091,7 +1108,7 @@ static void __devexit ath_pci_remove(struct pci_dev *pdev) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; - ath_detach(hw); + ath_detach(pdev, hw); ath5k_hw_detach(sc->ah); free_irq(pdev->irq, sc); pci_iounmap(pdev, sc->iobase); @@ -1106,8 +1123,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; - if (sc->sc_softled) - ath5k_hw_set_gpio(sc->ah, sc->sc_ledpin, 1); + if (sc->softled) + ath5k_hw_set_gpio(sc->ah, sc->ledpin, 1); // ath_stop(hw); pci_save_state(pdev); @@ -1140,9 +1157,9 @@ static int ath_pci_resume(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x41, 0); // ath_init(hw); - if (sc->sc_softled) { - ath5k_hw_set_gpio_output(sc->ah, sc->sc_ledpin); - ath5k_hw_set_gpio(sc->ah, sc->sc_ledpin, 0); + if (sc->softled) { + ath5k_hw_set_gpio_output(sc->ah, sc->ledpin); + ath5k_hw_set_gpio(sc->ah, sc->ledpin, 0); } return 0; diff --git a/ath/if_ath_pci.h b/ath/if_ath_pci.h deleted file mode 100644 index 1d152bd..0000000 --- a/ath/if_ath_pci.h +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - */ - -#ifndef _DEV_ATH_PCI_H_ -#define _DEV_ATH_PCI_H_ - -#include - -#define bus_map_single pci_map_single -#define bus_unmap_single pci_unmap_single -#define bus_dma_sync_single pci_dma_sync_single_for_cpu -#define BUS_DMA_MAP_ERROR(a) pci_dma_mapping_error(a) -#define bus_alloc_consistent pci_alloc_consistent -#define bus_free_consistent pci_free_consistent -#define BUS_DMA_FROMDEVICE PCI_DMA_FROMDEVICE -#define BUS_DMA_TODEVICE PCI_DMA_TODEVICE - -#endif /* _DEV_ATH_PCI_H_ */ diff --git a/ath/if_athvar.h b/ath/if_athvar.h index 1f15e18..14b5564 100644 --- a/ath/if_athvar.h +++ b/ath/if_athvar.h @@ -108,13 +108,13 @@ struct ath_node { } while (0) struct ath_buf { - struct list_head bf_list; - //int bf_nseg; - int bf_flags; /* tx descriptor flags */ - struct ath_desc *bf_desc; /* virtual addr of desc */ - dma_addr_t bf_daddr; /* physical addr of desc */ - struct sk_buff *bf_skb; /* skbuff for buf */ - dma_addr_t bf_skbaddr; /* physical addr of skb data */ + struct list_head list; + //int nseg; + int flags; /* tx descriptor flags */ + struct ath_desc *desc; /* virtual addr of desc */ + dma_addr_t daddr; /* physical addr of desc */ + struct sk_buff *skb; /* skbuff for buf */ + dma_addr_t skbaddr; /* physical addr of skb data */ #ifdef BLE struct ieee80211_node *bf_node; /* pointer to the node */ #endif @@ -179,7 +179,7 @@ struct ath_softc { void __iomem *iobase; /* address of the device */ struct mutex lock; /* dev-level lock */ // struct net_device_stats sc_devstats; /* device statistics */ - struct ath_stats sc_stats; /* private statistics */ + struct ath_stats stats; /* private statistics */ struct ieee80211_hw *hw; /* IEEE 802.11 common */ struct ieee80211_hw_mode modes[NUM_IEEE80211_MODES]; struct ieee80211_channel channels[ATH_CHAN_MAX]; @@ -190,7 +190,7 @@ struct ath_softc { int sc_regdomain; int sc_countrycode; #endif - int sc_debug; + int debug; #ifdef BLE void (*sc_recv_mgmt)(struct ieee80211com *, @@ -200,18 +200,19 @@ struct ath_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); void (*sc_node_free)(struct ieee80211_node *); - struct ath_desc *sc_desc; /* TX/RX descriptors */ - size_t sc_desc_len; /* size of TX/RX descriptors */ #endif - u16 sc_cachelsz; /* cache line size */ + struct ath_buf *bufptr; /* allocated buffer ptr */ + struct ath_desc *desc; /* TX/RX descriptors */ + dma_addr_t desc_daddr; /* DMA (physical) address */ + size_t desc_len; /* size of TX/RX descriptors */ + u16 cachelsz; /* cache line size */ #ifdef BLE - dma_addr_t sc_desc_daddr; /* DMA (physical) address */ struct ath_ratectrl *sc_rc; /* tx rate control support */ void (*sc_setdefantenna)(struct ath_softc *, u_int); #endif - unsigned int sc_invalid : 1, /* disable hardware accesses */ - sc_mrretry : 1, /* multi-rate retry support */ - sc_softled : 1, /* enable LED gpio status */ + unsigned int invalid : 1, /* disable hardware accesses */ + mrretry : 1, /* multi-rate retry support */ + softled : 1, /* enable LED gpio status */ xxx:1; #ifdef BLE sc_splitmic: 1, /* split TKIP MIC keys */ @@ -245,13 +246,13 @@ struct ath_softc { u8 sc_protrix; /* protection rate index */ u_int sc_txantenna; /* tx antenna (fixed or auto) */ #endif - enum ath5k_int sc_imask; /* interrupt mask copy */ - u_int sc_keymax; /* size of key cache */ + enum ath5k_int imask; /* interrupt mask copy */ + u_int keymax; /* size of key cache */ #ifdef BLE u8 sc_keymap[ATH_KEYBYTES];/* key use bit map */ struct ieee80211_node *sc_keyixmap[ATH_KEYMAX];/* key ix->node map */ #endif - u_int sc_ledpin; /* GPIO pin for driving LED */ + u_int ledpin; /* GPIO pin for driving LED */ #ifdef BLE u_int sc_ledon; /* pin setting for LED on */ u_int sc_ledidle; /* idle polling interval */ @@ -273,23 +274,23 @@ struct ath_softc { } u_rx_rt; int sc_rx_th_len; #endif - struct tasklet_struct sc_fataltq; /* fatal int tasklet */ + struct tasklet_struct fataltq; /* fatal int tasklet */ #ifdef BLE struct tasklet_struct sc_radartq; /* Radar detection */ int sc_rxbufsize; /* rx size based on mtu */ - struct list_head *sc_rxbuf; /* receive buffer */ #endif - struct tasklet_struct sc_rxtq; /* rx intr tasklet */ - struct tasklet_struct sc_rxorntq; /* rxorn intr tasklet */ - u32 *sc_rxlink; /* link ptr in last RX desc */ + struct list_head rxbuf; /* receive buffer */ + struct tasklet_struct rxtq; /* rx intr tasklet */ + struct tasklet_struct rxorntq; /* rxorn intr tasklet */ + u32 *rxlink; /* link ptr in last RX desc */ #ifdef BLE u8 sc_defant; /* current default antenna */ u8 sc_rxotherant; /* rx's on non-default antenna*/ - struct list_head *sc_txbuf; /* transmit buffer */ #endif - spinlock_t sc_txbuflock; /* txbuf lock */ + struct list_head txbuf; /* transmit buffer */ + spinlock_t txbuflock; /* txbuf lock */ #ifdef BLE int sc_tx_timer; /* transmit timeout */ u_int sc_txqsetup; /* h/w queues setup */ @@ -297,20 +298,19 @@ struct ath_softc { struct ath_txq sc_txq[AR5K_NUM_TX_QUEUES]; struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */ #endif - struct tasklet_struct sc_txtq; /* tx intr tasklet */ -#ifdef BLE + struct tasklet_struct txtq; /* tx intr tasklet */ - struct list_head *sc_bbuf; /* beacon buffers */ + struct list_head bbuf; /* beacon buffers */ +#ifdef BLE u_int sc_bhalq; /* HAL q for outgoing beacons */ u_int sc_bmisscount; /* missed beacon transmits */ u32 sc_ant_tx[8]; /* recent tx frames/antenna */ struct ath_txq *sc_cabq; /* tx q for cab frames */ - struct ath_buf *sc_bufptr; /* allocated buffer ptr */ #ifdef BLE - struct ieee80211_beacon_offsets sc_boff;/* dynamic update state */ + struct ieee80211_beacon_offsets boff; /* dynamic update state */ #endif #endif - struct tasklet_struct sc_bmisstq; /* bmiss intr tasklet */ + struct tasklet_struct bmisstq; /* bmiss intr tasklet */ #ifdef BLE struct tasklet_struct sc_bstuckq; /* stuck beacon processing */ enum {