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

net: dsa: felix: move probing to felix_vsc9959.c

Felix is not actually meant to be a DSA driver only for the switch
inside NXP LS1028A, but an umbrella for all Vitesse / Microsemi /
Microchip switches that are register-compatible with Ocelot and that are
using in DSA mode (with an NPI Ethernet port).

For the dsa_switch_ops exported by the felix driver to be generic enough
to be used by other non-PCI switches, we need to move the PCI-specific
probing to the low-level translation module felix_vsc9959.c. This way,
other switches can have their own probing functions, as platform devices
or otherwise.

This patch also removes the "Felix instance table", which did not stand
the test of time and is unnecessary at this point.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vladimir Oltean and committed by
David S. Miller
375e1314 aa92d836

+206 -191
+18 -177
drivers/net/dsa/ocelot/felix.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright 2019 NXP Semiconductors 3 + * 4 + * This is an umbrella module for all network switches that are 5 + * register-compatible with Ocelot and that perform I/O to their host CPU 6 + * through an NPI (Node Processor Interface) Ethernet port. 3 7 */ 4 8 #include <uapi/linux/if_bridge.h> 5 9 #include <soc/mscc/ocelot_vcap.h> ··· 189 185 struct phylink_link_state *state) 190 186 { 191 187 struct ocelot *ocelot = ds->priv; 192 - struct ocelot_port *ocelot_port = ocelot->ports[port]; 193 - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 188 + struct felix *felix = ocelot_to_felix(ocelot); 194 189 195 - if (state->interface != PHY_INTERFACE_MODE_NA && 196 - state->interface != ocelot_port->phy_mode) { 197 - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); 198 - return; 199 - } 200 - 201 - phylink_set_port_modes(mask); 202 - phylink_set(mask, Autoneg); 203 - phylink_set(mask, Pause); 204 - phylink_set(mask, Asym_Pause); 205 - phylink_set(mask, 10baseT_Half); 206 - phylink_set(mask, 10baseT_Full); 207 - phylink_set(mask, 100baseT_Half); 208 - phylink_set(mask, 100baseT_Full); 209 - phylink_set(mask, 1000baseT_Half); 210 - phylink_set(mask, 1000baseT_Full); 211 - 212 - if (state->interface == PHY_INTERFACE_MODE_INTERNAL || 213 - state->interface == PHY_INTERFACE_MODE_2500BASEX || 214 - state->interface == PHY_INTERFACE_MODE_USXGMII) { 215 - phylink_set(mask, 2500baseT_Full); 216 - phylink_set(mask, 2500baseX_Full); 217 - } 218 - 219 - bitmap_and(supported, supported, mask, 220 - __ETHTOOL_LINK_MODE_MASK_NBITS); 221 - bitmap_and(state->advertising, state->advertising, mask, 222 - __ETHTOOL_LINK_MODE_MASK_NBITS); 190 + if (felix->info->phylink_validate) 191 + felix->info->phylink_validate(ocelot, port, supported, state); 223 192 } 224 193 225 194 static int felix_phylink_mac_pcs_get_state(struct dsa_switch *ds, int port, ··· 433 456 { 434 457 struct ocelot *ocelot = &felix->ocelot; 435 458 phy_interface_t *port_phy_modes; 436 - resource_size_t switch_base; 437 459 struct resource res; 438 460 int port, i, err; 439 461 ··· 463 487 return err; 464 488 } 465 489 466 - switch_base = pci_resource_start(felix->pdev, 467 - felix->info->switch_pci_bar); 468 - 469 490 for (i = 0; i < TARGET_MAX; i++) { 470 491 struct regmap *target; 471 492 ··· 471 498 472 499 memcpy(&res, &felix->info->target_io_res[i], sizeof(res)); 473 500 res.flags = IORESOURCE_MEM; 474 - res.start += switch_base; 475 - res.end += switch_base; 501 + res.start += felix->switch_base; 502 + res.end += felix->switch_base; 476 503 477 504 target = ocelot_regmap_init(ocelot, &res); 478 505 if (IS_ERR(target)) { ··· 509 536 510 537 memcpy(&res, &felix->info->port_io_res[port], sizeof(res)); 511 538 res.flags = IORESOURCE_MEM; 512 - res.start += switch_base; 513 - res.end += switch_base; 539 + res.start += felix->switch_base; 540 + res.end += felix->switch_base; 514 541 515 542 target = ocelot_regmap_init(ocelot, &res); 516 543 if (IS_ERR(target)) { ··· 775 802 return -EOPNOTSUPP; 776 803 } 777 804 778 - static const struct dsa_switch_ops felix_switch_ops = { 805 + const struct dsa_switch_ops felix_switch_ops = { 779 806 .get_tag_protocol = felix_get_tag_protocol, 780 807 .setup = felix_setup, 781 808 .teardown = felix_teardown, ··· 818 845 .port_setup_tc = felix_port_setup_tc, 819 846 }; 820 847 821 - static struct felix_info *felix_instance_tbl[] = { 822 - [FELIX_INSTANCE_VSC9959] = &felix_info_vsc9959, 823 - }; 824 - 825 - static irqreturn_t felix_irq_handler(int irq, void *data) 848 + static int __init felix_init(void) 826 849 { 827 - struct ocelot *ocelot = (struct ocelot *)data; 828 - 829 - /* The INTB interrupt is used for both PTP TX timestamp interrupt 830 - * and preemption status change interrupt on each port. 831 - * 832 - * - Get txtstamp if have 833 - * - TODO: handle preemption. Without handling it, driver may get 834 - * interrupt storm. 835 - */ 836 - 837 - ocelot_get_txtstamp(ocelot); 838 - 839 - return IRQ_HANDLED; 850 + return pci_register_driver(&felix_vsc9959_pci_driver); 840 851 } 852 + module_init(felix_init); 841 853 842 - static int felix_pci_probe(struct pci_dev *pdev, 843 - const struct pci_device_id *id) 854 + static void __exit felix_exit(void) 844 855 { 845 - enum felix_instance instance = id->driver_data; 846 - struct dsa_switch *ds; 847 - struct ocelot *ocelot; 848 - struct felix *felix; 849 - int err; 850 - 851 - if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { 852 - dev_info(&pdev->dev, "device is disabled, skipping\n"); 853 - return -ENODEV; 854 - } 855 - 856 - err = pci_enable_device(pdev); 857 - if (err) { 858 - dev_err(&pdev->dev, "device enable failed\n"); 859 - goto err_pci_enable; 860 - } 861 - 862 - /* set up for high or low dma */ 863 - err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 864 - if (err) { 865 - err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 866 - if (err) { 867 - dev_err(&pdev->dev, 868 - "DMA configuration failed: 0x%x\n", err); 869 - goto err_dma; 870 - } 871 - } 872 - 873 - felix = kzalloc(sizeof(struct felix), GFP_KERNEL); 874 - if (!felix) { 875 - err = -ENOMEM; 876 - dev_err(&pdev->dev, "Failed to allocate driver memory\n"); 877 - goto err_alloc_felix; 878 - } 879 - 880 - pci_set_drvdata(pdev, felix); 881 - ocelot = &felix->ocelot; 882 - ocelot->dev = &pdev->dev; 883 - felix->pdev = pdev; 884 - felix->info = felix_instance_tbl[instance]; 885 - 886 - pci_set_master(pdev); 887 - 888 - err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL, 889 - &felix_irq_handler, IRQF_ONESHOT, 890 - "felix-intb", ocelot); 891 - if (err) { 892 - dev_err(&pdev->dev, "Failed to request irq\n"); 893 - goto err_alloc_irq; 894 - } 895 - 896 - ocelot->ptp = 1; 897 - 898 - ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); 899 - if (!ds) { 900 - err = -ENOMEM; 901 - dev_err(&pdev->dev, "Failed to allocate DSA switch\n"); 902 - goto err_alloc_ds; 903 - } 904 - 905 - ds->dev = &pdev->dev; 906 - ds->num_ports = felix->info->num_ports; 907 - ds->num_tx_queues = felix->info->num_tx_queues; 908 - ds->ops = &felix_switch_ops; 909 - ds->priv = ocelot; 910 - felix->ds = ds; 911 - 912 - err = dsa_register_switch(ds); 913 - if (err) { 914 - dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err); 915 - goto err_register_ds; 916 - } 917 - 918 - return 0; 919 - 920 - err_register_ds: 921 - kfree(ds); 922 - err_alloc_ds: 923 - err_alloc_irq: 924 - err_alloc_felix: 925 - kfree(felix); 926 - err_dma: 927 - pci_disable_device(pdev); 928 - err_pci_enable: 929 - return err; 856 + pci_unregister_driver(&felix_vsc9959_pci_driver); 930 857 } 931 - 932 - static void felix_pci_remove(struct pci_dev *pdev) 933 - { 934 - struct felix *felix; 935 - 936 - felix = pci_get_drvdata(pdev); 937 - 938 - dsa_unregister_switch(felix->ds); 939 - 940 - kfree(felix->ds); 941 - kfree(felix); 942 - 943 - pci_disable_device(pdev); 944 - } 945 - 946 - static struct pci_device_id felix_ids[] = { 947 - { 948 - /* NXP LS1028A */ 949 - PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0), 950 - .driver_data = FELIX_INSTANCE_VSC9959, 951 - }, 952 - { 0, } 953 - }; 954 - MODULE_DEVICE_TABLE(pci, felix_ids); 955 - 956 - static struct pci_driver felix_pci_driver = { 957 - .name = KBUILD_MODNAME, 958 - .id_table = felix_ids, 959 - .probe = felix_pci_probe, 960 - .remove = felix_pci_remove, 961 - }; 962 - 963 - module_pci_driver(felix_pci_driver); 858 + module_exit(felix_exit); 964 859 965 860 MODULE_DESCRIPTION("Felix Switch driver"); 966 861 MODULE_LICENSE("GPL v2");
+8 -7
drivers/net/dsa/ocelot/felix.h
··· 37 37 int speed, int duplex); 38 38 void (*pcs_link_state)(struct ocelot *ocelot, int port, 39 39 struct phylink_link_state *state); 40 + void (*phylink_validate)(struct ocelot *ocelot, int port, 41 + unsigned long *supported, 42 + struct phylink_link_state *state); 40 43 int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port, 41 44 phy_interface_t phy_mode); 42 45 int (*port_setup_tc)(struct dsa_switch *ds, int port, ··· 49 46 void (*xmit_template_populate)(struct ocelot *ocelot, int port); 50 47 }; 51 48 52 - extern struct felix_info felix_info_vsc9959; 53 - 54 - enum felix_instance { 55 - FELIX_INSTANCE_VSC9959 = 0, 56 - }; 49 + extern const struct dsa_switch_ops felix_switch_ops; 50 + extern struct pci_driver felix_vsc9959_pci_driver; 57 51 58 52 /* DSA glue / front-end for struct ocelot */ 59 53 struct felix { 60 54 struct dsa_switch *ds; 61 - struct pci_dev *pdev; 62 - struct felix_info *info; 55 + const struct felix_info *info; 63 56 struct ocelot ocelot; 64 57 struct mii_bus *imdio; 65 58 struct phy_device **pcs; 59 + resource_size_t switch_base; 60 + resource_size_t imdio_base; 66 61 }; 67 62 68 63 #endif
+180 -7
drivers/net/dsa/ocelot/felix_vsc9959.c
··· 1128 1128 vsc9959_pcs_link_state_resolve(pcs, state); 1129 1129 } 1130 1130 1131 + static void vsc9959_phylink_validate(struct ocelot *ocelot, int port, 1132 + unsigned long *supported, 1133 + struct phylink_link_state *state) 1134 + { 1135 + struct ocelot_port *ocelot_port = ocelot->ports[port]; 1136 + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 1137 + 1138 + if (state->interface != PHY_INTERFACE_MODE_NA && 1139 + state->interface != ocelot_port->phy_mode) { 1140 + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); 1141 + return; 1142 + } 1143 + 1144 + phylink_set_port_modes(mask); 1145 + phylink_set(mask, Autoneg); 1146 + phylink_set(mask, Pause); 1147 + phylink_set(mask, Asym_Pause); 1148 + phylink_set(mask, 10baseT_Half); 1149 + phylink_set(mask, 10baseT_Full); 1150 + phylink_set(mask, 100baseT_Half); 1151 + phylink_set(mask, 100baseT_Full); 1152 + phylink_set(mask, 1000baseT_Half); 1153 + phylink_set(mask, 1000baseT_Full); 1154 + 1155 + if (state->interface == PHY_INTERFACE_MODE_INTERNAL || 1156 + state->interface == PHY_INTERFACE_MODE_2500BASEX || 1157 + state->interface == PHY_INTERFACE_MODE_USXGMII) { 1158 + phylink_set(mask, 2500baseT_Full); 1159 + phylink_set(mask, 2500baseX_Full); 1160 + } 1161 + 1162 + bitmap_and(supported, supported, mask, 1163 + __ETHTOOL_LINK_MODE_MASK_NBITS); 1164 + bitmap_and(state->advertising, state->advertising, mask, 1165 + __ETHTOOL_LINK_MODE_MASK_NBITS); 1166 + } 1167 + 1131 1168 static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port, 1132 1169 phy_interface_t phy_mode) 1133 1170 { ··· 1208 1171 struct felix *felix = ocelot_to_felix(ocelot); 1209 1172 struct enetc_mdio_priv *mdio_priv; 1210 1173 struct device *dev = ocelot->dev; 1211 - resource_size_t imdio_base; 1212 1174 void __iomem *imdio_regs; 1213 1175 struct resource res; 1214 1176 struct enetc_hw *hw; ··· 1223 1187 return -ENOMEM; 1224 1188 } 1225 1189 1226 - imdio_base = pci_resource_start(felix->pdev, 1227 - felix->info->imdio_pci_bar); 1228 - 1229 1190 memcpy(&res, felix->info->imdio_res, sizeof(res)); 1230 1191 res.flags = IORESOURCE_MEM; 1231 - res.start += imdio_base; 1232 - res.end += imdio_base; 1192 + res.start += felix->imdio_base; 1193 + res.end += felix->imdio_base; 1233 1194 1234 1195 imdio_regs = devm_ioremap_resource(dev, &res); 1235 1196 if (IS_ERR(imdio_regs)) { ··· 1500 1467 packing(template, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); 1501 1468 } 1502 1469 1503 - struct felix_info felix_info_vsc9959 = { 1470 + static const struct felix_info felix_info_vsc9959 = { 1504 1471 .target_io_res = vsc9959_target_io_res, 1505 1472 .port_io_res = vsc9959_port_io_res, 1506 1473 .imdio_res = &vsc9959_imdio_res, ··· 1523 1490 .pcs_config = vsc9959_pcs_config, 1524 1491 .pcs_link_up = vsc9959_pcs_link_up, 1525 1492 .pcs_link_state = vsc9959_pcs_link_state, 1493 + .phylink_validate = vsc9959_phylink_validate, 1526 1494 .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, 1527 1495 .port_setup_tc = vsc9959_port_setup_tc, 1528 1496 .port_sched_speed_set = vsc9959_sched_speed_set, 1529 1497 .xmit_template_populate = vsc9959_xmit_template_populate, 1498 + }; 1499 + 1500 + static irqreturn_t felix_irq_handler(int irq, void *data) 1501 + { 1502 + struct ocelot *ocelot = (struct ocelot *)data; 1503 + 1504 + /* The INTB interrupt is used for both PTP TX timestamp interrupt 1505 + * and preemption status change interrupt on each port. 1506 + * 1507 + * - Get txtstamp if have 1508 + * - TODO: handle preemption. Without handling it, driver may get 1509 + * interrupt storm. 1510 + */ 1511 + 1512 + ocelot_get_txtstamp(ocelot); 1513 + 1514 + return IRQ_HANDLED; 1515 + } 1516 + 1517 + static int felix_pci_probe(struct pci_dev *pdev, 1518 + const struct pci_device_id *id) 1519 + { 1520 + struct dsa_switch *ds; 1521 + struct ocelot *ocelot; 1522 + struct felix *felix; 1523 + int err; 1524 + 1525 + if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { 1526 + dev_info(&pdev->dev, "device is disabled, skipping\n"); 1527 + return -ENODEV; 1528 + } 1529 + 1530 + err = pci_enable_device(pdev); 1531 + if (err) { 1532 + dev_err(&pdev->dev, "device enable failed\n"); 1533 + goto err_pci_enable; 1534 + } 1535 + 1536 + /* set up for high or low dma */ 1537 + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 1538 + if (err) { 1539 + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 1540 + if (err) { 1541 + dev_err(&pdev->dev, 1542 + "DMA configuration failed: 0x%x\n", err); 1543 + goto err_dma; 1544 + } 1545 + } 1546 + 1547 + felix = kzalloc(sizeof(struct felix), GFP_KERNEL); 1548 + if (!felix) { 1549 + err = -ENOMEM; 1550 + dev_err(&pdev->dev, "Failed to allocate driver memory\n"); 1551 + goto err_alloc_felix; 1552 + } 1553 + 1554 + pci_set_drvdata(pdev, felix); 1555 + ocelot = &felix->ocelot; 1556 + ocelot->dev = &pdev->dev; 1557 + felix->info = &felix_info_vsc9959; 1558 + felix->switch_base = pci_resource_start(pdev, 1559 + felix->info->switch_pci_bar); 1560 + felix->imdio_base = pci_resource_start(pdev, 1561 + felix->info->imdio_pci_bar); 1562 + 1563 + pci_set_master(pdev); 1564 + 1565 + err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL, 1566 + &felix_irq_handler, IRQF_ONESHOT, 1567 + "felix-intb", ocelot); 1568 + if (err) { 1569 + dev_err(&pdev->dev, "Failed to request irq\n"); 1570 + goto err_alloc_irq; 1571 + } 1572 + 1573 + ocelot->ptp = 1; 1574 + 1575 + ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); 1576 + if (!ds) { 1577 + err = -ENOMEM; 1578 + dev_err(&pdev->dev, "Failed to allocate DSA switch\n"); 1579 + goto err_alloc_ds; 1580 + } 1581 + 1582 + ds->dev = &pdev->dev; 1583 + ds->num_ports = felix->info->num_ports; 1584 + ds->num_tx_queues = felix->info->num_tx_queues; 1585 + ds->ops = &felix_switch_ops; 1586 + ds->priv = ocelot; 1587 + felix->ds = ds; 1588 + 1589 + err = dsa_register_switch(ds); 1590 + if (err) { 1591 + dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err); 1592 + goto err_register_ds; 1593 + } 1594 + 1595 + return 0; 1596 + 1597 + err_register_ds: 1598 + kfree(ds); 1599 + err_alloc_ds: 1600 + err_alloc_irq: 1601 + err_alloc_felix: 1602 + kfree(felix); 1603 + err_dma: 1604 + pci_disable_device(pdev); 1605 + err_pci_enable: 1606 + return err; 1607 + } 1608 + 1609 + static void felix_pci_remove(struct pci_dev *pdev) 1610 + { 1611 + struct felix *felix; 1612 + 1613 + felix = pci_get_drvdata(pdev); 1614 + 1615 + dsa_unregister_switch(felix->ds); 1616 + 1617 + kfree(felix->ds); 1618 + kfree(felix); 1619 + 1620 + pci_disable_device(pdev); 1621 + } 1622 + 1623 + static struct pci_device_id felix_ids[] = { 1624 + { 1625 + /* NXP LS1028A */ 1626 + PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0), 1627 + }, 1628 + { 0, } 1629 + }; 1630 + MODULE_DEVICE_TABLE(pci, felix_ids); 1631 + 1632 + struct pci_driver felix_vsc9959_pci_driver = { 1633 + .name = "mscc_felix", 1634 + .id_table = felix_ids, 1635 + .probe = felix_pci_probe, 1636 + .remove = felix_pci_remove, 1530 1637 };