qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4 4/9] igb: implement VFRE and VFTE registers


From: Akihiko Odaki
Subject: Re: [PATCH v4 4/9] igb: implement VFRE and VFTE registers
Date: Wed, 1 Feb 2023 22:13:15 +0900
User-agent: Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Thunderbird/102.7.0

On 2023/02/01 20:17, Sriram Yagnaraman wrote:
Also introduce:
- Checks for RXDCTL/TXDCTL queue enable bits
- IGB_NUM_VM_POOLS enum (Sec 1.5: Table 1-7)

It may be better to have RXDCTL.ENABLE check in igb_can_receive().


Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
---
  hw/net/igb_core.c | 36 ++++++++++++++++++++++++++++--------
  hw/net/igb_core.h |  1 +
  hw/net/igb_regs.h |  3 +++
  3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 1ddf54f630..c44b30b6d1 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -780,6 +780,18 @@ igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
      return igb_tx_wb_eic(core, txi->idx);
  }
+static inline bool
+igb_tx_enabled(IGBCore *core, const E1000E_RingInfo *txi)
+{
+    bool vmdq = core->mac[MRQC] & 1;
+    uint16_t qn = txi->idx;
+    uint16_t pool = qn % IGB_NUM_VM_POOLS;
+
+    return (core->mac[TCTL] & E1000_TCTL_EN) &&
+        (!vmdq || core->mac[VFTE] & BIT(pool)) &&
+        (core->mac[TXDCTL0 + (qn * 16)] & E1000_TXDCTL_QUEUE_ENABLE);
+}
+
  static void
  igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
  {
@@ -789,8 +801,7 @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
      const E1000E_RingInfo *txi = txr->i;
      uint32_t eic = 0;
- /* TODO: check if the queue itself is enabled too. */
-    if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
+    if (!igb_tx_enabled(core, txi)) {
          trace_e1000e_tx_disabled();
          return;
      }
@@ -932,7 +943,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_NUM_VM_POOLS; i++) {
                  if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
                      queues |= BIT(i);
                  }
@@ -966,7 +977,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_NUM_VM_POOLS; i++) {
                          if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
                              queues |= BIT(i);
                          }
@@ -989,7 +1000,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_NUM_VM_POOLS; i++) {
                      if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
                          mask |= BIT(i);
                      }
@@ -1005,6 +1016,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const 
struct eth_header *ehdr,
              queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT);
          }
+ queues &= core->mac[VFRE];
          igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, 
rss_info);
          if (rss_info->queue & 1) {
              queues <<= 8;
@@ -1562,12 +1574,12 @@ igb_receive_internal(IGBCore *core, const struct iovec 
*iov, int iovcnt,
      igb_rx_fix_l4_csum(core, core->rx_pkt);
for (i = 0; i < IGB_NUM_QUEUES; i++) {
-        if (!(queues & BIT(i))) {
+        if (!(queues & BIT(i)) ||
+            !(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
              continue;
          }
igb_rx_ring_init(core, &rxr, i);
-
          if (!igb_has_rxbufs(core, rxr.i, total_size)) {
              n |= E1000_ICS_RXO;
              trace_e1000e_rx_not_written_to_guest(rxr.i->idx);
@@ -1966,9 +1978,16 @@ static void igb_set_vfmailbox(IGBCore *core, int index, 
uint32_t val)
static void igb_vf_reset(IGBCore *core, uint16_t vfn)
  {
+    uint16_t qn0 = vfn;
+    uint16_t qn1 = vfn + IGB_NUM_VM_POOLS;
+
      /* disable Rx and Tx for the VF*/
-    core->mac[VFTE] &= ~BIT(vfn);
+    core->mac[RXDCTL0 + (qn0 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
+    core->mac[RXDCTL0 + (qn1 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
+    core->mac[TXDCTL0 + (qn0 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
+    core->mac[TXDCTL0 + (qn1 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
      core->mac[VFRE] &= ~BIT(vfn);
+    core->mac[VFTE] &= ~BIT(vfn);
      /* indicate VF reset to PF */
      core->mac[VFLRE] |= BIT(vfn);
      /* VFLRE and mailbox use the same interrupt cause */
@@ -3874,6 +3893,7 @@ igb_phy_reg_init[] = {
  static const uint32_t igb_mac_reg_init[] = {
      [LEDCTL]        = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24),
      [EEMNGCTL]      = BIT(31),
+    [TXDCTL0]       = E1000_TXDCTL_QUEUE_ENABLE,
      [RXDCTL0]       = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16),
      [RXDCTL1]       = 1 << 16,
      [RXDCTL2]       = 1 << 16,
diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h
index cc3b4d1f2b..9938922598 100644
--- a/hw/net/igb_core.h
+++ b/hw/net/igb_core.h
@@ -47,6 +47,7 @@
  #define IGB_MSIX_VEC_NUM        (10)
  #define IGBVF_MSIX_VEC_NUM      (3)
  #define IGB_NUM_QUEUES          (16)
+#define IGB_NUM_VM_POOLS        (8)
typedef struct IGBCore IGBCore; diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
index ddc0f931d6..4d98079906 100644
--- a/hw/net/igb_regs.h
+++ b/hw/net/igb_regs.h
@@ -160,6 +160,9 @@ union e1000_adv_rx_desc {
  #define E1000_MRQC_RSS_FIELD_IPV6_UDP       0x00800000
  #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX    0x01000000
+/* Additional Transmit Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */
+
  /* Additional Receive Descriptor Control definitions */
  #define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]