X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000%2Figb_ethdev.c;h=10ee0f33415af1f2a0d387b161c952afc60d0aef;hb=4a5a1e6b624e46f24b13d095e35a9b8699bd59b9;hp=7f99b76e48d6564e282794ae00854aff06240b08;hpb=2be70bcdb84002f479fae5a49f22d514e31e545d;p=dpdk.git diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index 7f99b76e48..10ee0f3341 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -17,8 +17,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -186,11 +186,6 @@ static int eth_igb_rss_reta_query(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); -static int eth_igb_syn_filter_get(struct rte_eth_dev *dev, - struct rte_eth_syn_filter *filter); -static int eth_igb_syn_filter_handle(struct rte_eth_dev *dev, - enum rte_filter_op filter_op, - void *arg); static int igb_add_2tuple_filter(struct rte_eth_dev *dev, struct rte_eth_ntuple_filter *ntuple_filter); static int igb_remove_2tuple_filter(struct rte_eth_dev *dev, @@ -199,15 +194,8 @@ static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev, struct rte_eth_ntuple_filter *ntuple_filter); static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev, struct rte_eth_ntuple_filter *ntuple_filter); -static int igb_get_ntuple_filter(struct rte_eth_dev *dev, - struct rte_eth_ntuple_filter *filter); -static int igb_ntuple_filter_handle(struct rte_eth_dev *dev, - enum rte_filter_op filter_op, - void *arg); -static int eth_igb_filter_ctrl(struct rte_eth_dev *dev, - enum rte_filter_type filter_type, - enum rte_filter_op filter_op, - void *arg); +static int eth_igb_flow_ops_get(struct rte_eth_dev *dev, + const struct rte_flow_ops **ops); static int eth_igb_get_reg_length(struct rte_eth_dev *dev); static int eth_igb_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs); @@ -384,7 +372,7 @@ static const struct eth_dev_ops eth_igb_ops = { .reta_query = eth_igb_rss_reta_query, .rss_hash_update = eth_igb_rss_hash_update, .rss_hash_conf_get = eth_igb_rss_hash_conf_get, - .filter_ctrl = eth_igb_filter_ctrl, + .flow_ops_get = eth_igb_flow_ops_get, .set_mc_addr_list = eth_igb_set_mc_addr_list, .rxq_info_get = igb_rxq_info_get, .txq_info_get = igb_txq_info_get, @@ -1837,8 +1825,7 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) /* Rx Errors */ rte_stats->imissed = stats->mpc; - rte_stats->ierrors = stats->crcerrs + - stats->rlec + stats->ruc + stats->roc + + rte_stats->ierrors = stats->crcerrs + stats->rlec + stats->rxerrc + stats->algnerrc + stats->cexterr; /* Tx Errors */ @@ -2172,9 +2159,11 @@ eth_igb_fw_version_get(struct rte_eth_dev *dev, char *fw_version, } break; } + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; @@ -2699,8 +2688,7 @@ igb_vlan_hw_extend_disable(struct rte_eth_dev *dev) /* Update maximum packet length */ if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) E1000_WRITE_REG(hw, E1000_RLPML, - dev->data->dev_conf.rxmode.max_rx_pkt_len + - VLAN_TAG_SIZE); + dev->data->dev_conf.rxmode.max_rx_pkt_len); } static void @@ -2719,7 +2707,7 @@ igb_vlan_hw_extend_enable(struct rte_eth_dev *dev) if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) E1000_WRITE_REG(hw, E1000_RLPML, dev->data->dev_conf.rxmode.max_rx_pkt_len + - 2 * VLAN_TAG_SIZE); + VLAN_TAG_SIZE); } static int @@ -3074,6 +3062,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) uint32_t rx_buf_size; uint32_t max_high_water; uint32_t rctl; + uint32_t ctrl; hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); if (fc_conf->autoneg != hw->mac.autoneg) @@ -3111,6 +3100,39 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) rctl &= ~E1000_RCTL_PMCF; E1000_WRITE_REG(hw, E1000_RCTL, rctl); + + /* + * check if we want to change flow control mode - driver doesn't have native + * capability to do that, so we'll write the registers ourselves + */ + ctrl = E1000_READ_REG(hw, E1000_CTRL); + + /* + * set or clear E1000_CTRL_RFCE and E1000_CTRL_TFCE bits depending + * on configuration + */ + switch (fc_conf->mode) { + case RTE_FC_NONE: + ctrl &= ~E1000_CTRL_RFCE & ~E1000_CTRL_TFCE; + break; + case RTE_FC_RX_PAUSE: + ctrl |= E1000_CTRL_RFCE; + ctrl &= ~E1000_CTRL_TFCE; + break; + case RTE_FC_TX_PAUSE: + ctrl |= E1000_CTRL_TFCE; + ctrl &= ~E1000_CTRL_RFCE; + break; + case RTE_FC_FULL: + ctrl |= E1000_CTRL_RFCE | E1000_CTRL_TFCE; + break; + default: + PMD_INIT_LOG(ERR, "invalid flow control mode"); + return -EINVAL; + } + + E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + E1000_WRITE_FLUSH(hw); return 0; @@ -3670,68 +3692,6 @@ eth_igb_syn_filter_set(struct rte_eth_dev *dev, return 0; } -static int -eth_igb_syn_filter_get(struct rte_eth_dev *dev, - struct rte_eth_syn_filter *filter) -{ - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint32_t synqf, rfctl; - - synqf = E1000_READ_REG(hw, E1000_SYNQF(0)); - if (synqf & E1000_SYN_FILTER_ENABLE) { - rfctl = E1000_READ_REG(hw, E1000_RFCTL); - filter->hig_pri = (rfctl & E1000_RFCTL_SYNQFP) ? 1 : 0; - filter->queue = (uint8_t)((synqf & E1000_SYN_FILTER_QUEUE) >> - E1000_SYN_FILTER_QUEUE_SHIFT); - return 0; - } - - return -ENOENT; -} - -static int -eth_igb_syn_filter_handle(struct rte_eth_dev *dev, - enum rte_filter_op filter_op, - void *arg) -{ - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - int ret; - - MAC_TYPE_FILTER_SUP(hw->mac.type); - - if (filter_op == RTE_ETH_FILTER_NOP) - return 0; - - if (arg == NULL) { - PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u", - filter_op); - return -EINVAL; - } - - switch (filter_op) { - case RTE_ETH_FILTER_ADD: - ret = eth_igb_syn_filter_set(dev, - (struct rte_eth_syn_filter *)arg, - TRUE); - break; - case RTE_ETH_FILTER_DELETE: - ret = eth_igb_syn_filter_set(dev, - (struct rte_eth_syn_filter *)arg, - FALSE); - break; - case RTE_ETH_FILTER_GET: - ret = eth_igb_syn_filter_get(dev, - (struct rte_eth_syn_filter *)arg); - break; - default: - PMD_DRV_LOG(ERR, "unsupported operation %u", filter_op); - ret = -EINVAL; - break; - } - - return ret; -} - /* translate elements in struct rte_eth_ntuple_filter to struct e1000_2tuple_filter_info*/ static inline int ntuple_filter_to_2tuple(struct rte_eth_ntuple_filter *filter, @@ -4050,7 +4010,7 @@ igb_remove_flex_filter(struct rte_eth_dev *dev, int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev, - struct rte_eth_flex_filter *filter, + struct igb_flex_filter *filter, bool add) { struct e1000_filter_info *filter_info = @@ -4432,16 +4392,20 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) frame_size > dev_info.max_rx_pktlen) return -EINVAL; - /* refuse mtu that requires the support of scattered packets when this - * feature has not been enabled before. */ - if (!dev->data->scattered_rx && - frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) + /* + * If device is started, refuse mtu that requires the support of + * scattered packets when this feature has not been enabled before. + */ + if (dev->data->dev_started && !dev->data->scattered_rx && + frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { + PMD_INIT_LOG(ERR, "Stop port first."); return -EINVAL; + } rctl = E1000_READ_REG(hw, E1000_RCTL); /* switch to jumbo mode if needed */ - if (frame_size > RTE_ETHER_MAX_LEN) { + if (frame_size > E1000_ETH_MAX_LEN) { dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; rctl |= E1000_RCTL_LPE; @@ -4512,126 +4476,6 @@ igb_add_del_ntuple_filter(struct rte_eth_dev *dev, return ret; } -/* - * igb_get_ntuple_filter - get a ntuple filter - * - * @param - * dev: Pointer to struct rte_eth_dev. - * ntuple_filter: Pointer to struct rte_eth_ntuple_filter - * - * @return - * - On success, zero. - * - On failure, a negative value. - */ -static int -igb_get_ntuple_filter(struct rte_eth_dev *dev, - struct rte_eth_ntuple_filter *ntuple_filter) -{ - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct e1000_filter_info *filter_info = - E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); - struct e1000_5tuple_filter_info filter_5tuple; - struct e1000_2tuple_filter_info filter_2tuple; - struct e1000_5tuple_filter *p_5tuple_filter; - struct e1000_2tuple_filter *p_2tuple_filter; - int ret; - - switch (ntuple_filter->flags) { - case RTE_5TUPLE_FLAGS: - case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG): - if (hw->mac.type != e1000_82576) - return -ENOTSUP; - memset(&filter_5tuple, - 0, - sizeof(struct e1000_5tuple_filter_info)); - ret = ntuple_filter_to_5tuple_82576(ntuple_filter, - &filter_5tuple); - if (ret < 0) - return ret; - p_5tuple_filter = igb_5tuple_filter_lookup_82576( - &filter_info->fivetuple_list, - &filter_5tuple); - if (p_5tuple_filter == NULL) { - PMD_DRV_LOG(ERR, "filter doesn't exist."); - return -ENOENT; - } - ntuple_filter->queue = p_5tuple_filter->queue; - break; - case RTE_2TUPLE_FLAGS: - case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG): - if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350) - return -ENOTSUP; - memset(&filter_2tuple, - 0, - sizeof(struct e1000_2tuple_filter_info)); - ret = ntuple_filter_to_2tuple(ntuple_filter, &filter_2tuple); - if (ret < 0) - return ret; - p_2tuple_filter = igb_2tuple_filter_lookup( - &filter_info->twotuple_list, - &filter_2tuple); - if (p_2tuple_filter == NULL) { - PMD_DRV_LOG(ERR, "filter doesn't exist."); - return -ENOENT; - } - ntuple_filter->queue = p_2tuple_filter->queue; - break; - default: - ret = -EINVAL; - break; - } - - return 0; -} - -/* - * igb_ntuple_filter_handle - Handle operations for ntuple filter. - * @dev: pointer to rte_eth_dev structure - * @filter_op:operation will be taken. - * @arg: a pointer to specific structure corresponding to the filter_op - */ -static int -igb_ntuple_filter_handle(struct rte_eth_dev *dev, - enum rte_filter_op filter_op, - void *arg) -{ - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - int ret; - - MAC_TYPE_FILTER_SUP(hw->mac.type); - - if (filter_op == RTE_ETH_FILTER_NOP) - return 0; - - if (arg == NULL) { - PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.", - filter_op); - return -EINVAL; - } - - switch (filter_op) { - case RTE_ETH_FILTER_ADD: - ret = igb_add_del_ntuple_filter(dev, - (struct rte_eth_ntuple_filter *)arg, - TRUE); - break; - case RTE_ETH_FILTER_DELETE: - ret = igb_add_del_ntuple_filter(dev, - (struct rte_eth_ntuple_filter *)arg, - FALSE); - break; - case RTE_ETH_FILTER_GET: - ret = igb_get_ntuple_filter(dev, - (struct rte_eth_ntuple_filter *)arg); - break; - default: - PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op); - ret = -EINVAL; - break; - } - return ret; -} - static inline int igb_ethertype_filter_lookup(struct e1000_filter_info *filter_info, uint16_t ethertype) @@ -4737,32 +4581,11 @@ igb_add_del_ethertype_filter(struct rte_eth_dev *dev, } static int -eth_igb_filter_ctrl(struct rte_eth_dev *dev, - enum rte_filter_type filter_type, - enum rte_filter_op filter_op, - void *arg) +eth_igb_flow_ops_get(struct rte_eth_dev *dev __rte_unused, + const struct rte_flow_ops **ops) { - int ret = 0; - - switch (filter_type) { - case RTE_ETH_FILTER_NTUPLE: - ret = igb_ntuple_filter_handle(dev, filter_op, arg); - break; - case RTE_ETH_FILTER_SYN: - ret = eth_igb_syn_filter_handle(dev, filter_op, arg); - break; - case RTE_ETH_FILTER_GENERIC: - if (filter_op != RTE_ETH_FILTER_GET) - return -EINVAL; - *(const void **)arg = &igb_flow_ops; - break; - default: - PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", - filter_type); - break; - } - - return ret; + *ops = &igb_flow_ops; + return 0; } static int @@ -5296,9 +5119,6 @@ eth_igb_get_module_eeprom(struct rte_eth_dev *dev, u16 first_word, last_word; int i = 0; - if (info->length == 0) - return -EINVAL; - first_word = info->offset >> 1; last_word = (info->offset + info->length - 1) >> 1; @@ -5598,9 +5418,3 @@ RTE_PMD_REGISTER_KMOD_DEP(net_e1000_igb, "* igb_uio | uio_pci_generic | vfio-pci RTE_PMD_REGISTER_PCI(net_e1000_igb_vf, rte_igbvf_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_e1000_igb_vf, pci_id_igbvf_map); RTE_PMD_REGISTER_KMOD_DEP(net_e1000_igb_vf, "* igb_uio | vfio-pci"); - -/* see e1000_logs.c */ -RTE_INIT(e1000_init_log) -{ - e1000_igb_init_log(); -}