diff options
Diffstat (limited to 'drivers/net/niu.c')
| -rw-r--r-- | drivers/net/niu.c | 52 | 
1 files changed, 40 insertions, 12 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ef940226ee2..30abb4e436f 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -36,8 +36,8 @@  #include "niu.h"  #define DRV_MODULE_NAME		"niu" -#define DRV_MODULE_VERSION	"1.0" -#define DRV_MODULE_RELDATE	"Nov 14, 2008" +#define DRV_MODULE_VERSION	"1.1" +#define DRV_MODULE_RELDATE	"Apr 22, 2010"  static char version[] __devinitdata =  	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -3444,6 +3444,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,  			      struct rx_ring_info *rp)  {  	unsigned int index = rp->rcr_index; +	struct rx_pkt_hdr1 *rh;  	struct sk_buff *skb;  	int len, num_rcr; @@ -3477,9 +3478,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,  		if (num_rcr == 1) {  			int ptype; -			off += 2; -			append_size -= 2; -  			ptype = (val >> RCR_ENTRY_PKT_TYPE_SHIFT);  			if ((ptype == RCR_PKT_TYPE_TCP ||  			     ptype == RCR_PKT_TYPE_UDP) && @@ -3488,8 +3486,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,  				skb->ip_summed = CHECKSUM_UNNECESSARY;  			else  				skb->ip_summed = CHECKSUM_NONE; -		} -		if (!(val & RCR_ENTRY_MULTI)) +		} else if (!(val & RCR_ENTRY_MULTI))  			append_size = len - skb->len;  		niu_rx_skb_append(skb, page, off, append_size); @@ -3510,8 +3507,17 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,  	}  	rp->rcr_index = index; -	skb_reserve(skb, NET_IP_ALIGN); -	__pskb_pull_tail(skb, min(len, VLAN_ETH_HLEN)); +	len += sizeof(*rh); +	len = min_t(int, len, sizeof(*rh) + VLAN_ETH_HLEN); +	__pskb_pull_tail(skb, len); + +	rh = (struct rx_pkt_hdr1 *) skb->data; +	if (np->dev->features & NETIF_F_RXHASH) +		skb->rxhash = ((u32)rh->hashval2_0 << 24 | +			       (u32)rh->hashval2_1 << 16 | +			       (u32)rh->hashval1_1 << 8 | +			       (u32)rh->hashval1_2 << 0); +	skb_pull(skb, sizeof(*rh));  	rp->rx_packets++;  	rp->rx_bytes += skb->len; @@ -4946,7 +4952,9 @@ static int niu_init_one_rx_channel(struct niu *np, struct rx_ring_info *rp)  	      RX_DMA_CTL_STAT_RCRTO |  	      RX_DMA_CTL_STAT_RBR_EMPTY));  	nw64(RXDMA_CFIG1(channel), rp->mbox_dma >> 32); -	nw64(RXDMA_CFIG2(channel), (rp->mbox_dma & 0x00000000ffffffc0)); +	nw64(RXDMA_CFIG2(channel), +	     ((rp->mbox_dma & RXDMA_CFIG2_MBADDR_L) | +	      RXDMA_CFIG2_FULL_HDR));  	nw64(RBR_CFIG_A(channel),  	     ((u64)rp->rbr_table_size << RBR_CFIG_A_LEN_SHIFT) |  	     (rp->rbr_dma & (RBR_CFIG_A_STADDR_BASE | RBR_CFIG_A_STADDR))); @@ -7910,6 +7918,18 @@ static int niu_phys_id(struct net_device *dev, u32 data)  	return 0;  } +static int niu_set_flags(struct net_device *dev, u32 data) +{ +	if (data & (ETH_FLAG_LRO | ETH_FLAG_NTUPLE)) +		return -EOPNOTSUPP; + +	if (data & ETH_FLAG_RXHASH) +		dev->features |= NETIF_F_RXHASH; +	else +		dev->features &= ~NETIF_F_RXHASH; +	return 0; +} +  static const struct ethtool_ops niu_ethtool_ops = {  	.get_drvinfo		= niu_get_drvinfo,  	.get_link		= ethtool_op_get_link, @@ -7926,6 +7946,8 @@ static const struct ethtool_ops niu_ethtool_ops = {  	.phys_id		= niu_phys_id,  	.get_rxnfc		= niu_get_nfc,  	.set_rxnfc		= niu_set_nfc, +	.set_flags		= niu_set_flags, +	.get_flags		= ethtool_op_get_flags,  };  static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent, @@ -9754,6 +9776,12 @@ static void __devinit niu_device_announce(struct niu *np)  	}  } +static void __devinit niu_set_basic_features(struct net_device *dev) +{ +	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | +			  NETIF_F_GRO | NETIF_F_RXHASH); +} +  static int __devinit niu_pci_init_one(struct pci_dev *pdev,  				      const struct pci_device_id *ent)  { @@ -9838,7 +9866,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,  		}  	} -	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); +	niu_set_basic_features(dev);  	np->regs = pci_ioremap_bar(pdev, 0);  	if (!np->regs) { @@ -10080,7 +10108,7 @@ static int __devinit niu_of_probe(struct of_device *op,  		goto err_out_free_dev;  	} -	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); +	niu_set_basic_features(dev);  	np->regs = of_ioremap(&op->resource[1], 0,  			      resource_size(&op->resource[1]),  |