aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/networking/gianfar.txt72
-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
7 files changed, 579 insertions, 112 deletions
diff --git a/Documentation/networking/gianfar.txt b/Documentation/networking/gianfar.txt
new file mode 100644
index 000000000000..ad474ea07d07
--- /dev/null
+++ b/Documentation/networking/gianfar.txt
@@ -0,0 +1,72 @@
1The Gianfar Ethernet Driver
2Sysfs File description
3
4Author: Andy Fleming <afleming@freescale.com>
5Updated: 2005-07-28
6
7SYSFS
8
9Several of the features of the gianfar driver are controlled
10through sysfs files. These are:
11
12bd_stash:
13To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
14bd_stash, echo 'off' or '0' to disable
15
16rx_stash_len:
17To stash the first n bytes of the packet in L2, echo the number
18of bytes to buf_stash_len. echo 0 to disable.
19
20WARNING: You could really screw these up if you set them too low or high!
21fifo_threshold:
22To change the number of bytes the controller needs in the
23fifo before it starts transmission, echo the number of bytes to
24fifo_thresh. Range should be 0-511.
25
26fifo_starve:
27When the FIFO has less than this many bytes during a transmit, it
28enters starve mode, and increases the priority of TX memory
29transactions. To change, echo the number of bytes to
30fifo_starve. Range should be 0-511.
31
32fifo_starve_off:
33Once in starve mode, the FIFO remains there until it has this
34many bytes. To change, echo the number of bytes to
35fifo_starve_off. Range should be 0-511.
36
37CHECKSUM OFFLOADING
38
39The eTSEC controller (first included in parts from late 2005 like
40the 8548) has the ability to perform TCP, UDP, and IP checksums
41in hardware. The Linux kernel only offloads the TCP and UDP
42checksums (and always performs the pseudo header checksums), so
43the driver only supports checksumming for TCP/IP and UDP/IP
44packets. Use ethtool to enable or disable this feature for RX
45and TX.
46
47VLAN
48
49In order to use VLAN, please consult Linux documentation on
50configuring VLANs. The gianfar driver supports hardware insertion and
51extraction of VLAN headers, but not filtering. Filtering will be
52done by the kernel.
53
54MULTICASTING
55
56The gianfar driver supports using the group hash table on the
57TSEC (and the extended hash table on the eTSEC) for multicast
58filtering. On the eTSEC, the exact-match MAC registers are used
59before the hash tables. See Linux documentation on how to join
60multicast groups.
61
62PADDING
63
64The gianfar driver supports padding received frames with 2 bytes
65to align the IP header to a 16-byte boundary, when supported by
66hardware.
67
68ETHTOOL
69
70The gianfar driver supports the use of ethtool for many
71configuration options. You must run ethtool only on currently
72open interfaces. See ethtool documentation for details.
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}