Merge branch 'hns-fixes'

Yisen Zhuang says:

====================
net: hns: bugs fixed for hns

This series includes some bug fixes and updates for hns driver.

>from Daode, one fix about mss.

>from Kejian, one fix about ping6 issue, one fix about mac address setting,
two fix for RSS setting, two fix about mtu setting.

>from qianqian, fixed HNS v2 xge statistic reg issue.

>from Sheng, one fix about manage packets sending, one fix about GMACs mac
setting.

For more details, please see individual patches.

Thanks a lot!

---
change log:
 Series V2:
  - fix the comments as below:
    1) modifies the wrong charator "whick" to "which" in commit log
    2) use the "eth_hdr()" help to get source mac of packets
    3) fix the wrong cast
    4) use tabs instead of spaces to indent the value

 Series V1:
  - first submit
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2016-03-22 15:45:59 -04:00
commit 0419f4a953
11 changed files with 117 additions and 41 deletions

View file

@ -147,6 +147,8 @@ enum hnae_led_state {
#define HNSV2_TXD_BUFNUM_S 0
#define HNSV2_TXD_BUFNUM_M (0x7 << HNSV2_TXD_BUFNUM_S)
#define HNSV2_TXD_PORTID_S 4
#define HNSV2_TXD_PORTID_M (0X7 << HNSV2_TXD_PORTID_S)
#define HNSV2_TXD_RI_B 1
#define HNSV2_TXD_L4CS_B 2
#define HNSV2_TXD_L3CS_B 3
@ -516,6 +518,7 @@ struct hnae_handle {
int q_num;
int vf_id;
u32 eport_id;
u32 dport_id; /* v2 tx bd should fill the dport_id */
enum hnae_port_type port_type;
struct list_head node; /* list to hnae_ae_dev->handle_list */
struct hnae_buf_ops *bops; /* operation for the buffer */

View file

@ -175,6 +175,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev,
ae_handle->phy_node = vf_cb->mac_cb->phy_node;
ae_handle->if_support = vf_cb->mac_cb->if_support;
ae_handle->port_type = vf_cb->mac_cb->mac_type;
ae_handle->dport_id = port_idx;
return ae_handle;
vf_id_err:
@ -419,7 +420,10 @@ static int hns_ae_set_autoneg(struct hnae_handle *handle, u8 enable)
static void hns_ae_set_promisc_mode(struct hnae_handle *handle, u32 en)
{
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
hns_dsaf_set_promisc_mode(hns_ae_get_dsaf_dev(handle->dev), en);
hns_mac_set_promisc(mac_cb, (u8)!!en);
}
static int hns_ae_get_autoneg(struct hnae_handle *handle)
@ -787,7 +791,8 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 *indir, u8 *key,
memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);
/* update the current hash->queue mappings from the shadow RSS table */
memcpy(indir, ppe_cb->rss_indir_table, HNS_PPEV2_RSS_IND_TBL_SIZE);
memcpy(indir, ppe_cb->rss_indir_table,
HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
return 0;
}
@ -799,10 +804,11 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const u32 *indir,
/* set the RSS Hash Key if specififed by the user */
if (key)
hns_ppe_set_rss_key(ppe_cb, (int *)key);
hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
/* update the shadow RSS table with user specified qids */
memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
memcpy(ppe_cb->rss_indir_table, indir,
HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
/* now update the hardware */
hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);

View file

@ -290,6 +290,24 @@ static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
return 0;
}
static void hns_gmac_set_uc_match(void *mac_drv, u16 en)
{
struct mac_driver *drv = mac_drv;
dsaf_set_dev_bit(drv, GMAC_REC_FILT_CONTROL_REG,
GMAC_UC_MATCH_EN_B, !en);
dsaf_set_dev_bit(drv, GMAC_STATION_ADDR_HIGH_2_REG,
GMAC_ADDR_EN_B, !en);
}
static void hns_gmac_set_promisc(void *mac_drv, u8 en)
{
struct mac_driver *drv = mac_drv;
if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
hns_gmac_set_uc_match(mac_drv, en);
}
static void hns_gmac_init(void *mac_drv)
{
u32 port;
@ -305,6 +323,8 @@ static void hns_gmac_init(void *mac_drv)
mdelay(10);
hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX);
hns_gmac_tx_loop_pkt_dis(mac_drv);
if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
hns_gmac_set_uc_match(mac_drv, 0);
}
void hns_gmac_update_stats(void *mac_drv)
@ -402,14 +422,17 @@ static void hns_gmac_set_mac_addr(void *mac_drv, char *mac_addr)
{
struct mac_driver *drv = (struct mac_driver *)mac_drv;
if (drv->mac_id >= DSAF_SERVICE_NW_NUM) {
u32 high_val = mac_addr[1] | (mac_addr[0] << 8);
u32 high_val = mac_addr[1] | (mac_addr[0] << 8);
u32 low_val = mac_addr[5] | (mac_addr[4] << 8)
| (mac_addr[3] << 16) | (mac_addr[2] << 24);
dsaf_write_dev(drv, GMAC_STATION_ADDR_LOW_2_REG, low_val);
dsaf_write_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG, high_val);
}
u32 low_val = mac_addr[5] | (mac_addr[4] << 8)
| (mac_addr[3] << 16) | (mac_addr[2] << 24);
u32 val = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG);
u32 sta_addr_en = dsaf_get_bit(val, GMAC_ADDR_EN_B);
dsaf_write_dev(drv, GMAC_STATION_ADDR_LOW_2_REG, low_val);
dsaf_write_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG,
high_val | (sta_addr_en << GMAC_ADDR_EN_B));
}
static int hns_gmac_config_loopback(void *mac_drv, enum hnae_loop loop_mode,
@ -699,6 +722,7 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
mac_drv->get_sset_count = hns_gmac_get_sset_count;
mac_drv->get_strings = hns_gmac_get_strings;
mac_drv->update_stats = hns_gmac_update_stats;
mac_drv->set_promiscuous = hns_gmac_set_promisc;
return (void *)mac_drv;
}

