numam-dpdk/drivers/net/ixgbe/rte_pmd_ixgbe.c
Ferruh Yigit ffc905f3b8 ethdev: separate driver APIs
Create a rte_ethdev_driver.h file and move PMD specific APIs here.
Drivers updated to include this new header file.

There is no update in header content and since ethdev.h included by
ethdev_driver.h, nothing changed from driver point of view, only
logically grouping of APIs. From applications point of view they can't
access to driver specific APIs anymore and they shouldn't.

More PMD specific data structures still remain in ethdev.h because of
inline functions in header use them. Those will be handled separately.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
2018-01-22 01:26:49 +01:00

1015 lines
22 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2017 Intel Corporation
*/
#include <rte_ethdev_driver.h>
#include "base/ixgbe_api.h"
#include "ixgbe_ethdev.h"
#include "rte_pmd_ixgbe.h"
int
rte_pmd_ixgbe_set_vf_mac_addr(uint16_t port, uint16_t vf,
struct ether_addr *mac_addr)
{
struct ixgbe_hw *hw;
struct ixgbe_vf_info *vfinfo;
int rar_entry;
uint8_t *new_mac = (uint8_t *)(mac_addr);
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
rar_entry = hw->mac.num_rar_entries - (vf + 1);
if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac,
ETHER_ADDR_LEN);
return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf,
IXGBE_RAH_AV);
}
return -EINVAL;
}
int
rte_pmd_ixgbe_ping_vf(uint16_t port, uint16_t vf)
{
struct ixgbe_hw *hw;
struct ixgbe_vf_info *vfinfo;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
uint32_t ctrl;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
ctrl = IXGBE_PF_CONTROL_MSG;
if (vfinfo[vf].clear_to_send)
ctrl |= IXGBE_VT_MSGTYPE_CTS;
ixgbe_write_mbx(hw, &ctrl, 1, vf);
return 0;
}
int
rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
{
struct ixgbe_hw *hw;
struct ixgbe_mac_info *mac;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
mac = &hw->mac;
mac->ops.set_vlan_anti_spoofing(hw, on, vf);
return 0;
}
int
rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
{
struct ixgbe_hw *hw;
struct ixgbe_mac_info *mac;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
mac = &hw->mac;
mac->ops.set_mac_anti_spoofing(hw, on, vf);
return 0;
}
int
rte_pmd_ixgbe_set_vf_vlan_insert(uint16_t port, uint16_t vf, uint16_t vlan_id)
{
struct ixgbe_hw *hw;
uint32_t ctrl;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (vlan_id > ETHER_MAX_VLAN_ID)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
if (vlan_id) {
ctrl = vlan_id;
ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
} else {
ctrl = 0;
}
IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
return 0;
}
int
rte_pmd_ixgbe_set_tx_loopback(uint16_t port, uint8_t on)
{
struct ixgbe_hw *hw;
uint32_t ctrl;
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
/* enable or disable VMDQ loopback */
if (on)
ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
else
ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
return 0;
}
int
rte_pmd_ixgbe_set_all_queues_drop_en(uint16_t port, uint8_t on)
{
struct ixgbe_hw *hw;
uint32_t reg_value;
int i;
int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
for (i = 0; i <= num_queues; i++) {
reg_value = IXGBE_QDE_WRITE |
(i << IXGBE_QDE_IDX_SHIFT) |
(on & IXGBE_QDE_ENABLE);
IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
}
return 0;
}
int
rte_pmd_ixgbe_set_vf_split_drop_en(uint16_t port, uint16_t vf, uint8_t on)
{
struct ixgbe_hw *hw;
uint32_t reg_value;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
/* only support VF's 0 to 63 */
if ((vf >= pci_dev->max_vfs) || (vf > 63))
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
if (on)
reg_value |= IXGBE_SRRCTL_DROP_EN;
else
reg_value &= ~IXGBE_SRRCTL_DROP_EN;
IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
return 0;
}
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on)
{
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
struct ixgbe_hw *hw;
uint16_t queues_per_pool;
uint32_t q;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
/* The PF has 128 queue pairs and in SRIOV configuration
* those queues will be assigned to VF's, so RXDCTL
* registers will be dealing with queues which will be
* assigned to VF's.
* Let's say we have SRIOV configured with 31 VF's then the
* first 124 queues 0-123 will be allocated to VF's and only
* the last 4 queues 123-127 will be assigned to the PF.
*/
if (hw->mac.type == ixgbe_mac_82598EB)
queues_per_pool = (uint16_t)hw->mac.max_rx_queues /
ETH_16_POOLS;
else
queues_per_pool = (uint16_t)hw->mac.max_rx_queues /
ETH_64_POOLS;
for (q = 0; q < queues_per_pool; q++)
(*dev->dev_ops->vlan_strip_queue_set)(dev,
q + vf * queues_per_pool, on);
return 0;
}
int
rte_pmd_ixgbe_set_vf_rxmode(uint16_t port, uint16_t vf,
uint16_t rx_mask, uint8_t on)
{
int val = 0;
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
struct ixgbe_hw *hw;
uint32_t vmolr;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
if (hw->mac.type == ixgbe_mac_82598EB) {
PMD_INIT_LOG(ERR, "setting VF receive mode set should be done"
" on 82599 hardware and newer");
return -ENOTSUP;
}
if (ixgbe_vt_check(hw) < 0)
return -ENOTSUP;
val = ixgbe_convert_vm_rx_mask_to_val(rx_mask, val);
if (on)
vmolr |= val;
else
vmolr &= ~val;
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
return 0;
}
int
rte_pmd_ixgbe_set_vf_rx(uint16_t port, uint16_t vf, uint8_t on)
{
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
uint32_t reg, addr;
uint32_t val;
const uint8_t bit1 = 0x1;
struct ixgbe_hw *hw;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (ixgbe_vt_check(hw) < 0)
return -ENOTSUP;
/* for vf >= 32, set bit in PFVFRE[1], otherwise PFVFRE[0] */
if (vf >= 32) {
addr = IXGBE_VFRE(1);
val = bit1 << (vf - 32);
} else {
addr = IXGBE_VFRE(0);
val = bit1 << vf;
}
reg = IXGBE_READ_REG(hw, addr);
if (on)
reg |= val;
else
reg &= ~val;
IXGBE_WRITE_REG(hw, addr, reg);
return 0;
}
int
rte_pmd_ixgbe_set_vf_tx(uint16_t port, uint16_t vf, uint8_t on)
{
struct rte_eth_dev *dev;
struct rte_pci_device *pci_dev;
uint32_t reg, addr;
uint32_t val;
const uint8_t bit1 = 0x1;
struct ixgbe_hw *hw;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
pci_dev = RTE_ETH_DEV_TO_PCI(dev);
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (vf >= pci_dev->max_vfs)
return -EINVAL;
if (on > 1)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (ixgbe_vt_check(hw) < 0)
return -ENOTSUP;
/* for vf >= 32, set bit in PFVFTE[1], otherwise PFVFTE[0] */
if (vf >= 32) {
addr = IXGBE_VFTE(1);
val = bit1 << (vf - 32);
} else {
addr = IXGBE_VFTE(0);
val = bit1 << vf;
}
reg = IXGBE_READ_REG(hw, addr);
if (on)
reg |= val;
else
reg &= ~val;
IXGBE_WRITE_REG(hw, addr, reg);
return 0;
}
int
rte_pmd_ixgbe_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
uint64_t vf_mask, uint8_t vlan_on)
{
struct rte_eth_dev *dev;
int ret = 0;
uint16_t vf_idx;
struct ixgbe_hw *hw;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if ((vlan > ETHER_MAX_VLAN_ID) || (vf_mask == 0))
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (ixgbe_vt_check(hw) < 0)
return -ENOTSUP;
for (vf_idx = 0; vf_idx < 64; vf_idx++) {
if (vf_mask & ((uint64_t)(1ULL << vf_idx))) {
ret = hw->mac.ops.set_vfta(hw, vlan, vf_idx,
vlan_on, false);
if (ret < 0)
return ret;
}
}
return ret;
}
int
rte_pmd_ixgbe_set_vf_rate_limit(uint16_t port, uint16_t vf,
uint16_t tx_rate, uint64_t q_msk)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_set_vf_rate_limit(dev, vf, tx_rate, q_msk);
}
int
rte_pmd_ixgbe_macsec_enable(uint16_t port, uint8_t en, uint8_t rp)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* Stop the data paths */
if (ixgbe_disable_sec_rx_path(hw) != IXGBE_SUCCESS)
return -ENOTSUP;
/**
* 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);
return 0;
}
int
rte_pmd_ixgbe_macsec_disable(uint16_t port)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* Stop the data paths */
if (ixgbe_disable_sec_rx_path(hw) != IXGBE_SUCCESS)
return -ENOTSUP;
/**
* 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);
return 0;
}
int
rte_pmd_ixgbe_macsec_config_txsc(uint16_t port, uint8_t *mac)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
ctrl = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
IXGBE_WRITE_REG(hw, IXGBE_LSECTXSCL, ctrl);
ctrl = mac[4] | (mac[5] << 8);
IXGBE_WRITE_REG(hw, IXGBE_LSECTXSCH, ctrl);
return 0;
}
int
rte_pmd_ixgbe_macsec_config_rxsc(uint16_t port, uint8_t *mac, uint16_t pi)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
ctrl = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
IXGBE_WRITE_REG(hw, IXGBE_LSECRXSCL, ctrl);
pi = rte_cpu_to_be_16(pi);
ctrl = mac[4] | (mac[5] << 8) | (pi << 16);
IXGBE_WRITE_REG(hw, IXGBE_LSECRXSCH, ctrl);
return 0;
}
int
rte_pmd_ixgbe_macsec_select_txsa(uint16_t port, uint8_t idx, uint8_t an,
uint32_t pn, uint8_t *key)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl, i;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (idx != 0 && idx != 1)
return -EINVAL;
if (an >= 4)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* Set the PN and key */
pn = rte_cpu_to_be_32(pn);
if (idx == 0) {
IXGBE_WRITE_REG(hw, IXGBE_LSECTXPN0, pn);
for (i = 0; i < 4; i++) {
ctrl = (key[i * 4 + 0] << 0) |
(key[i * 4 + 1] << 8) |
(key[i * 4 + 2] << 16) |
(key[i * 4 + 3] << 24);
IXGBE_WRITE_REG(hw, IXGBE_LSECTXKEY0(i), ctrl);
}
} else {
IXGBE_WRITE_REG(hw, IXGBE_LSECTXPN1, pn);
for (i = 0; i < 4; i++) {
ctrl = (key[i * 4 + 0] << 0) |
(key[i * 4 + 1] << 8) |
(key[i * 4 + 2] << 16) |
(key[i * 4 + 3] << 24);
IXGBE_WRITE_REG(hw, IXGBE_LSECTXKEY1(i), ctrl);
}
}
/* Set AN and select the SA */
ctrl = (an << idx * 2) | (idx << 4);
IXGBE_WRITE_REG(hw, IXGBE_LSECTXSA, ctrl);
return 0;
}
int
rte_pmd_ixgbe_macsec_select_rxsa(uint16_t port, uint8_t idx, uint8_t an,
uint32_t pn, uint8_t *key)
{
struct ixgbe_hw *hw;
struct rte_eth_dev *dev;
uint32_t ctrl, i;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (idx != 0 && idx != 1)
return -EINVAL;
if (an >= 4)
return -EINVAL;
/* Set the PN */
pn = rte_cpu_to_be_32(pn);
IXGBE_WRITE_REG(hw, IXGBE_LSECRXPN(idx), pn);
/* Set the key */
for (i = 0; i < 4; i++) {
ctrl = (key[i * 4 + 0] << 0) |
(key[i * 4 + 1] << 8) |
(key[i * 4 + 2] << 16) |
(key[i * 4 + 3] << 24);
IXGBE_WRITE_REG(hw, IXGBE_LSECRXKEY(idx, i), ctrl);
}
/* Set the AN and validate the SA */
ctrl = an | (1 << 2);
IXGBE_WRITE_REG(hw, IXGBE_LSECRXSA(idx), ctrl);
return 0;
}
int
rte_pmd_ixgbe_set_tc_bw_alloc(uint16_t port,
uint8_t tc_num,
uint8_t *bw_weight)
{
struct rte_eth_dev *dev;
struct ixgbe_dcb_config *dcb_config;
struct ixgbe_dcb_tc_config *tc;
struct rte_eth_conf *eth_conf;
struct ixgbe_bw_conf *bw_conf;
uint8_t i;
uint8_t nb_tcs;
uint16_t sum;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
if (tc_num > IXGBE_DCB_MAX_TRAFFIC_CLASS) {
PMD_DRV_LOG(ERR, "TCs should be no more than %d.",
IXGBE_DCB_MAX_TRAFFIC_CLASS);
return -EINVAL;
}
dcb_config = IXGBE_DEV_PRIVATE_TO_DCB_CFG(dev->data->dev_private);
bw_conf = IXGBE_DEV_PRIVATE_TO_BW_CONF(dev->data->dev_private);
eth_conf = &dev->data->dev_conf;
if (eth_conf->txmode.mq_mode == ETH_MQ_TX_DCB) {
nb_tcs = eth_conf->tx_adv_conf.dcb_tx_conf.nb_tcs;
} else if (eth_conf->txmode.mq_mode == ETH_MQ_TX_VMDQ_DCB) {
if (eth_conf->tx_adv_conf.vmdq_dcb_tx_conf.nb_queue_pools ==
ETH_32_POOLS)
nb_tcs = ETH_4_TCS;
else
nb_tcs = ETH_8_TCS;
} else {
nb_tcs = 1;
}
if (nb_tcs != tc_num) {
PMD_DRV_LOG(ERR,
"Weight should be set for all %d enabled TCs.",
nb_tcs);
return -EINVAL;
}
sum = 0;
for (i = 0; i < nb_tcs; i++)
sum += bw_weight[i];
if (sum != 100) {
PMD_DRV_LOG(ERR,
"The summary of the TC weight should be 100.");
return -EINVAL;
}
for (i = 0; i < nb_tcs; i++) {
tc = &dcb_config->tc_config[i];
tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent = bw_weight[i];
}
for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
tc = &dcb_config->tc_config[i];
tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent = 0;
}
bw_conf->tc_num = nb_tcs;
return 0;
}
#ifdef RTE_LIBRTE_IXGBE_BYPASS
int
rte_pmd_ixgbe_bypass_init(uint16_t port_id)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
ixgbe_bypass_init(dev);
return 0;
}
int
rte_pmd_ixgbe_bypass_state_show(uint16_t port_id, uint32_t *state)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_state_show(dev, state);
}
int
rte_pmd_ixgbe_bypass_state_set(uint16_t port_id, uint32_t *new_state)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_state_store(dev, new_state);
}
int
rte_pmd_ixgbe_bypass_event_show(uint16_t port_id,
uint32_t event,
uint32_t *state)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_event_show(dev, event, state);
}
int
rte_pmd_ixgbe_bypass_event_store(uint16_t port_id,
uint32_t event,
uint32_t state)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_event_store(dev, event, state);
}
int
rte_pmd_ixgbe_bypass_wd_timeout_store(uint16_t port_id, uint32_t timeout)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_wd_timeout_store(dev, timeout);
}
int
rte_pmd_ixgbe_bypass_ver_show(uint16_t port_id, uint32_t *ver)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_ver_show(dev, ver);
}
int
rte_pmd_ixgbe_bypass_wd_timeout_show(uint16_t port_id, uint32_t *wd_timeout)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_wd_timeout_show(dev, wd_timeout);
}
int
rte_pmd_ixgbe_bypass_wd_reset(uint16_t port_id)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (!is_ixgbe_supported(dev))
return -ENOTSUP;
return ixgbe_bypass_wd_reset(dev);
}
#endif