9
9
#include <linux/of_irq.h>
10
10
#include "stmmac.h"
11
11
12
- static int loongson_default_data (struct plat_stmmacenet_data * plat )
12
+ struct stmmac_pci_info {
13
+ int (* setup )(struct pci_dev * pdev , struct plat_stmmacenet_data * plat );
14
+ };
15
+
16
+ static void common_default_data (struct pci_dev * pdev ,
17
+ struct plat_stmmacenet_data * plat )
13
18
{
19
+ plat -> bus_id = (pci_domain_nr (pdev -> bus ) << 16 ) | PCI_DEVID (pdev -> bus -> number , pdev -> devfn );
20
+ plat -> interface = PHY_INTERFACE_MODE_GMII ;
21
+
14
22
plat -> clk_csr = 2 ; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
15
23
plat -> has_gmac = 1 ;
16
24
plat -> force_sf_dma_mode = 1 ;
17
25
18
26
/* Set default value for multicast hash bins */
19
- plat -> multicast_filter_bins = HASH_TABLE_SIZE ;
27
+ plat -> multicast_filter_bins = 256 ;
20
28
21
29
/* Set default value for unicast filter entries */
22
30
plat -> unicast_filter_entries = 1 ;
@@ -35,31 +43,80 @@ static int loongson_default_data(struct plat_stmmacenet_data *plat)
35
43
/* Disable RX queues routing by default */
36
44
plat -> rx_queues_cfg [0 ].pkt_route = 0x0 ;
37
45
38
- /* Default to phy auto-detection */
39
- plat -> phy_addr = -1 ;
40
-
41
46
plat -> dma_cfg -> pbl = 32 ;
42
47
plat -> dma_cfg -> pblx8 = true;
43
48
44
- plat -> multicast_filter_bins = 256 ;
49
+ plat -> clk_ref_rate = 125000000 ;
50
+ plat -> clk_ptp_rate = 125000000 ;
51
+ }
52
+
53
+ static int loongson_gmac_data (struct pci_dev * pdev ,
54
+ struct plat_stmmacenet_data * plat )
55
+ {
56
+ common_default_data (pdev , plat );
57
+
58
+ plat -> mdio_bus_data -> phy_mask = 0 ;
59
+
60
+ plat -> phy_addr = -1 ;
61
+ plat -> phy_interface = PHY_INTERFACE_MODE_RGMII_ID ;
62
+
63
+ stmmac_flow_ctrl = FLOW_OFF ;
64
+
45
65
return 0 ;
46
66
}
47
67
48
- static int loongson_dwmac_probe (struct pci_dev * pdev , const struct pci_device_id * id )
68
+ static struct stmmac_pci_info loongson_gmac_pci_info = {
69
+ .setup = loongson_gmac_data ,
70
+ };
71
+
72
+ static void loongson_gnet_fix_speed (void * priv , unsigned int speed )
73
+ {
74
+ struct net_device * ndev = (struct net_device * )(* (unsigned long * )priv );
75
+ struct stmmac_priv * ptr = netdev_priv (ndev );
76
+
77
+ if (speed == SPEED_1000 ) {
78
+ if (readl (ptr -> ioaddr + MAC_CTRL_REG ) & (1 << 15 ) /* PS */ ) {
79
+ /* reset phy */
80
+ phy_set_bits (ndev -> phydev , 0 /*MII_BMCR*/ ,
81
+ 0x200 /*BMCR_ANRESTART*/ );
82
+ }
83
+ }
84
+ }
85
+
86
+ static int loongson_gnet_data (struct pci_dev * pdev ,
87
+ struct plat_stmmacenet_data * plat )
88
+ {
89
+ common_default_data (pdev , plat );
90
+
91
+ plat -> mdio_bus_data -> phy_mask = 0xfffffffb ;
92
+
93
+ plat -> phy_addr = 2 ;
94
+ plat -> phy_interface = PHY_INTERFACE_MODE_GMII ;
95
+
96
+ /* GNET 1000M speed need workaround */
97
+ plat -> fix_mac_speed = loongson_gnet_fix_speed ;
98
+
99
+ /* Get netdev pointer address */
100
+ plat -> bsp_priv = & (pdev -> dev .driver_data );
101
+
102
+ return 0 ;
103
+ }
104
+
105
+ static struct stmmac_pci_info loongson_gnet_pci_info = {
106
+ .setup = loongson_gnet_data ,
107
+ };
108
+
109
+ static int loongson_dwmac_probe (struct pci_dev * pdev ,
110
+ const struct pci_device_id * id )
49
111
{
50
112
struct plat_stmmacenet_data * plat ;
113
+ struct stmmac_pci_info * info ;
51
114
struct stmmac_resources res ;
52
115
struct device_node * np ;
53
- int ret , i , phy_mode ;
116
+ int ret , i , bus_id , phy_mode ;
54
117
55
118
np = dev_of_node (& pdev -> dev );
56
-
57
- if (!np ) {
58
- pr_info ("dwmac_loongson_pci: No OF node\n" );
59
- return - ENODEV ;
60
- }
61
-
62
- if (!of_device_is_compatible (np , "loongson, pci-gmac" )) {
119
+ if (np && !of_device_is_compatible (np , "loongson, pci-gmac" )) {
63
120
pr_info ("dwmac_loongson_pci: Incompatible OF node\n" );
64
121
return - ENODEV ;
65
122
}
@@ -68,17 +125,14 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
68
125
if (!plat )
69
126
return - ENOMEM ;
70
127
128
+ plat -> mdio_bus_data = devm_kzalloc (& pdev -> dev ,
129
+ sizeof (* plat -> mdio_bus_data ), GFP_KERNEL );
130
+ if (!plat -> mdio_bus_data )
131
+ return - ENOMEM ;
132
+
71
133
plat -> mdio_node = of_get_child_by_name (np , "mdio" );
72
134
if (plat -> mdio_node ) {
73
135
dev_info (& pdev -> dev , "Found MDIO subnode\n" );
74
-
75
- plat -> mdio_bus_data = devm_kzalloc (& pdev -> dev ,
76
- sizeof (* plat -> mdio_bus_data ),
77
- GFP_KERNEL );
78
- if (!plat -> mdio_bus_data ) {
79
- ret = - ENOMEM ;
80
- goto err_put_node ;
81
- }
82
136
plat -> mdio_bus_data -> needs_reset = true;
83
137
}
84
138
@@ -105,45 +159,55 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
105
159
break ;
106
160
}
107
161
108
- plat -> bus_id = of_alias_get_id (np , "ethernet" );
109
- if (plat -> bus_id < 0 )
110
- plat -> bus_id = pci_dev_id (pdev );
162
+ pci_set_master (pdev );
111
163
112
- phy_mode = device_get_phy_mode (& pdev -> dev );
113
- if (phy_mode < 0 ) {
114
- dev_err (& pdev -> dev , "phy_mode not found\n" );
115
- ret = phy_mode ;
116
- goto err_disable_device ;
117
- }
164
+ info = (struct stmmac_pci_info * )id -> driver_data ;
165
+ ret = info -> setup (pdev , plat );
166
+ if (ret )
167
+ return ret ;
118
168
119
- plat -> phy_interface = phy_mode ;
120
- plat -> interface = PHY_INTERFACE_MODE_GMII ;
169
+ if (np ) {
170
+ bus_id = of_alias_get_id (np , "ethernet" );
171
+ if (bus_id >= 0 )
172
+ plat -> bus_id = bus_id ;
121
173
122
- pci_set_master (pdev );
174
+ phy_mode = device_get_phy_mode (& pdev -> dev );
175
+ if (phy_mode < 0 ) {
176
+ dev_err (& pdev -> dev , "phy_mode not found\n" );
177
+ ret = phy_mode ;
178
+ goto err_disable_device ;
179
+ }
180
+ plat -> phy_interface = phy_mode ;
181
+ }
123
182
124
- loongson_default_data (plat );
125
183
pci_enable_msi (pdev );
184
+
126
185
memset (& res , 0 , sizeof (res ));
127
186
res .addr = pcim_iomap_table (pdev )[0 ];
187
+ if (np ) {
188
+ res .irq = of_irq_get_byname (np , "macirq" );
189
+ if (res .irq < 0 ) {
190
+ dev_err (& pdev -> dev , "IRQ macirq not found\n" );
191
+ ret = - ENODEV ;
192
+ goto err_disable_msi ;
193
+ }
128
194
129
- res .irq = of_irq_get_byname (np , "macirq" );
130
- if (res .irq < 0 ) {
131
- dev_err (& pdev -> dev , "IRQ macirq not found\n" );
132
- ret = - ENODEV ;
133
- goto err_disable_msi ;
134
- }
135
-
136
- res .wol_irq = of_irq_get_byname (np , "eth_wake_irq" );
137
- if (res .wol_irq < 0 ) {
138
- dev_info (& pdev -> dev , "IRQ eth_wake_irq not found, using macirq\n" );
139
- res .wol_irq = res .irq ;
140
- }
195
+ res .wol_irq = of_irq_get_byname (np , "eth_wake_irq" );
196
+ if (res .wol_irq < 0 ) {
197
+ dev_info (& pdev -> dev ,
198
+ "IRQ eth_wake_irq not found, using macirq\n" );
199
+ res .wol_irq = res .irq ;
200
+ }
141
201
142
- res .lpi_irq = of_irq_get_byname (np , "eth_lpi" );
143
- if (res .lpi_irq < 0 ) {
144
- dev_err (& pdev -> dev , "IRQ eth_lpi not found\n" );
145
- ret = - ENODEV ;
146
- goto err_disable_msi ;
202
+ res .lpi_irq = of_irq_get_byname (np , "eth_lpi" );
203
+ if (res .lpi_irq < 0 ) {
204
+ dev_err (& pdev -> dev , "IRQ eth_lpi not found\n" );
205
+ ret = - ENODEV ;
206
+ goto err_disable_msi ;
207
+ }
208
+ } else {
209
+ res .irq = pdev -> irq ;
210
+ res .wol_irq = pdev -> irq ;
147
211
}
148
212
149
213
ret = stmmac_dvr_probe (& pdev -> dev , plat , & res );
@@ -219,8 +283,12 @@ static int __maybe_unused loongson_dwmac_resume(struct device *dev)
219
283
static SIMPLE_DEV_PM_OPS (loongson_dwmac_pm_ops , loongson_dwmac_suspend ,
220
284
loongson_dwmac_resume ) ;
221
285
286
+ #define PCI_DEVICE_ID_LOONGSON_GMAC 0x7a03
287
+ #define PCI_DEVICE_ID_LOONGSON_GNET 0x7a13
288
+
222
289
static const struct pci_device_id loongson_dwmac_id_table [] = {
223
- { PCI_VDEVICE (LOONGSON , 0x7a03 ) },
290
+ { PCI_DEVICE_DATA (LOONGSON , GMAC , & loongson_gmac_pci_info ) },
291
+ { PCI_DEVICE_DATA (LOONGSON , GNET , & loongson_gnet_pci_info ) },
224
292
{}
225
293
};
226
294
MODULE_DEVICE_TABLE (pci , loongson_dwmac_id_table );
0 commit comments