|
@@ -1755,6 +1755,24 @@ static int sis900_rx(struct net_device *net_dev)
|
|
|
} else {
|
|
|
struct sk_buff * skb;
|
|
|
|
|
|
+ pci_unmap_single(sis_priv->pci_dev,
|
|
|
+ sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
|
|
|
+ PCI_DMA_FROMDEVICE);
|
|
|
+
|
|
|
+ /* refill the Rx buffer, what if there is not enought
|
|
|
+ * memory for new socket buffer ?? */
|
|
|
+ if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
|
|
|
+ /*
|
|
|
+ * Not enough memory to refill the buffer
|
|
|
+ * so we need to recycle the old one so
|
|
|
+ * as to avoid creating a memory hole
|
|
|
+ * in the rx ring
|
|
|
+ */
|
|
|
+ skb = sis_priv->rx_skbuff[entry];
|
|
|
+ sis_priv->stats.rx_dropped++;
|
|
|
+ goto refill_rx_ring;
|
|
|
+ }
|
|
|
+
|
|
|
/* This situation should never happen, but due to
|
|
|
some unknow bugs, it is possible that
|
|
|
we are working on NULL sk_buff :-( */
|
|
@@ -1768,9 +1786,6 @@ static int sis900_rx(struct net_device *net_dev)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- pci_unmap_single(sis_priv->pci_dev,
|
|
|
- sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
|
|
|
- PCI_DMA_FROMDEVICE);
|
|
|
/* give the socket buffer to upper layers */
|
|
|
skb = sis_priv->rx_skbuff[entry];
|
|
|
skb_put(skb, rx_size);
|
|
@@ -1783,33 +1798,14 @@ static int sis900_rx(struct net_device *net_dev)
|
|
|
net_dev->last_rx = jiffies;
|
|
|
sis_priv->stats.rx_bytes += rx_size;
|
|
|
sis_priv->stats.rx_packets++;
|
|
|
-
|
|
|
- /* refill the Rx buffer, what if there is not enought
|
|
|
- * memory for new socket buffer ?? */
|
|
|
- if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
|
|
|
- /* not enough memory for skbuff, this makes a
|
|
|
- * "hole" on the buffer ring, it is not clear
|
|
|
- * how the hardware will react to this kind
|
|
|
- * of degenerated buffer */
|
|
|
- if (netif_msg_rx_status(sis_priv))
|
|
|
- printk(KERN_INFO "%s: Memory squeeze,"
|
|
|
- "deferring packet.\n",
|
|
|
- net_dev->name);
|
|
|
- sis_priv->rx_skbuff[entry] = NULL;
|
|
|
- /* reset buffer descriptor state */
|
|
|
- sis_priv->rx_ring[entry].cmdsts = 0;
|
|
|
- sis_priv->rx_ring[entry].bufptr = 0;
|
|
|
- sis_priv->stats.rx_dropped++;
|
|
|
- sis_priv->cur_rx++;
|
|
|
- break;
|
|
|
- }
|
|
|
+ sis_priv->dirty_rx++;
|
|
|
+refill_rx_ring:
|
|
|
skb->dev = net_dev;
|
|
|
sis_priv->rx_skbuff[entry] = skb;
|
|
|
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
|
|
sis_priv->rx_ring[entry].bufptr =
|
|
|
pci_map_single(sis_priv->pci_dev, skb->data,
|
|
|
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
|
|
- sis_priv->dirty_rx++;
|
|
|
}
|
|
|
sis_priv->cur_rx++;
|
|
|
entry = sis_priv->cur_rx % NUM_RX_DESC;
|