diff options
author | David S. Miller <davem@davemloft.net> | 2015-01-28 00:08:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-28 00:08:13 -0500 |
commit | ff660f75be36e6db75d45dc742a4a468c5a9c20d (patch) | |
tree | 36c2647d695b08324f11336e29cb52fc98578b04 | |
parent | 488327c6ef2a2f39adc6d9f017745921c8b747e5 (diff) | |
parent | d2a029bde37b4c2e2d8b26e7457bb2c58afbbadd (diff) |
Merge branch 'stmmac-pci'
Andy Shevchenko says:
====================
stmmac: Enable Intel Quark SoC X1000 Ethernet support
This is third version of the patch series [1] to bring network card support to
Intel Quark SoC.
The series has been tested on Intel Galileo board.
Changelog v3:
- rebase on top of recent net-next
- rework an approach to get the custom configuration
- rework an approach how to get unique bus_id
- improve DMI lookup function
[1] http://www.spinics.net/lists/netdev/msg296010.html
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 113 |
1 files changed, 112 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 054520d67de4..3bca908716e2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | |||
@@ -24,8 +24,50 @@ | |||
24 | *******************************************************************************/ | 24 | *******************************************************************************/ |
25 | 25 | ||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/dmi.h> | ||
28 | |||
27 | #include "stmmac.h" | 29 | #include "stmmac.h" |
28 | 30 | ||
31 | /* | ||
32 | * This struct is used to associate PCI Function of MAC controller on a board, | ||
33 | * discovered via DMI, with the address of PHY connected to the MAC. The | ||
34 | * negative value of the address means that MAC controller is not connected | ||
35 | * with PHY. | ||
36 | */ | ||
37 | struct stmmac_pci_dmi_data { | ||
38 | const char *name; | ||
39 | unsigned int func; | ||
40 | int phy_addr; | ||
41 | }; | ||
42 | |||
43 | struct stmmac_pci_info { | ||
44 | struct pci_dev *pdev; | ||
45 | int (*setup)(struct plat_stmmacenet_data *plat, | ||
46 | struct stmmac_pci_info *info); | ||
47 | struct stmmac_pci_dmi_data *dmi; | ||
48 | }; | ||
49 | |||
50 | static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info) | ||
51 | { | ||
52 | const char *name = dmi_get_system_info(DMI_BOARD_NAME); | ||
53 | unsigned int func = PCI_FUNC(info->pdev->devfn); | ||
54 | struct stmmac_pci_dmi_data *dmi; | ||
55 | |||
56 | /* | ||
57 | * Galileo boards with old firmware don't support DMI. We always return | ||
58 | * 1 here, so at least first found MAC controller would be probed. | ||
59 | */ | ||
60 | if (!name) | ||
61 | return 1; | ||
62 | |||
63 | for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) { | ||
64 | if (!strcmp(dmi->name, name) && dmi->func == func) | ||
65 | return dmi->phy_addr; | ||
66 | } | ||
67 | |||
68 | return -ENODEV; | ||
69 | } | ||
70 | |||
29 | static void stmmac_default_data(struct plat_stmmacenet_data *plat) | 71 | static void stmmac_default_data(struct plat_stmmacenet_data *plat) |
30 | { | 72 | { |
31 | plat->bus_id = 1; | 73 | plat->bus_id = 1; |
@@ -48,6 +90,62 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat) | |||
48 | plat->unicast_filter_entries = 1; | 90 | plat->unicast_filter_entries = 1; |
49 | } | 91 | } |
50 | 92 | ||
93 | static int quark_default_data(struct plat_stmmacenet_data *plat, | ||
94 | struct stmmac_pci_info *info) | ||
95 | { | ||
96 | struct pci_dev *pdev = info->pdev; | ||
97 | int ret; | ||
98 | |||
99 | /* | ||
100 | * Refuse to load the driver and register net device if MAC controller | ||
101 | * does not connect to any PHY interface. | ||
102 | */ | ||
103 | ret = stmmac_pci_find_phy_addr(info); | ||
104 | if (ret < 0) | ||
105 | return ret; | ||
106 | |||
107 | plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn); | ||
108 | plat->phy_addr = ret; | ||
109 | plat->interface = PHY_INTERFACE_MODE_RMII; | ||
110 | plat->clk_csr = 2; | ||
111 | plat->has_gmac = 1; | ||
112 | plat->force_sf_dma_mode = 1; | ||
113 | |||
114 | plat->mdio_bus_data->phy_reset = NULL; | ||
115 | plat->mdio_bus_data->phy_mask = 0; | ||
116 | |||
117 | plat->dma_cfg->pbl = 16; | ||
118 | plat->dma_cfg->burst_len = DMA_AXI_BLEN_256; | ||
119 | plat->dma_cfg->fixed_burst = 1; | ||
120 | |||
121 | /* Set default value for multicast hash bins */ | ||
122 | plat->multicast_filter_bins = HASH_TABLE_SIZE; | ||
123 | |||
124 | /* Set default value for unicast filter entries */ | ||
125 | plat->unicast_filter_entries = 1; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = { | ||
131 | { | ||
132 | .name = "Galileo", | ||
133 | .func = 6, | ||
134 | .phy_addr = 1, | ||
135 | }, | ||
136 | { | ||
137 | .name = "GalileoGen2", | ||
138 | .func = 6, | ||
139 | .phy_addr = 1, | ||
140 | }, | ||
141 | {} | ||
142 | }; | ||
143 | |||
144 | static struct stmmac_pci_info quark_pci_info = { | ||
145 | .setup = quark_default_data, | ||
146 | .dmi = quark_pci_dmi_data, | ||
147 | }; | ||
148 | |||
51 | /** | 149 | /** |
52 | * stmmac_pci_probe | 150 | * stmmac_pci_probe |
53 | * | 151 | * |
@@ -63,6 +161,7 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat) | |||
63 | static int stmmac_pci_probe(struct pci_dev *pdev, | 161 | static int stmmac_pci_probe(struct pci_dev *pdev, |
64 | const struct pci_device_id *id) | 162 | const struct pci_device_id *id) |
65 | { | 163 | { |
164 | struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; | ||
66 | struct plat_stmmacenet_data *plat; | 165 | struct plat_stmmacenet_data *plat; |
67 | struct stmmac_priv *priv; | 166 | struct stmmac_priv *priv; |
68 | int i; | 167 | int i; |
@@ -103,7 +202,17 @@ static int stmmac_pci_probe(struct pci_dev *pdev, | |||
103 | 202 | ||
104 | pci_set_master(pdev); | 203 | pci_set_master(pdev); |
105 | 204 | ||
106 | stmmac_default_data(plat); | 205 | if (info) { |
206 | info->pdev = pdev; | ||
207 | if (info->setup) { | ||
208 | ret = info->setup(plat, info); | ||
209 | if (ret) | ||
210 | return ret; | ||
211 | } | ||
212 | } else | ||
213 | stmmac_default_data(plat); | ||
214 | |||
215 | pci_enable_msi(pdev); | ||
107 | 216 | ||
108 | priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]); | 217 | priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]); |
109 | if (IS_ERR(priv)) { | 218 | if (IS_ERR(priv)) { |
@@ -155,11 +264,13 @@ static int stmmac_pci_resume(struct device *dev) | |||
155 | static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume); | 264 | static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume); |
156 | 265 | ||
157 | #define STMMAC_VENDOR_ID 0x700 | 266 | #define STMMAC_VENDOR_ID 0x700 |
267 | #define STMMAC_QUARK_ID 0x0937 | ||
158 | #define STMMAC_DEVICE_ID 0x1108 | 268 | #define STMMAC_DEVICE_ID 0x1108 |
159 | 269 | ||
160 | static const struct pci_device_id stmmac_id_table[] = { | 270 | static const struct pci_device_id stmmac_id_table[] = { |
161 | {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, | 271 | {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, |
162 | {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, | 272 | {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, |
273 | {PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info}, | ||
163 | {} | 274 | {} |
164 | }; | 275 | }; |
165 | 276 | ||