diff options
Diffstat (limited to 'drivers/net/niu.c')
-rw-r--r-- | drivers/net/niu.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d5cd16bfc907..30abb4e436f1 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include "niu.h" | 36 | #include "niu.h" |
37 | 37 | ||
38 | #define DRV_MODULE_NAME "niu" | 38 | #define DRV_MODULE_NAME "niu" |
39 | #define DRV_MODULE_VERSION "1.0" | 39 | #define DRV_MODULE_VERSION "1.1" |
40 | #define DRV_MODULE_RELDATE "Nov 14, 2008" | 40 | #define DRV_MODULE_RELDATE "Apr 22, 2010" |
41 | 41 | ||
42 | static char version[] __devinitdata = | 42 | static char version[] __devinitdata = |
43 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 43 | 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, | |||
3444 | struct rx_ring_info *rp) | 3444 | struct rx_ring_info *rp) |
3445 | { | 3445 | { |
3446 | unsigned int index = rp->rcr_index; | 3446 | unsigned int index = rp->rcr_index; |
3447 | struct rx_pkt_hdr1 *rh; | ||
3447 | struct sk_buff *skb; | 3448 | struct sk_buff *skb; |
3448 | int len, num_rcr; | 3449 | int len, num_rcr; |
3449 | 3450 | ||
@@ -3477,9 +3478,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | |||
3477 | if (num_rcr == 1) { | 3478 | if (num_rcr == 1) { |
3478 | int ptype; | 3479 | int ptype; |
3479 | 3480 | ||
3480 | off += 2; | ||
3481 | append_size -= 2; | ||
3482 | |||
3483 | ptype = (val >> RCR_ENTRY_PKT_TYPE_SHIFT); | 3481 | ptype = (val >> RCR_ENTRY_PKT_TYPE_SHIFT); |
3484 | if ((ptype == RCR_PKT_TYPE_TCP || | 3482 | if ((ptype == RCR_PKT_TYPE_TCP || |
3485 | ptype == RCR_PKT_TYPE_UDP) && | 3483 | ptype == RCR_PKT_TYPE_UDP) && |
@@ -3488,8 +3486,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | |||
3488 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 3486 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
3489 | else | 3487 | else |
3490 | skb->ip_summed = CHECKSUM_NONE; | 3488 | skb->ip_summed = CHECKSUM_NONE; |
3491 | } | 3489 | } else if (!(val & RCR_ENTRY_MULTI)) |
3492 | if (!(val & RCR_ENTRY_MULTI)) | ||
3493 | append_size = len - skb->len; | 3490 | append_size = len - skb->len; |
3494 | 3491 | ||
3495 | niu_rx_skb_append(skb, page, off, append_size); | 3492 | 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, | |||
3510 | } | 3507 | } |
3511 | rp->rcr_index = index; | 3508 | rp->rcr_index = index; |
3512 | 3509 | ||
3513 | skb_reserve(skb, NET_IP_ALIGN); | 3510 | len += sizeof(*rh); |
3514 | __pskb_pull_tail(skb, min(len, VLAN_ETH_HLEN)); | 3511 | len = min_t(int, len, sizeof(*rh) + VLAN_ETH_HLEN); |
3512 | __pskb_pull_tail(skb, len); | ||
3513 | |||
3514 | rh = (struct rx_pkt_hdr1 *) skb->data; | ||
3515 | if (np->dev->features & NETIF_F_RXHASH) | ||
3516 | skb->rxhash = ((u32)rh->hashval2_0 << 24 | | ||
3517 | (u32)rh->hashval2_1 << 16 | | ||
3518 | (u32)rh->hashval1_1 << 8 | | ||
3519 | (u32)rh->hashval1_2 << 0); | ||
3520 | skb_pull(skb, sizeof(*rh)); | ||
3515 | 3521 | ||
3516 | rp->rx_packets++; | 3522 | rp->rx_packets++; |
3517 | rp->rx_bytes += skb->len; | 3523 | rp->rx_bytes += skb->len; |
@@ -4946,7 +4952,9 @@ static int niu_init_one_rx_channel(struct niu *np, struct rx_ring_info *rp) | |||
4946 | RX_DMA_CTL_STAT_RCRTO | | 4952 | RX_DMA_CTL_STAT_RCRTO | |
4947 | RX_DMA_CTL_STAT_RBR_EMPTY)); | 4953 | RX_DMA_CTL_STAT_RBR_EMPTY)); |
4948 | nw64(RXDMA_CFIG1(channel), rp->mbox_dma >> 32); | 4954 | nw64(RXDMA_CFIG1(channel), rp->mbox_dma >> 32); |
4949 | nw64(RXDMA_CFIG2(channel), (rp->mbox_dma & 0x00000000ffffffc0)); | 4955 | nw64(RXDMA_CFIG2(channel), |
4956 | ((rp->mbox_dma & RXDMA_CFIG2_MBADDR_L) | | ||
4957 | RXDMA_CFIG2_FULL_HDR)); | ||
4950 | nw64(RBR_CFIG_A(channel), | 4958 | nw64(RBR_CFIG_A(channel), |
4951 | ((u64)rp->rbr_table_size << RBR_CFIG_A_LEN_SHIFT) | | 4959 | ((u64)rp->rbr_table_size << RBR_CFIG_A_LEN_SHIFT) | |
4952 | (rp->rbr_dma & (RBR_CFIG_A_STADDR_BASE | RBR_CFIG_A_STADDR))); | 4960 | (rp->rbr_dma & (RBR_CFIG_A_STADDR_BASE | RBR_CFIG_A_STADDR))); |
@@ -6314,7 +6322,6 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6314 | { | 6322 | { |
6315 | struct niu *np = netdev_priv(dev); | 6323 | struct niu *np = netdev_priv(dev); |
6316 | int i, alt_cnt, err; | 6324 | int i, alt_cnt, err; |
6317 | struct dev_addr_list *addr; | ||
6318 | struct netdev_hw_addr *ha; | 6325 | struct netdev_hw_addr *ha; |
6319 | unsigned long flags; | 6326 | unsigned long flags; |
6320 | u16 hash[16] = { 0, }; | 6327 | u16 hash[16] = { 0, }; |
@@ -6366,8 +6373,8 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6366 | for (i = 0; i < 16; i++) | 6373 | for (i = 0; i < 16; i++) |
6367 | hash[i] = 0xffff; | 6374 | hash[i] = 0xffff; |
6368 | } else if (!netdev_mc_empty(dev)) { | 6375 | } else if (!netdev_mc_empty(dev)) { |
6369 | netdev_for_each_mc_addr(addr, dev) { | 6376 | netdev_for_each_mc_addr(ha, dev) { |
6370 | u32 crc = ether_crc_le(ETH_ALEN, addr->da_addr); | 6377 | u32 crc = ether_crc_le(ETH_ALEN, ha->addr); |
6371 | 6378 | ||
6372 | crc >>= 24; | 6379 | crc >>= 24; |
6373 | hash[crc >> 4] |= (1 << (15 - (crc & 0xf))); | 6380 | hash[crc >> 4] |= (1 << (15 - (crc & 0xf))); |
@@ -7911,6 +7918,18 @@ static int niu_phys_id(struct net_device *dev, u32 data) | |||
7911 | return 0; | 7918 | return 0; |
7912 | } | 7919 | } |
7913 | 7920 | ||
7921 | static int niu_set_flags(struct net_device *dev, u32 data) | ||
7922 | { | ||
7923 | if (data & (ETH_FLAG_LRO | ETH_FLAG_NTUPLE)) | ||
7924 | return -EOPNOTSUPP; | ||
7925 | |||
7926 | if (data & ETH_FLAG_RXHASH) | ||
7927 | dev->features |= NETIF_F_RXHASH; | ||
7928 | else | ||
7929 | dev->features &= ~NETIF_F_RXHASH; | ||
7930 | return 0; | ||
7931 | } | ||
7932 | |||
7914 | static const struct ethtool_ops niu_ethtool_ops = { | 7933 | static const struct ethtool_ops niu_ethtool_ops = { |
7915 | .get_drvinfo = niu_get_drvinfo, | 7934 | .get_drvinfo = niu_get_drvinfo, |
7916 | .get_link = ethtool_op_get_link, | 7935 | .get_link = ethtool_op_get_link, |
@@ -7927,6 +7946,8 @@ static const struct ethtool_ops niu_ethtool_ops = { | |||
7927 | .phys_id = niu_phys_id, | 7946 | .phys_id = niu_phys_id, |
7928 | .get_rxnfc = niu_get_nfc, | 7947 | .get_rxnfc = niu_get_nfc, |
7929 | .set_rxnfc = niu_set_nfc, | 7948 | .set_rxnfc = niu_set_nfc, |
7949 | .set_flags = niu_set_flags, | ||
7950 | .get_flags = ethtool_op_get_flags, | ||
7930 | }; | 7951 | }; |
7931 | 7952 | ||
7932 | static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent, | 7953 | static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent, |
@@ -9755,6 +9776,12 @@ static void __devinit niu_device_announce(struct niu *np) | |||
9755 | } | 9776 | } |
9756 | } | 9777 | } |
9757 | 9778 | ||
9779 | static void __devinit niu_set_basic_features(struct net_device *dev) | ||
9780 | { | ||
9781 | dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | | ||
9782 | NETIF_F_GRO | NETIF_F_RXHASH); | ||
9783 | } | ||
9784 | |||
9758 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, | 9785 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, |
9759 | const struct pci_device_id *ent) | 9786 | const struct pci_device_id *ent) |
9760 | { | 9787 | { |
@@ -9839,7 +9866,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, | |||
9839 | } | 9866 | } |
9840 | } | 9867 | } |
9841 | 9868 | ||
9842 | dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); | 9869 | niu_set_basic_features(dev); |
9843 | 9870 | ||
9844 | np->regs = pci_ioremap_bar(pdev, 0); | 9871 | np->regs = pci_ioremap_bar(pdev, 0); |
9845 | if (!np->regs) { | 9872 | if (!np->regs) { |
@@ -10081,7 +10108,7 @@ static int __devinit niu_of_probe(struct of_device *op, | |||
10081 | goto err_out_free_dev; | 10108 | goto err_out_free_dev; |
10082 | } | 10109 | } |
10083 | 10110 | ||
10084 | dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); | 10111 | niu_set_basic_features(dev); |
10085 | 10112 | ||
10086 | np->regs = of_ioremap(&op->resource[1], 0, | 10113 | np->regs = of_ioremap(&op->resource[1], 0, |
10087 | resource_size(&op->resource[1]), | 10114 | resource_size(&op->resource[1]), |