View file

@ -467,8 +467,13 @@ int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu)
struct mac_driver *drv = hns_mac_get_drv(mac_cb);
u32 buf_size = mac_cb->dsaf_dev->buf_size;
u32 new_frm = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
u32 max_frm = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver) ?
MAC_MAX_MTU : MAC_MAX_MTU_V2;
if ((new_mtu < MAC_MIN_MTU) || (new_frm > MAC_MAX_MTU) ||
if (mac_cb->mac_type == HNAE_PORT_DEBUG)
max_frm = MAC_MAX_MTU_DBG;
if ((new_mtu < MAC_MIN_MTU) || (new_frm > max_frm) ||
(new_frm > HNS_RCB_RING_MAX_BD_PER_PKT * buf_size))
return -EINVAL;
@ -861,6 +866,14 @@ int hns_mac_get_sset_count(struct hns_mac_cb *mac_cb, int stringset)
return mac_ctrl_drv->get_sset_count(stringset);
}
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);
if (mac_ctrl_drv->set_promiscuous)
mac_ctrl_drv->set_promiscuous(mac_ctrl_drv, en);
}
int hns_mac_get_regs_count(struct hns_mac_cb *mac_cb)
{
struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);

View file

@ -26,7 +26,9 @@ struct dsaf_device;
#define MAC_DEFAULT_MTU (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + ETH_DATA_LEN)
#define MAC_MAX_MTU 9600
#define MAC_MAX_MTU_V2 9728
#define MAC_MIN_MTU 68
#define MAC_MAX_MTU_DBG MAC_DEFAULT_MTU
#define MAC_DEFAULT_PAUSE_TIME 0xff
@ -365,7 +367,7 @@ struct mac_driver {
/*config rx pause enable*/
void (*set_rx_ignore_pause_frames)(void *mac_drv, u32 enable);
/* config rx mode for promiscuous*/
int (*set_promiscuous)(void *mac_drv, u8 enable);
void (*set_promiscuous)(void *mac_drv, u8 enable);
/* get mac id */
void (*mac_get_id)(void *mac_drv, u8 *mac_id);
void (*mac_pausefrm_cfg)(void *mac_drv, u32 rx_en, u32 tx_en);
@ -453,4 +455,6 @@ int hns_mac_get_regs_count(struct hns_mac_cb *mac_cb);
void hns_set_led_opt(struct hns_mac_cb *mac_cb);
int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
enum hnae_led_state status);
void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en);
#endif /* _HNS_DSAF_MAC_H */

