Commit e9b1f1cc authored by Jochen Friedrich's avatar Jochen Friedrich Committed by Jeff Garzik

[PATCH] tms380tr patch 2/3 (queue fix)

Hi Jeff,

this one removes the internal queue of tms380tr. It was racy, anyways.

--jochen

 tms380tr.c |  178 +++++++++++++++++++++++--------------------------------------
 tms380tr.h |    4 -
 2 files changed, 70 insertions(+), 112 deletions(-)
parent c44253ad
...@@ -143,8 +143,8 @@ static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValu ...@@ -143,8 +143,8 @@ static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValu
/* "G" */ /* "G" */
static struct net_device_stats *tms380tr_get_stats(struct net_device *dev); static struct net_device_stats *tms380tr_get_stats(struct net_device *dev);
/* "H" */ /* "H" */
static void tms380tr_hardware_send_packet(struct net_device *dev, static int tms380tr_hardware_send_packet(struct sk_buff *skb,
struct net_local* tp); struct net_device *dev);
/* "I" */ /* "I" */
static int tms380tr_init_adapter(struct net_device *dev); static int tms380tr_init_adapter(struct net_device *dev);
static void tms380tr_init_ipb(struct net_local *tp); static void tms380tr_init_ipb(struct net_local *tp);
...@@ -388,9 +388,6 @@ static void tms380tr_init_net_local(struct net_device *dev) ...@@ -388,9 +388,6 @@ static void tms380tr_init_net_local(struct net_device *dev)
tp->LastOpenStatus = 0; tp->LastOpenStatus = 0;
tp->MaxPacketSize = DEFAULT_PACKET_SIZE; tp->MaxPacketSize = DEFAULT_PACKET_SIZE;
skb_queue_head_init(&tp->SendSkbQueue);
tp->QueueSkb = MAX_TX_QUEUE;
/* Create circular chain of transmit lists */ /* Create circular chain of transmit lists */
for (i = 0; i < TPL_NUM; i++) for (i = 0; i < TPL_NUM; i++)
{ {
...@@ -598,69 +595,47 @@ static void tms380tr_timeout(struct net_device *dev) ...@@ -598,69 +595,47 @@ static void tms380tr_timeout(struct net_device *dev)
static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev) static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev)
{ {
struct net_local *tp = (struct net_local *)dev->priv; struct net_local *tp = (struct net_local *)dev->priv;
int err;
/* err = tms380tr_hardware_send_packet(skb, dev);
* Block transmits from overlapping. if(tp->TplFree->NextTPLPtr->BusyFlag)
*/
netif_stop_queue(dev); netif_stop_queue(dev);
return (err);
if(tp->QueueSkb == 0)
return (1); /* Return with tbusy set: queue full */
tp->QueueSkb--;
skb_queue_tail(&tp->SendSkbQueue, skb);
tms380tr_hardware_send_packet(dev, tp);
if(tp->QueueSkb > 0)
netif_wake_queue(dev);
return (0);
} }
/* /*
* Move frames from internal skb queue into adapter tx queue * Move frames into adapter tx queue
*/ */
static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_local* tp) static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device *dev)
{ {
TPL *tpl; TPL *tpl;
short length; short length;
unsigned char *buf; unsigned char *buf;
unsigned long flags; unsigned long flags;
struct sk_buff *skb;
int i; int i;
dma_addr_t dmabuf, newbuf; dma_addr_t dmabuf, newbuf;
struct net_local *tp = (struct net_local *)dev->priv;
for(;;)
{
/* Try to get a free TPL from the chain. /* Try to get a free TPL from the chain.
* *
* NOTE: We *must* always leave one unused TPL in the chain, * NOTE: We *must* always leave one unused TPL in the chain,
* because otherwise the adapter might send frames twice. * because otherwise the adapter might send frames twice.
*/ */
spin_lock_irqsave(&tp->lock, flags); spin_lock_irqsave(&tp->lock, flags);
if(tp->TplFree->NextTPLPtr->BusyFlag) /* No free TPL */ if(tp->TplFree->NextTPLPtr->BusyFlag) { /* No free TPL */
{
if (tms380tr_debug > 0) if (tms380tr_debug > 0)
printk(KERN_DEBUG "%s: No free TPL\n", dev->name); printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
spin_unlock_irqrestore(&tp->lock, flags); spin_unlock_irqrestore(&tp->lock, flags);
return; return 1;
} }
/* Send first buffer from queue */
skb = skb_dequeue(&tp->SendSkbQueue);
if(skb == NULL)
{
spin_unlock_irqrestore(&tp->lock, flags);
return;
}
tp->QueueSkb++;
dmabuf = 0; dmabuf = 0;
/* Is buffer reachable for Busmaster-DMA? */ /* Is buffer reachable for Busmaster-DMA? */
length = skb->len; length = skb->len;
dmabuf = pci_map_single(tp->pdev, skb->data, length, PCI_DMA_TODEVICE); dmabuf = pci_map_single(tp->pdev, skb->data, length, PCI_DMA_TODEVICE);
if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) {
{
/* Copy frame to local buffer */ /* Copy frame to local buffer */
pci_unmap_single(tp->pdev, dmabuf, length, PCI_DMA_TODEVICE); pci_unmap_single(tp->pdev, dmabuf, length, PCI_DMA_TODEVICE);
dmabuf = 0; dmabuf = 0;
...@@ -669,8 +644,7 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc ...@@ -669,8 +644,7 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
memcpy(buf, skb->data, length); memcpy(buf, skb->data, length);
newbuf = ((char *)buf - (char *)tp) + tp->dmabuffer; newbuf = ((char *)buf - (char *)tp) + tp->dmabuffer;
} }
else else {
{
/* Send direct from skb->data */ /* Send direct from skb->data */
newbuf = dmabuf; newbuf = dmabuf;
buf = skb->data; buf = skb->data;
...@@ -700,9 +674,8 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc ...@@ -700,9 +674,8 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
/* Let adapter send the frame. */ /* Let adapter send the frame. */
tms380tr_exec_sifcmd(dev, CMD_TX_VALID); tms380tr_exec_sifcmd(dev, CMD_TX_VALID);
spin_unlock_irqrestore(&tp->lock, flags); spin_unlock_irqrestore(&tp->lock, flags);
}
return; return 0;
} }
/* /*
...@@ -747,7 +720,7 @@ static void tms380tr_timer_chk(unsigned long data) ...@@ -747,7 +720,7 @@ static void tms380tr_timer_chk(unsigned long data)
tms380tr_chk_outstanding_cmds(dev); tms380tr_chk_outstanding_cmds(dev);
if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies) if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies)
&& (tp->QueueSkb < MAX_TX_QUEUE || tp->TplFree != tp->TplBusy)) && (tp->TplFree != tp->TplBusy))
{ {
/* Anything to send, but stalled too long */ /* Anything to send, but stalled too long */
tp->LastSendTime = jiffies; tp->LastSendTime = jiffies;
...@@ -1769,8 +1742,8 @@ static void tms380tr_ring_status_irq(struct net_device *dev) ...@@ -1769,8 +1742,8 @@ static void tms380tr_ring_status_irq(struct net_device *dev)
if(tp->ssb.Parm[0] & ADAPTER_CLOSED) if(tp->ssb.Parm[0] & ADAPTER_CLOSED)
{ {
printk(KERN_INFO "%s: Adapter closed (Reopening)," printk(KERN_INFO "%s: Adapter closed (Reopening),"
"QueueSkb %d, CurrentRingStat %x\n", "CurrentRingStat %x\n",
dev->name, tp->QueueSkb, tp->CurrentRingStatus); dev->name, tp->CurrentRingStatus);
tp->AdapterOpenFlag = 0; tp->AdapterOpenFlag = 0;
tms380tr_open_adapter(dev); tms380tr_open_adapter(dev);
} }
...@@ -1998,7 +1971,6 @@ static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, ...@@ -1998,7 +1971,6 @@ static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
static void tms380tr_cancel_tx_queue(struct net_local* tp) static void tms380tr_cancel_tx_queue(struct net_local* tp)
{ {
TPL *tpl; TPL *tpl;
struct sk_buff *skb;
/* /*
* NOTE: There must not be an active TRANSMIT command pending, when * NOTE: There must not be an active TRANSMIT command pending, when
...@@ -2023,15 +1995,6 @@ static void tms380tr_cancel_tx_queue(struct net_local* tp) ...@@ -2023,15 +1995,6 @@ static void tms380tr_cancel_tx_queue(struct net_local* tp)
dev_kfree_skb_any(tpl->Skb); dev_kfree_skb_any(tpl->Skb);
} }
for(;;)
{
skb = skb_dequeue(&tp->SendSkbQueue);
if(skb == NULL)
break;
tp->QueueSkb++;
dev_kfree_skb_any(skb);
}
return; return;
} }
...@@ -2102,9 +2065,8 @@ static void tms380tr_tx_status_irq(struct net_device *dev) ...@@ -2102,9 +2065,8 @@ static void tms380tr_tx_status_irq(struct net_device *dev)
tpl->BusyFlag = 0; /* "free" TPL */ tpl->BusyFlag = 0; /* "free" TPL */
} }
if(!tp->TplFree->NextTPLPtr->BusyFlag)
netif_wake_queue(dev); netif_wake_queue(dev);
if(tp->QueueSkb < MAX_TX_QUEUE)
tms380tr_hardware_send_packet(dev, tp);
return; return;
} }
......
...@@ -598,7 +598,6 @@ typedef struct { ...@@ -598,7 +598,6 @@ typedef struct {
* in one RPL/TPL. (depending on TI firmware * in one RPL/TPL. (depending on TI firmware
* version) * version)
*/ */
#define MAX_TX_QUEUE 10 /* Maximal number of skb's queued in driver. */
/* /*
* AC (1), FC (1), Dst (6), Src (6), RIF (18), Data (4472) = 4504 * AC (1), FC (1), Dst (6), Src (6), RIF (18), Data (4472) = 4504
...@@ -1114,9 +1113,6 @@ typedef struct net_local { ...@@ -1114,9 +1113,6 @@ typedef struct net_local {
unsigned long StartTime; unsigned long StartTime;
unsigned long LastSendTime; unsigned long LastSendTime;
struct sk_buff_head SendSkbQueue;
unsigned short QueueSkb;
struct tr_statistics MacStat; /* MAC statistics structure */ struct tr_statistics MacStat; /* MAC statistics structure */
unsigned long dmalimit; /* the max DMA address (ie, ISA) */ unsigned long dmalimit; /* the max DMA address (ie, ISA) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment