X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fipn3ke%2Fipn3ke_ethdev.c;h=af87fda6bc81a1c3fc26aadadc99e1bd7305a6aa;hb=d28ae28eb7cc1f58984a792ff352c1ed888c4523;hp=d5fee6f126cee754f4d0e4e2043ea8db0db59c9a;hpb=c01c748e4ae6db0baeb73dd1d780320d431fe6d6;p=dpdk.git diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c index d5fee6f126..af87fda6bc 100644 --- a/drivers/net/ipn3ke/ipn3ke_ethdev.c +++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c @@ -21,6 +21,7 @@ #include #include "ipn3ke_rawdev_api.h" +#include "ipn3ke_flow.h" #include "ipn3ke_logs.h" #include "ipn3ke_ethdev.h" @@ -47,7 +48,6 @@ ipn3ke_indirect_read(struct ipn3ke_hw *hw, uint32_t *rd_data, if (eth_group_sel != 0 && eth_group_sel != 1) return -1; - addr &= 0x3FF; target_addr = addr | dev_sel << 17; indirect_value = RCMD | target_addr << 32; @@ -85,7 +85,6 @@ ipn3ke_indirect_write(struct ipn3ke_hw *hw, uint32_t wr_data, if (eth_group_sel != 0 && eth_group_sel != 1) return -1; - addr &= 0x3FF; target_addr = addr | dev_sel << 17; indirect_value = WCMD | target_addr << 32 | wr_data; @@ -190,6 +189,109 @@ ipn3ke_hw_cap_init(struct ipn3ke_hw *hw) 0, 0xFFFFF); } +static int +ipn3ke_vbng_init_done(struct ipn3ke_hw *hw) +{ + uint32_t timeout = 10000; + while (timeout > 0) { + if (IPN3KE_READ_REG(hw, IPN3KE_VBNG_INIT_STS) + == IPN3KE_VBNG_INIT_DONE) + break; + rte_delay_us(1000); + timeout--; + } + + if (!timeout) { + IPN3KE_AFU_PMD_ERR("IPN3KE vBNG INIT timeout.\n"); + return -1; + } + + return 0; +} + +static uint32_t +ipn3ke_mtu_cal(uint32_t tx, uint32_t rx) +{ + uint32_t tmp; + tmp = RTE_MIN(tx, rx); + tmp = RTE_MAX(tmp, (uint32_t)RTE_ETHER_MIN_MTU); + tmp = RTE_MIN(tmp, (uint32_t)(IPN3KE_MAC_FRAME_SIZE_MAX - + IPN3KE_ETH_OVERHEAD)); + return tmp; +} + +static void +ipn3ke_mtu_set(struct ipn3ke_hw *hw, uint32_t mac_num, + uint32_t eth_group_sel, uint32_t txaddr, uint32_t rxaddr) +{ + uint32_t tx; + uint32_t rx; + uint32_t tmp; + + if (!(*hw->f_mac_read) || !(*hw->f_mac_write)) + return; + + (*hw->f_mac_read)(hw, + &tx, + txaddr, + mac_num, + eth_group_sel); + + (*hw->f_mac_read)(hw, + &rx, + rxaddr, + mac_num, + eth_group_sel); + + tmp = ipn3ke_mtu_cal(tx, rx); + + (*hw->f_mac_write)(hw, + tmp, + txaddr, + mac_num, + eth_group_sel); + + (*hw->f_mac_write)(hw, + tmp, + rxaddr, + mac_num, + eth_group_sel); +} + +static void +ipn3ke_10G_mtu_setup(struct ipn3ke_hw *hw, uint32_t mac_num, + uint32_t eth_group_sel) +{ + ipn3ke_mtu_set(hw, mac_num, eth_group_sel, + IPN3KE_10G_TX_FRAME_MAXLENGTH, IPN3KE_10G_RX_FRAME_MAXLENGTH); +} + +static void +ipn3ke_25G_mtu_setup(struct ipn3ke_hw *hw, uint32_t mac_num, + uint32_t eth_group_sel) +{ + ipn3ke_mtu_set(hw, mac_num, eth_group_sel, + IPN3KE_25G_MAX_TX_SIZE_CONFIG, IPN3KE_25G_MAX_RX_SIZE_CONFIG); +} + +static void +ipn3ke_mtu_setup(struct ipn3ke_hw *hw) +{ + int i; + if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) { + for (i = 0; i < hw->port_num; i++) { + ipn3ke_10G_mtu_setup(hw, i, 0); + ipn3ke_10G_mtu_setup(hw, i, 1); + } + } else if (hw->retimer.mac_type == + IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI) { + for (i = 0; i < hw->port_num; i++) { + ipn3ke_25G_mtu_setup(hw, i, 0); + ipn3ke_25G_mtu_setup(hw, i, 1); + } + } +} + static int ipn3ke_hw_init(struct rte_afu_device *afu_dev, struct ipn3ke_hw *hw) @@ -222,15 +324,24 @@ ipn3ke_hw_init(struct rte_afu_device *afu_dev, "LineSideMACType", &mac_type); hw->retimer.mac_type = (int)mac_type; + IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0)); + if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW && afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) { + /* After power on, wait until init done */ + if (ipn3ke_vbng_init_done(hw)) + return -1; + ipn3ke_hw_cap_init(hw); - IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", - IPN3KE_READ_REG(hw, 0)); - /* Reset FPGA IP */ + /* Reset vBNG IP */ IPN3KE_WRITE_REG(hw, IPN3KE_CTRL_RESET, 1); + rte_delay_us(10); IPN3KE_WRITE_REG(hw, IPN3KE_CTRL_RESET, 0); + + /* After reset, wait until init done */ + if (ipn3ke_vbng_init_done(hw)) + return -1; } if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) { @@ -245,14 +356,39 @@ ipn3ke_hw_init(struct rte_afu_device *afu_dev, /* Enable the RX path */ ipn3ke_xmac_rx_enable(hw, i, 1); - /* Clear all TX statistics counters */ - ipn3ke_xmac_tx_clr_stcs(hw, i, 1); + /* Clear NIC side TX statistics counters */ + ipn3ke_xmac_tx_clr_10G_stcs(hw, i, 1); + + /* Clear NIC side RX statistics counters */ + ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 1); + + /* Clear line side TX statistics counters */ + ipn3ke_xmac_tx_clr_10G_stcs(hw, i, 0); + + /* Clear line RX statistics counters */ + ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 0); + } + } else if (hw->retimer.mac_type == + IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI) { + /* Enable inter connect channel */ + for (i = 0; i < hw->port_num; i++) { + /* Clear NIC side TX statistics counters */ + ipn3ke_xmac_tx_clr_25G_stcs(hw, i, 1); + + /* Clear NIC side RX statistics counters */ + ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 1); + + /* Clear line side TX statistics counters */ + ipn3ke_xmac_tx_clr_25G_stcs(hw, i, 0); - /* Clear all RX statistics counters */ - ipn3ke_xmac_rx_clr_stcs(hw, i, 1); + /* Clear line side RX statistics counters */ + ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 0); } } + /* init mtu */ + ipn3ke_mtu_setup(hw); + ret = rte_eth_switch_domain_alloc(&hw->switch_domain_id); if (ret) IPN3KE_AFU_PMD_WARN("failed to allocate switch domain for device %d", @@ -262,7 +398,14 @@ ipn3ke_hw_init(struct rte_afu_device *afu_dev, hw->flow_hw_enable = 0; if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW && afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) { + ret = ipn3ke_hw_tm_init(hw); + if (ret) + return ret; hw->tm_hw_enable = 1; + + ret = ipn3ke_flow_init(hw); + if (ret) + return ret; hw->flow_hw_enable = 1; } @@ -285,11 +428,32 @@ ipn3ke_hw_uninit(struct ipn3ke_hw *hw) /* Disable the RX path */ ipn3ke_xmac_rx_disable(hw, i, 1); - /* Clear all TX statistics counters */ - ipn3ke_xmac_tx_clr_stcs(hw, i, 1); + /* Clear NIC side TX statistics counters */ + ipn3ke_xmac_tx_clr_10G_stcs(hw, i, 1); + + /* Clear NIC side RX statistics counters */ + ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 1); + + /* Clear line side TX statistics counters */ + ipn3ke_xmac_tx_clr_10G_stcs(hw, i, 0); - /* Clear all RX statistics counters */ - ipn3ke_xmac_rx_clr_stcs(hw, i, 1); + /* Clear line side RX statistics counters */ + ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 0); + } + } else if (hw->retimer.mac_type == + IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI) { + for (i = 0; i < hw->port_num; i++) { + /* Clear NIC side TX statistics counters */ + ipn3ke_xmac_tx_clr_25G_stcs(hw, i, 1); + + /* Clear NIC side RX statistics counters */ + ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 1); + + /* Clear line side TX statistics counters */ + ipn3ke_xmac_tx_clr_25G_stcs(hw, i, 0); + + /* Clear line side RX statistics counters */ + ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 0); } } } @@ -339,7 +503,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev) retval = rte_eth_dev_create(&afu_dev->device, name, sizeof(struct ipn3ke_rpst), NULL, NULL, - NULL, &rpst); + ipn3ke_rpst_init, &rpst); if (retval) IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.", @@ -368,7 +532,7 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev) if (!ethdev) return -ENODEV; - rte_eth_dev_destroy(ethdev, NULL); + rte_eth_dev_destroy(ethdev, ipn3ke_rpst_uninit); } ret = rte_eth_switch_domain_free(hw->switch_domain_id); @@ -573,8 +737,7 @@ ipn3ke_cfg_probe(struct rte_vdev_device *dev) } ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name); - if (ret) - goto end; + end: if (kvlist) rte_kvargs_free(kvlist);