aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2012-02-17 08:43:05 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-03-01 01:36:56 -0500
commit719cdac54e0237837251a32a3d690bfe9c1e9bed (patch)
tree889f37acac24ca60453ec0347b987dcf46d48e6e
parent06b8db9cac717fcd6b8410b9efae8aca33b4b9e6 (diff)
e100: Support RXFCS feature flag.
This allows e100 to be configured to append the Ethernet FCS to the skb. Useful for sniffing networks. Signed-off-by: Ben Greear <greearb@candelatech.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/e100.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 485ab8cdac48..3ecbdedf6135 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -1075,7 +1075,7 @@ static void e100_get_defaults(struct nic *nic)
1075 /* Template for a freshly allocated RFD */ 1075 /* Template for a freshly allocated RFD */
1076 nic->blank_rfd.command = 0; 1076 nic->blank_rfd.command = 0;
1077 nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF); 1077 nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF);
1078 nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); 1078 nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN + ETH_FCS_LEN);
1079 1079
1080 /* MII setup */ 1080 /* MII setup */
1081 nic->mii.phy_id_mask = 0x1F; 1081 nic->mii.phy_id_mask = 0x1F;
@@ -1089,6 +1089,7 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1089{ 1089{
1090 struct config *config = &cb->u.config; 1090 struct config *config = &cb->u.config;
1091 u8 *c = (u8 *)config; 1091 u8 *c = (u8 *)config;
1092 struct net_device *netdev = nic->netdev;
1092 1093
1093 cb->command = cpu_to_le16(cb_config); 1094 cb->command = cpu_to_le16(cb_config);
1094 1095
@@ -1132,6 +1133,9 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1132 config->promiscuous_mode = 0x1; /* 1=on, 0=off */ 1133 config->promiscuous_mode = 0x1; /* 1=on, 0=off */
1133 } 1134 }
1134 1135
1136 if (unlikely(netdev->features & NETIF_F_RXFCS))
1137 config->rx_crc_transfer = 0x1; /* 1=save, 0=discard */
1138
1135 if (nic->flags & multicast_all) 1139 if (nic->flags & multicast_all)
1136 config->multicast_all = 0x1; /* 1=accept, 0=no */ 1140 config->multicast_all = 0x1; /* 1=accept, 0=no */
1137 1141
@@ -1881,7 +1885,7 @@ static inline void e100_start_receiver(struct nic *nic, struct rx *rx)
1881 } 1885 }
1882} 1886}
1883 1887
1884#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) 1888#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
1885static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) 1889static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1886{ 1890{
1887 if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN))) 1891 if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN)))
@@ -1919,6 +1923,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
1919 struct sk_buff *skb = rx->skb; 1923 struct sk_buff *skb = rx->skb;
1920 struct rfd *rfd = (struct rfd *)skb->data; 1924 struct rfd *rfd = (struct rfd *)skb->data;
1921 u16 rfd_status, actual_size; 1925 u16 rfd_status, actual_size;
1926 u16 fcs_pad = 0;
1922 1927
1923 if (unlikely(work_done && *work_done >= work_to_do)) 1928 if (unlikely(work_done && *work_done >= work_to_do))
1924 return -EAGAIN; 1929 return -EAGAIN;
@@ -1951,6 +1956,8 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
1951 } 1956 }
1952 1957
1953 /* Get actual data size */ 1958 /* Get actual data size */
1959 if (unlikely(dev->features & NETIF_F_RXFCS))
1960 fcs_pad = 4;
1954 actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF; 1961 actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
1955 if (unlikely(actual_size > RFD_BUF_LEN - sizeof(struct rfd))) 1962 if (unlikely(actual_size > RFD_BUF_LEN - sizeof(struct rfd)))
1956 actual_size = RFD_BUF_LEN - sizeof(struct rfd); 1963 actual_size = RFD_BUF_LEN - sizeof(struct rfd);
@@ -1980,13 +1987,13 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
1980 if (unlikely(!(rfd_status & cb_ok))) { 1987 if (unlikely(!(rfd_status & cb_ok))) {
1981 /* Don't indicate if hardware indicates errors */ 1988 /* Don't indicate if hardware indicates errors */
1982 dev_kfree_skb_any(skb); 1989 dev_kfree_skb_any(skb);
1983 } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) { 1990 } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + fcs_pad) {
1984 /* Don't indicate oversized frames */ 1991 /* Don't indicate oversized frames */
1985 nic->rx_over_length_errors++; 1992 nic->rx_over_length_errors++;
1986 dev_kfree_skb_any(skb); 1993 dev_kfree_skb_any(skb);
1987 } else { 1994 } else {
1988 dev->stats.rx_packets++; 1995 dev->stats.rx_packets++;
1989 dev->stats.rx_bytes += actual_size; 1996 dev->stats.rx_bytes += (actual_size - fcs_pad);
1990 netif_receive_skb(skb); 1997 netif_receive_skb(skb);
1991 if (work_done) 1998 if (work_done)
1992 (*work_done)++; 1999 (*work_done)++;
@@ -2058,7 +2065,8 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
2058 pci_dma_sync_single_for_device(nic->pdev, 2065 pci_dma_sync_single_for_device(nic->pdev,
2059 old_before_last_rx->dma_addr, sizeof(struct rfd), 2066 old_before_last_rx->dma_addr, sizeof(struct rfd),
2060 PCI_DMA_BIDIRECTIONAL); 2067 PCI_DMA_BIDIRECTIONAL);
2061 old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN); 2068 old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN
2069 + ETH_FCS_LEN);
2062 pci_dma_sync_single_for_device(nic->pdev, 2070 pci_dma_sync_single_for_device(nic->pdev,
2063 old_before_last_rx->dma_addr, sizeof(struct rfd), 2071 old_before_last_rx->dma_addr, sizeof(struct rfd),
2064 PCI_DMA_BIDIRECTIONAL); 2072 PCI_DMA_BIDIRECTIONAL);
@@ -2729,6 +2737,20 @@ static int e100_close(struct net_device *netdev)
2729 return 0; 2737 return 0;
2730} 2738}
2731 2739
2740static int e100_set_features(struct net_device *netdev,
2741 netdev_features_t features)
2742{
2743 struct nic *nic = netdev_priv(netdev);
2744 netdev_features_t changed = features ^ netdev->features;
2745
2746 if (!(changed & (NETIF_F_RXFCS)))
2747 return 0;
2748
2749 netdev->features = features;
2750 e100_exec_cb(nic, NULL, e100_configure);
2751 return 0;
2752}
2753
2732static const struct net_device_ops e100_netdev_ops = { 2754static const struct net_device_ops e100_netdev_ops = {
2733 .ndo_open = e100_open, 2755 .ndo_open = e100_open,
2734 .ndo_stop = e100_close, 2756 .ndo_stop = e100_close,
@@ -2742,6 +2764,7 @@ static const struct net_device_ops e100_netdev_ops = {
2742#ifdef CONFIG_NET_POLL_CONTROLLER 2764#ifdef CONFIG_NET_POLL_CONTROLLER
2743 .ndo_poll_controller = e100_netpoll, 2765 .ndo_poll_controller = e100_netpoll,
2744#endif 2766#endif
2767 .ndo_set_features = e100_set_features,
2745}; 2768};
2746 2769
2747static int __devinit e100_probe(struct pci_dev *pdev, 2770static int __devinit e100_probe(struct pci_dev *pdev,
@@ -2754,6 +2777,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2754 if (!(netdev = alloc_etherdev(sizeof(struct nic)))) 2777 if (!(netdev = alloc_etherdev(sizeof(struct nic))))
2755 return -ENOMEM; 2778 return -ENOMEM;
2756 2779
2780 netdev->hw_features |= NETIF_F_RXFCS;
2781
2757 netdev->netdev_ops = &e100_netdev_ops; 2782 netdev->netdev_ops = &e100_netdev_ops;
2758 SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops); 2783 SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
2759 netdev->watchdog_timeo = E100_WATCHDOG_PERIOD; 2784 netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;