Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+112 -1
+112 -1
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
··· 24 24 *******************************************************************************/ 25 25 26 26 #include <linux/pci.h> 27 + #include <linux/dmi.h> 28 + 27 29 #include "stmmac.h" 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 + } 28 70 29 71 static void stmmac_default_data(struct plat_stmmacenet_data *plat) 30 72 { ··· 90 48 plat->unicast_filter_entries = 1; 91 49 } 92 50 51 + static int quark_default_data(struct plat_stmmacenet_data *plat, 52 + struct stmmac_pci_info *info) 53 + { 54 + struct pci_dev *pdev = info->pdev; 55 + int ret; 56 + 57 + /* 58 + * Refuse to load the driver and register net device if MAC controller 59 + * does not connect to any PHY interface. 60 + */ 61 + ret = stmmac_pci_find_phy_addr(info); 62 + if (ret < 0) 63 + return ret; 64 + 65 + plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn); 66 + plat->phy_addr = ret; 67 + plat->interface = PHY_INTERFACE_MODE_RMII; 68 + plat->clk_csr = 2; 69 + plat->has_gmac = 1; 70 + plat->force_sf_dma_mode = 1; 71 + 72 + plat->mdio_bus_data->phy_reset = NULL; 73 + plat->mdio_bus_data->phy_mask = 0; 74 + 75 + plat->dma_cfg->pbl = 16; 76 + plat->dma_cfg->burst_len = DMA_AXI_BLEN_256; 77 + plat->dma_cfg->fixed_burst = 1; 78 + 79 + /* Set default value for multicast hash bins */ 80 + plat->multicast_filter_bins = HASH_TABLE_SIZE; 81 + 82 + /* Set default value for unicast filter entries */ 83 + plat->unicast_filter_entries = 1; 84 + 85 + return 0; 86 + } 87 + 88 + static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = { 89 + { 90 + .name = "Galileo", 91 + .func = 6, 92 + .phy_addr = 1, 93 + }, 94 + { 95 + .name = "GalileoGen2", 96 + .func = 6, 97 + .phy_addr = 1, 98 + }, 99 + {} 100 + }; 101 + 102 + static struct stmmac_pci_info quark_pci_info = { 103 + .setup = quark_default_data, 104 + .dmi = quark_pci_dmi_data, 105 + }; 106 + 93 107 /** 94 108 * stmmac_pci_probe 95 109 * ··· 161 63 static int stmmac_pci_probe(struct pci_dev *pdev, 162 64 const struct pci_device_id *id) 163 65 { 66 + struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; 164 67 struct plat_stmmacenet_data *plat; 165 68 struct stmmac_priv *priv; 166 69 int i; ··· 202 103 203 104 pci_set_master(pdev); 204 105 205 - stmmac_default_data(plat); 106 + if (info) { 107 + info->pdev = pdev; 108 + if (info->setup) { 109 + ret = info->setup(plat, info); 110 + if (ret) 111 + return ret; 112 + } 113 + } else 114 + stmmac_default_data(plat); 115 + 116 + pci_enable_msi(pdev); 206 117 207 118 priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]); 208 119 if (IS_ERR(priv)) { ··· 264 155 static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume); 265 156 266 157 #define STMMAC_VENDOR_ID 0x700 158 + #define STMMAC_QUARK_ID 0x0937 267 159 #define STMMAC_DEVICE_ID 0x1108 268 160 269 161 static const struct pci_device_id stmmac_id_table[] = { 270 162 {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, 271 163 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, 164 + {PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info}, 272 165 {} 273 166 }; 274 167