Merge branch 'hns3-Unicast-MAC-VLAN-table'
Salil Mehta says: ==================== Fixes, minor changes & cleanups for the Unicast MAC VLAN table This patch-set presents necessary modifications, fixes & cleanups related to Unicast MAC Vlan Table to support revision 0x21 hardware. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9798594cb9
9 changed files with 250 additions and 558 deletions
|
@ -46,9 +46,6 @@ enum hclge_mbx_mac_vlan_subcode {
|
|||
HCLGE_MBX_MAC_VLAN_MC_MODIFY, /* modify MC mac addr */
|
||||
HCLGE_MBX_MAC_VLAN_MC_ADD, /* add new MC mac addr */
|
||||
HCLGE_MBX_MAC_VLAN_MC_REMOVE, /* remove MC mac addr */
|
||||
HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, /* config func MTA enable */
|
||||
HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ, /* read func MTA type */
|
||||
HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE, /* update MTA status */
|
||||
};
|
||||
|
||||
/* below are per-VF vlan cfg subcodes */
|
||||
|
|
|
@ -355,8 +355,6 @@ struct hnae3_ae_ops {
|
|||
const unsigned char *addr);
|
||||
int (*rm_mc_addr)(struct hnae3_handle *handle,
|
||||
const unsigned char *addr);
|
||||
int (*update_mta_status)(struct hnae3_handle *handle);
|
||||
|
||||
void (*set_tso_stats)(struct hnae3_handle *handle, int enable);
|
||||
void (*update_stats)(struct hnae3_handle *handle,
|
||||
struct net_device_stats *net_stats);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
static void hns3_clear_all_ring(struct hnae3_handle *h);
|
||||
static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h);
|
||||
static void hns3_remove_hw_addr(struct net_device *netdev);
|
||||
|
||||
static const char hns3_driver_name[] = "hns3";
|
||||
const char hns3_driver_version[] = VERMAGIC_STRING;
|
||||
|
@ -475,9 +476,6 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
|
|||
if (netdev->flags & IFF_MULTICAST) {
|
||||
if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync))
|
||||
netdev_err(netdev, "sync mc address fail\n");
|
||||
|
||||
if (h->ae_algo->ops->update_mta_status)
|
||||
h->ae_algo->ops->update_mta_status(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2202,18 +2200,18 @@ static void hns3_rx_skb(struct hns3_enet_ring *ring, struct sk_buff *skb)
|
|||
napi_gro_receive(&ring->tqp_vector->napi, skb);
|
||||
}
|
||||
|
||||
static u16 hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
|
||||
struct hns3_desc *desc, u32 l234info)
|
||||
static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
|
||||
struct hns3_desc *desc, u32 l234info,
|
||||
u16 *vlan_tag)
|
||||
{
|
||||
struct pci_dev *pdev = ring->tqp->handle->pdev;
|
||||
u16 vlan_tag;
|
||||
|
||||
if (pdev->revision == 0x20) {
|
||||
vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
|
||||
if (!(vlan_tag & VLAN_VID_MASK))
|
||||
vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
|
||||
*vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
|
||||
if (!(*vlan_tag & VLAN_VID_MASK))
|
||||
*vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
|
||||
|
||||
return vlan_tag;
|
||||
return (*vlan_tag != 0);
|
||||
}
|
||||
|
||||
#define HNS3_STRP_OUTER_VLAN 0x1
|
||||
|
@ -2222,17 +2220,14 @@ static u16 hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
|
|||
switch (hnae3_get_field(l234info, HNS3_RXD_STRP_TAGP_M,
|
||||
HNS3_RXD_STRP_TAGP_S)) {
|
||||
case HNS3_STRP_OUTER_VLAN:
|
||||
vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
|
||||
break;
|
||||
*vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
|
||||
return true;
|
||||
case HNS3_STRP_INNER_VLAN:
|
||||
vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
|
||||
break;
|
||||
*vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
|
||||
return true;
|
||||
default:
|
||||
vlan_tag = 0;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
return vlan_tag;
|
||||
}
|
||||
|
||||
static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
|
||||
|
@ -2334,8 +2329,7 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
|
|||
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
u16 vlan_tag;
|
||||
|
||||
vlan_tag = hns3_parse_vlan_tag(ring, desc, l234info);
|
||||
if (vlan_tag & VLAN_VID_MASK)
|
||||
if (hns3_parse_vlan_tag(ring, desc, l234info, &vlan_tag))
|
||||
__vlan_hwaccel_put_tag(skb,
|
||||
htons(ETH_P_8021Q),
|
||||
vlan_tag);
|
||||
|
@ -3155,15 +3149,6 @@ static void hns3_init_mac_addr(struct net_device *netdev, bool init)
|
|||
|
||||
}
|
||||
|
||||
static void hns3_uninit_mac_addr(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
|
||||
if (h->ae_algo->ops->rm_uc_addr)
|
||||
h->ae_algo->ops->rm_uc_addr(h, netdev->dev_addr);
|
||||
}
|
||||
|
||||
static int hns3_restore_fd_rules(struct net_device *netdev)
|
||||
{
|
||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||
|
@ -3296,6 +3281,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
|
|||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
int ret;
|
||||
|
||||
hns3_remove_hw_addr(netdev);
|
||||
|
||||
if (netdev->reg_state != NETREG_UNINITIALIZED)
|
||||
unregister_netdev(netdev);
|
||||
|
||||
|
@ -3319,8 +3306,6 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
|
|||
|
||||
priv->ring_data = NULL;
|
||||
|
||||
hns3_uninit_mac_addr(netdev);
|
||||
|
||||
free_netdev(netdev);
|
||||
}
|
||||
|
||||
|
@ -3392,6 +3377,25 @@ static void hns3_recover_hw_addr(struct net_device *ndev)
|
|||
hns3_nic_mc_sync(ndev, ha->addr);
|
||||
}
|
||||
|
||||
static void hns3_remove_hw_addr(struct net_device *netdev)
|
||||
{
|
||||
struct netdev_hw_addr_list *list;
|
||||
struct netdev_hw_addr *ha, *tmp;
|
||||
|
||||
hns3_nic_uc_unsync(netdev, netdev->dev_addr);
|
||||
|
||||
/* go through and unsync uc_addr entries to the device */
|
||||
list = &netdev->uc;
|
||||
list_for_each_entry_safe(ha, tmp, &list->list, list)
|
||||
hns3_nic_uc_unsync(netdev, ha->addr);
|
||||
|
||||
/* go through and unsync mc_addr entries to the device */
|
||||
list = &netdev->mc;
|
||||
list_for_each_entry_safe(ha, tmp, &list->list, list)
|
||||
if (ha->refcount > 1)
|
||||
hns3_nic_mc_unsync(netdev, ha->addr);
|
||||
}
|
||||
|
||||
static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
|
||||
{
|
||||
while (ring->next_to_clean != ring->next_to_use) {
|
||||
|
@ -3637,14 +3641,14 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
|
|||
if (ret)
|
||||
netdev_err(netdev, "uninit ring error\n");
|
||||
|
||||
hns3_uninit_mac_addr(netdev);
|
||||
|
||||
/* it is cumbersome for hardware to pick-and-choose rules for deletion
|
||||
* from TCAM. Hence, for function reset software intervention is
|
||||
* required to delete the rules
|
||||
/* it is cumbersome for hardware to pick-and-choose entries for deletion
|
||||
* from table space. Hence, for function reset software intervention is
|
||||
* required to delete the entries
|
||||
*/
|
||||
if (hns3_dev_ongoing_func_reset(ae_dev))
|
||||
if (hns3_dev_ongoing_func_reset(ae_dev)) {
|
||||
hns3_remove_hw_addr(netdev);
|
||||
hns3_del_all_fd_rules(netdev, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -175,15 +175,9 @@ enum hclge_opcode_type {
|
|||
HCLGE_OPC_MAC_VLAN_REMOVE = 0x1001,
|
||||
HCLGE_OPC_MAC_VLAN_TYPE_ID = 0x1002,
|
||||
HCLGE_OPC_MAC_VLAN_INSERT = 0x1003,
|
||||
HCLGE_OPC_MAC_VLAN_ALLOCATE = 0x1004,
|
||||
HCLGE_OPC_MAC_ETHTYPE_ADD = 0x1010,
|
||||
HCLGE_OPC_MAC_ETHTYPE_REMOVE = 0x1011,
|
||||
HCLGE_OPC_MAC_VLAN_MASK_SET = 0x1012,
|
||||
|
||||
/* Multicast linear table commands */
|
||||
HCLGE_OPC_MTA_MAC_MODE_CFG = 0x1020,
|
||||
HCLGE_OPC_MTA_MAC_FUNC_CFG = 0x1021,
|
||||
HCLGE_OPC_MTA_TBL_ITEM_CFG = 0x1022,
|
||||
HCLGE_OPC_MTA_TBL_ITEM_QUERY = 0x1023,
|
||||
|
||||
/* VLAN commands */
|
||||
HCLGE_OPC_VLAN_FILTER_CTRL = 0x1100,
|
||||
|
@ -402,6 +396,8 @@ struct hclge_pf_res_cmd {
|
|||
#define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24)
|
||||
#define HCLGE_CFG_SPEED_ABILITY_S 0
|
||||
#define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0)
|
||||
#define HCLGE_CFG_UMV_TBL_SPACE_S 16
|
||||
#define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16)
|
||||
|
||||
struct hclge_cfg_param_cmd {
|
||||
__le32 offset;
|
||||
|
@ -591,13 +587,12 @@ struct hclge_mac_vlan_tbl_entry_cmd {
|
|||
u8 rsv2[6];
|
||||
};
|
||||
|
||||
#define HCLGE_VLAN_MASK_EN_B 0
|
||||
struct hclge_mac_vlan_mask_entry_cmd {
|
||||
u8 rsv0[2];
|
||||
u8 vlan_mask;
|
||||
u8 rsv1;
|
||||
u8 mac_mask[6];
|
||||
u8 rsv2[14];
|
||||
#define HCLGE_UMV_SPC_ALC_B 0
|
||||
struct hclge_umv_spc_alc_cmd {
|
||||
u8 allocate;
|
||||
u8 rsv1[3];
|
||||
__le32 space_size;
|
||||
u8 rsv2[16];
|
||||
};
|
||||
|
||||
#define HCLGE_MAC_MGR_MASK_VLAN_B BIT(0)
|
||||
|
@ -622,30 +617,6 @@ struct hclge_mac_mgr_tbl_entry_cmd {
|
|||
u8 rsv3[2];
|
||||
};
|
||||
|
||||
#define HCLGE_CFG_MTA_MAC_SEL_S 0
|
||||
#define HCLGE_CFG_MTA_MAC_SEL_M GENMASK(1, 0)
|
||||
#define HCLGE_CFG_MTA_MAC_EN_B 7
|
||||
struct hclge_mta_filter_mode_cmd {
|
||||
u8 dmac_sel_en; /* Use lowest 2 bit as sel_mode, bit 7 as enable */
|
||||
u8 rsv[23];
|
||||
};
|
||||
|
||||
#define HCLGE_CFG_FUNC_MTA_ACCEPT_B 0
|
||||
struct hclge_cfg_func_mta_filter_cmd {
|
||||
u8 accept; /* Only used lowest 1 bit */
|
||||
u8 function_id;
|
||||
u8 rsv[22];
|
||||
};
|
||||
|
||||
#define HCLGE_CFG_MTA_ITEM_ACCEPT_B 0
|
||||
#define HCLGE_CFG_MTA_ITEM_IDX_S 0
|
||||
#define HCLGE_CFG_MTA_ITEM_IDX_M GENMASK(11, 0)
|
||||
struct hclge_cfg_func_mta_item_cmd {
|
||||
__le16 item_idx; /* Only used lowest 12 bit */
|
||||
u8 accept; /* Only used lowest 1 bit */
|
||||
u8 rsv[21];
|
||||
};
|
||||
|
||||
struct hclge_mac_vlan_add_cmd {
|
||||
__le16 flags;
|
||||
__le16 mac_addr_hi16;
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
#define HCLGE_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset))))
|
||||
#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
|
||||
|
||||
static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
|
||||
enum hclge_mta_dmac_sel_type mta_mac_sel,
|
||||
bool enable);
|
||||
static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu);
|
||||
static int hclge_init_vlan_config(struct hclge_dev *hdev);
|
||||
static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev);
|
||||
static int hclge_set_umv_space(struct hclge_dev *hdev, u16 space_size,
|
||||
u16 *allocated_size, bool is_alloc);
|
||||
|
||||
static struct hnae3_ae_algo ae_algo;
|
||||
|
||||
|
@ -778,6 +777,11 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
|
|||
cfg->speed_ability = hnae3_get_field(__le32_to_cpu(req->param[1]),
|
||||
HCLGE_CFG_SPEED_ABILITY_M,
|
||||
HCLGE_CFG_SPEED_ABILITY_S);
|
||||
cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]),
|
||||
HCLGE_CFG_UMV_TBL_SPACE_M,
|
||||
HCLGE_CFG_UMV_TBL_SPACE_S);
|
||||
if (!cfg->umv_space)
|
||||
cfg->umv_space = HCLGE_DEFAULT_UMV_SPACE_PER_PF;
|
||||
}
|
||||
|
||||
/* hclge_get_cfg: query the static parameter from flash
|
||||
|
@ -856,6 +860,7 @@ static int hclge_configure(struct hclge_dev *hdev)
|
|||
hdev->tm_info.num_pg = 1;
|
||||
hdev->tc_max = cfg.tc_num;
|
||||
hdev->tm_info.hw_pfc_map = 0;
|
||||
hdev->wanted_umv_size = cfg.umv_space;
|
||||
|
||||
ret = hclge_parse_speed(cfg.default_speed, &hdev->hw.mac.speed);
|
||||
if (ret) {
|
||||
|
@ -1939,40 +1944,13 @@ static int hclge_get_autoneg(struct hnae3_handle *handle)
|
|||
return hdev->hw.mac.autoneg;
|
||||
}
|
||||
|
||||
static int hclge_set_default_mac_vlan_mask(struct hclge_dev *hdev,
|
||||
bool mask_vlan,
|
||||
u8 *mac_mask)
|
||||
{
|
||||
struct hclge_mac_vlan_mask_entry_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
int status;
|
||||
|
||||
req = (struct hclge_mac_vlan_mask_entry_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_MASK_SET, false);
|
||||
|
||||
hnae3_set_bit(req->vlan_mask, HCLGE_VLAN_MASK_EN_B,
|
||||
mask_vlan ? 1 : 0);
|
||||
ether_addr_copy(req->mac_mask, mac_mask);
|
||||
|
||||
status = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (status)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Config mac_vlan_mask failed for cmd_send, ret =%d\n",
|
||||
status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int hclge_mac_init(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hnae3_handle *handle = &hdev->vport[0].nic;
|
||||
struct net_device *netdev = handle->kinfo.netdev;
|
||||
struct hclge_mac *mac = &hdev->hw.mac;
|
||||
u8 mac_mask[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
struct hclge_vport *vport;
|
||||
int mtu;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
hdev->hw.mac.duplex = HCLGE_MAC_FULL;
|
||||
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
|
||||
|
@ -1985,39 +1963,6 @@ static int hclge_mac_init(struct hclge_dev *hdev)
|
|||
|
||||
mac->link = 0;
|
||||
|
||||
/* Initialize the MTA table work mode */
|
||||
hdev->enable_mta = true;
|
||||
hdev->mta_mac_sel_type = HCLGE_MAC_ADDR_47_36;
|
||||
|
||||
ret = hclge_set_mta_filter_mode(hdev,
|
||||
hdev->mta_mac_sel_type,
|
||||
hdev->enable_mta);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev, "set mta filter mode failed %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
vport = &hdev->vport[i];
|
||||
vport->accept_mta_mc = false;
|
||||
|
||||
memset(vport->mta_shadow, 0, sizeof(vport->mta_shadow));
|
||||
ret = hclge_cfg_func_mta_filter(hdev, vport->vport_id, false);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"set mta filter mode fail ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = hclge_set_default_mac_vlan_mask(hdev, true, mac_mask);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"set default mac_vlan_mask fail ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (netdev)
|
||||
mtu = netdev->mtu;
|
||||
else
|
||||
|
@ -4978,174 +4923,6 @@ static void hclge_prepare_mac_addr(struct hclge_mac_vlan_tbl_entry_cmd *new_req,
|
|||
new_req->mac_addr_lo16 = cpu_to_le16(low_val & 0xffff);
|
||||
}
|
||||
|
||||
static u16 hclge_get_mac_addr_to_mta_index(struct hclge_vport *vport,
|
||||
const u8 *addr)
|
||||
{
|
||||
u16 high_val = addr[1] | (addr[0] << 8);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u32 rsh = 4 - hdev->mta_mac_sel_type;
|
||||
u16 ret_val = (high_val >> rsh) & 0xfff;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
|
||||
enum hclge_mta_dmac_sel_type mta_mac_sel,
|
||||
bool enable)
|
||||
{
|
||||
struct hclge_mta_filter_mode_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
int ret;
|
||||
|
||||
req = (struct hclge_mta_filter_mode_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MTA_MAC_MODE_CFG, false);
|
||||
|
||||
hnae3_set_bit(req->dmac_sel_en, HCLGE_CFG_MTA_MAC_EN_B,
|
||||
enable);
|
||||
hnae3_set_field(req->dmac_sel_en, HCLGE_CFG_MTA_MAC_SEL_M,
|
||||
HCLGE_CFG_MTA_MAC_SEL_S, mta_mac_sel);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Config mat filter mode failed for cmd_send, ret =%d.\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hclge_cfg_func_mta_filter(struct hclge_dev *hdev,
|
||||
u8 func_id,
|
||||
bool enable)
|
||||
{
|
||||
struct hclge_cfg_func_mta_filter_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
int ret;
|
||||
|
||||
req = (struct hclge_cfg_func_mta_filter_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MTA_MAC_FUNC_CFG, false);
|
||||
|
||||
hnae3_set_bit(req->accept, HCLGE_CFG_FUNC_MTA_ACCEPT_B,
|
||||
enable);
|
||||
req->function_id = func_id;
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Config func_id enable failed for cmd_send, ret =%d.\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_set_mta_table_item(struct hclge_vport *vport,
|
||||
u16 idx,
|
||||
bool enable)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
struct hclge_cfg_func_mta_item_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
u16 item_idx = 0;
|
||||
int ret;
|
||||
|
||||
req = (struct hclge_cfg_func_mta_item_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MTA_TBL_ITEM_CFG, false);
|
||||
hnae3_set_bit(req->accept, HCLGE_CFG_MTA_ITEM_ACCEPT_B, enable);
|
||||
|
||||
hnae3_set_field(item_idx, HCLGE_CFG_MTA_ITEM_IDX_M,
|
||||
HCLGE_CFG_MTA_ITEM_IDX_S, idx);
|
||||
req->item_idx = cpu_to_le16(item_idx);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Config mta table item failed for cmd_send, ret =%d.\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
set_bit(idx, vport->mta_shadow);
|
||||
else
|
||||
clear_bit(idx, vport->mta_shadow);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_update_mta_status(struct hnae3_handle *handle)
|
||||
{
|
||||
unsigned long mta_status[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)];
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct net_device *netdev = handle->kinfo.netdev;
|
||||
struct netdev_hw_addr *ha;
|
||||
u16 tbl_idx;
|
||||
|
||||
memset(mta_status, 0, sizeof(mta_status));
|
||||
|
||||
/* update mta_status from mc addr list */
|
||||
netdev_for_each_mc_addr(ha, netdev) {
|
||||
tbl_idx = hclge_get_mac_addr_to_mta_index(vport, ha->addr);
|
||||
set_bit(tbl_idx, mta_status);
|
||||
}
|
||||
|
||||
return hclge_update_mta_status_common(vport, mta_status,
|
||||
0, HCLGE_MTA_TBL_SIZE, true);
|
||||
}
|
||||
|
||||
int hclge_update_mta_status_common(struct hclge_vport *vport,
|
||||
unsigned long *status,
|
||||
u16 idx,
|
||||
u16 count,
|
||||
bool update_filter)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u16 update_max = idx + count;
|
||||
u16 check_max;
|
||||
int ret = 0;
|
||||
bool used;
|
||||
u16 i;
|
||||
|
||||
/* setup mta check range */
|
||||
if (update_filter) {
|
||||
i = 0;
|
||||
check_max = HCLGE_MTA_TBL_SIZE;
|
||||
} else {
|
||||
i = idx;
|
||||
check_max = update_max;
|
||||
}
|
||||
|
||||
used = false;
|
||||
/* check and update all mta item */
|
||||
for (; i < check_max; i++) {
|
||||
/* ignore unused item */
|
||||
if (!test_bit(i, vport->mta_shadow))
|
||||
continue;
|
||||
|
||||
/* if i in update range then update it */
|
||||
if (i >= idx && i < update_max)
|
||||
if (!test_bit(i - idx, status))
|
||||
hclge_set_mta_table_item(vport, i, false);
|
||||
|
||||
if (!used && test_bit(i, vport->mta_shadow))
|
||||
used = true;
|
||||
}
|
||||
|
||||
/* no longer use mta, disable it */
|
||||
if (vport->accept_mta_mc && update_filter && !used) {
|
||||
ret = hclge_cfg_func_mta_filter(hdev,
|
||||
vport->vport_id,
|
||||
false);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"disable func mta filter fail ret=%d\n",
|
||||
ret);
|
||||
else
|
||||
vport->accept_mta_mc = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_remove_mac_vlan_tbl(struct hclge_vport *vport,
|
||||
struct hclge_mac_vlan_tbl_entry_cmd *req)
|
||||
{
|
||||
|
@ -5269,6 +5046,118 @@ static int hclge_add_mac_vlan_tbl(struct hclge_vport *vport,
|
|||
return cfg_status;
|
||||
}
|
||||
|
||||
static int hclge_init_umv_space(struct hclge_dev *hdev)
|
||||
{
|
||||
u16 allocated_size = 0;
|
||||
int ret;
|
||||
|
||||
ret = hclge_set_umv_space(hdev, hdev->wanted_umv_size, &allocated_size,
|
||||
true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (allocated_size < hdev->wanted_umv_size)
|
||||
dev_warn(&hdev->pdev->dev,
|
||||
"Alloc umv space failed, want %d, get %d\n",
|
||||
hdev->wanted_umv_size, allocated_size);
|
||||
|
||||
mutex_init(&hdev->umv_mutex);
|
||||
hdev->max_umv_size = allocated_size;
|
||||
hdev->priv_umv_size = hdev->max_umv_size / (hdev->num_req_vfs + 2);
|
||||
hdev->share_umv_size = hdev->priv_umv_size +
|
||||
hdev->max_umv_size % (hdev->num_req_vfs + 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_uninit_umv_space(struct hclge_dev *hdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (hdev->max_umv_size > 0) {
|
||||
ret = hclge_set_umv_space(hdev, hdev->max_umv_size, NULL,
|
||||
false);
|
||||
if (ret)
|
||||
return ret;
|
||||
hdev->max_umv_size = 0;
|
||||
}
|
||||
mutex_destroy(&hdev->umv_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_set_umv_space(struct hclge_dev *hdev, u16 space_size,
|
||||
u16 *allocated_size, bool is_alloc)
|
||||
{
|
||||
struct hclge_umv_spc_alc_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
int ret;
|
||||
|
||||
req = (struct hclge_umv_spc_alc_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_ALLOCATE, false);
|
||||
hnae3_set_bit(req->allocate, HCLGE_UMV_SPC_ALC_B, !is_alloc);
|
||||
req->space_size = cpu_to_le32(space_size);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"%s umv space failed for cmd_send, ret =%d\n",
|
||||
is_alloc ? "allocate" : "free", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (is_alloc && allocated_size)
|
||||
*allocated_size = le32_to_cpu(desc.data[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclge_reset_umv_space(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_vport *vport;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
vport = &hdev->vport[i];
|
||||
vport->used_umv_num = 0;
|
||||
}
|
||||
|
||||
mutex_lock(&hdev->umv_mutex);
|
||||
hdev->share_umv_size = hdev->priv_umv_size +
|
||||
hdev->max_umv_size % (hdev->num_req_vfs + 2);
|
||||
mutex_unlock(&hdev->umv_mutex);
|
||||
}
|
||||
|
||||
static bool hclge_is_umv_space_full(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
bool is_full;
|
||||
|
||||
mutex_lock(&hdev->umv_mutex);
|
||||
is_full = (vport->used_umv_num >= hdev->priv_umv_size &&
|
||||
hdev->share_umv_size == 0);
|
||||
mutex_unlock(&hdev->umv_mutex);
|
||||
|
||||
return is_full;
|
||||
}
|
||||
|
||||
static void hclge_update_umv_space(struct hclge_vport *vport, bool is_free)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
mutex_lock(&hdev->umv_mutex);
|
||||
if (is_free) {
|
||||
if (vport->used_umv_num > hdev->priv_umv_size)
|
||||
hdev->share_umv_size++;
|
||||
vport->used_umv_num--;
|
||||
} else {
|
||||
if (vport->used_umv_num >= hdev->priv_umv_size)
|
||||
hdev->share_umv_size--;
|
||||
vport->used_umv_num++;
|
||||
}
|
||||
mutex_unlock(&hdev->umv_mutex);
|
||||
}
|
||||
|
||||
static int hclge_add_uc_addr(struct hnae3_handle *handle,
|
||||
const unsigned char *addr)
|
||||
{
|
||||
|
@ -5314,8 +5203,19 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
|
|||
* is not allowed in the mac vlan table.
|
||||
*/
|
||||
ret = hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false);
|
||||
if (ret == -ENOENT)
|
||||
return hclge_add_mac_vlan_tbl(vport, &req, NULL);
|
||||
if (ret == -ENOENT) {
|
||||
if (!hclge_is_umv_space_full(vport)) {
|
||||
ret = hclge_add_mac_vlan_tbl(vport, &req, NULL);
|
||||
if (!ret)
|
||||
hclge_update_umv_space(vport, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_err(&hdev->pdev->dev, "UC MAC table full(%u)\n",
|
||||
hdev->priv_umv_size);
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* check if we just hit the duplicate */
|
||||
if (!ret)
|
||||
|
@ -5358,6 +5258,8 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
|
|||
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
|
||||
hclge_prepare_mac_addr(&req, addr);
|
||||
ret = hclge_remove_mac_vlan_tbl(vport, &req);
|
||||
if (!ret)
|
||||
hclge_update_umv_space(vport, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -5376,7 +5278,6 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
|
|||
struct hclge_dev *hdev = vport->back;
|
||||
struct hclge_mac_vlan_tbl_entry_cmd req;
|
||||
struct hclge_desc desc[3];
|
||||
u16 tbl_idx;
|
||||
int status;
|
||||
|
||||
/* mac addr check */
|
||||
|
@ -5406,25 +5307,8 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
|
|||
status = hclge_add_mac_vlan_tbl(vport, &req, desc);
|
||||
}
|
||||
|
||||
/* If mc mac vlan table is full, use MTA table */
|
||||
if (status == -ENOSPC) {
|
||||
if (!vport->accept_mta_mc) {
|
||||
status = hclge_cfg_func_mta_filter(hdev,
|
||||
vport->vport_id,
|
||||
true);
|
||||
if (status) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"set mta filter mode fail ret=%d\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
vport->accept_mta_mc = true;
|
||||
}
|
||||
|
||||
/* Set MTA table for this MAC address */
|
||||
tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr);
|
||||
status = hclge_set_mta_table_item(vport, tbl_idx, true);
|
||||
}
|
||||
if (status == -ENOSPC)
|
||||
dev_err(&hdev->pdev->dev, "mc mac vlan table is full\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -5639,7 +5523,7 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr,
|
|||
}
|
||||
|
||||
static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
|
||||
bool filter_en)
|
||||
u8 fe_type, bool filter_en)
|
||||
{
|
||||
struct hclge_vlan_filter_ctrl_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
|
@ -5649,7 +5533,7 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
|
|||
|
||||
req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data;
|
||||
req->vlan_type = vlan_type;
|
||||
req->vlan_fe = filter_en;
|
||||
req->vlan_fe = filter_en ? fe_type : 0;
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
|
@ -5661,13 +5545,30 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
|
|||
|
||||
#define HCLGE_FILTER_TYPE_VF 0
|
||||
#define HCLGE_FILTER_TYPE_PORT 1
|
||||
#define HCLGE_FILTER_FE_EGRESS_V1_B BIT(0)
|
||||
#define HCLGE_FILTER_FE_NIC_INGRESS_B BIT(0)
|
||||
#define HCLGE_FILTER_FE_NIC_EGRESS_B BIT(1)
|
||||
#define HCLGE_FILTER_FE_ROCE_INGRESS_B BIT(2)
|
||||
#define HCLGE_FILTER_FE_ROCE_EGRESS_B BIT(3)
|
||||
#define HCLGE_FILTER_FE_EGRESS (HCLGE_FILTER_FE_NIC_EGRESS_B \
|
||||
| HCLGE_FILTER_FE_ROCE_EGRESS_B)
|
||||
#define HCLGE_FILTER_FE_INGRESS (HCLGE_FILTER_FE_NIC_INGRESS_B \
|
||||
| HCLGE_FILTER_FE_ROCE_INGRESS_B)
|
||||
|
||||
static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, enable);
|
||||
if (hdev->pdev->revision >= 0x21) {
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS, enable);
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
|
||||
HCLGE_FILTER_FE_INGRESS, enable);
|
||||
} else {
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS_V1_B, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
|
||||
|
@ -5969,13 +5870,23 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (hdev->pdev->revision >= 0x21) {
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
|
||||
HCLGE_FILTER_FE_INGRESS, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS_V1_B,
|
||||
true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
|
||||
hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
|
||||
|
@ -6746,6 +6657,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
}
|
||||
}
|
||||
|
||||
ret = hclge_init_umv_space(hdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "umv space init error, ret=%d.\n", ret);
|
||||
goto err_msi_irq_uninit;
|
||||
}
|
||||
|
||||
ret = hclge_mac_init(hdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret);
|
||||
|
@ -6866,6 +6783,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hclge_reset_umv_space(hdev);
|
||||
|
||||
ret = hclge_mac_init(hdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret);
|
||||
|
@ -6919,6 +6838,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
|
|||
if (mac->phydev)
|
||||
mdiobus_unregister(mac->mdio_bus);
|
||||
|
||||
hclge_uninit_umv_space(hdev);
|
||||
|
||||
/* Disable MISC vector(vector0) */
|
||||
hclge_enable_vector(&hdev->misc_vector, false);
|
||||
synchronize_irq(hdev->misc_vector.vector_irq);
|
||||
|
@ -7317,7 +7238,6 @@ static const struct hnae3_ae_ops hclge_ops = {
|
|||
.rm_uc_addr = hclge_rm_uc_addr,
|
||||
.add_mc_addr = hclge_add_mc_addr,
|
||||
.rm_mc_addr = hclge_rm_mc_addr,
|
||||
.update_mta_status = hclge_update_mta_status,
|
||||
.set_autoneg = hclge_set_autoneg,
|
||||
.get_autoneg = hclge_get_autoneg,
|
||||
.get_pauseparam = hclge_get_pauseparam,
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define HCLGE_MOD_VERSION "1.0"
|
||||
#define HCLGE_DRIVER_NAME "hclge"
|
||||
|
||||
#define HCLGE_MAX_PF_NUM 8
|
||||
|
||||
#define HCLGE_INVALID_VPORT 0xffff
|
||||
|
||||
#define HCLGE_PF_CFG_BLOCK_SIZE 32
|
||||
|
@ -53,7 +55,9 @@
|
|||
#define HCLGE_RSS_TC_SIZE_6 64
|
||||
#define HCLGE_RSS_TC_SIZE_7 128
|
||||
|
||||
#define HCLGE_MTA_TBL_SIZE 4096
|
||||
#define HCLGE_UMV_TBL_SIZE 3072
|
||||
#define HCLGE_DEFAULT_UMV_SPACE_PER_PF \
|
||||
(HCLGE_UMV_TBL_SIZE / HCLGE_MAX_PF_NUM)
|
||||
|
||||
#define HCLGE_TQP_RESET_TRY_TIMES 10
|
||||
|
||||
|
@ -162,13 +166,6 @@ enum HCLGE_MAC_DUPLEX {
|
|||
HCLGE_MAC_FULL
|
||||
};
|
||||
|
||||
enum hclge_mta_dmac_sel_type {
|
||||
HCLGE_MAC_ADDR_47_36,
|
||||
HCLGE_MAC_ADDR_46_35,
|
||||
HCLGE_MAC_ADDR_45_34,
|
||||
HCLGE_MAC_ADDR_44_33,
|
||||
};
|
||||
|
||||
struct hclge_mac {
|
||||
u8 phy_addr;
|
||||
u8 flag;
|
||||
|
@ -251,6 +248,7 @@ struct hclge_cfg {
|
|||
u8 default_speed;
|
||||
u32 numa_node_map;
|
||||
u8 speed_ability;
|
||||
u16 umv_space;
|
||||
};
|
||||
|
||||
struct hclge_tm_info {
|
||||
|
@ -670,9 +668,6 @@ struct hclge_dev {
|
|||
u32 pkt_buf_size; /* Total pf buf size for tx/rx */
|
||||
u32 mps; /* Max packet size */
|
||||
|
||||
enum hclge_mta_dmac_sel_type mta_mac_sel_type;
|
||||
bool enable_mta; /* Multicast filter enable */
|
||||
|
||||
struct hclge_vlan_type_cfg vlan_type_cfg;
|
||||
|
||||
unsigned long vlan_table[VLAN_N_VID][BITS_TO_LONGS(HCLGE_VPORT_NUM)];
|
||||
|
@ -680,6 +675,15 @@ struct hclge_dev {
|
|||
struct hclge_fd_cfg fd_cfg;
|
||||
struct hlist_head fd_rule_list;
|
||||
u16 hclge_fd_rule_num;
|
||||
|
||||
u16 wanted_umv_size;
|
||||
/* max available unicast mac vlan space */
|
||||
u16 max_umv_size;
|
||||
/* private unicast mac vlan space, it's same for PF and its VFs */
|
||||
u16 priv_umv_size;
|
||||
/* unicast mac vlan space shared by PF and its VFs */
|
||||
u16 share_umv_size;
|
||||
struct mutex umv_mutex; /* protect share_umv_size */
|
||||
};
|
||||
|
||||
/* VPort level vlan tag configuration for TX direction */
|
||||
|
@ -732,13 +736,12 @@ struct hclge_vport {
|
|||
struct hclge_tx_vtag_cfg txvlan_cfg;
|
||||
struct hclge_rx_vtag_cfg rxvlan_cfg;
|
||||
|
||||
u16 used_umv_num;
|
||||
|
||||
int vport_id;
|
||||
struct hclge_dev *back; /* Back reference to associated dev */
|
||||
struct hnae3_handle nic;
|
||||
struct hnae3_handle roce;
|
||||
|
||||
bool accept_mta_mc; /* whether to accept mta filter multicast */
|
||||
unsigned long mta_shadow[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)];
|
||||
};
|
||||
|
||||
void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
|
||||
|
@ -753,15 +756,6 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
|
|||
int hclge_rm_mc_addr_common(struct hclge_vport *vport,
|
||||
const unsigned char *addr);
|
||||
|
||||
int hclge_cfg_func_mta_filter(struct hclge_dev *hdev,
|
||||
u8 func_id,
|
||||
bool enable);
|
||||
int hclge_update_mta_status_common(struct hclge_vport *vport,
|
||||
unsigned long *status,
|
||||
u16 idx,
|
||||
u16 count,
|
||||
bool update_filter);
|
||||
|
||||
struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle);
|
||||
int hclge_bind_ring_with_vector(struct hclge_vport *vport,
|
||||
int vector_id, bool en,
|
||||
|
|
|
@ -233,43 +233,6 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_set_vf_mc_mta_status(struct hclge_vport *vport,
|
||||
u8 *msg, u8 idx, bool is_end)
|
||||
{
|
||||
#define HCLGE_MTA_STATUS_MSG_SIZE 13
|
||||
#define HCLGE_MTA_STATUS_MSG_BITS \
|
||||
(HCLGE_MTA_STATUS_MSG_SIZE * BITS_PER_BYTE)
|
||||
#define HCLGE_MTA_STATUS_MSG_END_BITS \
|
||||
(HCLGE_MTA_TBL_SIZE % HCLGE_MTA_STATUS_MSG_BITS)
|
||||
unsigned long status[BITS_TO_LONGS(HCLGE_MTA_STATUS_MSG_BITS)];
|
||||
u16 tbl_cnt;
|
||||
u16 tbl_idx;
|
||||
u8 msg_ofs;
|
||||
u8 msg_bit;
|
||||
|
||||
tbl_cnt = is_end ? HCLGE_MTA_STATUS_MSG_END_BITS :
|
||||
HCLGE_MTA_STATUS_MSG_BITS;
|
||||
|
||||
/* set msg field */
|
||||
msg_ofs = 0;
|
||||
msg_bit = 0;
|
||||
memset(status, 0, sizeof(status));
|
||||
for (tbl_idx = 0; tbl_idx < tbl_cnt; tbl_idx++) {
|
||||
if (msg[msg_ofs] & BIT(msg_bit))
|
||||
set_bit(tbl_idx, status);
|
||||
|
||||
msg_bit++;
|
||||
if (msg_bit == BITS_PER_BYTE) {
|
||||
msg_bit = 0;
|
||||
msg_ofs++;
|
||||
}
|
||||
}
|
||||
|
||||
return hclge_update_mta_status_common(vport,
|
||||
status, idx * HCLGE_MTA_STATUS_MSG_BITS,
|
||||
tbl_cnt, is_end);
|
||||
}
|
||||
|
||||
static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req,
|
||||
bool gen_resp)
|
||||
|
@ -284,27 +247,6 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport,
|
|||
status = hclge_add_mc_addr_common(vport, mac_addr);
|
||||
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_REMOVE) {
|
||||
status = hclge_rm_mc_addr_common(vport, mac_addr);
|
||||
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE) {
|
||||
u8 func_id = vport->vport_id;
|
||||
bool enable = mbx_req->msg[2];
|
||||
|
||||
status = hclge_cfg_func_mta_filter(hdev, func_id, enable);
|
||||
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ) {
|
||||
resp_data = hdev->mta_mac_sel_type;
|
||||
resp_len = sizeof(u8);
|
||||
gen_resp = true;
|
||||
status = 0;
|
||||
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE) {
|
||||
/* mta status update msg format
|
||||
* msg[2.6 : 2.0] msg index
|
||||
* msg[2.7] msg is end
|
||||
* msg[15 : 3] mta status bits[103 : 0]
|
||||
*/
|
||||
bool is_end = (mbx_req->msg[2] & 0x80) ? true : false;
|
||||
|
||||
status = hclge_set_vf_mc_mta_status(vport, &mbx_req->msg[3],
|
||||
mbx_req->msg[2] & 0x7F,
|
||||
is_end);
|
||||
} else {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to set mcast mac addr, unknown subcode %d\n",
|
||||
|
|
|
@ -746,126 +746,6 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle)
|
|||
}
|
||||
}
|
||||
|
||||
static int hclgevf_cfg_func_mta_type(struct hclgevf_dev *hdev)
|
||||
{
|
||||
u8 resp_msg = HCLGEVF_MTA_TYPE_SEL_MAX;
|
||||
int ret;
|
||||
|
||||
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST,
|
||||
HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ,
|
||||
NULL, 0, true, &resp_msg, sizeof(u8));
|
||||
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Read mta type fail, ret=%d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (resp_msg > HCLGEVF_MTA_TYPE_SEL_MAX) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Read mta type invalid, resp=%d.\n", resp_msg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdev->mta_mac_sel_type = resp_msg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 hclgevf_get_mac_addr_to_mta_index(struct hclgevf_dev *hdev,
|
||||
const u8 *addr)
|
||||
{
|
||||
u32 rsh = HCLGEVF_MTA_TYPE_SEL_MAX - hdev->mta_mac_sel_type;
|
||||
u16 high_val = addr[1] | (addr[0] << 8);
|
||||
|
||||
return (high_val >> rsh) & 0xfff;
|
||||
}
|
||||
|
||||
static int hclgevf_do_update_mta_status(struct hclgevf_dev *hdev,
|
||||
unsigned long *status)
|
||||
{
|
||||
#define HCLGEVF_MTA_STATUS_MSG_SIZE 13
|
||||
#define HCLGEVF_MTA_STATUS_MSG_BITS \
|
||||
(HCLGEVF_MTA_STATUS_MSG_SIZE * BITS_PER_BYTE)
|
||||
#define HCLGEVF_MTA_STATUS_MSG_END_BITS \
|
||||
(HCLGEVF_MTA_TBL_SIZE % HCLGEVF_MTA_STATUS_MSG_BITS)
|
||||
u16 tbl_cnt;
|
||||
u16 tbl_idx;
|
||||
u8 msg_cnt;
|
||||
u8 msg_idx;
|
||||
int ret;
|
||||
|
||||
msg_cnt = DIV_ROUND_UP(HCLGEVF_MTA_TBL_SIZE,
|
||||
HCLGEVF_MTA_STATUS_MSG_BITS);
|
||||
tbl_idx = 0;
|
||||
msg_idx = 0;
|
||||
while (msg_cnt--) {
|
||||
u8 msg[HCLGEVF_MTA_STATUS_MSG_SIZE + 1];
|
||||
u8 *p = &msg[1];
|
||||
u8 msg_ofs;
|
||||
u8 msg_bit;
|
||||
|
||||
memset(msg, 0, sizeof(msg));
|
||||
|
||||
/* set index field */
|
||||
msg[0] = 0x7F & msg_idx;
|
||||
|
||||
/* set end flag field */
|
||||
if (msg_cnt == 0) {
|
||||
msg[0] |= 0x80;
|
||||
tbl_cnt = HCLGEVF_MTA_STATUS_MSG_END_BITS;
|
||||
} else {
|
||||
tbl_cnt = HCLGEVF_MTA_STATUS_MSG_BITS;
|
||||
}
|
||||
|
||||
/* set status field */
|
||||
msg_ofs = 0;
|
||||
msg_bit = 0;
|
||||
while (tbl_cnt--) {
|
||||
if (test_bit(tbl_idx, status))
|
||||
p[msg_ofs] |= BIT(msg_bit);
|
||||
|
||||
tbl_idx++;
|
||||
|
||||
msg_bit++;
|
||||
if (msg_bit == BITS_PER_BYTE) {
|
||||
msg_bit = 0;
|
||||
msg_ofs++;
|
||||
}
|
||||
}
|
||||
|
||||
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST,
|
||||
HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE,
|
||||
msg, sizeof(msg), false, NULL, 0);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
msg_idx++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclgevf_update_mta_status(struct hnae3_handle *handle)
|
||||
{
|
||||
unsigned long mta_status[BITS_TO_LONGS(HCLGEVF_MTA_TBL_SIZE)];
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
struct net_device *netdev = hdev->nic.kinfo.netdev;
|
||||
struct netdev_hw_addr *ha;
|
||||
u16 tbl_idx;
|
||||
|
||||
/* clear status */
|
||||
memset(mta_status, 0, sizeof(mta_status));
|
||||
|
||||
/* update status from mc addr list */
|
||||
netdev_for_each_mc_addr(ha, netdev) {
|
||||
tbl_idx = hclgevf_get_mac_addr_to_mta_index(hdev, ha->addr);
|
||||
set_bit(tbl_idx, mta_status);
|
||||
}
|
||||
|
||||
return hclgevf_do_update_mta_status(hdev, mta_status);
|
||||
}
|
||||
|
||||
static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
|
@ -1871,14 +1751,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
|||
goto err_config;
|
||||
}
|
||||
|
||||
/* Initialize mta type for this VF */
|
||||
ret = hclgevf_cfg_func_mta_type(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed(%d) to initialize MTA type\n", ret);
|
||||
goto err_config;
|
||||
}
|
||||
|
||||
/* Initialize RSS for this VF */
|
||||
ret = hclgevf_rss_init_hw(hdev);
|
||||
if (ret) {
|
||||
|
@ -2038,7 +1910,6 @@ static const struct hnae3_ae_ops hclgevf_ops = {
|
|||
.rm_uc_addr = hclgevf_rm_uc_addr,
|
||||
.add_mc_addr = hclgevf_add_mc_addr,
|
||||
.rm_mc_addr = hclgevf_rm_mc_addr,
|
||||
.update_mta_status = hclgevf_update_mta_status,
|
||||
.get_stats = hclgevf_get_stats,
|
||||
.update_stats = hclgevf_update_stats,
|
||||
.get_strings = hclgevf_get_strings,
|
||||
|
|
|
@ -47,9 +47,6 @@
|
|||
#define HCLGEVF_RSS_CFG_TBL_NUM \
|
||||
(HCLGEVF_RSS_IND_TBL_SIZE / HCLGEVF_RSS_CFG_TBL_SIZE)
|
||||
|
||||
#define HCLGEVF_MTA_TBL_SIZE 4096
|
||||
#define HCLGEVF_MTA_TYPE_SEL_MAX 4
|
||||
|
||||
/* states of hclgevf device & tasks */
|
||||
enum hclgevf_states {
|
||||
/* device states */
|
||||
|
@ -157,8 +154,6 @@ struct hclgevf_dev {
|
|||
u16 *vector_status;
|
||||
int *vector_irq;
|
||||
|
||||
bool accept_mta_mc; /* whether to accept mta filter multicast */
|
||||
u8 mta_mac_sel_type;
|
||||
bool mbx_event_pending;
|
||||
struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */
|
||||
struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */
|
||||
|
|
Loading…
Reference in a new issue