net/txgbe: add unicast hash bitmap

Add unicast hash bitmap.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
Jiawen Wu 2020-10-19 16:53:36 +08:00 committed by Ferruh Yigit
parent a331fe3b69
commit ca6cc80dd5
3 changed files with 133 additions and 1 deletions

View File

@ -8,7 +8,9 @@
#define TXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define TXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
#define TXGBE_ALIGN 128 /* as intel did */
#define TXGBE_MAX_UTA 128
#define TXGBE_ALIGN 128 /* as intel did */
#include "txgbe_status.h"
#include "txgbe_osdep.h"

View File

@ -1080,6 +1080,124 @@ txgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
return 0;
}
static uint32_t
txgbe_uta_vector(struct txgbe_hw *hw, struct rte_ether_addr *uc_addr)
{
uint32_t vector = 0;
switch (hw->mac.mc_filter_type) {
case 0: /* use bits [47:36] of the address */
vector = ((uc_addr->addr_bytes[4] >> 4) |
(((uint16_t)uc_addr->addr_bytes[5]) << 4));
break;
case 1: /* use bits [46:35] of the address */
vector = ((uc_addr->addr_bytes[4] >> 3) |
(((uint16_t)uc_addr->addr_bytes[5]) << 5));
break;
case 2: /* use bits [45:34] of the address */
vector = ((uc_addr->addr_bytes[4] >> 2) |
(((uint16_t)uc_addr->addr_bytes[5]) << 6));
break;
case 3: /* use bits [43:32] of the address */
vector = ((uc_addr->addr_bytes[4]) |
(((uint16_t)uc_addr->addr_bytes[5]) << 8));
break;
default: /* Invalid mc_filter_type */
break;
}
/* vector can only be 12-bits or boundary will be exceeded */
vector &= 0xFFF;
return vector;
}
static int
txgbe_uc_hash_table_set(struct rte_eth_dev *dev,
struct rte_ether_addr *mac_addr, uint8_t on)
{
uint32_t vector;
uint32_t uta_idx;
uint32_t reg_val;
uint32_t uta_mask;
uint32_t psrctl;
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
struct txgbe_uta_info *uta_info = TXGBE_DEV_UTA_INFO(dev);
/* The UTA table only exists on pf hardware */
if (hw->mac.type < txgbe_mac_raptor)
return -ENOTSUP;
vector = txgbe_uta_vector(hw, mac_addr);
uta_idx = (vector >> 5) & 0x7F;
uta_mask = 0x1UL << (vector & 0x1F);
if (!!on == !!(uta_info->uta_shadow[uta_idx] & uta_mask))
return 0;
reg_val = rd32(hw, TXGBE_UCADDRTBL(uta_idx));
if (on) {
uta_info->uta_in_use++;
reg_val |= uta_mask;
uta_info->uta_shadow[uta_idx] |= uta_mask;
} else {
uta_info->uta_in_use--;
reg_val &= ~uta_mask;
uta_info->uta_shadow[uta_idx] &= ~uta_mask;
}
wr32(hw, TXGBE_UCADDRTBL(uta_idx), reg_val);
psrctl = rd32(hw, TXGBE_PSRCTL);
if (uta_info->uta_in_use > 0)
psrctl |= TXGBE_PSRCTL_UCHFENA;
else
psrctl &= ~TXGBE_PSRCTL_UCHFENA;
psrctl &= ~TXGBE_PSRCTL_ADHF12_MASK;
psrctl |= TXGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type);
wr32(hw, TXGBE_PSRCTL, psrctl);
return 0;
}
static int
txgbe_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t on)
{
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
struct txgbe_uta_info *uta_info = TXGBE_DEV_UTA_INFO(dev);
uint32_t psrctl;
int i;
/* The UTA table only exists on pf hardware */
if (hw->mac.type < txgbe_mac_raptor)
return -ENOTSUP;
if (on) {
for (i = 0; i < ETH_VMDQ_NUM_UC_HASH_ARRAY; i++) {
uta_info->uta_shadow[i] = ~0;
wr32(hw, TXGBE_UCADDRTBL(i), ~0);
}
} else {
for (i = 0; i < ETH_VMDQ_NUM_UC_HASH_ARRAY; i++) {
uta_info->uta_shadow[i] = 0;
wr32(hw, TXGBE_UCADDRTBL(i), 0);
}
}
psrctl = rd32(hw, TXGBE_PSRCTL);
if (on)
psrctl |= TXGBE_PSRCTL_UCHFENA;
else
psrctl &= ~TXGBE_PSRCTL_UCHFENA;
psrctl &= ~TXGBE_PSRCTL_ADHF12_MASK;
psrctl |= TXGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type);
wr32(hw, TXGBE_PSRCTL, psrctl);
return 0;
}
/**
* set the IVAR registers, mapping interrupt causes to vectors
* @param hw
@ -1205,6 +1323,8 @@ static const struct eth_dev_ops txgbe_eth_dev_ops = {
.mac_addr_add = txgbe_add_rar,
.mac_addr_remove = txgbe_remove_rar,
.mac_addr_set = txgbe_set_default_mac_addr,
.uc_hash_table_set = txgbe_uc_hash_table_set,
.uc_all_hash_table_set = txgbe_uc_all_hash_table_set,
.set_mc_addr_list = txgbe_dev_set_mc_addr_list,
};

View File

@ -48,12 +48,19 @@ struct txgbe_interrupt {
uint32_t mask[2];
};
struct txgbe_uta_info {
uint8_t uc_filter_type;
uint16_t uta_in_use;
uint32_t uta_shadow[TXGBE_MAX_UTA];
};
/*
* Structure to store private data for each driver instance (for each port).
*/
struct txgbe_adapter {
struct txgbe_hw hw;
struct txgbe_interrupt intr;
struct txgbe_uta_info uta_info;
bool rx_bulk_alloc_allowed;
};
@ -66,6 +73,9 @@ struct txgbe_adapter {
#define TXGBE_DEV_INTR(dev) \
(&((struct txgbe_adapter *)(dev)->data->dev_private)->intr)
#define TXGBE_DEV_UTA_INFO(dev) \
(&((struct txgbe_adapter *)(dev)->data->dev_private)->uta_info)
void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,
uint8_t queue, uint8_t msix_vector);