mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
net: hns: add the support to add/remove the ucast entry to/from table
This patch adds the support to add or remove the unicast entries to the table and remove from the table. Reported-by: Daode Huang <huangdaode@hisilicon.com> Signed-off-by: Kejian Yan <yankejian@huawei.com> Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ec2cafe682
commit
66355f52ca
7 changed files with 155 additions and 0 deletions
|
@ -430,6 +430,10 @@ enum hnae_media_type {
|
||||||
* clear mcast tcam table
|
* clear mcast tcam table
|
||||||
* set_mc_addr()
|
* set_mc_addr()
|
||||||
* set multicast mode
|
* set multicast mode
|
||||||
|
* add_uc_addr()
|
||||||
|
* add ucast address
|
||||||
|
* rm_uc_addr()
|
||||||
|
* remove ucast address
|
||||||
* set_mtu()
|
* set_mtu()
|
||||||
* set mtu
|
* set mtu
|
||||||
* update_stats()
|
* update_stats()
|
||||||
|
@ -490,6 +494,10 @@ struct hnae_ae_ops {
|
||||||
void (*set_promisc_mode)(struct hnae_handle *handle, u32 en);
|
void (*set_promisc_mode)(struct hnae_handle *handle, u32 en);
|
||||||
int (*get_mac_addr)(struct hnae_handle *handle, void **p);
|
int (*get_mac_addr)(struct hnae_handle *handle, void **p);
|
||||||
int (*set_mac_addr)(struct hnae_handle *handle, void *p);
|
int (*set_mac_addr)(struct hnae_handle *handle, void *p);
|
||||||
|
int (*add_uc_addr)(struct hnae_handle *handle,
|
||||||
|
const unsigned char *addr);
|
||||||
|
int (*rm_uc_addr)(struct hnae_handle *handle,
|
||||||
|
const unsigned char *addr);
|
||||||
int (*clr_mc_addr)(struct hnae_handle *handle);
|
int (*clr_mc_addr)(struct hnae_handle *handle);
|
||||||
int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
|
int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
|
||||||
int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
|
int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
|
||||||
|
|
|
@ -199,6 +199,28 @@ static int hns_ae_set_mac_address(struct hnae_handle *handle, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hns_ae_add_uc_address(struct hnae_handle *handle,
|
||||||
|
const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
|
||||||
|
|
||||||
|
if (mac_cb->mac_type != HNAE_PORT_SERVICE)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
return hns_mac_add_uc_addr(mac_cb, handle->vf_id, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hns_ae_rm_uc_address(struct hnae_handle *handle,
|
||||||
|
const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
|
||||||
|
|
||||||
|
if (mac_cb->mac_type != HNAE_PORT_SERVICE)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
return hns_mac_rm_uc_addr(mac_cb, handle->vf_id, addr);
|
||||||
|
}
|
||||||
|
|
||||||
static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
|
static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -830,6 +852,8 @@ static struct hnae_ae_ops hns_dsaf_ops = {
|
||||||
.get_coalesce_range = hns_ae_get_coalesce_range,
|
.get_coalesce_range = hns_ae_get_coalesce_range,
|
||||||
.set_promisc_mode = hns_ae_set_promisc_mode,
|
.set_promisc_mode = hns_ae_set_promisc_mode,
|
||||||
.set_mac_addr = hns_ae_set_mac_address,
|
.set_mac_addr = hns_ae_set_mac_address,
|
||||||
|
.add_uc_addr = hns_ae_add_uc_address,
|
||||||
|
.rm_uc_addr = hns_ae_rm_uc_address,
|
||||||
.set_mc_addr = hns_ae_set_multicast_one,
|
.set_mc_addr = hns_ae_set_multicast_one,
|
||||||
.clr_mc_addr = hns_ae_clr_multicast,
|
.clr_mc_addr = hns_ae_clr_multicast,
|
||||||
.set_mtu = hns_ae_set_mtu,
|
.set_mtu = hns_ae_set_mtu,
|
||||||
|
|
|
@ -263,6 +263,46 @@ int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hns_mac_add_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
|
||||||
|
const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
|
||||||
|
struct dsaf_drv_mac_single_dest_entry mac_entry;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (HNS_DSAF_IS_DEBUG(dsaf_dev))
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
memset(&mac_entry, 0, sizeof(mac_entry));
|
||||||
|
memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
|
||||||
|
mac_entry.in_port_num = mac_cb->mac_id;
|
||||||
|
ret = hns_mac_get_inner_port_num(mac_cb, vf_id, &mac_entry.port_num);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return hns_dsaf_set_mac_uc_entry(dsaf_dev, &mac_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hns_mac_rm_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
|
||||||
|
const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
|
||||||
|
struct dsaf_drv_mac_single_dest_entry mac_entry;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (HNS_DSAF_IS_DEBUG(dsaf_dev))
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
memset(&mac_entry, 0, sizeof(mac_entry));
|
||||||
|
memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
|
||||||
|
mac_entry.in_port_num = mac_cb->mac_id;
|
||||||
|
ret = hns_mac_get_inner_port_num(mac_cb, vf_id, &mac_entry.port_num);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return hns_dsaf_rm_mac_addr(dsaf_dev, &mac_entry);
|
||||||
|
}
|
||||||
|
|
||||||
int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
|
int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
|
||||||
u32 port_num, char *addr, bool enable)
|
u32 port_num, char *addr, bool enable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -461,6 +461,10 @@ int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
|
||||||
void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en);
|
void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en);
|
||||||
int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
|
int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
|
||||||
u8 vmid, u8 *port_num);
|
u8 vmid, u8 *port_num);
|
||||||
|
int hns_mac_add_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
|
||||||
|
const unsigned char *addr);
|
||||||
|
int hns_mac_rm_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
|
||||||
|
const unsigned char *addr);
|
||||||
int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn);
|
int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn);
|
||||||
|
|
||||||
#endif /* _HNS_DSAF_MAC_H */
|
#endif /* _HNS_DSAF_MAC_H */
|
||||||
|
|
|
@ -1598,6 +1598,55 @@ int hns_dsaf_set_mac_uc_entry(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hns_dsaf_rm_mac_addr(
|
||||||
|
struct dsaf_device *dsaf_dev,
|
||||||
|
struct dsaf_drv_mac_single_dest_entry *mac_entry)
|
||||||
|
{
|
||||||
|
u16 entry_index = DSAF_INVALID_ENTRY_IDX;
|
||||||
|
struct dsaf_tbl_tcam_ucast_cfg mac_data;
|
||||||
|
struct dsaf_drv_tbl_tcam_key mac_key;
|
||||||
|
|
||||||
|
/* mac addr check */
|
||||||
|
if (!is_valid_ether_addr(mac_entry->addr)) {
|
||||||
|
dev_err(dsaf_dev->dev, "rm_uc_addr %s Mac %pM err!\n",
|
||||||
|
dsaf_dev->ae_dev.name, mac_entry->addr);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* config key */
|
||||||
|
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, mac_entry->in_vlan_id,
|
||||||
|
mac_entry->in_port_num, mac_entry->addr);
|
||||||
|
|
||||||
|
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
|
||||||
|
if (entry_index == DSAF_INVALID_ENTRY_IDX) {
|
||||||
|
/* can not find the tcam entry, return 0 */
|
||||||
|
dev_info(dsaf_dev->dev,
|
||||||
|
"rm_uc_addr no tcam, %s Mac key(%#x:%#x)\n",
|
||||||
|
dsaf_dev->ae_dev.name,
|
||||||
|
mac_key.high.val, mac_key.low.val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dsaf_dev->dev,
|
||||||
|
"rm_uc_addr, %s Mac key(%#x:%#x) entry_index%d\n",
|
||||||
|
dsaf_dev->ae_dev.name, mac_key.high.val,
|
||||||
|
mac_key.low.val, entry_index);
|
||||||
|
|
||||||
|
hns_dsaf_tcam_uc_get(
|
||||||
|
dsaf_dev, entry_index,
|
||||||
|
(struct dsaf_tbl_tcam_data *)&mac_key,
|
||||||
|
&mac_data);
|
||||||
|
|
||||||
|
/* unicast entry not used locally should not clear */
|
||||||
|
if (mac_entry->port_num != mac_data.tbl_ucast_out_port)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return hns_dsaf_del_mac_entry(dsaf_dev,
|
||||||
|
mac_entry->in_vlan_id,
|
||||||
|
mac_entry->in_port_num,
|
||||||
|
mac_entry->addr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hns_dsaf_set_mac_mc_entry - set mac mc-entry
|
* hns_dsaf_set_mac_mc_entry - set mac mc-entry
|
||||||
* @dsaf_dev: dsa fabric device struct pointer
|
* @dsaf_dev: dsa fabric device struct pointer
|
||||||
|
|
|
@ -468,6 +468,10 @@ void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
|
||||||
u32 *en);
|
u32 *en);
|
||||||
int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
|
int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
|
||||||
u32 en);
|
u32 en);
|
||||||
|
int hns_dsaf_rm_mac_addr(
|
||||||
|
struct dsaf_device *dsaf_dev,
|
||||||
|
struct dsaf_drv_mac_single_dest_entry *mac_entry);
|
||||||
|
|
||||||
int hns_dsaf_clr_mac_mc_port(struct dsaf_device *dsaf_dev,
|
int hns_dsaf_clr_mac_mc_port(struct dsaf_device *dsaf_dev,
|
||||||
u8 mac_id, u8 port_num);
|
u8 mac_id, u8 port_num);
|
||||||
|
|
||||||
|
|
|
@ -1493,6 +1493,29 @@ static netdev_features_t hns_nic_fix_features(
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hns_nic_uc_sync(struct net_device *netdev, const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct hns_nic_priv *priv = netdev_priv(netdev);
|
||||||
|
struct hnae_handle *h = priv->ae_handle;
|
||||||
|
|
||||||
|
if (h->dev->ops->add_uc_addr)
|
||||||
|
return h->dev->ops->add_uc_addr(h, addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hns_nic_uc_unsync(struct net_device *netdev,
|
||||||
|
const unsigned char *addr)
|
||||||
|
{
|
||||||
|
struct hns_nic_priv *priv = netdev_priv(netdev);
|
||||||
|
struct hnae_handle *h = priv->ae_handle;
|
||||||
|
|
||||||
|
if (h->dev->ops->rm_uc_addr)
|
||||||
|
return h->dev->ops->rm_uc_addr(h, addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nic_set_multicast_list - set mutl mac address
|
* nic_set_multicast_list - set mutl mac address
|
||||||
* @netdev: net device
|
* @netdev: net device
|
||||||
|
@ -1535,6 +1558,9 @@ void hns_nic_set_rx_mode(struct net_device *ndev)
|
||||||
}
|
}
|
||||||
|
|
||||||
hns_set_multicast_list(ndev);
|
hns_set_multicast_list(ndev);
|
||||||
|
|
||||||
|
if (__dev_uc_sync(ndev, hns_nic_uc_sync, hns_nic_uc_unsync))
|
||||||
|
netdev_err(ndev, "sync uc address fail\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
|
struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
|
||||||
|
|
Loading…
Reference in a new issue