4 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <rte_ethdev.h>
35 #include <rte_malloc.h>
36 #include <rte_memzone.h>
37 #include <rte_string_fns.h>
39 #include <rte_spinlock.h>
42 #include "base/fm10k_api.h"
44 /* Default delay to acquire mailbox lock */
45 #define FM10K_MBXLOCK_DELAY_US 20
47 /* Number of chars per uint32 type */
48 #define CHARS_PER_UINT32 (sizeof(uint32_t))
49 #define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1)
52 fm10k_mbx_initlock(struct fm10k_hw *hw)
54 rte_spinlock_init(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));
58 fm10k_mbx_lock(struct fm10k_hw *hw)
60 while (!rte_spinlock_trylock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back)))
61 rte_delay_us(FM10K_MBXLOCK_DELAY_US);
65 fm10k_mbx_unlock(struct fm10k_hw *hw)
67 rte_spinlock_unlock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));
71 fm10k_dev_configure(struct rte_eth_dev *dev)
73 PMD_INIT_FUNC_TRACE();
75 if (dev->data->dev_conf.rxmode.hw_strip_crc == 0)
76 PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
82 fm10k_link_update(struct rte_eth_dev *dev,
83 __rte_unused int wait_to_complete)
85 PMD_INIT_FUNC_TRACE();
87 /* The host-interface link is always up. The speed is ~50Gbps per Gen3
88 * x8 PCIe interface. For now, we leave the speed undefined since there
89 * is no 50Gbps Ethernet. */
90 dev->data->dev_link.link_speed = 0;
91 dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
92 dev->data->dev_link.link_status = 1;
98 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
100 uint64_t ipackets, opackets, ibytes, obytes;
101 struct fm10k_hw *hw =
102 FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
103 struct fm10k_hw_stats *hw_stats =
104 FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
107 PMD_INIT_FUNC_TRACE();
109 fm10k_update_hw_stats(hw, hw_stats);
111 ipackets = opackets = ibytes = obytes = 0;
112 for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
113 (i < FM10K_MAX_QUEUES_PF); ++i) {
114 stats->q_ipackets[i] = hw_stats->q[i].rx_packets.count;
115 stats->q_opackets[i] = hw_stats->q[i].tx_packets.count;
116 stats->q_ibytes[i] = hw_stats->q[i].rx_bytes.count;
117 stats->q_obytes[i] = hw_stats->q[i].tx_bytes.count;
118 ipackets += stats->q_ipackets[i];
119 opackets += stats->q_opackets[i];
120 ibytes += stats->q_ibytes[i];
121 obytes += stats->q_obytes[i];
123 stats->ipackets = ipackets;
124 stats->opackets = opackets;
125 stats->ibytes = ibytes;
126 stats->obytes = obytes;
130 fm10k_stats_reset(struct rte_eth_dev *dev)
132 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
133 struct fm10k_hw_stats *hw_stats =
134 FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
136 PMD_INIT_FUNC_TRACE();
138 memset(hw_stats, 0, sizeof(*hw_stats));
139 fm10k_rebind_hw_stats(hw, hw_stats);
143 fm10k_dev_infos_get(struct rte_eth_dev *dev,
144 struct rte_eth_dev_info *dev_info)
146 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
148 PMD_INIT_FUNC_TRACE();
150 dev_info->min_rx_bufsize = FM10K_MIN_RX_BUF_SIZE;
151 dev_info->max_rx_pktlen = FM10K_MAX_PKT_SIZE;
152 dev_info->max_rx_queues = hw->mac.max_queues;
153 dev_info->max_tx_queues = hw->mac.max_queues;
154 dev_info->max_mac_addrs = 1;
155 dev_info->max_hash_mac_addrs = 0;
156 dev_info->max_vfs = FM10K_MAX_VF_NUM;
157 dev_info->max_vmdq_pools = ETH_64_POOLS;
158 dev_info->rx_offload_capa =
159 DEV_RX_OFFLOAD_IPV4_CKSUM |
160 DEV_RX_OFFLOAD_UDP_CKSUM |
161 DEV_RX_OFFLOAD_TCP_CKSUM;
162 dev_info->tx_offload_capa = 0;
163 dev_info->reta_size = FM10K_MAX_RSS_INDICES;
165 dev_info->default_rxconf = (struct rte_eth_rxconf) {
167 .pthresh = FM10K_DEFAULT_RX_PTHRESH,
168 .hthresh = FM10K_DEFAULT_RX_HTHRESH,
169 .wthresh = FM10K_DEFAULT_RX_WTHRESH,
171 .rx_free_thresh = FM10K_RX_FREE_THRESH_DEFAULT(0),
175 dev_info->default_txconf = (struct rte_eth_txconf) {
177 .pthresh = FM10K_DEFAULT_TX_PTHRESH,
178 .hthresh = FM10K_DEFAULT_TX_HTHRESH,
179 .wthresh = FM10K_DEFAULT_TX_WTHRESH,
181 .tx_free_thresh = FM10K_TX_FREE_THRESH_DEFAULT(0),
182 .tx_rs_thresh = FM10K_TX_RS_THRESH_DEFAULT(0),
183 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
184 ETH_TXQ_FLAGS_NOOFFLOADS,
190 fm10k_reta_update(struct rte_eth_dev *dev,
191 struct rte_eth_rss_reta_entry64 *reta_conf,
194 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
195 uint16_t i, j, idx, shift;
199 PMD_INIT_FUNC_TRACE();
201 if (reta_size > FM10K_MAX_RSS_INDICES) {
202 PMD_INIT_LOG(ERR, "The size of hash lookup table configured "
203 "(%d) doesn't match the number hardware can supported "
204 "(%d)", reta_size, FM10K_MAX_RSS_INDICES);
209 * Update Redirection Table RETA[n], n=0..31. The redirection table has
210 * 128-entries in 32 registers
212 for (i = 0; i < FM10K_MAX_RSS_INDICES; i += CHARS_PER_UINT32) {
213 idx = i / RTE_RETA_GROUP_SIZE;
214 shift = i % RTE_RETA_GROUP_SIZE;
215 mask = (uint8_t)((reta_conf[idx].mask >> shift) &
216 BIT_MASK_PER_UINT32);
221 if (mask != BIT_MASK_PER_UINT32)
222 reta = FM10K_READ_REG(hw, FM10K_RETA(0, i >> 2));
224 for (j = 0; j < CHARS_PER_UINT32; j++) {
225 if (mask & (0x1 << j)) {
227 reta &= ~(UINT8_MAX << CHAR_BIT * j);
228 reta |= reta_conf[idx].reta[shift + j] <<
232 FM10K_WRITE_REG(hw, FM10K_RETA(0, i >> 2), reta);
239 fm10k_reta_query(struct rte_eth_dev *dev,
240 struct rte_eth_rss_reta_entry64 *reta_conf,
243 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
244 uint16_t i, j, idx, shift;
248 PMD_INIT_FUNC_TRACE();
250 if (reta_size < FM10K_MAX_RSS_INDICES) {
251 PMD_INIT_LOG(ERR, "The size of hash lookup table configured "
252 "(%d) doesn't match the number hardware can supported "
253 "(%d)", reta_size, FM10K_MAX_RSS_INDICES);
258 * Read Redirection Table RETA[n], n=0..31. The redirection table has
259 * 128-entries in 32 registers
261 for (i = 0; i < FM10K_MAX_RSS_INDICES; i += CHARS_PER_UINT32) {
262 idx = i / RTE_RETA_GROUP_SIZE;
263 shift = i % RTE_RETA_GROUP_SIZE;
264 mask = (uint8_t)((reta_conf[idx].mask >> shift) &
265 BIT_MASK_PER_UINT32);
269 reta = FM10K_READ_REG(hw, FM10K_RETA(0, i >> 2));
270 for (j = 0; j < CHARS_PER_UINT32; j++) {
271 if (mask & (0x1 << j))
272 reta_conf[idx].reta[shift + j] = ((reta >>
273 CHAR_BIT * j) & UINT8_MAX);
280 /* Mailbox message handler in VF */
281 static const struct fm10k_msg_data fm10k_msgdata_vf[] = {
282 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
283 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
284 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
285 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
288 /* Mailbox message handler in PF */
289 static const struct fm10k_msg_data fm10k_msgdata_pf[] = {
290 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
291 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
292 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
293 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
294 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
295 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
296 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
300 fm10k_setup_mbx_service(struct fm10k_hw *hw)
304 /* Initialize mailbox lock */
305 fm10k_mbx_initlock(hw);
307 /* Replace default message handler with new ones */
308 if (hw->mac.type == fm10k_mac_pf)
309 err = hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_pf);
311 err = hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_vf);
314 PMD_INIT_LOG(ERR, "Failed to register mailbox handler.err:%d",
318 /* Connect to SM for PF device or PF for VF device */
319 return hw->mbx.ops.connect(hw, &hw->mbx);
322 static struct eth_dev_ops fm10k_eth_dev_ops = {
323 .dev_configure = fm10k_dev_configure,
324 .stats_get = fm10k_stats_get,
325 .stats_reset = fm10k_stats_reset,
326 .link_update = fm10k_link_update,
327 .dev_infos_get = fm10k_dev_infos_get,
328 .reta_update = fm10k_reta_update,
329 .reta_query = fm10k_reta_query,
333 eth_fm10k_dev_init(__rte_unused struct eth_driver *eth_drv,
334 struct rte_eth_dev *dev)
336 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
339 PMD_INIT_FUNC_TRACE();
341 dev->dev_ops = &fm10k_eth_dev_ops;
343 /* only initialize in the primary process */
344 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
347 /* Vendor and Device ID need to be set before init of shared code */
348 memset(hw, 0, sizeof(*hw));
349 hw->device_id = dev->pci_dev->id.device_id;
350 hw->vendor_id = dev->pci_dev->id.vendor_id;
351 hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
352 hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
354 hw->hw_addr = (void *)dev->pci_dev->mem_resource[0].addr;
355 if (hw->hw_addr == NULL) {
356 PMD_INIT_LOG(ERR, "Bad mem resource."
357 " Try to blacklist unused devices.");
361 /* Store fm10k_adapter pointer */
362 hw->back = dev->data->dev_private;
364 /* Initialize the shared code */
365 diag = fm10k_init_shared_code(hw);
366 if (diag != FM10K_SUCCESS) {
367 PMD_INIT_LOG(ERR, "Shared code init failed: %d", diag);
372 * Inialize bus info. Normally we would call fm10k_get_bus_info(), but
373 * there is no way to get link status without reading BAR4. Until this
374 * works, assume we have maximum bandwidth.
375 * @todo - fix bus info
377 hw->bus_caps.speed = fm10k_bus_speed_8000;
378 hw->bus_caps.width = fm10k_bus_width_pcie_x8;
379 hw->bus_caps.payload = fm10k_bus_payload_512;
380 hw->bus.speed = fm10k_bus_speed_8000;
381 hw->bus.width = fm10k_bus_width_pcie_x8;
382 hw->bus.payload = fm10k_bus_payload_256;
384 /* Initialize the hw */
385 diag = fm10k_init_hw(hw);
386 if (diag != FM10K_SUCCESS) {
387 PMD_INIT_LOG(ERR, "Hardware init failed: %d", diag);
391 /* Initialize MAC address(es) */
392 dev->data->mac_addrs = rte_zmalloc("fm10k", ETHER_ADDR_LEN, 0);
393 if (dev->data->mac_addrs == NULL) {
394 PMD_INIT_LOG(ERR, "Cannot allocate memory for MAC addresses");
398 diag = fm10k_read_mac_addr(hw);
399 if (diag != FM10K_SUCCESS) {
401 * TODO: remove special handling on VF. Need shared code to
404 if (hw->mac.type == fm10k_mac_pf) {
405 PMD_INIT_LOG(ERR, "Read MAC addr failed: %d", diag);
408 /* Generate a random addr */
409 eth_random_addr(hw->mac.addr);
410 memcpy(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN);
414 ether_addr_copy((const struct ether_addr *)hw->mac.addr,
415 &dev->data->mac_addrs[0]);
417 /* Reset the hw statistics */
418 fm10k_stats_reset(dev);
421 diag = fm10k_reset_hw(hw);
422 if (diag != FM10K_SUCCESS) {
423 PMD_INIT_LOG(ERR, "Hardware reset failed: %d", diag);
427 /* Setup mailbox service */
428 diag = fm10k_setup_mbx_service(hw);
429 if (diag != FM10K_SUCCESS) {
430 PMD_INIT_LOG(ERR, "Failed to setup mailbox: %d", diag);
435 * Below function will trigger operations on mailbox, acquire lock to
436 * avoid race condition from interrupt handler. Operations on mailbox
437 * FIFO will trigger interrupt to PF/SM, in which interrupt handler
438 * will handle and generate an interrupt to our side. Then, FIFO in
439 * mailbox will be touched.
442 /* Enable port first */
443 hw->mac.ops.update_lport_state(hw, 0, 0, 1);
445 /* Update default vlan */
446 hw->mac.ops.update_vlan(hw, hw->mac.default_vid, 0, true);
449 * Add default mac/vlan filter. glort is assigned by SM for PF, while is
450 * unused for VF. PF will assign correct glort for VF.
452 hw->mac.ops.update_uc_addr(hw, hw->mac.dglort_map, hw->mac.addr,
453 hw->mac.default_vid, 1, 0);
455 /* Set unicast mode by default. App can change to other mode in other
458 hw->mac.ops.update_xcast_mode(hw, hw->mac.dglort_map,
459 FM10K_XCAST_MODE_MULTI);
461 fm10k_mbx_unlock(hw);
467 * The set of PCI devices this driver supports. This driver will enable both PF
468 * and SRIOV-VF devices.
470 static struct rte_pci_id pci_id_fm10k_map[] = {
471 #define RTE_PCI_DEV_ID_DECL_FM10K(vend, dev) { RTE_PCI_DEVICE(vend, dev) },
472 #include "rte_pci_dev_ids.h"
473 { .vendor_id = 0, /* sentinel */ },
476 static struct eth_driver rte_pmd_fm10k = {
478 .name = "rte_pmd_fm10k",
479 .id_table = pci_id_fm10k_map,
480 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
482 .eth_dev_init = eth_fm10k_dev_init,
483 .dev_private_size = sizeof(struct fm10k_adapter),
487 * Driver initialization routine.
488 * Invoked once at EAL init time.
489 * Register itself as the [Poll Mode] Driver of PCI FM10K devices.
492 rte_pmd_fm10k_init(__rte_unused const char *name,
493 __rte_unused const char *params)
495 PMD_INIT_FUNC_TRACE();
496 rte_eth_driver_register(&rte_pmd_fm10k);
500 static struct rte_driver rte_fm10k_driver = {
502 .init = rte_pmd_fm10k_init,
505 PMD_REGISTER_DRIVER(rte_fm10k_driver);