net/ixgbe: fix link status
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 1a2a425..30c0379 100644 (file)
@@ -151,8 +151,8 @@ static void ixgbe_dev_close(struct rte_eth_dev *dev);
 static int  ixgbe_dev_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
-static void ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
-static void ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static int ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
+static int ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int ixgbe_dev_link_update(struct rte_eth_dev *dev,
                                int wait_to_complete);
 static int ixgbe_dev_stats_get(struct rte_eth_dev *dev,
@@ -272,8 +272,8 @@ static void ixgbevf_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
 static void ixgbevf_configure_msix(struct rte_eth_dev *dev);
 static int ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
-static void ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev);
-static void ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static int ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev);
+static int ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev);
 
 /* For Eth VMDQ APIs support */
 static int ixgbe_uc_hash_table_set(struct rte_eth_dev *dev, struct
@@ -419,6 +419,16 @@ static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev);
 int ixgbe_logtype_init;
 int ixgbe_logtype_driver;
 
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_RX
+int ixgbe_logtype_rx;
+#endif
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX
+int ixgbe_logtype_tx;
+#endif
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE
+int ixgbe_logtype_tx_free;
+#endif
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -1245,6 +1255,11 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
                return -ENOMEM;
        }
 
+       /* Pass the information to the rte_eth_dev_close() that it should also
+        * release the private port resources.
+        */
+       eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+
        /* initialize the vfta */
        memset(shadow_vfta, 0, sizeof(*shadow_vfta));
 
@@ -1311,73 +1326,12 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
 static int
 eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 {
-       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
-       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
-       struct ixgbe_hw *hw;
-       int retries = 0;
-       int ret;
-
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
-       hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-
-       if (hw->adapter_stopped == 0)
-               ixgbe_dev_close(eth_dev);
-
-       eth_dev->dev_ops = NULL;
-       eth_dev->rx_pkt_burst = NULL;
-       eth_dev->tx_pkt_burst = NULL;
-
-       /* Unlock any pending hardware semaphore */
-       ixgbe_swfw_lock_reset(hw);
-
-       /* disable uio intr before callback unregister */
-       rte_intr_disable(intr_handle);
-
-       do {
-               ret = rte_intr_callback_unregister(intr_handle,
-                               ixgbe_dev_interrupt_handler, eth_dev);
-               if (ret >= 0) {
-                       break;
-               } else if (ret != -EAGAIN) {
-                       PMD_INIT_LOG(ERR,
-                               "intr callback unregister failed: %d",
-                               ret);
-                       return ret;
-               }
-               rte_delay_ms(100);
-       } while (retries++ < (10 + IXGBE_LINK_UP_TIME));
-
-       /* cancel the delay handler before remove dev */
-       rte_eal_alarm_cancel(ixgbe_dev_interrupt_delayed_handler, eth_dev);
-
-       /* cancel the link handler before remove dev */
-       rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, eth_dev);
-
-       /* uninitialize PF if max_vfs not zero */
-       ixgbe_pf_host_uninit(eth_dev);
-
-       /* remove all the fdir filters & hash */
-       ixgbe_fdir_filter_uninit(eth_dev);
-
-       /* remove all the L2 tunnel filters & hash */
-       ixgbe_l2_tn_filter_uninit(eth_dev);
-
-       /* Remove all ntuple filters of the device */
-       ixgbe_ntuple_filter_uninit(eth_dev);
-
-       /* clear all the filters list */
-       ixgbe_filterlist_flush();
-
-       /* Remove all Traffic Manager configuration */
-       ixgbe_tm_conf_uninit(eth_dev);
-
-#ifdef RTE_LIBRTE_SECURITY
-       rte_free(eth_dev->security_ctx);
-#endif
+       ixgbe_dev_close(eth_dev);
 
        return 0;
 }
@@ -1711,6 +1665,11 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
                return -ENOMEM;
        }
 
+       /* Pass the information to the rte_eth_dev_close() that it should also
+        * release the private port resources.
+        */
+       eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+
        /* Generate a random MAC address, if none was assigned by PF. */
        if (rte_is_zero_ether_addr(perm_addr)) {
                generate_random_mac_addr(perm_addr);
@@ -1762,30 +1721,12 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 static int
 eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
 {
-       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
-       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
-       struct ixgbe_hw *hw;
-
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
-       hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-
-       if (hw->adapter_stopped == 0)
-               ixgbevf_dev_close(eth_dev);
-
-       eth_dev->dev_ops = NULL;
-       eth_dev->rx_pkt_burst = NULL;
-       eth_dev->tx_pkt_burst = NULL;
-
-       /* Disable the interrupts for VF */
-       ixgbevf_intr_disable(eth_dev);
-
-       rte_intr_disable(intr_handle);
-       rte_intr_callback_unregister(intr_handle,
-                                    ixgbevf_dev_interrupt_handler, eth_dev);
+       ixgbevf_dev_close(eth_dev);
 
        return 0;
 }
@@ -2601,6 +2542,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        uint32_t *link_speeds;
        struct ixgbe_tm_conf *tm_conf =
                IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
+       struct ixgbe_macsec_setting *macsec_ctrl =
+               IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private);
 
        PMD_INIT_FUNC_TRACE();
 
