diff options
| -rw-r--r-- | sys/dev/aq/aq_hw.c | 12 | ||||
| -rw-r--r-- | sys/dev/aq/aq_hw.h | 2 | ||||
| -rw-r--r-- | sys/dev/aq/aq_main.c | 3 |
3 files changed, 14 insertions, 3 deletions
diff --git a/sys/dev/aq/aq_hw.c b/sys/dev/aq/aq_hw.c index f73805a939cd..5a45e61041c3 100644 --- a/sys/dev/aq/aq_hw.c +++ b/sys/dev/aq/aq_hw.c @@ -878,8 +878,16 @@ aq_hw_rss_set(struct aq_hw_s *self, memset(bitary, 0, sizeof(bitary)); for (i = HW_ATL_RSS_INDIRECTION_TABLE_MAX; i--;) { - (*(uint32_t *)(bitary + ((i * 3U) / 16U))) |= - ((rss_table[i]) << ((i * 3U) & 0xFU)); + uint32_t bit_pos = i * HW_ATL_RSS_INDIRECTION_ENTRY_BITS; + uint32_t word = bit_pos / 16U; + uint32_t shift = bit_pos % 16U; + uint32_t field = (uint32_t)(rss_table[i] & + (HW_ATL_RSS_INDIRECTION_QUEUES_MAX - 1U)) << shift; + + bitary[word] |= (uint16_t)field; + if (shift + HW_ATL_RSS_INDIRECTION_ENTRY_BITS > 16U && + word + 1U < ARRAY_SIZE(bitary)) + bitary[word + 1U] |= (uint16_t)(field >> 16); } for (i = ARRAY_SIZE(bitary); i--;) { diff --git a/sys/dev/aq/aq_hw.h b/sys/dev/aq/aq_hw.h index a4d4dbb3a512..bdd79871fd76 100644 --- a/sys/dev/aq/aq_hw.h +++ b/sys/dev/aq/aq_hw.h @@ -197,6 +197,8 @@ struct aq_hw { #define HW_ATL_RSS_INDIRECTION_TABLE_MAX 64U #define HW_ATL_RSS_HASHKEY_SIZE 40U +#define HW_ATL_RSS_INDIRECTION_QUEUES_MAX 8U +#define HW_ATL_RSS_INDIRECTION_ENTRY_BITS 3U /* PCI core control register */ #define AQ_HW_PCI_REG_CONTROL_6_ADR 0x1014U diff --git a/sys/dev/aq/aq_main.c b/sys/dev/aq/aq_main.c index 2ed9bd050780..e893bb7f73b3 100644 --- a/sys/dev/aq/aq_main.c +++ b/sys/dev/aq/aq_main.c @@ -466,8 +466,9 @@ aq_if_attach_post(if_ctx_t ctx) aq_add_stats_sysctls(softc); /* RSS */ arc4rand(softc->rss_key, HW_ATL_RSS_HASHKEY_SIZE, 0); + uint32_t rss_qs = MIN(softc->rx_rings_count, HW_ATL_RSS_INDIRECTION_QUEUES_MAX); for (int i = ARRAY_SIZE(softc->rss_table); i--;){ - softc->rss_table[i] = i & (softc->rx_rings_count - 1); + softc->rss_table[i] = i % rss_qs; } exit: AQ_DBG_EXIT(rc); |
