aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2005-11-11 13:38:59 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-18 13:31:26 -0500
commit7f7f53168dbee6d6a462acea666fddd18aad4f08 (patch)
tree9c59f9b4b7c06f70b48197408f37398e54b4771e /drivers/net
parentfed5eccdcf542742786701b2514b5cb7ab282b93 (diff)
[PATCH] Gianfar update and sysfs support
This seems to have gotten lost, so I'll resend. Signed-off-by: Andy Fleming <afleming@freescale.com> * Added sysfs support to gianfar for modifying FIFO and stashing parameters * Updated driver to support 10 Mbit, full duplex operation * Improved comments throughout * Cleaned up and optimized offloading code * Fixed a bug where rx buffers were being improperly mapped and unmapped * (only manifested if cache-coherency was off) * Added support for using the eTSEC exact-match MAC registers * Bumped the version to 1.3 * Added support for distinguishing between reduced 100 and 10 Mbit modes * Modified default coalescing values to lower latency * Added documentation Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/gianfar.c231
-rw-r--r--drivers/net/gianfar.h69
-rw-r--r--drivers/net/gianfar_ethtool.c2
-rw-r--r--drivers/net/gianfar_mii.h1
-rw-r--r--drivers/net/gianfar_sysfs.c311
6 files changed, 507 insertions, 112 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 27822a2f0683..505681406314 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,10 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
13obj-$(CONFIG_BONDING) += bonding/ 13obj-$(CONFIG_BONDING) += bonding/
14obj-$(CONFIG_GIANFAR) += gianfar_driver.o 14obj-$(CONFIG_GIANFAR) += gianfar_driver.o
15 15
16gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o 16gianfar_driver-objs := gianfar.o \
17 gianfar_ethtool.o \
18 gianfar_mii.o \
19 gianfar_sysfs.o
17 20
18# 21#
19# link order important here 22# link order important here
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0f030b73cbb3..146f9513aea5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2,7 +2,8 @@
2 * drivers/net/gianfar.c 2 * drivers/net/gianfar.c
3 * 3 *
4 * Gianfar Ethernet Driver 4 * Gianfar Ethernet Driver
5 * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560 5 * This driver is designed for the non-CPM ethernet controllers
6 * on the 85xx and 83xx family of integrated processors
6 * Based on 8260_io/fcc_enet.c 7 * Based on 8260_io/fcc_enet.c
7 * 8 *
8 * Author: Andy Fleming 9 * Author: Andy Fleming
@@ -22,8 +23,6 @@
22 * B-V +1.62 23 * B-V +1.62
23 * 24 *
24 * Theory of operation 25 * Theory of operation
25 * This driver is designed for the non-CPM ethernet controllers
26 * on the 85xx and 83xx family of integrated processors
27 * 26 *
28 * The driver is initialized through platform_device. Structures which 27 * The driver is initialized through platform_device. Structures which
29 * define the configuration needed by the board are defined in a 28 * define the configuration needed by the board are defined in a
@@ -110,7 +109,7 @@
110#endif 109#endif
111 110
112const char gfar_driver_name[] = "Gianfar Ethernet"; 111const char gfar_driver_name[] = "Gianfar Ethernet";
113const char gfar_driver_version[] = "1.2"; 112const char gfar_driver_version[] = "1.3";
114 113
115static int gfar_enet_open(struct net_device *dev); 114static int gfar_enet_open(struct net_device *dev);
116static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); 115static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -139,6 +138,10 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
139static void gfar_vlan_rx_register(struct net_device *netdev, 138static void gfar_vlan_rx_register(struct net_device *netdev,
140 struct vlan_group *grp); 139 struct vlan_group *grp);
141static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); 140static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
141void gfar_halt(struct net_device *dev);
142void gfar_start(struct net_device *dev);
143static void gfar_clear_exact_match(struct net_device *dev);
144static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
142 145
143extern struct ethtool_ops gfar_ethtool_ops; 146extern struct ethtool_ops gfar_ethtool_ops;
144 147
@@ -146,12 +149,10 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
146MODULE_DESCRIPTION("Gianfar Ethernet Driver"); 149MODULE_DESCRIPTION("Gianfar Ethernet Driver");
147MODULE_LICENSE("GPL"); 150MODULE_LICENSE("GPL");
148 151
149int gfar_uses_fcb(struct gfar_private *priv) 152/* Returns 1 if incoming frames use an FCB */
153static inline int gfar_uses_fcb(struct gfar_private *priv)
150{ 154{
151 if (priv->vlan_enable || priv->rx_csum_enable) 155 return (priv->vlan_enable || priv->rx_csum_enable);
152 return 1;
153 else
154 return 0;
155} 156}
156 157
157/* Set up the ethernet device structure, private data, 158/* Set up the ethernet device structure, private data,
@@ -320,15 +321,10 @@ static int gfar_probe(struct platform_device *pdev)
320 else 321 else
321 priv->padding = 0; 322 priv->padding = 0;
322 323
323 dev->hard_header_len += priv->padding;
324
325 if (dev->features & NETIF_F_IP_CSUM) 324 if (dev->features & NETIF_F_IP_CSUM)
326 dev->hard_header_len += GMAC_FCB_LEN; 325 dev->hard_header_len += GMAC_FCB_LEN;
327 326
328 priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; 327 priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
329#ifdef CONFIG_GFAR_BUFSTASH
330 priv->rx_stash_size = STASH_LENGTH;
331#endif
332 priv->tx_ring_size = DEFAULT_TX_RING_SIZE; 328 priv->tx_ring_size = DEFAULT_TX_RING_SIZE;
333 priv->rx_ring_size = DEFAULT_RX_RING_SIZE; 329 priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
334 330
@@ -350,6 +346,9 @@ static int gfar_probe(struct platform_device *pdev)
350 goto register_fail; 346 goto register_fail;
351 } 347 }
352 348
349 /* Create all the sysfs files */
350 gfar_init_sysfs(dev);
351
353 /* Print out the device info */ 352 /* Print out the device info */
354 printk(KERN_INFO DEVICE_NAME, dev->name); 353 printk(KERN_INFO DEVICE_NAME, dev->name);
355 for (idx = 0; idx < 6; idx++) 354 for (idx = 0; idx < 6; idx++)
@@ -357,8 +356,7 @@ static int gfar_probe(struct platform_device *pdev)
357 printk("\n"); 356 printk("\n");
358 357
359 /* Even more device info helps when determining which kernel */ 358 /* Even more device info helps when determining which kernel */
360 /* provided which set of benchmarks. Since this is global for all */ 359 /* provided which set of benchmarks. */
361 /* devices, we only print it once */
362#ifdef CONFIG_GFAR_NAPI 360#ifdef CONFIG_GFAR_NAPI
363 printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); 361 printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
364#else 362#else
@@ -463,19 +461,9 @@ static void init_registers(struct net_device *dev)
463 /* Initialize the max receive buffer length */ 461 /* Initialize the max receive buffer length */
464 gfar_write(&priv->regs->mrblr, priv->rx_buffer_size); 462 gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
465 463
466#ifdef CONFIG_GFAR_BUFSTASH
467 /* If we are stashing buffers, we need to set the
468 * extraction length to the size of the buffer */
469 gfar_write(&priv->regs->attreli, priv->rx_stash_size << 16);
470#endif
471
472 /* Initialize the Minimum Frame Length Register */ 464 /* Initialize the Minimum Frame Length Register */
473 gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS); 465 gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
474 466
475 /* Setup Attributes so that snooping is on for rx */
476 gfar_write(&priv->regs->attr, ATTR_INIT_SETTINGS);
477 gfar_write(&priv->regs->attreli, ATTRELI_INIT_SETTINGS);
478
479 /* Assign the TBI an address which won't conflict with the PHYs */ 467 /* Assign the TBI an address which won't conflict with the PHYs */
480 gfar_write(&priv->regs->tbipa, TBIPA_VALUE); 468 gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
481} 469}
@@ -577,8 +565,7 @@ static void free_skb_resources(struct gfar_private *priv)
577 for (i = 0; i < priv->rx_ring_size; i++) { 565 for (i = 0; i < priv->rx_ring_size; i++) {
578 if (priv->rx_skbuff[i]) { 566 if (priv->rx_skbuff[i]) {
579 dma_unmap_single(NULL, rxbdp->bufPtr, 567 dma_unmap_single(NULL, rxbdp->bufPtr,
580 priv->rx_buffer_size 568 priv->rx_buffer_size,
581 + RXBUF_ALIGNMENT,
582 DMA_FROM_DEVICE); 569 DMA_FROM_DEVICE);
583 570
584 dev_kfree_skb_any(priv->rx_skbuff[i]); 571 dev_kfree_skb_any(priv->rx_skbuff[i]);
@@ -636,6 +623,7 @@ int startup_gfar(struct net_device *dev)
636 struct gfar *regs = priv->regs; 623 struct gfar *regs = priv->regs;
637 int err = 0; 624 int err = 0;
638 u32 rctrl = 0; 625 u32 rctrl = 0;
626 u32 attrs = 0;
639 627
640 gfar_write(&regs->imask, IMASK_INIT_CLEAR); 628 gfar_write(&regs->imask, IMASK_INIT_CLEAR);
641 629
@@ -795,18 +783,50 @@ int startup_gfar(struct net_device *dev)
795 if (priv->rx_csum_enable) 783 if (priv->rx_csum_enable)
796 rctrl |= RCTRL_CHECKSUMMING; 784 rctrl |= RCTRL_CHECKSUMMING;
797 785
798 if (priv->extended_hash) 786 if (priv->extended_hash) {
799 rctrl |= RCTRL_EXTHASH; 787 rctrl |= RCTRL_EXTHASH;
800 788
789 gfar_clear_exact_match(dev);
790 rctrl |= RCTRL_EMEN;
791 }
792
801 if (priv->vlan_enable) 793 if (priv->vlan_enable)
802 rctrl |= RCTRL_VLAN; 794 rctrl |= RCTRL_VLAN;
803 795
796 if (priv->padding) {
797 rctrl &= ~RCTRL_PAL_MASK;
798 rctrl |= RCTRL_PADDING(priv->padding);
799 }
800
804 /* Init rctrl based on our settings */ 801 /* Init rctrl based on our settings */
805 gfar_write(&priv->regs->rctrl, rctrl); 802 gfar_write(&priv->regs->rctrl, rctrl);
806 803
807 if (dev->features & NETIF_F_IP_CSUM) 804 if (dev->features & NETIF_F_IP_CSUM)
808 gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM); 805 gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
809 806
807 /* Set the extraction length and index */
808 attrs = ATTRELI_EL(priv->rx_stash_size) |
809 ATTRELI_EI(priv->rx_stash_index);
810
811 gfar_write(&priv->regs->attreli, attrs);
812
813 /* Start with defaults, and add stashing or locking
814 * depending on the approprate variables */
815 attrs = ATTR_INIT_SETTINGS;
816
817 if (priv->bd_stash_en)
818 attrs |= ATTR_BDSTASH;
819
820 if (priv->rx_stash_size != 0)
821 attrs |= ATTR_BUFSTASH;
822
823 gfar_write(&priv->regs->attr, attrs);
824
825 gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
826 gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
827 gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
828
829 /* Start the controller */
810 gfar_start(dev); 830 gfar_start(dev);
811 831
812 return 0; 832 return 0;
@@ -851,34 +871,32 @@ static int gfar_enet_open(struct net_device *dev)
851 return err; 871 return err;
852} 872}
853 873
854static struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp) 874static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
855{ 875{
856 struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN); 876 struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
857 877
858 memset(fcb, 0, GMAC_FCB_LEN); 878 memset(fcb, 0, GMAC_FCB_LEN);
859 879
860 /* Flag the bd so the controller looks for the FCB */
861 bdp->status |= TXBD_TOE;
862
863 return fcb; 880 return fcb;
864} 881}
865 882
866static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb) 883static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
867{ 884{
868 int len; 885 u8 flags = 0;
869 886
870 /* If we're here, it's a IP packet with a TCP or UDP 887 /* If we're here, it's a IP packet with a TCP or UDP
871 * payload. We set it to checksum, using a pseudo-header 888 * payload. We set it to checksum, using a pseudo-header
872 * we provide 889 * we provide
873 */ 890 */
874 fcb->ip = 1; 891 flags = TXFCB_DEFAULT;
875 fcb->tup = 1;
876 fcb->ctu = 1;
877 fcb->nph = 1;
878 892
879 /* Notify the controller what the protocol is */ 893 /* Tell the controller what the protocol is */
880 if (skb->nh.iph->protocol == IPPROTO_UDP) 894 /* And provide the already calculated phcs */
881 fcb->udp = 1; 895 if (skb->nh.iph->protocol == IPPROTO_UDP) {
896 flags |= TXFCB_UDP;
897 fcb->phcs = skb->h.uh->check;
898 } else
899 fcb->phcs = skb->h.th->check;
882 900
883 /* l3os is the distance between the start of the 901 /* l3os is the distance between the start of the
884 * frame (skb->data) and the start of the IP hdr. 902 * frame (skb->data) and the start of the IP hdr.
@@ -887,17 +905,12 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
887 fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN); 905 fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN);
888 fcb->l4os = (u16)(skb->h.raw - skb->nh.raw); 906 fcb->l4os = (u16)(skb->h.raw - skb->nh.raw);
889 907
890 len = skb->nh.iph->tot_len - fcb->l4os; 908 fcb->flags = flags;
891
892 /* Provide the pseudoheader csum */
893 fcb->phcs = ~csum_tcpudp_magic(skb->nh.iph->saddr,
894 skb->nh.iph->daddr, len,
895 skb->nh.iph->protocol, 0);
896} 909}
897 910
898void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb) 911void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
899{ 912{
900 fcb->vln = 1; 913 fcb->flags |= TXFCB_VLN;
901 fcb->vlctl = vlan_tx_tag_get(skb); 914 fcb->vlctl = vlan_tx_tag_get(skb);
902} 915}
903 916
@@ -908,6 +921,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
908 struct gfar_private *priv = netdev_priv(dev); 921 struct gfar_private *priv = netdev_priv(dev);
909 struct txfcb *fcb = NULL; 922 struct txfcb *fcb = NULL;
910 struct txbd8 *txbdp; 923 struct txbd8 *txbdp;
924 u16 status;
911 925
912 /* Update transmit stats */ 926 /* Update transmit stats */
913 priv->stats.tx_bytes += skb->len; 927 priv->stats.tx_bytes += skb->len;
@@ -919,19 +933,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
919 txbdp = priv->cur_tx; 933 txbdp = priv->cur_tx;
920 934
921 /* Clear all but the WRAP status flags */ 935 /* Clear all but the WRAP status flags */
922 txbdp->status &= TXBD_WRAP; 936 status = txbdp->status & TXBD_WRAP;
923 937
924 /* Set up checksumming */ 938 /* Set up checksumming */
925 if ((dev->features & NETIF_F_IP_CSUM) 939 if (likely((dev->features & NETIF_F_IP_CSUM)
926 && (CHECKSUM_HW == skb->ip_summed)) { 940 && (CHECKSUM_HW == skb->ip_summed))) {
927 fcb = gfar_add_fcb(skb, txbdp); 941 fcb = gfar_add_fcb(skb, txbdp);
942 status |= TXBD_TOE;
928 gfar_tx_checksum(skb, fcb); 943 gfar_tx_checksum(skb, fcb);
929 } 944 }
930 945
931 if (priv->vlan_enable && 946 if (priv->vlan_enable &&
932 unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) { 947 unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
933 if (NULL == fcb) 948 if (unlikely(NULL == fcb)) {
934 fcb = gfar_add_fcb(skb, txbdp); 949 fcb = gfar_add_fcb(skb, txbdp);
950 status |= TXBD_TOE;
951 }
935 952
936 gfar_tx_vlan(skb, fcb); 953 gfar_tx_vlan(skb, fcb);
937 } 954 }
@@ -949,14 +966,16 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
949 (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size); 966 (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size);
950 967
951 /* Flag the BD as interrupt-causing */ 968 /* Flag the BD as interrupt-causing */
952 txbdp->status |= TXBD_INTERRUPT; 969 status |= TXBD_INTERRUPT;
953 970
954 /* Flag the BD as ready to go, last in frame, and */ 971 /* Flag the BD as ready to go, last in frame, and */
955 /* in need of CRC */ 972 /* in need of CRC */
956 txbdp->status |= (TXBD_READY | TXBD_LAST | TXBD_CRC); 973 status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
957 974
958 dev->trans_start = jiffies; 975 dev->trans_start = jiffies;
959 976
977 txbdp->status = status;
978
960 /* If this was the last BD in the ring, the next one */ 979 /* If this was the last BD in the ring, the next one */
961 /* is at the beginning of the ring */ 980 /* is at the beginning of the ring */
962 if (txbdp->status & TXBD_WRAP) 981 if (txbdp->status & TXBD_WRAP)
@@ -1010,21 +1029,7 @@ static struct net_device_stats * gfar_get_stats(struct net_device *dev)
1010/* Changes the mac address if the controller is not running. */ 1029/* Changes the mac address if the controller is not running. */
1011int gfar_set_mac_address(struct net_device *dev) 1030int gfar_set_mac_address(struct net_device *dev)
1012{ 1031{
1013 struct gfar_private *priv = netdev_priv(dev); 1032 gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
1014 int i;
1015 char tmpbuf[MAC_ADDR_LEN];
1016 u32 tempval;
1017
1018 /* Now copy it into the mac registers backwards, cuz */
1019 /* little endian is silly */
1020 for (i = 0; i < MAC_ADDR_LEN; i++)
1021 tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->dev_addr[i];
1022
1023 gfar_write(&priv->regs->macstnaddr1, *((u32 *) (tmpbuf)));
1024
1025 tempval = *((u32 *) (tmpbuf + 4));
1026
1027 gfar_write(&priv->regs->macstnaddr2, tempval);
1028 1033
1029 return 0; 1034 return 0;
1030} 1035}
@@ -1110,7 +1115,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
1110 INCREMENTAL_BUFFER_SIZE; 1115 INCREMENTAL_BUFFER_SIZE;
1111 1116
1112 /* Only stop and start the controller if it isn't already 1117 /* Only stop and start the controller if it isn't already
1113 * stopped */ 1118 * stopped, and we changed something */
1114 if ((oldsize != tempsize) && (dev->flags & IFF_UP)) 1119 if ((oldsize != tempsize) && (dev->flags & IFF_UP))
1115 stop_gfar(dev); 1120 stop_gfar(dev);
1116 1121
@@ -1220,6 +1225,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs)
1220 1225
1221struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) 1226struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
1222{ 1227{
1228 unsigned int alignamount;
1223 struct gfar_private *priv = netdev_priv(dev); 1229 struct gfar_private *priv = netdev_priv(dev);
1224 struct sk_buff *skb = NULL; 1230 struct sk_buff *skb = NULL;
1225 unsigned int timeout = SKB_ALLOC_TIMEOUT; 1231 unsigned int timeout = SKB_ALLOC_TIMEOUT;
@@ -1231,18 +1237,18 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
1231 if (NULL == skb) 1237 if (NULL == skb)
1232 return NULL; 1238 return NULL;
1233 1239
1240 alignamount = RXBUF_ALIGNMENT -
1241 (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1));
1242
1234 /* We need the data buffer to be aligned properly. We will reserve 1243 /* We need the data buffer to be aligned properly. We will reserve
1235 * as many bytes as needed to align the data properly 1244 * as many bytes as needed to align the data properly
1236 */ 1245 */
1237 skb_reserve(skb, 1246 skb_reserve(skb, alignamount);
1238 RXBUF_ALIGNMENT -
1239 (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1)));
1240 1247
1241 skb->dev = dev; 1248 skb->dev = dev;
1242 1249
1243 bdp->bufPtr = dma_map_single(NULL, skb->data, 1250 bdp->bufPtr = dma_map_single(NULL, skb->data,
1244 priv->rx_buffer_size + RXBUF_ALIGNMENT, 1251 priv->rx_buffer_size, DMA_FROM_DEVICE);
1245 DMA_FROM_DEVICE);
1246 1252
1247 bdp->length = 0; 1253 bdp->length = 0;
1248 1254
@@ -1350,7 +1356,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
1350 /* If valid headers were found, and valid sums 1356 /* If valid headers were found, and valid sums
1351 * were verified, then we tell the kernel that no 1357 * were verified, then we tell the kernel that no
1352 * checksumming is necessary. Otherwise, it is */ 1358 * checksumming is necessary. Otherwise, it is */
1353 if (fcb->cip && !fcb->eip && fcb->ctu && !fcb->etu) 1359 if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
1354 skb->ip_summed = CHECKSUM_UNNECESSARY; 1360 skb->ip_summed = CHECKSUM_UNNECESSARY;
1355 else 1361 else
1356 skb->ip_summed = CHECKSUM_NONE; 1362 skb->ip_summed = CHECKSUM_NONE;
@@ -1401,7 +1407,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
1401 skb->protocol = eth_type_trans(skb, dev); 1407 skb->protocol = eth_type_trans(skb, dev);
1402 1408
1403 /* Send the packet up the stack */ 1409 /* Send the packet up the stack */
1404 if (unlikely(priv->vlgrp && fcb->vln)) 1410 if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
1405 ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl); 1411 ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
1406 else 1412 else
1407 ret = RECEIVE(skb); 1413 ret = RECEIVE(skb);
@@ -1620,6 +1626,7 @@ static void adjust_link(struct net_device *dev)
1620 spin_lock_irqsave(&priv->lock, flags); 1626 spin_lock_irqsave(&priv->lock, flags);
1621 if (phydev->link) { 1627 if (phydev->link) {
1622 u32 tempval = gfar_read(&regs->maccfg2); 1628 u32 tempval = gfar_read(&regs->maccfg2);
1629 u32 ecntrl = gfar_read(&regs->ecntrl);
1623 1630
1624 /* Now we make sure that we can be in full duplex mode. 1631 /* Now we make sure that we can be in full duplex mode.
1625 * If not, we operate in half-duplex mode. */ 1632 * If not, we operate in half-duplex mode. */
@@ -1644,6 +1651,13 @@ static void adjust_link(struct net_device *dev)
1644 case 10: 1651 case 10:
1645 tempval = 1652 tempval =
1646 ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); 1653 ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
1654
1655 /* Reduced mode distinguishes
1656 * between 10 and 100 */
1657 if (phydev->speed == SPEED_100)
1658 ecntrl |= ECNTRL_R100;
1659 else
1660 ecntrl &= ~(ECNTRL_R100);
1647 break; 1661 break;
1648 default: 1662 default:
1649 if (netif_msg_link(priv)) 1663 if (netif_msg_link(priv))
@@ -1657,6 +1671,7 @@ static void adjust_link(struct net_device *dev)
1657 } 1671 }
1658 1672
1659 gfar_write(&regs->maccfg2, tempval); 1673 gfar_write(&regs->maccfg2, tempval);
1674 gfar_write(&regs->ecntrl, ecntrl);
1660 1675
1661 if (!priv->oldlink) { 1676 if (!priv->oldlink) {
1662 new_state = 1; 1677 new_state = 1;
@@ -1721,6 +1736,9 @@ static void gfar_set_multi(struct net_device *dev)
1721 gfar_write(&regs->gaddr6, 0xffffffff); 1736 gfar_write(&regs->gaddr6, 0xffffffff);
1722 gfar_write(&regs->gaddr7, 0xffffffff); 1737 gfar_write(&regs->gaddr7, 0xffffffff);
1723 } else { 1738 } else {
1739 int em_num;
1740 int idx;
1741
1724 /* zero out the hash */ 1742 /* zero out the hash */
1725 gfar_write(&regs->igaddr0, 0x0); 1743 gfar_write(&regs->igaddr0, 0x0);
1726 gfar_write(&regs->igaddr1, 0x0); 1744 gfar_write(&regs->igaddr1, 0x0);
@@ -1739,18 +1757,47 @@ static void gfar_set_multi(struct net_device *dev)
1739 gfar_write(&regs->gaddr6, 0x0); 1757 gfar_write(&regs->gaddr6, 0x0);
1740 gfar_write(&regs->gaddr7, 0x0); 1758 gfar_write(&regs->gaddr7, 0x0);
1741 1759
1760 /* If we have extended hash tables, we need to
1761 * clear the exact match registers to prepare for
1762 * setting them */
1763 if (priv->extended_hash) {
1764 em_num = GFAR_EM_NUM + 1;
1765 gfar_clear_exact_match(dev);
1766 idx = 1;
1767 } else {
1768 idx = 0;
1769 em_num = 0;
1770 }
1771
1742 if(dev->mc_count == 0) 1772 if(dev->mc_count == 0)
1743 return; 1773 return;
1744 1774
1745 /* Parse the list, and set the appropriate bits */ 1775 /* Parse the list, and set the appropriate bits */
1746 for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { 1776 for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
1747 gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr); 1777 if (idx < em_num) {
1778 gfar_set_mac_for_addr(dev, idx,
1779 mc_ptr->dmi_addr);
1780 idx++;
1781 } else
1782 gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
1748 } 1783 }
1749 } 1784 }
1750 1785
1751 return; 1786 return;
1752} 1787}
1753 1788
1789
1790/* Clears each of the exact match registers to zero, so they
1791 * don't interfere with normal reception */
1792static void gfar_clear_exact_match(struct net_device *dev)
1793{
1794 int idx;
1795 u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0};
1796
1797 for(idx = 1;idx < GFAR_EM_NUM + 1;idx++)
1798 gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr);
1799}
1800
1754/* Set the appropriate hash bit for the given addr */ 1801/* Set the appropriate hash bit for the given addr */
1755/* The algorithm works like so: 1802/* The algorithm works like so:
1756 * 1) Take the Destination Address (ie the multicast address), and 1803 * 1) Take the Destination Address (ie the multicast address), and
@@ -1781,6 +1828,32 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
1781 return; 1828 return;
1782} 1829}
1783 1830
1831
1832/* There are multiple MAC Address register pairs on some controllers
1833 * This function sets the numth pair to a given address
1834 */
1835static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
1836{
1837 struct gfar_private *priv = netdev_priv(dev);
1838 int idx;
1839 char tmpbuf[MAC_ADDR_LEN];
1840 u32 tempval;
1841 u32 *macptr = &priv->regs->macstnaddr1;
1842
1843 macptr += num*2;
1844
1845 /* Now copy it into the mac registers backwards, cuz */
1846 /* little endian is silly */
1847 for (idx = 0; idx < MAC_ADDR_LEN; idx++)
1848 tmpbuf[MAC_ADDR_LEN - 1 - idx] = addr[idx];
1849
1850 gfar_write(macptr, *((u32 *) (tmpbuf)));
1851
1852 tempval = *((u32 *) (tmpbuf + 4));
1853
1854 gfar_write(macptr+1, tempval);
1855}
1856
1784/* GFAR error interrupt handler */ 1857/* GFAR error interrupt handler */
1785static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs) 1858static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
1786{ 1859{
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 5065ba82cb76..94a91da84fbb 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -90,12 +90,26 @@ extern const char gfar_driver_version[];
90#define GFAR_RX_MAX_RING_SIZE 256 90#define GFAR_RX_MAX_RING_SIZE 256
91#define GFAR_TX_MAX_RING_SIZE 256 91#define GFAR_TX_MAX_RING_SIZE 256
92 92
93#define GFAR_MAX_FIFO_THRESHOLD 511
94#define GFAR_MAX_FIFO_STARVE 511
95#define GFAR_MAX_FIFO_STARVE_OFF 511
96
93#define DEFAULT_RX_BUFFER_SIZE 1536 97#define DEFAULT_RX_BUFFER_SIZE 1536
94#define TX_RING_MOD_MASK(size) (size-1) 98#define TX_RING_MOD_MASK(size) (size-1)
95#define RX_RING_MOD_MASK(size) (size-1) 99#define RX_RING_MOD_MASK(size) (size-1)
96#define JUMBO_BUFFER_SIZE 9728 100#define JUMBO_BUFFER_SIZE 9728
97#define JUMBO_FRAME_SIZE 9600 101#define JUMBO_FRAME_SIZE 9600
98 102
103#define DEFAULT_FIFO_TX_THR 0x100
104#define DEFAULT_FIFO_TX_STARVE 0x40
105#define DEFAULT_FIFO_TX_STARVE_OFF 0x80
106#define DEFAULT_BD_STASH 1
107#define DEFAULT_STASH_LENGTH 64
108#define DEFAULT_STASH_INDEX 0
109
110/* The number of Exact Match registers */
111#define GFAR_EM_NUM 15
112
99/* Latency of interface clock in nanoseconds */ 113/* Latency of interface clock in nanoseconds */
100/* Interface clock latency , in this case, means the 114/* Interface clock latency , in this case, means the
101 * time described by a value of 1 in the interrupt 115 * time described by a value of 1 in the interrupt
@@ -112,11 +126,11 @@ extern const char gfar_driver_version[];
112 126
113#define DEFAULT_TX_COALESCE 1 127#define DEFAULT_TX_COALESCE 1
114#define DEFAULT_TXCOUNT 16 128#define DEFAULT_TXCOUNT 16
115#define DEFAULT_TXTIME 400 129#define DEFAULT_TXTIME 4
116 130
117#define DEFAULT_RX_COALESCE 1 131#define DEFAULT_RX_COALESCE 1
118#define DEFAULT_RXCOUNT 16 132#define DEFAULT_RXCOUNT 16
119#define DEFAULT_RXTIME 400 133#define DEFAULT_RXTIME 4
120 134
121#define TBIPA_VALUE 0x1f 135#define TBIPA_VALUE 0x1f
122#define MIIMCFG_INIT_VALUE 0x00000007 136#define MIIMCFG_INIT_VALUE 0x00000007
@@ -147,6 +161,7 @@ extern const char gfar_driver_version[];
147 161
148#define ECNTRL_INIT_SETTINGS 0x00001000 162#define ECNTRL_INIT_SETTINGS 0x00001000
149#define ECNTRL_TBI_MODE 0x00000020 163#define ECNTRL_TBI_MODE 0x00000020
164#define ECNTRL_R100 0x00000008
150 165
151#define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE 166#define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE
152 167
@@ -181,10 +196,12 @@ extern const char gfar_driver_version[];
181#define RCTRL_PRSDEP_MASK 0x000000c0 196#define RCTRL_PRSDEP_MASK 0x000000c0
182#define RCTRL_PRSDEP_INIT 0x000000c0 197#define RCTRL_PRSDEP_INIT 0x000000c0
183#define RCTRL_PROM 0x00000008 198#define RCTRL_PROM 0x00000008
199#define RCTRL_EMEN 0x00000002
184#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \ 200#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \
185 | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT) 201 | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
186#define RCTRL_EXTHASH (RCTRL_GHTX) 202#define RCTRL_EXTHASH (RCTRL_GHTX)
187#define RCTRL_VLAN (RCTRL_PRSDEP_INIT) 203#define RCTRL_VLAN (RCTRL_PRSDEP_INIT)
204#define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK)
188 205
189 206
190#define RSTAT_CLEAR_RHALT 0x00800000 207#define RSTAT_CLEAR_RHALT 0x00800000
@@ -251,28 +268,26 @@ extern const char gfar_driver_version[];
251 IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \ 268 IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
252 | IMASK_PERR) 269 | IMASK_PERR)
253 270
271/* Fifo management */
272#define FIFO_TX_THR_MASK 0x01ff
273#define FIFO_TX_STARVE_MASK 0x01ff
274#define FIFO_TX_STARVE_OFF_MASK 0x01ff
254 275
255/* Attribute fields */ 276/* Attribute fields */
256 277
257/* This enables rx snooping for buffers and descriptors */ 278/* This enables rx snooping for buffers and descriptors */
258#ifdef CONFIG_GFAR_BDSTASH
259#define ATTR_BDSTASH 0x00000800 279#define ATTR_BDSTASH 0x00000800
260#else
261#define ATTR_BDSTASH 0x00000000
262#endif
263 280
264#ifdef CONFIG_GFAR_BUFSTASH
265#define ATTR_BUFSTASH 0x00004000 281#define ATTR_BUFSTASH 0x00004000
266#define STASH_LENGTH 64
267#else
268#define ATTR_BUFSTASH 0x00000000
269#endif
270 282
271#define ATTR_SNOOPING 0x000000c0 283#define ATTR_SNOOPING 0x000000c0
272#define ATTR_INIT_SETTINGS (ATTR_SNOOPING \ 284#define ATTR_INIT_SETTINGS ATTR_SNOOPING
273 | ATTR_BDSTASH | ATTR_BUFSTASH)
274 285
275#define ATTRELI_INIT_SETTINGS 0x0 286#define ATTRELI_INIT_SETTINGS 0x0
287#define ATTRELI_EL_MASK 0x3fff0000
288#define ATTRELI_EL(x) (x << 16)
289#define ATTRELI_EI_MASK 0x00003fff
290#define ATTRELI_EI(x) (x)
276 291
277 292
278/* TxBD status field bits */ 293/* TxBD status field bits */
@@ -328,6 +343,7 @@ extern const char gfar_driver_version[];
328#define RXFCB_CTU 0x0400 343#define RXFCB_CTU 0x0400
329#define RXFCB_EIP 0x0200 344#define RXFCB_EIP 0x0200
330#define RXFCB_ETU 0x0100 345#define RXFCB_ETU 0x0100
346#define RXFCB_CSUM_MASK 0x0f00
331#define RXFCB_PERR_MASK 0x000c 347#define RXFCB_PERR_MASK 0x000c
332#define RXFCB_PERR_BADL3 0x0008 348#define RXFCB_PERR_BADL3 0x0008
333 349
@@ -339,14 +355,7 @@ struct txbd8
339}; 355};
340 356
341struct txfcb { 357struct txfcb {
342 u8 vln:1, 358 u8 flags;
343 ip:1,
344 ip6:1,
345 tup:1,
346 udp:1,
347 cip:1,
348 ctu:1,
349 nph:1;
350 u8 reserved; 359 u8 reserved;
351 u8 l4os; /* Level 4 Header Offset */ 360 u8 l4os; /* Level 4 Header Offset */
352 u8 l3os; /* Level 3 Header Offset */ 361 u8 l3os; /* Level 3 Header Offset */
@@ -362,14 +371,7 @@ struct rxbd8
362}; 371};
363 372
364struct rxfcb { 373struct rxfcb {
365 u16 vln:1, 374 u16 flags;
366 ip:1,
367 ip6:1,
368 tup:1,
369 cip:1,
370 ctu:1,
371 eip:1,
372 etu:1;
373 u8 rq; /* Receive Queue index */ 375 u8 rq; /* Receive Queue index */
374 u8 pro; /* Layer 4 Protocol */ 376 u8 pro; /* Layer 4 Protocol */
375 u16 reserved; 377 u16 reserved;
@@ -688,12 +690,17 @@ struct gfar_private {
688 spinlock_t lock; 690 spinlock_t lock;
689 unsigned int rx_buffer_size; 691 unsigned int rx_buffer_size;
690 unsigned int rx_stash_size; 692 unsigned int rx_stash_size;
693 unsigned int rx_stash_index;
691 unsigned int tx_ring_size; 694 unsigned int tx_ring_size;
692 unsigned int rx_ring_size; 695 unsigned int rx_ring_size;
696 unsigned int fifo_threshold;
697 unsigned int fifo_starve;
698 unsigned int fifo_starve_off;
693 699
694 unsigned char vlan_enable:1, 700 unsigned char vlan_enable:1,
695 rx_csum_enable:1, 701 rx_csum_enable:1,
696 extended_hash:1; 702 extended_hash:1,
703 bd_stash_en:1;
697 unsigned short padding; 704 unsigned short padding;
698 struct vlan_group *vlgrp; 705 struct vlan_group *vlgrp;
699 /* Info structure initialized by board setup code */ 706 /* Info structure initialized by board setup code */
@@ -731,6 +738,6 @@ extern void stop_gfar(struct net_device *dev);
731extern void gfar_halt(struct net_device *dev); 738extern void gfar_halt(struct net_device *dev);
732extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, 739extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
733 int enable, u32 regnum, u32 read); 740 int enable, u32 regnum, u32 read);
734void gfar_setup_stashing(struct net_device *dev); 741void gfar_init_sysfs(struct net_device *dev);
735 742
736#endif /* __GIANFAR_H */ 743#endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index cfa3cd7c91a0..765e810620fe 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -125,7 +125,7 @@ static char stat_gstrings[][ETH_GSTRING_LEN] = {
125static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) 125static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
126{ 126{
127 struct gfar_private *priv = netdev_priv(dev); 127 struct gfar_private *priv = netdev_priv(dev);
128 128
129 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) 129 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
130 memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); 130 memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
131 else 131 else
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index e85eb216fb5b..d527cf2f9c1d 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -24,6 +24,7 @@
24#define MII_READ_COMMAND 0x00000001 24#define MII_READ_COMMAND 0x00000001
25 25
26#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \ 26#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
27 | SUPPORTED_10baseT_Full \
27 | SUPPORTED_100baseT_Half \ 28 | SUPPORTED_100baseT_Half \
28 | SUPPORTED_100baseT_Full \ 29 | SUPPORTED_100baseT_Full \
29 | SUPPORTED_Autoneg \ 30 | SUPPORTED_Autoneg \
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
new file mode 100644
index 000000000000..10d34cb19192
--- /dev/null
+++ b/drivers/net/gianfar_sysfs.c
@@ -0,0 +1,311 @@
1/*
2 * drivers/net/gianfar_sysfs.c
3 *
4 * Gianfar Ethernet Driver
5 * This driver is designed for the non-CPM ethernet controllers
6 * on the 85xx and 83xx family of integrated processors
7 * Based on 8260_io/fcc_enet.c
8 *
9 * Author: Andy Fleming
10 * Maintainer: Kumar Gala (kumar.gala@freescale.com)
11 *
12 * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * Sysfs file creation and management
20 */
21
22#include <linux/config.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/string.h>
26#include <linux/errno.h>
27#include <linux/unistd.h>
28#include <linux/slab.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/etherdevice.h>
32#include <linux/spinlock.h>
33#include <linux/mm.h>
34#include <linux/device.h>
35
36#include <asm/uaccess.h>
37#include <linux/module.h>
38#include <linux/version.h>
39
40#include "gianfar.h"
41
42#define GFAR_ATTR(_name) \
43static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
44static ssize_t gfar_set_##_name(struct class_device *cdev, \
45 const char *buf, size_t count); \
46static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
47
48#define GFAR_CREATE_FILE(_dev, _name) \
49 class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
50
51GFAR_ATTR(bd_stash);
52GFAR_ATTR(rx_stash_size);
53GFAR_ATTR(rx_stash_index);
54GFAR_ATTR(fifo_threshold);
55GFAR_ATTR(fifo_starve);
56GFAR_ATTR(fifo_starve_off);
57
58#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
59
60static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
61{
62 struct net_device *dev = to_net_dev(cdev);
63 struct gfar_private *priv = netdev_priv(dev);
64
65 return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
66}
67
68static ssize_t gfar_set_bd_stash(struct class_device *cdev,
69 const char *buf, size_t count)
70{
71 struct net_device *dev = to_net_dev(cdev);
72 struct gfar_private *priv = netdev_priv(dev);
73 int new_setting = 0;
74 u32 temp;
75 unsigned long flags;
76
77 /* Find out the new setting */
78 if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
79 new_setting = 1;
80 else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
81 new_setting = 0;
82 else
83 return count;
84
85 spin_lock_irqsave(&priv->lock, flags);
86
87 /* Set the new stashing value */
88 priv->bd_stash_en = new_setting;
89
90 temp = gfar_read(&priv->regs->attr);
91
92 if (new_setting)
93 temp |= ATTR_BDSTASH;
94 else
95 temp &= ~(ATTR_BDSTASH);
96
97 gfar_write(&priv->regs->attr, temp);
98
99 spin_unlock_irqrestore(&priv->lock, flags);
100
101 return count;
102}
103
104static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
105{
106 struct net_device *dev = to_net_dev(cdev);
107 struct gfar_private *priv = netdev_priv(dev);
108
109 return sprintf(buf, "%d\n", priv->rx_stash_size);
110}
111
112static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
113 const char *buf, size_t count)
114{
115 struct net_device *dev = to_net_dev(cdev);
116 struct gfar_private *priv = netdev_priv(dev);
117 unsigned int length = simple_strtoul(buf, NULL, 0);
118 u32 temp;
119 unsigned long flags;
120
121 spin_lock_irqsave(&priv->lock, flags);
122 if (length > priv->rx_buffer_size)
123 return count;
124
125 if (length == priv->rx_stash_size)
126 return count;
127
128 priv->rx_stash_size = length;
129
130 temp = gfar_read(&priv->regs->attreli);
131 temp &= ~ATTRELI_EL_MASK;
132 temp |= ATTRELI_EL(length);
133 gfar_write(&priv->regs->attreli, temp);
134
135 /* Turn stashing on/off as appropriate */
136 temp = gfar_read(&priv->regs->attr);
137
138 if (length)
139 temp |= ATTR_BUFSTASH;
140 else
141 temp &= ~(ATTR_BUFSTASH);
142
143 gfar_write(&priv->regs->attr, temp);
144
145 spin_unlock_irqrestore(&priv->lock, flags);
146
147 return count;
148}
149
150
151/* Stashing will only be enabled when rx_stash_size != 0 */
152static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
153{
154 struct net_device *dev = to_net_dev(cdev);
155 struct gfar_private *priv = netdev_priv(dev);
156
157 return sprintf(buf, "%d\n", priv->rx_stash_index);
158}
159
160static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
161 const char *buf, size_t count)
162{
163 struct net_device *dev = to_net_dev(cdev);
164 struct gfar_private *priv = netdev_priv(dev);
165 unsigned short index = simple_strtoul(buf, NULL, 0);
166 u32 temp;
167 unsigned long flags;
168
169 spin_lock_irqsave(&priv->lock, flags);
170 if (index > priv->rx_stash_size)
171 return count;
172
173 if (index == priv->rx_stash_index)
174 return count;
175
176 priv->rx_stash_index = index;
177
178 temp = gfar_read(&priv->regs->attreli);
179 temp &= ~ATTRELI_EI_MASK;
180 temp |= ATTRELI_EI(index);
181 gfar_write(&priv->regs->attreli, flags);
182
183 spin_unlock_irqrestore(&priv->lock, flags);
184
185 return count;
186}
187
188static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
189{
190 struct net_device *dev = to_net_dev(cdev);
191 struct gfar_private *priv = netdev_priv(dev);
192
193 return sprintf(buf, "%d\n", priv->fifo_threshold);
194}
195
196static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
197 const char *buf, size_t count)
198{
199 struct net_device *dev = to_net_dev(cdev);
200 struct gfar_private *priv = netdev_priv(dev);
201 unsigned int length = simple_strtoul(buf, NULL, 0);
202 u32 temp;
203 unsigned long flags;
204
205 if (length > GFAR_MAX_FIFO_THRESHOLD)
206 return count;
207
208 spin_lock_irqsave(&priv->lock, flags);
209
210 priv->fifo_threshold = length;
211
212 temp = gfar_read(&priv->regs->fifo_tx_thr);
213 temp &= ~FIFO_TX_THR_MASK;
214 temp |= length;
215 gfar_write(&priv->regs->fifo_tx_thr, temp);
216
217 spin_unlock_irqrestore(&priv->lock, flags);
218
219 return count;
220}
221
222static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
223{
224 struct net_device *dev = to_net_dev(cdev);
225 struct gfar_private *priv = netdev_priv(dev);
226
227 return sprintf(buf, "%d\n", priv->fifo_starve);
228}
229
230
231static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
232 const char *buf, size_t count)
233{
234 struct net_device *dev = to_net_dev(cdev);
235 struct gfar_private *priv = netdev_priv(dev);
236 unsigned int num = simple_strtoul(buf, NULL, 0);
237 u32 temp;
238 unsigned long flags;
239
240 if (num > GFAR_MAX_FIFO_STARVE)
241 return count;
242
243 spin_lock_irqsave(&priv->lock, flags);
244
245 priv->fifo_starve = num;
246
247 temp = gfar_read(&priv->regs->fifo_tx_starve);
248 temp &= ~FIFO_TX_STARVE_MASK;
249 temp |= num;
250 gfar_write(&priv->regs->fifo_tx_starve, temp);
251
252 spin_unlock_irqrestore(&priv->lock, flags);
253
254 return count;
255}
256
257static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
258{
259 struct net_device *dev = to_net_dev(cdev);
260 struct gfar_private *priv = netdev_priv(dev);
261
262 return sprintf(buf, "%d\n", priv->fifo_starve_off);
263}
264
265static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
266 const char *buf, size_t count)
267{
268 struct net_device *dev = to_net_dev(cdev);
269 struct gfar_private *priv = netdev_priv(dev);
270 unsigned int num = simple_strtoul(buf, NULL, 0);
271 u32 temp;
272 unsigned long flags;
273
274 if (num > GFAR_MAX_FIFO_STARVE_OFF)
275 return count;
276
277 spin_lock_irqsave(&priv->lock, flags);
278
279 priv->fifo_starve_off = num;
280
281 temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
282 temp &= ~FIFO_TX_STARVE_OFF_MASK;
283 temp |= num;
284 gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
285
286 spin_unlock_irqrestore(&priv->lock, flags);
287
288 return count;
289}
290
291void gfar_init_sysfs(struct net_device *dev)
292{
293 struct gfar_private *priv = netdev_priv(dev);
294
295 /* Initialize the default values */
296 priv->rx_stash_size = DEFAULT_STASH_LENGTH;
297 priv->rx_stash_index = DEFAULT_STASH_INDEX;
298 priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
299 priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
300 priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
301 priv->bd_stash_en = DEFAULT_BD_STASH;
302
303 /* Create our sysfs files */
304 GFAR_CREATE_FILE(dev, bd_stash);
305 GFAR_CREATE_FILE(dev, rx_stash_size);
306 GFAR_CREATE_FILE(dev, rx_stash_index);
307 GFAR_CREATE_FILE(dev, fifo_threshold);
308 GFAR_CREATE_FILE(dev, fifo_starve);
309 GFAR_CREATE_FILE(dev, fifo_starve_off);
310
311}