@@ -2853,6 +2796,9 @@ skip_link_setup:
         */
        ixgbe_dev_link_update(dev, 0);
 
+       /* setup the macsec ctrl register */
+       ixgbe_dev_macsec_register_enable(dev, macsec_ctrl);
+
        return 0;
 
 error:
@@ -2879,8 +2825,14 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        struct ixgbe_tm_conf *tm_conf =
                IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
 
+       if (hw->adapter_stopped)
+               return;
+
        PMD_INIT_FUNC_TRACE();
 
+       /* disable mecsec register */
+       ixgbe_dev_macsec_register_disable(dev);
+
        rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
 
        /* disable interrupts */
@@ -2931,6 +2883,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        tm_conf->committed = false;
 
        adapter->rss_reta_updated = 0;
+
+       hw->adapter_stopped = true;
 }
 
 /*
@@ -2958,6 +2912,7 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev)
        } else {
                /* Turn on the laser */
                ixgbe_enable_tx_laser(hw);
+               ixgbe_dev_link_update(dev, 0);
        }
 
        return 0;
@@ -2988,6 +2943,7 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev)
        } else {
                /* Turn off the laser */
                ixgbe_disable_tx_laser(hw);
+               ixgbe_dev_link_update(dev, 0);
        }
 
        return 0;
@@ -3001,13 +2957,16 @@ ixgbe_dev_close(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+       int retries = 0;
+       int ret;
 
        PMD_INIT_FUNC_TRACE();
 
        ixgbe_pf_reset_hw(hw);
 
        ixgbe_dev_stop(dev);
-       hw->adapter_stopped = 1;
 
        ixgbe_dev_free_queues(dev);
 
@@ -3015,6 +2974,55 @@ ixgbe_dev_close(struct rte_eth_dev *dev)
 
        /* reprogram the RAR[0] in case user changed it. */
        ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+
+       dev->dev_ops = NULL;
+       dev->rx_pkt_burst = NULL;
+       dev->tx_pkt_burst = NULL;
+
+       /* Unlock any pending hardware semaphore */
+       ixgbe_swfw_lock_reset(hw);
+
+       /* disable uio intr before callback unregister */
+       rte_intr_disable(intr_handle);
+
+       do {
+               ret = rte_intr_callback_unregister(intr_handle,
+                               ixgbe_dev_interrupt_handler, dev);
+               if (ret >= 0 || ret == -ENOENT) {
+                       break;
+               } else if (ret != -EAGAIN) {
+                       PMD_INIT_LOG(ERR,
+                               "intr callback unregister failed: %d",
+                               ret);
+               }
+               rte_delay_ms(100);
+       } while (retries++ < (10 + IXGBE_LINK_UP_TIME));
+
+       /* cancel the delay handler before remove dev */
+       rte_eal_alarm_cancel(ixgbe_dev_interrupt_delayed_handler, dev);
+
+       /* uninitialize PF if max_vfs not zero */
+       ixgbe_pf_host_uninit(dev);
+
+       /* remove all the fdir filters & hash */
+       ixgbe_fdir_filter_uninit(dev);
+
+       /* remove all the L2 tunnel filters & hash */
+       ixgbe_l2_tn_filter_uninit(dev);
+
+       /* Remove all ntuple filters of the device */
+       ixgbe_ntuple_filter_uninit(dev);
+
+       /* clear all the filters list */
+       ixgbe_filterlist_flush();
+
+       /* Remove all Traffic Manager configuration */
+       ixgbe_tm_conf_uninit(dev);
+
+#ifdef RTE_LIBRTE_SECURITY
+       rte_free(dev->security_ctx);
+#endif
+
 }
 
 /*
@@ -3852,6 +3860,11 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 
        dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+       if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
+                       hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
+               dev_info->speed_capa = ETH_LINK_SPEED_10M |
+                       ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G;
+
        if (hw->mac.type == ixgbe_mac_X540 ||
            hw->mac.type == ixgbe_mac_X540_vf ||
            hw->mac.type == ixgbe_mac_X550 ||
@@ -3905,7 +3918,7 @@ ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
            dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc)
                return ptypes;
 
-#if defined(RTE_ARCH_X86)
+#if defined(RTE_ARCH_X86) || defined(RTE_MACHINE_CPUFLAG_NEON)
        if (dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
            dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
                return ptypes;
@@ -4105,6 +4118,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
        int link_up;
        int diag;
        int wait = 1;
+       u32 esdp_reg;
 
        memset(&link, 0, sizeof(link));
        link.link_status = ETH_LINK_DOWN;
@@ -4132,6 +4146,10 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
                return rte_eth_linkstatus_set(dev, &link);
        }
 
+       esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+       if ((esdp_reg & IXGBE_ESDP_SDP3))
+               link_up = 0;
+
        if (link_up == 0) {
                if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
                        intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
@@ -4220,7 +4238,7 @@ ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
        return 0;
 }
 
-static void
+static int
 ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4229,20 +4247,24 @@ ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
        fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
        fctrl |= IXGBE_FCTRL_MPE;
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+       return 0;
 }
 
-static void
+static int
 ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t fctrl;
 
        if (dev->data->promiscuous == 1)
-               return; /* must remain in all_multicast mode */
+               return 0; /* must remain in all_multicast mode */
 
        fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
        fctrl &= (~IXGBE_FCTRL_MPE);
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+       return 0;
 }
 
 /**
@@ -5253,6 +5275,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
         */
        ixgbevf_dev_link_update(dev, 0);
 
