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:
parent
a331fe3b69
commit
ca6cc80dd5
@ -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"
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user