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/pci.h>
14 #include <linux/pci_regs.h>
15 #include <linux/slab.h>
19 MODULE_DESCRIPTION("SSB Broadcom Gigabit Ethernet driver");
20 MODULE_AUTHOR("Michael Buesch");
21 MODULE_LICENSE("GPL");
24 static const struct ssb_device_id ssb_gige_tbl
[] = {
25 SSB_DEVICE(SSB_VENDOR_BROADCOM
, SSB_DEV_ETHERNET_GBIT
, SSB_ANY_REV
),
28 /* MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl); */
31 static inline u8
gige_read8(struct ssb_gige
*dev
, u16 offset
)
33 return ssb_read8(dev
->dev
, offset
);
36 static inline u16
gige_read16(struct ssb_gige
*dev
, u16 offset
)
38 return ssb_read16(dev
->dev
, offset
);
41 static inline u32
gige_read32(struct ssb_gige
*dev
, u16 offset
)
43 return ssb_read32(dev
->dev
, offset
);
46 static inline void gige_write8(struct ssb_gige
*dev
,
49 ssb_write8(dev
->dev
, offset
, value
);
52 static inline void gige_write16(struct ssb_gige
*dev
,
53 u16 offset
, u16 value
)
55 ssb_write16(dev
->dev
, offset
, value
);
58 static inline void gige_write32(struct ssb_gige
*dev
,
59 u16 offset
, u32 value
)
61 ssb_write32(dev
->dev
, offset
, value
);
65 u8
gige_pcicfg_read8(struct ssb_gige
*dev
, unsigned int offset
)
67 BUG_ON(offset
>= 256);
68 return gige_read8(dev
, SSB_GIGE_PCICFG
+ offset
);
72 u16
gige_pcicfg_read16(struct ssb_gige
*dev
, unsigned int offset
)
74 BUG_ON(offset
>= 256);
75 return gige_read16(dev
, SSB_GIGE_PCICFG
+ offset
);
79 u32
gige_pcicfg_read32(struct ssb_gige
*dev
, unsigned int offset
)
81 BUG_ON(offset
>= 256);
82 return gige_read32(dev
, SSB_GIGE_PCICFG
+ offset
);
86 void gige_pcicfg_write8(struct ssb_gige
*dev
,
87 unsigned int offset
, u8 value
)
89 BUG_ON(offset
>= 256);
90 gige_write8(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
94 void gige_pcicfg_write16(struct ssb_gige
*dev
,
95 unsigned int offset
, u16 value
)
97 BUG_ON(offset
>= 256);
98 gige_write16(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
102 void gige_pcicfg_write32(struct ssb_gige
*dev
,
103 unsigned int offset
, u32 value
)
105 BUG_ON(offset
>= 256);
106 gige_write32(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
109 static int __devinit
ssb_gige_pci_read_config(struct pci_bus
*bus
,
110 unsigned int devfn
, int reg
,
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 __devinit
ssb_gige_pci_write_config(struct pci_bus
*bus
,
141 unsigned int devfn
, int reg
,
144 struct ssb_gige
*dev
= container_of(bus
->ops
, struct ssb_gige
, pci_ops
);
147 if ((PCI_SLOT(devfn
) > 0) || (PCI_FUNC(devfn
) > 0))
148 return PCIBIOS_DEVICE_NOT_FOUND
;
150 return PCIBIOS_DEVICE_NOT_FOUND
;
152 spin_lock_irqsave(&dev
->lock
, flags
);
155 gige_pcicfg_write8(dev
, reg
, val
);
158 gige_pcicfg_write16(dev
, reg
, val
);
161 gige_pcicfg_write32(dev
, reg
, val
);
166 spin_unlock_irqrestore(&dev
->lock
, flags
);
168 return PCIBIOS_SUCCESSFUL
;
171 static int __devinit
ssb_gige_probe(struct ssb_device
*sdev
,
172 const struct ssb_device_id
*id
)
174 struct ssb_gige
*dev
;
175 u32 base
, tmslow
, tmshigh
;
177 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
182 spin_lock_init(&dev
->lock
);
183 dev
->pci_controller
.pci_ops
= &dev
->pci_ops
;
184 dev
->pci_controller
.io_resource
= &dev
->io_resource
;
185 dev
->pci_controller
.mem_resource
= &dev
->mem_resource
;
186 dev
->pci_controller
.io_map_base
= 0x800;
187 dev
->pci_ops
.read
= ssb_gige_pci_read_config
;
188 dev
->pci_ops
.write
= ssb_gige_pci_write_config
;
190 dev
->io_resource
.name
= SSB_GIGE_IO_RES_NAME
;
191 dev
->io_resource
.start
= 0x800;
192 dev
->io_resource
.end
= 0x8FF;
193 dev
->io_resource
.flags
= IORESOURCE_IO
| IORESOURCE_PCI_FIXED
;
195 if (!ssb_device_is_enabled(sdev
))
196 ssb_device_enable(sdev
, 0);
198 /* Setup BAR0. This is a 64k MMIO region. */
199 base
= ssb_admatch_base(ssb_read32(sdev
, SSB_ADMATCH1
));
200 gige_pcicfg_write32(dev
, PCI_BASE_ADDRESS_0
, base
);
201 gige_pcicfg_write32(dev
, PCI_BASE_ADDRESS_1
, 0);
203 dev
->mem_resource
.name
= SSB_GIGE_MEM_RES_NAME
;
204 dev
->mem_resource
.start
= base
;
205 dev
->mem_resource
.end
= base
+ 0x10000 - 1;
206 dev
->mem_resource
.flags
= IORESOURCE_MEM
| IORESOURCE_PCI_FIXED
;
208 /* Enable the memory region. */
209 gige_pcicfg_write16(dev
, PCI_COMMAND
,
210 gige_pcicfg_read16(dev
, PCI_COMMAND
)
211 | PCI_COMMAND_MEMORY
);
213 /* Write flushing is controlled by the Flush Status Control register.
214 * We want to flush every register write with a timeout and we want
215 * to disable the IRQ mask while flushing to avoid concurrency.
216 * Note that automatic write flushing does _not_ work from
217 * an IRQ handler. The driver must flush manually by reading a register.
219 gige_write32(dev
, SSB_GIGE_SHIM_FLUSHSTAT
, 0x00000068);
221 /* Check if we have an RGMII or GMII PHY-bus.
222 * On RGMII do not bypass the DLLs */
223 tmslow
= ssb_read32(sdev
, SSB_TMSLOW
);
224 tmshigh
= ssb_read32(sdev
, SSB_TMSHIGH
);
225 if (tmshigh
& SSB_GIGE_TMSHIGH_RGMII
) {
226 tmslow
&= ~SSB_GIGE_TMSLOW_TXBYPASS
;
227 tmslow
&= ~SSB_GIGE_TMSLOW_RXBYPASS
;
230 tmslow
|= SSB_GIGE_TMSLOW_TXBYPASS
;
231 tmslow
|= SSB_GIGE_TMSLOW_RXBYPASS
;
234 tmslow
|= SSB_GIGE_TMSLOW_DLLEN
;
235 ssb_write32(sdev
, SSB_TMSLOW
, tmslow
);
237 ssb_set_drvdata(sdev
, dev
);
238 register_pci_controller(&dev
->pci_controller
);
243 bool pdev_is_ssb_gige_core(struct pci_dev
*pdev
)
245 if (!pdev
->resource
[0].name
)
247 return (strcmp(pdev
->resource
[0].name
, SSB_GIGE_MEM_RES_NAME
) == 0);
249 EXPORT_SYMBOL(pdev_is_ssb_gige_core
);
251 int ssb_gige_pcibios_plat_dev_init(struct ssb_device
*sdev
,
252 struct pci_dev
*pdev
)
254 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
255 struct resource
*res
;
257 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
258 /* The PCI device is not on this SSB GigE bridge device. */
262 /* Fixup the PCI resources. */
263 res
= &(pdev
->resource
[0]);
264 res
->flags
= IORESOURCE_MEM
| IORESOURCE_PCI_FIXED
;
265 res
->name
= dev
->mem_resource
.name
;
266 res
->start
= dev
->mem_resource
.start
;
267 res
->end
= dev
->mem_resource
.end
;
269 /* Fixup interrupt lines. */
270 pdev
->irq
= ssb_mips_irq(sdev
) + 2;
271 pci_write_config_byte(pdev
, PCI_INTERRUPT_LINE
, pdev
->irq
);
276 int ssb_gige_map_irq(struct ssb_device
*sdev
,
277 const struct pci_dev
*pdev
)
279 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
281 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
282 /* The PCI device is not on this SSB GigE bridge device. */
286 return ssb_mips_irq(sdev
) + 2;
289 static struct ssb_driver ssb_gige_driver
= {
291 .id_table
= ssb_gige_tbl
,
292 .probe
= ssb_gige_probe
,
295 int ssb_gige_init(void)
297 return ssb_driver_register(&ssb_gige_driver
);