X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Focteontx%2Focteontx_ethdev_ops.c;h=dbe13ce3826b15100feba5d47c7342cda4327d83;hb=b8f5d2ae75c97698190d46f4810d01f407016aad;hp=8c30655428485944b66427b0a51d8b4c1f2a609b;hpb=56139e85abec19ac9e91aed610abdb0c3629a638;p=dpdk.git diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c b/drivers/net/octeontx/octeontx_ethdev_ops.c index 8c30655428..dbe13ce382 100644 --- a/drivers/net/octeontx/octeontx_ethdev_ops.c +++ b/drivers/net/octeontx/octeontx_ethdev_ops.c @@ -43,16 +43,6 @@ octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) rxmode = &dev->data->dev_conf.rxmode; - if (mask & ETH_VLAN_EXTEND_MASK) { - octeontx_log_err("Extend offload not supported"); - return -ENOTSUP; - } - - if (mask & ETH_VLAN_STRIP_MASK) { - octeontx_log_err("VLAN strip offload not supported"); - return -ENOTSUP; - } - if (mask & ETH_VLAN_FILTER_MASK) { if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { rc = octeontx_vlan_hw_filter(nic, true); @@ -182,3 +172,162 @@ octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev) return rc; } + +int +octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev); + int rc, i; + + rc = octeontx_bgx_port_set_link_state(nic->port_id, true); + if (rc) + goto done; + + /* Start tx queues */ + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) + octeontx_dev_tx_queue_start(eth_dev, i); + +done: + return rc; +} + +int +octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev); + int i; + + /* Stop tx queues */ + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) + octeontx_dev_tx_queue_stop(eth_dev, i); + + return octeontx_bgx_port_set_link_state(nic->port_id, false); +} + +int +octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + octeontx_mbox_bgx_port_fc_cfg_t conf; + int rc; + + memset(&conf, 0, sizeof(octeontx_mbox_bgx_port_fc_cfg_t)); + + rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf); + if (rc) + return rc; + + if (conf.rx_pause && conf.tx_pause) + fc_conf->mode = RTE_FC_FULL; + else if (conf.rx_pause) + fc_conf->mode = RTE_FC_RX_PAUSE; + else if (conf.tx_pause) + fc_conf->mode = RTE_FC_TX_PAUSE; + else + fc_conf->mode = RTE_FC_NONE; + + /* low_water & high_water values are in Bytes */ + fc_conf->low_water = conf.low_water; + fc_conf->high_water = conf.high_water; + + return rc; +} + +int +octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + struct octeontx_fc_info *fc = &nic->fc; + octeontx_mbox_bgx_port_fc_cfg_t conf; + uint8_t tx_pause, rx_pause; + uint16_t max_high_water; + int rc; + + if (fc_conf->pause_time || fc_conf->mac_ctrl_frame_fwd || + fc_conf->autoneg) { + octeontx_log_err("Below flowctrl parameters are not supported " + "pause_time, mac_ctrl_frame_fwd and autoneg"); + return -EINVAL; + } + + if (fc_conf->high_water == fc->high_water && + fc_conf->low_water == fc->low_water && + fc_conf->mode == fc->mode) + return 0; + + max_high_water = fc->rx_fifosz - OCTEONTX_BGX_RSVD_RX_FIFOBYTES; + + if (fc_conf->high_water > max_high_water || + fc_conf->high_water < fc_conf->low_water) { + octeontx_log_err("Invalid high/low water values " + "High_water(in Bytes) must <= 0x%x ", + max_high_water); + return -EINVAL; + } + + if (fc_conf->high_water % BIT(4) || fc_conf->low_water % BIT(4)) { + octeontx_log_err("High/low water value must be multiple of 16"); + return -EINVAL; + } + + rx_pause = (fc_conf->mode == RTE_FC_FULL) || + (fc_conf->mode == RTE_FC_RX_PAUSE); + tx_pause = (fc_conf->mode == RTE_FC_FULL) || + (fc_conf->mode == RTE_FC_TX_PAUSE); + + conf.high_water = fc_conf->high_water; + conf.low_water = fc_conf->low_water; + conf.fc_cfg = BGX_PORT_FC_CFG_SET; + conf.rx_pause = rx_pause; + conf.tx_pause = tx_pause; + + rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf); + if (rc) + return rc; + + fc->high_water = fc_conf->high_water; + fc->low_water = fc_conf->low_water; + fc->mode = fc_conf->mode; + + return rc; +} + +int +octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + struct octeontx_fc_info *fc = &nic->fc; + struct rte_eth_fc_conf fc_conf; + int rc; + + rc = octeontx_dev_flow_ctrl_get(dev, &fc_conf); + if (rc) { + octeontx_log_err("Failed to get flow control info"); + return rc; + } + + fc->def_highmark = fc_conf.high_water; + fc->def_lowmark = fc_conf.low_water; + fc->def_mode = fc_conf.mode; + + return rc; +} + +int +octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev) +{ + struct octeontx_nic *nic = octeontx_pmd_priv(dev); + struct octeontx_fc_info *fc = &nic->fc; + struct rte_eth_fc_conf fc_conf; + + memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf)); + + /* Restore flow control parameters with default values */ + fc_conf.high_water = fc->def_highmark; + fc_conf.low_water = fc->def_lowmark; + fc_conf.mode = fc->def_mode; + + return octeontx_dev_flow_ctrl_set(dev, &fc_conf); +}