On 2023/01/28 22:46, Sriram Yagnaraman wrote:
RSS for VFs is only enabled if VMOLR[n].RSSE is set.

Signed-off-by: Sriram Yagnaraman <sriram.yagnara...@est.tech>
---
  hw/net/igb_core.c | 18 +++++++++++++-----
  1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 1eb7ba168f..e4fd4a1a5f 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -69,7 +69,7 @@ typedef struct IGBTxPktVmdqCallbackContext {
static ssize_t
  igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
-                     bool has_vnet, bool *assigned);
+                     bool has_vnet, bool *external_tx);

I admit external_tx is somewhat confusing, but it is more than just telling if it is assigned to Rx queue or not. If external_tx is not NULL, it indicates it is part of Tx packet switching. In that case, a bool value which describes whether the packet should be routed to external LAN must be assigned. The value can be false even if the packet is assigned to Rx queues; it will be always false if it is multicast, for example.

static inline void
  igb_set_interrupt_cause(IGBCore *core, uint32_t val);
@@ -942,7 +942,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const 
struct eth_header *ehdr,
if (core->mac[MRQC] & 1) {
          if (is_broadcast_ether_addr(ehdr->h_dest)) {
-            for (i = 0; i < 8; i++) {
+            for (i = 0; i < IGB_MAX_VF_FUNCTIONS; i++) {

I just left it as 8 because VMDq is not specific to VF. Perhaps it is better to have another macro to denote the number of VMDq pools, but it is not done yet.

                  if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
                      queues |= BIT(i);
                  }
@@ -976,7 +976,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const 
struct eth_header *ehdr,
                  f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
                  f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff;
                  if (macp[f >> 5] & (1 << (f & 0x1f))) {
-                    for (i = 0; i < 8; i++) {
+                    for (i = 0; i < IGB_MAX_VF_FUNCTIONS; i++) {
                          if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
                              queues |= BIT(i);
                          }
@@ -999,7 +999,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const 
struct eth_header *ehdr,
                      }
                  }
              } else {
-                for (i = 0; i < 8; i++) {
+                for (i = 0; i < IGB_MAX_VF_FUNCTIONS; i++) {
                      if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
                          mask |= BIT(i);
                      }
@@ -1018,7 +1018,15 @@ static uint16_t igb_receive_assign(IGBCore *core, const 
struct eth_header *ehdr,
          queues &= core->mac[VFRE];
          igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, 
rss_info);
          if (rss_info->queue & 1) {
-            queues <<= 8;
+            for (i = 0; i < IGB_MAX_VF_FUNCTIONS; i++) {
+                if (!(queues & BIT(i))) {
+                    continue;
+                }
+                if (core->mac[VMOLR0 + i] & E1000_VMOLR_RSSE) {
+                    queues |= BIT(i + IGB_MAX_VF_FUNCTIONS);
+                    queues &= ~BIT(i);
+                }
+            }
          }
      } else {
          switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {

Reply via email to