struct timespec *timestamp);
static int ixgbe_timesync_write_time(struct rte_eth_dev *dev,
const struct timespec *timestamp);
+
static int ixgbe_dev_l2_tunnel_eth_type_conf
(struct rte_eth_dev *dev, struct rte_eth_l2_tunnel_conf *l2_tunnel);
static int ixgbe_dev_l2_tunnel_offload_set
enum rte_filter_op filter_op,
void *arg);
+static int ixgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
+ struct rte_eth_udp_tunnel *udp_tunnel);
+static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
+ struct rte_eth_udp_tunnel *udp_tunnel);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
uint32_t idx = (q) / (sizeof ((h)->bitmap[0]) * NBBY); \
uint32_t bit = (q) % (sizeof ((h)->bitmap[0]) * NBBY); \
(h)->bitmap[idx] |= 1 << bit;\
- }while(0)
+ } while (0)
#define IXGBE_CLEAR_HWSTRIP(h, q) do{\
uint32_t idx = (q) / (sizeof ((h)->bitmap[0]) * NBBY); \
uint32_t bit = (q) % (sizeof ((h)->bitmap[0]) * NBBY); \
(h)->bitmap[idx] &= ~(1 << bit);\
- }while(0)
+ } while (0)
#define IXGBE_GET_HWSTRIP(h, q, r) do{\
uint32_t idx = (q) / (sizeof ((h)->bitmap[0]) * NBBY); \
uint32_t bit = (q) % (sizeof ((h)->bitmap[0]) * NBBY); \
(r) = (h)->bitmap[idx] >> bit & 1;\
- }while(0)
+ } while (0)
/*
* The set of PCI devices this driver supports
.timesync_write_time = ixgbe_timesync_write_time,
.l2_tunnel_eth_type_conf = ixgbe_dev_l2_tunnel_eth_type_conf,
.l2_tunnel_offload_set = ixgbe_dev_l2_tunnel_offload_set,
+ .udp_tunnel_port_add = ixgbe_dev_udp_tunnel_port_add,
+ .udp_tunnel_port_del = ixgbe_dev_udp_tunnel_port_del,
};
/*
{
uint32_t i;
- for(i = 0; i != IXGBE_NB_STAT_MAPPING_REGS; i++) {
+ for (i = 0; i != IXGBE_NB_STAT_MAPPING_REGS; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), 0);
}
struct ixgbe_hwstrip *hwstrip =
IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(dev->data->dev_private);
- if(queue >= IXGBE_MAX_RX_QUEUE_NUM)
+ if (queue >= IXGBE_MAX_RX_QUEUE_NUM)
return;
if (on)
static void
ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
- if(mask & ETH_VLAN_STRIP_MASK){
+ if (mask & ETH_VLAN_STRIP_MASK) {
if (dev->data->dev_conf.rxmode.hw_vlan_strip)
ixgbe_vlan_hw_strip_enable_all(dev);
else
ixgbe_vlan_hw_strip_disable_all(dev);
}
- if(mask & ETH_VLAN_FILTER_MASK){
+ if (mask & ETH_VLAN_FILTER_MASK) {
if (dev->data->dev_conf.rxmode.hw_vlan_filter)
ixgbe_vlan_hw_filter_enable(dev);
else
ixgbe_vlan_hw_filter_disable(dev);
}
- if(mask & ETH_VLAN_EXTEND_MASK){
+ if (mask & ETH_VLAN_EXTEND_MASK) {
if (dev->data->dev_conf.rxmode.hw_vlan_extend)
ixgbe_vlan_hw_extend_enable(dev);
else
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* VLNCTRL: enable vlan filtering and allow all vlan tags through */
uint32_t vlanctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlanctrl |= IXGBE_VLNCTRL_VFE ; /* enable vlan filters */
+ vlanctrl |= IXGBE_VLNCTRL_VFE; /* enable vlan filters */
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlanctrl);
}
!RTE_ETH_DEV_SRIOV(dev).active)
dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
+ if (hw->mac.type == ixgbe_mac_X550 ||
+ hw->mac.type == ixgbe_mac_X550EM_x)
+ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_SCTP_CKSUM |
DEV_TX_OFFLOAD_TCP_TSO;
+ if (hw->mac.type == ixgbe_mac_X550 ||
+ hw->mac.type == ixgbe_mac_X550EM_x)
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+
dev_info->default_rxconf = (struct rte_eth_rxconf) {
.rx_thresh = {
.pthresh = IXGBE_DEFAULT_RX_PTHRESH,
/* Low water mark of zero causes XOFF floods */
if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
/* High/Low water can not be 0 */
- if( (!hw->fc.high_water[tc_num])|| (!hw->fc.low_water[tc_num])) {
+ if ((!hw->fc.high_water[tc_num]) || (!hw->fc.low_water[tc_num])) {
PMD_INIT_LOG(ERR, "Invalid water mark configuration");
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}
- if(hw->fc.low_water[tc_num] >= hw->fc.high_water[tc_num]) {
+ if (hw->fc.low_water[tc_num] >= hw->fc.high_water[tc_num]) {
PMD_INIT_LOG(ERR, "Invalid water mark configuration");
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int32_t ret_val = IXGBE_NOT_IMPLEMENTED;
- if(hw->mac.type != ixgbe_mac_82598EB) {
+ if (hw->mac.type != ixgbe_mac_82598EB) {
ret_val = ixgbe_dcb_pfc_enable_generic(hw,tc_num);
}
return ret_val;
for (i = 0; i < IXGBE_VFTA_SIZE; i++){
vfta = shadow_vfta->vfta[i];
- if(vfta){
+ if (vfta) {
mask = 1;
for (j = 0; j < 32; j++){
- if(vfta & mask)
+ if (vfta & mask)
ixgbe_set_vfta(hw, (i<<5)+j, 0, on);
mask<<=1;
}
/* vind is not used in VF driver, set to 0, check ixgbe_set_vfta_vf */
ret = ixgbe_set_vfta(hw, vlan_id, 0, !!on);
- if(ret){
+ if (ret) {
PMD_INIT_LOG(ERR, "Unable to set VF vlan");
return ret;
}
PMD_INIT_FUNC_TRACE();
- if(queue >= hw->mac.max_rx_queues)
+ if (queue >= hw->mac.max_rx_queues)
return;
ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(queue));
- if(on)
+ if (on)
ctrl |= IXGBE_RXDCTL_VME;
else
ctrl &= ~IXGBE_RXDCTL_VME;
int on = 0;
/* VF function only support hw strip feature, others are not support */
- if(mask & ETH_VLAN_STRIP_MASK){
+ if (mask & ETH_VLAN_STRIP_MASK) {
on = !!(dev->data->dev_conf.rxmode.hw_vlan_strip);
- for(i=0; i < hw->mac.max_rx_queues; i++)
+ for (i = 0; i < hw->mac.max_rx_queues; i++)
ixgbevf_vlan_strip_queue_set(dev,i,on);
}
}
uta_shift = vector & ixgbe_uta_bit_mask;
rc = ((uta_info->uta_shadow[uta_idx] >> uta_shift & bit1) != 0);
- if(rc == on)
+ if (rc == on)
return 0;
reg_val = IXGBE_READ_REG(hw, IXGBE_UTA(uta_idx));
if (hw->mac.type < ixgbe_mac_82599EB)
return -ENOTSUP;
- if(on) {
+ if (on) {
for (i = 0; i < ETH_VMDQ_NUM_UC_HASH_ARRAY; i++) {
uta_info->uta_shadow[i] = ~0;
IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0);
/* search vlan id related pool vlan filter index */
reg_index = ixgbe_find_vlvf_slot(hw,
mirror_conf->vlan.vlan_id[i]);
- if(reg_index < 0)
+ if (reg_index < 0)
return -EINVAL;
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_index));
if ((vlvf & IXGBE_VLVF_VIEN) &&
mr_info->mr_conf[rule_id].vlan.vlan_mask =
mirror_conf->vlan.vlan_mask;
- for(i = 0 ;i < ETH_VMDQ_MAX_VLAN_FILTERS; i++) {
- if(mirror_conf->vlan.vlan_mask & (1ULL << i))
+ for (i = 0; i < ETH_VMDQ_MAX_VLAN_FILTERS; i++) {
+ if (mirror_conf->vlan.vlan_mask & (1ULL << i))
mr_info->mr_conf[rule_id].vlan.vlan_id[i] =
mirror_conf->vlan.vlan_id[i];
}
mv_lsb = 0;
mv_msb = 0;
mr_info->mr_conf[rule_id].vlan.vlan_mask = 0;
- for(i = 0 ;i < ETH_VMDQ_MAX_VLAN_FILTERS; i++)
+ for (i = 0; i < ETH_VMDQ_MAX_VLAN_FILTERS; i++)
mr_info->mr_conf[rule_id].vlan.vlan_id[i] = 0;
}
}
return ret;
}
+static int
+ixgbe_update_vxlan_port(struct ixgbe_hw *hw,
+ uint16_t port)
+{
+ IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, port);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/* There's only one register for VxLAN UDP port.
+ * So, we cannot add several ports. Will update it.
+ */
+static int
+ixgbe_add_vxlan_port(struct ixgbe_hw *hw,
+ uint16_t port)
+{
+ if (port == 0) {
+ PMD_DRV_LOG(ERR, "Add VxLAN port 0 is not allowed.");
+ return -EINVAL;
+ }
+
+ return ixgbe_update_vxlan_port(hw, port);
+}
+
+/* We cannot delete the VxLAN port. For there's a register for VxLAN
+ * UDP port, it must have a value.
+ * So, will reset it to the original value 0.
+ */
+static int
+ixgbe_del_vxlan_port(struct ixgbe_hw *hw,
+ uint16_t port)
+{
+ uint16_t cur_port;
+
+ cur_port = (uint16_t)IXGBE_READ_REG(hw, IXGBE_VXLANCTRL);
+
+ if (cur_port != port) {
+ PMD_DRV_LOG(ERR, "Port %u does not exist.", port);
+ return -EINVAL;
+ }
+
+ return ixgbe_update_vxlan_port(hw, 0);
+}
+
+/* Add UDP tunneling port */
+static int
+ixgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
+ struct rte_eth_udp_tunnel *udp_tunnel)
+{
+ int ret = 0;
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (hw->mac.type != ixgbe_mac_X550 &&
+ hw->mac.type != ixgbe_mac_X550EM_x) {
+ return -ENOTSUP;
+ }
+
+ if (udp_tunnel == NULL)
+ return -EINVAL;
+
+ switch (udp_tunnel->prot_type) {
+ case RTE_TUNNEL_TYPE_VXLAN:
+ ret = ixgbe_add_vxlan_port(hw, udp_tunnel->udp_port);
+ break;
+
+ case RTE_TUNNEL_TYPE_GENEVE:
+ case RTE_TUNNEL_TYPE_TEREDO:
+ PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
+ ret = -EINVAL;
+ break;
+
+ default:
+ PMD_DRV_LOG(ERR, "Invalid tunnel type");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/* Remove UDP tunneling port */
+static int
+ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
+ struct rte_eth_udp_tunnel *udp_tunnel)
+{
+ int ret = 0;
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (hw->mac.type != ixgbe_mac_X550 &&
+ hw->mac.type != ixgbe_mac_X550EM_x) {
+ return -ENOTSUP;
+ }
+
+ if (udp_tunnel == NULL)
+ return -EINVAL;
+
+ switch (udp_tunnel->prot_type) {
+ case RTE_TUNNEL_TYPE_VXLAN:
+ ret = ixgbe_del_vxlan_port(hw, udp_tunnel->udp_port);
+ break;
+ case RTE_TUNNEL_TYPE_GENEVE:
+ case RTE_TUNNEL_TYPE_TEREDO:
+ PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
+ ret = -EINVAL;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Invalid tunnel type");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static struct rte_driver rte_ixgbe_driver = {
.type = PMD_PDEV,
.init = rte_ixgbe_pmd_init,