aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fs_enet/mac-fcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fs_enet/mac-fcc.c')
-rw-r--r--drivers/net/fs_enet/mac-fcc.c89
1 files changed, 65 insertions, 24 deletions
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index e990f728d51b..6094cbf542a2 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -42,6 +42,10 @@
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44 44
45#ifdef CONFIG_PPC_CPM_NEW_BINDING
46#include <asm/of_device.h>
47#endif
48
45#include "fs_enet.h" 49#include "fs_enet.h"
46 50
47/*************************************************/ 51/*************************************************/
@@ -74,33 +78,64 @@
74 78
75#define MAX_CR_CMD_LOOPS 10000 79#define MAX_CR_CMD_LOOPS 10000
76 80
77static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) 81static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
78{ 82{
79 const struct fs_platform_info *fpi = fep->fpi; 83 const struct fs_platform_info *fpi = fep->fpi;
80 cpm2_map_t *immap = fs_enet_immap; 84 cpm2_map_t *immap = fs_enet_immap;
81 cpm_cpm2_t *cpmp = &immap->im_cpm; 85 cpm_cpm2_t *cpmp = &immap->im_cpm;
82 u32 v;
83 int i; 86 int i;
84 87
85 /* Currently I don't know what feature call will look like. But 88 W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
86 I guess there'd be something like do_cpm_cmd() which will require page & sblock */
87 v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
88 W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
89 for (i = 0; i < MAX_CR_CMD_LOOPS; i++) 89 for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
90 if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) 90 if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
91 break; 91 return 0;
92
93 if (i >= MAX_CR_CMD_LOOPS) {
94 printk(KERN_ERR "%s(): Not able to issue CPM command\n",
95 __FUNCTION__);
96 return 1;
97 }
98 92
99 return 0; 93 printk(KERN_ERR "%s(): Not able to issue CPM command\n",
94 __FUNCTION__);
95 return 1;
100} 96}
101 97
102static int do_pd_setup(struct fs_enet_private *fep) 98static int do_pd_setup(struct fs_enet_private *fep)
103{ 99{
100#ifdef CONFIG_PPC_CPM_NEW_BINDING
101 struct of_device *ofdev = to_of_device(fep->dev);
102 struct fs_platform_info *fpi = fep->fpi;
103 int ret = -EINVAL;
104
105 fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
106 if (fep->interrupt == NO_IRQ)
107 goto out;
108
109 fep->fcc.fccp = of_iomap(ofdev->node, 0);
110 if (!fep->fcc.fccp)
111 goto out;
112
113 fep->fcc.ep = of_iomap(ofdev->node, 1);
114 if (!fep->fcc.ep)
115 goto out_fccp;
116
117 fep->fcc.fcccp = of_iomap(ofdev->node, 2);
118 if (!fep->fcc.fcccp)
119 goto out_ep;
120
121 fep->fcc.mem = (void *)cpm_dpalloc(128, 8);
122 fpi->dpram_offset = (u32)cpm2_immr;
123 if (IS_ERR_VALUE(fpi->dpram_offset)) {
124 ret = fpi->dpram_offset;
125 goto out_fcccp;
126 }
127
128 return 0;
129
130out_fcccp:
131 iounmap(fep->fcc.fcccp);
132out_ep:
133 iounmap(fep->fcc.ep);
134out_fccp:
135 iounmap(fep->fcc.fccp);
136out:
137 return ret;
138#else
104 struct platform_device *pdev = to_platform_device(fep->dev); 139 struct platform_device *pdev = to_platform_device(fep->dev);
105 struct resource *r; 140 struct resource *r;
106 141
@@ -138,6 +173,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
138 return -EINVAL; 173 return -EINVAL;
139 174
140 return 0; 175 return 0;
176#endif
141} 177}
142 178
143#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) 179#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
@@ -148,11 +184,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
148static int setup_data(struct net_device *dev) 184static int setup_data(struct net_device *dev)
149{ 185{
150 struct fs_enet_private *fep = netdev_priv(dev); 186 struct fs_enet_private *fep = netdev_priv(dev);
151 const struct fs_platform_info *fpi = fep->fpi; 187#ifndef CONFIG_PPC_CPM_NEW_BINDING
188 struct fs_platform_info *fpi = fep->fpi;
189
190 fpi->cp_command = (fpi->cp_page << 26) |
191 (fpi->cp_block << 21) |
192 (12 << 6);
152 193
153 fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); 194 fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
154 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ 195 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
155 return -EINVAL; 196 return -EINVAL;
197#endif
156 198
157 if (do_pd_setup(fep) != 0) 199 if (do_pd_setup(fep) != 0)
158 return -EINVAL; 200 return -EINVAL;
@@ -226,7 +268,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
226 W16(ep, fen_taddrh, taddrh); 268 W16(ep, fen_taddrh, taddrh);
227 W16(ep, fen_taddrm, taddrm); 269 W16(ep, fen_taddrm, taddrm);
228 W16(ep, fen_taddrl, taddrl); 270 W16(ep, fen_taddrl, taddrl);
229 fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); 271 fcc_cr_cmd(fep, CPM_CR_SET_GADDR);
230} 272}
231 273
232static void set_multicast_finish(struct net_device *dev) 274static void set_multicast_finish(struct net_device *dev)
@@ -281,7 +323,7 @@ static void restart(struct net_device *dev)
281 323
282 /* clear everything (slow & steady does it) */ 324 /* clear everything (slow & steady does it) */
283 for (i = 0; i < sizeof(*ep); i++) 325 for (i = 0; i < sizeof(*ep); i++)
284 out_8((char *)ep + i, 0); 326 out_8((u8 __iomem *)ep + i, 0);
285 327
286 /* get physical address */ 328 /* get physical address */
287 rx_bd_base_phys = fep->ring_mem_addr; 329 rx_bd_base_phys = fep->ring_mem_addr;
@@ -397,7 +439,7 @@ static void restart(struct net_device *dev)
397 S8(fcccp, fcc_gfemr, 0x20); 439 S8(fcccp, fcc_gfemr, 0x20);
398 } 440 }
399 441
400 fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); 442 fcc_cr_cmd(fep, CPM_CR_INIT_TRX);
401 443
402 /* clear events */ 444 /* clear events */
403 W16(fccp, fcc_fcce, 0xffff); 445 W16(fccp, fcc_fcce, 0xffff);
@@ -515,23 +557,22 @@ int get_regs(struct net_device *dev, void *p, int *sizep)
515{ 557{
516 struct fs_enet_private *fep = netdev_priv(dev); 558 struct fs_enet_private *fep = netdev_priv(dev);
517 559
518 if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) 560 if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1)
519 return -EINVAL; 561 return -EINVAL;
520 562
521 memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); 563 memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
522 p = (char *)p + sizeof(fcc_t); 564 p = (char *)p + sizeof(fcc_t);
523 565
524 memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
525 p = (char *)p + sizeof(fcc_c_t);
526
527 memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); 566 memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
567 p = (char *)p + sizeof(fcc_enet_t);
528 568
569 memcpy_fromio(p, fep->fcc.fcccp, 1);
529 return 0; 570 return 0;
530} 571}
531 572
532int get_regs_len(struct net_device *dev) 573int get_regs_len(struct net_device *dev)
533{ 574{
534 return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); 575 return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1;
535} 576}
536 577
537/* Some transmit errors cause the transmitter to shut 578/* Some transmit errors cause the transmitter to shut
@@ -551,7 +592,7 @@ void tx_restart(struct net_device *dev)
551 udelay(10); 592 udelay(10);
552 S32(fccp, fcc_gfmr, FCC_GFMR_ENT); 593 S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
553 594
554 fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); 595 fcc_cr_cmd(fep, CPM_CR_RESTART_TX);
555} 596}
556 597
557/*************************************************************************/ 598/*************************************************************************/