2 * Sonics Silicon Backplane
3 * Broadcom Gigabit Ethernet core driver
5 * Copyright 2008, Broadcom Corporation
6 * Copyright 2008, Michael Buesch <m@bues.ch>
8 * Licensed under the GNU/GPL. See COPYING for details.
11 #include <linux/ssb/ssb.h>
12 #include <linux/ssb/ssb_driver_gige.h>
13 #include <linux/export.h>
14 #include <linux/pci.h>
15 #include <linux/pci_regs.h>
16 #include <linux/slab.h>
20 MODULE_DESCRIPTION("SSB Broadcom Gigabit Ethernet driver");
21 MODULE_AUTHOR("Michael Buesch");
22 MODULE_LICENSE("GPL");
25 static const struct ssb_device_id ssb_gige_tbl
[] = {
26 SSB_DEVICE(SSB_VENDOR_BROADCOM
, SSB_DEV_ETHERNET_GBIT
, SSB_ANY_REV
),
29 /* MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl); */
32 static inline u8
gige_read8(struct ssb_gige
*dev
, u16 offset
)
34 return ssb_read8(dev
->dev
, offset
);
37 static inline u16
gige_read16(struct ssb_gige
*dev
, u16 offset
)
39 return ssb_read16(dev
->dev
, offset
);
42 static inline u32
gige_read32(struct ssb_gige
*dev
, u16 offset
)
44 return ssb_read32(dev
->dev
, offset
);
47 static inline void gige_write8(struct ssb_gige
*dev
,
50 ssb_write8(dev
->dev
, offset
, value
);
53 static inline void gige_write16(struct ssb_gige
*dev
,
54 u16 offset
, u16 value
)
56 ssb_write16(dev
->dev
, offset
, value
);
59 static inline void gige_write32(struct ssb_gige
*dev
,
60 u16 offset
, u32 value
)
62 ssb_write32(dev
->dev
, offset
, value
);
66 u8
gige_pcicfg_read8(struct ssb_gige
*dev
, unsigned int offset
)
68 BUG_ON(offset
>= 256);
69 return gige_read8(dev
, SSB_GIGE_PCICFG
+ offset
);
73 u16
gige_pcicfg_read16(struct ssb_gige
*dev
, unsigned int offset
)
75 BUG_ON(offset
>= 256);
76 return gige_read16(dev
, SSB_GIGE_PCICFG
+ offset
);
80 u32
gige_pcicfg_read32(struct ssb_gige
*dev
, unsigned int offset
)
82 BUG_ON(offset
>= 256);
83 return gige_read32(dev
, SSB_GIGE_PCICFG
+ offset
);
87 void gige_pcicfg_write8(struct ssb_gige
*dev
,
88 unsigned int offset
, u8 value
)
90 BUG_ON(offset
>= 256);
91 gige_write8(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
95 void gige_pcicfg_write16(struct ssb_gige
*dev
,
96 unsigned int offset
, u16 value
)
98 BUG_ON(offset
>= 256);
99 gige_write16(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
103 void gige_pcicfg_write32(struct ssb_gige
*dev
,
104 unsigned int offset
, u32 value
)
106 BUG_ON(offset
>= 256);
107 gige_write32(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
110 static int ssb_gige_pci_read_config(struct pci_bus
*bus
, unsigned int devfn
,
111 int reg
, int size
, u32
*val
)
113 struct ssb_gige
*dev
= container_of(bus
->ops
, struct ssb_gige
, pci_ops
);
116 if ((PCI_SLOT(devfn
) > 0) || (PCI_FUNC(devfn
) > 0))
117 return PCIBIOS_DEVICE_NOT_FOUND
;
119 return PCIBIOS_DEVICE_NOT_FOUND
;
121 spin_lock_irqsave(&dev
->lock
, flags
);
124 *val
= gige_pcicfg_read8(dev
, reg
);
127 *val
= gige_pcicfg_read16(dev
, reg
);
130 *val
= gige_pcicfg_read32(dev
, reg
);
135 spin_unlock_irqrestore(&dev
->lock
, flags
);
137 return PCIBIOS_SUCCESSFUL
;
140 static int ssb_gige_pci_write_config(struct pci_bus
*bus
, unsigned int devfn
,
141 int reg
, int size
, u32 val
)
143 struct ssb_gige
*dev
= container_of(bus
->ops
, struct ssb_gige
, pci_ops
);
146 if ((PCI_SLOT(devfn
) > 0) || (PCI_FUNC(devfn
) > 0))
147 return PCIBIOS_DEVICE_NOT_FOUND
;
149 return PCIBIOS_DEVICE_NOT_FOUND
;
151 spin_lock_irqsave(&dev
->lock
, flags
);
154 gige_pcicfg_write8(dev
, reg
, val
);
157 gige_pcicfg_write16(dev
, reg
, val
);
160 gige_pcicfg_write32(dev
, reg
, val
);
165 spin_unlock_irqrestore(&dev
->lock
, flags
);
167 return PCIBIOS_SUCCESSFUL
;
170 static int ssb_gige_probe(struct ssb_device
*sdev
,
171 const struct ssb_device_id
*id
)
173 struct ssb_gige
*dev
;
174 u32 base
, tmslow
, tmshigh
;
176 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
181 spin_lock_init(&dev
->lock
);
182 dev
->pci_controller
.pci_ops
= &dev
->pci_ops
;
183 dev
->pci_controller
.io_resource
= &dev
->io_resource
;
184 dev
->pci_controller
.mem_resource
= &dev
->mem_resource
;
185 dev
->pci_controller
.io_map_base
= 0x800;
186 dev
->pci_ops
.read
= ssb_gige_pci_read_config
;
187 dev
->pci_ops
.write
= ssb_gige_pci_write_config
;
189 dev
->io_resource
.name
= SSB_GIGE_IO_RES_NAME
;
190 dev
->io_resource
.start
= 0x800;
191 dev
->io_resource
.end
= 0x8FF;
192 dev
->io_resource
.flags
= IORESOURCE_IO
| IORESOURCE_PCI_FIXED
;
194 if (!ssb_device_is_enabled(sdev
))
195 ssb_device_enable(sdev
, 0);
197 /* Setup BAR0. This is a 64k MMIO region. */
198 base
= ssb_admatch_base(ssb_read32(sdev
, SSB_ADMATCH1
));
199 gige_pcicfg_write32(dev
, PCI_BASE_ADDRESS_0
, base
);
200 gige_pcicfg_write32(dev
, PCI_BASE_ADDRESS_1
, 0);
202 dev
->mem_resource
.name
= SSB_GIGE_MEM_RES_NAME
;
203 dev
->mem_resource
.start
= base
;
204 dev
->mem_resource
.end
= base
+ 0x10000 - 1;
205 dev
->mem_resource
.flags
= IORESOURCE_MEM
| IORESOURCE_PCI_FIXED
;
207 /* Enable the memory region. */
208 gige_pcicfg_write16(dev
, PCI_COMMAND
,
209 gige_pcicfg_read16(dev
, PCI_COMMAND
)
210 | PCI_COMMAND_MEMORY
);
212 /* Write flushing is controlled by the Flush Status Control register.
213 * We want to flush every register write with a timeout and we want
214 * to disable the IRQ mask while flushing to avoid concurrency.
215 * Note that automatic write flushing does _not_ work from
216 * an IRQ handler. The driver must flush manually by reading a register.
218 gige_write32(dev
, SSB_GIGE_SHIM_FLUSHSTAT
, 0x00000068);
220 /* Check if we have an RGMII or GMII PHY-bus.
221 * On RGMII do not bypass the DLLs */
222 tmslow
= ssb_read32(sdev
, SSB_TMSLOW
);
223 tmshigh
= ssb_read32(sdev
, SSB_TMSHIGH
);
224 if (tmshigh
& SSB_GIGE_TMSHIGH_RGMII
) {
225 tmslow
&= ~SSB_GIGE_TMSLOW_TXBYPASS
;
226 tmslow
&= ~SSB_GIGE_TMSLOW_RXBYPASS
;
229 tmslow
|= SSB_GIGE_TMSLOW_TXBYPASS
;
230 tmslow
|= SSB_GIGE_TMSLOW_RXBYPASS
;
233 tmslow
|= SSB_GIGE_TMSLOW_DLLEN
;
234 ssb_write32(sdev
, SSB_TMSLOW
, tmslow
);
236 ssb_set_drvdata(sdev
, dev
);
237 register_pci_controller(&dev
->pci_controller
);
242 bool pdev_is_ssb_gige_core(struct pci_dev
*pdev
)
244 if (!pdev
->resource
[0].name
)
246 return (strcmp(pdev
->resource
[0].name
, SSB_GIGE_MEM_RES_NAME
) == 0);
248 EXPORT_SYMBOL(pdev_is_ssb_gige_core
);
250 int ssb_gige_pcibios_plat_dev_init(struct ssb_device
*sdev
,
251 struct pci_dev
*pdev
)
253 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
254 struct resource
*res
;
256 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
257 /* The PCI device is not on this SSB GigE bridge device. */
261 /* Fixup the PCI resources. */
262 res
= &(pdev
->resource
[0]);
263 res
->flags
= IORESOURCE_MEM
| IORESOURCE_PCI_FIXED
;
264 res
->name
= dev
->mem_resource
.name
;
265 res
->start
= dev
->mem_resource
.start
;
266 res
->end
= dev
->mem_resource
.end
;
268 /* Fixup interrupt lines. */
269 pdev
->irq
= ssb_mips_irq(sdev
) + 2;
270 pci_write_config_byte(pdev
, PCI_INTERRUPT_LINE
, pdev
->irq
);
275 int ssb_gige_map_irq(struct ssb_device
*sdev
,
276 const struct pci_dev
*pdev
)
278 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
280 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
281 /* The PCI device is not on this SSB GigE bridge device. */
285 return ssb_mips_irq(sdev
) + 2;
288 static struct ssb_driver ssb_gige_driver
= {
290 .id_table
= ssb_gige_tbl
,
291 .probe
= ssb_gige_probe
,
294 int ssb_gige_init(void)
296 return ssb_driver_register(&ssb_gige_driver
);