+       hw->adapter_stopped = false;
+
        return 0;
 }
 
@@ -5264,6 +5288,9 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
+       if (hw->adapter_stopped)
+               return;
+
        PMD_INIT_FUNC_TRACE();
 
        rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
@@ -5298,6 +5325,8 @@ static void
 ixgbevf_dev_close(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -5313,6 +5342,14 @@ ixgbevf_dev_close(struct rte_eth_dev *dev)
         * after stop, close and detach of the VF
         **/
        ixgbevf_remove_mac_addr(dev, 0);
+
+       dev->dev_ops = NULL;
+       dev->rx_pkt_burst = NULL;
+       dev->tx_pkt_burst = NULL;
+
+       rte_intr_disable(intr_handle);
+       rte_intr_callback_unregister(intr_handle,
+                                    ixgbevf_dev_interrupt_handler, dev);
 }
 
 /*
@@ -8457,20 +8494,47 @@ ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev)
        return ret;
 }
 
-static void
+static int
 ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
+       int mode = IXGBEVF_XCAST_MODE_ALLMULTI;
 
-       hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_ALLMULTI);
+       switch (hw->mac.ops.update_xcast_mode(hw, mode)) {
+       case IXGBE_SUCCESS:
+               ret = 0;
+               break;
+       case IXGBE_ERR_FEATURE_NOT_SUPPORTED:
+               ret = -ENOTSUP;
+               break;
+       default:
+               ret = -EAGAIN;
+               break;
+       }
+
+       return ret;
 }
 
-static void
+static int
 ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
 
-       hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_MULTI);
+       switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_MULTI)) {
+       case IXGBE_SUCCESS:
+               ret = 0;
+               break;
+       case IXGBE_ERR_FEATURE_NOT_SUPPORTED:
+               ret = -ENOTSUP;
+               break;
+       default:
+               ret = -EAGAIN;
+               break;
+       }
+
+       return ret;
 }
 
 static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
@@ -8767,6 +8831,147 @@ ixgbe_clear_all_l2_tn_filter(struct rte_eth_dev *dev)
        return 0;
 }
 
+void
+ixgbe_dev_macsec_setting_save(struct rte_eth_dev *dev,
+                               struct ixgbe_macsec_setting *macsec_setting)
+{
+       struct ixgbe_macsec_setting *macsec =
+               IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private);
+
+       macsec->encrypt_en = macsec_setting->encrypt_en;
+       macsec->replayprotect_en = macsec_setting->replayprotect_en;
+}
+
+void
+ixgbe_dev_macsec_setting_reset(struct rte_eth_dev *dev)
+{
+       struct ixgbe_macsec_setting *macsec =
+               IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private);
+
+       macsec->encrypt_en = 0;
+       macsec->replayprotect_en = 0;
+}
+
+void
+ixgbe_dev_macsec_register_enable(struct rte_eth_dev *dev,
+                               struct ixgbe_macsec_setting *macsec_setting)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t ctrl;
+       uint8_t en = macsec_setting->encrypt_en;
+       uint8_t rp = macsec_setting->replayprotect_en;
+
+       /**
+        * Workaround:
+        * As no ixgbe_disable_sec_rx_path equivalent is
+        * implemented for tx in the base code, and we are
+        * not allowed to modify the base code in DPDK, so
+        * just call the hand-written one directly for now.
+        * The hardware support has been checked by
+        * ixgbe_disable_sec_rx_path().
+        */
+       ixgbe_disable_sec_tx_path_generic(hw);
+
+       /* Enable Ethernet CRC (required by MACsec offload) */
+       ctrl = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+       ctrl |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_RXCRCSTRP;
+       IXGBE_WRITE_REG(hw, IXGBE_HLREG0, ctrl);
+
+       /* Enable the TX and RX crypto engines */
+       ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+       ctrl &= ~IXGBE_SECTXCTRL_SECTX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl);
+
+       ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+       ctrl &= ~IXGBE_SECRXCTRL_SECRX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl);
+
+       ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+       ctrl &= ~IXGBE_SECTX_MINSECIFG_MASK;
+       ctrl |= 0x3;
+       IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, ctrl);
+
+       /* Enable SA lookup */
+       ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL);
+       ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK;
+       ctrl |= en ? IXGBE_LSECTXCTRL_AUTH_ENCRYPT :
+                    IXGBE_LSECTXCTRL_AUTH;
+       ctrl |= IXGBE_LSECTXCTRL_AISCI;
+       ctrl &= ~IXGBE_LSECTXCTRL_PNTHRSH_MASK;
+       ctrl |= IXGBE_MACSEC_PNTHRSH & IXGBE_LSECTXCTRL_PNTHRSH_MASK;
+       IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl);
+
+       ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL);
+       ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK;
+       ctrl |= IXGBE_LSECRXCTRL_STRICT << IXGBE_LSECRXCTRL_EN_SHIFT;
+       ctrl &= ~IXGBE_LSECRXCTRL_PLSH;
+       if (rp)
+               ctrl |= IXGBE_LSECRXCTRL_RP;
+       else
+               ctrl &= ~IXGBE_LSECRXCTRL_RP;
+       IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl);
+
+       /* Start the data paths */
+       ixgbe_enable_sec_rx_path(hw);
+       /**
+        * Workaround:
+        * As no ixgbe_enable_sec_rx_path equivalent is
+        * implemented for tx in the base code, and we are
+        * not allowed to modify the base code in DPDK, so
+        * just call the hand-written one directly for now.
+        */
+       ixgbe_enable_sec_tx_path_generic(hw);
+}
+
+void
+ixgbe_dev_macsec_register_disable(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t ctrl;
+
+       /**
+        * Workaround:
+        * As no ixgbe_disable_sec_rx_path equivalent is
+        * implemented for tx in the base code, and we are
+        * not allowed to modify the base code in DPDK, so
+        * just call the hand-written one directly for now.
+        * The hardware support has been checked by
+        * ixgbe_disable_sec_rx_path().
+        */
+       ixgbe_disable_sec_tx_path_generic(hw);
+
+       /* Disable the TX and RX crypto engines */
+       ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+       ctrl |= IXGBE_SECTXCTRL_SECTX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl);
+
+       ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+       ctrl |= IXGBE_SECRXCTRL_SECRX_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl);
+
+       /* Disable SA lookup */
+       ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL);
+       ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK;
+       ctrl |= IXGBE_LSECTXCTRL_DISABLE;
+       IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl);
+
+       ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL);
+       ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK;
+       ctrl |= IXGBE_LSECRXCTRL_DISABLE << IXGBE_LSECRXCTRL_EN_SHIFT;
+       IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl);
+
+       /* Start the data paths */
+       ixgbe_enable_sec_rx_path(hw);
+       /**
+        * Workaround:
+        * As no ixgbe_enable_sec_rx_path equivalent is
+        * implemented for tx in the base code, and we are
+        * not allowed to modify the base code in DPDK, so
+        * just call the hand-written one directly for now.
+        */
+       ixgbe_enable_sec_tx_path_generic(hw);
+}
+
 RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio-pci");
@@ -8784,4 +8989,21 @@ RTE_INIT(ixgbe_init_log)
        ixgbe_logtype_driver = rte_log_register("pmd.net.ixgbe.driver");
        if (ixgbe_logtype_driver >= 0)
                rte_log_set_level(ixgbe_logtype_driver, RTE_LOG_NOTICE);
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_RX
+       ixgbe_logtype_rx = rte_log_register("pmd.net.ixgbe.rx");
+       if (ixgbe_logtype_rx >= 0)
+               rte_log_set_level(ixgbe_logtype_rx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX
+       ixgbe_logtype_tx = rte_log_register("pmd.net.ixgbe.tx");
+       if (ixgbe_logtype_tx >= 0)
+               rte_log_set_level(ixgbe_logtype_tx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE
+       ixgbe_logtype_tx_free = rte_log_register("pmd.net.ixgbe.tx_free");
+       if (ixgbe_logtype_tx_free >= 0)
+               rte_log_set_level(ixgbe_logtype_tx_free, RTE_LOG_DEBUG);
+#endif
 }