diff options
Diffstat (limited to 'drivers/net/fs_enet/mac-scc.c')
-rw-r--r-- | drivers/net/fs_enet/mac-scc.c | 110 |
1 files changed, 66 insertions, 44 deletions
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 7540966687ec..03134f47a4eb 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -1,14 +1,14 @@ /* * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx. * - * Copyright (c) 2003 Intracom S.A. + * Copyright (c) 2003 Intracom S.A. * by Pantelis Antoniou <panto@intracom.gr> - * - * 2005 (c) MontaVista Software, Inc. + * + * 2005 (c) MontaVista Software, Inc. * Vitaly Bordug <vbordug@ru.mvista.com> * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ @@ -43,6 +43,10 @@ #include <asm/commproc.h> #endif +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include <asm/of_platform.h> +#endif + #include "fs_enet.h" /*************************************************/ @@ -82,34 +86,45 @@ #define SCC_MAX_MULTICAST_ADDRS 64 /* - * Delay to wait for SCC reset command to complete (in us) + * Delay to wait for SCC reset command to complete (in us) */ #define SCC_RESET_DELAY 50 #define MAX_CR_CMD_LOOPS 10000 static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) { - cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; - u32 v, ch; - int i = 0; + const struct fs_platform_info *fpi = fep->fpi; + int i; - ch = fep->scc.idx << 2; - v = mk_cr_cmd(ch, op); - W16(cpmp, cp_cpcr, v | CPM_CR_FLG); + W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8)); for (i = 0; i < MAX_CR_CMD_LOOPS; i++) if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) - break; + return 0; - if (i >= MAX_CR_CMD_LOOPS) { - printk(KERN_ERR "%s(): Not able to issue CPM command\n", - __FUNCTION__); - return 1; - } - return 0; + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; } static int do_pd_setup(struct fs_enet_private *fep) { +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct of_device *ofdev = to_of_device(fep->dev); + + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + if (fep->interrupt == NO_IRQ) + return -EINVAL; + + fep->scc.sccp = of_iomap(ofdev->node, 0); + if (!fep->scc.sccp) + return -EINVAL; + + fep->scc.ep = of_iomap(ofdev->node, 1); + if (!fep->scc.ep) { + iounmap(fep->scc.sccp); + return -EINVAL; + } +#else struct platform_device *pdev = to_platform_device(fep->dev); struct resource *r; @@ -129,6 +144,7 @@ static int do_pd_setup(struct fs_enet_private *fep) if (fep->scc.ep == NULL) return -EINVAL; +#endif return 0; } @@ -141,12 +157,17 @@ static int do_pd_setup(struct fs_enet_private *fep) static int setup_data(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - const struct fs_platform_info *fpi = fep->fpi; + +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct fs_platform_info *fpi = fep->fpi; fep->scc.idx = fs_get_scc_index(fpi->fs_no); - if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ + if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */ return -EINVAL; + fpi->cp_command = fep->fcc.idx << 6; +#endif + do_pd_setup(fep); fep->scc.hthi = 0; @@ -154,7 +175,7 @@ static int setup_data(struct net_device *dev) fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; fep->ev_rx = SCC_RX_EVENT; - fep->ev_tx = SCC_TX_EVENT; + fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE; fep->ev_err = SCC_ERR_EVENT_MSK; return 0; @@ -170,7 +191,8 @@ static int allocate_bd(struct net_device *dev) if (IS_ERR_VALUE(fep->ring_mem_addr)) return -ENOMEM; - fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr); + fep->ring_base = (void __iomem __force*) + cpm_dpram_addr(fep->ring_mem_addr); return 0; } @@ -189,9 +211,9 @@ static void cleanup_data(struct net_device *dev) } static void set_promiscuous_mode(struct net_device *dev) -{ +{ struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; S16(sccp, scc_psmr, SCC_PSMR_PRO); } @@ -199,7 +221,7 @@ static void set_promiscuous_mode(struct net_device *dev) static void set_multicast_start(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_enet_t *ep = fep->scc.ep; + scc_enet_t __iomem *ep = fep->scc.ep; W16(ep, sen_gaddr1, 0); W16(ep, sen_gaddr2, 0); @@ -210,7 +232,7 @@ static void set_multicast_start(struct net_device *dev) static void set_multicast_one(struct net_device *dev, const u8 * mac) { struct fs_enet_private *fep = netdev_priv(dev); - scc_enet_t *ep = fep->scc.ep; + scc_enet_t __iomem *ep = fep->scc.ep; u16 taddrh, taddrm, taddrl; taddrh = ((u16) mac[5] << 8) | mac[4]; @@ -226,8 +248,8 @@ static void set_multicast_one(struct net_device *dev, const u8 * mac) static void set_multicast_finish(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; - scc_enet_t *ep = fep->scc.ep; + scc_t __iomem *sccp = fep->scc.sccp; + scc_enet_t __iomem *ep = fep->scc.ep; /* clear promiscuous always */ C16(sccp, scc_psmr, SCC_PSMR_PRO); @@ -264,8 +286,8 @@ static void set_multicast_list(struct net_device *dev) static void restart(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; - scc_enet_t *ep = fep->scc.ep; + scc_t __iomem *sccp = fep->scc.sccp; + scc_enet_t __iomem *ep = fep->scc.ep; const struct fs_platform_info *fpi = fep->fpi; u16 paddrh, paddrm, paddrl; const unsigned char *mac; @@ -275,7 +297,7 @@ static void restart(struct net_device *dev) /* clear everything (slow & steady does it) */ for (i = 0; i < sizeof(*ep); i++) - __fs_out8((char *)ep + i, 0); + __fs_out8((u8 __iomem *)ep + i, 0); /* point to bds */ W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr); @@ -323,7 +345,7 @@ static void restart(struct net_device *dev) W16(ep, sen_iaddr3, 0); W16(ep, sen_iaddr4, 0); - /* set address + /* set address */ mac = dev->dev_addr; paddrh = ((u16) mac[5] << 8) | mac[4]; @@ -345,7 +367,7 @@ static void restart(struct net_device *dev) W16(sccp, scc_scce, 0xffff); - /* Enable interrupts we wish to service. + /* Enable interrupts we wish to service. */ W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); @@ -373,10 +395,10 @@ static void restart(struct net_device *dev) S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } -static void stop(struct net_device *dev) +static void stop(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; int i; for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++) @@ -420,7 +442,7 @@ static void post_free_irq(struct net_device *dev, int irq) static void napi_clear_rx_event(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK); } @@ -428,7 +450,7 @@ static void napi_clear_rx_event(struct net_device *dev) static void napi_enable_rx(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); } @@ -436,7 +458,7 @@ static void napi_enable_rx(struct net_device *dev) static void napi_disable_rx(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); } @@ -454,7 +476,7 @@ static void tx_kickstart(struct net_device *dev) static u32 get_int_events(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; return (u32) R16(sccp, scc_scce); } @@ -462,7 +484,7 @@ static u32 get_int_events(struct net_device *dev) static void clear_int_events(struct net_device *dev, u32 int_events) { struct fs_enet_private *fep = netdev_priv(dev); - scc_t *sccp = fep->scc.sccp; + scc_t __iomem *sccp = fep->scc.sccp; W16(sccp, scc_scce, int_events & 0xffff); } @@ -477,20 +499,20 @@ static int get_regs(struct net_device *dev, void *p, int *sizep) { struct fs_enet_private *fep = netdev_priv(dev); - if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t)) + if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t __iomem *)) return -EINVAL; memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t)); p = (char *)p + sizeof(scc_t); - memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t)); + memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t __iomem *)); return 0; } static int get_regs_len(struct net_device *dev) { - return sizeof(scc_t) + sizeof(scc_enet_t); + return sizeof(scc_t) + sizeof(scc_enet_t __iomem *); } static void tx_restart(struct net_device *dev) |