View file

@ -748,8 +748,9 @@ static void hns_dsaf_tbl_stat_en(struct dsaf_device *dsaf_dev)
*/
static void hns_dsaf_rocee_bp_en(struct dsaf_device *dsaf_dev)
{
dsaf_set_dev_bit(dsaf_dev, DSAF_XGE_CTRL_SIG_CFG_0_REG,
DSAF_FC_XGE_TX_PAUSE_S, 1);
if (AE_IS_VER1(dsaf_dev->dsaf_ver))
dsaf_set_dev_bit(dsaf_dev, DSAF_XGE_CTRL_SIG_CFG_0_REG,
DSAF_FC_XGE_TX_PAUSE_S, 1);
}
/* set msk for dsaf exception irq*/

View file

@ -27,7 +27,7 @@ void hns_ppe_set_tso_enable(struct hns_ppe_cb *ppe_cb, u32 value)
void hns_ppe_set_rss_key(struct hns_ppe_cb *ppe_cb,
const u32 rss_key[HNS_PPEV2_RSS_KEY_NUM])
{
int key_item = 0;
u32 key_item;
for (key_item = 0; key_item < HNS_PPEV2_RSS_KEY_NUM; key_item++)
dsaf_write_dev(ppe_cb, PPEV2_RSS_KEY_REG + key_item * 0x4,
@ -343,6 +343,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
hns_ppe_set_vlan_strip(ppe_cb, 0);
dsaf_write_dev(ppe_cb, PPE_CFG_MAX_FRAME_LEN_REG,
HNS_PPEV2_MAX_FRAME_LEN);
/* set default RSS key in h/w */
hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);

View file

@ -30,6 +30,8 @@
#define HNS_PPEV2_RSS_KEY_SIZE 40 /* in bytes or 320 bits */
#define HNS_PPEV2_RSS_KEY_NUM (HNS_PPEV2_RSS_KEY_SIZE / sizeof(u32))
#define HNS_PPEV2_MAX_FRAME_LEN 0X980
enum ppe_qid_mode {
PPE_QID_MODE0 = 0, /* fixed queue id mode */
PPE_QID_MODE1, /* switch:128VM non switch:6Port/4VM/4TC */

View file

@ -922,6 +922,8 @@
#define GMAC_LP_REG_CF2MI_LP_EN_B 2
#define GMAC_MODE_CHANGE_EB_B 0
#define GMAC_UC_MATCH_EN_B 0
#define GMAC_ADDR_EN_B 16
#define GMAC_RECV_CTRL_STRIP_PAD_EN_B 3
#define GMAC_RECV_CTRL_RUNT_PKT_EN_B 4

View file

@ -48,7 +48,6 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct sk_buff *skb;
int skb_tmp_len;
__be16 protocol;
u8 bn_pid = 0;
u8 rrcfv = 0;
@ -66,10 +65,14 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
desc->addr = cpu_to_le64(dma);
desc->tx.send_size = cpu_to_le16((u16)size);
/*config bd buffer end */
/* config bd buffer end */
hnae_set_bit(rrcfv, HNSV2_TXD_VLD_B, 1);
hnae_set_field(bn_pid, HNSV2_TXD_BUFNUM_M, 0, buf_num - 1);
/* fill port_id in the tx bd for sending management pkts */
hnae_set_field(bn_pid, HNSV2_TXD_PORTID_M,
HNSV2_TXD_PORTID_S, ring->q->handle->dport_id);
if (type == DESC_TYPE_SKB) {
skb = (struct sk_buff *)priv;
@ -90,13 +93,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
hnae_set_bit(rrcfv, HNSV2_TXD_L4CS_B, 1);
/* check for tcp/udp header */
if (iphdr->protocol == IPPROTO_TCP) {
if (iphdr->protocol == IPPROTO_TCP &&
skb_is_gso(skb)) {
hnae_set_bit(tvsvsn,
HNSV2_TXD_TSE_B, 1);
skb_tmp_len = SKB_TMP_LEN(skb);
l4_len = tcp_hdrlen(skb);
mss = mtu - skb_tmp_len - ETH_FCS_LEN;
paylen = skb->len - skb_tmp_len;
mss = skb_shinfo(skb)->gso_size;
paylen = skb->len - SKB_TMP_LEN(skb);
}
} else if (skb->protocol == htons(ETH_P_IPV6)) {
hnae_set_bit(tvsvsn, HNSV2_TXD_IPV6_B, 1);
@ -104,13 +107,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
hnae_set_bit(rrcfv, HNSV2_TXD_L4CS_B, 1);
/* check for tcp/udp header */
if (ipv6hdr->nexthdr == IPPROTO_TCP) {
if (ipv6hdr->nexthdr == IPPROTO_TCP &&
skb_is_gso(skb) && skb_is_gso_v6(skb)) {
hnae_set_bit(tvsvsn,
HNSV2_TXD_TSE_B, 1);
skb_tmp_len = SKB_TMP_LEN(skb);
l4_len = tcp_hdrlen(skb);
mss = mtu - skb_tmp_len - ETH_FCS_LEN;
paylen = skb->len - skb_tmp_len;
mss = skb_shinfo(skb)->gso_size;
paylen = skb->len - SKB_TMP_LEN(skb);
}
}
desc->tx.ip_offset = ip_offset;
@ -564,6 +567,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
struct sk_buff *skb;
struct hnae_desc *desc;
struct hnae_desc_cb *desc_cb;
struct ethhdr *eh;
unsigned char *va;
int bnum, length, i;
int pull_len;
@ -670,6 +674,14 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
return -EFAULT;
}
/* filter out multicast pkt with the same src mac as this port */
eh = eth_hdr(skb);
if (unlikely(is_multicast_ether_addr(eh->h_dest) &&
ether_addr_equal(ndev->dev_addr, eh->h_source))) {
dev_kfree_skb_any(skb);
return -EFAULT;
}
ring->stats.rx_pkts++;
ring->stats.rx_bytes += skb->len;

View file

@ -1173,18 +1173,15 @@ hns_get_rss_key_size(struct net_device *netdev)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
u32 ret;
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
"RSS feature is not supported on this hardware\n");
return -EOPNOTSUPP;
return 0;
}
ops = priv->ae_handle->dev->ops;
ret = ops->get_rss_key_size(priv->ae_handle);
return ret;
return ops->get_rss_key_size(priv->ae_handle);
}
static u32
@ -1192,18 +1189,15 @@ hns_get_rss_indir_size(struct net_device *netdev)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
u32 ret;
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
"RSS feature is not supported on this hardware\n");
return -EOPNOTSUPP;
return 0;
}
ops = priv->ae_handle->dev->ops;
ret = ops->get_rss_indir_size(priv->ae_handle);
return ret;
return ops->get_rss_indir_size(priv->ae_handle);
}
static int
@ -1211,7 +1205,6 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
int ret;
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
@ -1224,9 +1217,7 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
if (!indir)
return 0;
ret = ops->get_rss(priv->ae_handle, indir, key, hfunc);
return 0;
return ops->get_rss(priv->ae_handle, indir, key, hfunc);
}
static int
@ -1235,7 +1226,6 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key,
{
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
int ret;
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
@ -1252,7 +1242,22 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key,
if (!indir)
return 0;
ret = ops->set_rss(priv->ae_handle, indir, key, hfunc);
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
}
static int hns_get_rxnfc(struct net_device *netdev,
struct ethtool_rxnfc *cmd,
u32 *rule_locs)
{
struct hns_nic_priv *priv = netdev_priv(netdev);
switch (cmd->cmd) {
case ETHTOOL_GRXRINGS:
cmd->data = priv->ae_handle->q_num;
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
@ -1280,6 +1285,7 @@ static struct ethtool_ops hns_ethtool_ops = {
.get_rxfh_indir_size = hns_get_rss_indir_size,
.get_rxfh = hns_get_rss,
.set_rxfh = hns_set_rss,
.get_rxnfc = hns_get_rxnfc,
};
void hns_ethtool_set_ops(struct net_device *ndev)