X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Figc%2Figc_ethdev.c;h=6ab3ee909d1bb28015555437e1998be8abd6b668;hb=8688fcf030f746b07ecc70b382ca60b0f731b016;hp=15b63d1fd3caaf3b786b717b28d7e9d4b48af2b2;hpb=5f266d0d8c6decb07fef3d6a6f828bcc75f5fefe;p=dpdk.git diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c index 15b63d1fd3..6ab3ee909d 100644 --- a/drivers/net/igc/igc_ethdev.c +++ b/drivers/net/igc/igc_ethdev.c @@ -15,6 +15,8 @@ #include "igc_logs.h" #include "igc_txrx.h" +#include "igc_filter.h" +#include "igc_flow.h" #define IGC_INTEL_VENDOR_ID 0x8086 @@ -50,10 +52,17 @@ /* 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 */ @@ -292,6 +301,7 @@ static const struct eth_dev_ops eth_igc_ops = { .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, }; /* @@ -635,6 +645,9 @@ eth_igc_stop(struct rte_eth_dev *dev) /* 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); @@ -1060,6 +1073,19 @@ eth_igc_start(struct rte_eth_dev *dev) 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: @@ -1158,6 +1184,9 @@ eth_igc_close(struct rte_eth_dev *dev) 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, @@ -1325,6 +1354,8 @@ eth_igc_dev_init(struct rte_eth_dev *dev) igc->rxq_stats_map[i] = -1; } + igc_flow_init(dev); + igc_clear_all_filter(dev); return 0; err_late: @@ -2235,6 +2266,8 @@ eth_igc_rss_reta_update(struct rte_eth_dev *dev, 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; @@ -2247,7 +2280,8 @@ eth_igc_rss_reta_update(struct rte_eth_dev *dev, 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 */ @@ -2258,6 +2292,7 @@ eth_igc_rss_reta_update(struct rte_eth_dev *dev, 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] = @@ -2287,6 +2322,8 @@ eth_igc_rss_reta_query(struct rte_eth_dev *dev, 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; @@ -2299,10 +2336,12 @@ eth_igc_rss_reta_query(struct rte_eth_dev *dev, 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++) {