diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-03-07 14:06:37 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2006-03-09 17:19:03 -0500 |
commit | 70f1be4812a833ac856818c3149e432ff6a84c2e (patch) | |
tree | 35bfffeb385e987ba98bcb81a9216291c210c501 /drivers/net/sky2.c | |
parent | b19666d92009ad2aa8e12d25f2cab59fb32421eb (diff) |
sky2: truncate oversize packets
Turn on truncation to prevent getting choked by frames larger than expected.
Without this fix, driver hangs after receiving an oversize packet.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1078b7cab076..73260364cba3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -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)); |
@@ -1712,10 +1716,12 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1712 | 1716 | ||
1713 | 1717 | ||
1714 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | 1718 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
1715 | /* 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 | */ | ||
1716 | static inline unsigned sky2_buf_size(int mtu) | 1722 | static inline unsigned sky2_buf_size(int mtu) |
1717 | { | 1723 | { |
1718 | return roundup(mtu + ETH_HLEN + 4, 8); | 1724 | return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
1719 | } | 1725 | } |
1720 | 1726 | ||
1721 | 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) |
@@ -1798,7 +1804,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1798 | if (!(status & GMR_FS_RX_OK)) | 1804 | if (!(status & GMR_FS_RX_OK)) |
1799 | goto resubmit; | 1805 | goto resubmit; |
1800 | 1806 | ||
1801 | if ((status >> 16) != length || length > sky2->rx_bufsize) | 1807 | if (length > sky2->netdev->mtu + ETH_HLEN) |
1802 | goto oversize; | 1808 | goto oversize; |
1803 | 1809 | ||
1804 | if (length < copybreak) { | 1810 | if (length < copybreak) { |