diff options
Diffstat (limited to 'drivers/net/sky2.c')
| -rw-r--r-- | drivers/net/sky2.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 72c1630977d6..73260364cba3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -74,7 +74,7 @@ | |||
| 74 | #define TX_RING_SIZE 512 | 74 | #define TX_RING_SIZE 512 |
| 75 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 75 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) |
| 76 | #define TX_MIN_PENDING 64 | 76 | #define TX_MIN_PENDING 64 |
| 77 | #define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS) | 77 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
| 78 | 78 | ||
| 79 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 79 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
| 80 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 80 | #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) | |||
| 622 | 622 | ||
| 623 | /* Configure Rx MAC FIFO */ | 623 | /* Configure Rx MAC FIFO */ |
| 624 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 624 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
| 625 | sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T), | 625 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
| 626 | GMF_RX_CTRL_DEF); | 626 | GMF_OPER_ON | GMF_RX_F_FL_ON); |
| 627 | 627 | ||
| 628 | /* Flush Rx MAC FIFO on any flow control or error */ | 628 | /* Flush Rx MAC FIFO on any flow control or error */ |
| 629 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); | 629 | 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) | |||
| 995 | sky2_rx_add(sky2, re->mapaddr); | 995 | sky2_rx_add(sky2, re->mapaddr); |
| 996 | } | 996 | } |
| 997 | 997 | ||
| 998 | /* Truncate oversize frames */ | ||
| 999 | sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); | ||
| 1000 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); | ||
| 1001 | |||
| 998 | /* Tell chip about available buffers */ | 1002 | /* Tell chip about available buffers */ |
| 999 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | 1003 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
| 1000 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); | 1004 | 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) | |||
| 1145 | struct sky2_tx_le *le = NULL; | 1149 | struct sky2_tx_le *le = NULL; |
| 1146 | struct tx_ring_info *re; | 1150 | struct tx_ring_info *re; |
| 1147 | unsigned i, len; | 1151 | unsigned i, len; |
| 1152 | int avail; | ||
| 1148 | dma_addr_t mapping; | 1153 | dma_addr_t mapping; |
| 1149 | u32 addr64; | 1154 | u32 addr64; |
| 1150 | u16 mss; | 1155 | u16 mss; |
| @@ -1287,12 +1292,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 1287 | re->idx = sky2->tx_prod; | 1292 | re->idx = sky2->tx_prod; |
| 1288 | le->ctrl |= EOP; | 1293 | le->ctrl |= EOP; |
| 1289 | 1294 | ||
| 1295 | avail = tx_avail(sky2); | ||
| 1296 | if (mss != 0 || avail < TX_MIN_PENDING) { | ||
| 1297 | le->ctrl |= FRC_STAT; | ||
| 1298 | if (avail <= MAX_SKB_TX_LE) | ||
| 1299 | netif_stop_queue(dev); | ||
| 1300 | } | ||
| 1301 | |||
| 1290 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, | 1302 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, |
| 1291 | &sky2->tx_last_put, TX_RING_SIZE); | 1303 | &sky2->tx_last_put, TX_RING_SIZE); |
| 1292 | 1304 | ||
| 1293 | if (tx_avail(sky2) <= MAX_SKB_TX_LE) | ||
| 1294 | netif_stop_queue(dev); | ||
| 1295 | |||
| 1296 | out_unlock: | 1305 | out_unlock: |
| 1297 | spin_unlock(&sky2->tx_lock); | 1306 | spin_unlock(&sky2->tx_lock); |
| 1298 | 1307 | ||
| @@ -1707,10 +1716,12 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
| 1707 | 1716 | ||
| 1708 | 1717 | ||
| 1709 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | 1718 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
| 1710 | /* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */ | 1719 | /* Want receive buffer size to be multiple of 64 bits |
| 1720 | * and incl room for vlan and truncation | ||
| 1721 | */ | ||
| 1711 | static inline unsigned sky2_buf_size(int mtu) | 1722 | static inline unsigned sky2_buf_size(int mtu) |
| 1712 | { | 1723 | { |
| 1713 | return roundup(mtu + ETH_HLEN + 4, 8); | 1724 | return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
| 1714 | } | 1725 | } |
| 1715 | 1726 | ||
| 1716 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1727 | 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, | |||
| 1793 | if (!(status & GMR_FS_RX_OK)) | 1804 | if (!(status & GMR_FS_RX_OK)) |
| 1794 | goto resubmit; | 1805 | goto resubmit; |
| 1795 | 1806 | ||
| 1796 | if ((status >> 16) != length || length > sky2->rx_bufsize) | 1807 | if (length > sky2->netdev->mtu + ETH_HLEN) |
| 1797 | goto oversize; | 1808 | goto oversize; |
| 1798 | 1809 | ||
| 1799 | if (length < copybreak) { | 1810 | if (length < copybreak) { |
| @@ -3243,8 +3254,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3243 | } | 3254 | } |
| 3244 | } | 3255 | } |
| 3245 | 3256 | ||
| 3246 | err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, | 3257 | err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); |
| 3247 | DRV_NAME, hw); | ||
| 3248 | if (err) { | 3258 | if (err) { |
| 3249 | printk(KERN_ERR PFX "%s: cannot assign irq %d\n", | 3259 | printk(KERN_ERR PFX "%s: cannot assign irq %d\n", |
| 3250 | pci_name(pdev), pdev->irq); | 3260 | pci_name(pdev), pdev->irq); |
