From 466757e6fc749c546155f4652eb39705fcb24f0f Mon Sep 17 00:00:00 2001 From: Shaopeng He Date: Thu, 4 Feb 2016 20:43:21 +0800 Subject: [PATCH] fm10k: enable broadcast loopback suppression In FM10K, a single PCIe port can derive out a few logical ports, like SRIOV PF/VF devices, VMDQ objects. To better manage them, FM10K silicon assigns a Unique GLORT ID to each logical port. When a logical port sends a broadcast packet, the silicon will flood it to all logical ports, including the one that sent the broadcast packet. To prevent this, silicon has an rxq register to store the glort id of the logical port that queue binds to. FM10K has a switch core inside, which has a loopback suppression mechanism in the switch level. Switch level loopback suppression mostly works for the ether port traffic. This patch assigns a SGLORT for each RX queue, and enables PCIe port level loopback suppression. Signed-off-by: Shaopeng He Acked-by: Jing Chen --- drivers/net/fm10k/fm10k_ethdev.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index 068a20c014..3ae604ddb9 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -687,13 +687,16 @@ static int fm10k_dev_rx_init(struct rte_eth_dev *dev) { struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct fm10k_macvlan_filter_info *macvlan; struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle; int i, ret; struct fm10k_rx_queue *rxq; uint64_t base_addr; uint32_t size; uint32_t rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY; + uint32_t logic_port = hw->mac.dglort_map; uint16_t buf_size; + uint16_t queue_stride = 0; /* enable RXINT for interrupt mode */ i = 0; @@ -748,7 +751,8 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev) buf_size -= FM10K_RX_DATABUF_ALIGN; FM10K_WRITE_REG(hw, FM10K_SRRCTL(i), - buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT); + (buf_size >> FM10K_SRRCTL_BSIZEPKT_SHIFT) | + FM10K_SRRCTL_LOOPBACK_SUPPRESS); /* It adds dual VLAN length for supporting dual VLAN */ if ((dev->data->dev_conf.rxmode.max_rx_pkt_len + @@ -775,6 +779,18 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev) /* Decide the best RX function */ fm10k_set_rx_function(dev); + /* update RX_SGLORT for loopback suppress*/ + if (hw->mac.type != fm10k_mac_pf) + return 0; + macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data->dev_private); + if (macvlan->nb_queue_pools) + queue_stride = dev->data->nb_rx_queues / macvlan->nb_queue_pools; + for (i = 0; i < dev->data->nb_rx_queues; ++i) { + if (i && queue_stride && !(i % queue_stride)) + logic_port++; + FM10K_WRITE_REG(hw, FM10K_RX_SGLORT(i), logic_port); + } + return 0; }