aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/microblaze/include/asm/system.h11
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/ll_temac.h14
-rw-r--r--drivers/net/ll_temac_main.c137
4 files changed, 126 insertions, 38 deletions
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
index 157970688b2a..88fc92cdd8ce 100644
--- a/arch/microblaze/include/asm/system.h
+++ b/arch/microblaze/include/asm/system.h
@@ -12,6 +12,7 @@
12#include <asm/registers.h> 12#include <asm/registers.h>
13#include <asm/setup.h> 13#include <asm/setup.h>
14#include <asm/irqflags.h> 14#include <asm/irqflags.h>
15#include <asm/cache.h>
15 16
16#include <asm-generic/cmpxchg.h> 17#include <asm-generic/cmpxchg.h>
17#include <asm-generic/cmpxchg-local.h> 18#include <asm-generic/cmpxchg-local.h>
@@ -93,4 +94,14 @@ extern struct dentry *of_debugfs_root;
93 94
94#define arch_align_stack(x) (x) 95#define arch_align_stack(x) (x)
95 96
97/*
98 * MicroBlaze doesn't handle unaligned accesses in hardware.
99 *
100 * Based on this we force the IP header alignment in network drivers.
101 * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
102 * cacheline alignment of buffers.
103 */
104#define NET_IP_ALIGN 2
105#define NET_SKB_PAD L1_CACHE_BYTES
106
96#endif /* _ASM_MICROBLAZE_SYSTEM_H */ 107#endif /* _ASM_MICROBLAZE_SYSTEM_H */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a55bff26a264..20e2dec1d534 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2435,8 +2435,8 @@ config MV643XX_ETH
2435 2435
2436config XILINX_LL_TEMAC 2436config XILINX_LL_TEMAC
2437 tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" 2437 tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
2438 depends on PPC || MICROBLAZE
2438 select PHYLIB 2439 select PHYLIB
2439 depends on PPC_DCR_NATIVE
2440 help 2440 help
2441 This driver supports the Xilinx 10/100/1000 LocalLink TEMAC 2441 This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
2442 core used in Xilinx Spartan and Virtex FPGAs 2442 core used in Xilinx Spartan and Virtex FPGAs
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
index 1af66a1e6911..c03358434acb 100644
--- a/drivers/net/ll_temac.h
+++ b/drivers/net/ll_temac.h
@@ -5,8 +5,11 @@
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/of.h> 6#include <linux/of.h>
7#include <linux/spinlock.h> 7#include <linux/spinlock.h>
8
9#ifdef CONFIG_PPC_DCR
8#include <asm/dcr.h> 10#include <asm/dcr.h>
9#include <asm/dcr-regs.h> 11#include <asm/dcr-regs.h>
12#endif
10 13
11/* packet size info */ 14/* packet size info */
12#define XTE_HDR_SIZE 14 /* size of Ethernet header */ 15#define XTE_HDR_SIZE 14 /* size of Ethernet header */
@@ -290,9 +293,6 @@ This option defaults to enabled (set) */
290 293
291#define TX_CONTROL_CALC_CSUM_MASK 1 294#define TX_CONTROL_CALC_CSUM_MASK 1
292 295
293#define XTE_ALIGN 32
294#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
295
296#define MULTICAST_CAM_TABLE_NUM 4 296#define MULTICAST_CAM_TABLE_NUM 4
297 297
298/* TX/RX CURDESC_PTR points to first descriptor */ 298/* TX/RX CURDESC_PTR points to first descriptor */
@@ -335,9 +335,15 @@ struct temac_local {
335 struct mii_bus *mii_bus; /* MII bus reference */ 335 struct mii_bus *mii_bus; /* MII bus reference */
336 int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ 336 int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */
337 337
338 /* IO registers and IRQs */ 338 /* IO registers, dma functions and IRQs */
339 void __iomem *regs; 339 void __iomem *regs;
340 void __iomem *sdma_regs;
341#ifdef CONFIG_PPC_DCR
340 dcr_host_t sdma_dcrs; 342 dcr_host_t sdma_dcrs;
343#endif
344 u32 (*dma_in)(struct temac_local *, int);
345 void (*dma_out)(struct temac_local *, int, u32);
346
341 int tx_irq; 347 int tx_irq;
342 int rx_irq; 348 int rx_irq;
343 int emac_num; 349 int emac_num;
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index 30474d6b15c3..b6edb2fd0a8a 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -20,9 +20,6 @@
20 * or rx, so this should be okay. 20 * or rx, so this should be okay.
21 * 21 *
22 * TODO: 22 * TODO:
23 * - Fix driver to work on more than just Virtex5. Right now the driver
24 * assumes that the locallink DMA registers are accessed via DCR
25 * instructions.
26 * - Factor out locallink DMA code into separate driver 23 * - Factor out locallink DMA code into separate driver
27 * - Fix multicast assignment. 24 * - Fix multicast assignment.
28 * - Fix support for hardware checksumming. 25 * - Fix support for hardware checksumming.
@@ -115,17 +112,86 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
115 temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); 112 temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
116} 113}
117 114
115/**
116 * temac_dma_in32 - Memory mapped DMA read, this function expects a
117 * register input that is based on DCR word addresses which
118 * are then converted to memory mapped byte addresses
119 */
118static u32 temac_dma_in32(struct temac_local *lp, int reg) 120static u32 temac_dma_in32(struct temac_local *lp, int reg)
119{ 121{
120 return dcr_read(lp->sdma_dcrs, reg); 122 return in_be32((u32 *)(lp->sdma_regs + (reg << 2)));
121} 123}
122 124
125/**
126 * temac_dma_out32 - Memory mapped DMA read, this function expects a
127 * register input that is based on DCR word addresses which
128 * are then converted to memory mapped byte addresses
129 */
123static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) 130static void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
124{ 131{
132 out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value);
133}
134
135/* DMA register access functions can be DCR based or memory mapped.
136 * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both
137 * memory mapped.
138 */
139#ifdef CONFIG_PPC_DCR
140
141/**
142 * temac_dma_dcr_in32 - DCR based DMA read
143 */
144static u32 temac_dma_dcr_in(struct temac_local *lp, int reg)
145{
146 return dcr_read(lp->sdma_dcrs, reg);
147}
148
149/**
150 * temac_dma_dcr_out32 - DCR based DMA write
151 */
152static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value)
153{
125 dcr_write(lp->sdma_dcrs, reg, value); 154 dcr_write(lp->sdma_dcrs, reg, value);
126} 155}
127 156
128/** 157/**
158 * temac_dcr_setup - If the DMA is DCR based, then setup the address and
159 * I/O functions
160 */
161static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
162 struct device_node *np)
163{
164 unsigned int dcrs;
165
166 /* setup the dcr address mapping if it's in the device tree */
167
168 dcrs = dcr_resource_start(np, 0);
169 if (dcrs != 0) {
170 lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
171 lp->dma_in = temac_dma_dcr_in;
172 lp->dma_out = temac_dma_dcr_out;
173 dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
174 return 0;
175 }
176 /* no DCR in the device tree, indicate a failure */
177 return -1;
178}
179
180#else
181
182/*
183 * temac_dcr_setup - This is a stub for when DCR is not supported,
184 * such as with MicroBlaze
185 */
186static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
187 struct device_node *np)
188{
189 return -1;
190}
191
192#endif
193
194/**
129 * temac_dma_bd_init - Setup buffer descriptor rings 195 * temac_dma_bd_init - Setup buffer descriptor rings
130 */ 196 */
131static int temac_dma_bd_init(struct net_device *ndev) 197static int temac_dma_bd_init(struct net_device *ndev)
@@ -155,14 +221,14 @@ static int temac_dma_bd_init(struct net_device *ndev)
155 lp->rx_bd_v[i].next = lp->rx_bd_p + 221 lp->rx_bd_v[i].next = lp->rx_bd_p +
156 sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); 222 sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
157 223
158 skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE 224 skb = netdev_alloc_skb_ip_align(ndev,
159 + XTE_ALIGN, GFP_ATOMIC); 225 XTE_MAX_JUMBO_FRAME_SIZE);
226
160 if (skb == 0) { 227 if (skb == 0) {
161 dev_err(&ndev->dev, "alloc_skb error %d\n", i); 228 dev_err(&ndev->dev, "alloc_skb error %d\n", i);
162 return -1; 229 return -1;
163 } 230 }
164 lp->rx_skb[i] = skb; 231 lp->rx_skb[i] = skb;
165 skb_reserve(skb, BUFFER_ALIGN(skb->data));
166 /* returns physical address of skb->data */ 232 /* returns physical address of skb->data */
167 lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, 233 lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
168 skb->data, 234 skb->data,
@@ -172,23 +238,23 @@ static int temac_dma_bd_init(struct net_device *ndev)
172 lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; 238 lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
173 } 239 }
174 240
175 temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 | 241 lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
176 CHNL_CTRL_IRQ_EN | 242 CHNL_CTRL_IRQ_EN |
177 CHNL_CTRL_IRQ_DLY_EN | 243 CHNL_CTRL_IRQ_DLY_EN |
178 CHNL_CTRL_IRQ_COAL_EN); 244 CHNL_CTRL_IRQ_COAL_EN);
179 /* 0x10220483 */ 245 /* 0x10220483 */
180 /* 0x00100483 */ 246 /* 0x00100483 */
181 temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 | 247 lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 |
182 CHNL_CTRL_IRQ_EN | 248 CHNL_CTRL_IRQ_EN |
183 CHNL_CTRL_IRQ_DLY_EN | 249 CHNL_CTRL_IRQ_DLY_EN |
184 CHNL_CTRL_IRQ_COAL_EN | 250 CHNL_CTRL_IRQ_COAL_EN |
185 CHNL_CTRL_IRQ_IOE); 251 CHNL_CTRL_IRQ_IOE);
186 /* 0xff010283 */ 252 /* 0xff010283 */
187 253
188 temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p); 254 lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p);
189 temac_dma_out32(lp, RX_TAILDESC_PTR, 255 lp->dma_out(lp, RX_TAILDESC_PTR,
190 lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); 256 lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
191 temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p); 257 lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p);
192 258
193 return 0; 259 return 0;
194} 260}
@@ -426,9 +492,9 @@ static void temac_device_reset(struct net_device *ndev)
426 temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); 492 temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
427 493
428 /* Reset Local Link (DMA) */ 494 /* Reset Local Link (DMA) */
429 temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); 495 lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
430 timeout = 1000; 496 timeout = 1000;
431 while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { 497 while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
432 udelay(1); 498 udelay(1);
433 if (--timeout == 0) { 499 if (--timeout == 0) {
434 dev_err(&ndev->dev, 500 dev_err(&ndev->dev,
@@ -436,7 +502,7 @@ static void temac_device_reset(struct net_device *ndev)
436 break; 502 break;
437 } 503 }
438 } 504 }
439 temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); 505 lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
440 506
441 temac_dma_bd_init(ndev); 507 temac_dma_bd_init(ndev);
442 508
@@ -597,7 +663,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
597 lp->tx_bd_tail = 0; 663 lp->tx_bd_tail = 0;
598 664
599 /* Kick off the transfer */ 665 /* Kick off the transfer */
600 temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ 666 lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
601 667
602 return NETDEV_TX_OK; 668 return NETDEV_TX_OK;
603} 669}
@@ -639,16 +705,15 @@ static void ll_temac_recv(struct net_device *ndev)
639 ndev->stats.rx_packets++; 705 ndev->stats.rx_packets++;
640 ndev->stats.rx_bytes += length; 706 ndev->stats.rx_bytes += length;
641 707
642 new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN, 708 new_skb = netdev_alloc_skb_ip_align(ndev,
643 GFP_ATOMIC); 709 XTE_MAX_JUMBO_FRAME_SIZE);
710
644 if (new_skb == 0) { 711 if (new_skb == 0) {
645 dev_err(&ndev->dev, "no memory for new sk_buff\n"); 712 dev_err(&ndev->dev, "no memory for new sk_buff\n");
646 spin_unlock_irqrestore(&lp->rx_lock, flags); 713 spin_unlock_irqrestore(&lp->rx_lock, flags);
647 return; 714 return;
648 } 715 }
649 716
650 skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
651
652 cur_p->app0 = STS_CTRL_APP0_IRQONEND; 717 cur_p->app0 = STS_CTRL_APP0_IRQONEND;
653 cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, 718 cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
654 XTE_MAX_JUMBO_FRAME_SIZE, 719 XTE_MAX_JUMBO_FRAME_SIZE,
@@ -663,7 +728,7 @@ static void ll_temac_recv(struct net_device *ndev)
663 cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; 728 cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
664 bdstat = cur_p->app0; 729 bdstat = cur_p->app0;
665 } 730 }
666 temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p); 731 lp->dma_out(lp, RX_TAILDESC_PTR, tail_p);
667 732
668 spin_unlock_irqrestore(&lp->rx_lock, flags); 733 spin_unlock_irqrestore(&lp->rx_lock, flags);
669} 734}
@@ -674,8 +739,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
674 struct temac_local *lp = netdev_priv(ndev); 739 struct temac_local *lp = netdev_priv(ndev);
675 unsigned int status; 740 unsigned int status;
676 741
677 status = temac_dma_in32(lp, TX_IRQ_REG); 742 status = lp->dma_in(lp, TX_IRQ_REG);
678 temac_dma_out32(lp, TX_IRQ_REG, status); 743 lp->dma_out(lp, TX_IRQ_REG, status);
679 744
680 if (status & (IRQ_COAL | IRQ_DLY)) 745 if (status & (IRQ_COAL | IRQ_DLY))
681 temac_start_xmit_done(lp->ndev); 746 temac_start_xmit_done(lp->ndev);
@@ -692,8 +757,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
692 unsigned int status; 757 unsigned int status;
693 758
694 /* Read and clear the status registers */ 759 /* Read and clear the status registers */
695 status = temac_dma_in32(lp, RX_IRQ_REG); 760 status = lp->dma_in(lp, RX_IRQ_REG);
696 temac_dma_out32(lp, RX_IRQ_REG, status); 761 lp->dma_out(lp, RX_IRQ_REG, status);
697 762
698 if (status & (IRQ_COAL | IRQ_DLY)) 763 if (status & (IRQ_COAL | IRQ_DLY))
699 ll_temac_recv(lp->ndev); 764 ll_temac_recv(lp->ndev);
@@ -794,7 +859,7 @@ static ssize_t temac_show_llink_regs(struct device *dev,
794 int i, len = 0; 859 int i, len = 0;
795 860
796 for (i = 0; i < 0x11; i++) 861 for (i = 0; i < 0x11; i++)
797 len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i), 862 len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i),
798 (i % 8) == 7 ? "\n" : " "); 863 (i % 8) == 7 ? "\n" : " ");
799 len += sprintf(buf + len, "\n"); 864 len += sprintf(buf + len, "\n");
800 865
@@ -820,7 +885,6 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
820 struct net_device *ndev; 885 struct net_device *ndev;
821 const void *addr; 886 const void *addr;
822 int size, rc = 0; 887 int size, rc = 0;
823 unsigned int dcrs;
824 888
825 /* Init network device structure */ 889 /* Init network device structure */
826 ndev = alloc_etherdev(sizeof(*lp)); 890 ndev = alloc_etherdev(sizeof(*lp));
@@ -870,13 +934,20 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
870 goto nodev; 934 goto nodev;
871 } 935 }
872 936
873 dcrs = dcr_resource_start(np, 0); 937 /* Setup the DMA register accesses, could be DCR or memory mapped */
874 if (dcrs == 0) { 938 if (temac_dcr_setup(lp, op, np)) {
875 dev_err(&op->dev, "could not get DMA register address\n"); 939
876 goto nodev; 940 /* no DCR in the device tree, try non-DCR */
941 lp->sdma_regs = of_iomap(np, 0);
942 if (lp->sdma_regs) {
943 lp->dma_in = temac_dma_in32;
944 lp->dma_out = temac_dma_out32;
945 dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs);
946 } else {
947 dev_err(&op->dev, "unable to map DMA registers\n");
948 goto nodev;
949 }
877 } 950 }
878 lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
879 dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
880 951
881 lp->rx_irq = irq_of_parse_and_map(np, 0); 952 lp->rx_irq = irq_of_parse_and_map(np, 0);
882 lp->tx_irq = irq_of_parse_and_map(np, 1); 953 lp->tx_irq = irq_of_parse_and_map(np, 1);