~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/bcm63xx/dev-enet.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
  7  */
  8 
  9 #include <linux/init.h>
 10 #include <linux/kernel.h>
 11 #include <linux/platform_device.h>
 12 #include <linux/export.h>
 13 #include <bcm63xx_dev_enet.h>
 14 #include <bcm63xx_io.h>
 15 #include <bcm63xx_regs.h>
 16 
 17 static const unsigned long bcm6348_regs_enetdmac[] = {
 18         [ENETDMAC_CHANCFG]      = ENETDMAC_CHANCFG_REG,
 19         [ENETDMAC_IR]           = ENETDMAC_IR_REG,
 20         [ENETDMAC_IRMASK]       = ENETDMAC_IRMASK_REG,
 21         [ENETDMAC_MAXBURST]     = ENETDMAC_MAXBURST_REG,
 22 };
 23 
 24 static const unsigned long bcm6345_regs_enetdmac[] = {
 25         [ENETDMAC_CHANCFG]      = ENETDMA_6345_CHANCFG_REG,
 26         [ENETDMAC_IR]           = ENETDMA_6345_IR_REG,
 27         [ENETDMAC_IRMASK]       = ENETDMA_6345_IRMASK_REG,
 28         [ENETDMAC_MAXBURST]     = ENETDMA_6345_MAXBURST_REG,
 29         [ENETDMAC_BUFALLOC]     = ENETDMA_6345_BUFALLOC_REG,
 30         [ENETDMAC_RSTART]       = ENETDMA_6345_RSTART_REG,
 31         [ENETDMAC_FC]           = ENETDMA_6345_FC_REG,
 32         [ENETDMAC_LEN]          = ENETDMA_6345_LEN_REG,
 33 };
 34 
 35 const unsigned long *bcm63xx_regs_enetdmac;
 36 EXPORT_SYMBOL(bcm63xx_regs_enetdmac);
 37 
 38 static __init void bcm63xx_enetdmac_regs_init(void)
 39 {
 40         if (BCMCPU_IS_6345())
 41                 bcm63xx_regs_enetdmac = bcm6345_regs_enetdmac;
 42         else
 43                 bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac;
 44 }
 45 
 46 static struct resource shared_res[] = {
 47         {
 48                 .start          = -1, /* filled at runtime */
 49                 .end            = -1, /* filled at runtime */
 50                 .flags          = IORESOURCE_MEM,
 51         },
 52         {
 53                 .start          = -1, /* filled at runtime */
 54                 .end            = -1, /* filled at runtime */
 55                 .flags          = IORESOURCE_MEM,
 56         },
 57         {
 58                 .start          = -1, /* filled at runtime */
 59                 .end            = -1, /* filled at runtime */
 60                 .flags          = IORESOURCE_MEM,
 61         },
 62 };
 63 
 64 static struct platform_device bcm63xx_enet_shared_device = {
 65         .name           = "bcm63xx_enet_shared",
 66         .id             = 0,
 67         .num_resources  = ARRAY_SIZE(shared_res),
 68         .resource       = shared_res,
 69 };
 70 
 71 static int shared_device_registered;
 72 
 73 static u64 enet_dmamask = DMA_BIT_MASK(32);
 74 
 75 static struct resource enet0_res[] = {
 76         {
 77                 .start          = -1, /* filled at runtime */
 78                 .end            = -1, /* filled at runtime */
 79                 .flags          = IORESOURCE_MEM,
 80         },
 81         {
 82                 .start          = -1, /* filled at runtime */
 83                 .flags          = IORESOURCE_IRQ,
 84         },
 85         {
 86                 .start          = -1, /* filled at runtime */
 87                 .flags          = IORESOURCE_IRQ,
 88         },
 89         {
 90                 .start          = -1, /* filled at runtime */
 91                 .flags          = IORESOURCE_IRQ,
 92         },
 93 };
 94 
 95 static struct bcm63xx_enet_platform_data enet0_pd;
 96 
 97 static struct platform_device bcm63xx_enet0_device = {
 98         .name           = "bcm63xx_enet",
 99         .id             = 0,
100         .num_resources  = ARRAY_SIZE(enet0_res),
101         .resource       = enet0_res,
102         .dev            = {
103                 .platform_data = &enet0_pd,
104                 .dma_mask = &enet_dmamask,
105                 .coherent_dma_mask = DMA_BIT_MASK(32),
106         },
107 };
108 
109 static struct resource enet1_res[] = {
110         {
111                 .start          = -1, /* filled at runtime */
112                 .end            = -1, /* filled at runtime */
113                 .flags          = IORESOURCE_MEM,
114         },
115         {
116                 .start          = -1, /* filled at runtime */
117                 .flags          = IORESOURCE_IRQ,
118         },
119         {
120                 .start          = -1, /* filled at runtime */
121                 .flags          = IORESOURCE_IRQ,
122         },
123         {
124                 .start          = -1, /* filled at runtime */
125                 .flags          = IORESOURCE_IRQ,
126         },
127 };
128 
129 static struct bcm63xx_enet_platform_data enet1_pd;
130 
131 static struct platform_device bcm63xx_enet1_device = {
132         .name           = "bcm63xx_enet",
133         .id             = 1,
134         .num_resources  = ARRAY_SIZE(enet1_res),
135         .resource       = enet1_res,
136         .dev            = {
137                 .platform_data = &enet1_pd,
138                 .dma_mask = &enet_dmamask,
139                 .coherent_dma_mask = DMA_BIT_MASK(32),
140         },
141 };
142 
143 static struct resource enetsw_res[] = {
144         {
145                 /* start & end filled at runtime */
146                 .flags          = IORESOURCE_MEM,
147         },
148         {
149                 /* start filled at runtime */
150                 .flags          = IORESOURCE_IRQ,
151         },
152         {
153                 /* start filled at runtime */
154                 .flags          = IORESOURCE_IRQ,
155         },
156 };
157 
158 static struct bcm63xx_enetsw_platform_data enetsw_pd;
159 
160 static struct platform_device bcm63xx_enetsw_device = {
161         .name           = "bcm63xx_enetsw",
162         .num_resources  = ARRAY_SIZE(enetsw_res),
163         .resource       = enetsw_res,
164         .dev            = {
165                 .platform_data = &enetsw_pd,
166                 .dma_mask = &enet_dmamask,
167                 .coherent_dma_mask = DMA_BIT_MASK(32),
168         },
169 };
170 
171 static int __init register_shared(void)
172 {
173         int ret, chan_count;
174 
175         if (shared_device_registered)
176                 return 0;
177 
178         bcm63xx_enetdmac_regs_init();
179 
180         shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
181         shared_res[0].end = shared_res[0].start;
182         if (BCMCPU_IS_6345())
183                 shared_res[0].end += (RSET_6345_ENETDMA_SIZE) - 1;
184         else
185                 shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
186 
187         if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368())
188                 chan_count = 32;
189         else if (BCMCPU_IS_6345())
190                 chan_count = 8;
191         else
192                 chan_count = 16;
193 
194         shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC);
195         shared_res[1].end = shared_res[1].start;
196         shared_res[1].end += RSET_ENETDMAC_SIZE(chan_count)  - 1;
197 
198         shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS);
199         shared_res[2].end = shared_res[2].start;
200         shared_res[2].end += RSET_ENETDMAS_SIZE(chan_count)  - 1;
201 
202         ret = platform_device_register(&bcm63xx_enet_shared_device);
203         if (ret)
204                 return ret;
205         shared_device_registered = 1;
206 
207         return 0;
208 }
209 
210 int __init bcm63xx_enet_register(int unit,
211                                  const struct bcm63xx_enet_platform_data *pd)
212 {
213         struct platform_device *pdev;
214         struct bcm63xx_enet_platform_data *dpd;
215         int ret;
216 
217         if (unit > 1)
218                 return -ENODEV;
219 
220         if (unit == 1 && (BCMCPU_IS_6338() || BCMCPU_IS_6345()))
221                 return -ENODEV;
222 
223         ret = register_shared();
224         if (ret)
225                 return ret;
226 
227         if (unit == 0) {
228                 enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
229                 enet0_res[0].end = enet0_res[0].start;
230                 enet0_res[0].end += RSET_ENET_SIZE - 1;
231                 enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
232                 enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
233                 enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
234                 pdev = &bcm63xx_enet0_device;
235         } else {
236                 enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
237                 enet1_res[0].end = enet1_res[0].start;
238                 enet1_res[0].end += RSET_ENET_SIZE - 1;
239                 enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
240                 enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
241                 enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
242                 pdev = &bcm63xx_enet1_device;
243         }
244 
245         /* copy given platform data */
246         dpd = pdev->dev.platform_data;
247         memcpy(dpd, pd, sizeof(*pd));
248 
249         /* adjust them in case internal phy is used */
250         if (dpd->use_internal_phy) {
251 
252                 /* internal phy only exists for enet0 */
253                 if (unit == 1)
254                         return -ENODEV;
255 
256                 dpd->phy_id = 1;
257                 dpd->has_phy_interrupt = 1;
258                 dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
259         }
260 
261         dpd->dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
262         dpd->dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
263         if (BCMCPU_IS_6345()) {
264                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_CHAINING_MASK;
265                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_WRAP_EN_MASK;
266                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_FLOWC_EN_MASK;
267                 dpd->dma_chan_int_mask |= ENETDMA_IR_BUFDONE_MASK;
268                 dpd->dma_chan_int_mask |= ENETDMA_IR_NOTOWNER_MASK;
269                 dpd->dma_chan_width = ENETDMA_6345_CHAN_WIDTH;
270                 dpd->dma_desc_shift = ENETDMA_6345_DESC_SHIFT;
271         } else {
272                 dpd->dma_has_sram = true;
273                 dpd->dma_chan_width = ENETDMA_CHAN_WIDTH;
274         }
275 
276         if (unit == 0) {
277                 dpd->rx_chan = 0;
278                 dpd->tx_chan = 1;
279         } else {
280                 dpd->rx_chan = 2;
281                 dpd->tx_chan = 3;
282         }
283 
284         ret = platform_device_register(pdev);
285         if (ret)
286                 return ret;
287         return 0;
288 }
289 
290 int __init
291 bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd)
292 {
293         int ret;
294 
295         if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
296                 return -ENODEV;
297 
298         ret = register_shared();
299         if (ret)
300                 return ret;
301 
302         enetsw_res[0].start = bcm63xx_regset_address(RSET_ENETSW);
303         enetsw_res[0].end = enetsw_res[0].start;
304         enetsw_res[0].end += RSET_ENETSW_SIZE - 1;
305         enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0);
306         enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0);
307         if (!enetsw_res[2].start)
308                 enetsw_res[2].start = -1;
309 
310         memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof(*pd));
311 
312         if (BCMCPU_IS_6328())
313                 enetsw_pd.num_ports = ENETSW_PORTS_6328;
314         else if (BCMCPU_IS_6362() || BCMCPU_IS_6368())
315                 enetsw_pd.num_ports = ENETSW_PORTS_6368;
316 
317         enetsw_pd.dma_has_sram = true;
318         enetsw_pd.dma_chan_width = ENETDMA_CHAN_WIDTH;
319         enetsw_pd.dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
320         enetsw_pd.dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
321 
322         ret = platform_device_register(&bcm63xx_enetsw_device);
323         if (ret)
324                 return ret;
325 
326         return 0;
327 }
328 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php