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 72c1630977d..73260364cba 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -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); | 
