diff options
Diffstat (limited to 'drivers/net/fs_enet/mac-fcc.c')
-rw-r--r-- | drivers/net/fs_enet/mac-fcc.c | 89 |
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 | ||
77 | static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) | 81 | static 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 | ||
102 | static int do_pd_setup(struct fs_enet_private *fep) | 98 | static 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 | |||
130 | out_fcccp: | ||
131 | iounmap(fep->fcc.fcccp); | ||
132 | out_ep: | ||
133 | iounmap(fep->fcc.ep); | ||
134 | out_fccp: | ||
135 | iounmap(fep->fcc.fccp); | ||
136 | out: | ||
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) | |||
148 | static int setup_data(struct net_device *dev) | 184 | static 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 | ||
232 | static void set_multicast_finish(struct net_device *dev) | 274 | static 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 | ||
532 | int get_regs_len(struct net_device *dev) | 573 | int 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 | /*************************************************************************/ |