Commit 6b8609d8 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns-fixes'

Salil Mehta says:

====================
Bug fixes & Code improvements in HNS driver

This patch-set introduces some bug fixes and code improvements.
These have been identified during internal review or testing of
the driver by internal Hisilicon teams.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f522a5fc 66355f52
......@@ -45,6 +45,12 @@ Required properties:
depends on the hardware user manual.
- port-mode-offset: is offset of port mode field for each port in dsaf. Its
value depends on the hardware user manual.
- mc-mac-mask: mask of multicast address, determines bit in multicast address
to set:
1 stands for this bit will be precisely matched, TCAM will check this bit of
MAC address.
0 stands for this bit will be fuzzy matched, TCAM won't care about this bit
of MAC address.
[1] Documentation/devicetree/bindings/net/phy.txt
......@@ -74,10 +80,12 @@ dsaf0: dsa@c7000000 {
reg = 0;
phy-handle = <&phy0>;
serdes-syscon = <&serdes>;
mc-mac-mask = [ff f0 00 00 00 00];
};
port@1 {
reg = 1;
serdes-syscon = <&serdes>;
mc-mac-mask = [ff f0 00 00 00 00];
};
};
......@@ -426,8 +426,14 @@ enum hnae_media_type {
* get mac address
* set_mac_addr()
* set mac address
* clr_mc_addr()
* clear mcast tcam table
* set_mc_addr()
* set multicast mode
* add_uc_addr()
* add ucast address
* rm_uc_addr()
* remove ucast address
* set_mtu()
* set mtu
* update_stats()
......@@ -488,6 +494,11 @@ struct hnae_ae_ops {
void (*set_promisc_mode)(struct hnae_handle *handle, u32 en);
int (*get_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 (*set_mc_addr)(struct hnae_handle *handle, void *addr);
int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
void (*set_tso_stats)(struct hnae_handle *handle, int enable);
......@@ -590,7 +601,7 @@ static inline int hnae_alloc_buffer_attach(struct hnae_ring *ring, int i)
if (ret)
return ret;
ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma);
return 0;
}
......@@ -621,14 +632,14 @@ static inline void hnae_replace_buffer(struct hnae_ring *ring, int i,
bops->unmap_buffer(ring, &ring->desc_cb[i]);
ring->desc_cb[i] = *res_cb;
ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma);
ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
}
static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
{
ring->desc_cb[i].reuse_flag = 0;
ring->desc[i].addr = (__le64)(ring->desc_cb[i].dma
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma
+ ring->desc_cb[i].page_offset);
ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
}
......
......@@ -18,9 +18,6 @@
#include "hns_dsaf_rcb.h"
#define AE_NAME_PORT_ID_IDX 6
#define ETH_STATIC_REG 1
#define ETH_DUMP_REG 5
#define ETH_GSTRING_LEN 32
static struct hns_mac_cb *hns_get_mac_cb(struct hnae_handle *handle)
{
......@@ -202,6 +199,28 @@ static int hns_ae_set_mac_address(struct hnae_handle *handle, void *p)
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)
{
int ret;
......@@ -235,6 +254,16 @@ static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
return ret;
}
static int hns_ae_clr_multicast(struct hnae_handle *handle)
{
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
if (mac_cb->mac_type != HNAE_PORT_SERVICE)
return 0;
return hns_mac_clr_multicast(mac_cb, handle->vf_id);
}
static int hns_ae_set_mtu(struct hnae_handle *handle, int new_mtu)
{
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
......@@ -823,7 +852,10 @@ static struct hnae_ae_ops hns_dsaf_ops = {
.get_coalesce_range = hns_ae_get_coalesce_range,
.set_promisc_mode = hns_ae_set_promisc_mode,
.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,
.clr_mc_addr = hns_ae_clr_multicast,
.set_mtu = hns_ae_set_mtu,
.update_stats = hns_ae_update_stats,
.set_tso_stats = hns_ae_set_tso_stats,
......
......@@ -37,8 +37,8 @@ static const struct mac_stats_string g_gmac_stats_string[] = {
{"gmac_rx_very_long_err", MAC_STATS_FIELD_OFF(rx_long_err)},
{"gmac_rx_runt_err", MAC_STATS_FIELD_OFF(rx_minto64)},
{"gmac_rx_short_err", MAC_STATS_FIELD_OFF(rx_under_min)},
{"gmac_rx_filt_pkt", MAC_STATS_FIELD_OFF(rx_filter_bytes)},
{"gmac_rx_octets_total_filt", MAC_STATS_FIELD_OFF(rx_filter_pkts)},
{"gmac_rx_filt_pkt", MAC_STATS_FIELD_OFF(rx_filter_pkts)},
{"gmac_rx_octets_total_filt", MAC_STATS_FIELD_OFF(rx_filter_bytes)},
{"gmac_rx_overrun_cnt", MAC_STATS_FIELD_OFF(rx_fifo_overrun_err)},
{"gmac_rx_length_err", MAC_STATS_FIELD_OFF(rx_len_err)},
{"gmac_rx_fail_comma", MAC_STATS_FIELD_OFF(rx_comma_err)},
......
......@@ -263,6 +263,46 @@ int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb,
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,
u32 port_num, char *addr, bool enable)
{
......@@ -330,13 +370,24 @@ int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac)
return 0;
}
int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn)
{
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
u8 port_num;
int ret = hns_mac_get_inner_port_num(mac_cb, vfn, &port_num);
if (ret)
return ret;
return hns_dsaf_clr_mac_mc_port(dsaf_dev, mac_cb->mac_id, port_num);
}
static void hns_mac_param_get(struct mac_params *param,
struct hns_mac_cb *mac_cb)
{
param->vaddr = (void *)mac_cb->vaddr;
param->mac_mode = hns_get_enet_interface(mac_cb);
memcpy(param->addr, mac_cb->addr_entry_idx[0].addr,
MAC_NUM_OCTETS_PER_ADDR);
ether_addr_copy(param->addr, mac_cb->addr_entry_idx[0].addr);
param->mac_id = mac_cb->mac_id;
param->dev = mac_cb->dev;
}
......@@ -353,8 +404,7 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
{
int ret;
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
u8 addr[MAC_NUM_OCTETS_PER_ADDR]
= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
u8 addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct dsaf_drv_mac_single_dest_entry mac_entry;
/* directy return ok in debug network mode */
......@@ -389,8 +439,7 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
int ret;
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
u8 port_num;
u8 addr[MAC_NUM_OCTETS_PER_ADDR]
= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
u8 addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct mac_entry_idx *uc_mac_entry;
struct dsaf_drv_mac_single_dest_entry mac_entry;
......@@ -868,6 +917,13 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb)
}
}
if (fwnode_property_read_u8_array(mac_cb->fw_port, "mc-mac-mask",
mac_cb->mc_mask, ETH_ALEN)) {
dev_warn(mac_cb->dev,
"no mc-mac-mask property, set to default value.\n");
eth_broadcast_addr(mac_cb->mc_mask);
}
return 0;
}
......@@ -1081,6 +1137,8 @@ void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en)
{
struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
hns_dsaf_set_promisc_tcam(mac_cb->dsaf_dev, mac_cb->mac_id, !!en);
if (mac_ctrl_drv->set_promiscuous)
mac_ctrl_drv->set_promiscuous(mac_ctrl_drv, en);
}
......
......@@ -31,7 +31,7 @@ struct dsaf_device;
#define MAC_MIN_MTU 68
#define MAC_MAX_MTU_DBG MAC_DEFAULT_MTU
#define MAC_DEFAULT_PAUSE_TIME 0xff
#define MAC_DEFAULT_PAUSE_TIME 0xffff
#define MAC_GMAC_IDX 0
#define MAC_XGMAC_IDX 1
......@@ -56,9 +56,6 @@ struct dsaf_device;
/*check mac addr multicast*/
#define MAC_IS_MULTICAST(p) ((*((u8 *)((p) + 0)) & 0x01) ? (1) : (0))
/**< Number of octets (8-bit bytes) in an ethernet address */
#define MAC_NUM_OCTETS_PER_ADDR 6
struct mac_priv {
void *mac;
};
......@@ -189,7 +186,7 @@ struct mac_statistics {
/*mac para struct ,mac get param from nic or dsaf when initialize*/
struct mac_params {
char addr[MAC_NUM_OCTETS_PER_ADDR];
char addr[ETH_ALEN];
void *vaddr; /*virtual address*/
struct device *dev;
u8 mac_id;
......@@ -214,7 +211,7 @@ struct mac_info {
};
struct mac_entry_idx {
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u8 addr[ETH_ALEN];
u16 vlan_id:12;
u16 valid:1;
u16 qos:3;
......@@ -317,6 +314,7 @@ struct hns_mac_cb {
u8 __iomem *serdes_vaddr;
struct regmap *serdes_ctrl;
struct regmap *cpld_ctrl;
char mc_mask[ETH_ALEN];
u32 cpld_ctrl_reg;
u32 port_rst_off;
u32 port_mode_off;
......@@ -409,7 +407,7 @@ struct mac_driver {
};
struct mac_stats_string {
char desc[64];
char desc[ETH_GSTRING_LEN];
unsigned long offset;
};
......@@ -463,5 +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);
int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
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);
#endif /* _HNS_DSAF_MAC_H */
......@@ -591,6 +591,16 @@ static void hns_dsaf_voq_bp_all_thrd_cfg(struct dsaf_device *dsaf_dev)
}
}
static void hns_dsaf_tbl_tcam_match_cfg(
struct dsaf_device *dsaf_dev,
struct dsaf_tbl_tcam_data *ptbl_tcam_data)
{
dsaf_write_dev(dsaf_dev, DSAF_TBL_TCAM_MATCH_CFG_L_REG,
ptbl_tcam_data->tbl_tcam_data_low);
dsaf_write_dev(dsaf_dev, DSAF_TBL_TCAM_MATCH_CFG_H_REG,
ptbl_tcam_data->tbl_tcam_data_high);
}
/**
* hns_dsaf_tbl_tcam_data_cfg - tbl
* @dsaf_id: dsa fabric id
......@@ -755,7 +765,7 @@ static void hns_dsaf_tbl_tcam_data_ucast_pul(
void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en)
{
if (!HNS_DSAF_IS_DEBUG(dsaf_dev))
if (AE_IS_VER1(dsaf_dev->dsaf_ver) && !HNS_DSAF_IS_DEBUG(dsaf_dev))
dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG,
DSAF_CFG_MIX_MODE_S, !!en);
}
......@@ -894,15 +904,16 @@ static void hns_dsaf_tcam_uc_cfg(
}
/**
* hns_dsaf_tcam_mc_cfg - INT
* @dsaf_id: dsa fabric id
* @address,
* @ptbl_tcam_data,
* @ptbl_tcam_mcast,
* hns_dsaf_tcam_mc_cfg - cfg the tcam for mc
* @dsaf_dev: dsa fabric device struct pointer
* @address: tcam index
* @ptbl_tcam_data: tcam data struct pointer
* @ptbl_tcam_mcast: tcam mask struct pointer, it must be null for HNSv1
*/
static void hns_dsaf_tcam_mc_cfg(
struct dsaf_device *dsaf_dev, u32 address,
struct dsaf_tbl_tcam_data *ptbl_tcam_data,
struct dsaf_tbl_tcam_data *ptbl_tcam_mask,
struct dsaf_tbl_tcam_mcast_cfg *ptbl_tcam_mcast)
{
spin_lock_bh(&dsaf_dev->tcam_lock);
......@@ -913,7 +924,11 @@ static void hns_dsaf_tcam_mc_cfg(
hns_dsaf_tbl_tcam_data_cfg(dsaf_dev, ptbl_tcam_data);
/*Write Tcam Mcast*/
hns_dsaf_tbl_tcam_mcast_cfg(dsaf_dev, ptbl_tcam_mcast);
/*Write Plus*/
/* Write Match Data */
if (ptbl_tcam_mask)
hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
/* Write Puls */
hns_dsaf_tbl_tcam_data_mcast_pul(dsaf_dev);
spin_unlock_bh(&dsaf_dev->tcam_lock);
......@@ -944,6 +959,16 @@ static void hns_dsaf_tcam_mc_invld(struct dsaf_device *dsaf_dev, u32 address)
spin_unlock_bh(&dsaf_dev->tcam_lock);
}
void hns_dsaf_tcam_addr_get(struct dsaf_drv_tbl_tcam_key *mac_key, u8 *addr)
{
addr[0] = mac_key->high.bits.mac_0;
addr[1] = mac_key->high.bits.mac_1;
addr[2] = mac_key->high.bits.mac_2;
addr[3] = mac_key->high.bits.mac_3;
addr[4] = mac_key->low.bits.mac_4;
addr[5] = mac_key->low.bits.mac_5;
}
/**
* hns_dsaf_tcam_uc_get - INT
* @dsaf_id: dsa fabric id
......@@ -1369,6 +1394,12 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev)
if (HNS_DSAF_IS_DEBUG(dsaf_dev))
return 0;
if (AE_IS_VER1(dsaf_dev->dsaf_ver))
dsaf_dev->tcam_max_num = DSAF_TCAM_SUM;
else
dsaf_dev->tcam_max_num =
DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM;
spin_lock_init(&dsaf_dev->tcam_lock);
ret = hns_dsaf_init_hw(dsaf_dev);
if (ret)
......@@ -1424,7 +1455,7 @@ static u16 hns_dsaf_find_soft_mac_entry(
u32 i;
soft_mac_entry = priv->soft_mac_tbl;
for (i = 0; i < DSAF_TCAM_SUM; i++) {
for (i = 0; i < dsaf_dev->tcam_max_num; i++) {
/* invall tab entry */
if ((soft_mac_entry->index != DSAF_INVALID_ENTRY_IDX) &&
(soft_mac_entry->tcam_key.high.val == mac_key->high.val) &&
......@@ -1449,7 +1480,7 @@ static u16 hns_dsaf_find_empty_mac_entry(struct dsaf_device *dsaf_dev)
u32 i;
soft_mac_entry = priv->soft_mac_tbl;
for (i = 0; i < DSAF_TCAM_SUM; i++) {
for (i = 0; i < dsaf_dev->tcam_max_num; i++) {
/* inv all entry */
if (soft_mac_entry->index == DSAF_INVALID_ENTRY_IDX)
/* return find result --soft index */
......@@ -1488,8 +1519,12 @@ static void hns_dsaf_set_mac_key(
mac_key->high.bits.mac_3 = addr[3];
mac_key->low.bits.mac_4 = addr[4];
mac_key->low.bits.mac_5 = addr[5];
mac_key->low.bits.vlan = vlan_id;
mac_key->low.bits.port = port;
dsaf_set_field(mac_key->low.bits.port_vlan, DSAF_TBL_TCAM_KEY_VLAN_M,
DSAF_TBL_TCAM_KEY_VLAN_S, vlan_id);
dsaf_set_field(mac_key->low.bits.port_vlan, DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S, port);
mac_key->low.bits.port_vlan = le16_to_cpu(mac_key->low.bits.port_vlan);
}
/**
......@@ -1507,6 +1542,7 @@ int hns_dsaf_set_mac_uc_entry(
struct dsaf_drv_priv *priv =
(struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
struct dsaf_tbl_tcam_data tcam_data;
/* mac addr check */
if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
......@@ -1548,9 +1584,10 @@ int hns_dsaf_set_mac_uc_entry(
/* default config dvc to 0 */
mac_data.tbl_ucast_dvc = 0;
mac_data.tbl_ucast_out_port = mac_entry->port_num;
hns_dsaf_tcam_uc_cfg(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
tcam_data.tbl_tcam_data_high = cpu_to_le32(mac_key.high.val);
tcam_data.tbl_tcam_data_low = cpu_to_le32(mac_key.low.val);
hns_dsaf_tcam_uc_cfg(dsaf_dev, entry_index, &tcam_data, &mac_data);
/* config software entry */
soft_mac_entry += entry_index;
......@@ -1561,6 +1598,55 @@ int hns_dsaf_set_mac_uc_entry(
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
* @dsaf_dev: dsa fabric device struct pointer
......@@ -1577,6 +1663,7 @@ int hns_dsaf_set_mac_mc_entry(
(struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
struct dsaf_drv_tbl_tcam_key tmp_mac_key;
struct dsaf_tbl_tcam_data tcam_data;
/* mac addr check */
if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
......@@ -1609,9 +1696,12 @@ int hns_dsaf_set_mac_mc_entry(
0, sizeof(mac_data.tbl_mcast_port_msk));
} else {
/* config hardware entry */
hns_dsaf_tcam_mc_get(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&tmp_mac_key), &mac_data);
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data,
&mac_data);
tmp_mac_key.high.val =
le32_to_cpu(tcam_data.tbl_tcam_data_high);
tmp_mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
}
mac_data.tbl_mcast_old_en = 0;
mac_data.tbl_mcast_item_vld = 1;
......@@ -1623,9 +1713,11 @@ int hns_dsaf_set_mac_mc_entry(
dsaf_dev->ae_dev.name, mac_key.high.val,
mac_key.low.val, entry_index);
hns_dsaf_tcam_mc_cfg(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
tcam_data.tbl_tcam_data_high = cpu_to_le32(mac_key.high.val);
tcam_data.tbl_tcam_data_low = cpu_to_le32(mac_key.low.val);
hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index, &tcam_data, NULL,
&mac_data);
/* config software entry */
soft_mac_entry += entry_index;
......@@ -1636,6 +1728,16 @@ int hns_dsaf_set_mac_mc_entry(
return 0;
}
static void hns_dsaf_mc_mask_bit_clear(char *dst, const char *src)
{
u16 *a = (u16 *)dst;
const u16 *b = (const u16 *)src;
a[0] &= b[0];
a[1] &= b[1];
a[2] &= b[2];
}
/**
* hns_dsaf_add_mac_mc_port - add mac mc-port
* @dsaf_dev: dsa fabric device struct pointer
......@@ -1646,11 +1748,15 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
{
u16 entry_index = DSAF_INVALID_ENTRY_IDX;
struct dsaf_drv_tbl_tcam_key mac_key;
struct dsaf_drv_tbl_tcam_key mask_key;
struct dsaf_tbl_tcam_data *pmask_key = NULL;
struct dsaf_tbl_tcam_mcast_cfg mac_data;
struct dsaf_drv_priv *priv =
(struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
struct dsaf_drv_tbl_tcam_key tmp_mac_key;
struct dsaf_tbl_tcam_data tcam_data;
u8 mc_addr[ETH_ALEN];
u8 *mc_mask;
int mskid;
/*chechk mac addr */
......@@ -1660,14 +1766,32 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
return -EINVAL;
}
ether_addr_copy(mc_addr, mac_entry->addr);
mc_mask = dsaf_dev->mac_cb[mac_entry->in_port_num]->mc_mask;
if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
/* prepare for key data setting */
hns_dsaf_mc_mask_bit_clear(mc_addr, mc_mask);
/* config key mask */
hns_dsaf_set_mac_key(dsaf_dev, &mask_key,
0x0,
0xff,
mc_mask);
mask_key.high.val = le32_to_cpu(mask_key.high.val);
mask_key.low.val = le32_to_cpu(mask_key.low.val);
pmask_key = (struct dsaf_tbl_tcam_data *)(&mask_key);
}
/*config key */
hns_dsaf_set_mac_key(
dsaf_dev, &mac_key, mac_entry->in_vlan_id,
mac_entry->in_port_num, mac_entry->addr);
mac_entry->in_port_num, mc_addr);
memset(&mac_data, 0, sizeof(struct dsaf_tbl_tcam_mcast_cfg));
/*check exist? */
/* check if the tcam is exist */
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
if (entry_index == DSAF_INVALID_ENTRY_IDX) {
/*if hasnot , find a empty*/
......@@ -1681,11 +1805,15 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
return -EINVAL;
}
} else {
/*if exist, add in */
hns_dsaf_tcam_mc_get(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&tmp_mac_key), &mac_data);
/* if exist, add in */
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data,
&mac_data);
tmp_mac_key.high.val =
le32_to_cpu(tcam_data.tbl_tcam_data_high);
tmp_mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
}
/* config hardware entry */
if (mac_entry->port_num < DSAF_SERVICE_NW_NUM) {
mskid = mac_entry->port_num;
......@@ -1708,9 +1836,12 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
dsaf_dev->ae_dev.name, mac_key.high.val,
mac_key.low.val, entry_index);
hns_dsaf_tcam_mc_cfg(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
tcam_data.tbl_tcam_data_high = cpu_to_le32(mac_key.high.val);
tcam_data.tbl_tcam_data_low = cpu_to_le32(mac_key.low.val);
/* config mc entry with mask */
hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index, &tcam_data,
pmask_key, &mac_data);
/*config software entry */
soft_mac_entry += entry_index;
......@@ -1782,15 +1913,18 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
{
u16 entry_index = DSAF_INVALID_ENTRY_IDX;
struct dsaf_drv_tbl_tcam_key mac_key;
struct dsaf_drv_priv *priv =
(struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
u16 vlan_id;
u8 in_port_num;
struct dsaf_tbl_tcam_mcast_cfg mac_data;
struct dsaf_drv_tbl_tcam_key tmp_mac_key;
struct dsaf_tbl_tcam_data tcam_data;
int mskid;
const u8 empty_msk[sizeof(mac_data.tbl_mcast_port_msk)] = {0};
struct dsaf_drv_tbl_tcam_key mask_key, tmp_mac_key;
struct dsaf_tbl_tcam_data *pmask_key = NULL;
u8 mc_addr[ETH_ALEN];
u8 *mc_mask;
if (!(void *)mac_entry) {
dev_err(dsaf_dev->dev,
......@@ -1798,10 +1932,6 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
return -EINVAL;
}
/*get key info*/
vlan_id = mac_entry->in_vlan_id;
in_port_num = mac_entry->in_port_num;
/*check mac addr */
if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
dev_err(dsaf_dev->dev, "del_port failed, addr %pM!\n",
......@@ -1809,11 +1939,31 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
return -EINVAL;
}
/*config key */
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, vlan_id, in_port_num,
mac_entry->addr);
/* always mask vlan_id field */
ether_addr_copy(mc_addr, mac_entry->addr);
mc_mask = dsaf_dev->mac_cb[mac_entry->in_port_num]->mc_mask;
if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
/* prepare for key data setting */
hns_dsaf_mc_mask_bit_clear(mc_addr, mc_mask);
/* config key mask */
hns_dsaf_set_mac_key(dsaf_dev, &mask_key, 0x00, 0xff, mc_addr);
mask_key.high.val = le32_to_cpu(mask_key.high.val);
mask_key.low.val = le32_to_cpu(mask_key.low.val);
/*check is exist? */
pmask_key = (struct dsaf_tbl_tcam_data *)(&mask_key);
}
/* get key info */
vlan_id = mac_entry->in_vlan_id;
in_port_num = mac_entry->in_port_num;
/* config key */
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, vlan_id, in_port_num, mc_addr);
/* check if the tcam entry is exist */
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
if (entry_index == DSAF_INVALID_ENTRY_IDX) {
/*find none */
......@@ -1829,10 +1979,11 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
dsaf_dev->ae_dev.name, mac_key.high.val,
mac_key.low.val, entry_index);
/*read entry*/
hns_dsaf_tcam_mc_get(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&tmp_mac_key), &mac_data);
/* read entry */
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
tmp_mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
tmp_mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
/*del the port*/
if (mac_entry->port_num < DSAF_SERVICE_NW_NUM) {
......@@ -1857,15 +2008,87 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
/* del soft entry */
soft_mac_entry += entry_index;
soft_mac_entry->index = DSAF_INVALID_ENTRY_IDX;
} else { /* not zer, just del port, updata*/
hns_dsaf_tcam_mc_cfg(
dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
} else { /* not zero, just del port, update */
tcam_data.tbl_tcam_data_high = cpu_to_le32(mac_key.high.val);
tcam_data.tbl_tcam_data_low = cpu_to_le32(mac_key.low.val);
hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index,
&tcam_data,
pmask_key, &mac_data);
}
return 0;
}
int hns_dsaf_clr_mac_mc_port(struct dsaf_device *dsaf_dev, u8 mac_id,
u8 port_num)
{
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry;
struct dsaf_tbl_tcam_mcast_cfg mac_data;
int ret = 0, i;
if (HNS_DSAF_IS_DEBUG(dsaf_dev))
return 0;
for (i = 0; i < DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM; i++) {
u8 addr[ETH_ALEN];
u8 port;
soft_mac_entry = priv->soft_mac_tbl + i;
hns_dsaf_tcam_addr_get(&soft_mac_entry->tcam_key, addr);
port = dsaf_get_field(
soft_mac_entry->tcam_key.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S);
/* check valid tcam mc entry */
if (soft_mac_entry->index != DSAF_INVALID_ENTRY_IDX &&
port == mac_id &&
is_multicast_ether_addr(addr) &&
!is_broadcast_ether_addr(addr)) {
const u32 empty_msk[DSAF_PORT_MSK_NUM] = {0};
struct dsaf_drv_mac_single_dest_entry mac_entry;
/* disable receiving of this multicast address for
* the VF.
*/
ether_addr_copy(mac_entry.addr, addr);
mac_entry.in_vlan_id = dsaf_get_field(
soft_mac_entry->tcam_key.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_VLAN_M,
DSAF_TBL_TCAM_KEY_VLAN_S);
mac_entry.in_port_num = mac_id;
mac_entry.port_num = port_num;
if (hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry)) {
ret = -EINVAL;
continue;
}
/* disable receiving of this multicast address for
* the mac port if all VF are disable
*/
hns_dsaf_tcam_mc_get(dsaf_dev, i,
(struct dsaf_tbl_tcam_data *)
(&soft_mac_entry->tcam_key),
&mac_data);
dsaf_set_bit(mac_data.tbl_mcast_port_msk[mac_id / 32],
mac_id % 32, 0);
if (!memcmp(mac_data.tbl_mcast_port_msk, empty_msk,
sizeof(u32) * DSAF_PORT_MSK_NUM)) {
mac_entry.port_num = mac_id;
if (hns_dsaf_del_mac_mc_port(dsaf_dev,
&mac_entry)) {
ret = -EINVAL;
continue;
}
}
}
}
return ret;
}
/**
* hns_dsaf_get_mac_uc_entry - get mac uc entry
* @dsaf_dev: dsa fabric device struct pointer
......@@ -1878,6 +2101,7 @@ int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_tbl_tcam_key mac_key;
struct dsaf_tbl_tcam_ucast_cfg mac_data;
struct dsaf_tbl_tcam_data tcam_data;
/* check macaddr */
if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
......@@ -1906,9 +2130,12 @@ int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
dsaf_dev->ae_dev.name, mac_key.high.val,
mac_key.low.val, entry_index);
/*read entry*/
hns_dsaf_tcam_uc_get(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&mac_key, &mac_data);
/* read entry */
hns_dsaf_tcam_uc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
mac_entry->port_num = mac_data.tbl_ucast_out_port;
return 0;
......@@ -1926,6 +2153,7 @@ int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_tbl_tcam_key mac_key;
struct dsaf_tbl_tcam_mcast_cfg mac_data;
struct dsaf_tbl_tcam_data tcam_data;
/*check mac addr */
if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
......@@ -1955,8 +2183,10 @@ int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
mac_key.low.val, entry_index);
/*read entry */
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&mac_key, &mac_data);
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
mac_entry->port_mask[0] = mac_data.tbl_mcast_port_msk[0] & 0x3F;
return 0;
......@@ -1976,9 +2206,10 @@ int hns_dsaf_get_mac_entry_by_index(
struct dsaf_tbl_tcam_mcast_cfg mac_data;
struct dsaf_tbl_tcam_ucast_cfg mac_uc_data;
char mac_addr[MAC_NUM_OCTETS_PER_ADDR] = {0};
struct dsaf_tbl_tcam_data tcam_data;
char mac_addr[ETH_ALEN] = {0};
if (entry_index >= DSAF_TCAM_SUM) {
if (entry_index >= dsaf_dev->tcam_max_num) {
/* find none, del error */
dev_err(dsaf_dev->dev, "get_uc_entry failed, %s\n",
dsaf_dev->ae_dev.name);
......@@ -1986,8 +2217,10 @@ int hns_dsaf_get_mac_entry_by_index(
}
/* mc entry, do read opt */
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&mac_key, &mac_data);
hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
mac_entry->port_mask[0] = mac_data.tbl_mcast_port_msk[0] & 0x3F;
......@@ -2004,9 +2237,12 @@ int hns_dsaf_get_mac_entry_by_index(
/**mc donot do*/
} else {
/*is not mc, just uc... */
hns_dsaf_tcam_uc_get(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&mac_key,
hns_dsaf_tcam_uc_get(dsaf_dev, entry_index, &tcam_data,
&mac_uc_data);
mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
mac_entry->port_mask[0] = (1 << mac_uc_data.tbl_ucast_out_port);
}
......@@ -2670,6 +2906,59 @@ int hns_dsaf_get_regs_count(void)
return DSAF_DUMP_REGS_NUM;
}
/* Reserve the last TCAM entry for promisc support */
#define dsaf_promisc_tcam_entry(port) \
(DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM + (port))
void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
u32 port, bool enable)
{
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
u16 entry_index;
struct dsaf_drv_tbl_tcam_key tbl_tcam_data, tbl_tcam_mask;
struct dsaf_tbl_tcam_mcast_cfg mac_data = {0};
if ((AE_IS_VER1(dsaf_dev->dsaf_ver)) || HNS_DSAF_IS_DEBUG(dsaf_dev))
return;
/* find the tcam entry index for promisc */
entry_index = dsaf_promisc_tcam_entry(port);
/* config key mask */
if (enable) {
memset(&tbl_tcam_data, 0, sizeof(tbl_tcam_data));
memset(&tbl_tcam_mask, 0, sizeof(tbl_tcam_mask));
dsaf_set_field(tbl_tcam_data.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S, port);
dsaf_set_field(tbl_tcam_mask.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S, 0xf);
/* SUB_QID */
dsaf_set_bit(mac_data.tbl_mcast_port_msk[0],
DSAF_SERVICE_NW_NUM, true);
mac_data.tbl_mcast_item_vld = true; /* item_vld bit */
} else {
mac_data.tbl_mcast_item_vld = false; /* item_vld bit */
}
dev_dbg(dsaf_dev->dev,
"set_promisc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
dsaf_dev->ae_dev.name, tbl_tcam_data.high.val,
tbl_tcam_data.low.val, entry_index);
/* config promisc entry with mask */
hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&tbl_tcam_data,
(struct dsaf_tbl_tcam_data *)&tbl_tcam_mask,
&mac_data);
/* config software entry */
soft_mac_entry += entry_index;
soft_mac_entry->index = enable ? entry_index : DSAF_INVALID_ENTRY_IDX;
}
/**
* dsaf_probe - probo dsaf dev
* @pdev: dasf platform device
......
......@@ -35,8 +35,6 @@ struct hns_mac_cb;
#define DSAF_CFG_READ_CNT 30
#define MAC_NUM_OCTETS_PER_ADDR 6
#define DSAF_DUMP_REGS_NUM 504
#define DSAF_STATIC_NUM 28
#define DSAF_V2_STATIC_NUM 44
......@@ -165,7 +163,7 @@ enum dsaf_mode {
/*mac entry, mc or uc entry*/
struct dsaf_drv_mac_single_dest_entry {
/* mac addr, match the entry*/
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u8 addr[ETH_ALEN];
u16 in_vlan_id; /* value of VlanId */
/* the vld input port num, dsaf-mode fix 0, */
......@@ -179,7 +177,7 @@ struct dsaf_drv_mac_single_dest_entry {
/*only mc entry*/
struct dsaf_drv_mac_multi_dest_entry {
/* mac addr, match the entry*/
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u8 addr[ETH_ALEN];
u16 in_vlan_id;
/* this mac addr output port,*/
/* bit0-bit5 means Port0-Port5(1bit is vld)**/
......@@ -308,8 +306,6 @@ struct dsaf_misc_op {
/* reset series function, it will be reset if the dereset is 0 */
void (*dsaf_reset)(struct dsaf_device *dsaf_dev, bool dereset);
void (*xge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*xge_core_srst)(struct dsaf_device *dsaf_dev, u32 port,
bool dereset);
void (*ge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*ppe_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*ppe_comm_srst)(struct dsaf_device *dsaf_dev, bool dereset);
......@@ -343,6 +339,7 @@ struct dsaf_device {
enum hal_dsaf_mode dsaf_en;
enum hal_dsaf_tc_mode dsaf_tc_mode;
u32 dsaf_ver;
u16 tcam_max_num; /* max TCAM entry for user except promisc */
struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM];
struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM];
......@@ -360,6 +357,11 @@ static inline void *hns_dsaf_dev_priv(const struct dsaf_device *dsaf_dev)
return (void *)((u8 *)dsaf_dev + sizeof(*dsaf_dev));
}
#define DSAF_TBL_TCAM_KEY_PORT_S 0
#define DSAF_TBL_TCAM_KEY_PORT_M (((1ULL << 4) - 1) << 0)
#define DSAF_TBL_TCAM_KEY_VLAN_S 4
#define DSAF_TBL_TCAM_KEY_VLAN_M (((1ULL << 12) - 1) << 4)
struct dsaf_drv_tbl_tcam_key {
union {
struct {
......@@ -373,11 +375,9 @@ struct dsaf_drv_tbl_tcam_key {
} high;
union {
struct {
u32 port:4; /* port id, */
/* dsaf-mode fixed 0, non-dsaf-mode port id*/
u32 vlan:12; /* vlan id */
u32 mac_5:8;
u32 mac_4:8;
u16 port_vlan;
u8 mac_5;
u8 mac_4;
} bits;
u32 val;
......@@ -461,10 +461,19 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port,
void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
int hns_dsaf_get_regs_count(void);
void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
u32 port, bool enable);
void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
u32 *en);
int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
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,
u8 mac_id, u8 port_num);
#endif /* __HNS_DSAF_MAIN_H__ */
......@@ -23,7 +23,6 @@ enum _dsm_op_index {
enum _dsm_rst_type {
HNS_DSAF_RESET_FUNC = 0x1,
HNS_PPE_RESET_FUNC = 0x2,
HNS_XGE_CORE_RESET_FUNC = 0x3,
HNS_XGE_RESET_FUNC = 0x4,
HNS_GE_RESET_FUNC = 0x5,
HNS_DSAF_CHN_RESET_FUNC = 0x6,
......@@ -213,26 +212,6 @@ static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
HNS_XGE_RESET_FUNC, port, dereset);
}
static void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
u32 port, bool dereset)
{
u32 reg_val = 0;
u32 reg_addr;
if (port >= DSAF_XGE_NUM)
return;
reg_val |= XGMAC_TRX_CORE_SRST_M
<< dsaf_dev->mac_cb[port]->port_rst_off;
if (!dereset)
reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
else
reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
}
/**
* hns_dsaf_srst_chns - reset dsaf channels
* @dsaf_dev: dsaf device struct pointer
......@@ -293,14 +272,6 @@ void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
HNS_ROCE_RESET_FUNC, 0, dereset);
}
static void
hns_dsaf_xge_core_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
u32 port, bool dereset)
{
hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
HNS_XGE_CORE_RESET_FUNC, port, dereset);
}
static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
bool dereset)
{
......@@ -597,7 +568,6 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
misc_op->dsaf_reset = hns_dsaf_rst;
misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port;
misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
misc_op->ppe_srst = hns_ppe_srst_by_port;
misc_op->ppe_comm_srst = hns_ppe_com_srst;
......@@ -615,7 +585,6 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
misc_op->dsaf_reset = hns_dsaf_rst_acpi;
misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port_acpi;
misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
misc_op->ppe_comm_srst = hns_ppe_com_srst;
......
......@@ -41,6 +41,9 @@
#define DSAF_SW_PORT_NUM 8
#define DSAF_TOTAL_QUEUE_NUM 129
/* reserved a tcam entry for each port to support promisc by fuzzy match */
#define DSAFV2_MAC_FUZZY_TCAM_NUM DSAF_MAX_PORT_NUM
#define DSAF_TCAM_SUM 512
#define DSAF_LINE_SUM (2048 * 14)
......@@ -297,6 +300,8 @@
#define DSAF_TBL_LKUP_NUM_I_0_REG 0x50C0
#define DSAF_TBL_LKUP_NUM_O_0_REG 0x50E0
#define DSAF_TBL_UCAST_BCAST_MIS_INFO_0_0_REG 0x510C
#define DSAF_TBL_TCAM_MATCH_CFG_H_REG 0x5130
#define DSAF_TBL_TCAM_MATCH_CFG_L_REG 0x5134
#define DSAF_INODE_FIFO_WL_0_REG 0x6000
#define DSAF_ONODE_FIFO_WL_0_REG 0x6020
......@@ -309,7 +314,6 @@
#define PPE_COM_INTEN_REG 0x110
#define PPE_COM_RINT_REG 0x114
#define PPE_COM_INTSTS_REG 0x118
#define PPE_COM_COMMON_CNT_CLR_CE_REG 0x1120
#define PPE_COM_HIS_RX_PKT_QID_DROP_CNT_REG 0x300
#define PPE_COM_HIS_RX_PKT_QID_OK_CNT_REG 0x600
#define PPE_COM_HIS_TX_PKT_QID_ERR_CNT_REG 0x900
......@@ -698,8 +702,6 @@
#define XGMAC_RX_SYMBOLERRPKTS 0x0210
#define XGMAC_RX_FCSERRPKTS 0x0218
#define XGMAC_TRX_CORE_SRST_M 0x2080
#define DSAF_SRAM_INIT_OVER_M 0xff
#define DSAFV2_SRAM_INIT_OVER_M 0x3ff
#define DSAF_SRAM_INIT_OVER_S 0
......@@ -978,6 +980,11 @@
#define XGMAC_ENABLE_TX_B 0
#define XGMAC_ENABLE_RX_B 1
#define XGMAC_UNIDIR_EN_B 0
#define XGMAC_RF_TX_EN_B 1
#define XGMAC_LF_RF_INSERT_S 2
#define XGMAC_LF_RF_INSERT_M (0x3 << XGMAC_LF_RF_INSERT_S)
#define XGMAC_CTL_TX_FCS_B 0
#define XGMAC_CTL_TX_PAD_B 1
#define XGMAC_CTL_TX_PREAMBLE_TRANS_B 3
......
......@@ -107,6 +107,31 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
dsaf_set_dev_bit(drv, XGMAC_MAC_ENABLE_REG, XGMAC_ENABLE_RX_B, !!value);
}
/**
* hns_xgmac_tx_lf_rf_insert - insert lf rf control about xgmac
* @mac_drv: mac driver
* @mode: inserf rf or lf
*/
static void hns_xgmac_lf_rf_insert(struct mac_driver *mac_drv, u32 mode)
{
dsaf_set_dev_field(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG,
XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, mode);
}
/**
* hns_xgmac__lf_rf_control_init - initial the lf rf control register
* @mac_drv: mac driver
*/
static void hns_xgmac_lf_rf_control_init(struct mac_driver *mac_drv)
{
u32 val = 0;
dsaf_set_bit(val, XGMAC_UNIDIR_EN_B, 0);
dsaf_set_bit(val, XGMAC_RF_TX_EN_B, 1);
dsaf_set_field(val, XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, 0);
dsaf_write_reg(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG, val);
}
/**
*hns_xgmac_enable - enable xgmac port
*@drv: mac driver
......@@ -115,12 +140,8 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
{
struct mac_driver *drv = (struct mac_driver *)mac_drv;
struct dsaf_device *dsaf_dev
= (struct dsaf_device *)dev_get_drvdata(drv->dev);
u32 port = drv->mac_id;
dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 1);
mdelay(10);
hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_NO_LF_RF_INSERT);
/*enable XGE rX/tX */
if (mode == MAC_COMM_MODE_TX) {
......@@ -143,9 +164,6 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
{
struct mac_driver *drv = (struct mac_driver *)mac_drv;
struct dsaf_device *dsaf_dev
= (struct dsaf_device *)dev_get_drvdata(drv->dev);
u32 port = drv->mac_id;
if (mode == MAC_COMM_MODE_TX) {
hns_xgmac_tx_enable(drv, 0);
......@@ -155,9 +173,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
hns_xgmac_tx_enable(drv, 0);
hns_xgmac_rx_enable(drv, 0);
}
mdelay(10);
dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 0);
hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_LF_INSERT);
}
/**
......@@ -203,6 +219,7 @@ static void hns_xgmac_init(void *mac_drv)
dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1);
mdelay(100);
hns_xgmac_lf_rf_control_init(drv);
hns_xgmac_exc_irq_en(drv, 0);
hns_xgmac_pma_fec_enable(drv, 0x0, 0x0);
......@@ -788,7 +805,7 @@ static int hns_xgmac_get_sset_count(int stringset)
*/
static int hns_xgmac_get_regs_count(void)
{
return ETH_XGMAC_DUMP_NUM;
return HNS_XGMAC_DUMP_NUM;
}
void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
......
......@@ -10,6 +10,7 @@
#ifndef _HNS_XGMAC_H
#define _HNS_XGMAC_H
#define ETH_XGMAC_DUMP_NUM (214)
#define HNS_XGMAC_DUMP_NUM 214
#define HNS_XGMAC_NO_LF_RF_INSERT 0x0
#define HNS_XGMAC_LF_INSERT 0x2
#endif
......@@ -1493,6 +1493,29 @@ static netdev_features_t hns_nic_fix_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
* @netdev: net device
......@@ -1511,6 +1534,10 @@ void hns_set_multicast_list(struct net_device *ndev)
return;
}
if (h->dev->ops->clr_mc_addr)
if (h->dev->ops->clr_mc_addr(h))
netdev_err(ndev, "clear multicast address fail\n");
if (h->dev->ops->set_mc_addr) {
netdev_for_each_mc_addr(ha, ndev)
if (h->dev->ops->set_mc_addr(h, ha->addr))
......@@ -1531,6 +1558,9 @@ void hns_nic_set_rx_mode(struct net_device *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,
......
......@@ -1178,7 +1178,8 @@ static int hns_nic_nway_reset(struct net_device *netdev)
struct phy_device *phy = netdev->phydev;
if (netif_running(netdev)) {
if (phy)
/* if autoneg is disabled, don't restart auto-negotiation */
if (phy && phy->autoneg == AUTONEG_ENABLE)
ret = genphy_restart_aneg(phy);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment