diff options
| -rw-r--r-- | arch/microblaze/include/asm/system.h | 11 | ||||
| -rw-r--r-- | drivers/net/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/net/ll_temac.h | 14 | ||||
| -rw-r--r-- | drivers/net/ll_temac_main.c | 137 | 
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 | ||
| 2436 | config XILINX_LL_TEMAC | 2436 | config 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 | */ | ||
| 118 | static u32 temac_dma_in32(struct temac_local *lp, int reg) | 120 | static 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 | */ | ||
| 123 | static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) | 130 | static 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 | */ | ||
| 144 | static 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 | */ | ||
| 152 | static 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 | */ | ||
| 161 | static 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 | */ | ||
| 186 | static 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 | */ | 
| 131 | static int temac_dma_bd_init(struct net_device *ndev) | 197 | static 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); | 
