mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
Merge branch 'code-optimizations-and-bugfixes-for-HNS3-driver'
Huazhong Tan says: ==================== code optimizations & bugfixes for HNS3 driver This patchset includes bugfixes and code optimizations for the HNS3 ethernet controller driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
caf337bdef
@ -21,6 +21,7 @@ enum HCLGE_MBX_OPCODE {
|
||||
HCLGE_MBX_SET_MACVLAN, /* (VF -> PF) set unicast filter */
|
||||
HCLGE_MBX_API_NEGOTIATE, /* (VF -> PF) negotiate API version */
|
||||
HCLGE_MBX_GET_QINFO, /* (VF -> PF) get queue config */
|
||||
HCLGE_MBX_GET_QDEPTH, /* (VF -> PF) get queue depth */
|
||||
HCLGE_MBX_GET_TCINFO, /* (VF -> PF) get TC config */
|
||||
HCLGE_MBX_GET_RETA, /* (VF -> PF) get RETA */
|
||||
HCLGE_MBX_GET_RSS_KEY, /* (VF -> PF) get RSS key */
|
||||
|
@ -87,7 +87,8 @@ struct hnae3_queue {
|
||||
struct hnae3_handle *handle;
|
||||
int tqp_index; /* index in a handle */
|
||||
u32 buf_size; /* size for hnae_desc->addr, preset by AE */
|
||||
u16 desc_num; /* total number of desc */
|
||||
u16 tx_desc_num;/* total number of tx desc */
|
||||
u16 rx_desc_num;/* total number of rx desc */
|
||||
};
|
||||
|
||||
/*hnae3 loop mode*/
|
||||
@ -505,7 +506,8 @@ struct hnae3_knic_private_info {
|
||||
u16 rss_size; /* Allocated RSS queues */
|
||||
u16 req_rss_size;
|
||||
u16 rx_buf_len;
|
||||
u16 num_desc;
|
||||
u16 num_tx_desc;
|
||||
u16 num_rx_desc;
|
||||
|
||||
u8 num_tc; /* Total number of enabled TCs */
|
||||
u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */
|
||||
@ -537,7 +539,9 @@ struct hnae3_roce_private_info {
|
||||
struct hnae3_unic_private_info {
|
||||
struct net_device *netdev;
|
||||
u16 rx_buf_len;
|
||||
u16 num_desc;
|
||||
u16 num_tx_desc;
|
||||
u16 num_rx_desc;
|
||||
|
||||
u16 num_tqps; /* total number of tqps in this handle */
|
||||
struct hnae3_queue **tqp; /* array base of all TQPs of this instance */
|
||||
};
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "hnae3.h"
|
||||
#include "hns3_enet.h"
|
||||
|
||||
#define hns3_set_field(origin, shift, val) ((origin) |= ((val) << (shift)))
|
||||
|
||||
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);
|
||||
@ -378,6 +380,29 @@ out_start_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hns3_config_xps(struct hns3_nic_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->vector_num; i++) {
|
||||
struct hns3_enet_tqp_vector *tqp_vector = &priv->tqp_vector[i];
|
||||
struct hns3_enet_ring *ring = tqp_vector->tx_group.ring;
|
||||
|
||||
while (ring) {
|
||||
int ret;
|
||||
|
||||
ret = netif_set_xps_queue(priv->netdev,
|
||||
&tqp_vector->affinity_mask,
|
||||
ring->tqp->tqp_index);
|
||||
if (ret)
|
||||
netdev_warn(priv->netdev,
|
||||
"set xps queue failed: %d", ret);
|
||||
|
||||
ring = ring->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int hns3_nic_net_open(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
@ -410,6 +435,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
|
||||
if (h->ae_algo->ops->set_timer_task)
|
||||
h->ae_algo->ops->set_timer_task(priv->ae_handle, true);
|
||||
|
||||
hns3_config_xps(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -595,7 +621,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
|
||||
return 0;
|
||||
|
||||
ret = skb_cow_head(skb, 0);
|
||||
if (ret)
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
l3.hdr = skb_network_header(skb);
|
||||
@ -634,7 +660,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
|
||||
|
||||
/* normal or tunnel packet*/
|
||||
l4_offset = l4.hdr - skb->data;
|
||||
hdr_len = (l4.tcp->doff * 4) + l4_offset;
|
||||
hdr_len = (l4.tcp->doff << 2) + l4_offset;
|
||||
|
||||
/* remove payload length from inner pseudo checksum when tso*/
|
||||
l4_paylen = skb->len - l4_offset;
|
||||
@ -643,8 +669,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
|
||||
|
||||
/* find the txbd field values */
|
||||
*paylen = skb->len - hdr_len;
|
||||
hnae3_set_bit(*type_cs_vlan_tso,
|
||||
HNS3_TXD_TSO_B, 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_TSO_B, 1);
|
||||
|
||||
/* get MSS for TSO */
|
||||
*mss = skb_shinfo(skb)->gso_size;
|
||||
@ -723,21 +748,19 @@ static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto,
|
||||
|
||||
/* compute L2 header size for normal packet, defined in 2 Bytes */
|
||||
l2_len = l3.hdr - skb->data;
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L2LEN_M,
|
||||
HNS3_TXD_L2LEN_S, l2_len >> 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L2LEN_S, l2_len >> 1);
|
||||
|
||||
/* tunnel packet*/
|
||||
if (skb->encapsulation) {
|
||||
/* compute OL2 header size, defined in 2 Bytes */
|
||||
ol2_len = l2_len;
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_L2LEN_M,
|
||||
HNS3_TXD_L2LEN_S, ol2_len >> 1);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_L2LEN_S, ol2_len >> 1);
|
||||
|
||||
/* compute OL3 header size, defined in 4 Bytes */
|
||||
ol3_len = l4.hdr - l3.hdr;
|
||||
hnae3_set_field(*ol_type_vlan_len_msec, HNS3_TXD_L3LEN_M,
|
||||
HNS3_TXD_L3LEN_S, ol3_len >> 2);
|
||||
hns3_set_field(*ol_type_vlan_len_msec, HNS3_TXD_L3LEN_S,
|
||||
ol3_len >> 2);
|
||||
|
||||
/* MAC in UDP, MAC in GRE (0x6558)*/
|
||||
if ((ol4_proto == IPPROTO_UDP) || (ol4_proto == IPPROTO_GRE)) {
|
||||
@ -746,17 +769,16 @@ static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto,
|
||||
|
||||
/* compute OL4 header size, defined in 4 Bytes. */
|
||||
ol4_len = l2_hdr - l4.hdr;
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_L4LEN_M, HNS3_TXD_L4LEN_S,
|
||||
ol4_len >> 2);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_L4LEN_S, ol4_len >> 2);
|
||||
|
||||
/* switch IP header ptr from outer to inner header */
|
||||
l3.hdr = skb_inner_network_header(skb);
|
||||
|
||||
/* compute inner l2 header size, defined in 2 Bytes. */
|
||||
l2_len = l3.hdr - l2_hdr;
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L2LEN_M,
|
||||
HNS3_TXD_L2LEN_S, l2_len >> 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L2LEN_S,
|
||||
l2_len >> 1);
|
||||
} else {
|
||||
/* skb packet types not supported by hardware,
|
||||
* txbd len fild doesn't be filled.
|
||||
@ -772,24 +794,21 @@ static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto,
|
||||
|
||||
/* compute inner(/normal) L3 header size, defined in 4 Bytes */
|
||||
l3_len = l4.hdr - l3.hdr;
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3LEN_M,
|
||||
HNS3_TXD_L3LEN_S, l3_len >> 2);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3LEN_S, l3_len >> 2);
|
||||
|
||||
/* compute inner(/normal) L4 header size, defined in 4 Bytes */
|
||||
switch (l4_proto) {
|
||||
case IPPROTO_TCP:
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_M,
|
||||
HNS3_TXD_L4LEN_S, l4.tcp->doff);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_S,
|
||||
l4.tcp->doff);
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_M,
|
||||
HNS3_TXD_L4LEN_S,
|
||||
(sizeof(struct sctphdr) >> 2));
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_S,
|
||||
(sizeof(struct sctphdr) >> 2));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_M,
|
||||
HNS3_TXD_L4LEN_S,
|
||||
(sizeof(struct udphdr) >> 2));
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4LEN_S,
|
||||
(sizeof(struct udphdr) >> 2));
|
||||
break;
|
||||
default:
|
||||
/* skb packet types not supported by hardware,
|
||||
@ -834,34 +853,30 @@ static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto,
|
||||
/* define outer network header type.*/
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
if (skb_is_gso(skb))
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_OL3T_M,
|
||||
HNS3_TXD_OL3T_S,
|
||||
HNS3_OL3T_IPV4_CSUM);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_OL3T_S,
|
||||
HNS3_OL3T_IPV4_CSUM);
|
||||
else
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_OL3T_M,
|
||||
HNS3_TXD_OL3T_S,
|
||||
HNS3_OL3T_IPV4_NO_CSUM);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_OL3T_S,
|
||||
HNS3_OL3T_IPV4_NO_CSUM);
|
||||
|
||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
hnae3_set_field(*ol_type_vlan_len_msec, HNS3_TXD_OL3T_M,
|
||||
HNS3_TXD_OL3T_S, HNS3_OL3T_IPV6);
|
||||
hns3_set_field(*ol_type_vlan_len_msec, HNS3_TXD_OL3T_S,
|
||||
HNS3_OL3T_IPV6);
|
||||
}
|
||||
|
||||
/* define tunnel type(OL4).*/
|
||||
switch (l4_proto) {
|
||||
case IPPROTO_UDP:
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_TUNTYPE_M,
|
||||
HNS3_TXD_TUNTYPE_S,
|
||||
HNS3_TUN_MAC_IN_UDP);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_TUNTYPE_S,
|
||||
HNS3_TUN_MAC_IN_UDP);
|
||||
break;
|
||||
case IPPROTO_GRE:
|
||||
hnae3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_TUNTYPE_M,
|
||||
HNS3_TXD_TUNTYPE_S,
|
||||
HNS3_TUN_NVGRE);
|
||||
hns3_set_field(*ol_type_vlan_len_msec,
|
||||
HNS3_TXD_TUNTYPE_S,
|
||||
HNS3_TUN_NVGRE);
|
||||
break;
|
||||
default:
|
||||
/* drop the skb tunnel packet if hardware don't support,
|
||||
@ -882,43 +897,37 @@ static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto,
|
||||
}
|
||||
|
||||
if (l3.v4->version == 4) {
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3T_M,
|
||||
HNS3_TXD_L3T_S, HNS3_L3T_IPV4);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3T_S,
|
||||
HNS3_L3T_IPV4);
|
||||
|
||||
/* the stack computes the IP header already, the only time we
|
||||
* need the hardware to recompute it is in the case of TSO.
|
||||
*/
|
||||
if (skb_is_gso(skb))
|
||||
hnae3_set_bit(*type_cs_vlan_tso, HNS3_TXD_L3CS_B, 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3CS_B, 1);
|
||||
} else if (l3.v6->version == 6) {
|
||||
hnae3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3T_M,
|
||||
HNS3_TXD_L3T_S, HNS3_L3T_IPV6);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L3T_S,
|
||||
HNS3_L3T_IPV6);
|
||||
}
|
||||
|
||||
switch (l4_proto) {
|
||||
case IPPROTO_TCP:
|
||||
hnae3_set_bit(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hnae3_set_field(*type_cs_vlan_tso,
|
||||
HNS3_TXD_L4T_M,
|
||||
HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_TCP);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_TCP);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if (hns3_tunnel_csum_bug(skb))
|
||||
break;
|
||||
|
||||
hnae3_set_bit(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hnae3_set_field(*type_cs_vlan_tso,
|
||||
HNS3_TXD_L4T_M,
|
||||
HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_UDP);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_UDP);
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
hnae3_set_bit(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hnae3_set_field(*type_cs_vlan_tso,
|
||||
HNS3_TXD_L4T_M,
|
||||
HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_SCTP);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1);
|
||||
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4T_S,
|
||||
HNS3_L4T_SCTP);
|
||||
break;
|
||||
default:
|
||||
/* drop the skb tunnel packet if hardware don't support,
|
||||
@ -940,11 +949,8 @@ static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto,
|
||||
static void hns3_set_txbd_baseinfo(u16 *bdtp_fe_sc_vld_ra_ri, int frag_end)
|
||||
{
|
||||
/* Config bd buffer end */
|
||||
hnae3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_BDTYPE_M,
|
||||
HNS3_TXD_BDTYPE_S, 0);
|
||||
hnae3_set_bit(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, !!frag_end);
|
||||
hnae3_set_bit(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1);
|
||||
hnae3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_SC_M, HNS3_TXD_SC_S, 0);
|
||||
hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, !!frag_end);
|
||||
hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1);
|
||||
}
|
||||
|
||||
static int hns3_fill_desc_vtags(struct sk_buff *skb,
|
||||
@ -977,10 +983,10 @@ static int hns3_fill_desc_vtags(struct sk_buff *skb,
|
||||
* and use inner_vtag in one tag case.
|
||||
*/
|
||||
if (skb->protocol == htons(ETH_P_8021Q)) {
|
||||
hnae3_set_bit(*out_vlan_flag, HNS3_TXD_OVLAN_B, 1);
|
||||
hns3_set_field(*out_vlan_flag, HNS3_TXD_OVLAN_B, 1);
|
||||
*out_vtag = vlan_tag;
|
||||
} else {
|
||||
hnae3_set_bit(*inner_vlan_flag, HNS3_TXD_VLAN_B, 1);
|
||||
hns3_set_field(*inner_vlan_flag, HNS3_TXD_VLAN_B, 1);
|
||||
*inner_vtag = vlan_tag;
|
||||
}
|
||||
} else if (skb->protocol == htons(ETH_P_8021Q)) {
|
||||
@ -988,7 +994,7 @@ static int hns3_fill_desc_vtags(struct sk_buff *skb,
|
||||
int rc;
|
||||
|
||||
rc = skb_cow_head(skb, 0);
|
||||
if (rc < 0)
|
||||
if (unlikely(rc < 0))
|
||||
return rc;
|
||||
vhdr = (struct vlan_ethhdr *)skb->data;
|
||||
vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority & 0x7)
|
||||
@ -1005,26 +1011,21 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
|
||||
struct hns3_desc *desc = &ring->desc[ring->next_to_use];
|
||||
struct device *dev = ring_to_dev(ring);
|
||||
u32 ol_type_vlan_len_msec = 0;
|
||||
u16 bdtp_fe_sc_vld_ra_ri = 0;
|
||||
struct skb_frag_struct *frag;
|
||||
unsigned int frag_buf_num;
|
||||
u32 type_cs_vlan_tso = 0;
|
||||
struct sk_buff *skb;
|
||||
u16 inner_vtag = 0;
|
||||
u16 out_vtag = 0;
|
||||
unsigned int k;
|
||||
int sizeoflast;
|
||||
u32 paylen = 0;
|
||||
int k, sizeoflast;
|
||||
dma_addr_t dma;
|
||||
u16 mss = 0;
|
||||
u8 ol4_proto;
|
||||
u8 il4_proto;
|
||||
int ret;
|
||||
|
||||
if (type == DESC_TYPE_SKB) {
|
||||
skb = (struct sk_buff *)priv;
|
||||
paylen = skb->len;
|
||||
struct sk_buff *skb = (struct sk_buff *)priv;
|
||||
u32 ol_type_vlan_len_msec = 0;
|
||||
u32 type_cs_vlan_tso = 0;
|
||||
u32 paylen = skb->len;
|
||||
u16 inner_vtag = 0;
|
||||
u16 out_vtag = 0;
|
||||
u16 mss = 0;
|
||||
int ret;
|
||||
|
||||
ret = hns3_fill_desc_vtags(skb, ring, &type_cs_vlan_tso,
|
||||
&ol_type_vlan_len_msec,
|
||||
@ -1033,10 +1034,12 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
return ret;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
u8 ol4_proto, il4_proto;
|
||||
|
||||
skb_reset_mac_len(skb);
|
||||
|
||||
ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto);
|
||||
if (ret)
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
hns3_set_l2l3l4_len(skb, ol4_proto, il4_proto,
|
||||
&type_cs_vlan_tso,
|
||||
@ -1044,12 +1047,12 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
ret = hns3_set_l3l4_type_csum(skb, ol4_proto, il4_proto,
|
||||
&type_cs_vlan_tso,
|
||||
&ol_type_vlan_len_msec);
|
||||
if (ret)
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
ret = hns3_set_tso(skb, &paylen, &mss,
|
||||
&type_cs_vlan_tso);
|
||||
if (ret)
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1069,15 +1072,15 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
if (dma_mapping_error(ring->dev, dma)) {
|
||||
if (unlikely(dma_mapping_error(ring->dev, dma))) {
|
||||
ring->stats.sw_err_cnt++;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
desc_cb->length = size;
|
||||
|
||||
frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
|
||||
sizeoflast = size % HNS3_MAX_BD_SIZE;
|
||||
frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET;
|
||||
sizeoflast = size & HNS3_TX_LAST_SIZE_M;
|
||||
sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;
|
||||
|
||||
/* When frag size is bigger than hardware limit, split this frag */
|
||||
@ -1121,22 +1124,23 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
|
||||
int i;
|
||||
|
||||
size = skb_headlen(skb);
|
||||
buf_num = (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
|
||||
buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET;
|
||||
|
||||
frag_num = skb_shinfo(skb)->nr_frags;
|
||||
for (i = 0; i < frag_num; i++) {
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
size = skb_frag_size(frag);
|
||||
bdnum_for_frag =
|
||||
(size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
|
||||
if (bdnum_for_frag > HNS3_MAX_BD_PER_FRAG)
|
||||
bdnum_for_frag = (size + HNS3_MAX_BD_SIZE - 1) >>
|
||||
HNS3_MAX_BD_SIZE_OFFSET;
|
||||
if (unlikely(bdnum_for_frag > HNS3_MAX_BD_PER_FRAG))
|
||||
return -ENOMEM;
|
||||
|
||||
buf_num += bdnum_for_frag;
|
||||
}
|
||||
|
||||
if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
|
||||
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
|
||||
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) >>
|
||||
HNS3_MAX_BD_SIZE_OFFSET;
|
||||
if (ring_space(ring) < buf_num)
|
||||
return -EBUSY;
|
||||
/* manual split the send packet */
|
||||
@ -1257,9 +1261,9 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
|
||||
next_to_use_head = ring->next_to_use;
|
||||
|
||||
ret = priv->ops.fill_desc(ring, skb, size, seg_num == 1 ? 1 : 0,
|
||||
DESC_TYPE_SKB);
|
||||
if (ret)
|
||||
ret = hns3_fill_desc(ring, skb, size, seg_num == 1 ? 1 : 0,
|
||||
DESC_TYPE_SKB);
|
||||
if (unlikely(ret))
|
||||
goto head_fill_err;
|
||||
|
||||
next_to_use_frag = ring->next_to_use;
|
||||
@ -1268,11 +1272,11 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
frag = &skb_shinfo(skb)->frags[i - 1];
|
||||
size = skb_frag_size(frag);
|
||||
|
||||
ret = priv->ops.fill_desc(ring, frag, size,
|
||||
seg_num - 1 == i ? 1 : 0,
|
||||
DESC_TYPE_PAGE);
|
||||
ret = hns3_fill_desc(ring, frag, size,
|
||||
seg_num - 1 == i ? 1 : 0,
|
||||
DESC_TYPE_PAGE);
|
||||
|
||||
if (ret)
|
||||
if (unlikely(ret))
|
||||
goto frag_fill_err;
|
||||
}
|
||||
|
||||
@ -2314,13 +2318,12 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
/* check if hardware has done checksum */
|
||||
if (!hnae3_get_bit(bd_base_info, HNS3_RXD_L3L4P_B))
|
||||
if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
|
||||
return;
|
||||
|
||||
if (unlikely(hnae3_get_bit(l234info, HNS3_RXD_L3E_B) ||
|
||||
hnae3_get_bit(l234info, HNS3_RXD_L4E_B) ||
|
||||
hnae3_get_bit(l234info, HNS3_RXD_OL3E_B) ||
|
||||
hnae3_get_bit(l234info, HNS3_RXD_OL4E_B))) {
|
||||
if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) ||
|
||||
BIT(HNS3_RXD_OL3E_B) ||
|
||||
BIT(HNS3_RXD_OL4E_B)))) {
|
||||
u64_stats_update_begin(&ring->syncp);
|
||||
ring->stats.l3l4_csum_err++;
|
||||
u64_stats_update_end(&ring->syncp);
|
||||
@ -2328,11 +2331,6 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
|
||||
return;
|
||||
}
|
||||
|
||||
l3_type = hnae3_get_field(l234info, HNS3_RXD_L3ID_M,
|
||||
HNS3_RXD_L3ID_S);
|
||||
l4_type = hnae3_get_field(l234info, HNS3_RXD_L4ID_M,
|
||||
HNS3_RXD_L4ID_S);
|
||||
|
||||
ol4_type = hnae3_get_field(l234info, HNS3_RXD_OL4ID_M,
|
||||
HNS3_RXD_OL4ID_S);
|
||||
switch (ol4_type) {
|
||||
@ -2341,6 +2339,11 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
|
||||
skb->csum_level = 1;
|
||||
/* fall through */
|
||||
case HNS3_OL4_TYPE_NO_TUN:
|
||||
l3_type = hnae3_get_field(l234info, HNS3_RXD_L3ID_M,
|
||||
HNS3_RXD_L3ID_S);
|
||||
l4_type = hnae3_get_field(l234info, HNS3_RXD_L4ID_M,
|
||||
HNS3_RXD_L4ID_S);
|
||||
|
||||
/* Can checksum ipv4 or ipv6 + UDP/TCP/SCTP packets */
|
||||
if ((l3_type == HNS3_L3_TYPE_IPV4 ||
|
||||
l3_type == HNS3_L3_TYPE_IPV6) &&
|
||||
@ -2465,11 +2468,11 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc,
|
||||
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
|
||||
}
|
||||
|
||||
while (!hnae3_get_bit(bd_base_info, HNS3_RXD_FE_B)) {
|
||||
while (!(bd_base_info & BIT(HNS3_RXD_FE_B))) {
|
||||
desc = &ring->desc[ring->next_to_clean];
|
||||
desc_cb = &ring->desc_cb[ring->next_to_clean];
|
||||
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
|
||||
if (!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B))
|
||||
if (!(bd_base_info & BIT(HNS3_RXD_VLD_B)))
|
||||
return -ENXIO;
|
||||
|
||||
if (unlikely(ring->frag_num >= MAX_SKB_FRAGS)) {
|
||||
@ -2583,7 +2586,7 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
|
||||
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
|
||||
|
||||
/* Check valid BD */
|
||||
if (unlikely(!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B)))
|
||||
if (unlikely(!(bd_base_info & BIT(HNS3_RXD_VLD_B))))
|
||||
return -ENXIO;
|
||||
|
||||
if (!skb)
|
||||
@ -2646,7 +2649,7 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
|
||||
vlan_tag);
|
||||
}
|
||||
|
||||
if (unlikely(!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B))) {
|
||||
if (unlikely(!(bd_base_info & BIT(HNS3_RXD_VLD_B)))) {
|
||||
u64_stats_update_begin(&ring->syncp);
|
||||
ring->stats.non_vld_descs++;
|
||||
u64_stats_update_end(&ring->syncp);
|
||||
@ -2656,23 +2659,19 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
|
||||
}
|
||||
|
||||
if (unlikely((!desc->rx.pkt_len) ||
|
||||
hnae3_get_bit(l234info, HNS3_RXD_TRUNCAT_B))) {
|
||||
(l234info & (BIT(HNS3_RXD_TRUNCAT_B) |
|
||||
BIT(HNS3_RXD_L2E_B))))) {
|
||||
u64_stats_update_begin(&ring->syncp);
|
||||
ring->stats.err_pkt_len++;
|
||||
if (l234info & BIT(HNS3_RXD_L2E_B))
|
||||
ring->stats.l2_err++;
|
||||
else
|
||||
ring->stats.err_pkt_len++;
|
||||
u64_stats_update_end(&ring->syncp);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (unlikely(hnae3_get_bit(l234info, HNS3_RXD_L2E_B))) {
|
||||
u64_stats_update_begin(&ring->syncp);
|
||||
ring->stats.l2_err++;
|
||||
u64_stats_update_end(&ring->syncp);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
l2_frame_type = hnae3_get_field(l234info, HNS3_RXD_DMAC_M,
|
||||
HNS3_RXD_DMAC_S);
|
||||
@ -3232,19 +3231,21 @@ static int hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv,
|
||||
{
|
||||
struct hns3_nic_ring_data *ring_data = priv->ring_data;
|
||||
int queue_num = priv->ae_handle->kinfo.num_tqps;
|
||||
int desc_num = priv->ae_handle->kinfo.num_desc;
|
||||
struct pci_dev *pdev = priv->ae_handle->pdev;
|
||||
struct hns3_enet_ring *ring;
|
||||
int desc_num;
|
||||
|
||||
ring = devm_kzalloc(&pdev->dev, sizeof(*ring), GFP_KERNEL);
|
||||
if (!ring)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ring_type == HNAE3_RING_TYPE_TX) {
|
||||
desc_num = priv->ae_handle->kinfo.num_tx_desc;
|
||||
ring_data[q->tqp_index].ring = ring;
|
||||
ring_data[q->tqp_index].queue_index = q->tqp_index;
|
||||
ring->io_base = (u8 __iomem *)q->io_base + HNS3_TX_REG_OFFSET;
|
||||
} else {
|
||||
desc_num = priv->ae_handle->kinfo.num_rx_desc;
|
||||
ring_data[q->tqp_index + queue_num].ring = ring;
|
||||
ring_data[q->tqp_index + queue_num].queue_index = q->tqp_index;
|
||||
ring->io_base = q->io_base;
|
||||
@ -3557,7 +3558,6 @@ static void hns3_nic_set_priv_ops(struct net_device *netdev)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->ops.fill_desc = hns3_fill_desc;
|
||||
if ((netdev->features & NETIF_F_TSO) ||
|
||||
(netdev->features & NETIF_F_TSO6))
|
||||
priv->ops.maybe_stop_tx = hns3_nic_maybe_stop_tso;
|
||||
@ -3656,7 +3656,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
|
||||
ret = hns3_client_start(handle);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
|
||||
goto out_reg_netdev_fail;
|
||||
goto out_client_start;
|
||||
}
|
||||
|
||||
hns3_dcbnl_setup(handle);
|
||||
@ -3670,6 +3670,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
|
||||
|
||||
return ret;
|
||||
|
||||
out_client_start:
|
||||
unregister_netdev(netdev);
|
||||
out_reg_netdev_fail:
|
||||
hns3_uninit_phy(netdev);
|
||||
out_init_phy:
|
||||
|
@ -74,7 +74,7 @@ enum hns3_nic_state {
|
||||
#define HNS3_RING_NAME_LEN 16
|
||||
#define HNS3_BUFFER_SIZE_2048 2048
|
||||
#define HNS3_RING_MAX_PENDING 32768
|
||||
#define HNS3_RING_MIN_PENDING 8
|
||||
#define HNS3_RING_MIN_PENDING 24
|
||||
#define HNS3_RING_BD_MULTIPLE 8
|
||||
/* max frame size of mac */
|
||||
#define HNS3_MAC_MAX_FRAME 9728
|
||||
@ -184,6 +184,8 @@ enum hns3_nic_state {
|
||||
#define HNS3_TXD_MSS_S 0
|
||||
#define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S)
|
||||
|
||||
#define HNS3_TX_LAST_SIZE_M 0xffff
|
||||
|
||||
#define HNS3_VECTOR_TX_IRQ BIT_ULL(0)
|
||||
#define HNS3_VECTOR_RX_IRQ BIT_ULL(1)
|
||||
|
||||
@ -191,6 +193,7 @@ enum hns3_nic_state {
|
||||
#define HNS3_VECTOR_INITED 1
|
||||
|
||||
#define HNS3_MAX_BD_SIZE 65535
|
||||
#define HNS3_MAX_BD_SIZE_OFFSET 16
|
||||
#define HNS3_MAX_BD_PER_FRAG 8
|
||||
#define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS
|
||||
|
||||
@ -441,11 +444,8 @@ struct hns3_nic_ring_data {
|
||||
};
|
||||
|
||||
struct hns3_nic_ops {
|
||||
int (*fill_desc)(struct hns3_enet_ring *ring, void *priv,
|
||||
int size, int frag_end, enum hns_desc_type type);
|
||||
int (*maybe_stop_tx)(struct sk_buff **out_skb,
|
||||
int *bnum, struct hns3_enet_ring *ring);
|
||||
void (*get_rxd_bnum)(u32 bnum_flag, int *out_bnum);
|
||||
};
|
||||
|
||||
enum hns3_flow_level_range {
|
||||
|
@ -748,15 +748,19 @@ static int hns3_get_rxnfc(struct net_device *netdev,
|
||||
}
|
||||
|
||||
static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
|
||||
u32 new_desc_num)
|
||||
u32 tx_desc_num, u32 rx_desc_num)
|
||||
{
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int i;
|
||||
|
||||
h->kinfo.num_desc = new_desc_num;
|
||||
h->kinfo.num_tx_desc = tx_desc_num;
|
||||
h->kinfo.num_rx_desc = rx_desc_num;
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps * 2; i++)
|
||||
priv->ring_data[i].ring->desc_num = new_desc_num;
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++) {
|
||||
priv->ring_data[i].ring->desc_num = tx_desc_num;
|
||||
priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num =
|
||||
rx_desc_num;
|
||||
}
|
||||
|
||||
return hns3_init_all_ring(priv);
|
||||
}
|
||||
@ -767,7 +771,9 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
bool if_running = netif_running(ndev);
|
||||
u32 old_desc_num, new_desc_num;
|
||||
u32 old_tx_desc_num, new_tx_desc_num;
|
||||
u32 old_rx_desc_num, new_rx_desc_num;
|
||||
int queue_num = h->kinfo.num_tqps;
|
||||
int ret;
|
||||
|
||||
if (hns3_nic_resetting(ndev))
|
||||
@ -776,32 +782,28 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
if (param->rx_mini_pending || param->rx_jumbo_pending)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->tx_pending != param->rx_pending) {
|
||||
netdev_err(ndev,
|
||||
"Descriptors of tx and rx must be equal");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param->tx_pending > HNS3_RING_MAX_PENDING ||
|
||||
param->tx_pending < HNS3_RING_MIN_PENDING) {
|
||||
netdev_err(ndev,
|
||||
"Descriptors requested (Tx/Rx: %d) out of range [%d-%d]\n",
|
||||
param->tx_pending, HNS3_RING_MIN_PENDING,
|
||||
HNS3_RING_MAX_PENDING);
|
||||
param->tx_pending < HNS3_RING_MIN_PENDING ||
|
||||
param->rx_pending > HNS3_RING_MAX_PENDING ||
|
||||
param->rx_pending < HNS3_RING_MIN_PENDING) {
|
||||
netdev_err(ndev, "Queue depth out of range [%d-%d]\n",
|
||||
HNS3_RING_MIN_PENDING, HNS3_RING_MAX_PENDING);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
new_desc_num = param->tx_pending;
|
||||
|
||||
/* Hardware requires that its descriptors must be multiple of eight */
|
||||
new_desc_num = ALIGN(new_desc_num, HNS3_RING_BD_MULTIPLE);
|
||||
old_desc_num = h->kinfo.num_desc;
|
||||
if (old_desc_num == new_desc_num)
|
||||
new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE);
|
||||
new_rx_desc_num = ALIGN(param->rx_pending, HNS3_RING_BD_MULTIPLE);
|
||||
old_tx_desc_num = priv->ring_data[0].ring->desc_num;
|
||||
old_rx_desc_num = priv->ring_data[queue_num].ring->desc_num;
|
||||
if (old_tx_desc_num == new_tx_desc_num &&
|
||||
old_rx_desc_num == new_rx_desc_num)
|
||||
return 0;
|
||||
|
||||
netdev_info(ndev,
|
||||
"Changing descriptor count from %d to %d.\n",
|
||||
old_desc_num, new_desc_num);
|
||||
"Changing Tx/Rx ring depth from %d/%d to %d/%d\n",
|
||||
old_tx_desc_num, old_rx_desc_num,
|
||||
new_tx_desc_num, new_rx_desc_num);
|
||||
|
||||
if (if_running)
|
||||
ndev->netdev_ops->ndo_stop(ndev);
|
||||
@ -810,9 +812,11 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hns3_change_all_ring_bd_num(priv, new_desc_num);
|
||||
ret = hns3_change_all_ring_bd_num(priv, new_tx_desc_num,
|
||||
new_rx_desc_num);
|
||||
if (ret) {
|
||||
ret = hns3_change_all_ring_bd_num(priv, old_desc_num);
|
||||
ret = hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
|
||||
old_rx_desc_num);
|
||||
if (ret) {
|
||||
netdev_err(ndev,
|
||||
"Revert to old bd num fail, ret=%d.\n", ret);
|
||||
|
@ -693,7 +693,9 @@ struct hclge_mac_vlan_remove_cmd {
|
||||
struct hclge_vlan_filter_ctrl_cmd {
|
||||
u8 vlan_type;
|
||||
u8 vlan_fe;
|
||||
u8 rsv[22];
|
||||
u8 rsv1[2];
|
||||
u8 vf_id;
|
||||
u8 rsv2[19];
|
||||
};
|
||||
|
||||
struct hclge_vlan_filter_pf_cfg_cmd {
|
||||
|
@ -1148,10 +1148,10 @@ static int hclge_log_rocee_ovf_error(struct hclge_dev *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
static enum hnae3_reset_type
|
||||
hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
{
|
||||
enum hnae3_reset_type reset_type = HNAE3_FUNC_RESET;
|
||||
struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
|
||||
enum hnae3_reset_type reset_type = HNAE3_NONE_RESET;
|
||||
struct device *dev = &hdev->pdev->dev;
|
||||
struct hclge_desc desc[2];
|
||||
unsigned int status;
|
||||
@ -1164,17 +1164,20 @@ static int hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to query ROCEE RAS INT SRC\n", ret);
|
||||
/* reset everything for now */
|
||||
HCLGE_SET_DEFAULT_RESET_REQUEST(HNAE3_GLOBAL_RESET);
|
||||
return ret;
|
||||
return HNAE3_GLOBAL_RESET;
|
||||
}
|
||||
|
||||
status = le32_to_cpu(desc[0].data[0]);
|
||||
|
||||
if (status & HCLGE_ROCEE_RERR_INT_MASK)
|
||||
if (status & HCLGE_ROCEE_RERR_INT_MASK) {
|
||||
dev_warn(dev, "ROCEE RAS AXI rresp error\n");
|
||||
reset_type = HNAE3_FUNC_RESET;
|
||||
}
|
||||
|
||||
if (status & HCLGE_ROCEE_BERR_INT_MASK)
|
||||
if (status & HCLGE_ROCEE_BERR_INT_MASK) {
|
||||
dev_warn(dev, "ROCEE RAS AXI bresp error\n");
|
||||
reset_type = HNAE3_FUNC_RESET;
|
||||
}
|
||||
|
||||
if (status & HCLGE_ROCEE_ECC_INT_MASK) {
|
||||
dev_warn(dev, "ROCEE RAS 2bit ECC error\n");
|
||||
@ -1186,9 +1189,9 @@ static int hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to process ovf error\n", ret);
|
||||
/* reset everything for now */
|
||||
HCLGE_SET_DEFAULT_RESET_REQUEST(HNAE3_GLOBAL_RESET);
|
||||
return ret;
|
||||
return HNAE3_GLOBAL_RESET;
|
||||
}
|
||||
reset_type = HNAE3_FUNC_RESET;
|
||||
}
|
||||
|
||||
/* clear error status */
|
||||
@ -1197,12 +1200,10 @@ static int hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to clear ROCEE RAS error\n", ret);
|
||||
/* reset everything for now */
|
||||
reset_type = HNAE3_GLOBAL_RESET;
|
||||
return HNAE3_GLOBAL_RESET;
|
||||
}
|
||||
|
||||
HCLGE_SET_DEFAULT_RESET_REQUEST(reset_type);
|
||||
|
||||
return ret;
|
||||
return reset_type;
|
||||
}
|
||||
|
||||
static int hclge_config_rocee_ras_interrupt(struct hclge_dev *hdev, bool en)
|
||||
@ -1232,15 +1233,18 @@ static int hclge_config_rocee_ras_interrupt(struct hclge_dev *hdev, bool en)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_handle_rocee_ras_error(struct hnae3_ae_dev *ae_dev)
|
||||
static void hclge_handle_rocee_ras_error(struct hnae3_ae_dev *ae_dev)
|
||||
{
|
||||
enum hnae3_reset_type reset_type = HNAE3_NONE_RESET;
|
||||
struct hclge_dev *hdev = ae_dev->priv;
|
||||
|
||||
if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
|
||||
hdev->pdev->revision < 0x21)
|
||||
return HNAE3_NONE_RESET;
|
||||
return;
|
||||
|
||||
return hclge_log_and_clear_rocee_ras_error(hdev);
|
||||
reset_type = hclge_log_and_clear_rocee_ras_error(hdev);
|
||||
if (reset_type != HNAE3_NONE_RESET)
|
||||
HCLGE_SET_DEFAULT_RESET_REQUEST(reset_type);
|
||||
}
|
||||
|
||||
static const struct hclge_hw_blk hw_blk[] = {
|
||||
|
@ -1033,7 +1033,8 @@ static int hclge_configure(struct hclge_dev *hdev)
|
||||
ether_addr_copy(hdev->hw.mac.mac_addr, cfg.mac_addr);
|
||||
hdev->hw.mac.media_type = cfg.media_type;
|
||||
hdev->hw.mac.phy_addr = cfg.phy_addr;
|
||||
hdev->num_desc = cfg.tqp_desc_num;
|
||||
hdev->num_tx_desc = cfg.tqp_desc_num;
|
||||
hdev->num_rx_desc = cfg.tqp_desc_num;
|
||||
hdev->tm_info.num_pg = 1;
|
||||
hdev->tc_max = cfg.tc_num;
|
||||
hdev->tm_info.hw_pfc_map = 0;
|
||||
@ -1140,7 +1141,8 @@ static int hclge_alloc_tqps(struct hclge_dev *hdev)
|
||||
|
||||
tqp->q.ae_algo = &ae_algo;
|
||||
tqp->q.buf_size = hdev->rx_buf_len;
|
||||
tqp->q.desc_num = hdev->num_desc;
|
||||
tqp->q.tx_desc_num = hdev->num_tx_desc;
|
||||
tqp->q.rx_desc_num = hdev->num_rx_desc;
|
||||
tqp->q.io_base = hdev->hw.io_base + HCLGE_TQP_REG_OFFSET +
|
||||
i * HCLGE_TQP_REG_SIZE;
|
||||
|
||||
@ -1184,7 +1186,8 @@ static int hclge_assign_tqp(struct hclge_vport *vport, u16 num_tqps)
|
||||
if (!hdev->htqp[i].alloced) {
|
||||
hdev->htqp[i].q.handle = &vport->nic;
|
||||
hdev->htqp[i].q.tqp_index = alloced;
|
||||
hdev->htqp[i].q.desc_num = kinfo->num_desc;
|
||||
hdev->htqp[i].q.tx_desc_num = kinfo->num_tx_desc;
|
||||
hdev->htqp[i].q.rx_desc_num = kinfo->num_rx_desc;
|
||||
kinfo->tqp[alloced] = &hdev->htqp[i].q;
|
||||
hdev->htqp[i].alloced = true;
|
||||
alloced++;
|
||||
@ -1197,15 +1200,18 @@ static int hclge_assign_tqp(struct hclge_vport *vport, u16 num_tqps)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_knic_setup(struct hclge_vport *vport,
|
||||
u16 num_tqps, u16 num_desc)
|
||||
static int hclge_knic_setup(struct hclge_vport *vport, u16 num_tqps,
|
||||
u16 num_tx_desc, u16 num_rx_desc)
|
||||
|
||||
{
|
||||
struct hnae3_handle *nic = &vport->nic;
|
||||
struct hnae3_knic_private_info *kinfo = &nic->kinfo;
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int ret;
|
||||
|
||||
kinfo->num_desc = num_desc;
|
||||
kinfo->num_tx_desc = num_tx_desc;
|
||||
kinfo->num_rx_desc = num_rx_desc;
|
||||
|
||||
kinfo->rx_buf_len = hdev->rx_buf_len;
|
||||
|
||||
kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, num_tqps,
|
||||
@ -1279,7 +1285,9 @@ static int hclge_vport_setup(struct hclge_vport *vport, u16 num_tqps)
|
||||
nic->numa_node_mask = hdev->numa_node_mask;
|
||||
|
||||
if (hdev->ae_dev->dev_type == HNAE3_DEV_KNIC) {
|
||||
ret = hclge_knic_setup(vport, num_tqps, hdev->num_desc);
|
||||
ret = hclge_knic_setup(vport, num_tqps,
|
||||
hdev->num_tx_desc, hdev->num_rx_desc);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev, "knic setup failed %d\n",
|
||||
ret);
|
||||
@ -6329,7 +6337,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,
|
||||
u8 fe_type, bool filter_en)
|
||||
u8 fe_type, bool filter_en, u8 vf_id)
|
||||
{
|
||||
struct hclge_vlan_filter_ctrl_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
@ -6340,6 +6348,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 ? fe_type : 0;
|
||||
req->vf_id = vf_id;
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret)
|
||||
@ -6368,12 +6377,13 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
|
||||
|
||||
if (hdev->pdev->revision >= 0x21) {
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS, enable);
|
||||
HCLGE_FILTER_FE_EGRESS, enable, 0);
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
|
||||
HCLGE_FILTER_FE_INGRESS, enable);
|
||||
HCLGE_FILTER_FE_INGRESS, enable, 0);
|
||||
} else {
|
||||
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS_V1_B, enable);
|
||||
HCLGE_FILTER_FE_EGRESS_V1_B, enable,
|
||||
0);
|
||||
}
|
||||
if (enable)
|
||||
handle->netdev_flags |= HNAE3_VLAN_FLTR;
|
||||
@ -6681,19 +6691,27 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
|
||||
int i;
|
||||
|
||||
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;
|
||||
/* for revision 0x21, vf vlan filter is per function */
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
vport = &hdev->vport[i];
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev,
|
||||
HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS,
|
||||
true,
|
||||
vport->vport_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
|
||||
HCLGE_FILTER_FE_INGRESS, true);
|
||||
HCLGE_FILTER_FE_INGRESS, true,
|
||||
0);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
|
||||
HCLGE_FILTER_FE_EGRESS_V1_B,
|
||||
true);
|
||||
true, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -706,7 +706,8 @@ struct hclge_dev {
|
||||
u16 num_alloc_vport; /* Num vports this driver supports */
|
||||
u32 numa_node_mask;
|
||||
u16 rx_buf_len;
|
||||
u16 num_desc;
|
||||
u16 num_tx_desc; /* desc num of per tx queue */
|
||||
u16 num_rx_desc; /* desc num of per rx queue */
|
||||
u8 hw_tc_map;
|
||||
u8 tc_num_last_time;
|
||||
enum hclge_fc_mode fc_mode_last_time;
|
||||
|
@ -357,20 +357,34 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req,
|
||||
bool gen_resp)
|
||||
{
|
||||
#define HCLGE_TQPS_RSS_INFO_LEN 8
|
||||
#define HCLGE_TQPS_RSS_INFO_LEN 6
|
||||
u8 resp_data[HCLGE_TQPS_RSS_INFO_LEN];
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
/* get the queue related info */
|
||||
memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16));
|
||||
memcpy(&resp_data[2], &vport->nic.kinfo.rss_size, sizeof(u16));
|
||||
memcpy(&resp_data[4], &hdev->num_desc, sizeof(u16));
|
||||
memcpy(&resp_data[6], &hdev->rx_buf_len, sizeof(u16));
|
||||
memcpy(&resp_data[4], &hdev->rx_buf_len, sizeof(u16));
|
||||
|
||||
return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data,
|
||||
HCLGE_TQPS_RSS_INFO_LEN);
|
||||
}
|
||||
|
||||
static int hclge_get_vf_queue_depth(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req,
|
||||
bool gen_resp)
|
||||
{
|
||||
#define HCLGE_TQPS_DEPTH_INFO_LEN 4
|
||||
u8 resp_data[HCLGE_TQPS_DEPTH_INFO_LEN];
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
/* get the queue depth info */
|
||||
memcpy(&resp_data[0], &hdev->num_tx_desc, sizeof(u16));
|
||||
memcpy(&resp_data[2], &hdev->num_rx_desc, sizeof(u16));
|
||||
return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data,
|
||||
HCLGE_TQPS_DEPTH_INFO_LEN);
|
||||
}
|
||||
|
||||
static int hclge_get_link_info(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
|
||||
{
|
||||
@ -476,6 +490,24 @@ static int hclge_get_queue_id_in_pf(struct hclge_vport *vport,
|
||||
return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, 2);
|
||||
}
|
||||
|
||||
static int hclge_get_rss_key(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
|
||||
{
|
||||
#define HCLGE_RSS_MBX_RESP_LEN 8
|
||||
u8 resp_data[HCLGE_RSS_MBX_RESP_LEN];
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u8 index;
|
||||
|
||||
index = mbx_req->msg[2];
|
||||
|
||||
memcpy(&resp_data[0],
|
||||
&hdev->vport[0].rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN],
|
||||
HCLGE_RSS_MBX_RESP_LEN);
|
||||
|
||||
return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data,
|
||||
HCLGE_RSS_MBX_RESP_LEN);
|
||||
}
|
||||
|
||||
static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
|
||||
{
|
||||
u32 tail = hclge_read_dev(hw, HCLGE_NIC_CRQ_TAIL_REG);
|
||||
@ -567,6 +599,14 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
|
||||
"PF failed(%d) to get Q info for VF\n",
|
||||
ret);
|
||||
break;
|
||||
case HCLGE_MBX_GET_QDEPTH:
|
||||
ret = hclge_get_vf_queue_depth(vport, req, true);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"PF failed(%d) to get Q depth for VF\n",
|
||||
ret);
|
||||
break;
|
||||
|
||||
case HCLGE_MBX_GET_TCINFO:
|
||||
ret = hclge_get_vf_tcinfo(vport, req, true);
|
||||
if (ret)
|
||||
@ -603,6 +643,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
|
||||
"PF failed(%d) to get qid for VF\n",
|
||||
ret);
|
||||
break;
|
||||
case HCLGE_MBX_GET_RSS_KEY:
|
||||
ret = hclge_get_rss_key(vport, req);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"PF fail(%d) to get rss key for VF\n",
|
||||
ret);
|
||||
break;
|
||||
case HCLGE_MBX_GET_LINK_MODE:
|
||||
hclge_get_link_mode(vport, req);
|
||||
break;
|
||||
|
@ -247,7 +247,7 @@ static int hclgevf_get_tc_info(struct hclgevf_dev *hdev)
|
||||
|
||||
static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
|
||||
{
|
||||
#define HCLGEVF_TQPS_RSS_INFO_LEN 8
|
||||
#define HCLGEVF_TQPS_RSS_INFO_LEN 6
|
||||
u8 resp_msg[HCLGEVF_TQPS_RSS_INFO_LEN];
|
||||
int status;
|
||||
|
||||
@ -263,8 +263,29 @@ static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
|
||||
|
||||
memcpy(&hdev->num_tqps, &resp_msg[0], sizeof(u16));
|
||||
memcpy(&hdev->rss_size_max, &resp_msg[2], sizeof(u16));
|
||||
memcpy(&hdev->num_desc, &resp_msg[4], sizeof(u16));
|
||||
memcpy(&hdev->rx_buf_len, &resp_msg[6], sizeof(u16));
|
||||
memcpy(&hdev->rx_buf_len, &resp_msg[4], sizeof(u16));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev)
|
||||
{
|
||||
#define HCLGEVF_TQPS_DEPTH_INFO_LEN 4
|
||||
u8 resp_msg[HCLGEVF_TQPS_DEPTH_INFO_LEN];
|
||||
int ret;
|
||||
|
||||
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QDEPTH, 0, NULL, 0,
|
||||
true, resp_msg,
|
||||
HCLGEVF_TQPS_DEPTH_INFO_LEN);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"VF request to get tqp depth info from PF failed %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(&hdev->num_tx_desc, &resp_msg[0], sizeof(u16));
|
||||
memcpy(&hdev->num_rx_desc, &resp_msg[2], sizeof(u16));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -304,7 +325,8 @@ static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev)
|
||||
|
||||
tqp->q.ae_algo = &ae_algovf;
|
||||
tqp->q.buf_size = hdev->rx_buf_len;
|
||||
tqp->q.desc_num = hdev->num_desc;
|
||||
tqp->q.tx_desc_num = hdev->num_tx_desc;
|
||||
tqp->q.rx_desc_num = hdev->num_rx_desc;
|
||||
tqp->q.io_base = hdev->hw.io_base + HCLGEVF_TQP_REG_OFFSET +
|
||||
i * HCLGEVF_TQP_REG_SIZE;
|
||||
|
||||
@ -323,7 +345,8 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
|
||||
|
||||
kinfo = &nic->kinfo;
|
||||
kinfo->num_tc = 0;
|
||||
kinfo->num_desc = hdev->num_desc;
|
||||
kinfo->num_tx_desc = hdev->num_tx_desc;
|
||||
kinfo->num_rx_desc = hdev->num_rx_desc;
|
||||
kinfo->rx_buf_len = hdev->rx_buf_len;
|
||||
for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++)
|
||||
if (hdev->hw_tc_map & BIT(i))
|
||||
@ -597,12 +620,50 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* for revision 0x20, vf shared the same rss config with pf */
|
||||
static int hclgevf_get_rss_hash_key(struct hclgevf_dev *hdev)
|
||||
{
|
||||
#define HCLGEVF_RSS_MBX_RESP_LEN 8
|
||||
|
||||
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
|
||||
u8 resp_msg[HCLGEVF_RSS_MBX_RESP_LEN];
|
||||
u16 msg_num, hash_key_index;
|
||||
u8 index;
|
||||
int ret;
|
||||
|
||||
msg_num = (HCLGEVF_RSS_KEY_SIZE + HCLGEVF_RSS_MBX_RESP_LEN - 1) /
|
||||
HCLGEVF_RSS_MBX_RESP_LEN;
|
||||
for (index = 0; index < msg_num; index++) {
|
||||
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_RSS_KEY, 0,
|
||||
&index, sizeof(index),
|
||||
true, resp_msg,
|
||||
HCLGEVF_RSS_MBX_RESP_LEN);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"VF get rss hash key from PF failed, ret=%d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hash_key_index = HCLGEVF_RSS_MBX_RESP_LEN * index;
|
||||
if (index == msg_num - 1)
|
||||
memcpy(&rss_cfg->rss_hash_key[hash_key_index],
|
||||
&resp_msg[0],
|
||||
HCLGEVF_RSS_KEY_SIZE - hash_key_index);
|
||||
else
|
||||
memcpy(&rss_cfg->rss_hash_key[hash_key_index],
|
||||
&resp_msg[0], HCLGEVF_RSS_MBX_RESP_LEN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
|
||||
u8 *hfunc)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
if (handle->pdev->revision >= 0x21) {
|
||||
/* Get hash algorithm */
|
||||
@ -624,6 +685,16 @@ static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key,
|
||||
if (key)
|
||||
memcpy(key, rss_cfg->rss_hash_key,
|
||||
HCLGEVF_RSS_KEY_SIZE);
|
||||
} else {
|
||||
if (hfunc)
|
||||
*hfunc = ETH_RSS_HASH_TOP;
|
||||
if (key) {
|
||||
ret = hclgevf_get_rss_hash_key(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
memcpy(key, rss_cfg->rss_hash_key,
|
||||
HCLGEVF_RSS_KEY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (indir)
|
||||
@ -1747,6 +1818,12 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
|
||||
ret = hclgevf_get_queue_info(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* get queue depth info from PF */
|
||||
ret = hclgevf_get_queue_depth(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* get tc configuration from PF */
|
||||
return hclgevf_get_tc_info(hdev);
|
||||
}
|
||||
|
@ -239,7 +239,8 @@ struct hclgevf_dev {
|
||||
u16 num_alloc_vport; /* num vports this driver supports */
|
||||
u32 numa_node_mask;
|
||||
u16 rx_buf_len;
|
||||
u16 num_desc;
|
||||
u16 num_tx_desc; /* desc num of per tx queue */
|
||||
u16 num_rx_desc; /* desc num of per rx queue */
|
||||
u8 hw_tc_map;
|
||||
|
||||
u16 num_msi;
|
||||
|
Loading…
Reference in New Issue
Block a user