RX bottom half.
This commit is contained in:
parent
49383a393f
commit
b906d24b62
1
CHANGES
1
CHANGES
|
@ -41,6 +41,7 @@
|
|||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
- Moved RX processing to a bottom half instead of hard irq context.
|
||||
- Further script improvements: signal strength filtering, and some
|
||||
space handling stuff. The latter is not complete yet.
|
||||
- lnxreq_commsquality wasn't setting the status field properly on the
|
||||
|
|
|
@ -169,10 +169,8 @@ extern struct iw_handler_def p80211wext_handler_def;
|
|||
/* WLAN device type */
|
||||
typedef struct wlandevice
|
||||
{
|
||||
void *priv; /* private data for MSD */
|
||||
struct wlandevice *next; /* link for list of devices */
|
||||
|
||||
UINT32 nsdcaps; /* NSD Capabilities flags */
|
||||
void *priv; /* private data for MSD */
|
||||
|
||||
/* Subsystem State */
|
||||
char *name; /* Dev name, from register_wlandev()*/
|
||||
|
@ -185,6 +183,7 @@ typedef struct wlandevice
|
|||
UINT iobase;
|
||||
UINT membase;
|
||||
char slotname[16]; /* physical bus location */
|
||||
UINT32 nsdcaps; /* NSD Capabilities flags */
|
||||
|
||||
/* Config vars */
|
||||
UINT ethconv;
|
||||
|
@ -225,6 +224,10 @@ typedef struct wlandevice
|
|||
struct proc_dir_entry *procwlandev;
|
||||
#endif
|
||||
|
||||
/* Rx bottom half */
|
||||
struct tq_struct rx_bh;
|
||||
struct sk_buff_head nsd_rxq;
|
||||
|
||||
/* 802.11 device statistics */
|
||||
struct p80211_frmrx_t rx;
|
||||
|
||||
|
|
|
@ -122,6 +122,8 @@ static struct proc_dir_entry *proc_p80211;
|
|||
static int wlandev_get_index(wlandevice_t *wlandev);
|
||||
static void wlandev_clear_index(wlandevice_t *wlandev);
|
||||
|
||||
static void p80211netdev_rx_bh(void *arg);
|
||||
|
||||
/* netdevice method functions */
|
||||
static int p80211knetdev_init( netdevice_t *netdev);
|
||||
static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
|
||||
|
@ -326,7 +328,6 @@ int p80211knetdev_stop( netdevice_t *netdev )
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211netdev_rx
|
||||
*
|
||||
|
@ -340,34 +341,67 @@ int p80211knetdev_stop( netdevice_t *netdev )
|
|||
* Side effects:
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
|
||||
void
|
||||
p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
|
||||
{
|
||||
DBFENTER;
|
||||
|
||||
/* Enqueue for post-irq processing */
|
||||
skb_queue_tail(&wlandev->nsd_rxq, skb);
|
||||
|
||||
queue_task(&wlandev->rx_bh, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
|
||||
DBFEXIT;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* p80211netdev_rx_bh
|
||||
*
|
||||
* Deferred processing of all received frames.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev WLAN network device structure
|
||||
* skb skbuff containing a full 802.11 frame.
|
||||
* Returns:
|
||||
* nothing
|
||||
* Side effects:
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void p80211netdev_rx_bh(void *arg)
|
||||
{
|
||||
wlandevice_t *wlandev = (wlandevice_t *) arg;
|
||||
struct sk_buff *skb = NULL;
|
||||
netdevice_t *dev = wlandev->netdev;
|
||||
|
||||
DBFENTER;
|
||||
|
||||
if (wlandev->state == WLAN_DEVICE_OPEN) {
|
||||
/* Let's empty our our queue */
|
||||
while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
|
||||
if (wlandev->state == WLAN_DEVICE_OPEN) {
|
||||
|
||||
if (dev->type != ARPHRD_ETHER) {
|
||||
/* RAW frame; we shouldn't convert it */
|
||||
skb->dev->last_rx = jiffies;
|
||||
wlandev->linux_stats.rx_packets++;
|
||||
wlandev->linux_stats.rx_bytes += skb->len;
|
||||
netif_rx(skb);
|
||||
goto done;
|
||||
} else {
|
||||
if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
|
||||
if (dev->type != ARPHRD_ETHER) {
|
||||
/* RAW frame; we shouldn't convert it */
|
||||
skb->dev->last_rx = jiffies;
|
||||
wlandev->linux_stats.rx_packets++;
|
||||
wlandev->linux_stats.rx_bytes += skb->len;
|
||||
netif_rx(skb);
|
||||
goto done;
|
||||
}
|
||||
WLAN_LOG_DEBUG0(1, "p80211_to_ether failed.\n");
|
||||
continue;
|
||||
} else {
|
||||
if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
|
||||
skb->dev->last_rx = jiffies;
|
||||
wlandev->linux_stats.rx_packets++;
|
||||
wlandev->linux_stats.rx_bytes += skb->len;
|
||||
netif_rx(skb);
|
||||
continue;
|
||||
}
|
||||
WLAN_LOG_DEBUG0(1, "p80211_to_ether failed.\n");
|
||||
}
|
||||
}
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
done:
|
||||
DBFEXIT;
|
||||
}
|
||||
|
||||
|
@ -814,6 +848,12 @@ int wlan_setup(wlandevice_t *wlandev)
|
|||
|
||||
init_waitqueue_head(&wlandev->reqwq);
|
||||
|
||||
/* Set up the rx queue */
|
||||
skb_queue_head_init(&wlandev->nsd_rxq);
|
||||
INIT_TQUEUE(&wlandev->rx_bh,
|
||||
p80211netdev_rx_bh,
|
||||
(void*)wlandev);
|
||||
|
||||
/* Allocate and initialize the struct device */
|
||||
dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC);
|
||||
if ( dev == NULL ) {
|
||||
|
|
Loading…
Reference in New Issue