|
@@ -74,7 +74,7 @@
|
|
|
#define TX_RING_SIZE 512
|
|
|
#define TX_DEF_PENDING (TX_RING_SIZE - 1)
|
|
|
#define TX_MIN_PENDING 64
|
|
|
-#define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS)
|
|
|
+#define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
|
|
|
|
|
|
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */
|
|
|
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
|
|
@@ -622,8 +622,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
|
|
|
|
|
|
/* Configure Rx MAC FIFO */
|
|
|
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
|
|
|
- sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
|
|
|
- GMF_RX_CTRL_DEF);
|
|
|
+ sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
|
|
|
+ GMF_OPER_ON | GMF_RX_F_FL_ON);
|
|
|
|
|
|
/* Flush Rx MAC FIFO on any flow control or error */
|
|
|
sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
|
|
@@ -995,6 +995,10 @@ static int sky2_rx_start(struct sky2_port *sky2)
|
|
|
sky2_rx_add(sky2, re->mapaddr);
|
|
|
}
|
|
|
|
|
|
+ /* Truncate oversize frames */
|
|
|
+ sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8);
|
|
|
+ sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
|
|
|
+
|
|
|
/* Tell chip about available buffers */
|
|
|
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
|
|
|
sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
|
|
@@ -1145,6 +1149,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
|
|
|
struct sky2_tx_le *le = NULL;
|
|
|
struct tx_ring_info *re;
|
|
|
unsigned i, len;
|
|
|
+ int avail;
|
|
|
dma_addr_t mapping;
|
|
|
u32 addr64;
|
|
|
u16 mss;
|
|
@@ -1287,12 +1292,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
|
|
|
re->idx = sky2->tx_prod;
|
|
|
le->ctrl |= EOP;
|
|
|
|
|
|
+ avail = tx_avail(sky2);
|
|
|
+ if (mss != 0 || avail < TX_MIN_PENDING) {
|
|
|
+ le->ctrl |= FRC_STAT;
|
|
|
+ if (avail <= MAX_SKB_TX_LE)
|
|
|
+ netif_stop_queue(dev);
|
|
|
+ }
|
|
|
+
|
|
|
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
|
|
|
&sky2->tx_last_put, TX_RING_SIZE);
|
|
|
|
|
|
- if (tx_avail(sky2) <= MAX_SKB_TX_LE)
|
|
|
- netif_stop_queue(dev);
|
|
|
-
|
|
|
out_unlock:
|
|
|
spin_unlock(&sky2->tx_lock);
|
|
|
|
|
@@ -1707,10 +1716,12 @@ static void sky2_tx_timeout(struct net_device *dev)
|
|
|
|
|
|
|
|
|
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
|
|
-/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
|
|
|
+/* Want receive buffer size to be multiple of 64 bits
|
|
|
+ * and incl room for vlan and truncation
|
|
|
+ */
|
|
|
static inline unsigned sky2_buf_size(int mtu)
|
|
|
{
|
|
|
- return roundup(mtu + ETH_HLEN + 4, 8);
|
|
|
+ return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
|
|
|
}
|
|
|
|
|
|
static int sky2_change_mtu(struct net_device *dev, int new_mtu)
|
|
@@ -1793,7 +1804,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2,
|
|
|
if (!(status & GMR_FS_RX_OK))
|
|
|
goto resubmit;
|
|
|
|
|
|
- if ((status >> 16) != length || length > sky2->rx_bufsize)
|
|
|
+ if (length > sky2->netdev->mtu + ETH_HLEN)
|
|
|
goto oversize;
|
|
|
|
|
|
if (length < copybreak) {
|
|
@@ -3243,8 +3254,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
|
|
|
- DRV_NAME, hw);
|
|
|
+ err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
|
|
|
if (err) {
|
|
|
printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
|
|
|
pci_name(pdev), pdev->irq);
|