1 /* SPDX-License-Identifier: BSD-3-Clause
6 #include <rte_ethdev_pci.h>
8 #include "enetc_logs.h"
11 int enetc_logtype_pmd;
13 /* Functions Prototypes */
14 static int enetc_dev_configure(struct rte_eth_dev *dev);
15 static int enetc_dev_start(struct rte_eth_dev *dev);
16 static void enetc_dev_stop(struct rte_eth_dev *dev);
17 static void enetc_dev_close(struct rte_eth_dev *dev);
18 static void enetc_dev_infos_get(struct rte_eth_dev *dev,
19 struct rte_eth_dev_info *dev_info);
20 static int enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
21 static int enetc_hardware_init(struct enetc_eth_hw *hw);
24 * The set of PCI devices this driver supports
26 static const struct rte_pci_id pci_id_enetc_map[] = {
27 { RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID) },
28 { RTE_PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_VF) },
29 { .vendor_id = 0, /* sentinel */ },
32 /* Features supported by this driver */
33 static const struct eth_dev_ops enetc_ops = {
34 .dev_configure = enetc_dev_configure,
35 .dev_start = enetc_dev_start,
36 .dev_stop = enetc_dev_stop,
37 .dev_close = enetc_dev_close,
38 .link_update = enetc_link_update,
39 .dev_infos_get = enetc_dev_infos_get,
43 * Initialisation of the enetc device
46 * - Pointer to the structure rte_eth_dev
50 * - On failure, negative value.
53 enetc_dev_init(struct rte_eth_dev *eth_dev)
56 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
57 struct enetc_eth_hw *hw =
58 ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
60 PMD_INIT_FUNC_TRACE();
61 eth_dev->dev_ops = &enetc_ops;
62 eth_dev->rx_pkt_burst = NULL;
63 eth_dev->tx_pkt_burst = NULL;
65 /* Retrieving and storing the HW base address of device */
66 hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
67 hw->device_id = pci_dev->id.device_id;
69 error = enetc_hardware_init(hw);
71 ENETC_PMD_ERR("Hardware initialization failed");
75 /* Allocate memory for storing MAC addresses */
76 eth_dev->data->mac_addrs = rte_zmalloc("enetc_eth", ETHER_ADDR_LEN, 0);
77 if (!eth_dev->data->mac_addrs) {
78 ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
79 "store MAC addresses",
85 /* Copy the permanent MAC address */
86 ether_addr_copy((struct ether_addr *)hw->mac.addr,
87 ð_dev->data->mac_addrs[0]);
89 ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
90 eth_dev->data->port_id, pci_dev->id.vendor_id,
91 pci_dev->id.device_id);
96 enetc_dev_uninit(struct rte_eth_dev *eth_dev)
98 PMD_INIT_FUNC_TRACE();
99 rte_free(eth_dev->data->mac_addrs);
105 enetc_dev_configure(struct rte_eth_dev *dev __rte_unused)
107 PMD_INIT_FUNC_TRACE();
112 enetc_dev_start(struct rte_eth_dev *dev)
114 struct enetc_eth_hw *hw =
115 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
118 PMD_INIT_FUNC_TRACE();
119 val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
121 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
122 val | ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
125 val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
126 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
133 enetc_dev_stop(struct rte_eth_dev *dev)
135 struct enetc_eth_hw *hw =
136 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
139 PMD_INIT_FUNC_TRACE();
141 val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR));
142 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PMR),
143 val & (~ENETC_PMR_EN));
145 val = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
147 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PM0_CMD_CFG),
148 val & (~(ENETC_PM0_TX_EN | ENETC_PM0_RX_EN)));
152 enetc_dev_close(struct rte_eth_dev *dev __rte_unused)
154 PMD_INIT_FUNC_TRACE();
157 /* return 0 means link status changed, -1 means not changed */
159 enetc_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
161 struct enetc_eth_hw *hw =
162 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
163 struct rte_eth_link link;
166 PMD_INIT_FUNC_TRACE();
168 memset(&link, 0, sizeof(link));
170 status = ENETC_REG_READ(ENETC_GET_HW_ADDR(hw->hw.port,
173 if (status & ENETC_LINK_MODE)
174 link.link_duplex = ETH_LINK_FULL_DUPLEX;
176 link.link_duplex = ETH_LINK_HALF_DUPLEX;
178 if (status & ENETC_LINK_STATUS)
179 link.link_status = ETH_LINK_UP;
181 link.link_status = ETH_LINK_DOWN;
183 switch (status & ENETC_LINK_SPEED_MASK) {
184 case ENETC_LINK_SPEED_1G:
185 link.link_speed = ETH_SPEED_NUM_1G;
188 case ENETC_LINK_SPEED_100M:
189 link.link_speed = ETH_SPEED_NUM_100M;
193 case ENETC_LINK_SPEED_10M:
194 link.link_speed = ETH_SPEED_NUM_10M;
197 return rte_eth_linkstatus_set(dev, &link);
201 enetc_hardware_init(struct enetc_eth_hw *hw)
205 PMD_INIT_FUNC_TRACE();
206 /* Calculating and storing the base HW addresses */
207 hw->hw.port = (void *)((size_t)hw->hw.reg + ENETC_PORT_BASE);
208 hw->hw.global = (void *)((size_t)hw->hw.reg + ENETC_GLOBAL_BASE);
210 /* Enabling Station Interface */
211 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.reg, ENETC_SIMR),
214 /* Setting to accept broadcast packets for each inetrface */
215 psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0) |
216 ENETC_PSIPMR_SET_VLAN_MP(0);
217 psipmr |= ENETC_PSIPMR_SET_UP(1) | ENETC_PSIPMR_SET_MP(1) |
218 ENETC_PSIPMR_SET_VLAN_MP(1);
219 psipmr |= ENETC_PSIPMR_SET_UP(2) | ENETC_PSIPMR_SET_MP(2) |
220 ENETC_PSIPMR_SET_VLAN_MP(2);
222 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMR),
225 /* Enabling broadcast address */
226 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR0(0)),
228 ENETC_REG_WRITE(ENETC_GET_HW_ADDR(hw->hw.port, ENETC_PSIPMAR1(0)),
235 enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
236 struct rte_eth_dev_info *dev_info)
238 PMD_INIT_FUNC_TRACE();
239 dev_info->max_rx_queues = MAX_RX_RINGS;
240 dev_info->max_tx_queues = MAX_TX_RINGS;
241 dev_info->max_rx_pktlen = 1500;
245 enetc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
246 struct rte_pci_device *pci_dev)
248 return rte_eth_dev_pci_generic_probe(pci_dev,
249 sizeof(struct enetc_eth_adapter),
254 enetc_pci_remove(struct rte_pci_device *pci_dev)
256 return rte_eth_dev_pci_generic_remove(pci_dev, enetc_dev_uninit);
259 static struct rte_pci_driver rte_enetc_pmd = {
260 .id_table = pci_id_enetc_map,
261 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
262 .probe = enetc_pci_probe,
263 .remove = enetc_pci_remove,
266 RTE_PMD_REGISTER_PCI(net_enetc, rte_enetc_pmd);
267 RTE_PMD_REGISTER_PCI_TABLE(net_enetc, pci_id_enetc_map);
268 RTE_PMD_REGISTER_KMOD_DEP(net_enetc, "* vfio-pci");
270 RTE_INIT(enetc_pmd_init_log)
272 enetc_logtype_pmd = rte_log_register("pmd.net.enetc");
273 if (enetc_logtype_pmd >= 0)
274 rte_log_set_level(enetc_logtype_pmd, RTE_LOG_NOTICE);