net/bnxt: support tunneling
[dpdk.git] / drivers / net / bnxt / bnxt_ethdev.c
index 416c5e6..121c29e 100644 (file)
@@ -228,28 +228,31 @@ static int bnxt_init_chip(struct bnxt *bp)
 
                rc = bnxt_hwrm_vnic_alloc(bp, vnic);
                if (rc) {
-                       RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
-                               rc);
+                       RTE_LOG(ERR, PMD, "HWRM vnic %d alloc failure rc: %x\n",
+                               i, rc);
                        goto err_out;
                }
 
                rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic);
                if (rc) {
                        RTE_LOG(ERR, PMD,
-                               "HWRM vnic ctx alloc failure rc: %x\n", rc);
+                               "HWRM vnic %d ctx alloc failure rc: %x\n",
+                               i, rc);
                        goto err_out;
                }
 
                rc = bnxt_hwrm_vnic_cfg(bp, vnic);
                if (rc) {
-                       RTE_LOG(ERR, PMD, "HWRM vnic cfg failure rc: %x\n", rc);
+                       RTE_LOG(ERR, PMD, "HWRM vnic %d cfg failure rc: %x\n",
+                               i, rc);
                        goto err_out;
                }
 
                rc = bnxt_set_hwrm_vnic_filters(bp, vnic);
                if (rc) {
-                       RTE_LOG(ERR, PMD, "HWRM vnic filter failure rc: %x\n",
-                               rc);
+                       RTE_LOG(ERR, PMD,
+                               "HWRM vnic %d filter failure rc: %x\n",
+                               i, rc);
                        goto err_out;
                }
                if (vnic->rss_table && vnic->hash_type) {
@@ -269,8 +272,8 @@ static int bnxt_init_chip(struct bnxt *bp)
                        rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
                        if (rc) {
                                RTE_LOG(ERR, PMD,
-                                       "HWRM vnic set RSS failure rc: %x\n",
-                                       rc);
+                                       "HWRM vnic %d set RSS failure rc: %x\n",
+                                       i, rc);
                                goto err_out;
                        }
                }
@@ -360,7 +363,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
        dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
                                        DEV_TX_OFFLOAD_TCP_CKSUM |
                                        DEV_TX_OFFLOAD_UDP_CKSUM |
-                                       DEV_TX_OFFLOAD_TCP_TSO;
+                                       DEV_TX_OFFLOAD_TCP_TSO |
+                                       DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+                                       DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+                                       DEV_TX_OFFLOAD_GRE_TNL_TSO |
+                                       DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+                                       DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
 
        /* *INDENT-OFF* */
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -638,7 +646,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
                        new.link_speed = ETH_LINK_SPEED_100M;
                        new.link_duplex = ETH_LINK_FULL_DUPLEX;
                        RTE_LOG(ERR, PMD,
-                               "Failed to retrieve link rc = 0x%x!", rc);
+                               "Failed to retrieve link rc = 0x%x!\n", rc);
                        goto out;
                }
                rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
@@ -972,6 +980,116 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
        return bnxt_set_hwrm_link_config(bp, true);
 }
 
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+                        struct rte_eth_udp_tunnel *udp_tunnel)
+{
+       struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+       uint16_t tunnel_type = 0;
+       int rc = 0;
+
+       switch (udp_tunnel->prot_type) {
+       case RTE_TUNNEL_TYPE_VXLAN:
+               if (bp->vxlan_port_cnt) {
+                       RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+                               udp_tunnel->udp_port);
+                       if (bp->vxlan_port != udp_tunnel->udp_port) {
+                               RTE_LOG(ERR, PMD, "Only one port allowed\n");
+                               return -ENOSPC;
+                       }
+                       bp->vxlan_port_cnt++;
+                       return 0;
+               }
+               tunnel_type =
+                       HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+               bp->vxlan_port_cnt++;
+               break;
+       case RTE_TUNNEL_TYPE_GENEVE:
+               if (bp->geneve_port_cnt) {
+                       RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+                               udp_tunnel->udp_port);
+                       if (bp->geneve_port != udp_tunnel->udp_port) {
+                               RTE_LOG(ERR, PMD, "Only one port allowed\n");
+                               return -ENOSPC;
+                       }
+                       bp->geneve_port_cnt++;
+                       return 0;
+               }
+               tunnel_type =
+                       HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+               bp->geneve_port_cnt++;
+               break;
+       default:
+               RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+               return -ENOTSUP;
+       }
+       rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+                                            tunnel_type);
+       return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+                        struct rte_eth_udp_tunnel *udp_tunnel)
+{
+       struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+       uint16_t tunnel_type = 0;
+       uint16_t port = 0;
+       int rc = 0;
+
+       switch (udp_tunnel->prot_type) {
+       case RTE_TUNNEL_TYPE_VXLAN:
+               if (!bp->vxlan_port_cnt) {
+                       RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+                       return -EINVAL;
+               }
+               if (bp->vxlan_port != udp_tunnel->udp_port) {
+                       RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+                               udp_tunnel->udp_port, bp->vxlan_port);
+                       return -EINVAL;
+               }
+               if (--bp->vxlan_port_cnt)
+                       return 0;
+
+               tunnel_type =
+                       HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+               port = bp->vxlan_fw_dst_port_id;
+               break;
+       case RTE_TUNNEL_TYPE_GENEVE:
+               if (!bp->geneve_port_cnt) {
+                       RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+                       return -EINVAL;
+               }
+               if (bp->geneve_port != udp_tunnel->udp_port) {
+                       RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+                               udp_tunnel->udp_port, bp->geneve_port);
+                       return -EINVAL;
+               }
+               if (--bp->geneve_port_cnt)
+                       return 0;
+
+               tunnel_type =
+                       HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+               port = bp->geneve_fw_dst_port_id;
+               break;
+       default:
+               RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+               return -ENOTSUP;
+       }
+
+       rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+       if (!rc) {
+               if (tunnel_type ==
+                   HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+                       bp->vxlan_port = 0;
+               if (tunnel_type ==
+                   HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+                       bp->geneve_port = 0;
+       }
+       return rc;
+}
+
 /*
  * Initialization
  */
@@ -1003,6 +1121,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
        .mac_addr_remove = bnxt_mac_addr_remove_op,
        .flow_ctrl_get = bnxt_flow_ctrl_get_op,
        .flow_ctrl_set = bnxt_flow_ctrl_set_op,
+       .udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
+       .udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1010,7 +1130,8 @@ static bool bnxt_vf_pciid(uint16_t id)
        if (id == BROADCOM_DEV_ID_57304_VF ||
            id == BROADCOM_DEV_ID_57406_VF ||
            id == BROADCOM_DEV_ID_5731X_VF ||
-           id == BROADCOM_DEV_ID_5741X_VF)
+           id == BROADCOM_DEV_ID_5741X_VF ||
+           id == BROADCOM_DEV_ID_57414_VF)
                return true;
        return false;
 }
@@ -1066,7 +1187,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
        int rc;
 
        if (version_printed++ == 0)
-               RTE_LOG(INFO, PMD, "%s", bnxt_version);
+               RTE_LOG(INFO, PMD, "%s\n", bnxt_version);
 
        rte_eth_copy_pci_info(eth_dev, pci_dev);
        eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
@@ -1207,6 +1328,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
        if (rc)
                goto error_free_int;
 
+       rc = bnxt_alloc_def_cp_ring(bp);
+       if (rc)
+               goto error_free_int;
+
        bnxt_enable_int(bp);
 
        return 0;