-
Notifications
You must be signed in to change notification settings - Fork 4
[PWCI] "net/r8169: support multiq and code refactor" #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,7 +47,16 @@ static int rtl_allmulticast_disable(struct rte_eth_dev *dev); | |
| static int rtl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); | ||
| static int rtl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, | ||
| size_t fw_size); | ||
|
|
||
| static int rtl_reta_update(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_reta_entry64 *reta_conf, | ||
| uint16_t reta_size); | ||
| static int rtl_reta_query(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_reta_entry64 *reta_conf, | ||
| uint16_t reta_size); | ||
| static int rtl_rss_hash_update(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_conf *rss_conf); | ||
| static int rtl_rss_hash_conf_get(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_conf *rss_conf); | ||
| /* | ||
| * The set of PCI devices this driver supports | ||
| */ | ||
|
|
@@ -108,6 +117,11 @@ static const struct eth_dev_ops rtl_eth_dev_ops = { | |
| .tx_queue_release = rtl_tx_queue_release, | ||
| .tx_done_cleanup = rtl_tx_done_cleanup, | ||
| .txq_info_get = rtl_txq_info_get, | ||
|
|
||
| .reta_update = rtl_reta_update, | ||
| .reta_query = rtl_reta_query, | ||
| .rss_hash_update = rtl_rss_hash_update, | ||
| .rss_hash_conf_get = rtl_rss_hash_conf_get, | ||
| }; | ||
|
|
||
| static int | ||
|
|
@@ -150,26 +164,19 @@ _rtl_setup_link(struct rte_eth_dev *dev) | |
|
|
||
| /* Setup link speed and duplex */ | ||
| if (*link_speeds == RTE_ETH_LINK_SPEED_AUTONEG) { | ||
| switch (hw->mcfg) { | ||
| case CFG_METHOD_48: | ||
| case CFG_METHOD_49: | ||
| case CFG_METHOD_50: | ||
| case CFG_METHOD_51: | ||
| case CFG_METHOD_52: | ||
| case CFG_METHOD_53: | ||
| case CFG_METHOD_54: | ||
| case CFG_METHOD_55: | ||
| case CFG_METHOD_56: | ||
| case CFG_METHOD_57: | ||
| case CFG_METHOD_58: | ||
| switch (hw->chipset_name) { | ||
| case RTL8125A: | ||
| case RTL8125B: | ||
| case RTL8168KB: | ||
| case RTL8125BP: | ||
| case RTL8125D: | ||
| case RTL8125CP: | ||
| speed_mode = SPEED_2500; | ||
| break; | ||
| case CFG_METHOD_69: | ||
| case CFG_METHOD_70: | ||
| case CFG_METHOD_71: | ||
| case RTL8126A: | ||
| speed_mode = SPEED_5000; | ||
| break; | ||
| case CFG_METHOD_91: | ||
| case RTL8127: | ||
| speed_mode = SPEED_10000; | ||
| break; | ||
| default: | ||
|
|
@@ -408,8 +415,13 @@ rtl_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) | |
| dev_info->max_rx_pktlen = JUMBO_FRAME_9K; | ||
| dev_info->max_mac_addrs = 1; | ||
|
|
||
| dev_info->max_rx_queues = 1; | ||
| dev_info->max_tx_queues = 1; | ||
| if (hw->mcfg >= CFG_METHOD_69) { | ||
| dev_info->max_rx_queues = 4; | ||
| dev_info->max_tx_queues = 2; | ||
| } else { | ||
| dev_info->max_rx_queues = 1; | ||
| dev_info->max_tx_queues = 1; | ||
| } | ||
|
|
||
| dev_info->default_rxconf = (struct rte_eth_rxconf) { | ||
| .rx_free_thresh = RTL_RX_FREE_THRESH, | ||
|
|
@@ -445,10 +457,14 @@ rtl_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) | |
| dev_info->min_mtu = RTE_ETHER_MIN_MTU; | ||
| dev_info->max_mtu = dev_info->max_rx_pktlen - RTL_ETH_OVERHEAD; | ||
|
|
||
| dev_info->rx_offload_capa = (rtl_get_rx_port_offloads() | | ||
| dev_info->rx_offload_capa = (rtl_get_rx_port_offloads(hw) | | ||
| dev_info->rx_queue_offload_capa); | ||
| dev_info->tx_offload_capa = rtl_get_tx_port_offloads(); | ||
|
|
||
| dev_info->hash_key_size = RTL_RSS_KEY_SIZE; | ||
| dev_info->reta_size = RTL_MAX_INDIRECTION_TABLE_ENTRIES; | ||
| dev_info->flow_type_rss_offloads = RTL_RSS_CTRL_OFFLOAD_ALL; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
|
|
@@ -535,7 +551,7 @@ rtl_sw_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) | |
|
|
||
| static int | ||
| rtl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats, | ||
| struct eth_queue_stats *qstats __rte_unused) | ||
| struct eth_queue_stats *qstats __rte_unused) | ||
| { | ||
| struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); | ||
| struct rtl_hw *hw = &adapter->hw; | ||
|
|
@@ -709,6 +725,160 @@ rtl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) | |
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| rtl_reta_update(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) | ||
| { | ||
| struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); | ||
| struct rtl_hw *hw = &adapter->hw; | ||
| u32 reta; | ||
| u16 idx, shift; | ||
| u8 mask, rss_indir_tbl; | ||
| int i, j; | ||
|
|
||
| if (reta_size != RTL_MAX_INDIRECTION_TABLE_ENTRIES) { | ||
| PMD_DRV_LOG(ERR, "The size of hash lookup table configured " | ||
| "(%d) doesn't match the number hardware can supported " | ||
| "(%d)", reta_size, RTL_MAX_INDIRECTION_TABLE_ENTRIES); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| for (i = 0; i < reta_size; i += 4) { | ||
| idx = i / RTE_ETH_RETA_GROUP_SIZE; | ||
| shift = i % RTE_ETH_RETA_GROUP_SIZE; | ||
| mask = (reta_conf[idx].mask >> shift) & 0xf; | ||
|
|
||
| if (!mask) | ||
| continue; | ||
|
|
||
| for (j = 0, reta = 0; j < 4; j++) { | ||
| rss_indir_tbl = (u8)reta_conf[idx].reta[shift + j]; | ||
| reta |= rss_indir_tbl << (j * 8); | ||
|
|
||
| if (!(mask & (1 << j))) | ||
| continue; | ||
|
|
||
| hw->rss_indir_tbl[i + j] = rss_indir_tbl; | ||
| } | ||
|
|
||
| RTL_W32(hw, RSS_INDIRECTION_TBL_8125_V2 + i, reta); | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
Comment on lines
+728
to
+768
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mask handling bug in RETA update; unmasked entries are overwritten. Validate queue IDs. Build each 32‑bit RETA word from existing values, and only override masked positions. Also check target queue < nb_rx_queues. static int
rtl_reta_update(struct rte_eth_dev *dev,
struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
{
struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
struct rtl_hw *hw = &adapter->hw;
- u32 reta;
- u16 idx, shift;
- u8 mask, rss_indir_tbl;
- int i, j;
+ u32 reta;
+ u16 idx, shift;
+ u8 mask;
+ int i, j;
if (reta_size != RTL_MAX_INDIRECTION_TABLE_ENTRIES) {
@@
- for (i = 0; i < reta_size; i += 4) {
+ for (i = 0; i < reta_size; i += 4) {
idx = i / RTE_ETH_RETA_GROUP_SIZE;
shift = i % RTE_ETH_RETA_GROUP_SIZE;
- mask = (reta_conf[idx].mask >> shift) & 0xf;
+ mask = (reta_conf[idx].mask >> shift) & 0xF;
if (!mask)
continue;
- for (j = 0, reta = 0; j < 4; j++) {
- rss_indir_tbl = (u8)reta_conf[idx].reta[shift + j];
- reta |= rss_indir_tbl << (j * 8);
-
- if (!(mask & (1 << j)))
- continue;
-
- hw->rss_indir_tbl[i + j] = rss_indir_tbl;
- }
+ reta = 0;
+ for (j = 0; j < 4; j++) {
+ u8 v = hw->rss_indir_tbl[i + j];
+ if (mask & (1U << j)) {
+ v = (u8)reta_conf[idx].reta[shift + j];
+ if (v >= dev->data->nb_rx_queues)
+ return -EINVAL;
+ hw->rss_indir_tbl[i + j] = v;
+ }
+ reta |= ((u32)v) << (j * 8);
+ }
RTL_W32(hw, RSS_INDIRECTION_TBL_8125_V2 + i, reta);
}
return 0;
} |
||
|
|
||
| static int | ||
| rtl_reta_query(struct rte_eth_dev *dev, | ||
| struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) | ||
| { | ||
| struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); | ||
| struct rtl_hw *hw = &adapter->hw; | ||
| u16 idx, shift; | ||
| int i; | ||
|
|
||
| if (reta_size != RTL_MAX_INDIRECTION_TABLE_ENTRIES) { | ||
| PMD_DRV_LOG(ERR, "The size of hash lookup table configured " | ||
| "(%d) doesn't match the number hardware can supported " | ||
| "(%d)", reta_size, RTL_MAX_INDIRECTION_TABLE_ENTRIES); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| for (i = 0; i < reta_size; i++) { | ||
| idx = i / RTE_ETH_RETA_GROUP_SIZE; | ||
| shift = i % RTE_ETH_RETA_GROUP_SIZE; | ||
|
|
||
| if (reta_conf[idx].mask & (1ULL << shift)) | ||
| reta_conf[idx].reta[shift] = hw->rss_indir_tbl[i]; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| rtl_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) | ||
| { | ||
| struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); | ||
| struct rtl_hw *hw = &adapter->hw; | ||
| u32 rss_ctrl_8125; | ||
|
|
||
| if (!hw->EnableRss || !(rss_conf->rss_hf & RTL_RSS_OFFLOAD_ALL)) | ||
| return -EINVAL; | ||
|
|
||
| if (rss_conf->rss_key) | ||
| memcpy(hw->rss_key, rss_conf->rss_key, RTL_RSS_KEY_SIZE); | ||
|
|
||
| rtl8125_store_rss_key(hw); | ||
|
|
||
| rss_ctrl_8125 = RTL_R32(hw, RSS_CTRL_8125) & ~RTL_RSS_CTRL_OFFLOAD_ALL; | ||
|
|
||
| if (rss_conf->rss_hf & RTE_ETH_RSS_IPV4) | ||
| rss_ctrl_8125 |= RSS_CTRL_IPV4_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) | ||
| rss_ctrl_8125 |= RSS_CTRL_TCP_IPV4_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) | ||
| rss_ctrl_8125 |= RSS_CTRL_TCP_IPV6_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6) | ||
| rss_ctrl_8125 |= RSS_CTRL_IPV6_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6_EX) | ||
| rss_ctrl_8125 |= RSS_CTRL_IPV6_EXT_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) | ||
| rss_ctrl_8125 |= RSS_CTRL_TCP_IPV6_EXT_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) | ||
| rss_ctrl_8125 |= RSS_CTRL_UDP_IPV4_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) | ||
| rss_ctrl_8125 |= RSS_CTRL_UDP_IPV6_SUPP; | ||
| if (rss_conf->rss_hf & RTE_ETH_RSS_IPV6_UDP_EX) | ||
| rss_ctrl_8125 |= RSS_CTRL_UDP_IPV6_EXT_SUPP; | ||
|
|
||
| RTL_W32(hw, RSS_CTRL_8125, rss_ctrl_8125); | ||
|
|
||
| return 0; | ||
| } | ||
|
Comment on lines
+797
to
+836
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rss_hash_update: accept zero mask (disable), validate key length, and reject unsupported bits instead of requiring any supported bit. Also return -ENOTSUP when RSS not enabled. static int
rtl_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
{
struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
struct rtl_hw *hw = &adapter->hw;
u32 rss_ctrl_8125;
- if (!hw->EnableRss || !(rss_conf->rss_hf & RTL_RSS_OFFLOAD_ALL))
- return -EINVAL;
+ if (!hw->EnableRss)
+ return -ENOTSUP;
+ /* Only allow supported bits */
+ if (rss_conf->rss_hf & ~RTL_RSS_OFFLOAD_ALL)
+ return -EINVAL;
- if (rss_conf->rss_key)
- memcpy(hw->rss_key, rss_conf->rss_key, RTL_RSS_KEY_SIZE);
+ if (rss_conf->rss_key) {
+ if (rss_conf->rss_key_len != RTL_RSS_KEY_SIZE)
+ return -EINVAL;
+ memcpy(hw->rss_key, rss_conf->rss_key, RTL_RSS_KEY_SIZE);
+ }
rtl8125_store_rss_key(hw);
rss_ctrl_8125 = RTL_R32(hw, RSS_CTRL_8125) & ~RTL_RSS_CTRL_OFFLOAD_ALL;
@@
- RTL_W32(hw, RSS_CTRL_8125, rss_ctrl_8125);
+ /* If rss_hf == 0, this clears all offload bits (disable RSS hashing). */
+ RTL_W32(hw, RSS_CTRL_8125, rss_ctrl_8125);
return 0;
}🤖 Prompt for AI Agents |
||
|
|
||
| static int | ||
| rtl_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) | ||
| { | ||
| struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); | ||
| struct rtl_hw *hw = &adapter->hw; | ||
| u64 rss_hf = 0; | ||
| u32 rss_ctrl_8125; | ||
|
|
||
| if (!hw->EnableRss) { | ||
| rss_conf->rss_hf = rss_hf; | ||
| return 0; | ||
| } | ||
|
|
||
| if (rss_conf->rss_key) { | ||
| rss_conf->rss_key_len = RTL_RSS_KEY_SIZE; | ||
| memcpy(rss_conf->rss_key, hw->rss_key, RTL_RSS_KEY_SIZE); | ||
| } | ||
|
|
||
| rss_ctrl_8125 = RTL_R32(hw, RSS_CTRL_8125); | ||
|
|
||
| if (rss_ctrl_8125 & RSS_CTRL_IPV4_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_IPV4; | ||
| if (rss_ctrl_8125 & RSS_CTRL_TCP_IPV4_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; | ||
| if (rss_ctrl_8125 & RSS_CTRL_TCP_IPV6_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; | ||
| if (rss_ctrl_8125 & RSS_CTRL_IPV6_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_IPV6; | ||
| if (rss_ctrl_8125 & RSS_CTRL_IPV6_EXT_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_IPV6_EX; | ||
| if (rss_ctrl_8125 & RSS_CTRL_TCP_IPV6_EXT_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_IPV6_TCP_EX; | ||
| if (rss_ctrl_8125 & RSS_CTRL_UDP_IPV4_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; | ||
| if (rss_ctrl_8125 & RSS_CTRL_UDP_IPV6_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; | ||
| if (rss_ctrl_8125 & RSS_CTRL_UDP_IPV6_EXT_SUPP) | ||
| rss_hf |= RTE_ETH_RSS_IPV6_UDP_EX; | ||
|
|
||
| rss_conf->rss_hf = rss_hf; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| rtl_dev_init(struct rte_eth_dev *dev) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flow_type_rss_offloads uses HW register bits; must use RTE RSS flags. Also avoid ORing with uninitialized queue capa.
dev_info->rx_offload_capadirectly from driver capabilities.RTL_RSS_OFFLOAD_ALLforflow_type_rss_offloads.📝 Committable suggestion
🤖 Prompt for AI Agents