#include "igc_logs.h"
#include "igc_txrx.h"
+#include "igc_filter.h"
+#include "igc_flow.h"
#define IGC_INTEL_VENDOR_ID 0x8086
/* External VLAN Enable bit mask */
#define IGC_CTRL_EXT_EXT_VLAN (1u << 26)
+/* Speed select */
+#define IGC_CTRL_SPEED_MASK (7u << 8)
+#define IGC_CTRL_SPEED_2500 (6u << 8)
+
/* External VLAN Ether Type bit mask and shift */
#define IGC_VET_EXT 0xFFFF0000
#define IGC_VET_EXT_SHIFT 16
+/* Force EEE Auto-negotiation */
+#define IGC_EEER_EEE_FRC_AN (1u << 28)
+
/* Per Queue Good Packets Received Count */
#define IGC_PQGPRC(idx) (0x10010 + 0x100 * (idx))
/* Per Queue Good Octets Received Count */
.vlan_offload_set = eth_igc_vlan_offload_set,
.vlan_tpid_set = eth_igc_vlan_tpid_set,
.vlan_strip_queue_set = eth_igc_vlan_strip_queue_set,
+ .filter_ctrl = eth_igc_filter_ctrl,
};
/*
/* disable all wake up */
IGC_WRITE_REG(hw, IGC_WUC, 0);
+ /* disable checking EEE operation in MAC loopback mode */
+ igc_read_reg_check_clear_bits(hw, IGC_EEER, IGC_EEER_EEE_FRC_AN);
+
/* Set bit for Go Link disconnect */
igc_read_reg_check_set_bits(hw, IGC_82580_PHY_POWER_MGMT,
IGC_82580_PM_GO_LINKD);
eth_igc_rxtx_control(dev, true);
eth_igc_link_update(dev, 0);
+ /* configure MAC-loopback mode */
+ if (dev->data->dev_conf.lpbk_mode == 1) {
+ uint32_t reg_val;
+
+ reg_val = IGC_READ_REG(hw, IGC_CTRL);
+ reg_val &= ~IGC_CTRL_SPEED_MASK;
+ reg_val |= IGC_CTRL_SLU | IGC_CTRL_FRCSPD |
+ IGC_CTRL_FRCDPX | IGC_CTRL_FD | IGC_CTRL_SPEED_2500;
+ IGC_WRITE_REG(hw, IGC_CTRL, reg_val);
+
+ igc_read_reg_check_set_bits(hw, IGC_EEER, IGC_EEER_EEE_FRC_AN);
+ }
+
return 0;
error_invalid_config:
if (!adapter->stopped)
eth_igc_stop(dev);
+ igc_flow_flush(dev, NULL);
+ igc_clear_all_filter(dev);
+
igc_intr_other_disable(dev);
do {
int ret = rte_intr_callback_unregister(intr_handle,
igc->rxq_stats_map[i] = -1;
}
+ igc_flow_init(dev);
+ igc_clear_all_filter(dev);
return 0;
err_late:
return -EINVAL;
}
+ RTE_BUILD_BUG_ON(ETH_RSS_RETA_SIZE_128 % IGC_RSS_RDT_REG_SIZE);
+
/* set redirection table */
for (i = 0; i < ETH_RSS_RETA_SIZE_128; i += IGC_RSS_RDT_REG_SIZE) {
union igc_rss_reta_reg reta, reg;
IGC_RSS_RDT_REG_SIZE_MASK);
/* if no need to update the register */
- if (!mask)
+ if (!mask ||
+ shift > (RTE_RETA_GROUP_SIZE - IGC_RSS_RDT_REG_SIZE))
continue;
/* check mask whether need to read the register value first */
IGC_RETA(i / IGC_RSS_RDT_REG_SIZE));
/* update the register */
+ RTE_BUILD_BUG_ON(sizeof(reta.bytes) != IGC_RSS_RDT_REG_SIZE);
for (j = 0; j < IGC_RSS_RDT_REG_SIZE; j++) {
if (mask & (1u << j))
reta.bytes[j] =
return -EINVAL;
}
+ RTE_BUILD_BUG_ON(ETH_RSS_RETA_SIZE_128 % IGC_RSS_RDT_REG_SIZE);
+
/* read redirection table */
for (i = 0; i < ETH_RSS_RETA_SIZE_128; i += IGC_RSS_RDT_REG_SIZE) {
union igc_rss_reta_reg reta;
IGC_RSS_RDT_REG_SIZE_MASK);
/* if no need to read register */
- if (!mask)
+ if (!mask ||
+ shift > (RTE_RETA_GROUP_SIZE - IGC_RSS_RDT_REG_SIZE))
continue;
/* read register and get the queue index */
+ RTE_BUILD_BUG_ON(sizeof(reta.bytes) != IGC_RSS_RDT_REG_SIZE);
reta.dword = IGC_READ_REG_LE_VALUE(hw,
IGC_RETA(i / IGC_RSS_RDT_REG_SIZE));
for (j = 0; j < IGC_RSS_RDT_REG_SIZE; j++) {