xref: /OK3568_Linux_fs/kernel/include/linux/ssb/ssb_driver_gige.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef LINUX_SSB_DRIVER_GIGE_H_
3*4882a593Smuzhiyun #define LINUX_SSB_DRIVER_GIGE_H_
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/ssb/ssb.h>
6*4882a593Smuzhiyun #include <linux/bug.h>
7*4882a593Smuzhiyun #include <linux/pci.h>
8*4882a593Smuzhiyun #include <linux/spinlock.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #ifdef CONFIG_SSB_DRIVER_GIGE
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define SSB_GIGE_PCIIO			0x0000 /* PCI I/O Registers (1024 bytes) */
15*4882a593Smuzhiyun #define SSB_GIGE_RESERVED		0x0400 /* Reserved (1024 bytes) */
16*4882a593Smuzhiyun #define SSB_GIGE_PCICFG			0x0800 /* PCI config space (256 bytes) */
17*4882a593Smuzhiyun #define SSB_GIGE_SHIM_FLUSHSTAT		0x0C00 /* PCI to OCP: Flush status control (32bit) */
18*4882a593Smuzhiyun #define SSB_GIGE_SHIM_FLUSHRDA		0x0C04 /* PCI to OCP: Flush read address (32bit) */
19*4882a593Smuzhiyun #define SSB_GIGE_SHIM_FLUSHTO		0x0C08 /* PCI to OCP: Flush timeout counter (32bit) */
20*4882a593Smuzhiyun #define SSB_GIGE_SHIM_BARRIER		0x0C0C /* PCI to OCP: Barrier register (32bit) */
21*4882a593Smuzhiyun #define SSB_GIGE_SHIM_MAOCPSI		0x0C10 /* PCI to OCP: MaocpSI Control (32bit) */
22*4882a593Smuzhiyun #define SSB_GIGE_SHIM_SIOCPMA		0x0C14 /* PCI to OCP: SiocpMa Control (32bit) */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /* TM Status High flags */
25*4882a593Smuzhiyun #define SSB_GIGE_TMSHIGH_RGMII		0x00010000 /* Have an RGMII PHY-bus */
26*4882a593Smuzhiyun /* TM Status Low flags */
27*4882a593Smuzhiyun #define SSB_GIGE_TMSLOW_TXBYPASS	0x00080000 /* TX bypass (no delay) */
28*4882a593Smuzhiyun #define SSB_GIGE_TMSLOW_RXBYPASS	0x00100000 /* RX bypass (no delay) */
29*4882a593Smuzhiyun #define SSB_GIGE_TMSLOW_DLLEN		0x01000000 /* Enable DLL controls */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /* Boardflags (low) */
32*4882a593Smuzhiyun #define SSB_GIGE_BFL_ROBOSWITCH		0x0010
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define SSB_GIGE_MEM_RES_NAME		"SSB Broadcom 47xx GigE memory"
36*4882a593Smuzhiyun #define SSB_GIGE_IO_RES_NAME		"SSB Broadcom 47xx GigE I/O"
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun struct ssb_gige {
39*4882a593Smuzhiyun 	struct ssb_device *dev;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	spinlock_t lock;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	/* True, if the device has an RGMII bus.
44*4882a593Smuzhiyun 	 * False, if the device has a GMII bus. */
45*4882a593Smuzhiyun 	bool has_rgmii;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	/* The PCI controller device. */
48*4882a593Smuzhiyun 	struct pci_controller pci_controller;
49*4882a593Smuzhiyun 	struct pci_ops pci_ops;
50*4882a593Smuzhiyun 	struct resource mem_resource;
51*4882a593Smuzhiyun 	struct resource io_resource;
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* Check whether a PCI device is a SSB Gigabit Ethernet core. */
55*4882a593Smuzhiyun extern bool pdev_is_ssb_gige_core(struct pci_dev *pdev);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* Convert a pci_dev pointer to a ssb_gige pointer. */
pdev_to_ssb_gige(struct pci_dev * pdev)58*4882a593Smuzhiyun static inline struct ssb_gige * pdev_to_ssb_gige(struct pci_dev *pdev)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	if (!pdev_is_ssb_gige_core(pdev))
61*4882a593Smuzhiyun 		return NULL;
62*4882a593Smuzhiyun 	return container_of(pdev->bus->ops, struct ssb_gige, pci_ops);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /* Returns whether the PHY is connected by an RGMII bus. */
ssb_gige_is_rgmii(struct pci_dev * pdev)66*4882a593Smuzhiyun static inline bool ssb_gige_is_rgmii(struct pci_dev *pdev)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
69*4882a593Smuzhiyun 	return (dev ? dev->has_rgmii : 0);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* Returns whether we have a Roboswitch. */
ssb_gige_have_roboswitch(struct pci_dev * pdev)73*4882a593Smuzhiyun static inline bool ssb_gige_have_roboswitch(struct pci_dev *pdev)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
76*4882a593Smuzhiyun 	if (dev)
77*4882a593Smuzhiyun 		return !!(dev->dev->bus->sprom.boardflags_lo &
78*4882a593Smuzhiyun 			  SSB_GIGE_BFL_ROBOSWITCH);
79*4882a593Smuzhiyun 	return 0;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /* Returns whether we can only do one DMA at once. */
ssb_gige_one_dma_at_once(struct pci_dev * pdev)83*4882a593Smuzhiyun static inline bool ssb_gige_one_dma_at_once(struct pci_dev *pdev)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
86*4882a593Smuzhiyun 	if (dev)
87*4882a593Smuzhiyun 		return ((dev->dev->bus->chip_id == 0x4785) &&
88*4882a593Smuzhiyun 			(dev->dev->bus->chip_rev < 2));
89*4882a593Smuzhiyun 	return 0;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Returns whether we must flush posted writes. */
ssb_gige_must_flush_posted_writes(struct pci_dev * pdev)93*4882a593Smuzhiyun static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
96*4882a593Smuzhiyun 	if (dev)
97*4882a593Smuzhiyun 		return (dev->dev->bus->chip_id == 0x4785);
98*4882a593Smuzhiyun 	return 0;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /* Get the device MAC address */
ssb_gige_get_macaddr(struct pci_dev * pdev,u8 * macaddr)102*4882a593Smuzhiyun static inline int ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
105*4882a593Smuzhiyun 	if (!dev)
106*4882a593Smuzhiyun 		return -ENODEV;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	memcpy(macaddr, dev->dev->bus->sprom.et0mac, 6);
109*4882a593Smuzhiyun 	return 0;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /* Get the device phy address */
ssb_gige_get_phyaddr(struct pci_dev * pdev)113*4882a593Smuzhiyun static inline int ssb_gige_get_phyaddr(struct pci_dev *pdev)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	struct ssb_gige *dev = pdev_to_ssb_gige(pdev);
116*4882a593Smuzhiyun 	if (!dev)
117*4882a593Smuzhiyun 		return -ENODEV;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	return dev->dev->bus->sprom.et0phyaddr;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
123*4882a593Smuzhiyun 					  struct pci_dev *pdev);
124*4882a593Smuzhiyun extern int ssb_gige_map_irq(struct ssb_device *sdev,
125*4882a593Smuzhiyun 			    const struct pci_dev *pdev);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* The GigE driver is not a standalone module, because we don't have support
128*4882a593Smuzhiyun  * for unregistering the driver. So we could not unload the module anyway. */
129*4882a593Smuzhiyun extern int ssb_gige_init(void);
ssb_gige_exit(void)130*4882a593Smuzhiyun static inline void ssb_gige_exit(void)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	/* Currently we can not unregister the GigE driver,
133*4882a593Smuzhiyun 	 * because we can not unregister the PCI bridge. */
134*4882a593Smuzhiyun 	BUG();
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun #else /* CONFIG_SSB_DRIVER_GIGE */
139*4882a593Smuzhiyun /* Gigabit Ethernet driver disabled */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 
ssb_gige_pcibios_plat_dev_init(struct ssb_device * sdev,struct pci_dev * pdev)142*4882a593Smuzhiyun static inline int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
143*4882a593Smuzhiyun 						 struct pci_dev *pdev)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	return -ENOSYS;
146*4882a593Smuzhiyun }
ssb_gige_map_irq(struct ssb_device * sdev,const struct pci_dev * pdev)147*4882a593Smuzhiyun static inline int ssb_gige_map_irq(struct ssb_device *sdev,
148*4882a593Smuzhiyun 				   const struct pci_dev *pdev)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	return -ENOSYS;
151*4882a593Smuzhiyun }
ssb_gige_init(void)152*4882a593Smuzhiyun static inline int ssb_gige_init(void)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	return 0;
155*4882a593Smuzhiyun }
ssb_gige_exit(void)156*4882a593Smuzhiyun static inline void ssb_gige_exit(void)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
pdev_is_ssb_gige_core(struct pci_dev * pdev)160*4882a593Smuzhiyun static inline bool pdev_is_ssb_gige_core(struct pci_dev *pdev)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	return 0;
163*4882a593Smuzhiyun }
pdev_to_ssb_gige(struct pci_dev * pdev)164*4882a593Smuzhiyun static inline struct ssb_gige * pdev_to_ssb_gige(struct pci_dev *pdev)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	return NULL;
167*4882a593Smuzhiyun }
ssb_gige_is_rgmii(struct pci_dev * pdev)168*4882a593Smuzhiyun static inline bool ssb_gige_is_rgmii(struct pci_dev *pdev)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun 	return 0;
171*4882a593Smuzhiyun }
ssb_gige_have_roboswitch(struct pci_dev * pdev)172*4882a593Smuzhiyun static inline bool ssb_gige_have_roboswitch(struct pci_dev *pdev)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	return 0;
175*4882a593Smuzhiyun }
ssb_gige_one_dma_at_once(struct pci_dev * pdev)176*4882a593Smuzhiyun static inline bool ssb_gige_one_dma_at_once(struct pci_dev *pdev)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun 	return 0;
179*4882a593Smuzhiyun }
ssb_gige_must_flush_posted_writes(struct pci_dev * pdev)180*4882a593Smuzhiyun static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	return 0;
183*4882a593Smuzhiyun }
ssb_gige_get_macaddr(struct pci_dev * pdev,u8 * macaddr)184*4882a593Smuzhiyun static inline int ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	return -ENODEV;
187*4882a593Smuzhiyun }
ssb_gige_get_phyaddr(struct pci_dev * pdev)188*4882a593Smuzhiyun static inline int ssb_gige_get_phyaddr(struct pci_dev *pdev)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	return -ENODEV;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun #endif /* CONFIG_SSB_DRIVER_GIGE */
194*4882a593Smuzhiyun #endif /* LINUX_SSB_DRIVER_GIGE_H_ */
195