[PATCH V2 for-next 03/11] IB/hns: Optimize the logic of allocating memory using APIs

2016-11-15 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch modified the logic of allocating memory using APIs in
hns RoCE driver. We used kcalloc instead of kmalloc_array and
bitmap_zero. And When kcalloc failed, call vzalloc to alloc
memory.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Ping Zhang 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_mr.c |   15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c 
b/drivers/infiniband/hw/hns/hns_roce_mr.c
index fb87883..d3dfb5f 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -137,11 +137,12 @@ static int hns_roce_buddy_init(struct hns_roce_buddy 
*buddy, int max_order)
 
for (i = 0; i <= buddy->max_order; ++i) {
s = BITS_TO_LONGS(1 << (buddy->max_order - i));
-   buddy->bits[i] = kmalloc_array(s, sizeof(long), GFP_KERNEL);
-   if (!buddy->bits[i])
-   goto err_out_free;
-
-   bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
+   buddy->bits[i] = kcalloc(s, sizeof(long), GFP_KERNEL);
+   if (!buddy->bits[i]) {
+   buddy->bits[i] = vzalloc(s * sizeof(long));
+   if (!buddy->bits[i])
+   goto err_out_free;
+   }
}
 
set_bit(0, buddy->bits[buddy->max_order]);
@@ -151,7 +152,7 @@ static int hns_roce_buddy_init(struct hns_roce_buddy 
*buddy, int max_order)
 
 err_out_free:
for (i = 0; i <= buddy->max_order; ++i)
-   kfree(buddy->bits[i]);
+   kvfree(buddy->bits[i]);
 
 err_out:
kfree(buddy->bits);
@@ -164,7 +165,7 @@ static void hns_roce_buddy_cleanup(struct hns_roce_buddy 
*buddy)
int i;
 
for (i = 0; i <= buddy->max_order; ++i)
-   kfree(buddy->bits[i]);
+   kvfree(buddy->bits[i]);
 
kfree(buddy->bits);
kfree(buddy->num_free);
-- 
1.7.9.5




[PATCH V2 for-next 08/11] IB/hns: Modify query info named port_num when querying RC QP

2016-11-15 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch modified the output query info qp_attr->port_num
to fix bug in hip06.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 509ea75..34b7898 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2857,9 +2857,7 @@ static int hns_roce_v1_q_qp(struct ib_qp *ibqp, struct 
ib_qp_attr *qp_attr,
qp_attr->pkey_index = roce_get_field(context->qpc_bytes_12,
  QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
  QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S);
-   qp_attr->port_num = (u8)roce_get_field(context->qpc_bytes_156,
-QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
-QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S) + 1;
+   qp_attr->port_num = hr_qp->port + 1;
qp_attr->sq_draining = 0;
qp_attr->max_rd_atomic = roce_get_field(context->qpc_bytes_156,
 QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M,
-- 
1.7.9.5




[PATCH net-next] net: hns: Fix to conditionally convey RX checksum flag to stack

2016-11-25 Thread Salil Mehta
This patch introduces the RX checksum function to check the
status of the hardware calculated checksum and its error and
appropriately convey status to the upper stack in skb->ip_summed
field.

We only support checksum for IPv4, UDP(over IPv4 or IPv6),
TCP(over IPv4 or IPv6) and SCTP but we support many L3(IPv4, IPv6,
MPLS, PPPoE etc) and L4(TCP, UDP, GRE, SCTP, IGMP, ICMP etc.)
protocols. We want to filter out L3 and L4 protocols early on for
which checksum is not supported.

Our present hardware RX Descriptor lacks L3/L4 "Checksum
Status & Error" bit (indicating whether checksum was calculated
and if there was an error encountered) for the supported protocol
received in the packet. Therefore, we do the following to optimize
the logic:
1. Filter the protocols for which checksum is not supported.
2. Check if there were any errors encountered in L3 or L4
   protocols. These errors might not just be Checksum errors but
   could be related to version, length of IPv4, UDP, TCP etc.
   2a. If L3 Errors amd L4 Errors exists, then try to check
   if any of  these errors were the RX checksum errors of
   IPv4, TCP or UDP. This is done by accessing the register
   in the HNS hardware.
   2b. If above errors do not exists, then we set checksum
   un-necessary for upper layers.

Signed-off-by: Salil Mehta 
---
Change Log:
Patch V1: This patch is a result of the comments given by
  David Miller 
  Link: https://lkml.org/lkml/2016/6/15/27
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |3 +
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |   30 
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |6 ++
 drivers/net/ethernet/hisilicon/hns/hns_enet.c |   76 +++--
 4 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 09602f1..fc6ff5e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -99,6 +99,8 @@ enum hnae_led_state {
 #define HNS_RX_FLAG_L3ID_IPV6 0x1
 #define HNS_RX_FLAG_L4ID_UDP 0x0
 #define HNS_RX_FLAG_L4ID_TCP 0x1
+#define HNS_RX_FLAG_L4ID_SCTP 0x3
+
 
 #define HNS_TXD_ASID_S 0
 #define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
@@ -513,6 +515,7 @@ struct hnae_ae_ops {
  enum hnae_led_state status);
void (*get_regs)(struct hnae_handle *handle, void *data);
int (*get_regs_len)(struct hnae_handle *handle);
+   bool (*is_l3l4csum_err)(struct hnae_handle *handle);
u32 (*get_rss_key_size)(struct hnae_handle *handle);
u32 (*get_rss_indir_size)(struct hnae_handle *handle);
int (*get_rss)(struct hnae_handle *handle, u32 *indir, u8 *key,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 0a9cdf0..4ca130f4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -778,6 +778,35 @@ int hns_ae_get_regs_len(struct hnae_handle *handle)
return total_num;
 }
 
+static bool hns_ae_is_l3l4_csum_err(struct hnae_handle *handle)
+{
+   struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);
+   u32 regval;
+   bool retval = false;
+
+   /* read PPE_HIS_PRO_ERR register and check for the checksum errors */
+   regval = dsaf_read_dev(ppe_cb, PPE_HIS_PRO_ERR_REG);
+
+   if (dsaf_get_bit(regval, PPE_L4_TCP_CSUM_ERR_B)) {
+   dsaf_set_bit(regval, PPE_L4_TCP_CSUM_ERR_B, 0);
+   retval = true;
+   } else if (dsaf_get_bit(regval, PPE_L4_IPV6_UDP_CSUM_ERR_B)) {
+   dsaf_set_bit(regval, PPE_L4_IPV6_UDP_CSUM_ERR_B, 0);
+   retval = true;
+   } else if (dsaf_get_bit(regval, PPE_L4_IPV4_UDP_CSUM_ERR_B)) {
+   dsaf_set_bit(regval, PPE_L4_IPV4_UDP_CSUM_ERR_B, 0);
+   retval = true;
+   } else if (dsaf_get_bit(regval, PPE_L3_IPV4_CSUM_ERR_B)) {
+   dsaf_set_bit(regval, PPE_L3_IPV4_CSUM_ERR_B, 0);
+   retval = true;
+   } else if (dsaf_get_bit(regval, PPE_L4_SCTP_CSUM_ERR_B)) {
+   dsaf_set_bit(regval, PPE_L4_SCTP_CSUM_ERR_B, 0);
+   retval = true;
+   }
+
+   return retval;
+}
+
 static u32 hns_ae_get_rss_key_size(struct hnae_handle *handle)
 {
return HNS_PPEV2_RSS_KEY_SIZE;
@@ -866,6 +895,7 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
.set_led_id = hns_ae_cpld_set_led_id,
.get_regs = hns_ae_get_regs,
.get_regs_len = hns_ae_get_regs_len,
+   .is_l3l4csum_err = hns_ae_is_l3l4_csum_err,
.get_rss_key_size = hns_ae_get_rss_key_size,
.get_rss_indir_size = hns_ae_get_rss_indir_size,
.get_rss = hns_ae_get_rss,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 872266

RE: [PATCH V2 net-next] net: hns: Fix to conditionally convey RX checksum flag to stack

2016-12-01 Thread Salil Mehta
> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Wednesday, November 30, 2016 7:26 PM
> To: Salil Mehta
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH V2 net-next] net: hns: Fix to conditionally convey
> RX checksum flag to stack
> 
> From: Salil Mehta 
> Date: Tue, 29 Nov 2016 13:09:45 +
> 
> > +   /* We only support checksum for IPv4,UDP(over IPv4 or IPv6),
> TCP(over
> > +* IPv4 or IPv6) and SCTP but we support many L3(IPv4, IPv6,
> MPLS,
> > +* PPPoE etc) and L4(TCP, UDP, GRE, SCTP, IGMP, ICMP etc.)
> protocols.
> > +* We want to filter out L3 and L4 protocols early on for which
> checksum
> > +* is not supported.
>  ...
> > +*/
> > +   l3id = hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S);
> > +   l4id = hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S);
> > +   if ((l3id != HNS_RX_FLAG_L3ID_IPV4) &&
> > +   ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
> > +(l4id != HNS_RX_FLAG_L4ID_UDP)) &&
> > +   ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
> > +(l4id != HNS_RX_FLAG_L4ID_TCP)) &&
> > +   (l4id != HNS_RX_FLAG_L4ID_SCTP))
> > +   return;
> 
> I have a hard time understanding this seemingly overcomplicated
> check.
> 
> It looks like if L3 is IPV4 it will accept any underlying L4 protocol,
> but is that what is really intended?  That doesn't match what this new
> comment states.
I agree that it is bit difficult to read. Earlier, I was banking on the
register(mistakenly, its hardware implementation err ) to de-multiplex
the checksum error type. The register supported indication of just IPv4
Header Checksum Error as well (which meant it could carry any L4 protocol).
IPv6 does not have similar Header checksum error. Therefore, to check
if it is just IPv4 Header checksum error or any supported L4 transport
(UDP or TCP) error over IPv4 or IPv6 I had to bank upon above complex
check

Below suggested solution check would have been insufficient for
example, if packet had IPv4/IGMP and there was a checksum error in IPv4
header.

Comment states:
" We only support checksum for IPv4, UDP(over IPv4 or IPv6), 
  TCP(over IPv4 or IPv6) and SCTP"
   1) Checksum of IPv4 (IPv4 header)
   2) UDP(over IPv4 or IPv6)
   3) TCP(over IPv4 or IPv6)
   4) SCTP (over IPv4 or IPv6)*

(*) I should have put IPv4/IPv6 check for SCTP in the code
and made it clear in the comment as well?

> 
> My understanding is that the chip supports checksums for:
> 
>   UDP/IPV4
>   UDP/IPV6
>   TCP/IPV4
>   TCP/IPV6
>   SCTP/IPV4
>   SCTP/IPV6

Hardware also supports checksum of IPv4 Header.

> 
> So the simplest thing is to validate each level one at a time:
> 
>   if (l3 != IPV4 && l3 != IPV6)
>   return;
>   if (l4 != UDP && l4 != TCP && l4 != SCTP)
>   return;
I guess above check will fail to catch cases like IPv4/IGMP, when there
is a bad checksum in The IPv4 header. 

But maybe now since we don't have any method to de-multiplex the kind of
checksum error (cannot depend upon register) we can have below code
re-arrangement:

hns_nic_rx_checksum() {
  /* check supported L3 protocol */
if (l3 != IPV4 && l3 != IPV6)
return;
  /* check if L3 protocols error */
  if (l3e)
return;

  /* check if the packets are fragmented */
If (l3frags)
Return;

  /* check supported L4 protocol */
if (l4 != UDP && l4 != TCP && l4 != SCTP)
return;
  /* check if any L4 protocol error */
  if (l3e)
return;

  /* packet with valid checksum - covey to stack */
  skb->ip_summed = CHECKSUM_UNNECESSARY
}

Hope I am not missing something here. Please correct my understanding
if there is any gap here. Thanks!

Best regards
Salil


RE: [PATCH V2 net-next] net: hns: Fix to conditionally convey RX checksum flag to stack

2016-12-01 Thread Salil Mehta
> -Original Message-
> From: Salil Mehta
> Sent: Thursday, December 01, 2016 12:09 PM
> To: 'David Miller'
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: RE: [PATCH V2 net-next] net: hns: Fix to conditionally convey
> RX checksum flag to stack
> 
> > -Original Message-
> > From: David Miller [mailto:da...@davemloft.net]
> > Sent: Wednesday, November 30, 2016 7:26 PM
> > To: Salil Mehta
> > Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> > Subject: Re: [PATCH V2 net-next] net: hns: Fix to conditionally
> convey
> > RX checksum flag to stack
> >
> > From: Salil Mehta 
> > Date: Tue, 29 Nov 2016 13:09:45 +
> >
> > > + /* We only support checksum for IPv4,UDP(over IPv4 or IPv6),
> > TCP(over
> > > +  * IPv4 or IPv6) and SCTP but we support many L3(IPv4, IPv6,
> > MPLS,
> > > +  * PPPoE etc) and L4(TCP, UDP, GRE, SCTP, IGMP, ICMP etc.)
> > protocols.
> > > +  * We want to filter out L3 and L4 protocols early on for which
> > checksum
> > > +  * is not supported.
> >  ...
> > > +  */
> > > + l3id = hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S);
> > > + l4id = hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S);
> > > + if ((l3id != HNS_RX_FLAG_L3ID_IPV4) &&
> > > + ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
> > > +  (l4id != HNS_RX_FLAG_L4ID_UDP)) &&
> > > + ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
> > > +  (l4id != HNS_RX_FLAG_L4ID_TCP)) &&
> > > + (l4id != HNS_RX_FLAG_L4ID_SCTP))
> > > + return;
> >
> > I have a hard time understanding this seemingly overcomplicated
> > check.
> >
> > It looks like if L3 is IPV4 it will accept any underlying L4
> protocol,
> > but is that what is really intended?  That doesn't match what this
> new
> > comment states.
> I agree that it is bit difficult to read. Earlier, I was banking on the
> register(mistakenly, its hardware implementation err ) to de-multiplex
> the checksum error type. The register supported indication of just IPv4
> Header Checksum Error as well (which meant it could carry any L4
> protocol).
> IPv6 does not have similar Header checksum error. Therefore, to check
> if it is just IPv4 Header checksum error or any supported L4 transport
> (UDP or TCP) error over IPv4 or IPv6 I had to bank upon above complex
> check
> 
> Below suggested solution check would have been insufficient for
> example, if packet had IPv4/IGMP and there was a checksum error in IPv4
> header.
> 
> Comment states:
> " We only support checksum for IPv4, UDP(over IPv4 or IPv6),
>   TCP(over IPv4 or IPv6) and SCTP"
>1) Checksum of IPv4 (IPv4 header)
>2) UDP(over IPv4 or IPv6)
>3) TCP(over IPv4 or IPv6)
>4) SCTP (over IPv4 or IPv6)*
> 
> (*) I should have put IPv4/IPv6 check for SCTP in the code
> and made it clear in the comment as well?
> 
> >
> > My understanding is that the chip supports checksums for:
> >
> > UDP/IPV4
> > UDP/IPV6
> > TCP/IPV4
> > TCP/IPV6
> > SCTP/IPV4
> > SCTP/IPV6
> 
> Hardware also supports checksum of IPv4 Header.
> 
> >
> > So the simplest thing is to validate each level one at a time:
> >
> > if (l3 != IPV4 && l3 != IPV6)
> > return;
> > if (l4 != UDP && l4 != TCP && l4 != SCTP)
> > return;
> I guess above check will fail to catch cases like IPv4/IGMP, when there
> is a bad checksum in The IPv4 header.
> 
> But maybe now since we don't have any method to de-multiplex the kind
> of
> checksum error (cannot depend upon register) we can have below code
> re-arrangement:
> 
> hns_nic_rx_checksum() {
>   /* check supported L3 protocol */
>   if (l3 != IPV4 && l3 != IPV6)
>   return;
>   /* check if L3 protocols error */
>   if (l3e)
>   return;
> 
>   /* check if the packets are fragmented */
>   If (l3frags)
>   Return;
> 
>   /* check supported L4 protocol */
>   if (l4 != UDP && l4 != TCP && l4 != SCTP)
>   return;
Hi David,
This logic might not do as well since IGMP packet with valid IP
Checksum will be bypassed here. We would want to set
CHECKSUM_UNNECESSARY for such IP packets as well.

It looks to me the cumbersome check in the PATCH V2 should
be retained.

>   /* check if any L4 protocol error */
>   if (l3e)
>   return;
> 
>   /* packet with valid checksum - covey to stack */
>   skb->ip_summed = CHECKSUM_UNNECESSARY
> }

> 
> Hope I am not missing something here. Please correct my understanding
> if there is any gap here. Thanks!
> 
> Best regards
> Salil


RE: [PATCH net-next] net: hns: Fix to conditionally convey RX checksum flag to stack

2016-11-29 Thread Salil Mehta
> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Monday, November 28, 2016 5:13 PM
> To: Salil Mehta
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH net-next] net: hns: Fix to conditionally convey RX
> checksum flag to stack
> 
> From: Salil Mehta 
> Date: Fri, 25 Nov 2016 13:32:40 +
> 
> > @@ -778,6 +778,35 @@ int hns_ae_get_regs_len(struct hnae_handle
> *handle)
> > return total_num;
> >  }
> >
> > +static bool hns_ae_is_l3l4_csum_err(struct hnae_handle *handle)
> > +{
> > +   struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);
> > +   u32 regval;
> > +   bool retval = false;
> > +
> > +   /* read PPE_HIS_PRO_ERR register and check for the checksum
> errors */
> > +   regval = dsaf_read_dev(ppe_cb, PPE_HIS_PRO_ERR_REG);
> > +
> 
> I don't see how a single register can properly provide error status for
> a ring
> of pending received packets.
> 
> No matter how this register is implemented, it is either going to
> result in
> packets erroneously being marked as having errors, or error status
> being
> lost when multiple packets in a row have such errors.
> 
> For example, if you receive several packets in a row that have errors,
> you'll read this register for the first one.  If this read clears the
> error
> status, which I am guessing it does, then you won't see the error
> status
> for the next packet that had one of these errors as well.
Agreed David. I think I missed this part. This register is 
not well thought of and looks useless for checksum. Thanks
for identifying this!

> 
> If you don't have something which is provided on a per-packet basis
> then you can't determine the error properly.  Therefore you will just
> have to always ignore the checksum if there is any error indicated in
> the ring descriptor.
Yes, will float another patch ignoring the checksum.

Thanks
Salil 



[PATCH V2 net-next] net: hns: Fix to conditionally convey RX checksum flag to stack

2016-11-29 Thread Salil Mehta
This patch introduces the RX checksum function to check the
status of the hardware calculated checksum and its error and
appropriately convey status to the upper stack in skb->ip_summed
field.

We only support checksum for IPv4, UDP(over IPv4 or IPv6),
TCP(over IPv4 or IPv6) and SCTP but we support many L3(IPv4, IPv6,
MPLS, PPPoE etc) and L4(TCP, UDP, GRE, SCTP, IGMP, ICMP etc.)
protocols. We want to filter out L3 and L4 protocols early on for
which checksum is not supported.

Our present hardware RX Descriptor lacks L3/L4 "Checksum
Status & Error" bit (indicating whether checksum was calculated
and if there was an error encountered) for the supported protocol
received in the packet. Therefore, we do the following:
1. Filter the protocols for which checksum is not supported.
2. Check if there were any errors encountered in L3 or L4
   protocols. These errors might not just be Checksum errors but
   could be related to version, length of IPv4, UDP, TCP etc.
   2a. If L3 Errors amd L4 Errors exists, then return as our RX
   descriptor lacks Status-and-Error bits for checksum so
   cannot identify specifically if error was because of
   checksum error or other error for this packet.
   2b. If above errors do not exists, then we set checksum
   un-necessary for upper layers.

Signed-off-by: Salil Mehta 
---
Change Log:
Patch V2: Addressed the comment by David Miller
  Link: https://www.spinics.net/lists/netdev/msg406697.html
Patch V1: This patch is a result of the comments given by
  David Miller 
  Link: https://lkml.org/lkml/2016/6/15/27
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |2 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.c |   71 ++---
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 09602f1..8016854 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -99,6 +99,8 @@ enum hnae_led_state {
 #define HNS_RX_FLAG_L3ID_IPV6 0x1
 #define HNS_RX_FLAG_L4ID_UDP 0x0
 #define HNS_RX_FLAG_L4ID_TCP 0x1
+#define HNS_RX_FLAG_L4ID_SCTP 0x3
+
 
 #define HNS_TXD_ASID_S 0
 #define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 255fede..6450d0e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -565,6 +565,66 @@ static void get_rx_desc_bnum(u32 bnum_flag, int *out_bnum)
   HNS_RXD_BUFNUM_M, HNS_RXD_BUFNUM_S);
 }
 
+static void hns_nic_rx_checksum(struct hns_nic_ring_data *ring_data,
+   struct sk_buff *skb, u32 flag)
+{
+   struct net_device *netdev = ring_data->napi.dev;
+   u32 l3id;
+   u32 l4id;
+
+   /* check if RX checksum offload is enabled */
+   if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
+   return;
+
+   /* We only support checksum for IPv4,UDP(over IPv4 or IPv6), TCP(over
+* IPv4 or IPv6) and SCTP but we support many L3(IPv4, IPv6, MPLS,
+* PPPoE etc) and L4(TCP, UDP, GRE, SCTP, IGMP, ICMP etc.) protocols.
+* We want to filter out L3 and L4 protocols early on for which checksum
+* is not supported.
+*
+* Our present hardware RX Descriptor lacks L3/L4 "Checksum Status &
+* Error" bit (indicating whether checksum was calculated and if there
+* was an error encountered) for the supported protocol received in the
+* packet. Therefore, we do the following:
+* 1. Filter the protocols for which checksum is not supported.
+* 2. Check if there were any errors encountered in L3 or L4 protocols.
+*These errors might not just be Checksum errors but could be
+*related to version, length of IPv4, UDP, TCP etc.
+*2a. If L3 Errors amd L4 Errors exists, then return as our RX
+*descriptor lacks Status-and-Error bits for checksum so cannot
+*identify specifically if error was because of checksum error
+*or other error for this packet.
+*2b. If above errors do not exists, then we set checksum
+*un-necessary for upper layers.
+*/
+   l3id = hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S);
+   l4id = hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S);
+   if ((l3id != HNS_RX_FLAG_L3ID_IPV4) &&
+   ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
+(l4id != HNS_RX_FLAG_L4ID_UDP)) &&
+   ((l3id != HNS_RX_FLAG_L3ID_IPV6) ||
+(l4id != HNS_RX_FLAG_L4ID_TCP)) &&
+   (l4id != HNS_RX_FLAG_L4ID_SCTP))
+   return;
+
+   /* We do not support checksum of fragmented packets */
+   i

[PATCH for-next 0/6] IB/hns: Bug Fixes for HNS RoCE Driver

2016-11-29 Thread Salil Mehta
This patch-set contains bug fixes for the HNS RoCE driver.

Lijun Ou (1):
  IB/hns: Fix the IB device name

Shaobo Xu (2):
  IB/hns: Fix the bug when free mr
  IB/hns: Fix the bug when free cq

Wei Hu (Xavier) (3):
  IB/hns: Fix the bug when destroy qp
  IB/hns: Fix the bug of setting port mtu
  IB/hns: Delete the redundant memset operation

 drivers/infiniband/hw/hns/hns_roce_cmd.h|5 -
 drivers/infiniband/hw/hns/hns_roce_common.h |   42 ++
 drivers/infiniband/hw/hns/hns_roce_cq.c |   27 +-
 drivers/infiniband/hw/hns/hns_roce_device.h |   18 +
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |  967 ---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h  |   57 ++
 drivers/infiniband/hw/hns/hns_roce_main.c   |   26 +-
 drivers/infiniband/hw/hns/hns_roce_mr.c |   21 +-
 8 files changed, 1026 insertions(+), 137 deletions(-)

-- 
1.7.9.5




[PATCH for-next 3/6] IB/hns: Fix the bug of setting port mtu

2016-11-29 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

In hns_roce driver, we need not call iboe_get_mtu to reduce
IB headers from effective IBoE MTU because hr_dev->caps.max_mtu
has already been reduced.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_main.c |   16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c 
b/drivers/infiniband/hw/hns/hns_roce_main.c
index 0cedec0..5e620f9 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -72,18 +72,6 @@ static void hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 
port, u8 *addr)
hr_dev->hw->set_mac(hr_dev, phy_port, addr);
 }
 
-static void hns_roce_set_mtu(struct hns_roce_dev *hr_dev, u8 port, int mtu)
-{
-   u8 phy_port = hr_dev->iboe.phy_port[port];
-   enum ib_mtu tmp;
-
-   tmp = iboe_get_mtu(mtu);
-   if (!tmp)
-   tmp = IB_MTU_256;
-
-   hr_dev->hw->set_mtu(hr_dev, phy_port, tmp);
-}
-
 static int hns_roce_add_gid(struct ib_device *device, u8 port_num,
unsigned int index, const union ib_gid *gid,
const struct ib_gid_attr *attr, void **context)
@@ -188,8 +176,8 @@ static int hns_roce_setup_mtu_mac(struct hns_roce_dev 
*hr_dev)
u8 i;
 
for (i = 0; i < hr_dev->caps.num_ports; i++) {
-   hns_roce_set_mtu(hr_dev, i,
-ib_mtu_enum_to_int(hr_dev->caps.max_mtu));
+   hr_dev->hw->set_mtu(hr_dev, hr_dev->iboe.phy_port[i],
+   hr_dev->caps.max_mtu);
hns_roce_set_mac(hr_dev, i, hr_dev->iboe.netdevs[i]->dev_addr);
}
 
-- 
1.7.9.5




[PATCH for-next 2/6] IB/hns: Fix the bug when free mr

2016-11-29 Thread Salil Mehta
From: Shaobo Xu 

If the resources of mr are freed while executing the user case, hardware
can not been notified in hip06 SoC. Then hardware will hold on when it
reads the payload by the PA which has been released.

In order to slove this problem, RoCE driver creates 8 reserved loopback
QPs to ensure zero wqe when free mr. When the mac address is reset, in
order to avoid loopback failure, we need to release the reserved loopback
QPs and recreate them.

Signed-off-by: Shaobo Xu 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_cmd.h|5 -
 drivers/infiniband/hw/hns/hns_roce_device.h |   10 +
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |  485 +++
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h  |   34 ++
 drivers/infiniband/hw/hns/hns_roce_main.c   |5 +-
 drivers/infiniband/hw/hns/hns_roce_mr.c |   21 +-
 6 files changed, 545 insertions(+), 15 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.h 
b/drivers/infiniband/hw/hns/hns_roce_cmd.h
index ed14ad3..f5a9ee2 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cmd.h
+++ b/drivers/infiniband/hw/hns/hns_roce_cmd.h
@@ -58,11 +58,6 @@ enum {
HNS_ROCE_CMD_QUERY_QP   = 0x22,
 };
 
-struct hns_roce_cmd_mailbox {
-   void   *buf;
-   dma_addr_t  dma;
-};
-
 int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param,
  unsigned long in_modifier, u8 op_modifier, u16 op,
  unsigned long timeout);
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index e48464d..1050829 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -388,6 +388,11 @@ struct hns_roce_cmdq {
u8  toggle;
 };
 
+struct hns_roce_cmd_mailbox {
+   void   *buf;
+   dma_addr_t  dma;
+};
+
 struct hns_roce_dev;
 
 struct hns_roce_qp {
@@ -522,6 +527,7 @@ struct hns_roce_hw {
 struct ib_recv_wr **bad_recv_wr);
int (*req_notify_cq)(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+   int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr);
void*priv;
 };
 
@@ -688,6 +694,10 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 
start, u64 length,
   u64 virt_addr, int access_flags,
   struct ib_udata *udata);
 int hns_roce_dereg_mr(struct ib_mr *ibmr);
+int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
+  struct hns_roce_cmd_mailbox *mailbox,
+  unsigned long mpt_index);
+unsigned long key_to_hw_index(u32 key);
 
 void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
   struct hns_roce_buf *buf);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index aee1d01..f67a3bf 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -295,6 +295,8 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct 
ib_send_wr *wr,
roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SQ_HEAD_M,
   SQ_DOORBELL_U32_4_SQ_HEAD_S,
  (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)));
+   roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SL_M,
+  SQ_DOORBELL_U32_4_SL_S, qp->sl);
roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M,
   SQ_DOORBELL_U32_4_PORT_S, qp->phy_port);
roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M,
@@ -622,6 +624,213 @@ static int hns_roce_db_ext_init(struct hns_roce_dev 
*hr_dev, u32 sdb_ext_mod,
return ret;
 }
 
+static struct hns_roce_qp *hns_roce_v1_create_lp_qp(struct hns_roce_dev 
*hr_dev,
+   struct ib_pd *pd)
+{
+   struct device *dev = &hr_dev->pdev->dev;
+   struct ib_qp_init_attr init_attr;
+   struct ib_qp *qp;
+
+   memset(&init_attr, 0, sizeof(struct ib_qp_init_attr));
+   init_attr.qp_type   = IB_QPT_RC;
+   init_attr.sq_sig_type   = IB_SIGNAL_ALL_WR;
+   init_attr.cap.max_recv_wr   = HNS_ROCE_MIN_WQE_NUM;
+   init_attr.cap.max_send_wr   = HNS_ROCE_MIN_WQE_NUM;
+
+   qp = hns_roce_create_qp(pd, &init_attr, NULL);
+   if (IS_ERR(qp)) {
+   dev_err(dev, "Create loop qp for mr free failed!");
+   return NULL;
+   }
+
+   return to_hr_qp(qp);
+}
+
+static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
+{
+   struct hns_roce_caps *caps = &hr_dev->caps;
+ 

[PATCH for-next 4/6] IB/hns: Delete the redundant memset operation

2016-11-29 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

It deleted the redundant memset operation because the memory allocated
by ib_alloc_device has been set zero.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_main.c |3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c 
b/drivers/infiniband/hw/hns/hns_roce_main.c
index 5e620f9..28a8f24 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -843,9 +843,6 @@ static int hns_roce_probe(struct platform_device *pdev)
if (!hr_dev)
return -ENOMEM;
 
-   memset((u8 *)hr_dev + sizeof(struct ib_device), 0,
-   sizeof(struct hns_roce_dev) - sizeof(struct ib_device));
-
hr_dev->pdev = pdev;
platform_set_drvdata(pdev, hr_dev);
 
-- 
1.7.9.5




[PATCH for-next 6/6] IB/hns: Fix the IB device name

2016-11-29 Thread Salil Mehta
From: Lijun Ou 

This patch mainly fix the name for IB device in order
to match with libhns.

Signed-off-by: Lijun Ou 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_main.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c 
b/drivers/infiniband/hw/hns/hns_roce_main.c
index 28a8f24..eddb053 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -433,7 +433,7 @@ static int hns_roce_register_device(struct hns_roce_dev 
*hr_dev)
spin_lock_init(&iboe->lock);
 
ib_dev = &hr_dev->ib_dev;
-   strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX);
+   strlcpy(ib_dev->name, "hns_%d", IB_DEVICE_NAME_MAX);
 
ib_dev->owner   = THIS_MODULE;
ib_dev->node_type   = RDMA_NODE_IB_CA;
-- 
1.7.9.5




[PATCH for-next 1/6] IB/hns: Fix the bug when destroy qp

2016-11-29 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

If send queue is still working when qp is in reset state by modify qp
in destroy qp function, hardware will hold on and don't work in hip06
SoC. In current codes, RoCE driver check hardware pointer of sending and
hardware pointer of processing to ensure that hardware has processed all
the dbs of this qp. But while the environment of wire becomes not good,
The checking time maybe too long.

In order to solve this problem, RoCE driver created a workqueue at probe
function. If there is a timeout when checking the status of qp, driver
initialize work entry and push it into the workqueue, Work function will
finish checking and release the related resources later.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Lijun Ou 
Signed-off-by: Dongdong Huang(Donald) 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_common.h |   40 +++
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |  435 +--
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h  |   23 ++
 3 files changed, 402 insertions(+), 96 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h 
b/drivers/infiniband/hw/hns/hns_roce_common.h
index 0dcb620..a055632 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -57,6 +57,32 @@
 #define roce_set_bit(origin, shift, val) \
roce_set_field((origin), (1ul << (shift)), (shift), (val))
 
+/*
+ * roce_hw_index_cmp_lt - Compare two hardware index values in hisilicon
+ *SOC, check if a is less than b.
+ * @a: hardware index value
+ * @b: hardware index value
+ * @bits: the number of bits of a and b, range: 0~31.
+ *
+ * Hardware index increases continuously till max value, and then restart
+ * from zero, again and again. Because the bits of reg field is often
+ * limited, the reg field can only hold the low bits of the hardware index
+ * in hisilicon SOC.
+ * In some scenes we need to compare two values(a,b) getted from two reg
+ * fields in this driver, for example:
+ * If a equals 0xfffe, b equals 0x1 and bits equals 16, we think b has
+ * incresed from 0x to 0x1 and a is less than b.
+ * If a equals 0xfffe, b equals 0x0xf001 and bits equals 16, we think a
+ * is bigger than b.
+ *
+ * Return true on a less than b, otherwise false.
+ */
+#define roce_hw_index_mask(bits)   ((1ul << (bits)) - 1)
+#define roce_hw_index_shift(bits)  (32 - (bits))
+#define roce_hw_index_cmp_lt(a, b, bits) \
+   ((int)a) - (b)) & roce_hw_index_mask(bits)) << \
+   roce_hw_index_shift(bits)) < 0)
+
 #define ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S 3
 #define ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S 4
 
@@ -245,10 +271,22 @@
 #define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M   \
(((1UL << 28) - 1) << ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)
 
+#define ROCEE_SDB_PTR_CMP_BITS 28
+
 #define ROCEE_SDB_INV_CNT_SDB_INV_CNT_S 0
 #define ROCEE_SDB_INV_CNT_SDB_INV_CNT_M   \
(((1UL << 16) - 1) << ROCEE_SDB_INV_CNT_SDB_INV_CNT_S)
 
+#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S 0
+#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M \
+   (((1UL << 16) - 1) << ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S)
+
+#define ROCEE_SDB_CNT_CMP_BITS 16
+
+#define ROCEE_TSP_BP_ST_QH_FIFO_ENTRY_S20
+
+#define ROCEE_CNT_CLR_CE_CNT_CLR_CE_S 0
+
 /*ROCEE_REG DEFINITION/
 #define ROCEE_VENDOR_ID_REG0x0
 #define ROCEE_VENDOR_PART_ID_REG   0x4
@@ -317,6 +355,8 @@
 #define ROCEE_SDB_ISSUE_PTR_REG0x758
 #define ROCEE_SDB_SEND_PTR_REG 0x75C
 #define ROCEE_SDB_INV_CNT_REG  0x9A4
+#define ROCEE_SDB_RETRY_CNT_REG0x9AC
+#define ROCEE_TSP_BP_ST_REG0x9EC
 #define ROCEE_ECC_UCERR_ALM0_REG   0xB34
 #define ROCEE_ECC_CERR_ALM0_REG0xB40
 
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 125ab90..aee1d01 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -948,6 +948,38 @@ int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool 
dereset)
return ret;
 }
 
+static int hns_roce_des_qp_init(struct hns_roce_dev *hr_dev)
+{
+   struct device *dev = &hr_dev->pdev->dev;
+   struct hns_roce_v1_priv *priv;
+   struct hns_roce_des_qp *des_qp;
+
+   priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+   des_qp = &priv->des_qp;
+
+   des_qp->requeue_flag = 1;
+   des_qp->qp_wq = create_singlethread_workqueue("hns_roce_destroy_qp");
+   if (!des_qp->qp_wq) {
+   dev_err(dev, "Create destroy qp workqueue failed!\n");
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+static void hns_roce_des_qp_free(struct hns_roce_dev *hr_

[PATCH for-next 5/6] IB/hns: Fix the bug when free cq

2016-11-29 Thread Salil Mehta
From: Shaobo Xu 

If the resources of cq are freed while executing the user case, hardware
can not been notified in hip06 SoC. Then hardware will hold on when it
writes the cq buffer which has been released.

In order to slove this problem, RoCE driver checks the CQE counter, and
ensure that the outstanding CQE have been written. Then the cq buffer
can be released.

Signed-off-by: Shaobo Xu 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta 
---
 drivers/infiniband/hw/hns/hns_roce_common.h |2 +
 drivers/infiniband/hw/hns/hns_roce_cq.c |   27 --
 drivers/infiniband/hw/hns/hns_roce_device.h |8 
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |   53 +++
 4 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h 
b/drivers/infiniband/hw/hns/hns_roce_common.h
index a055632..4af403e 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -354,6 +354,8 @@
 
 #define ROCEE_SDB_ISSUE_PTR_REG0x758
 #define ROCEE_SDB_SEND_PTR_REG 0x75C
+#define ROCEE_CAEP_CQE_WCMD_EMPTY  0x850
+#define ROCEE_SCAEP_WR_CQE_CNT 0x8D0
 #define ROCEE_SDB_INV_CNT_REG  0x9A4
 #define ROCEE_SDB_RETRY_CNT_REG0x9AC
 #define ROCEE_TSP_BP_ST_REG0x9EC
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c 
b/drivers/infiniband/hw/hns/hns_roce_cq.c
index c9f6c3d..ff9a6a3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -179,8 +179,7 @@ static int hns_roce_hw2sw_cq(struct hns_roce_dev *dev,
 HNS_ROCE_CMD_TIMEOUT_MSECS);
 }
 
-static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
-struct hns_roce_cq *hr_cq)
+void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
 {
struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
struct device *dev = &hr_dev->pdev->dev;
@@ -392,19 +391,25 @@ int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq)
 {
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
+   int ret = 0;
 
-   hns_roce_free_cq(hr_dev, hr_cq);
-   hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
+   if (hr_dev->hw->destroy_cq) {
+   ret = hr_dev->hw->destroy_cq(ib_cq);
+   } else {
+   hns_roce_free_cq(hr_dev, hr_cq);
+   hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
 
-   if (ib_cq->uobject)
-   ib_umem_release(hr_cq->umem);
-   else
-   /* Free the buff of stored cq */
-   hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe);
+   if (ib_cq->uobject)
+   ib_umem_release(hr_cq->umem);
+   else
+   /* Free the buff of stored cq */
+   hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
+   ib_cq->cqe);
 
-   kfree(hr_cq);
+   kfree(hr_cq);
+   }
 
-   return 0;
+   return ret;
 }
 
 void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index 1050829..d4f0fce 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -56,6 +56,12 @@
 #define HNS_ROCE_MAX_INNER_MTPT_NUM0x7
 #define HNS_ROCE_MAX_MTPT_PBL_NUM  0x10
 
+#define HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS   20
+#define HNS_ROCE_MAX_FREE_CQ_WAIT_CNT  \
+   (5000 / HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS)
+#define HNS_ROCE_CQE_WCMD_EMPTY_BIT0x2
+#define HNS_ROCE_MIN_CQE_CNT   16
+
 #define HNS_ROCE_MAX_IRQ_NUM   34
 
 #define HNS_ROCE_COMP_VEC_NUM  32
@@ -528,6 +534,7 @@ struct hns_roce_hw {
int (*req_notify_cq)(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr);
+   int (*destroy_cq)(struct ib_cq *ibcq);
void*priv;
 };
 
@@ -734,6 +741,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device 
*ib_dev,
struct ib_udata *udata);
 
 int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq);
+void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq);
 
 void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);
 void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c

RE: [PATCH for-next 03/11] IB/hns: Optimize the logic of allocating memory using APIs

2016-11-21 Thread Salil Mehta
> -Original Message-
> From: Leon Romanovsky [mailto:l...@kernel.org]
> Sent: Wednesday, November 16, 2016 8:36 AM
> To: Salil Mehta
> Cc: dledf...@redhat.com; Huwei (Xavier); oulijun;
> mehta.salil@gmail.com; linux-r...@vger.kernel.org;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> Zhangping (ZP)
> Subject: Re: [PATCH for-next 03/11] IB/hns: Optimize the logic of
> allocating memory using APIs
> 
> On Tue, Nov 15, 2016 at 03:52:46PM +, Salil Mehta wrote:
> > > -Original Message-
> > > From: Leon Romanovsky [mailto:l...@kernel.org]
> > > Sent: Wednesday, November 09, 2016 7:22 AM
> > > To: Salil Mehta
> > > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun;
> > > mehta.salil@gmail.com; linux-r...@vger.kernel.org;
> > > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> > > Zhangping (ZP)
> > > Subject: Re: [PATCH for-next 03/11] IB/hns: Optimize the logic of
> > > allocating memory using APIs
> > >
> > > On Fri, Nov 04, 2016 at 04:36:25PM +, Salil Mehta wrote:
> > > > From: "Wei Hu (Xavier)" 
> > > >
> > > > This patch modified the logic of allocating memory using APIs in
> > > > hns RoCE driver. We used kcalloc instead of kmalloc_array and
> > > > bitmap_zero. And When kcalloc failed, call vzalloc to alloc
> > > > memory.
> > > >
> > > > Signed-off-by: Wei Hu (Xavier) 
> > > > Signed-off-by: Ping Zhang 
> > > > Signed-off-by: Salil Mehta  
> > > > ---
> > > >  drivers/infiniband/hw/hns/hns_roce_mr.c |   15 ---
> > > >  1 file changed, 8 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > b/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > index fb87883..d3dfb5f 100644
> > > > --- a/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > @@ -137,11 +137,12 @@ static int hns_roce_buddy_init(struct
> > > hns_roce_buddy *buddy, int max_order)
> > > >
> > > > for (i = 0; i <= buddy->max_order; ++i) {
> > > > s = BITS_TO_LONGS(1 << (buddy->max_order - i));
> > > > -   buddy->bits[i] = kmalloc_array(s, sizeof(long),
> > > GFP_KERNEL);
> > > > -   if (!buddy->bits[i])
> > > > -   goto err_out_free;
> > > > -
> > > > -   bitmap_zero(buddy->bits[i], 1 << (buddy->max_order -
> i));
> > > > +   buddy->bits[i] = kcalloc(s, sizeof(long),
> GFP_KERNEL);
> > > > +   if (!buddy->bits[i]) {
> > > > +   buddy->bits[i] = vzalloc(s * sizeof(long));
> > >
> > > I wonder, why don't you use directly vzalloc instead of kcalloc
> > > fallback?
> > As we know we will have physical contiguous pages if the kcalloc
> > call succeeds. This will give us a chance to have better performance
> > over the allocations which are just virtually contiguous through the
> > function vzalloc(). Therefore, later has only been used as a fallback
> > when our memory request cannot be entertained through kcalloc.
> >
> > Are you suggesting that there will not be much performance penalty
> > if we use just vzalloc ?
> 
> Not exactly,
> I asked it, because we have similar code in our drivers and this
> construction looks strange to me.
> 
> 1. If performance is critical, we will use kmalloc.
> 2. If performance is not critical, we will use vmalloc.
> 
> But in this case, such construction shows me that we can live with
> vmalloc performance and kmalloc allocation are not really needed.
> 
> In your specific case, I'm not sure that kcalloc will ever fail.
Performance is definitely critical here. Though, I agree this is bit
unusual way of memory allocation. In actual, we were encountering
memory alloc failures using kmalloc (if you see allocation amount
is on the higher side and is exponential) so we ended up using
vmalloc as fall back - It is very naïve allocation scheme.

Maybe we need to rethink this allocation scheme part? Also, I can pull
back this particular patch for now or just live with vzalloc() till
we figure out proper solution to this? 

> 
> Thanks
> 
> 
> >
> > >
> > > > +   if (!buddy->bits[i])
> > > > +   goto err_out_free;
> > > > +   }
> > > > }


RE: [PATCH for-next 03/11] IB/hns: Optimize the logic of allocating memory using APIs

2016-11-21 Thread Salil Mehta
> -Original Message-
> From: netdev-ow...@vger.kernel.org [mailto:netdev-
> ow...@vger.kernel.org] On Behalf Of Leon Romanovsky
> Sent: Monday, November 21, 2016 5:14 PM
> To: Salil Mehta
> Cc: dledf...@redhat.com; Huwei (Xavier); oulijun;
> mehta.salil@gmail.com; linux-r...@vger.kernel.org;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> Zhangping (ZP)
> Subject: Re: [PATCH for-next 03/11] IB/hns: Optimize the logic of
> allocating memory using APIs
> 
> On Mon, Nov 21, 2016 at 04:12:38PM +, Salil Mehta wrote:
> > > -Original Message-
> > > From: Leon Romanovsky [mailto:l...@kernel.org]
> > > Sent: Wednesday, November 16, 2016 8:36 AM
> > > To: Salil Mehta
> > > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun;
> > > mehta.salil@gmail.com; linux-r...@vger.kernel.org;
> > > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> > > Zhangping (ZP)
> > > Subject: Re: [PATCH for-next 03/11] IB/hns: Optimize the logic of
> > > allocating memory using APIs
> > >
> > > On Tue, Nov 15, 2016 at 03:52:46PM +, Salil Mehta wrote:
> > > > > -Original Message-
> > > > > From: Leon Romanovsky [mailto:l...@kernel.org]
> > > > > Sent: Wednesday, November 09, 2016 7:22 AM
> > > > > To: Salil Mehta
> > > > > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun;
> > > > > mehta.salil@gmail.com; linux-r...@vger.kernel.org;
> > > > > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> > > > > Zhangping (ZP)
> > > > > Subject: Re: [PATCH for-next 03/11] IB/hns: Optimize the logic
> of
> > > > > allocating memory using APIs
> > > > >
> > > > > On Fri, Nov 04, 2016 at 04:36:25PM +, Salil Mehta wrote:
> > > > > > From: "Wei Hu (Xavier)" 
> > > > > >
> > > > > > This patch modified the logic of allocating memory using APIs
> in
> > > > > > hns RoCE driver. We used kcalloc instead of kmalloc_array and
> > > > > > bitmap_zero. And When kcalloc failed, call vzalloc to alloc
> > > > > > memory.
> > > > > >
> > > > > > Signed-off-by: Wei Hu (Xavier) 
> > > > > > Signed-off-by: Ping Zhang 
> > > > > > Signed-off-by: Salil Mehta  
> > > > > > ---
> > > > > >  drivers/infiniband/hw/hns/hns_roce_mr.c |   15 -
> --
> > > > > >  1 file changed, 8 insertions(+), 7 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > > b/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > > > index fb87883..d3dfb5f 100644
> > > > > > --- a/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > > > +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> > > > > > @@ -137,11 +137,12 @@ static int hns_roce_buddy_init(struct
> > > > > hns_roce_buddy *buddy, int max_order)
> > > > > >
> > > > > > for (i = 0; i <= buddy->max_order; ++i) {
> > > > > > s = BITS_TO_LONGS(1 << (buddy->max_order - i));
> > > > > > -   buddy->bits[i] = kmalloc_array(s, sizeof(long),
> > > > > GFP_KERNEL);
> > > > > > -   if (!buddy->bits[i])
> > > > > > -   goto err_out_free;
> > > > > > -
> > > > > > -   bitmap_zero(buddy->bits[i], 1 << (buddy->max_order -
> > > i));
> > > > > > +   buddy->bits[i] = kcalloc(s, sizeof(long),
> > > GFP_KERNEL);
> > > > > > +   if (!buddy->bits[i]) {
> > > > > > +   buddy->bits[i] = vzalloc(s * sizeof(long));
> > > > >
> > > > > I wonder, why don't you use directly vzalloc instead of kcalloc
> > > > > fallback?
> > > > As we know we will have physical contiguous pages if the kcalloc
> > > > call succeeds. This will give us a chance to have better
> performance
> > > > over the allocations which are just virtually contiguous through
> the
> > > > function vzalloc(). Therefore, later has only been used as a
> fallback
> > > > when our memory request cannot be entertained through kcalloc.
> > > >
> > > > Are you suggesting that there wi

[PATCH for-next 01/11] IB/hns: Add the interface for querying QP1

2016-11-04 Thread Salil Mehta
From: Lijun Ou 

In old code, It only added the interface for querying non-specific
QP. This patch mainly adds an interface for querying QP1.

Signed-off-by: Lijun Ou 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |   87 +++-
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h |6 +-
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 71232e5..ca8b784 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2630,8 +2630,82 @@ static int hns_roce_v1_query_qpc(struct hns_roce_dev 
*hr_dev,
return ret;
 }
 
-int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
-int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+static int hns_roce_v1_q_sqp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+int qp_attr_mask,
+struct ib_qp_init_attr *qp_init_attr)
+{
+   struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+   struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+   struct hns_roce_sqp_context *context;
+   u32 addr;
+
+   context = kzalloc(sizeof(*context), GFP_KERNEL);
+   if (!context)
+   return -ENOMEM;
+
+   mutex_lock(&hr_qp->mutex);
+
+   if (hr_qp->state == IB_QPS_RESET) {
+   qp_attr->qp_state = IB_QPS_RESET;
+   goto done;
+   }
+
+   addr = ROCEE_QP1C_CFG0_0_REG + hr_qp->port * sizeof(*context);
+   context->qp1c_bytes_4 = roce_read(hr_dev, addr);
+   context->sq_rq_bt_l = roce_read(hr_dev, addr + 1);
+   context->qp1c_bytes_12 = roce_read(hr_dev, addr + 2);
+   context->qp1c_bytes_16 = roce_read(hr_dev, addr + 3);
+   context->qp1c_bytes_20 = roce_read(hr_dev, addr + 4);
+   context->cur_rq_wqe_ba_l = roce_read(hr_dev, addr + 5);
+   context->qp1c_bytes_28 = roce_read(hr_dev, addr + 6);
+   context->qp1c_bytes_32 = roce_read(hr_dev, addr + 7);
+   context->cur_sq_wqe_ba_l = roce_read(hr_dev, addr + 8);
+   context->qp1c_bytes_40 = roce_read(hr_dev, addr + 9);
+
+   hr_qp->state = roce_get_field(context->qp1c_bytes_4,
+ QP1C_BYTES_4_QP_STATE_M,
+ QP1C_BYTES_4_QP_STATE_S);
+   qp_attr->qp_state   = hr_qp->state;
+   qp_attr->path_mtu   = IB_MTU_256;
+   qp_attr->path_mig_state = IB_MIG_ARMED;
+   qp_attr->qkey   = QKEY_VAL;
+   qp_attr->rq_psn = 0;
+   qp_attr->sq_psn = 0;
+   qp_attr->dest_qp_num= 1;
+   qp_attr->qp_access_flags = 6;
+
+   qp_attr->pkey_index = roce_get_field(context->qp1c_bytes_20,
+QP1C_BYTES_20_PKEY_IDX_M,
+QP1C_BYTES_20_PKEY_IDX_S);
+   qp_attr->port_num = hr_qp->port + 1;
+   qp_attr->sq_draining = 0;
+   qp_attr->max_rd_atomic = 0;
+   qp_attr->max_dest_rd_atomic = 0;
+   qp_attr->min_rnr_timer = 0;
+   qp_attr->timeout = 0;
+   qp_attr->retry_cnt = 0;
+   qp_attr->rnr_retry = 0;
+   qp_attr->alt_timeout = 0;
+
+done:
+   qp_attr->cur_qp_state = qp_attr->qp_state;
+   qp_attr->cap.max_recv_wr = hr_qp->rq.wqe_cnt;
+   qp_attr->cap.max_recv_sge = hr_qp->rq.max_gs;
+   qp_attr->cap.max_send_wr = hr_qp->sq.wqe_cnt;
+   qp_attr->cap.max_send_sge = hr_qp->sq.max_gs;
+   qp_attr->cap.max_inline_data = 0;
+   qp_init_attr->cap = qp_attr->cap;
+   qp_init_attr->create_flags = 0;
+
+   mutex_unlock(&hr_qp->mutex);
+   kfree(context);
+
+   return 0;
+}
+
+static int hns_roce_v1_q_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+   int qp_attr_mask,
+   struct ib_qp_init_attr *qp_init_attr)
 {
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
@@ -2767,6 +2841,15 @@ int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct 
ib_qp_attr *qp_attr,
return ret;
 }
 
+int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+{
+   struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+
+   return hr_qp->doorbell_qpn <= 1 ?
+   hns_roce_v1_q_sqp(ibqp, qp_attr, qp_attr_mask, qp_init_attr) :
+   hns_roce_v1_q_qp(ibqp, qp_attr, qp_attr_mask, qp_init_attr);
+}
 static void hns_roce_v1_destroy_qp_common(struct hns_roce_dev *hr_dev,
  struct hns_roce_qp *hr_qp,
 

[PATCH for-next 05/11] IB/hns: Modify the condition of notifying hardware loopback

2016-11-04 Thread Salil Mehta
From: Lijun Ou 

This patch modified the condition of notifying hardware loopback.

In hip06, RoCE Engine has several ports, one QP is related
to one port. hardware only support loopback in the same port,
not in the different ports.

So, If QP related to port N, the dmac in the QP context equals
the smac of the local port N or the loop_idc is 1, we should
set loopback bit in QP context to notify hardware.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Lijun Ou 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |   24 +++-
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index d6df6dd..8ca36a7 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2244,24 +2244,14 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const 
struct ib_qp_attr *attr,
 QP_CONTEXT_QPC_BYTE_32_SIGNALING_TYPE_S,
 hr_qp->sq_signal_bits);
 
-   for (port = 0; port < hr_dev->caps.num_ports; port++) {
-   smac = (u8 *)hr_dev->dev_addr[port];
-   dev_dbg(dev, "smac: %2x: %2x: %2x: %2x: %2x: %2x\n",
-   smac[0], smac[1], smac[2], smac[3], smac[4],
-   smac[5]);
-   if ((dmac[0] == smac[0]) && (dmac[1] == smac[1]) &&
-   (dmac[2] == smac[2]) && (dmac[3] == smac[3]) &&
-   (dmac[4] == smac[4]) && (dmac[5] == smac[5])) {
-   roce_set_bit(context->qpc_bytes_32,
-   QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S,
-   1);
-   break;
-   }
-   }
-
-   if (hr_dev->loop_idc == 0x1)
+   port = (attr_mask & IB_QP_PORT) ? (attr->port_num - 1) :
+   hr_qp->port;
+   smac = (u8 *)hr_dev->dev_addr[port];
+   /* when dmac equals smac or loop_idc is 1, it should loopback */
+   if (ether_addr_equal_unaligned(dmac, smac) ||
+   hr_dev->loop_idc == 0x1)
roce_set_bit(context->qpc_bytes_32,
-   QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S, 1);
+ QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S, 1);
 
roce_set_bit(context->qpc_bytes_32,
 QP_CONTEXT_QPC_BYTE_32_GLOBAL_HEADER_S,
-- 
1.7.9.5




[PATCH for-next 08/11] IB/hns: Modify query info named port_num when querying RC QP

2016-11-04 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch modified the output query info qp_attr->port_num
to fix bug in hip06.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index c39a9b2..76edebe 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2861,9 +2861,7 @@ static int hns_roce_v1_q_qp(struct ib_qp *ibqp, struct 
ib_qp_attr *qp_attr,
qp_attr->pkey_index = roce_get_field(context->qpc_bytes_12,
  QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
  QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S);
-   qp_attr->port_num = (u8)roce_get_field(context->qpc_bytes_156,
-QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
-QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S) + 1;
+   qp_attr->port_num = hr_qp->port + 1;
qp_attr->sq_draining = 0;
qp_attr->max_rd_atomic = roce_get_field(context->qpc_bytes_156,
 QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M,
-- 
1.7.9.5




[PATCH for-next 03/11] IB/hns: Optimize the logic of allocating memory using APIs

2016-11-04 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch modified the logic of allocating memory using APIs in
hns RoCE driver. We used kcalloc instead of kmalloc_array and
bitmap_zero. And When kcalloc failed, call vzalloc to alloc
memory.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Ping Zhang 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_mr.c |   15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c 
b/drivers/infiniband/hw/hns/hns_roce_mr.c
index fb87883..d3dfb5f 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -137,11 +137,12 @@ static int hns_roce_buddy_init(struct hns_roce_buddy 
*buddy, int max_order)
 
for (i = 0; i <= buddy->max_order; ++i) {
s = BITS_TO_LONGS(1 << (buddy->max_order - i));
-   buddy->bits[i] = kmalloc_array(s, sizeof(long), GFP_KERNEL);
-   if (!buddy->bits[i])
-   goto err_out_free;
-
-   bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
+   buddy->bits[i] = kcalloc(s, sizeof(long), GFP_KERNEL);
+   if (!buddy->bits[i]) {
+   buddy->bits[i] = vzalloc(s * sizeof(long));
+   if (!buddy->bits[i])
+   goto err_out_free;
+   }
}
 
set_bit(0, buddy->bits[buddy->max_order]);
@@ -151,7 +152,7 @@ static int hns_roce_buddy_init(struct hns_roce_buddy 
*buddy, int max_order)
 
 err_out_free:
for (i = 0; i <= buddy->max_order; ++i)
-   kfree(buddy->bits[i]);
+   kvfree(buddy->bits[i]);
 
 err_out:
kfree(buddy->bits);
@@ -164,7 +165,7 @@ static void hns_roce_buddy_cleanup(struct hns_roce_buddy 
*buddy)
int i;
 
for (i = 0; i <= buddy->max_order; ++i)
-   kfree(buddy->bits[i]);
+   kvfree(buddy->bits[i]);
 
kfree(buddy->bits);
kfree(buddy->num_free);
-- 
1.7.9.5




[PATCH for-next 06/11] IB/hns: Fix the bug for qp state in hns_roce_v1_m_qp()

2016-11-04 Thread Salil Mehta
From: Lijun Ou 

In old code, the value of qp state from qpc was assigned for
attr->qp_state. The value may be an error while attr_mask &
IB_QP_STATE is zero.

Signed-off-by: Lijun Ou 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 8ca36a7..2d48406 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -2571,7 +2571,7 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const 
struct ib_qp_attr *attr,
/* Every status migrate must change state */
roce_set_field(context->qpc_bytes_144,
   QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
-  QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, attr->qp_state);
+  QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, new_state);
 
/* SW pass context to HW */
ret = hns_roce_v1_qp_modify(hr_dev, &hr_qp->mtt,
-- 
1.7.9.5




[PATCH for-next 04/11] IB/hns: add self loopback for CM

2016-11-04 Thread Salil Mehta
From: Lijun Ou 

This patch mainly adds self loopback support for CM.

Signed-off-by: Lijun Ou 
Signed-off-by: Peter Chen 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |   11 +++
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h |2 ++
 2 files changed, 13 insertions(+)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 7750d0d..d6df6dd 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -32,6 +32,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include "hns_roce_common.h"
 #include "hns_roce_device.h"
@@ -72,6 +73,8 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct 
ib_send_wr *wr,
int nreq = 0;
u32 ind = 0;
int ret = 0;
+   u8 *smac;
+   int loopback;
 
if (unlikely(ibqp->qp_type != IB_QPT_GSI &&
ibqp->qp_type != IB_QPT_RC)) {
@@ -129,6 +132,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct 
ib_send_wr *wr,
   UD_SEND_WQE_U32_8_DMAC_5_M,
   UD_SEND_WQE_U32_8_DMAC_5_S,
   ah->av.mac[5]);
+
+   smac = (u8 *)hr_dev->dev_addr[qp->port];
+   loopback = ether_addr_equal_unaligned(ah->av.mac,
+ smac) ? 1 : 0;
+   roce_set_bit(ud_sq_wqe->u32_8,
+UD_SEND_WQE_U32_8_LOOPBACK_INDICATOR_S,
+loopback);
+
roce_set_field(ud_sq_wqe->u32_8,
   UD_SEND_WQE_U32_8_OPERATION_TYPE_M,
   UD_SEND_WQE_U32_8_OPERATION_TYPE_S,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index 6004c7f..cf28f1b 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -440,6 +440,8 @@ struct hns_roce_ud_send_wqe {
 #define UD_SEND_WQE_U32_8_DMAC_5_M   \
(((1UL << 8) - 1) << UD_SEND_WQE_U32_8_DMAC_5_S)
 
+#define UD_SEND_WQE_U32_8_LOOPBACK_INDICATOR_S 22
+
 #define UD_SEND_WQE_U32_8_OPERATION_TYPE_S 16
 #define UD_SEND_WQE_U32_8_OPERATION_TYPE_M   \
(((1UL << 4) - 1) << UD_SEND_WQE_U32_8_OPERATION_TYPE_S)
-- 
1.7.9.5




[PATCH for-next 10/11] IB/hns: Implement the add_gid/del_gid and optimize the GIDs management

2016-11-04 Thread Salil Mehta
From: Shaobo Xu 

IB core has implemented the calculation of GIDs and the management
of GID tables, and it is now responsible to supply query function
for GIDs. So the calculation of GIDs and the management of GID
tables in the RoCE driver is redundant.

The patch is to implement the add_gid/del_gid to set the GIDs in
the RoCE driver, remove the redundant calculation and management of
GIDs in the notifier call of the net device and the inet, and
update the query_gid.

Signed-off-by: Shaobo Xu 
Reviewed-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_device.h |2 -
 drivers/infiniband/hw/hns/hns_roce_main.c   |  270 +--
 2 files changed, 48 insertions(+), 224 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index 593a42a..9ef1cc3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -429,8 +429,6 @@ struct hns_roce_ib_iboe {
struct net_device  *netdevs[HNS_ROCE_MAX_PORTS];
struct notifier_block   nb;
struct notifier_block   nb_inet;
-   /* 16 GID is shared by 6 port in v1 engine. */
-   union ib_gidgid_table[HNS_ROCE_MAX_GID_NUM];
u8  phy_port[HNS_ROCE_MAX_PORTS];
 };
 
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c 
b/drivers/infiniband/hw/hns/hns_roce_main.c
index 6770171..795ef97 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -35,52 +35,13 @@
 #include 
 #include 
 #include 
+#include 
 #include "hns_roce_common.h"
 #include "hns_roce_device.h"
 #include "hns_roce_user.h"
 #include "hns_roce_hem.h"
 
 /**
- * hns_roce_addrconf_ifid_eui48 - Get default gid.
- * @eui: eui.
- * @vlan_id:  gid
- * @dev:  net device
- * Description:
- *MAC convert to GID
- *gid[0..7] = fe80   
- *gid[8] = mac[0] ^ 2
- *gid[9] = mac[1]
- *gid[10] = mac[2]
- *gid[11] = ff(VLAN ID high byte (4 MS bits))
- *gid[12] = fe(VLAN ID low byte)
- *gid[13] = mac[3]
- *gid[14] = mac[4]
- *gid[15] = mac[5]
- */
-static void hns_roce_addrconf_ifid_eui48(u8 *eui, u16 vlan_id,
-struct net_device *dev)
-{
-   memcpy(eui, dev->dev_addr, 3);
-   memcpy(eui + 5, dev->dev_addr + 3, 3);
-   if (vlan_id < 0x1000) {
-   eui[3] = vlan_id >> 8;
-   eui[4] = vlan_id & 0xff;
-   } else {
-   eui[3] = 0xff;
-   eui[4] = 0xfe;
-   }
-   eui[0] ^= 2;
-}
-
-static void hns_roce_make_default_gid(struct net_device *dev, union ib_gid 
*gid)
-{
-   memset(gid, 0, sizeof(*gid));
-   gid->raw[0] = 0xFE;
-   gid->raw[1] = 0x80;
-   hns_roce_addrconf_ifid_eui48(&gid->raw[8], 0x, dev);
-}
-
-/**
  * hns_get_gid_index - Get gid index.
  * @hr_dev: pointer to structure hns_roce_dev.
  * @port:  port, value range: 0 ~ MAX
@@ -96,30 +57,6 @@ int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, 
int gid_index)
return gid_index * hr_dev->caps.num_ports + port;
 }
 
-static int hns_roce_set_gid(struct hns_roce_dev *hr_dev, u8 port, int 
gid_index,
-union ib_gid *gid)
-{
-   struct device *dev = &hr_dev->pdev->dev;
-   u8 gid_idx = 0;
-
-   if (gid_index >= hr_dev->caps.gid_table_len[port]) {
-   dev_err(dev, "gid_index %d illegal, port %d gid range: 0~%d\n",
-   gid_index, port, hr_dev->caps.gid_table_len[port] - 1);
-   return -EINVAL;
-   }
-
-   gid_idx = hns_get_gid_index(hr_dev, port, gid_index);
-
-   if (!memcmp(gid, &hr_dev->iboe.gid_table[gid_idx], sizeof(*gid)))
-   return -EINVAL;
-
-   memcpy(&hr_dev->iboe.gid_table[gid_idx], gid, sizeof(*gid));
-
-   hr_dev->hw->set_gid(hr_dev, port, gid_index, gid);
-
-   return 0;
-}
-
 static void hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr)
 {
u8 phy_port;
@@ -147,15 +84,44 @@ static void hns_roce_set_mtu(struct hns_roce_dev *hr_dev, 
u8 port, int mtu)
hr_dev->hw->set_mtu(hr_dev, phy_port, tmp);
 }
 
-static void hns_roce_update_gids(struct hns_roce_dev *hr_dev, int port)
+static int hns_roce_add_gid(struct ib_device *device, u8 port_num,
+   unsigned int index, const union ib_gid *gid,
+   const struct ib_gid_attr *attr, void **context)
+{
+   struct hns_roce_dev *hr_dev = to_hr_dev(device);
+   u8 port = port_num - 1;
+   unsigned long flags;
+
+   if (port >= hr_dev->caps.num_ports)
+   return -EINVAL;
+
+   spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+
+   hr_dev->hw

[PATCH for-next 11/11] IB/hns: Fix for Checkpatch.pl comment style errors

2016-11-04 Thread Salil Mehta
This patch correct the comment style errors caught by
checkpatch.pl script

Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_cmd.c|8 ++--
 drivers/infiniband/hw/hns/hns_roce_device.h |   28 +++---
 drivers/infiniband/hw/hns/hns_roce_eq.c |6 +--
 drivers/infiniband/hw/hns/hns_roce_hem.c|6 +--
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |   56 +--
 drivers/infiniband/hw/hns/hns_roce_main.c   |   28 +++---
 6 files changed, 66 insertions(+), 66 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c 
b/drivers/infiniband/hw/hns/hns_roce_cmd.c
index 2a0b6c0..8c1f7a6 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cmd.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c
@@ -216,10 +216,10 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev 
*hr_dev, u64 in_param,
goto out;
 
/*
-   * It is timeout when wait_for_completion_timeout return 0
-   * The return value is the time limit set in advance
-   * how many seconds showing
-   */
+* It is timeout when wait_for_completion_timeout return 0
+* The return value is the time limit set in advance
+* how many seconds showing
+*/
if (!wait_for_completion_timeout(&context->done,
 msecs_to_jiffies(timeout))) {
dev_err(dev, "[cmd]wait_for_completion_timeout timeout\n");
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index 9ef1cc3..e48464d 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -201,9 +201,9 @@ struct hns_roce_bitmap {
 /* Order = 0: bitmap is biggest, order = max bitmap is least (only a bit) */
 /* Every bit repesent to a partner free/used status in bitmap */
 /*
-* Initial, bits of other bitmap are all 0 except that a bit of max_order is 1
-* Bit = 1 represent to idle and available; bit = 0: not available
-*/
+ * Initial, bits of other bitmap are all 0 except that a bit of max_order is 1
+ * Bit = 1 represent to idle and available; bit = 0: not available
+ */
 struct hns_roce_buddy {
/* Members point to every order level bitmap */
unsigned long **bits;
@@ -365,25 +365,25 @@ struct hns_roce_cmdq {
struct mutexhcr_mutex;
struct semaphorepoll_sem;
/*
-   * Event mode: cmd register mutex protection,
-   * ensure to not exceed max_cmds and user use limit region
-   */
+* Event mode: cmd register mutex protection,
+* ensure to not exceed max_cmds and user use limit region
+*/
struct semaphoreevent_sem;
int max_cmds;
spinlock_t  context_lock;
int free_head;
struct hns_roce_cmd_context *context;
/*
-   * Result of get integer part
-   * which max_comds compute according a power of 2
-   */
+* Result of get integer part
+* which max_comds compute according a power of 2
+*/
u16 token_mask;
/*
-   * Process whether use event mode, init default non-zero
-   * After the event queue of cmd event ready,
-   * can switch into event mode
-   * close device, switch into poll mode(non event mode)
-   */
+* Process whether use event mode, init default non-zero
+* After the event queue of cmd event ready,
+* can switch into event mode
+* close device, switch into poll mode(non event mode)
+*/
u8  use_events;
u8  toggle;
 };
diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c 
b/drivers/infiniband/hw/hns/hns_roce_eq.c
index 21e21b0..50f8649 100644
--- a/drivers/infiniband/hw/hns/hns_roce_eq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_eq.c
@@ -371,9 +371,9 @@ static int hns_roce_aeq_ovf_int(struct hns_roce_dev *hr_dev,
int i = 0;
 
/**
-   * AEQ overflow ECC mult bit err CEQ overflow alarm
-   * must clear interrupt, mask irq, clear irq, cancel mask operation
-   */
+* AEQ overflow ECC mult bit err CEQ overflow alarm
+* must clear interrupt, mask irq, clear irq, cancel mask operation
+*/
aeshift_val = roce_read(hr_dev, ROCEE_CAEP_AEQC_AEQE_SHIFT_REG);
 
if (roce_get_bit(aeshift_val,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c 
b/drivers/infiniband/hw/hns/hns_roce_hem.c
index 250d8f2..c5104e0 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
@@ -80,9 +80,9 @@ struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev 
*hr_dev, int npages,
--order;
 
/*
-   * Alloc memory one time. If failed, don't alloc small block
-   * memory

[PATCH for-next 09/11] IB/hns: Change qpn allocation to round-robin mode.

2016-11-04 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

When using CM to establish connections, qp number that was freed
just now will be rejected by ib core. To fix these problem, We
change qpn allocation to round-robin mode. We added the round-robin
mode for allocating resources using bitmap. We use round-robin mode
for qp number and non round-robing mode for other resources like
cq number, pd number etc.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_alloc.c  |   11 +++
 drivers/infiniband/hw/hns/hns_roce_cq.c |4 ++--
 drivers/infiniband/hw/hns/hns_roce_device.h |9 +++--
 drivers/infiniband/hw/hns/hns_roce_mr.c |2 +-
 drivers/infiniband/hw/hns/hns_roce_pd.c |5 +++--
 drivers/infiniband/hw/hns/hns_roce_qp.c |2 +-
 6 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c 
b/drivers/infiniband/hw/hns/hns_roce_alloc.c
index 863a17a..605962f 100644
--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c
+++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
@@ -61,9 +61,10 @@ int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, 
unsigned long *obj)
return ret;
 }
 
-void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj)
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj,
+ int rr)
 {
-   hns_roce_bitmap_free_range(bitmap, obj, 1);
+   hns_roce_bitmap_free_range(bitmap, obj, 1, rr);
 }
 
 int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
@@ -106,7 +107,8 @@ int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap 
*bitmap, int cnt,
 }
 
 void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
-   unsigned long obj, int cnt)
+   unsigned long obj, int cnt,
+   int rr)
 {
int i;
 
@@ -116,7 +118,8 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap 
*bitmap,
for (i = 0; i < cnt; i++)
clear_bit(obj + i, bitmap->table);
 
-   bitmap->last = min(bitmap->last, obj);
+   if (!rr)
+   bitmap->last = min(bitmap->last, obj);
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
   & bitmap->mask;
spin_unlock(&bitmap->lock);
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c 
b/drivers/infiniband/hw/hns/hns_roce_cq.c
index 461a273..c9f6c3d 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -166,7 +166,7 @@ static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, 
int nent,
hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
 
 err_out:
-   hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+   hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR);
return ret;
 }
 
@@ -204,7 +204,7 @@ static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
spin_unlock_irq(&cq_table->lock);
 
hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
-   hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+   hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR);
 }
 
 static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev,
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index 7242b14..593a42a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -72,6 +72,9 @@
 #define HNS_ROCE_MAX_GID_NUM   16
 #define HNS_ROCE_GID_SIZE  16
 
+#define BITMAP_NO_RR   0
+#define BITMAP_RR  1
+
 #define MR_TYPE_MR 0x00
 #define MR_TYPE_DMA0x03
 
@@ -661,7 +664,8 @@ int hns_roce_buf_write_mtt(struct hns_roce_dev *hr_dev,
 void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev);
 
 int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj);
-void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj);
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj,
+int rr);
 int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
 u32 reserved_bot, u32 resetrved_top);
 void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap);
@@ -669,7 +673,8 @@ int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, 
u32 num, u32 mask,
 int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
int align, unsigned long *obj);
 void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
-   unsigned long obj, int cnt);
+   

[PATCH for-next 02/11] IB/hns: Add code for refreshing CQ CI using TPTR

2016-11-04 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch added the code for refreshing CQ CI using TPTR in hip06
SoC.

We will send a doorbell to hardware for refreshing CQ CI when user
succeed to poll a cqe. But it will be failed if the doorbell has
been blocked. So hardware will read a special buffer called TPTR
to get the lastest CI value when the cq is almost full.

This patch support the special CI buffer as follows:
a) Alloc the memory for TPTR in the hns_roce_tptr_init function and
   free it in hns_roce_tptr_free function, these two functions will
   be called in probe function and in the remove function.
b) Add the code for computing offset(every cq need 2 bytes) and
   write the dma addr to every cq context to notice hardware in the
   function named hns_roce_v1_write_cqc.
c) Add code for mapping TPTR buffer to user space in function named
   hns_roce_mmap. The mapping distinguish TPTR and UAR of user mode
   by vm_pgoff(0: UAR, 1: TPTR, others:invaild) in hip06.
d) Alloc the code for refreshing CQ CI using TPTR in the function
   named hns_roce_v1_poll_cq.
e) Add some variable definitions to the related structure.

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Dongdong Huang(Donald) 
Signed-off-by: Lijun Ou 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_common.h |2 -
 drivers/infiniband/hw/hns/hns_roce_cq.c |9 +++
 drivers/infiniband/hw/hns/hns_roce_device.h |6 +-
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |   79 ---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h  |9 +++
 drivers/infiniband/hw/hns/hns_roce_main.c   |   13 -
 6 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h 
b/drivers/infiniband/hw/hns/hns_roce_common.h
index 2970161..0dcb620 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -253,8 +253,6 @@
 #define ROCEE_VENDOR_ID_REG0x0
 #define ROCEE_VENDOR_PART_ID_REG   0x4
 
-#define ROCEE_HW_VERSION_REG   0x8
-
 #define ROCEE_SYS_IMAGE_GUID_L_REG 0xC
 #define ROCEE_SYS_IMAGE_GUID_H_REG 0x10
 
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c 
b/drivers/infiniband/hw/hns/hns_roce_cq.c
index 0973659..5dc8d92 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -349,6 +349,15 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device 
*ib_dev,
goto err_mtt;
}
 
+   /*
+* For the QP created by kernel space, tptr value should be initialized
+* to zero; For the QP created by user space, it will cause synchronous
+* problems if tptr is set to zero here, so we initialze it in user
+* space.
+*/
+   if (!context)
+   *hr_cq->tptr_addr = 0;
+
/* Get created cq handler and carry out event */
hr_cq->comp = hns_roce_ib_cq_comp;
hr_cq->event = hns_roce_ib_cq_event;
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index 3417315..7242b14 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -37,6 +37,8 @@
 
 #define DRV_NAME "hns_roce"
 
+#define HNS_ROCE_HW_VER1   ('h' << 24 | 'i' << 16 | '0' << 8 | '6')
+
 #define MAC_ADDR_OCTET_NUM 6
 #define HNS_ROCE_MAX_MSG_LEN   0x8000
 
@@ -296,7 +298,7 @@ struct hns_roce_cq {
u32 cq_depth;
u32 cons_index;
void __iomem*cq_db_l;
-   void __iomem*tptr_addr;
+   u16 *tptr_addr;
unsigned long   cqn;
u32 vector;
atomic_trefcount;
@@ -553,6 +555,8 @@ struct hns_roce_dev {
 
int cmd_mod;
int loop_idc;
+   dma_addr_t  tptr_dma_addr; /*only for hw v1*/
+   u32 tptr_size; /*only for hw v1*/
struct hns_roce_hw  *hw;
 };
 
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index ca8b784..7750d0d 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -849,6 +849,45 @@ static void hns_roce_bt_free(struct hns_roce_dev *hr_dev)
priv->bt_table.qpc_buf.buf, priv->bt_table.qpc_buf.map);
 }
 
+static int hns_roce_tptr_init(struct hns_roce_dev *hr_dev)
+{
+   struct device *dev = &hr_dev->pdev->dev;
+   struct hns_roce_buf_list *tptr_buf;
+   struct hns_roce_v1_priv *priv;
+
+   priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+   tptr_buf = &

[PATCH for-next 07/11] IB/hns: Modify the macro for the timeout when cmd process

2016-11-04 Thread Salil Mehta
From: "Wei Hu (Xavier)" 

This patch modified the macro for the timeout when cmd is
processing as follows:
Before modification:
 enum {
HNS_ROCE_CMD_TIME_CLASS_A   = 1,
HNS_ROCE_CMD_TIME_CLASS_B   = 1,
HNS_ROCE_CMD_TIME_CLASS_C   = 1,
 };
After modification:
 #define HNS_ROCE_CMD_TIMEOUT_MSECS 1

Signed-off-by: Wei Hu (Xavier) 
Signed-off-by: Salil Mehta  
---
 drivers/infiniband/hw/hns/hns_roce_cmd.h   |7 +--
 drivers/infiniband/hw/hns/hns_roce_cq.c|4 ++--
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |8 
 drivers/infiniband/hw/hns/hns_roce_mr.c|4 ++--
 4 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.h 
b/drivers/infiniband/hw/hns/hns_roce_cmd.h
index e3997d3..ed14ad3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cmd.h
+++ b/drivers/infiniband/hw/hns/hns_roce_cmd.h
@@ -34,6 +34,7 @@
 #define _HNS_ROCE_CMD_H
 
 #define HNS_ROCE_MAILBOX_SIZE  4096
+#define HNS_ROCE_CMD_TIMEOUT_MSECS 1
 
 enum {
/* TPT commands */
@@ -57,12 +58,6 @@ enum {
HNS_ROCE_CMD_QUERY_QP   = 0x22,
 };
 
-enum {
-   HNS_ROCE_CMD_TIME_CLASS_A   = 1,
-   HNS_ROCE_CMD_TIME_CLASS_B   = 1,
-   HNS_ROCE_CMD_TIME_CLASS_C   = 1,
-};
-
 struct hns_roce_cmd_mailbox {
void   *buf;
dma_addr_t  dma;
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c 
b/drivers/infiniband/hw/hns/hns_roce_cq.c
index 5dc8d92..461a273 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -77,7 +77,7 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev,
 unsigned long cq_num)
 {
return hns_roce_cmd_mbox(dev, mailbox->dma, 0, cq_num, 0,
-   HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIME_CLASS_A);
+   HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIMEOUT_MSECS);
 }
 
 static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
@@ -176,7 +176,7 @@ static int hns_roce_hw2sw_cq(struct hns_roce_dev *dev,
 {
return hns_roce_cmd_mbox(dev, 0, mailbox ? mailbox->dma : 0, cq_num,
 mailbox ? 0 : 1, HNS_ROCE_CMD_HW2SW_CQ,
-HNS_ROCE_CMD_TIME_CLASS_A);
+HNS_ROCE_CMD_TIMEOUT_MSECS);
 }
 
 static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 2d48406..c39a9b2 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -1871,12 +1871,12 @@ static int hns_roce_v1_qp_modify(struct hns_roce_dev 
*hr_dev,
if (op[cur_state][new_state] == HNS_ROCE_CMD_2RST_QP)
return hns_roce_cmd_mbox(hr_dev, 0, 0, hr_qp->qpn, 2,
 HNS_ROCE_CMD_2RST_QP,
-HNS_ROCE_CMD_TIME_CLASS_A);
+HNS_ROCE_CMD_TIMEOUT_MSECS);
 
if (op[cur_state][new_state] == HNS_ROCE_CMD_2ERR_QP)
return hns_roce_cmd_mbox(hr_dev, 0, 0, hr_qp->qpn, 2,
 HNS_ROCE_CMD_2ERR_QP,
-HNS_ROCE_CMD_TIME_CLASS_A);
+HNS_ROCE_CMD_TIMEOUT_MSECS);
 
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
if (IS_ERR(mailbox))
@@ -1886,7 +1886,7 @@ static int hns_roce_v1_qp_modify(struct hns_roce_dev 
*hr_dev,
 
ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, hr_qp->qpn, 0,
op[cur_state][new_state],
-   HNS_ROCE_CMD_TIME_CLASS_C);
+   HNS_ROCE_CMD_TIMEOUT_MSECS);
 
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
return ret;
@@ -2681,7 +2681,7 @@ static int hns_roce_v1_query_qpc(struct hns_roce_dev 
*hr_dev,
 
ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, hr_qp->qpn, 0,
HNS_ROCE_CMD_QUERY_QP,
-   HNS_ROCE_CMD_TIME_CLASS_A);
+   HNS_ROCE_CMD_TIMEOUT_MSECS);
if (!ret)
memcpy(hr_context, mailbox->buf, sizeof(*hr_context));
else
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c 
b/drivers/infiniband/hw/hns/hns_roce_mr.c
index d3dfb5f..2227962 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -53,7 +53,7 @@ static int hns_roce_sw2hw_mpt(struct hns_roce_dev *hr_dev,
 {
return hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, mpt_index, 0,
 HNS_ROCE_CMD_SW2HW_MPT,
-HNS_ROCE_CMD_TIME_CLASS_B);
+HNS_R

[PATCH for-next 00/11] Code improvements & fixes for HNS RoCE driver

2016-11-04 Thread Salil Mehta
This patchset introduces some code improvements and fixes
for the identified problems in the HNS RoCE driver.

Lijun Ou (4):
  IB/hns: Add the interface for querying QP1
  IB/hns: add self loopback for CM
  IB/hns: Modify the condition of notifying hardware loopback
  IB/hns: Fix the bug for qp state in hns_roce_v1_m_qp()

Salil Mehta (1):
  IB/hns: Fix for Checkpatch.pl comment style errors

Shaobo Xu (1):
  IB/hns: Implement the add_gid/del_gid and optimize the GIDs
management

Wei Hu (Xavier) (5):
  IB/hns: Add code for refreshing CQ CI using TPTR
  IB/hns: Optimize the logic of allocating memory using APIs
  IB/hns: Modify the macro for the timeout when cmd process
  IB/hns: Modify query info named port_num when querying RC QP
  IB/hns: Change qpn allocation to round-robin mode.

 drivers/infiniband/hw/hns/hns_roce_alloc.c  |   11 +-
 drivers/infiniband/hw/hns/hns_roce_cmd.c|8 +-
 drivers/infiniband/hw/hns/hns_roce_cmd.h|7 +-
 drivers/infiniband/hw/hns/hns_roce_common.h |2 -
 drivers/infiniband/hw/hns/hns_roce_cq.c |   17 +-
 drivers/infiniband/hw/hns/hns_roce_device.h |   45 ++--
 drivers/infiniband/hw/hns/hns_roce_eq.c |6 +-
 drivers/infiniband/hw/hns/hns_roce_hem.c|6 +-
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |  271 +--
 drivers/infiniband/hw/hns/hns_roce_hw_v1.h  |   17 +-
 drivers/infiniband/hw/hns/hns_roce_main.c   |  311 +++
 drivers/infiniband/hw/hns/hns_roce_mr.c |   21 +-
 drivers/infiniband/hw/hns/hns_roce_pd.c |5 +-
 drivers/infiniband/hw/hns/hns_roce_qp.c |2 +-
 14 files changed, 367 insertions(+), 362 deletions(-)

-- 
1.7.9.5




RE: [PATCH for-next 01/11] IB/hns: Add the interface for querying QP1

2016-11-07 Thread Salil Mehta


> -Original Message-
> From: Anurup m
> Sent: Monday, November 07, 2016 5:46 AM
> To: Salil Mehta; dledf...@redhat.com
> Cc: linux-r...@vger.kernel.org; net...@vger.kernel.org;
> mehta.salil@gmail.com; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH for-next 01/11] IB/hns: Add the interface for
> querying QP1
> 
> 
> 
> On 11/4/2016 10:06 PM, Salil Mehta wrote:
> > From: Lijun Ou 
> >
> > In old code, It only added the interface for querying non-specific
> > QP. This patch mainly adds an interface for querying QP1.
> >
> > Signed-off-by: Lijun Ou 
> > Reviewed-by: Wei Hu (Xavier) 
> > Signed-off-by: Salil Mehta  
> > ---
> >  drivers/infiniband/hw/hns/hns_roce_hw_v1.c |   87
> +++-
> >  drivers/infiniband/hw/hns/hns_roce_hw_v1.h |6 +-
> >  2 files changed, 90 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> > index 71232e5..ca8b784 100644
> > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> > @@ -2630,8 +2630,82 @@ static int hns_roce_v1_query_qpc(struct
> hns_roce_dev *hr_dev,
> > return ret;
> >  }
> >
> > -int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr
> *qp_attr,
> > -int qp_attr_mask, struct ib_qp_init_attr
> *qp_init_attr)
> > +static int hns_roce_v1_q_sqp(struct ib_qp *ibqp, struct ib_qp_attr
> *qp_attr,
> > +int qp_attr_mask,
> > +struct ib_qp_init_attr *qp_init_attr)
> > +{
> > +   struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
> > +   struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
> > +   struct hns_roce_sqp_context *context;
> > +   u32 addr;
> > +
> > +   context = kzalloc(sizeof(*context), GFP_KERNEL);
> > +   if (!context)
> > +   return -ENOMEM;
> > +
> Do we really need dynamic alloc here as the size is fixed and this
> memory scope is
> only inside this function. I think better to use a static allocation.
Agreed. Somehow missed this in the internal review. Will change!

Thanks
Salil
> 
> > +   mutex_lock(&hr_qp->mutex);
> > +
> > +   if (hr_qp->state == IB_QPS_RESET) {
> I think alloc can be moved after this check (if dynamic alloc is really
> needed).
> > +   qp_attr->qp_state = IB_QPS_RESET;
> > +   goto done;
> > +   }
> > +
> > +   addr = ROCEE_QP1C_CFG0_0_REG + hr_qp->port * sizeof(*context);
> > +   context->qp1c_bytes_4 = roce_read(hr_dev, addr);
> > +   context->sq_rq_bt_l = roce_read(hr_dev, addr + 1);
> > +   context->qp1c_bytes_12 = roce_read(hr_dev, addr + 2);
> > +   context->qp1c_bytes_16 = roce_read(hr_dev, addr + 3);
> > +   context->qp1c_bytes_20 = roce_read(hr_dev, addr + 4);
> > +   context->cur_rq_wqe_ba_l = roce_read(hr_dev, addr + 5);
> > +   context->qp1c_bytes_28 = roce_read(hr_dev, addr + 6);
> > +   context->qp1c_bytes_32 = roce_read(hr_dev, addr + 7);
> > +   context->cur_sq_wqe_ba_l = roce_read(hr_dev, addr + 8);
> > +   context->qp1c_bytes_40 = roce_read(hr_dev, addr + 9);
> > +
> > +   hr_qp->state = roce_get_field(context->qp1c_bytes_4,
> > + QP1C_BYTES_4_QP_STATE_M,
> > + QP1C_BYTES_4_QP_STATE_S);
> > +   qp_attr->qp_state   = hr_qp->state;
> > +   qp_attr->path_mtu   = IB_MTU_256;
> > +   qp_attr->path_mig_state = IB_MIG_ARMED;
> > +   qp_attr->qkey   = QKEY_VAL;
> > +   qp_attr->rq_psn = 0;
> > +   qp_attr->sq_psn = 0;
> > +   qp_attr->dest_qp_num= 1;
> > +   qp_attr->qp_access_flags = 6;
> > +
> > +   qp_attr->pkey_index = roce_get_field(context->qp1c_bytes_20,
> > +QP1C_BYTES_20_PKEY_IDX_M,
> > +QP1C_BYTES_20_PKEY_IDX_S);
> > +   qp_attr->port_num = hr_qp->port + 1;
> > +   qp_attr->sq_draining = 0;
> > +   qp_attr->max_rd_atomic = 0;
> > +   qp_attr->max_dest_rd_atomic = 0;
> > +   qp_attr->min_rnr_timer = 0;
> > +   qp_attr->timeout = 0;
> > +   qp_attr->retry_cnt = 0;
> > +   qp_attr->rnr_retry = 0;
> > +   qp_attr->alt_timeout = 0;
> > +
> > +done:
> > +   qp_attr->cur_qp_state = qp_attr->qp_state;
> > +   qp_attr->cap.max_recv_wr = hr_qp->rq.wqe_cnt;
>

[PATCH net] net: hns: Fix the device being used for dma mapping during TX

2017-02-09 Thread Salil Mehta
From: Kejian Yan 

This patch fixes the device being used to DMA map skb->data.
Erroneous device assignment causes the crash when SMMU is enabled.
This happens during TX since buffer gets DMA mapped with device
correspondign to net_device and gets unmapped using the device
related to DSAF.

Signed-off-by: Kejian Yan 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 672b646..2b52a12 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -305,7 +305,7 @@ int hns_nic_net_xmit_hw(struct net_device *ndev,
struct hns_nic_ring_data *ring_data)
 {
struct hns_nic_priv *priv = netdev_priv(ndev);
-   struct device *dev = priv->dev;
+   struct device *dev = ring_to_dev(ring_data->ring);
struct hnae_ring *ring = ring_data->ring;
struct netdev_queue *dev_queue;
struct skb_frag_struct *frag;
-- 
1.7.9.5




RE: [PATCH net] net: hns: Fix the device being used for dma mapping during TX

2017-02-09 Thread Salil Mehta
> -Original Message-
> From: YUAN Linyu [mailto:linyu.y...@alcatel-sbell.com.cn]
> Sent: Thursday, February 09, 2017 9:36 AM
> To: Salil Mehta; da...@davemloft.net
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> Yankejian (Hackim Yim)
> Subject: RE: [PATCH net] net: hns: Fix the device being used for dma
> mapping during TX
> 
> 
> 
> > -Original Message-
> > From: netdev-ow...@vger.kernel.org [mailto:netdev-
> ow...@vger.kernel.org]
> > On Behalf Of Salil Mehta
> > Sent: Thursday, February 09, 2017 5:24 PM
> > To: da...@davemloft.net
> > Cc: salil.me...@huawei.com; yisen.zhu...@huawei.com;
> > mehta.salil@gmail.com; net...@vger.kernel.org;
> > linux-kernel@vger.kernel.org; linux...@huawei.com; Kejian Yan
> > Subject: [PATCH net] net: hns: Fix the device being used for dma
> mapping during
> > TX
> >
> > From: Kejian Yan 
> >
> > This patch fixes the device being used to DMA map skb->data.
> > Erroneous device assignment causes the crash when SMMU is enabled.
> > This happens during TX since buffer gets DMA mapped with device
> > correspondign to net_device and gets unmapped using the device
> > related to DSAF.
> >
> > Signed-off-by: Kejian Yan 
> > Reviewed-by: Yisen Zhuang 
> > Signed-off-by: Salil Mehta 
> > ---
> >  drivers/net/ethernet/hisilicon/hns/hns_enet.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > index 672b646..2b52a12 100644
> > --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > @@ -305,7 +305,7 @@ int hns_nic_net_xmit_hw(struct net_device *ndev,
> > struct hns_nic_ring_data *ring_data)
> >  {
> > struct hns_nic_priv *priv = netdev_priv(ndev);
> > -   struct device *dev = priv->dev;
> > +   struct device *dev = ring_to_dev(ring_data->ring);
> > struct hnae_ring *ring = ring_data->ring;
> struct device *dev = ring_to_dev(ring); ??
Yes, name of the macro is slight misnomer but this gets the dsaf device.
Hope this answers your question?

Thanks
Salil
> > struct netdev_queue *dev_queue;
> > struct skb_frag_struct *frag;
> > --
> > 1.7.9.5
> >



RE: [PATCH net] net: hns: Fix the device being used for dma mapping during TX

2017-02-09 Thread Salil Mehta
> -Original Message-
> From: Salil Mehta
> Sent: Thursday, February 09, 2017 9:48 AM
> To: 'YUAN Linyu'; da...@davemloft.net
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> Yankejian (Hackim Yim)
> Subject: RE: [PATCH net] net: hns: Fix the device being used for dma
> mapping during TX
> 
> > -Original Message-
> > From: YUAN Linyu [mailto:linyu.y...@alcatel-sbell.com.cn]
> > Sent: Thursday, February 09, 2017 9:36 AM
> > To: Salil Mehta; da...@davemloft.net
> > Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm;
> > Yankejian (Hackim Yim)
> > Subject: RE: [PATCH net] net: hns: Fix the device being used for dma
> > mapping during TX
> >
> >
> >
> > > -Original Message-
> > > From: netdev-ow...@vger.kernel.org [mailto:netdev-
> > ow...@vger.kernel.org]
> > > On Behalf Of Salil Mehta
> > > Sent: Thursday, February 09, 2017 5:24 PM
> > > To: da...@davemloft.net
> > > Cc: salil.me...@huawei.com; yisen.zhu...@huawei.com;
> > > mehta.salil@gmail.com; net...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; linux...@huawei.com; Kejian Yan
> > > Subject: [PATCH net] net: hns: Fix the device being used for dma
> > mapping during
> > > TX
> > >
> > > From: Kejian Yan 
> > >
> > > This patch fixes the device being used to DMA map skb->data.
> > > Erroneous device assignment causes the crash when SMMU is enabled.
> > > This happens during TX since buffer gets DMA mapped with device
> > > correspondign to net_device and gets unmapped using the device
> > > related to DSAF.
> > >
> > > Signed-off-by: Kejian Yan 
> > > Reviewed-by: Yisen Zhuang 
> > > Signed-off-by: Salil Mehta 
> > > ---
> > >  drivers/net/ethernet/hisilicon/hns/hns_enet.c |2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > > b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > > index 672b646..2b52a12 100644
> > > --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > > +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > > @@ -305,7 +305,7 @@ int hns_nic_net_xmit_hw(struct net_device
> *ndev,
> > >   struct hns_nic_ring_data *ring_data)
> > >  {
> > >   struct hns_nic_priv *priv = netdev_priv(ndev);
> > > - struct device *dev = priv->dev;
> > > + struct device *dev = ring_to_dev(ring_data->ring);
> > >   struct hnae_ring *ring = ring_data->ring;
> > struct device *dev = ring_to_dev(ring); ??
> Yes, name of the macro is slight misnomer but this gets the dsaf
> device.
> Hope this answers your question?

I realized this lately, I think you meant below:
struct hnae_ring *ring = ring_data->ring;
struct device *dev = ring_to_dev(ring);

I will correct this and float a patch. Thanks!

Best regards
Salil
> 
> Thanks
> Salil
> > >   struct netdev_queue *dev_queue;
> > >   struct skb_frag_struct *frag;
> > > --
> > > 1.7.9.5
> > >



RE: [PATCH net] net: hns: Fix the device being used for dma mapping during TX

2017-02-09 Thread Salil Mehta
> -Original Message-
> From: Lino Sanfilippo [mailto:linosanfili...@gmx.de]
> Sent: Thursday, February 09, 2017 10:25 AM
> To: Salil Mehta
> Cc: da...@davemloft.net; Salil Mehta; Zhuangyuzeng (Yisen);
> mehta.salil@gmail.com; net...@vger.kernel.org; linux-
> ker...@vger.kernel.org; Linuxarm; Yankejian (Hackim Yim)
> Subject: Re: [PATCH net] net: hns: Fix the device being used for dma
> mapping during TX
> 
> Hi,
> 
> > From: Kejian Yan 
> >
> > This patch fixes the device being used to DMA map skb->data.
> > Erroneous device assignment causes the crash when SMMU is enabled.
> > This happens during TX since buffer gets DMA mapped with device
> > correspondign to net_device and gets unmapped using the device
> > related to DSAF.
> >
> > Signed-off-by: Kejian Yan 
> > Reviewed-by: Yisen Zhuang 
> > Signed-off-by: Salil Mehta 
> > ---
> >  drivers/net/ethernet/hisilicon/hns/hns_enet.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > index 672b646..2b52a12 100644
> > --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> > @@ -305,7 +305,7 @@ int hns_nic_net_xmit_hw(struct net_device *ndev,
> > struct hns_nic_ring_data *ring_data)
> >  {
> > struct hns_nic_priv *priv = netdev_priv(ndev);
> > -   struct device *dev = priv->dev;
> > +   struct device *dev = ring_to_dev(ring_data->ring);
> > struct hnae_ring *ring = ring_data->ring;
> > struct netdev_queue *dev_queue;
> > struct skb_frag_struct *frag;
> > --
> 
> I would say it should be the other way around: Use priv->dev for
> mapping and
> unmapping instead of ring_to_dev().
Yes, you got it right. Ideally, it should be per-port and for
legacy reasons we have it this way. In the current design, we have
SMMU node per-dsaf and I guess we will not land in the right
dma-ops if we use per-netdev platform-device/device right now.

Best regards
Salil
> 
> Regards,
> Lino


[PATCH V2 net] net: hns: Fix the device being used for dma mapping during TX

2017-02-09 Thread Salil Mehta
From: Kejian Yan 

This patch fixes the device being used to DMA map skb->data.
Erroneous device assignment causes the crash when SMMU is enabled.
This happens during TX since buffer gets DMA mapped with device
correspondign to net_device and gets unmapped using the device
related to DSAF.

Signed-off-by: Kejian Yan 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
Change log:

PATCH V2: Addressed comment given by,
  Yuan Linyu 

PATCH V1: Initial submit
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 672b646..8aed728 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -305,8 +305,8 @@ int hns_nic_net_xmit_hw(struct net_device *ndev,
struct hns_nic_ring_data *ring_data)
 {
struct hns_nic_priv *priv = netdev_priv(ndev);
-   struct device *dev = priv->dev;
struct hnae_ring *ring = ring_data->ring;
+   struct device *dev = ring_to_dev(ring);
struct netdev_queue *dev_queue;
struct skb_frag_struct *frag;
int buf_num;
-- 
1.7.9.5




Re: [PATCH] net: hns: avoid uninitialized variable warning:

2016-01-06 Thread Salil Mehta


On 1/5/2016 9:43 PM, David Miller wrote:

From: Arnd Bergmann 
Date: Fri, 01 Jan 2016 23:27:57 +0100


gcc fails to see that the use of the 'last_offset' variable
in hns_nic_reuse_page() is used correctly and issues a bogus
warning:

drivers/net/ethernet/hisilicon/hns/hns_enet.c: In function 'hns_nic_reuse_page':
drivers/net/ethernet/hisilicon/hns/hns_enet.c:541:6: warning: 'last_offset' may 
be used uninitialized in this function [-Wmaybe-uninitialized]

This simplifies the function to make it more obvious what is
going on to both readers and compilers, which makes the warning
go away.

Signed-off-by: Arnd Bergmann 
---
Compile-tested only, and complex enough that this requires a proper
review and testing before it gets apply. Please have a look at this.

If this goes yet another day without being reviewed, I'm just applying
it.

You hisilicon folks can't just let patches rot, you must review them
in a timely manner or else I'm applying them without waiting for you
to look at them.

Hi David and Arnd,
Apologies for the delay in response and the review. Most of us were on 
the Annual Holidays and have just returned back.


Change looks good to me!

Best Regards
Salil


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RFC 0/4] Changes to Support *Virtual* CPU Hotplug for ARM64

2020-06-25 Thread Salil Mehta
Changes to support virtual cpu hotplug in QEMU[1] have been introduced to the
community as RFC. These are under review.

To support virtual cpu hotplug guest kernel must:
1. Identify disabled/present vcpus and set/unset the present mask of the vcpu
   during initialization and hotplug event. It must also set the possible mask
   (which includes disabled vcpus) during init of guest kernel.
2. Provide architecture specific ACPI hooks, for example to map/unmap the
   logical cpuid to hwids/MPIDR. Linux kernel already has generic ACPI cpu
   hotplug framework support.

Changes introduced in this patch-set also ensures that initialization of the
cpus when virtual cpu hotplug is not supported remains un-affected.

Repository:
(*) Kernel changes are at,
 https://github.com/salil-mehta/linux.git virt-cpuhp-arm64/rfc-v1
(*) QEMU changes for vcpu hotplug could be cloned from below site,
 https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v1


THINGS TO DO:
1. Handling of per-cpu variables especially the first-chunk allocations
   (which are NUMA aware) when the vcpu is hotplugged needs further attention
   and review.
2. NUMA related stuff has not been fully tested both in QEMU and kernel.
3. Comprehensive Testing including when cpu hotplug is not supported.
4. Docs

DISCLAIMER:
This is not a complete work but an effort to present the arm vcpu hotplug
implementation to the community. This RFC is being used as a way to verify
the idea mentioned above and to support changes presented for QEMU[1] to
support vcpu hotplug. As of now this is *not* a production level code and might
have bugs. Only a basic testing has been done on HiSilicon Kunpeng920 ARM64
based SoC for Servers to verify the proof-of-concept that has been found 
working!

Best regards
Salil.

REFERENCES:
[1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg712010.html
[2] https://lkml.org/lkml/2019/6/28/1157
[3] https://lists.cs.columbia.edu/pipermail/kvmarm/2018-July/032316.html

Organization of Patches:
[Patch 1-3]
(*) Changes required during guest boot time to support vcpu hotplug 
(*) Max cpu overflow checks
(*) Changes required to pre-setup cpu-operations even for disabled cpus
[Patch 4]
(*) Arch changes required by guest kernel ACPI CPU Hotplug framework.


Salil Mehta (4):
  arm64: kernel: Handle disabled[(+)present] cpus in MADT/GICC during
init
  arm64: kernel: Bound the total(present+disabled) cpus with nr_cpu_ids
  arm64: kernel: Init cpu operations for all possible vcpus
  arm64: kernel: Arch specific ACPI hooks(like logical cpuid<->hwid
etc.)

 arch/arm64/kernel/smp.c | 153 
 1 file changed, 123 insertions(+), 30 deletions(-)

-- 
2.17.1




[PATCH RFC 3/4] arm64: kernel: Init cpu operations for all possible vcpus

2020-06-25 Thread Salil Mehta
Currently, cpu-operations are only initialized for the cpus which
already have logical cpuid to hwid assoication established. And this
only happens for the cpus which are present during boot time.

To support virtual cpu hotplug, we shall initialze the cpu-operations
for all possible(present+disabled) vcpus. This means logical cpuid to
hwid/mpidr association might not exists(i.e. might be INVALID_HWID)
during init. Later, when the vcpu is actually hotplugged logical cpuid
is allocated and associated with the hwid/mpidr.

This patch does some refactoring to support above change.

Signed-off-by: Salil Mehta 
Signed-off-by: Xiongfeng Wang 
---
 arch/arm64/kernel/smp.c | 38 --
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 864ccd3da419..63f31ea23e55 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -503,13 +503,16 @@ static int __init smp_cpu_setup(int cpu)
const struct cpu_operations *ops;
 
if (init_cpu_ops(cpu))
-   return -ENODEV;
+   goto out;
 
ops = get_cpu_ops(cpu);
if (ops->cpu_init(cpu))
-   return -ENODEV;
+   goto out;
 
return 0;
+out:
+   cpu_logical_map(cpu) = INVALID_HWID;
+   return -ENODEV;
 }
 
 static bool bootcpu_valid __initdata;
@@ -547,7 +550,8 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", 
hwid);
 #else
cpu_madt_gicc[total_cpu_count] = *processor;
-   set_cpu_possible(total_cpu_count, true);
+   if (!smp_cpu_setup(total_cpu_count))
+   set_cpu_possible(total_cpu_count, true);
disabled_cpu_count++;
 #endif
return;
@@ -591,8 +595,11 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
 */
acpi_set_mailbox_entry(total_cpu_count, processor);
 
-   set_cpu_possible(total_cpu_count, true);
-   set_cpu_present(total_cpu_count, true);
+   if (!smp_cpu_setup(total_cpu_count)) {
+   set_cpu_possible(total_cpu_count, true);
+   set_cpu_present(total_cpu_count, true);
+   }
+
cpu_count++;
 }
 
@@ -701,8 +708,10 @@ static void __init of_parse_and_init_cpus(void)
 
early_map_cpu_to_node(cpu_count, of_node_to_nid(dn));
 
-   set_cpu_possible(cpu_count, true);
-   set_cpu_present(cpu_count, true);
+   if (!smp_cpu_setup(cpu_count)) {
+   set_cpu_possible(cpu_count, true);
+   set_cpu_present(cpu_count, true);
+   }
 next:
cpu_count++;
}
@@ -716,7 +725,6 @@ static void __init of_parse_and_init_cpus(void)
 void __init smp_init_cpus(void)
 {
unsigned int total_cpu_count = disabled_cpu_count + cpu_count;
-   int i;
 
if (acpi_disabled)
of_parse_and_init_cpus();
@@ -731,20 +739,6 @@ void __init smp_init_cpus(void)
pr_err("missing boot CPU MPIDR, not enabling secondaries\n");
return;
}
-
-   /*
-* We need to set the cpu_logical_map entries before enabling
-* the cpus so that cpu processor description entries (DT cpu nodes
-* and ACPI MADT entries) can be retrieved by matching the cpu hwid
-* with entries in cpu_logical_map while initializing the cpus.
-* If the cpu set-up fails, invalidate the cpu_logical_map entry.
-*/
-   for (i = 1; i < nr_cpu_ids; i++) {
-   if (cpu_logical_map(i) != INVALID_HWID) {
-   if (smp_cpu_setup(i))
-   cpu_logical_map(i) = INVALID_HWID;
-   }
-   }
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
-- 
2.17.1




[PATCH RFC 2/4] arm64: kernel: Bound the total(present+disabled) cpus with nr_cpu_ids

2020-06-25 Thread Salil Mehta
Bound the total number of identified cpus(including disabled cpus) by
maximum allowed limit by the kernel. Max value is either specified as
part of the kernel parameters 'nr_cpus' or specified during compile
time using CONFIG_NR_CPUS.

Signed-off-by: Salil Mehta 
Signed-off-by: Xiongfeng Wang 
---
 arch/arm64/kernel/smp.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 51a707928302..864ccd3da419 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -513,6 +513,7 @@ static int __init smp_cpu_setup(int cpu)
 }
 
 static bool bootcpu_valid __initdata;
+static bool cpus_clipped __initdata = false;
 static unsigned int cpu_count = 1;
 static unsigned int disabled_cpu_count;
 
@@ -536,6 +537,11 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
unsigned int total_cpu_count = disabled_cpu_count + cpu_count;
u64 hwid = processor->arm_mpidr;
 
+   if (total_cpu_count > nr_cpu_ids) {
+   cpus_clipped = true;
+   return;
+   }
+
if (!(processor->flags & ACPI_MADT_ENABLED)) {
 #ifndef CONFIG_ACPI_HOTPLUG_CPU
pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", 
hwid);
@@ -569,9 +575,6 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
return;
}
 
-   if (cpu_count >= NR_CPUS)
-   return;
-
/* map the logical cpu id to cpu MPIDR */
cpu_logical_map(total_cpu_count) = hwid;
 
@@ -688,8 +691,10 @@ static void __init of_parse_and_init_cpus(void)
continue;
}
 
-   if (cpu_count >= NR_CPUS)
+   if (cpu_count >= NR_CPUS) {
+   cpus_clipped = true;
goto next;
+   }
 
pr_debug("cpu logical map 0x%llx\n", hwid);
cpu_logical_map(cpu_count) = hwid;
@@ -710,6 +715,7 @@ static void __init of_parse_and_init_cpus(void)
  */
 void __init smp_init_cpus(void)
 {
+   unsigned int total_cpu_count = disabled_cpu_count + cpu_count;
int i;
 
if (acpi_disabled)
@@ -717,9 +723,9 @@ void __init smp_init_cpus(void)
else
acpi_parse_and_init_cpus();
 
-   if (cpu_count > nr_cpu_ids)
+   if (cpus_clipped)
pr_warn("Number of cores (%d) exceeds configured maximum of %u 
- clipping\n",
-   cpu_count, nr_cpu_ids);
+   total_cpu_count, nr_cpu_ids);
 
if (!bootcpu_valid) {
pr_err("missing boot CPU MPIDR, not enabling secondaries\n");
-- 
2.17.1




[PATCH RFC 4/4] arm64: kernel: Arch specific ACPI hooks(like logical cpuid<->hwid etc.)

2020-06-25 Thread Salil Mehta
To support virtual cpu hotplug, some arch specifc hooks must be
facilitated. These hooks are called by the generic ACPI cpu hotplug
framework during a vcpu hot-(un)plug event handling. The changes
required involve:

1. Allocation of the logical cpuid corresponding to the hwid/mpidr
2. Mapping of logical cpuid to hwid/mpidr and marking present
3. Removing vcpu from present mask during hot-unplug
4. For arm64, all possible cpus are registered within topology_init()
   Hence, we need to override the weak ACPI call of arch_register_cpu()
   (which returns -ENODEV) and return success.
5. NUMA node mapping set for this vcpu using SRAT Table info during init
   time will be discarded as the logical cpu-ids used at that time
   might not be correct. This mapping will be set again using the
   proximity/node info obtained by evaluating _PXM ACPI method.

Note, during hot unplug of vcpu, we do not unmap the association between
the logical cpuid and hwid/mpidr. This remains persistent.

Signed-off-by: Salil Mehta 
Signed-off-by: Xiongfeng Wang 
---
 arch/arm64/kernel/smp.c | 80 +
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 63f31ea23e55..f3315840e829 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -528,6 +528,86 @@ struct acpi_madt_generic_interrupt 
*acpi_cpu_get_madt_gicc(int cpu)
return &cpu_madt_gicc[cpu];
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+int arch_register_cpu(int num)
+{
+   return 0;
+}
+
+static int set_numa_node_for_cpu(acpi_handle handle, int cpu)
+{
+#ifdef CONFIG_ACPI_NUMA
+   int node_id;
+
+   /* will evaluate _PXM */
+   node_id = acpi_get_node(handle);
+   if (node_id != NUMA_NO_NODE)
+   set_cpu_numa_node(cpu, node_id);
+#endif
+   return 0;
+}
+
+static void unset_numa_node_for_cpu(int cpu)
+{
+#ifdef CONFIG_ACPI_NUMA
+   set_cpu_numa_node(cpu, NUMA_NO_NODE);
+#endif
+}
+
+static int allocate_logical_cpuid(u64 physid)
+{
+   int first_invalid_idx = -1;
+   bool first = true;
+   int i;
+
+   for_each_possible_cpu(i) {
+   /*
+* logical cpuid<->hwid association remains persistent once
+* established
+*/
+   if (cpu_logical_map(i) == physid)
+   return i;
+
+   if ((cpu_logical_map(i) == INVALID_HWID) && first) {
+   first_invalid_idx = i;
+   first = false;
+   }
+   }
+
+   return first_invalid_idx;
+}
+
+int acpi_unmap_cpu(int cpu)
+{
+   set_cpu_present(cpu, false);
+   unset_numa_node_for_cpu(cpu);
+
+   return 0;
+}
+
+int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id,
+int *cpuid)
+{
+   int cpu;
+
+   cpu = allocate_logical_cpuid(physid);
+   if (cpu < 0) {
+   pr_warn("Unable to map logical cpuid to physid 0x%llx\n",
+   physid);
+   return -ENOSPC;
+   }
+
+   /* map the logical cpu id to cpu MPIDR */
+   cpu_logical_map(cpu) = physid;
+   set_numa_node_for_cpu(handle, cpu);
+
+   set_cpu_present(cpu, true);
+   *cpuid = cpu;
+
+   return 0;
+}
+#endif
+
 /*
  * acpi_map_gic_cpu_interface - parse processor MADT entry
  *
-- 
2.17.1




[PATCH RFC 1/4] arm64: kernel: Handle disabled[(+)present] cpus in MADT/GICC during init

2020-06-25 Thread Salil Mehta
With ACPI enabled, cpus get identified by the presence of the GICC
entry in the MADT Table. Each GICC entry part of MADT presents cpu as
enabled or disabled. As of now, the disabled cpus are skipped as
physical cpu hotplug is not supported. These remain disabled even after
the kernel has booted.

To support virtual cpu hotplug(in which case disabled vcpus could be
hotplugged even after kernel has booted), QEMU will populate MADT Table
with appropriate details of GICC entry for each possible(present+disabled)
vcpu. Now, during the init time vcpus will be identified as present or
disabled. To achieve this, below changes have been made with respect to
the present/possible vcpu handling along with the mentioned reasoning:

1. Identify all possible(present+disabled) vcpus at boot/init time
   and set their present mask and possible mask. In the existing code,
   cpus are being marked present quite late within smp_prepare_cpus()
   function, which gets called in context to the kernel thread. Since
   the cpu hotplug is not supported, present cpus are always equal to
   the possible cpus. But with cpu hotplug enabled, this assumption is
   not true. Hence, present cpus should be marked while MADT GICC entries
   are bring parsed for each vcpu.
2. Set possible cpus to include disabled. This needs to be done now
   while parsing MADT GICC entries corresponding to each vcpu as the
   disabled vcpu info is available only at this point as for hotplug
   case possible vcpus is not equal to present vcpus.
3. We will store the parsed madt/gicc entry even for the disabled vcpus
   during init time. This is needed as some modules like PMU registers
   IRQs for each possible vcpus during init time. Therefore, a valid
   entry of the MADT GICC should be present for all possible vcpus.
4. Refactoring related to DT/OF is also done to align it with the init
   changes to support vcpu hotplug.

Signed-off-by: Salil Mehta 
Signed-off-by: Xiongfeng Wang 
---
 arch/arm64/kernel/smp.c | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index e43a8ff19f0f..51a707928302 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -509,13 +509,12 @@ static int __init smp_cpu_setup(int cpu)
if (ops->cpu_init(cpu))
return -ENODEV;
 
-   set_cpu_possible(cpu, true);
-
return 0;
 }
 
 static bool bootcpu_valid __initdata;
 static unsigned int cpu_count = 1;
+static unsigned int disabled_cpu_count;
 
 #ifdef CONFIG_ACPI
 static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS];
@@ -534,10 +533,17 @@ struct acpi_madt_generic_interrupt 
*acpi_cpu_get_madt_gicc(int cpu)
 static void __init
 acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
 {
+   unsigned int total_cpu_count = disabled_cpu_count + cpu_count;
u64 hwid = processor->arm_mpidr;
 
if (!(processor->flags & ACPI_MADT_ENABLED)) {
+#ifndef CONFIG_ACPI_HOTPLUG_CPU
pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", 
hwid);
+#else
+   cpu_madt_gicc[total_cpu_count] = *processor;
+   set_cpu_possible(total_cpu_count, true);
+   disabled_cpu_count++;
+#endif
return;
}
 
@@ -546,7 +552,7 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
return;
}
 
-   if (is_mpidr_duplicate(cpu_count, hwid)) {
+   if (is_mpidr_duplicate(total_cpu_count, hwid)) {
pr_err("duplicate CPU MPIDR 0x%llx in MADT\n", hwid);
return;
}
@@ -567,9 +573,9 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
return;
 
/* map the logical cpu id to cpu MPIDR */
-   cpu_logical_map(cpu_count) = hwid;
+   cpu_logical_map(total_cpu_count) = hwid;
 
-   cpu_madt_gicc[cpu_count] = *processor;
+   cpu_madt_gicc[total_cpu_count] = *processor;
 
/*
 * Set-up the ACPI parking protocol cpu entries
@@ -580,8 +586,10 @@ acpi_map_gic_cpu_interface(struct 
acpi_madt_generic_interrupt *processor)
 * initialize the cpu if the parking protocol is
 * the only available enable method).
 */
-   acpi_set_mailbox_entry(cpu_count, processor);
+   acpi_set_mailbox_entry(total_cpu_count, processor);
 
+   set_cpu_possible(total_cpu_count, true);
+   set_cpu_present(total_cpu_count, true);
cpu_count++;
 }
 
@@ -614,6 +622,9 @@ static void __init acpi_parse_and_init_cpus(void)
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
  acpi_parse_gic_cpu_interface, 0);
 
+   pr_debug("possible cpus(%u) present cpus(%u) disabled cpus(%u)\n",
+cpu_count+disabled_cpu_count, cpu_count, disabled_cpu_count);
+
/*
 * In ACPI, SMP and C

RE: [PATCH RFC 0/4] Changes to Support *Virtual* CPU Hotplug for ARM64

2020-07-08 Thread Salil Mehta
Hi James,
Thanks for taking time to respond. Please find my replies inline

Thanks

> From: James Morse [mailto:james.mo...@arm.com]
> Sent: Wednesday, July 8, 2020 1:30 PM
> To: Salil Mehta 
> 
> Hi Salil,
> 
> On 07/07/2020 10:52, Salil Mehta wrote:
> >> From: Salil Mehta
> 
> 
> Disambiguation: by cpu-hotplug here, you don't mean
> CONFIG_HOTPLUG_CPU backed by PSCI, which is commonly what we mean in the arm
> world. You
> mean: package hot-add. A bunch of CPUs (and maybe more) that weren't present
> at boot have
> turned up.


Exactly, and hence the terminology of the possible, present and disabled comes
from there.

Present  : which are present at boot time of the guest and were presented as
'ENABLED'(set in the flag) in the ACPI MADT Table cpu interface 
entry
 by QEMU
Disabled : which were not-present at boot time of the guest and were presented
as 'DISABLED'(not set in the flag) in the ACPI MADT Table cpu 
interface
entry by QEMU
Possible : (Present + Disabled)

This series is meant to support infrastructure to hot-(un)plug of virtual cpus
at QEMU level. It does not assumes any Hardware cpu hotplug support present at
the host machine rather it is an attempt to make virtual cpu hotplug support
fairly independent of the hardware.


> >> Changes to support virtual cpu hotplug in QEMU[1] have been introduced to 
> >> the
> >> community as RFC. These are under review.
> >>
> >> To support virtual cpu hotplug guest kernel must:
> 
> Surely number 1 is: know its a virtual machine, and that whatever needs
> doing/describing
> on a real machine, doesn't need doing or describing here...
> 
> We add support for virtual machines after support for the physical machine. Is
> anyone building hardware that supports this?


Do we really care about it if we could make virtual layer independent of the
Hardware by pre-sizing the resources(vcpus, GIC etc.) at QEMU level? :)

AFAIK, right now there is *no* known real benefit of the  physical cpu hotplug
except for some of the cases which are really hard to solve *physically* and
perhaps require more comprehensive system architecture defined, like

1. Scalable servers, where cards could be purchased to add resources and compute
   on demand. This might be useful for small to medium enterprises who would
   like to start with something small but would want to scale up in time as 
their
   business grows. You would want to keep some resources closely coupled because
   of 'N' reasons 
2. Die/SoC Hotplug, similar to above but more granular. This could be used for
   saving power as well.

Again any of above looks to be a far-fetched idea right now. 

But there are definite benefits and use-cases(as described in QEMU patches) to
support *virtual* cpu hotplug. Plus, we need to keep the way we support hotplug
consistent with x86. Yes, there are some inherent differences between APIC of 
x86
and GIC of ARM but those workaround are in the QEMU and the guest kernel is
agnostic about them and so is the host kernel. Why not let virtualizer deal
with this?

BTW, if you are aware of any physical cpu hotplug implementations then please
do let us know.


> We can assume some will exist during the lifetime of a stable-kernel. The
> stable-kernel
> will claim to support this, but in reality it will crash and burn in exciting
> ways.
> (e.g. parts of the interrupt controller in the hot-added package would need
> configuring.
> We'd either lock up during boot when we try, but its not there ... or not do
> it when the
> package is added because we assumed this was a VM)


Sure, but right now we are not even aware of the physical cpu hotplug 
requirements
(and look to be far-fetched) but *virtual* cpu hotplug requirement are very 
clear.

As far as I can tell, the changes being presented are non-intrusive to the host
and guest kernel but if there are any aspects of the patches which make you feel
otherwise then please do clarify objectively that it will make our life easier.

As such, broadly 2 types of changes are being presented in the patch:
1. Arch specific
   a. Reshuffling of the code where and how the present/disabled cpus are being
  counted and their corresponding mask set.
   b. Their cpu operations
2. Generic ACPI CPU hotplug hooks which lands in arch specific code. These must
   be implemented in any case.  

Changes in 1a. and 1b.(part of patches 01/04, 02/04, 03/04) are mere reshuffling
to be frank. And rest changes in 2. are the hooks being called by hotplug
specific framework. 

 
> I don't think linux can support this for virtual machines until it works for
> real machines
> too. We don't have a reliable way of determining we are running in a VM.


x86 supports both physical and vcpu hotplug. And I cou

RE: [PATCH V2 net-next 0/2] net: hns3: adds two VLAN feature

2020-05-28 Thread Salil Mehta
Hi Jakub/David,

> From: Jakub Kicinski [mailto:k...@kernel.org]
> Sent: Wednesday, May 27, 2020 8:31 PM
> To: tanhuazhong 
> Cc: David Miller ; net...@vger.kernel.org;
> linux-kernel@vger.kernel.org; Salil Mehta ;
> Zhuangyuzeng (Yisen) ; Linuxarm 
> Subject: Re: [PATCH V2 net-next 0/2] net: hns3: adds two VLAN feature
> 
> On Wed, 27 May 2020 10:31:59 +0800 tanhuazhong wrote:
> > Hi, Jakub & David.
> >
> > For patch#1, is it acceptable adding "ethtool --get-priv-flags"
> > to query the VLAN. If yes, I will send a RFC for it.
> 
> The recommended way of implementing vfs with advanced vlan
> configurations is via "switchdev mode" & representors.

AFAIK, switchdev ops only facilitates the standard abstract
interface to any underlying standard or proprietary hardware
which could be ASIC, eswitch etc. Therefore, standard tools
like ip, bridge or even stacks like FRR etc. could be used
while leveraging the below hardware forwarding.

Not sure how will switchdev ops will be of help here?


Just curious how does Mellanox supports Hybrid port mode?

In general, 
We can have port being configured as Access/Trunk ports.

Access port = Only untagged packets are sent or are expected.
RX'ed Tagged packets are dropped.
Trunk Port  = Only Tagged packet are received or sent and any
Untagged packets received are dropped.

Mellanox also support Hybrid mode in Onyx platform:

Hybrid - packets are sent tagged or untagged, the port
expects both tagged and untagged packets. This mode is
a combination of Access and Trunk modes. There is an
option to configure multiple VLANs on the hybrid port.
PVID is configured on the port for untagged ingress
packets.

First two configuration are easy to realize using the
standard Linux configuration tools like ip/bridge but
not sure about the hybrid? also, why do we even need
to create a bridge to realize any of above port modes?

Note: HNS hardware does not have eswitch support.


Salil.



RE: [REPORT] possible circular locking dependency when booting a VM on arm64 host

2020-07-09 Thread Salil Mehta
Hi Yuzenghui,
I will try to reproduce it today at our platform. Just one question is it easily
reproducible or is a rare occurrence?

Thanks
Salil

> From: yuzenghui
> Sent: Thursday, July 9, 2020 11:41 AM
> To: Marc Zyngier ; Thomas Gleixner ; 
> Linux
> Kernel Mailing List ;
> linux-arm-ker...@lists.infradead.org
> Cc: Zhuangyuzeng (Yisen) ; Salil Mehta
> ; Wanghaibin (D) 
> Subject: [REPORT] possible circular locking dependency when booting a VM on 
> arm64
> host
> 
> Hi All,
> 
> I had seen the following lockdep splat when booting a guest on my
> Kunpeng 920 with GICv4 enabled. I can also trigger the same splat
> on v5.5 so it should already exist in the kernel for a while. I'm
> not sure what the exact problem is and hope someone can have a look!
> 
> 
> Thanks,
> Zenghui
> 
> [  103.855511] ==
> [  103.861664] WARNING: possible circular locking dependency detected
> [  103.867817] 5.8.0-rc4+ #35 Tainted: GW
> [  103.872932] --
> [  103.879083] CPU 2/KVM/20515 is trying to acquire lock:
> [  103.884200] 202fcd5865b0 (&irq_desc_lock_class){-.-.}-{2:2}, at:
> __irq_get_desc_lock+0x60/0xa0
> [  103.893127]
> but task is already holding lock:
> [  103.898933] 202fcfd07f58 (&rq->lock){-.-.}-{2:2}, at:
> __schedule+0x114/0x8b8
> [  103.906301]
> which lock already depends on the new lock.
> 
> [  103.914441]
> the existing dependency chain (in reverse order) is:
> [  103.921888]
> -> #3 (&rq->lock){-.-.}-{2:2}:
> [  103.927438]_raw_spin_lock+0x54/0x70
> [  103.931605]task_fork_fair+0x48/0x150
> [  103.935860]sched_fork+0x100/0x268
> [  103.939856]copy_process+0x628/0x1868
> [  103.944106]_do_fork+0x74/0x710
> [  103.947840]kernel_thread+0x78/0xa0
> [  103.951917]rest_init+0x30/0x270
> [  103.955742]arch_call_rest_init+0x14/0x1c
> [  103.960339]start_kernel+0x534/0x568
> [  103.964503]
> -> #2 (&p->pi_lock){-.-.}-{2:2}:
> [  103.970224]_raw_spin_lock_irqsave+0x70/0x98
> [  103.975080]try_to_wake_up+0x5c/0x5b0
> [  103.979330]wake_up_process+0x28/0x38
> [  103.983581]create_worker+0x128/0x1b8
> [  103.987834]workqueue_init+0x308/0x3bc
> [  103.992172]kernel_init_freeable+0x180/0x33c
> [  103.997027]kernel_init+0x18/0x118
> [  104.001020]ret_from_fork+0x10/0x18
> [  104.005097]
> -> #1 (&pool->lock){-.-.}-{2:2}:
> [  104.010817]_raw_spin_lock+0x54/0x70
> [  104.014983]__queue_work+0x120/0x6e8
> [  104.019146]queue_work_on+0xa0/0xd8
> [  104.023225]irq_set_affinity_locked+0xa8/0x178
> [  104.028253]__irq_set_affinity+0x5c/0x90
> [  104.032762]irq_set_affinity_hint+0x74/0xb0
> [  104.037540]hns3_nic_init_irq+0xe0/0x210 [hns3]
> [  104.042655]hns3_client_init+0x2d8/0x4e0 [hns3]
> [  104.047779]hclge_init_client_instance+0xf0/0x3a8 [hclge]
> [  104.053760]hnae3_init_client_instance.part.3+0x30/0x68 [hnae3]
> [  104.060257]hnae3_register_ae_dev+0x100/0x1f0 [hnae3]
> [  104.065892]hns3_probe+0x60/0xa8 [hns3]
> [  104.070319]local_pci_probe+0x44/0x98
> [  104.074573]work_for_cpu_fn+0x20/0x30
> [  104.078823]process_one_work+0x258/0x618
> [  104.08]worker_thread+0x1c0/0x438
> [  104.087585]kthread+0x120/0x128
> [  104.091318]ret_from_fork+0x10/0x18
> [  104.095394]
> -> #0 (&irq_desc_lock_class){-.-.}-{2:2}:
> [  104.101895]__lock_acquire+0x11bc/0x1530
> [  104.106406]lock_acquire+0x100/0x3f8
> [  104.110570]_raw_spin_lock_irqsave+0x70/0x98
> [  104.115426]__irq_get_desc_lock+0x60/0xa0
> [  104.120021]irq_set_vcpu_affinity+0x48/0xc8
> [  104.124793]its_make_vpe_non_resident+0x6c/0xc0
> [  104.129910]vgic_v4_put+0x64/0x70
> [  104.133815]vgic_v3_put+0x28/0x100
> [  104.137806]kvm_vgic_put+0x3c/0x60
> [  104.141801]kvm_arch_vcpu_put+0x38/0x58
> [  104.146228]kvm_sched_out+0x38/0x58
> [  104.150306]__schedule+0x554/0x8b8
> [  104.154298]schedule+0x50/0xe0
> [  104.157946]kvm_arch_vcpu_ioctl_run+0x644/0x9e8
> [  104.163063]kvm_vcpu_ioctl+0x4b4/0x918
> [  104.167403]ksys_ioctl+0xb4/0xd0
> [  104.171222]__arm64_sys_ioctl+0x28/0xc8
> [  104.175647]el0_svc_common.constprop.2+0x74/0x138
> [  104.180935]

RE: [REPORT] possible circular locking dependency when booting a VM on arm64 host

2020-07-09 Thread Salil Mehta
> From: yuzenghui
> Sent: Thursday, July 9, 2020 12:50 PM
> To: Salil Mehta 
> Cc: Marc Zyngier ; Thomas Gleixner ; 
> Linux
> Kernel Mailing List ;
> linux-arm-ker...@lists.infradead.org; Zhuangyuzeng (Yisen)
> ; Wanghaibin (D) 
> Subject: Re: [REPORT] possible circular locking dependency when booting a VM
> on arm64 host
> 
> On 2020/7/9 18:54, Salil Mehta wrote:
> > Hi Yuzenghui,
> > I will try to reproduce it today at our platform. Just one question is it 
> > easily
> > reproducible or is a rare occurrence?
> 
> Salil, it's 100% reproducible once you start a guest. You don't even
> need to assign hostdev to the VM.

Thanks!


RE: [REPORT] possible circular locking dependency when booting a VM on arm64 host

2020-07-15 Thread Salil Mehta
> From: Marc Zyngier [mailto:m...@kernel.org]
> Sent: Wednesday, July 15, 2020 5:09 PM
> To: yuzenghui 
> 
> Hi Zenghui,
> 
> On 2020-07-09 11:41, Zenghui Yu wrote:
> > Hi All,
> >
> > I had seen the following lockdep splat when booting a guest on my
> > Kunpeng 920 with GICv4 enabled. I can also trigger the same splat
> > on v5.5 so it should already exist in the kernel for a while. I'm
> > not sure what the exact problem is and hope someone can have a look!
> 
> I can't manage to trigger this splat on my D05, despite running guests
> with GICv4 enabled. A couple of questions below:


Sorry I forgot to update but I did try on Friday and I could not manage
to trigger it on D06/Kunpeng920 either. I used 5.8.0-rc4.


> > Thanks,
> > Zenghui
> >
> > [  103.855511] ==
> > [  103.861664] WARNING: possible circular locking dependency detected
> > [  103.867817] 5.8.0-rc4+ #35 Tainted: GW
> > [  103.872932] --
> > [  103.879083] CPU 2/KVM/20515 is trying to acquire lock:
> > [  103.884200] 202fcd5865b0 (&irq_desc_lock_class){-.-.}-{2:2},
> > at: __irq_get_desc_lock+0x60/0xa0
> > [  103.893127]
> >but task is already holding lock:
> > [  103.898933] 202fcfd07f58 (&rq->lock){-.-.}-{2:2}, at:
> > __schedule+0x114/0x8b8
> > [  103.906301]
> >which lock already depends on the new lock.
> >
> > [  103.914441]
> >the existing dependency chain (in reverse order) is:
> > [  103.921888]
> >-> #3 (&rq->lock){-.-.}-{2:2}:
> > [  103.927438]_raw_spin_lock+0x54/0x70
> > [  103.931605]task_fork_fair+0x48/0x150
> > [  103.935860]sched_fork+0x100/0x268
> > [  103.939856]copy_process+0x628/0x1868
> > [  103.944106]_do_fork+0x74/0x710
> > [  103.947840]kernel_thread+0x78/0xa0
> > [  103.951917]rest_init+0x30/0x270
> > [  103.955742]arch_call_rest_init+0x14/0x1c
> > [  103.960339]start_kernel+0x534/0x568
> > [  103.964503]
> >-> #2 (&p->pi_lock){-.-.}-{2:2}:
> > [  103.970224]_raw_spin_lock_irqsave+0x70/0x98
> > [  103.975080]try_to_wake_up+0x5c/0x5b0
> > [  103.979330]wake_up_process+0x28/0x38
> > [  103.983581]create_worker+0x128/0x1b8
> > [  103.987834]workqueue_init+0x308/0x3bc
> > [  103.992172]kernel_init_freeable+0x180/0x33c
> > [  103.997027]kernel_init+0x18/0x118
> > [  104.001020]ret_from_fork+0x10/0x18
> > [  104.005097]
> >-> #1 (&pool->lock){-.-.}-{2:2}:
> > [  104.010817]_raw_spin_lock+0x54/0x70
> > [  104.014983]__queue_work+0x120/0x6e8
> > [  104.019146]queue_work_on+0xa0/0xd8
> > [  104.023225]irq_set_affinity_locked+0xa8/0x178
> > [  104.028253]__irq_set_affinity+0x5c/0x90
> > [  104.032762]irq_set_affinity_hint+0x74/0xb0
> > [  104.037540]hns3_nic_init_irq+0xe0/0x210 [hns3]
> > [  104.042655]hns3_client_init+0x2d8/0x4e0 [hns3]
> > [  104.047779]hclge_init_client_instance+0xf0/0x3a8 [hclge]
> > [  104.053760]hnae3_init_client_instance.part.3+0x30/0x68
> > [hnae3]
> > [  104.060257]hnae3_register_ae_dev+0x100/0x1f0 [hnae3]
> > [  104.065892]hns3_probe+0x60/0xa8 [hns3]
> 
> Are you performing some kind of PCIe hot-plug here? Or is that done
> at boot only? It seems to help triggering the splat.


I am not sure how you can do that since HNS3 is integrated NIC so
physical hot-plug is definitely ruled out. local_pci_probe()
should also get called when we insert the hns3_enet module which
eventually initializes the driver.


> > [  104.070319]local_pci_probe+0x44/0x98
> > [  104.074573]work_for_cpu_fn+0x20/0x30
> > [  104.078823]process_one_work+0x258/0x618
> > [  104.08]worker_thread+0x1c0/0x438
> > [  104.087585]kthread+0x120/0x128
> > [  104.091318]ret_from_fork+0x10/0x18
> > [  104.095394]
> >-> #0 (&irq_desc_lock_class){-.-.}-{2:2}:
> > [  104.101895]__lock_acquire+0x11bc/0x1530
> > [  104.106406]lock_acquire+0x100/0x3f8
> > [  104.110570]_raw_spin_lock_irqsave+0x70/0x98
> > [  104.115426]__irq_get_desc_lock+0x60/0xa0
> > [  104.120021]irq_set_vcpu_affinity+0x48/0xc8   
> > [  104.124793]its_make_vpe_non_resident+0x6c/0xc0
> > [  104.129910]vgic_v4_put+0x64/0x70
> > [  104.133815]vgic_v3_put+0x28/0x100
> > [  104.137806]kvm_vgic_put+0x3c/0x60
> > [  104.141801]kvm_arch_vcpu_put+0x38/0x58
> > [  104.146228]kvm_sched_out+0x38/0x58
> > [  104.150306]__schedule+0x554/0x8b8
> > [  104.154298]schedule+0x50/0xe0
> > [  104.157946]kvm_arch_vcpu_ioctl_run+0x644/0x9e8
> > [  104.163063]kvm_vcpu_ioctl+0x4b4/0x918
> > [  104.167403]ksys_ioctl+0xb4/0xd0
> > [  104.171222]__arm64_sys_io

RE: [REPORT] possible circular locking dependency when booting a VM on arm64 host

2020-07-16 Thread Salil Mehta
> From: Salil Mehta
> Sent: Thursday, July 16, 2020 1:53 AM
> To: 'Marc Zyngier' ; yuzenghui 
> 
> > From: Marc Zyngier [mailto:m...@kernel.org]
> > Sent: Wednesday, July 15, 2020 5:09 PM
> > To: yuzenghui 
> >
> > Hi Zenghui,
> >
> > On 2020-07-09 11:41, Zenghui Yu wrote:
> > > Hi All,
> > >
> > > I had seen the following lockdep splat when booting a guest on my
> > > Kunpeng 920 with GICv4 enabled. I can also trigger the same splat
> > > on v5.5 so it should already exist in the kernel for a while. I'm
> > > not sure what the exact problem is and hope someone can have a look!
> >
> > I can't manage to trigger this splat on my D05, despite running guests
> > with GICv4 enabled. A couple of questions below:
> 
> 
> Sorry I forgot to update but I did try on Friday and I could not manage
> to trigger it on D06/Kunpeng920 either. I used 5.8.0-rc4.
> 
> 
> > > Thanks,
> > > Zenghui
> > >
> > > [  103.855511] ==
> > > [  103.861664] WARNING: possible circular locking dependency detected
> > > [  103.867817] 5.8.0-rc4+ #35 Tainted: GW
> > > [  103.872932] --
> > > [  103.879083] CPU 2/KVM/20515 is trying to acquire lock:
> > > [  103.884200] 202fcd5865b0 (&irq_desc_lock_class){-.-.}-{2:2},
> > > at: __irq_get_desc_lock+0x60/0xa0
> > > [  103.893127]
> > >but task is already holding lock:
> > > [  103.898933] 202fcfd07f58 (&rq->lock){-.-.}-{2:2}, at:
> > > __schedule+0x114/0x8b8
> > > [  103.906301]
> > >which lock already depends on the new lock.
> > >
> > > [  103.914441]
> > >the existing dependency chain (in reverse order) is:
> > > [  103.921888]
> > >-> #3 (&rq->lock){-.-.}-{2:2}:
> > > [  103.927438]_raw_spin_lock+0x54/0x70
> > > [  103.931605]task_fork_fair+0x48/0x150
> > > [  103.935860]sched_fork+0x100/0x268
> > > [  103.939856]copy_process+0x628/0x1868
> > > [  103.944106]_do_fork+0x74/0x710
> > > [  103.947840]kernel_thread+0x78/0xa0
> > > [  103.951917]rest_init+0x30/0x270
> > > [  103.955742]arch_call_rest_init+0x14/0x1c
> > > [  103.960339]start_kernel+0x534/0x568
> > > [  103.964503]
> > >-> #2 (&p->pi_lock){-.-.}-{2:2}:
> > > [  103.970224]_raw_spin_lock_irqsave+0x70/0x98
> > > [  103.975080]try_to_wake_up+0x5c/0x5b0
> > > [  103.979330]wake_up_process+0x28/0x38
> > > [  103.983581]create_worker+0x128/0x1b8
> > > [  103.987834]workqueue_init+0x308/0x3bc
> > > [  103.992172]kernel_init_freeable+0x180/0x33c
> > > [  103.997027]kernel_init+0x18/0x118
> > > [  104.001020]ret_from_fork+0x10/0x18
> > > [  104.005097]
> > >-> #1 (&pool->lock){-.-.}-{2:2}:
> > > [  104.010817]_raw_spin_lock+0x54/0x70
> > > [  104.014983]__queue_work+0x120/0x6e8
> > > [  104.019146]queue_work_on+0xa0/0xd8
> > > [  104.023225]irq_set_affinity_locked+0xa8/0x178
> > > [  104.028253]__irq_set_affinity+0x5c/0x90
> > > [  104.032762]irq_set_affinity_hint+0x74/0xb0
> > > [  104.037540]hns3_nic_init_irq+0xe0/0x210 [hns3]
> > > [  104.042655]hns3_client_init+0x2d8/0x4e0 [hns3]
> > > [  104.047779]hclge_init_client_instance+0xf0/0x3a8 [hclge]
> > > [  104.053760]hnae3_init_client_instance.part.3+0x30/0x68
> > > [hnae3]
> > > [  104.060257]hnae3_register_ae_dev+0x100/0x1f0 [hnae3]
> > > [  104.065892]hns3_probe+0x60/0xa8 [hns3]
> >
> > Are you performing some kind of PCIe hot-plug here? Or is that done
> > at boot only? It seems to help triggering the splat.
> 
> 
> I am not sure how you can do that since HNS3 is integrated NIC so
> physical hot-plug is definitely ruled out. local_pci_probe()
> should also get called when we insert the hns3_enet module which
> eventually initializes the driver.

Or perhaps you meant below?

echo 1 > /sys/bus/pci/devices//xx.x/remove
echo 1 > /sys/bus/pci/devices/rescan

Above is not being used I did confirm this with Zenghui earlier.

 



RE: [PATCH RFC 0/4] Changes to Support *Virtual* CPU Hotplug for ARM64

2020-07-07 Thread Salil Mehta
Hello,
A gentle reminder, any comments regarding this series will help us know
your opinion and also confirm/correct our understanding about the topic
and will be much appreciated.

Thanks in anticipation!

Best regards
Salil

> From: Salil Mehta
> Sent: Thursday, June 25, 2020 2:38 PM
> To: linux-arm-ker...@lists.infradead.org
> Cc: m...@kernel.org; w...@kernel.org; catalin.mari...@arm.com;
> christoffer.d...@arm.com; andre.przyw...@arm.com; james.mo...@arm.com;
> mark.rutl...@arm.com; lorenzo.pieral...@arm.com; sudeep.ho...@arm.com;
> qemu-...@nongnu.org; peter.mayd...@linaro.org; richard.hender...@linaro.org;
> imamm...@redhat.com; m...@redhat.com; drjo...@redhat.com; pbonz...@redhat.com;
> eric.au...@redhat.com; gs...@redhat.com; da...@redhat.com;
> k...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> ; mehta.salil@gmail.com; Salil Mehta
> 
> Subject: [PATCH RFC 0/4] Changes to Support *Virtual* CPU Hotplug for ARM64
> 
> Changes to support virtual cpu hotplug in QEMU[1] have been introduced to the
> community as RFC. These are under review.
> 
> To support virtual cpu hotplug guest kernel must:
> 1. Identify disabled/present vcpus and set/unset the present mask of the vcpu
>during initialization and hotplug event. It must also set the possible mask
>(which includes disabled vcpus) during init of guest kernel.
> 2. Provide architecture specific ACPI hooks, for example to map/unmap the
>logical cpuid to hwids/MPIDR. Linux kernel already has generic ACPI cpu
>hotplug framework support.
> 
> Changes introduced in this patch-set also ensures that initialization of the
> cpus when virtual cpu hotplug is not supported remains un-affected.
> 
> Repository:
> (*) Kernel changes are at,
>  https://github.com/salil-mehta/linux.git virt-cpuhp-arm64/rfc-v1
> (*) QEMU changes for vcpu hotplug could be cloned from below site,
>  https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v1
> 
> 
> THINGS TO DO:
> 1. Handling of per-cpu variables especially the first-chunk allocations
>(which are NUMA aware) when the vcpu is hotplugged needs further attention
>and review.
> 2. NUMA related stuff has not been fully tested both in QEMU and kernel.
> 3. Comprehensive Testing including when cpu hotplug is not supported.
> 4. Docs
> 
> DISCLAIMER:
> This is not a complete work but an effort to present the arm vcpu hotplug
> implementation to the community. This RFC is being used as a way to verify
> the idea mentioned above and to support changes presented for QEMU[1] to
> support vcpu hotplug. As of now this is *not* a production level code and 
> might
> have bugs. Only a basic testing has been done on HiSilicon Kunpeng920 ARM64
> based SoC for Servers to verify the proof-of-concept that has been found 
> working!
> 
> Best regards
> Salil.
> 
> REFERENCES:
> [1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg712010.html
> [2] https://lkml.org/lkml/2019/6/28/1157
> [3] https://lists.cs.columbia.edu/pipermail/kvmarm/2018-July/032316.html
> 
> Organization of Patches:
> [Patch 1-3]
> (*) Changes required during guest boot time to support vcpu hotplug
> (*) Max cpu overflow checks
> (*) Changes required to pre-setup cpu-operations even for disabled cpus
> [Patch 4]
> (*) Arch changes required by guest kernel ACPI CPU Hotplug framework.
> 
> 
> Salil Mehta (4):
>   arm64: kernel: Handle disabled[(+)present] cpus in MADT/GICC during
> init
>   arm64: kernel: Bound the total(present+disabled) cpus with nr_cpu_ids
>   arm64: kernel: Init cpu operations for all possible vcpus
>   arm64: kernel: Arch specific ACPI hooks(like logical cpuid<->hwid
> etc.)
> 
>  arch/arm64/kernel/smp.c | 153 
>  1 file changed, 123 insertions(+), 30 deletions(-)
> 
> --
> 2.17.1
> 



RE: [PATCH net-next] net: link_watch: prevent starvation when processing linkwatch wq

2019-05-29 Thread Salil Mehta
> From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org] On 
> Behalf Of Yunsheng Lin
> Sent: Tuesday, May 28, 2019 2:04 AM
> 
> On 2019/5/27 22:58, Stephen Hemminger wrote:
> > On Mon, 27 May 2019 09:47:54 +0800
> > Yunsheng Lin  wrote:
> >
> >> When user has configured a large number of virtual netdev, such
> >> as 4K vlans, the carrier on/off operation of the real netdev
> >> will also cause it's virtual netdev's link state to be processed
> >> in linkwatch. Currently, the processing is done in a work queue,
> >> which may cause worker starvation problem for other work queue.


I think we had already discussed about this internally and using separate
workqueue with WQ_UNBOUND should solve this problem. HNS3 driver was sharing
workqueue with the system workqueue. 


> >> This patch releases the cpu when link watch worker has processed
> >> a fixed number of netdev' link watch event, and schedule the
> >> work queue again when there is still link watch event remaining.


We need proper examples/use-cases because of which we require above
kind of co-operative scheduling. Touching the common shared queue logic
which solid argument might invite for more problem to other modules.


> >> Signed-off-by: Yunsheng Lin 
> >
> > Why not put link watch in its own workqueue so it is scheduled
> > separately from the system workqueue?
> 
> From testing and debuging, the workqueue runs on the cpu where the
> workqueue is schedule when using normal workqueue, even using its
> own workqueue instead of system workqueue. So if the cpu is busy
> processing the linkwatch event, it is not able to process other
> workqueue' work when the workqueue is scheduled on the same cpu.
> 
> Using unbound workqueue may solve the cpu starvation problem.

[...]

> But the __linkwatch_run_queue is called with rtnl_lock, so if it
> takes a lot time to process, other need to take the rtnl_lock may
> not be able to move forward.

Please help me in understanding, Are you trying to pitch this patch
to solve more general system issue OR still your argument/concern
is related to the HNS3 driver problem mentioned in this patch?

Salil.









RE: [PATCH v2 net-next] net: link_watch: prevent starvation when processing linkwatch wq

2019-05-31 Thread Salil Mehta
> From: netdev-ow...@vger.kernel.org On Behalf Of Yunsheng Lin
> Sent: Friday, May 31, 2019 10:01 AM
> To: da...@davemloft.net
> Cc: hkallwe...@gmail.com; f.faine...@gmail.com;
> step...@networkplumber.org; net...@vger.kernel.org; linux-
> ker...@vger.kernel.org; Linuxarm 
> Subject: [PATCH v2 net-next] net: link_watch: prevent starvation when
> processing linkwatch wq
> 
> When user has configured a large number of virtual netdev, such
> as 4K vlans, the carrier on/off operation of the real netdev
> will also cause it's virtual netdev's link state to be processed
> in linkwatch. Currently, the processing is done in a work queue,
> which may cause cpu and rtnl locking starvation problem.
> 
> This patch releases the cpu and rtnl lock when link watch worker
> has processed a fixed number of netdev' link watch event.
> 
> Currently __linkwatch_run_queue is called with rtnl lock, so
> enfore it with ASSERT_RTNL();


Typo enfore --> enforce ?



> Signed-off-by: Yunsheng Lin 
> ---
> V2: use cond_resched and rtnl_unlock after processing a fixed
> number of events
> ---
>  net/core/link_watch.c | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/net/core/link_watch.c b/net/core/link_watch.c
> index 7f51efb..07eebfb 100644
> --- a/net/core/link_watch.c
> +++ b/net/core/link_watch.c
> @@ -168,9 +168,18 @@ static void linkwatch_do_dev(struct net_device
> *dev)
> 
>  static void __linkwatch_run_queue(int urgent_only)
>  {
> +#define MAX_DO_DEV_PER_LOOP  100
> +
> + int do_dev = MAX_DO_DEV_PER_LOOP;
>   struct net_device *dev;
>   LIST_HEAD(wrk);
> 
> + ASSERT_RTNL();
> +
> + /* Give urgent case more budget */
> + if (urgent_only)
> + do_dev += MAX_DO_DEV_PER_LOOP;
> +
>   /*
>* Limit the number of linkwatch events to one
>* per second so that a runaway driver does not
> @@ -200,6 +209,14 @@ static void __linkwatch_run_queue(int urgent_only)
>   }
>   spin_unlock_irq(&lweventlist_lock);
>   linkwatch_do_dev(dev);
> +


A comment like below would be helpful in explaining the reason of the code.
 
/* This function is called with rtnl_lock held. If excessive events
 * are present as part of the watch list, their processing could
 * monopolize the rtnl_lock and which could lead to starvation in
 * other modules which want to acquire this lock. Hence, co-operative
 * scheme like below might be helpful in mitigating the problem.
 * This also tries to be fair CPU wise by conditional rescheduling.
 */


> + if (--do_dev < 0) {
> + rtnl_unlock();
> + cond_resched();
> + do_dev = MAX_DO_DEV_PER_LOOP;
> + rtnl_lock();
> + }
> +
>   spin_lock_irq(&lweventlist_lock);
>   }


RE: [PATCH v2 net-next] net: link_watch: prevent starvation when processing linkwatch wq

2019-05-31 Thread Salil Mehta
> From: netdev-ow...@vger.kernel.org [mailto:netdev-
> ow...@vger.kernel.org] On Behalf Of Yunsheng Lin
> Sent: Friday, May 31, 2019 10:01 AM
> To: da...@davemloft.net
> Cc: hkallwe...@gmail.com; f.faine...@gmail.com;
> step...@networkplumber.org; net...@vger.kernel.org; linux-
> ker...@vger.kernel.org; Linuxarm 
> Subject: [PATCH v2 net-next] net: link_watch: prevent starvation when
> processing linkwatch wq
> 
> When user has configured a large number of virtual netdev, such
> as 4K vlans, the carrier on/off operation of the real netdev
> will also cause it's virtual netdev's link state to be processed
> in linkwatch. Currently, the processing is done in a work queue,
> which may cause cpu and rtnl locking starvation problem.
> 
> This patch releases the cpu and rtnl lock when link watch worker
> has processed a fixed number of netdev' link watch event.
> 
> Currently __linkwatch_run_queue is called with rtnl lock, so
> enfore it with ASSERT_RTNL();
> 
> Signed-off-by: Yunsheng Lin 
> ---
> V2: use cond_resched and rtnl_unlock after processing a fixed
> number of events
> ---
>  net/core/link_watch.c | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/net/core/link_watch.c b/net/core/link_watch.c
> index 7f51efb..07eebfb 100644
> --- a/net/core/link_watch.c
> +++ b/net/core/link_watch.c
> @@ -168,9 +168,18 @@ static void linkwatch_do_dev(struct net_device
> *dev)
> 
>  static void __linkwatch_run_queue(int urgent_only)
>  {
> +#define MAX_DO_DEV_PER_LOOP  100
> +
> + int do_dev = MAX_DO_DEV_PER_LOOP;
>   struct net_device *dev;
>   LIST_HEAD(wrk);
> 
> + ASSERT_RTNL();
> +
> + /* Give urgent case more budget */
> + if (urgent_only)
> + do_dev += MAX_DO_DEV_PER_LOOP;
> +
>   /*
>* Limit the number of linkwatch events to one
>* per second so that a runaway driver does not
> @@ -200,6 +209,14 @@ static void __linkwatch_run_queue(int urgent_only)
>   }
>   spin_unlock_irq(&lweventlist_lock);
>   linkwatch_do_dev(dev);
> +
> + if (--do_dev < 0) {
> + rtnl_unlock();
> + cond_resched();



Sorry, missed in my earlier comment. I could see multiple problems here
and please correct me if I am wrong:

1. It looks like releasing the rtnl_lock here and then res-scheduling might
   not be safe, especially when you have already held *lweventlist_lock*
   (which is global and not per-netdev), and when you are trying to
   reschedule. This can cause *deadlock* with itself.

   Reason: once you release the rtnl_lock() the similar leg of function 
   netdev_wait_allrefs() could be called for some other netdevice which
   might end up in waiting for same global linkwatch event list lock
   i.e. *lweventlist_lock*.

2. After releasing the rtnl_lock() we have not ensured that all the rcu
   operations are complete. Perhaps we need to take rcu_barrier() before
   retaking the rtnl_lock()




> + do_dev = MAX_DO_DEV_PER_LOOP;



Here, I think rcu_barrier() should exist.



> + rtnl_lock();
> + }
> +
>   spin_lock_irq(&lweventlist_lock);
>   }



[PATCH net 02/19] net: hns: Modify GMAC init TX threshold value

2017-03-30 Thread Salil Mehta
From: lipeng 

This patch reduces GMAC TX threshold value to avoid gmac
hang-up with speed 100M/duplex half.

Signed-off-by: lipeng 
Signed-off-by: JinchuanTian 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 6 ++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  | 4 
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 3382441..a8dbe00 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -325,6 +325,12 @@ static void hns_gmac_init(void *mac_drv)
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);
+
+   /* reduce gmac tx water line to avoid gmac hang-up
+* in speed 100M and duplex half.
+*/
+   dsaf_set_dev_field(drv, GMAC_TX_WATER_LINE_REG, GMAC_TX_WATER_LINE_MASK,
+  GMAC_TX_WATER_LINE_SHIFT, 8);
 }
 
 void hns_gmac_update_stats(void *mac_drv)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 8fa18fc..4b8af68 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -466,6 +466,7 @@
 
 #define GMAC_DUPLEX_TYPE_REG   0x0008UL
 #define GMAC_FD_FC_TYPE_REG0x000CUL
+#define GMAC_TX_WATER_LINE_REG 0x0010UL
 #define GMAC_FC_TX_TIMER_REG   0x001CUL
 #define GMAC_FD_FC_ADDR_LOW_REG0x0020UL
 #define GMAC_FD_FC_ADDR_HIGH_REG   0x0024UL
@@ -912,6 +913,9 @@
 
 #define GMAC_DUPLEX_TYPE_B 0
 
+#define GMAC_TX_WATER_LINE_MASK((1UL << 8) - 1)
+#define GMAC_TX_WATER_LINE_SHIFT   0
+
 #define GMAC_FC_TX_TIMER_S 0
 #define GMAC_FC_TX_TIMER_M 0x
 
-- 
2.7.4




[PATCH net 08/19] net: hns: Fix to adjust buf_size of ring according to mtu

2017-03-30 Thread Salil Mehta
From: lipeng 

Because buf_size of ring set to 2048, the process of rx_poll_one
can reuse the page, therefore the performance of XGE can improve.
But the chip only supports three bds in one package, so the max mtu
is 6K when it sets to 2048. For better performane in litter mtu, we
need change buf_size according to mtu.

When user change mtu, hns is only change the desc in memory. There
are some desc has been fetched by the chip, these desc can not be
changed by the code. So it needs set the port loopback and send
some packages to let the chip consumes the wrong desc and fetch new
desc.
Because the Pv660 do not support rss indirection, we need add version
check in mtu change process.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |  37 
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  26 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c |   3 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h |   2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c |  41 +++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h |   3 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 249 +-
 7 files changed, 337 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 85df7c7..ad79a76 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -67,6 +67,8 @@ do { \
 #define AE_IS_VER1(ver) ((ver) == AE_VERSION_1)
 #define AE_NAME_SIZE 16
 
+#define BD_SIZE_2048_MAX_MTU   6000
+
 /* some said the RX and TX RCB format should not be the same in the future. But
  * it is the same now...
  */
@@ -648,6 +650,41 @@ static inline void hnae_reuse_buffer(struct hnae_ring 
*ring, int i)
ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
 }
 
+/* when reinit buffer size, we should reinit buffer description */
+static inline void hnae_reinit_all_ring_desc(struct hnae_handle *h)
+{
+   int i, j;
+   struct hnae_ring *ring;
+
+   for (i = 0; i < h->q_num; i++) {
+   ring = &h->qs[i]->rx_ring;
+   for (j = 0; j < ring->desc_num; j++)
+   ring->desc[j].addr = cpu_to_le64(ring->desc_cb[j].dma);
+   }
+
+   wmb();  /* commit all data before submit */
+}
+
+/* when reinit buffer size, we should reinit page offset */
+static inline void hnae_reinit_all_ring_page_off(struct hnae_handle *h)
+{
+   int i, j;
+   struct hnae_ring *ring;
+
+   for (i = 0; i < h->q_num; i++) {
+   ring = &h->qs[i]->rx_ring;
+   for (j = 0; j < ring->desc_num; j++) {
+   ring->desc_cb[j].page_offset = 0;
+   if (ring->desc[j].addr !=
+   cpu_to_le64(ring->desc_cb[j].dma))
+   ring->desc[j].addr =
+   cpu_to_le64(ring->desc_cb[j].dma);
+   }
+   }
+
+   wmb();  /* commit all data before submit */
+}
+
 #define hnae_set_field(origin, mask, shift, val) \
do { \
(origin) &= (~(mask)); \
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index abafa25..53af14e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -272,8 +272,32 @@ static int hns_ae_clr_multicast(struct hnae_handle *handle)
 static int hns_ae_set_mtu(struct hnae_handle *handle, int new_mtu)
 {
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
+   struct hnae_queue *q;
+   u32 rx_buf_size;
+   int i, ret;
+
+   /* when buf_size is 2048, max mtu is 6K for rx ring max bd num is 3. */
+   if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
+   if (new_mtu <= BD_SIZE_2048_MAX_MTU)
+   rx_buf_size = 2048;
+   else
+   rx_buf_size = 4096;
+   } else {
+   rx_buf_size = mac_cb->dsaf_dev->buf_size;
+   }
+
+   ret = hns_mac_set_mtu(mac_cb, new_mtu, rx_buf_size);
 
-   return hns_mac_set_mtu(mac_cb, new_mtu);
+   if (!ret) {
+   /* reinit ring buf_size */
+   for (i = 0; i < handle->q_num; i++) {
+   q = handle->qs[i];
+   q->rx_ring.buf_size = rx_buf_size;
+   hns_rcb_set_rx_ring_bs(q, rx_buf_size);
+   }
+   }
+
+   return ret;
 }
 
 static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 3239d27..edf9a23 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hn

[PATCH net 10/19] net: hns: Correct HNS RSS key set function

2017-03-30 Thread Salil Mehta
From: lipeng 

This patch fixes below ethtool configuration error:

localhost:~ # ethtool -X eth0 hkey XX:XX:XX...
Cannot set Rx flow hash configuration: Operation not supported

Signed-off-by: lipeng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 23 ++-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  |  9 -
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 53af14e..58b51e5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -831,8 +831,9 @@ 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 * sizeof(*indir));
+   if (indir)
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE  * sizeof(*indir));
 
return 0;
 }
@@ -843,15 +844,19 @@ static int hns_ae_set_rss(struct hnae_handle *handle, 
const u32 *indir,
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);
 
/* set the RSS Hash Key if specififed by the user */
-   if (key)
-   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
+   if (key) {
+   memcpy(ppe_cb->rss_key, key, HNS_PPEV2_RSS_KEY_SIZE);
+   hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
+   }
 
-   /* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir,
-  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
+   if (indir) {
+   /* update the shadow RSS table with user specified qids */
+   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);
+   /* now update the hardware */
+   hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
+   }
 
return 0;
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3404eac..3a2a342 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1244,6 +1244,7 @@ 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,
@@ -1253,12 +1254,10 @@ hns_set_rss(struct net_device *netdev, const u32 
*indir, const u8 *key,
 
ops = priv->ae_handle->dev->ops;
 
-   /* currently hfunc can only be Toeplitz hash */
-   if (key ||
-   (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
+   if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
+   netdev_err(netdev, "Invalid hfunc!\n");
return -EOPNOTSUPP;
-   if (!indir)
-   return 0;
+   }
 
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
-- 
2.7.4




[PATCH net 16/19] net: hns: Simplify the exception sequence in hns_ppe_init()

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

We need to free all ppe submodule if it fails to initialize ppe by
any fault, so this patch will free all ppe resource before
hns_ppe_init() returns exception situation

Reported-by: JinchuanTian 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index 6ea8722..eba406b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -496,17 +496,17 @@ void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 
*data)
  */
 int hns_ppe_init(struct dsaf_device *dsaf_dev)
 {
-   int i, k;
int ret;
+   int i;
 
for (i = 0; i < HNS_PPE_COM_NUM; i++) {
ret = hns_ppe_common_get_cfg(dsaf_dev, i);
if (ret)
-   goto get_ppe_cfg_fail;
+   goto get_cfg_fail;
 
ret = hns_rcb_common_get_cfg(dsaf_dev, i);
if (ret)
-   goto get_rcb_cfg_fail;
+   goto get_cfg_fail;
 
hns_ppe_get_cfg(dsaf_dev->ppe_common[i]);
 
@@ -518,13 +518,12 @@ int hns_ppe_init(struct dsaf_device *dsaf_dev)
 
return 0;
 
-get_rcb_cfg_fail:
-   hns_ppe_common_free_cfg(dsaf_dev, i);
-get_ppe_cfg_fail:
-   for (k = i - 1; k >= 0; k--) {
-   hns_rcb_common_free_cfg(dsaf_dev, k);
-   hns_ppe_common_free_cfg(dsaf_dev, k);
+get_cfg_fail:
+   for (i = 0; i < HNS_PPE_COM_NUM; i++) {
+   hns_rcb_common_free_cfg(dsaf_dev, i);
+   hns_ppe_common_free_cfg(dsaf_dev, i);
}
+
return ret;
 }
 
-- 
2.7.4




[PATCH net 17/19] net: hns: Adjust the SBM module buffer threshold

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

HNS needs SMB Buffers to store at least two packets after sending
pause frame because of the link delay. The MTU of HNS is 9728. As
the processor user manual described, the SBM buffer threshold should
be modified.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index abd8aec..d07b4fe 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -510,10 +510,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device 
*dsaf_dev)
o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 48);
+  DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 55);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 80);
+  DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 110);
dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg);
 
/* for no enable pfc mode */
@@ -521,10 +521,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device 
*dsaf_dev)
o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 192);
+  DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 128);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 240);
+  DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 192);
dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg);
}
 
-- 
2.7.4




[PATCH net 19/19] net: hns: Some checkpatch.pl script & warning fixes

2017-03-30 Thread Salil Mehta
This patch fixes some checkpatch.pl script caught errors and
warnings during the compilation time.

Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 11 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  |  9 +
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  1 -
 6 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index a2c49ea..c8c41d2 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -103,7 +103,6 @@ enum hnae_led_state {
 #define HNS_RX_FLAG_L4ID_TCP 0x1
 #define HNS_RX_FLAG_L4ID_SCTP 0x3
 
-
 #define HNS_TXD_ASID_S 0
 #define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
 #define HNS_TXD_BUFNUM_S 8
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 035db86..74bd260 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -86,12 +86,11 @@ static void hns_gmac_disable(void *mac_drv, enum 
mac_commom_mode mode)
dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0);
 }
 
-/**
-*hns_gmac_get_en - get port enable
-*@mac_drv:mac device
-*@rx:rx enable
-*@tx:tx enable
-*/
+/* hns_gmac_get_en - get port enable
+ * @mac_drv:mac device
+ * @rx:rx enable
+ * @tx:tx enable
+ */
 static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 4db02e2..4507e82 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -68,7 +68,7 @@ enum dsaf_roce_qos_sl {
 };
 
 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset
-#define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP)
+#define HNS_DSAF_IS_DEBUG(dev) ((dev)->dsaf_mode == DSAF_MODE_DISABLE_SP)
 
 enum hal_dsaf_mode {
HRD_DSAF_NO_DSAF_MODE   = 0x0,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
index 9b66057..c20a0f4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
@@ -471,7 +471,6 @@ static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb 
*ring_pair_cb)
 static int hns_rcb_get_port_in_comm(
struct rcb_common_cb *rcb_common, int ring_idx)
 {
-
return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn);
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index c4aa095..e307568 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -514,7 +514,8 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
int last_offset;
bool twobufs;
 
-   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring) == 
HNS_BUFFER_SIZE_2048);
+   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring)
+   == HNS_BUFFER_SIZE_2048);
 
desc = &ring->desc[ring->next_to_clean];
size = le16_to_cpu(desc->rx.size);
@@ -924,8 +925,8 @@ static int is_valid_clean_head(struct hnae_ring *ring, int 
h)
 
 /* netif_tx_lock will turn down the performance, set only when necessary */
 #ifdef CONFIG_NET_POLL_CONTROLLER
-#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
-#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
+#define NETIF_TX_LOCK(ring) spin_lock(&(ring)->lock)
+#define NETIF_TX_UNLOCK(ring) spin_unlock(&(ring)->lock)
 #else
 #define NETIF_TX_LOCK(ring)
 #define NETIF_TX_UNLOCK(ring)
@@ -2075,7 +2076,7 @@ static void hns_nic_reset_subtask(struct hns_nic_priv 
*priv)
 static void hns_nic_service_event_complete(struct hns_nic_priv *priv)
 {
WARN_ON(!test_bit(NIC_STATE_SERVICE_SCHED, &priv->state));
-
+   /* make sure to commit the things */
smp_mb__before_atomic();
clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 36f33bd..b8fab14 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1242,7 +1242,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,
-- 
2.7.4




[PATCH net 11/19] net: hns: Remove the redundant adding and deleting mac function

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

The functions (hns_dsaf_set_mac_mc_entry() and hns_mac_del_mac()) are
not called by any functions. They are dead code in hns. And the same
features are implemented by the patch (the id is 66355f5).

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 38 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 81 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  2 -
 4 files changed, 122 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index edf9a23..696f2ae 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -332,44 +332,6 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
return 0;
 }
 
-/**
- *hns_mac_del_mac - delete mac address into dsaf table,can't delete the same
- *  address twice
- *@net_dev: net device
- *@vfn :   vf lan
- *@mac : mac address
- *return status
- */
-int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac)
-{
-   struct mac_entry_idx *old_mac;
-   struct dsaf_device *dsaf_dev;
-   u32 ret;
-
-   dsaf_dev = mac_cb->dsaf_dev;
-
-   if (vfn < DSAF_MAX_VM_NUM) {
-   old_mac = &mac_cb->addr_entry_idx[vfn];
-   } else {
-   dev_err(mac_cb->dev,
-   "vf queue is too large, %s mac%d queue = %#x!\n",
-   mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vfn);
-   return -EINVAL;
-   }
-
-   if (dsaf_dev) {
-   ret = hns_dsaf_del_mac_entry(dsaf_dev, old_mac->vlan_id,
-mac_cb->mac_id, old_mac->addr);
-   if (ret)
-   return ret;
-
-   if (memcmp(old_mac->addr, mac, sizeof(old_mac->addr)) == 0)
-   old_mac->valid = 0;
-   }
-
-   return 0;
-}
-
 int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn)
 {
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index 7f14d91..e6842c9 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -436,7 +436,6 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
 int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vm, bool enable);
 void hns_mac_start(struct hns_mac_cb *mac_cb);
 void hns_mac_stop(struct hns_mac_cb *mac_cb);
-int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac);
 void hns_mac_uninit(struct dsaf_device *dsaf_dev);
 void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex);
 void hns_mac_reset(struct hns_mac_cb *mac_cb);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 90dbda7..6a069ff 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -1647,87 +1647,6 @@ int hns_dsaf_rm_mac_addr(
  mac_entry->addr);
 }
 
-/**
- * hns_dsaf_set_mac_mc_entry - set mac mc-entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mc-mac entry
- */
-int hns_dsaf_set_mac_mc_entry(
-   struct dsaf_device *dsaf_dev,
-   struct dsaf_drv_mac_multi_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   struct dsaf_drv_tbl_tcam_key mac_key;
-   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_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)) {
-   dev_err(dsaf_dev->dev, "set uc %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 ie exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*if hasnot, find enpty entry*/
-   entry_index = hns_dsaf_find_empty_mac_entry(dsaf_dev);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*if hasnot empty, error*/
-

[PATCH net 18/19] net: hns: Avoid Hip06 chip TX packet line bug

2017-03-30 Thread Salil Mehta
From: lipeng 

There is a bug on Hip06 that tx ring interrupts packets count will be
clear when drivers send data to tx ring, so that the tx packets count
will never upgrade to packets line, and cause the interrupts engendered
was delayed.
Sometimes, it will cause sending performance lower than expected.

To fix this bug, we set tx ring interrupts packets line to 1 forever,
to avoid count clear. And set the gap time to 20us, to solve the problem
that too many interrupts engendered when packets line is 1.

This patch could advance the send performance on ARM  from 6.6G to 9.37G
when an iperf send thread on ARM and an iperf send thread on X86 for XGE.

Signed-off-by: lipeng 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c |   5 ++
 drivers/net/ethernet/hisilicon/hns/hnae.h |   6 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  78 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 101 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h |  23 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |   2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  |  24 +++--
 7 files changed, 169 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index 513c257..8950b74 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -57,10 +57,15 @@ static int hnae_alloc_buffer(struct hnae_ring *ring, struct 
hnae_desc_cb *cb)
 
 static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
 {
+   if (unlikely(!cb->priv))
+   return;
+
if (cb->type == DESC_TYPE_SKB)
dev_kfree_skb_any((struct sk_buff *)cb->priv);
else if (unlikely(is_rx_ring(ring)))
put_page((struct page *)cb->priv);
+
+   cb->priv = NULL;
 }
 
 static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 987880b..a2c49ea 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -488,11 +488,11 @@ struct hnae_ae_ops {
  u32 auto_neg, u32 rx_en, u32 tx_en);
void (*get_coalesce_usecs)(struct hnae_handle *handle,
   u32 *tx_usecs, u32 *rx_usecs);
-   void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
-   u32 *tx_frames, u32 *rx_frames);
+   void (*get_max_coalesced_frames)(struct hnae_handle *handle,
+u32 *tx_frames, u32 *rx_frames);
int (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
int (*set_coalesce_frames)(struct hnae_handle *handle,
-  u32 coalesce_frames);
+  u32 tx_frames, u32 rx_frames);
void (*get_coalesce_range)(struct hnae_handle *handle,
   u32 *tx_frames_low, u32 *rx_frames_low,
   u32 *tx_frames_high, u32 *rx_frames_high,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 58b51e5..84c8b9f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -492,15 +492,21 @@ static void hns_ae_get_coalesce_usecs(struct hnae_handle 
*handle,
   ring_pair->port_id_in_comm);
 }
 
-static void hns_ae_get_rx_max_coalesced_frames(struct hnae_handle *handle,
-  u32 *tx_frames, u32 *rx_frames)
+static void hns_ae_get_max_coalesced_frames(struct hnae_handle *handle,
+   u32 *tx_frames, u32 *rx_frames)
 {
struct ring_pair_cb *ring_pair =
container_of(handle->qs[0], struct ring_pair_cb, q);
+   struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);
 
-   *tx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
- ring_pair->port_id_in_comm);
-   *rx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
+   if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
+   handle->port_type == HNAE_PORT_DEBUG)
+   *tx_frames = hns_rcb_get_rx_coalesced_frames(
+   ring_pair->rcb_common, ring_pair->port_id_in_comm);
+   else
+   *tx_frames = hns_rcb_get_tx_coalesced_frames(
+   ring_pair->rcb_common, ring_pair->port_id_in_comm);
+   *rx_frames = hns_rcb_get_rx_coalesced_frames(ring_pair->rcb_common,
  ring_pair->port_id_in_comm);
 }
 
@@ -514,

[PATCH net 15/19] net: hns: Optimise the code in hns_mdio_wait_ready()

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

This patch fixes the code to clear pclint warning/info.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index fad1c5b..e5221d9 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -175,18 +175,20 @@ static int mdio_sc_cfg_reg_write(struct hns_mdio_device 
*mdio_dev,
 static int hns_mdio_wait_ready(struct mii_bus *bus)
 {
struct hns_mdio_device *mdio_dev = bus->priv;
+   u32 cmd_reg_value;
int i;
-   u32 cmd_reg_value = 1;
 
/* waitting for MDIO_COMMAND_REG 's mdio_start==0 */
/* after that can do read or write*/
-   for (i = 0; cmd_reg_value; i++) {
+   for (i = 0; i < MDIO_TIMEOUT; i++) {
cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
 MDIO_COMMAND_REG,
 MDIO_CMD_START_B);
-   if (i == MDIO_TIMEOUT)
-   return -ETIMEDOUT;
+   if (!cmd_reg_value)
+   break;
}
+   if ((i == MDIO_TIMEOUT) && cmd_reg_value)
+   return -ETIMEDOUT;
 
return 0;
 }
-- 
2.7.4




[PATCH net 12/19] net: hns: Remove redundant mac_get_id()

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

There is a mac_id in mac control block structure, so the callback
function mac_get_id() is useless. Here we remove this function.

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c  |  8 
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h   |  2 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 13 -
 3 files changed, 23 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 723f3ae..035db86 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -466,13 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
 static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info)
 {
enum hns_gmac_duplex_mdoe duplex;
@@ -714,7 +707,6 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc;
mac_drv->config_half_duplex = hns_gmac_set_duplex_type;
mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames;
-   mac_drv->mac_get_id = hns_gmac_get_id;
mac_drv->get_info = hns_gmac_get_info;
mac_drv->autoneg_stat = hns_gmac_autoneg_stat;
mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index e6842c9..24dfba5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -373,8 +373,6 @@ struct mac_driver {
void (*set_rx_ignore_pause_frames)(void *mac_drv, u32 enable);
/* config rx mode for promiscuous*/
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);
 
void (*autoneg_stat)(void *mac_drv, u32 *enable);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index aae830a..37a2fc3 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -300,18 +300,6 @@ static void hns_xgmac_set_tx_auto_pause_frames(void 
*mac_drv, u16 enable)
 }
 
 /**
- *hns_xgmac_get_id - get xgmac port id
- *@mac_drv: mac driver
- *@newval:xgmac max frame length
- */
-static void hns_xgmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
-/**
  *hns_xgmac_config_max_frame_length - set xgmac max frame length
  *@mac_drv: mac driver
  *@newval:xgmac max frame length
@@ -833,7 +821,6 @@ void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_half_duplex = NULL;
mac_drv->set_rx_ignore_pause_frames =
hns_xgmac_set_rx_ignore_pause_frames;
-   mac_drv->mac_get_id = hns_xgmac_get_id;
mac_drv->mac_free = hns_xgmac_free;
mac_drv->adjust_link = NULL;
mac_drv->set_tx_auto_pause_frames = hns_xgmac_set_tx_auto_pause_frames;
-- 
2.7.4




[PATCH net 14/19] net: hns: Clean redundant code from hns_mdio.c file

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

This patch cleans the redundant code from  hns_mdio.c.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index 501eb20..fad1c5b 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -23,17 +23,9 @@
 #include 
 #include 
 #include 
-#include 
 
 #define MDIO_DRV_NAME "Hi-HNS_MDIO"
 #define MDIO_BUS_NAME "Hisilicon MII Bus"
-#define MDIO_DRV_VERSION "1.3.0"
-#define MDIO_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
-#define MDIO_DRV_STRING MDIO_BUS_NAME
-#define MDIO_DEFAULT_DEVICE_DESCR MDIO_BUS_NAME
-
-#define MDIO_CTL_DEV_ADDR(x)   (x & 0x1f)
-#define MDIO_CTL_PORT_ADDR(x)  ((x & 0x1f) << 5)
 
 #define MDIO_TIMEOUT   100
 
@@ -64,9 +56,7 @@ struct hns_mdio_device {
 #define MDIO_CMD_DEVAD_S   0
 #define MDIO_CMD_PRTAD_M   0x1f
 #define MDIO_CMD_PRTAD_S   5
-#define MDIO_CMD_OP_M  0x3
 #define MDIO_CMD_OP_S  10
-#define MDIO_CMD_ST_M  0x3
 #define MDIO_CMD_ST_S  12
 #define MDIO_CMD_START_B   14
 
-- 
2.7.4




[PATCH net 09/19] net: hns: Replace netif_tx_lock to ring spin lock

2017-03-30 Thread Salil Mehta
From: lipeng 

netif_tx_lock is a global spin lock, it will take affect
in all rings in the netdevice. In tx_poll_one process, it can
only lock the current ring, in this case, we define a spin lock
in hnae_ring struct for it.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c |  1 +
 drivers/net/ethernet/hisilicon/hns/hnae.h |  3 +++
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 21 +++--
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index 78af663..513c257 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -196,6 +196,7 @@ hnae_init_ring(struct hnae_queue *q, struct hnae_ring 
*ring, int flags)
 
ring->q = q;
ring->flags = flags;
+   spin_lock_init(&ring->lock);
assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
 
/* not matter for tx or rx ring, the ntc and ntc start from 0 */
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index ad79a76..987880b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -275,6 +275,9 @@ struct hnae_ring {
/* statistic */
struct ring_stats stats;
 
+   /* ring lock for poll one */
+   spinlock_t lock;
+
dma_addr_t desc_dma_addr;
u32 buf_size;   /* size for hnae_desc->addr, preset by AE */
u16 desc_num;   /* total number of desc */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 2a12764..c4aa095 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -924,12 +924,13 @@ static int is_valid_clean_head(struct hnae_ring *ring, 
int h)
 
 /* netif_tx_lock will turn down the performance, set only when necessary */
 #ifdef CONFIG_NET_POLL_CONTROLLER
-#define NETIF_TX_LOCK(ndev) netif_tx_lock(ndev)
-#define NETIF_TX_UNLOCK(ndev) netif_tx_unlock(ndev)
+#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
+#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
 #else
-#define NETIF_TX_LOCK(ndev)
-#define NETIF_TX_UNLOCK(ndev)
+#define NETIF_TX_LOCK(ring)
+#define NETIF_TX_UNLOCK(ring)
 #endif
+
 /* reclaim all desc in one budget
  * return error or number of desc left
  */
@@ -943,13 +944,13 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
int head;
int bytes, pkts;
 
-   NETIF_TX_LOCK(ndev);
+   NETIF_TX_LOCK(ring);
 
head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
rmb(); /* make sure head is ready before touch any data */
 
if (is_ring_empty(ring) || head == ring->next_to_clean) {
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
return 0; /* no data to poll */
}
 
@@ -957,7 +958,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
netdev_err(ndev, "wrong head (%d, %d-%d)\n", head,
   ring->next_to_use, ring->next_to_clean);
ring->stats.io_err_cnt++;
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
return -EIO;
}
 
@@ -969,7 +970,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
prefetch(&ring->desc_cb[ring->next_to_clean]);
}
 
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
 
dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
netdev_tx_completed_queue(dev_queue, pkts, bytes);
@@ -1030,7 +1031,7 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
int head;
int bytes, pkts;
 
-   NETIF_TX_LOCK(ndev);
+   NETIF_TX_LOCK(ring);
 
head = ring->next_to_use; /* ntu :soft setted ring position*/
bytes = 0;
@@ -1038,7 +1039,7 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
while (head != ring->next_to_clean)
hns_nic_reclaim_one_desc(ring, &bytes, &pkts);
 
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
 
dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
netdev_tx_reset_queue(dev_queue);
-- 
2.7.4




[PATCH net 13/19] net: hns: Remove redundant mac table operations

2017-03-30 Thread Salil Mehta
From: Kejian Yan 

This patch removes redundant functions used only for debugging
purposes.

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 160 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  10 --
 2 files changed, 170 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 6a069ff..abd8aec 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -2008,166 +2008,6 @@ int hns_dsaf_clr_mac_mc_port(struct dsaf_device 
*dsaf_dev, u8 mac_id,
return ret;
 }
 
-/**
- * hns_dsaf_get_mac_uc_entry - get mac uc entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
- struct dsaf_drv_mac_single_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   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) ||
-   MAC_IS_BROADCAST(mac_entry->addr)) {
-   dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
-   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);
-
-   /*check exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*find none, error */
-   dev_err(dsaf_dev->dev,
-   "get_uc_entry failed, %s Mac key(%#x:%#x)\n",
-   dsaf_dev->ae_dev.name,
-   mac_key.high.val, mac_key.low.val);
-   return -EINVAL;
-   }
-   dev_dbg(dsaf_dev->dev,
-   "get_uc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
-   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, &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;
-}
-
-/**
- * hns_dsaf_get_mac_mc_entry - get mac mc entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
- struct dsaf_drv_mac_multi_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   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) ||
-   MAC_IS_BROADCAST(mac_entry->addr)) {
-   dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
-   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);
-
-   /*check exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /* find none, error */
-   dev_err(dsaf_dev->dev,
-   "get_mac_uc_entry failed, %s Mac key(%#x:%#x)\n",
-   dsaf_dev->ae_dev.name, mac_key.high.val,
-   mac_key.low.val);
-   return -EINVAL;
-   }
-   dev_dbg(dsaf_dev->dev,
-   "get_mac_uc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
-   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, &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;
-}
-
-/**
- * hns_dsaf_get_mac_entry_by_index - get mac entry by tab index
- * @dsaf_dev: dsa fabric device struct pointer
- * @entry_index: tab entry index
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_entry_by_index(
-   s

[PATCH net 05/19] net: hns: Remove redundant memset during buffer release

2017-03-30 Thread Salil Mehta
From: lipeng 

Because all members of desc_cb is assigned when xmit one package, so it
can delete in hnae_free_buffer, as follows:
- "dma, priv, length, type" are assigned in fill_v2_desc.
- "page_offset, reuse_flag, buf" are not used in tx direction.

Signed-off-by: lipeng 
Signed-off-by: Weiwei Deng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index b6ed818..78af663 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -61,7 +61,6 @@ static void hnae_free_buffer(struct hnae_ring *ring, struct 
hnae_desc_cb *cb)
dev_kfree_skb_any((struct sk_buff *)cb->priv);
else if (unlikely(is_rx_ring(ring)))
put_page((struct page *)cb->priv);
-   memset(cb, 0, sizeof(*cb));
 }
 
 static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
-- 
2.7.4




[PATCH net 07/19] net: hns: Optimize hns_nic_common_poll for better performance

2017-03-30 Thread Salil Mehta
From: lipeng 

After polling less than buget packages, we need check again. If
there are still some packages, we call napi_schedule add softirq
queue, this is not better way. So we return buget value instead
of napi_schedule.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 50 ---
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  2 +-
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 646f601..a083660 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -861,7 +861,7 @@ static int hns_nic_rx_poll_one(struct hns_nic_ring_data 
*ring_data,
return recv_pkts;
 }
 
-static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int num = 0;
@@ -875,22 +875,23 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data 
*ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);
 
-   napi_schedule(&ring_data->napi);
+   return false;
+   } else {
+   return true;
}
 }
 
-static void hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
-   int num = 0;
+   int num;
 
num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
 
-   if (num == 0)
-   ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-   ring, 0);
+   if (!num)
+   return true;
else
-   napi_schedule(&ring_data->napi);
+   return false;
 }
 
 static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
@@ -991,7 +992,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
return 0;
 }
 
-static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int head;
@@ -1004,20 +1005,21 @@ static void hns_nic_tx_fini_pro(struct 
hns_nic_ring_data *ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);
 
-   napi_schedule(&ring_data->napi);
+   return false;
+   } else {
+   return true;
}
 }
 
-static void hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
 
if (head == ring->next_to_clean)
-   ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-   ring, 0);
+   return true;
else
-   napi_schedule(&ring_data->napi);
+   return false;
 }
 
 static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
@@ -1044,15 +1046,23 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
 
 static int hns_nic_common_poll(struct napi_struct *napi, int budget)
 {
+   int clean_complete = 0;
struct hns_nic_ring_data *ring_data =
container_of(napi, struct hns_nic_ring_data, napi);
-   int clean_complete = ring_data->poll_one(
-   ring_data, budget, ring_data->ex_process);
+   struct hnae_ring *ring = ring_data->ring;
 
-   if (clean_complete >= 0 && clean_complete < budget) {
-   napi_complete(napi);
-   ring_data->fini_process(ring_data);
-   return 0;
+try_again:
+   clean_complete += ring_data->poll_one(
+   ring_data, budget - clean_complete,
+   ring_data->ex_process);
+
+   if (clean_complete < budget) {
+   if (ring_data->fini_process(ring_data)) {
+   napi_complete(napi);
+   ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
+   } else {
+   goto try_again;
+   }
}
 
return clean_complete;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
index fff8f8a..1b83232 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
@@ -41,7 +41,7 @@

[PATCH net 04/19] net: hns: Change the TX queue selection algorithm

2017-03-30 Thread Salil Mehta
From: lipeng 

This patch changes the TX queue selection algorithm from default
to based on tuple {sport,dport,sip,dip}/indirection table
similar to used during RX with Receive Side Scaling.

Signed-off-by: lipeng 
Signed-off-by: Weiwei Deng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |  2 +
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  5 ++
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 63 +++
 3 files changed, 70 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 8016854..85df7c7 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -545,6 +545,8 @@ struct hnae_handle {
int vf_id;
u32 eport_id;
u32 dport_id;   /* v2 tx bd should fill the dport_id */
+   u32 *rss_key;
+   u32 *rss_indir_table;
enum hnae_port_type port_type;
enum hnae_media_type media_type;
struct list_head node;/* list to hnae_ae_dev->handle_list */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 0a9cdf0..abafa25 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -80,6 +80,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev,
struct hnae_handle *ae_handle;
struct ring_pair_cb *ring_pair_cb;
struct hnae_vf_cb *vf_cb;
+   struct hns_ppe_cb *ppe_cb;
 
dsaf_dev = hns_ae_get_dsaf_dev(dev);
 
@@ -127,11 +128,15 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev 
*dev,
vf_cb->port_index = port_id;
vf_cb->mac_cb = dsaf_dev->mac_cb[port_id];
 
+   ppe_cb = hns_get_ppe_cb(ae_handle);
+
ae_handle->phy_if = vf_cb->mac_cb->phy_if;
ae_handle->phy_dev = vf_cb->mac_cb->phy_dev;
ae_handle->if_support = vf_cb->mac_cb->if_support;
ae_handle->port_type = vf_cb->mac_cb->mac_type;
ae_handle->media_type = vf_cb->mac_cb->media_type;
+   ae_handle->rss_key = ppe_cb->rss_key;
+   ae_handle->rss_indir_table = ppe_cb->rss_indir_table;
ae_handle->dport_id = port_id;
 
return ae_handle;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 73ec8c8..646f601 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -40,6 +40,8 @@
 #define SKB_TMP_LEN(SKB) \
(((SKB)->transport_header - (SKB)->mac_header) + tcp_hdrlen(SKB))
 
+#define INVALID_TX_RING0x
+
 static void fill_v2_desc(struct hnae_ring *ring, void *priv,
 int size, dma_addr_t dma, int frag_end,
 int buf_num, enum hns_desc_type type, int mtu)
@@ -1657,17 +1659,78 @@ static void hns_nic_get_stats64(struct net_device *ndev,
stats->tx_compressed = ndev->stats.tx_compressed;
 }
 
+static u32 hns_calc_tx_rss(u32 sip, u32 dip, u32 sport, u32 dport, u32 
*rss_key)
+{
+   u32 rss = 0;
+   int i;
+   u32 port;
+
+   port = (sport << 16) | dport;
+
+   for (i = 0; i < 32; i++)
+   if (sip & (1 << (31 - i)))
+   rss ^= (rss_key[9] << i) |
+   (u32)((u64)rss_key[8] >> (32 - i));
+
+   for (i = 0; i < 32; i++)
+   if (dip & (1 << (31 - i)))
+   rss ^= (rss_key[8] << i) |
+   (u32)((u64)rss_key[7] >> (32 - i));
+
+   for (i = 0; i < 32; i++)
+   if (port & (1 << (31 - i)))
+   rss ^= (rss_key[7] << i) |
+   (u32)((u64)rss_key[6] >> (32 - i));
+
+   return rss;
+}
+
+/* if tcp or udp, then calc tx ring index */
+static u16 hns_calc_tx_ring_idx(struct hns_nic_priv *priv,
+   struct sk_buff *skb)
+{
+   struct hnae_handle *handle;
+   struct iphdr *iphdr;
+   struct tcphdr *tcphdr;
+   u32 rss;
+   int protocol;
+   u16 ring = INVALID_TX_RING;
+
+   if (skb->protocol == htons(ETH_P_IP)) {
+   iphdr = ip_hdr(skb);
+   protocol = iphdr->protocol;
+   if (protocol == IPPROTO_TCP) {
+   /* because tcp and udp dest and src port is same */
+   tcphdr = tcp_hdr(skb);
+   handle = priv->ae_handle;
+   rss = hns_calc_tx_rss(ntohl(iphdr->daddr),
+ ntohl(iphdr->saddr),
+ ntohs(tcphdr->dest),
+ 

[PATCH net] net: hns: Add ACPI support to check SFP present

2017-03-30 Thread Salil Mehta
From: Daode Huang 

The current code only supports DT to check SFP present.
This patch adds ACPI support as well.

Signed-off-by: Daode Huang 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 11 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 28 +-
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 696f2ae..0c1f56e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -82,9 +82,12 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 
*link_status)
else
*link_status = 0;
 
-   ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, &sfp_prsnt);
-   if (!ret)
-   *link_status = *link_status && sfp_prsnt;
+   if (mac_cb->media_type == HNAE_MEDIA_TYPE_FIBER) {
+   ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb,
+  &sfp_prsnt);
+   if (!ret)
+   *link_status = *link_status && sfp_prsnt;
+   }
 
mac_cb->link = *link_status;
 }
@@ -816,7 +819,7 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
of_node_put(np);
 
np = of_parse_phandle(to_of_node(mac_cb->fw_port),
-   "serdes-syscon", 0);
+ "serdes-syscon", 0);
syscon = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR_OR_NULL(syscon)) {
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index a2c22d0..e13aa06 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -461,6 +461,32 @@ int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int 
*sfp_prsnt)
return 0;
 }
 
+int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
+{
+   union acpi_object *obj;
+   union acpi_object obj_args, argv4;
+
+   obj_args.integer.type = ACPI_TYPE_INTEGER;
+   obj_args.integer.value = mac_cb->mac_id;
+
+   argv4.type = ACPI_TYPE_PACKAGE,
+   argv4.package.count = 1,
+   argv4.package.elements = &obj_args,
+
+   obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
+   hns_dsaf_acpi_dsm_uuid, 0,
+   HNS_OP_GET_SFP_STAT_FUNC, &argv4);
+
+   if (!obj || obj->type != ACPI_TYPE_INTEGER)
+   return -ENODEV;
+
+   *sfp_prsnt = obj->integer.value;
+
+   ACPI_FREE(obj);
+
+   return 0;
+}
+
 /**
  * hns_mac_config_sds_loopback - set loop back for serdes
  * @mac_cb: mac control block
@@ -592,7 +618,7 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device 
*dsaf_dev)
misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
 
misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
-   misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
+   misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
 
misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
} else {
-- 
2.7.4




[PATCH net 06/19] net: hns: bug fix of ethtool show the speed

2017-03-30 Thread Salil Mehta
From: Daode Huang 

When run ethtool ethX on hns driver, the speed will show
as "Unknown". The base.speed is not correct assigned,
this patch fix this bug.

Signed-off-by: Daode Huang 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3ac2183..3404eac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -146,7 +146,7 @@ static int hns_nic_get_link_ksettings(struct net_device 
*net_dev,
 
/* When there is no phy, autoneg is off. */
cmd->base.autoneg = false;
-   cmd->base.cmd = speed;
+   cmd->base.speed = speed;
cmd->base.duplex = duplex;
 
if (net_dev->phydev)
-- 
2.7.4




[PATCH net 01/19] net: hns: Fix the implementation of irq affinity function

2017-03-30 Thread Salil Mehta
From: lipeng 

This patch fixes the implementation of the IRQ affinity
function. This function is used to create the cpu mask
which eventually is used to initialize the cpu<->queue
association for XPS(Transmit Packet Steering).

Signed-off-by: lipeng 
Signed-off-by: Kejian Yan 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 75 +++
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  1 +
 2 files changed, 30 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index fca37e2..73ec8c8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1196,54 +1196,31 @@ static void hns_nic_ring_close(struct net_device 
*netdev, int idx)
napi_disable(&priv->ring_data[idx].napi);
 }
 
-static void hns_set_irq_affinity(struct hns_nic_priv *priv)
+static int hns_nic_init_affinity_mask(int q_num, int ring_idx,
+ struct hnae_ring *ring, cpumask_t *mask)
 {
-   struct hnae_handle *h = priv->ae_handle;
-   struct hns_nic_ring_data *rd;
-   int i;
int cpu;
-   cpumask_var_t mask;
 
-   if (!alloc_cpumask_var(&mask, GFP_KERNEL))
-   return;
-
-   /*diffrent irq banlance for 16core and 32core*/
-   if (h->q_num == num_possible_cpus()) {
-   for (i = 0; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   /* Diffrent irq banlance between 16core and 32core.
+* The cpu mask set by ring index according to the ring flag
+* which indicate the ring is tx or rx.
+*/
+   if (q_num == num_possible_cpus()) {
+   if (is_tx_ring(ring))
+   cpu = ring_idx;
+   else
+   cpu = ring_idx - q_num;
} else {
-   for (i = 0; i < h->q_num; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
-
-   for (i = h->q_num; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2 + 1)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2 + 1;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   if (is_tx_ring(ring))
+   cpu = ring_idx * 2;
+   else
+   cpu = (ring_idx - q_num) * 2 + 1;
}
 
-   free_cpumask_var(mask);
+   cpumask_clear(mask);
+   cpumask_set_cpu(cpu, mask);
+
+   return cpu;
 }
 
 static int hns_nic_init_irq(struct hns_nic_priv *priv)
@@ -1252,6 +1229,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
struct hns_nic_ring_data *rd;
int i;
int ret;
+   int cpu;
 
for (i = 0; i < h->q_num * 2; i++) {
rd = &priv->ring_data[i];
@@ -1261,7 +1239,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
 
snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN,
 "%s-%s%d", priv->netdev->name,
-(i < h->q_num ? "tx" : "rx"), rd->queue_index);
+(is_tx_ring(rd->ring) ? "tx" : "rx"), rd->queue_index);
 
rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
 
@@ -1273,12 +1251,17 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
return ret;
}
disable_irq(rd->ring->irq);
+
+   cpu = hns_nic_init_affinity_mask(h->q_num, i,
+rd->ring, &rd-&

[PATCH net 03/19] net: hns: Optimize the code for GMAC pad and crc Config

2017-03-30 Thread Salil Mehta
From: lipeng 

This patch optimises the init configuration code leg
for gmac pad and crc set interface.

Signed-off-by: lipeng 
Signed-off-by: JinchuanTian 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 36 ++
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index a8dbe00..723f3ae 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -148,6 +148,17 @@ static void hns_gmac_config_max_frame_length(void 
*mac_drv, u16 newval)
   GMAC_MAX_FRM_SIZE_S, newval);
 }
 
+static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
+{
+   u32 tx_ctrl;
+   struct mac_driver *drv = (struct mac_driver *)mac_drv;
+
+   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
+   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
+}
+
 static void hns_gmac_config_an_mode(void *mac_drv, u8 newval)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
@@ -250,7 +261,6 @@ static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 
*rx_pause_en,
 static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
u32 full_duplex)
 {
-   u32 tx_ctrl;
struct mac_driver *drv = (struct mac_driver *)mac_drv;
 
dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG,
@@ -279,14 +289,6 @@ static int hns_gmac_adjust_link(void *mac_drv, enum 
mac_speed speed,
return -EINVAL;
}
 
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, 1);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, 1);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-
-   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
-GMAC_MODE_CHANGE_EB_B, 1);
-
return 0;
 }
 
@@ -326,6 +328,11 @@ static void hns_gmac_init(void *mac_drv)
if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
hns_gmac_set_uc_match(mac_drv, 0);
 
+   hns_gmac_config_pad_and_crc(mac_drv, 1);
+
+   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
+GMAC_MODE_CHANGE_EB_B, 1);
+
/* reduce gmac tx water line to avoid gmac hang-up
 * in speed 100M and duplex half.
 */
@@ -459,17 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
-{
-   u32 tx_ctrl;
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-}
-
 static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
-- 
2.7.4




[PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code Improvements

2017-03-30 Thread Salil Mehta
This patch set introduces various HNS bug fixes, optimizations and code
improvements.

Daode Huang (1):
  net: hns: bug fix of ethtool show the speed

Kejian Yan (7):
  net: hns: Remove the redundant adding and deleting mac function
  net: hns: Remove redundant mac_get_id()
  net: hns: Remove redundant mac table operations
  net: hns: Clean redundant code from hns_mdio.c file
  net: hns: Optimise the code in hns_mdio_wait_ready()
  net: hns: Simplify the exception sequence in hns_ppe_init()
  net: hns: Adjust the SBM module buffer threshold

Salil Mehta (1):
  net: hns: Some checkpatch.pl script & warning fixes

lipeng (10):
  net: hns: Fix the implementation of irq affinity function
  net: hns: Modify GMAC init TX threshold value
  net: hns: Optimize the code for GMAC pad and crc Config
  net: hns: Change the TX queue selection algorithm
  net: hns: Remove redundant memset during buffer release
  net: hns: Optimize hns_nic_common_poll for better performance
  net: hns: Fix to adjust buf_size of ring according to mtu
  net: hns: Replace netif_tx_lock to ring spin lock
  net: hns: Correct HNS RSS key set function
  net: hns: Avoid Hip06 chip TX packet line bug

 drivers/net/ethernet/hisilicon/hns/hnae.c  |   7 +-
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  49 ++-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  | 132 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  61 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |  41 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |   5 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 249 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  14 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c  |  17 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  | 143 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h  |  26 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |   6 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c|  13 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  | 463 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.h  |   3 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  34 +-
 drivers/net/ethernet/hisilicon/hns_mdio.c  |  20 +-
 17 files changed, 723 insertions(+), 560 deletions(-)

-- 
2.7.4




RE: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code Improvements

2017-03-30 Thread Salil Mehta

> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Thursday, March 30, 2017 6:09 PM
> To: Salil Mehta
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code
> Improvements
> 
> From: Salil Mehta 
> Date: Thu, 30 Mar 2017 16:30:47 +0100
> 
> > This patch set introduces various HNS bug fixes, optimizations and code
> > improvements.
> 
> What tree are you targetting?
> 
> You say "net" in your Subject lines, but this series has cleanups and all
> sorts
> of other things which are absolutely not appropriate for 'net' and are
> 'net-next'
> material.
Hi David,
Sorry David, These bug fixes are for the next merge window and for net-next.
Should I resend the patches with below change?

>>>>[PATCH net-next 00/19] net: hns: Misc. HNS Bug Fixes & Code Improvements  

Best regards
Salil



RE: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code Improvements

2017-03-30 Thread Salil Mehta


> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Thursday, March 30, 2017 6:22 PM
> To: Salil Mehta
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code
> Improvements
> 
> From: Salil Mehta 
> Date: Thu, 30 Mar 2017 17:19:44 +
> 
> >
> >> -Original Message-
> >> From: David Miller [mailto:da...@davemloft.net]
> >> Sent: Thursday, March 30, 2017 6:09 PM
> >> To: Salil Mehta
> >> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> >> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> >> Subject: Re: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code
> >> Improvements
> >>
> >> From: Salil Mehta 
> >> Date: Thu, 30 Mar 2017 16:30:47 +0100
> >>
> >> > This patch set introduces various HNS bug fixes, optimizations and
> code
> >> > improvements.
> >>
> >> What tree are you targetting?
> >>
> >> You say "net" in your Subject lines, but this series has cleanups
> and all
> >> sorts
> >> of other things which are absolutely not appropriate for 'net' and
> are
> >> 'net-next'
> >> material.
> > Hi David,
> > Sorry David, These bug fixes are for the next merge window and for
> net-next.
> > Should I resend the patches with below change?
> 
> It is not necessary to resend, thanks for clarifying.
Sure thanks.


RE: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code Improvements

2017-03-31 Thread Salil Mehta


> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Friday, March 31, 2017 4:03 AM
> To: Salil Mehta
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH net 00/19] net: hns: Misc. HNS Bug Fixes & Code
> Improvements
> 
> From: Salil Mehta 
> Date: Thu, 30 Mar 2017 16:30:47 +0100
> 
> > This patch set introduces various HNS bug fixes, optimizations and
> code
> > improvements.
> 
> There is no way you should do such an expensive calculation for every
> single transmit packet as you are doing in your select_queue() routine.
> 
> That's really crazy.
> 
> Just use the networking stack's queue selection scheme, or suggest
> ways to improve it.  Don't do private hashing like this in your
> driver, please!
Hi David,
I got your point. I will drop this patch from this patch-set for now.

Thanks
Salil 










[PATCH V2 net-next 04/18] net: hns: Remove redundant memset during buffer release

2017-03-31 Thread Salil Mehta
From: lipeng 

Because all members of desc_cb is assigned when xmit one package, so it
can delete in hnae_free_buffer, as follows:
- "dma, priv, length, type" are assigned in fill_v2_desc.
- "page_offset, reuse_flag, buf" are not used in tx direction.

Signed-off-by: lipeng 
Signed-off-by: Weiwei Deng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index b6ed818..78af663 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -61,7 +61,6 @@ static void hnae_free_buffer(struct hnae_ring *ring, struct 
hnae_desc_cb *cb)
dev_kfree_skb_any((struct sk_buff *)cb->priv);
else if (unlikely(is_rx_ring(ring)))
put_page((struct page *)cb->priv);
-   memset(cb, 0, sizeof(*cb));
 }
 
 static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
-- 
2.7.4




[PATCH V2 net-next 00/18] net: hns: Misc. HNS Bug Fixes & Code Improvements

2017-03-31 Thread Salil Mehta
This patch set introduces various HNS bug fixes, optimizations and code
improvements.

Daode Huang (1):
  net: hns: bug fix of ethtool show the speed

Kejian Yan (7):
  net: hns: Remove the redundant adding and deleting mac function
  net: hns: Remove redundant mac_get_id()
  net: hns: Remove redundant mac table operations
  net: hns: Clean redundant code from hns_mdio.c file
  net: hns: Optimise the code in hns_mdio_wait_ready()
  net: hns: Simplify the exception sequence in hns_ppe_init()
  net: hns: Adjust the SBM module buffer threshold

Salil Mehta (1):
  net: hns: Some checkpatch.pl script & warning fixes

lipeng (9):
  net: hns: Fix the implementation of irq affinity function
  net: hns: Modify GMAC init TX threshold value
  net: hns: Optimize the code for GMAC pad and crc Config
  net: hns: Remove redundant memset during buffer release
  net: hns: Optimize hns_nic_common_poll for better performance
  net: hns: Fix to adjust buf_size of ring according to mtu
  net: hns: Replace netif_tx_lock to ring spin lock
  net: hns: Correct HNS RSS key set function
  net: hns: Avoid Hip06 chip TX packet line bug

 drivers/net/ethernet/hisilicon/hns/hnae.c  |   7 +-
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  47 ++-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  | 127 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  61 ++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |  41 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |   5 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 249 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  14 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c  |  17 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  | 143 ++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h  |  26 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |   6 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c|  13 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  | 400 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.h  |   3 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  34 +-
 drivers/net/ethernet/hisilicon/hns_mdio.c  |  20 +-
 17 files changed, 653 insertions(+), 560 deletions(-)

-- 
2.7.4




[PATCH V2 net-next 05/18] net: hns: bug fix of ethtool show the speed

2017-03-31 Thread Salil Mehta
From: Daode Huang 

When run ethtool ethX on hns driver, the speed will show
as "Unknown". The base.speed is not correct assigned,
this patch fix this bug.

Signed-off-by: Daode Huang 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3ac2183..3404eac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -146,7 +146,7 @@ static int hns_nic_get_link_ksettings(struct net_device 
*net_dev,
 
/* When there is no phy, autoneg is off. */
cmd->base.autoneg = false;
-   cmd->base.cmd = speed;
+   cmd->base.speed = speed;
cmd->base.duplex = duplex;
 
if (net_dev->phydev)
-- 
2.7.4




[PATCH V2 net-next 06/18] net: hns: Optimize hns_nic_common_poll for better performance

2017-03-31 Thread Salil Mehta
From: lipeng 

After polling less than buget packages, we need check again. If
there are still some packages, we call napi_schedule add softirq
queue, this is not better way. So we return buget value instead
of napi_schedule.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 50 ---
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  2 +-
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 73ec8c8..5f67db2 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -859,7 +859,7 @@ static int hns_nic_rx_poll_one(struct hns_nic_ring_data 
*ring_data,
return recv_pkts;
 }
 
-static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int num = 0;
@@ -873,22 +873,23 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data 
*ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);
 
-   napi_schedule(&ring_data->napi);
+   return false;
+   } else {
+   return true;
}
 }
 
-static void hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
-   int num = 0;
+   int num;
 
num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
 
-   if (num == 0)
-   ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-   ring, 0);
+   if (!num)
+   return true;
else
-   napi_schedule(&ring_data->napi);
+   return false;
 }
 
 static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
@@ -989,7 +990,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
return 0;
 }
 
-static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int head;
@@ -1002,20 +1003,21 @@ static void hns_nic_tx_fini_pro(struct 
hns_nic_ring_data *ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);
 
-   napi_schedule(&ring_data->napi);
+   return false;
+   } else {
+   return true;
}
 }
 
-static void hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
struct hnae_ring *ring = ring_data->ring;
int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
 
if (head == ring->next_to_clean)
-   ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-   ring, 0);
+   return true;
else
-   napi_schedule(&ring_data->napi);
+   return false;
 }
 
 static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
@@ -1042,15 +1044,23 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
 
 static int hns_nic_common_poll(struct napi_struct *napi, int budget)
 {
+   int clean_complete = 0;
struct hns_nic_ring_data *ring_data =
container_of(napi, struct hns_nic_ring_data, napi);
-   int clean_complete = ring_data->poll_one(
-   ring_data, budget, ring_data->ex_process);
+   struct hnae_ring *ring = ring_data->ring;
 
-   if (clean_complete >= 0 && clean_complete < budget) {
-   napi_complete(napi);
-   ring_data->fini_process(ring_data);
-   return 0;
+try_again:
+   clean_complete += ring_data->poll_one(
+   ring_data, budget - clean_complete,
+   ring_data->ex_process);
+
+   if (clean_complete < budget) {
+   if (ring_data->fini_process(ring_data)) {
+   napi_complete(napi);
+   ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
+   } else {
+   goto try_again;
+   }
}
 
return clean_complete;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
index fff8f8a..1b83232 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
@@ -41,7 +41,7 @@

[PATCH V2 net-next 08/18] net: hns: Replace netif_tx_lock to ring spin lock

2017-03-31 Thread Salil Mehta
From: lipeng 

netif_tx_lock is a global spin lock, it will take affect
in all rings in the netdevice. In tx_poll_one process, it can
only lock the current ring, in this case, we define a spin lock
in hnae_ring struct for it.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c |  1 +
 drivers/net/ethernet/hisilicon/hns/hnae.h |  3 +++
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 21 +++--
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index 78af663..513c257 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -196,6 +196,7 @@ hnae_init_ring(struct hnae_queue *q, struct hnae_ring 
*ring, int flags)
 
ring->q = q;
ring->flags = flags;
+   spin_lock_init(&ring->lock);
assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
 
/* not matter for tx or rx ring, the ntc and ntc start from 0 */
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index c66581d..859c536 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -275,6 +275,9 @@ struct hnae_ring {
/* statistic */
struct ring_stats stats;
 
+   /* ring lock for poll one */
+   spinlock_t lock;
+
dma_addr_t desc_dma_addr;
u32 buf_size;   /* size for hnae_desc->addr, preset by AE */
u16 desc_num;   /* total number of desc */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 3449a18..3634366 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -922,12 +922,13 @@ static int is_valid_clean_head(struct hnae_ring *ring, 
int h)
 
 /* netif_tx_lock will turn down the performance, set only when necessary */
 #ifdef CONFIG_NET_POLL_CONTROLLER
-#define NETIF_TX_LOCK(ndev) netif_tx_lock(ndev)
-#define NETIF_TX_UNLOCK(ndev) netif_tx_unlock(ndev)
+#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
+#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
 #else
-#define NETIF_TX_LOCK(ndev)
-#define NETIF_TX_UNLOCK(ndev)
+#define NETIF_TX_LOCK(ring)
+#define NETIF_TX_UNLOCK(ring)
 #endif
+
 /* reclaim all desc in one budget
  * return error or number of desc left
  */
@@ -941,13 +942,13 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
int head;
int bytes, pkts;
 
-   NETIF_TX_LOCK(ndev);
+   NETIF_TX_LOCK(ring);
 
head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
rmb(); /* make sure head is ready before touch any data */
 
if (is_ring_empty(ring) || head == ring->next_to_clean) {
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
return 0; /* no data to poll */
}
 
@@ -955,7 +956,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
netdev_err(ndev, "wrong head (%d, %d-%d)\n", head,
   ring->next_to_use, ring->next_to_clean);
ring->stats.io_err_cnt++;
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
return -EIO;
}
 
@@ -967,7 +968,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data 
*ring_data,
prefetch(&ring->desc_cb[ring->next_to_clean]);
}
 
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
 
dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
netdev_tx_completed_queue(dev_queue, pkts, bytes);
@@ -1028,7 +1029,7 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
int head;
int bytes, pkts;
 
-   NETIF_TX_LOCK(ndev);
+   NETIF_TX_LOCK(ring);
 
head = ring->next_to_use; /* ntu :soft setted ring position*/
bytes = 0;
@@ -1036,7 +1037,7 @@ static void hns_nic_tx_clr_all_bufs(struct 
hns_nic_ring_data *ring_data)
while (head != ring->next_to_clean)
hns_nic_reclaim_one_desc(ring, &bytes, &pkts);
 
-   NETIF_TX_UNLOCK(ndev);
+   NETIF_TX_UNLOCK(ring);
 
dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
netdev_tx_reset_queue(dev_queue);
-- 
2.7.4




[PATCH V2 net-next 15/18] net: hns: Simplify the exception sequence in hns_ppe_init()

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

We need to free all ppe submodule if it fails to initialize ppe by
any fault, so this patch will free all ppe resource before
hns_ppe_init() returns exception situation

Reported-by: JinchuanTian 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index 6ea8722..eba406b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -496,17 +496,17 @@ void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 
*data)
  */
 int hns_ppe_init(struct dsaf_device *dsaf_dev)
 {
-   int i, k;
int ret;
+   int i;
 
for (i = 0; i < HNS_PPE_COM_NUM; i++) {
ret = hns_ppe_common_get_cfg(dsaf_dev, i);
if (ret)
-   goto get_ppe_cfg_fail;
+   goto get_cfg_fail;
 
ret = hns_rcb_common_get_cfg(dsaf_dev, i);
if (ret)
-   goto get_rcb_cfg_fail;
+   goto get_cfg_fail;
 
hns_ppe_get_cfg(dsaf_dev->ppe_common[i]);
 
@@ -518,13 +518,12 @@ int hns_ppe_init(struct dsaf_device *dsaf_dev)
 
return 0;
 
-get_rcb_cfg_fail:
-   hns_ppe_common_free_cfg(dsaf_dev, i);
-get_ppe_cfg_fail:
-   for (k = i - 1; k >= 0; k--) {
-   hns_rcb_common_free_cfg(dsaf_dev, k);
-   hns_ppe_common_free_cfg(dsaf_dev, k);
+get_cfg_fail:
+   for (i = 0; i < HNS_PPE_COM_NUM; i++) {
+   hns_rcb_common_free_cfg(dsaf_dev, i);
+   hns_ppe_common_free_cfg(dsaf_dev, i);
}
+
return ret;
 }
 
-- 
2.7.4




[PATCH V2 net-next 16/18] net: hns: Adjust the SBM module buffer threshold

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

HNS needs SMB Buffers to store at least two packets after sending
pause frame because of the link delay. The MTU of HNS is 9728. As
the processor user manual described, the SBM buffer threshold should
be modified.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index abd8aec..d07b4fe 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -510,10 +510,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device 
*dsaf_dev)
o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 48);
+  DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 55);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 80);
+  DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 110);
dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg);
 
/* for no enable pfc mode */
@@ -521,10 +521,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device 
*dsaf_dev)
o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 192);
+  DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 128);
dsaf_set_field(o_sbm_bp_cfg,
   DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M,
-  DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 240);
+  DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 192);
dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg);
}
 
-- 
2.7.4




[PATCH V2 net-next 17/18] net: hns: Avoid Hip06 chip TX packet line bug

2017-03-31 Thread Salil Mehta
From: lipeng 

There is a bug on Hip06 that tx ring interrupts packets count will be
clear when drivers send data to tx ring, so that the tx packets count
will never upgrade to packets line, and cause the interrupts engendered
was delayed.
Sometimes, it will cause sending performance lower than expected.

To fix this bug, we set tx ring interrupts packets line to 1 forever,
to avoid count clear. And set the gap time to 20us, to solve the problem
that too many interrupts engendered when packets line is 1.

This patch could advance the send performance on ARM  from 6.6G to 9.37G
when an iperf send thread on ARM and an iperf send thread on X86 for XGE.

Signed-off-by: lipeng 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.c |   5 ++
 drivers/net/ethernet/hisilicon/hns/hnae.h |   6 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  78 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 101 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h |  23 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |   2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  |  24 +++--
 7 files changed, 169 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index 513c257..8950b74 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -57,10 +57,15 @@ static int hnae_alloc_buffer(struct hnae_ring *ring, struct 
hnae_desc_cb *cb)
 
 static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
 {
+   if (unlikely(!cb->priv))
+   return;
+
if (cb->type == DESC_TYPE_SKB)
dev_kfree_skb_any((struct sk_buff *)cb->priv);
else if (unlikely(is_rx_ring(ring)))
put_page((struct page *)cb->priv);
+
+   cb->priv = NULL;
 }
 
 static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 859c536..0943138 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -488,11 +488,11 @@ struct hnae_ae_ops {
  u32 auto_neg, u32 rx_en, u32 tx_en);
void (*get_coalesce_usecs)(struct hnae_handle *handle,
   u32 *tx_usecs, u32 *rx_usecs);
-   void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
-   u32 *tx_frames, u32 *rx_frames);
+   void (*get_max_coalesced_frames)(struct hnae_handle *handle,
+u32 *tx_frames, u32 *rx_frames);
int (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
int (*set_coalesce_frames)(struct hnae_handle *handle,
-  u32 coalesce_frames);
+  u32 tx_frames, u32 rx_frames);
void (*get_coalesce_range)(struct hnae_handle *handle,
   u32 *tx_frames_low, u32 *rx_frames_low,
   u32 *tx_frames_high, u32 *rx_frames_high,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index f0142e5..ff864a1 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -487,15 +487,21 @@ static void hns_ae_get_coalesce_usecs(struct hnae_handle 
*handle,
   ring_pair->port_id_in_comm);
 }
 
-static void hns_ae_get_rx_max_coalesced_frames(struct hnae_handle *handle,
-  u32 *tx_frames, u32 *rx_frames)
+static void hns_ae_get_max_coalesced_frames(struct hnae_handle *handle,
+   u32 *tx_frames, u32 *rx_frames)
 {
struct ring_pair_cb *ring_pair =
container_of(handle->qs[0], struct ring_pair_cb, q);
+   struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);
 
-   *tx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
- ring_pair->port_id_in_comm);
-   *rx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
+   if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
+   handle->port_type == HNAE_PORT_DEBUG)
+   *tx_frames = hns_rcb_get_rx_coalesced_frames(
+   ring_pair->rcb_common, ring_pair->port_id_in_comm);
+   else
+   *tx_frames = hns_rcb_get_tx_coalesced_frames(
+   ring_pair->rcb_common, ring_pair->port_id_in_comm);
+   *rx_frames = hns_rcb_get_rx_coalesced_frames(ring_pair->rcb_common,
  ring_pair->port_id_in_comm);
 }
 
@@ -509,

[PATCH V2 net-next 18/18] net: hns: Some checkpatch.pl script & warning fixes

2017-03-31 Thread Salil Mehta
This patch fixes some checkpatch.pl script caught errors and
warnings during the compilation time.

Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 11 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  |  9 +
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  1 -
 6 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 0943138..04211ac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -103,7 +103,6 @@ enum hnae_led_state {
 #define HNS_RX_FLAG_L4ID_TCP 0x1
 #define HNS_RX_FLAG_L4ID_SCTP 0x3
 
-
 #define HNS_TXD_ASID_S 0
 #define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
 #define HNS_TXD_BUFNUM_S 8
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 035db86..74bd260 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -86,12 +86,11 @@ static void hns_gmac_disable(void *mac_drv, enum 
mac_commom_mode mode)
dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0);
 }
 
-/**
-*hns_gmac_get_en - get port enable
-*@mac_drv:mac device
-*@rx:rx enable
-*@tx:tx enable
-*/
+/* hns_gmac_get_en - get port enable
+ * @mac_drv:mac device
+ * @rx:rx enable
+ * @tx:tx enable
+ */
 static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 4db02e2..4507e82 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -68,7 +68,7 @@ enum dsaf_roce_qos_sl {
 };
 
 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset
-#define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP)
+#define HNS_DSAF_IS_DEBUG(dev) ((dev)->dsaf_mode == DSAF_MODE_DISABLE_SP)
 
 enum hal_dsaf_mode {
HRD_DSAF_NO_DSAF_MODE   = 0x0,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
index 9b66057..c20a0f4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
@@ -471,7 +471,6 @@ static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb 
*ring_pair_cb)
 static int hns_rcb_get_port_in_comm(
struct rcb_common_cb *rcb_common, int ring_idx)
 {
-
return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn);
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 3634366..837f119 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -512,7 +512,8 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
int last_offset;
bool twobufs;
 
-   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring) == 
HNS_BUFFER_SIZE_2048);
+   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring)
+   == HNS_BUFFER_SIZE_2048);
 
desc = &ring->desc[ring->next_to_clean];
size = le16_to_cpu(desc->rx.size);
@@ -922,8 +923,8 @@ static int is_valid_clean_head(struct hnae_ring *ring, int 
h)
 
 /* netif_tx_lock will turn down the performance, set only when necessary */
 #ifdef CONFIG_NET_POLL_CONTROLLER
-#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
-#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
+#define NETIF_TX_LOCK(ring) spin_lock(&(ring)->lock)
+#define NETIF_TX_UNLOCK(ring) spin_unlock(&(ring)->lock)
 #else
 #define NETIF_TX_LOCK(ring)
 #define NETIF_TX_UNLOCK(ring)
@@ -2012,7 +2013,7 @@ static void hns_nic_reset_subtask(struct hns_nic_priv 
*priv)
 static void hns_nic_service_event_complete(struct hns_nic_priv *priv)
 {
WARN_ON(!test_bit(NIC_STATE_SERVICE_SCHED, &priv->state));
-
+   /* make sure to commit the things */
smp_mb__before_atomic();
clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 36f33bd..b8fab14 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1242,7 +1242,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,
-- 
2.7.4




[PATCH V2 net-next 12/18] net: hns: Remove redundant mac table operations

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

This patch removes redundant functions used only for debugging
purposes.

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 160 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  10 --
 2 files changed, 170 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 6a069ff..abd8aec 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -2008,166 +2008,6 @@ int hns_dsaf_clr_mac_mc_port(struct dsaf_device 
*dsaf_dev, u8 mac_id,
return ret;
 }
 
-/**
- * hns_dsaf_get_mac_uc_entry - get mac uc entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
- struct dsaf_drv_mac_single_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   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) ||
-   MAC_IS_BROADCAST(mac_entry->addr)) {
-   dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
-   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);
-
-   /*check exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*find none, error */
-   dev_err(dsaf_dev->dev,
-   "get_uc_entry failed, %s Mac key(%#x:%#x)\n",
-   dsaf_dev->ae_dev.name,
-   mac_key.high.val, mac_key.low.val);
-   return -EINVAL;
-   }
-   dev_dbg(dsaf_dev->dev,
-   "get_uc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
-   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, &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;
-}
-
-/**
- * hns_dsaf_get_mac_mc_entry - get mac mc entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
- struct dsaf_drv_mac_multi_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   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) ||
-   MAC_IS_BROADCAST(mac_entry->addr)) {
-   dev_err(dsaf_dev->dev, "get_entry failed,addr %pM\n",
-   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);
-
-   /*check exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /* find none, error */
-   dev_err(dsaf_dev->dev,
-   "get_mac_uc_entry failed, %s Mac key(%#x:%#x)\n",
-   dsaf_dev->ae_dev.name, mac_key.high.val,
-   mac_key.low.val);
-   return -EINVAL;
-   }
-   dev_dbg(dsaf_dev->dev,
-   "get_mac_uc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
-   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, &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;
-}
-
-/**
- * hns_dsaf_get_mac_entry_by_index - get mac entry by tab index
- * @dsaf_dev: dsa fabric device struct pointer
- * @entry_index: tab entry index
- * @mac_entry: mac entry
- */
-int hns_dsaf_get_mac_entry_by_index(
-   s

[PATCH V2 net-next 14/18] net: hns: Optimise the code in hns_mdio_wait_ready()

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

This patch fixes the code to clear pclint warning/info.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index fad1c5b..e5221d9 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -175,18 +175,20 @@ static int mdio_sc_cfg_reg_write(struct hns_mdio_device 
*mdio_dev,
 static int hns_mdio_wait_ready(struct mii_bus *bus)
 {
struct hns_mdio_device *mdio_dev = bus->priv;
+   u32 cmd_reg_value;
int i;
-   u32 cmd_reg_value = 1;
 
/* waitting for MDIO_COMMAND_REG 's mdio_start==0 */
/* after that can do read or write*/
-   for (i = 0; cmd_reg_value; i++) {
+   for (i = 0; i < MDIO_TIMEOUT; i++) {
cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
 MDIO_COMMAND_REG,
 MDIO_CMD_START_B);
-   if (i == MDIO_TIMEOUT)
-   return -ETIMEDOUT;
+   if (!cmd_reg_value)
+   break;
}
+   if ((i == MDIO_TIMEOUT) && cmd_reg_value)
+   return -ETIMEDOUT;
 
return 0;
 }
-- 
2.7.4




[PATCH V2 net-next 13/18] net: hns: Clean redundant code from hns_mdio.c file

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

This patch cleans the redundant code from  hns_mdio.c.

Reported-by: Ping Zhang 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index 501eb20..fad1c5b 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -23,17 +23,9 @@
 #include 
 #include 
 #include 
-#include 
 
 #define MDIO_DRV_NAME "Hi-HNS_MDIO"
 #define MDIO_BUS_NAME "Hisilicon MII Bus"
-#define MDIO_DRV_VERSION "1.3.0"
-#define MDIO_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
-#define MDIO_DRV_STRING MDIO_BUS_NAME
-#define MDIO_DEFAULT_DEVICE_DESCR MDIO_BUS_NAME
-
-#define MDIO_CTL_DEV_ADDR(x)   (x & 0x1f)
-#define MDIO_CTL_PORT_ADDR(x)  ((x & 0x1f) << 5)
 
 #define MDIO_TIMEOUT   100
 
@@ -64,9 +56,7 @@ struct hns_mdio_device {
 #define MDIO_CMD_DEVAD_S   0
 #define MDIO_CMD_PRTAD_M   0x1f
 #define MDIO_CMD_PRTAD_S   5
-#define MDIO_CMD_OP_M  0x3
 #define MDIO_CMD_OP_S  10
-#define MDIO_CMD_ST_M  0x3
 #define MDIO_CMD_ST_S  12
 #define MDIO_CMD_START_B   14
 
-- 
2.7.4




[PATCH V2 net-next 10/18] net: hns: Remove the redundant adding and deleting mac function

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

The functions (hns_dsaf_set_mac_mc_entry() and hns_mac_del_mac()) are
not called by any functions. They are dead code in hns. And the same
features are implemented by the patch (the id is 66355f5).

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 38 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 81 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  2 -
 4 files changed, 122 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index edf9a23..696f2ae 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -332,44 +332,6 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
return 0;
 }
 
-/**
- *hns_mac_del_mac - delete mac address into dsaf table,can't delete the same
- *  address twice
- *@net_dev: net device
- *@vfn :   vf lan
- *@mac : mac address
- *return status
- */
-int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac)
-{
-   struct mac_entry_idx *old_mac;
-   struct dsaf_device *dsaf_dev;
-   u32 ret;
-
-   dsaf_dev = mac_cb->dsaf_dev;
-
-   if (vfn < DSAF_MAX_VM_NUM) {
-   old_mac = &mac_cb->addr_entry_idx[vfn];
-   } else {
-   dev_err(mac_cb->dev,
-   "vf queue is too large, %s mac%d queue = %#x!\n",
-   mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vfn);
-   return -EINVAL;
-   }
-
-   if (dsaf_dev) {
-   ret = hns_dsaf_del_mac_entry(dsaf_dev, old_mac->vlan_id,
-mac_cb->mac_id, old_mac->addr);
-   if (ret)
-   return ret;
-
-   if (memcmp(old_mac->addr, mac, sizeof(old_mac->addr)) == 0)
-   old_mac->valid = 0;
-   }
-
-   return 0;
-}
-
 int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn)
 {
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index 7f14d91..e6842c9 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -436,7 +436,6 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
 int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vm, bool enable);
 void hns_mac_start(struct hns_mac_cb *mac_cb);
 void hns_mac_stop(struct hns_mac_cb *mac_cb);
-int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac);
 void hns_mac_uninit(struct dsaf_device *dsaf_dev);
 void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex);
 void hns_mac_reset(struct hns_mac_cb *mac_cb);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 90dbda7..6a069ff 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -1647,87 +1647,6 @@ int hns_dsaf_rm_mac_addr(
  mac_entry->addr);
 }
 
-/**
- * hns_dsaf_set_mac_mc_entry - set mac mc-entry
- * @dsaf_dev: dsa fabric device struct pointer
- * @mac_entry: mc-mac entry
- */
-int hns_dsaf_set_mac_mc_entry(
-   struct dsaf_device *dsaf_dev,
-   struct dsaf_drv_mac_multi_dest_entry *mac_entry)
-{
-   u16 entry_index = DSAF_INVALID_ENTRY_IDX;
-   struct dsaf_drv_tbl_tcam_key mac_key;
-   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_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)) {
-   dev_err(dsaf_dev->dev, "set uc %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 ie exist? */
-   entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*if hasnot, find enpty entry*/
-   entry_index = hns_dsaf_find_empty_mac_entry(dsaf_dev);
-   if (entry_index == DSAF_INVALID_ENTRY_IDX) {
-   /*if hasnot empty, error*/
-

[PATCH V2 net-next 11/18] net: hns: Remove redundant mac_get_id()

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

There is a mac_id in mac control block structure, so the callback
function mac_get_id() is useless. Here we remove this function.

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c  |  8 
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h   |  2 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 13 -
 3 files changed, 23 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 723f3ae..035db86 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -466,13 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
 static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info)
 {
enum hns_gmac_duplex_mdoe duplex;
@@ -714,7 +707,6 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc;
mac_drv->config_half_duplex = hns_gmac_set_duplex_type;
mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames;
-   mac_drv->mac_get_id = hns_gmac_get_id;
mac_drv->get_info = hns_gmac_get_info;
mac_drv->autoneg_stat = hns_gmac_autoneg_stat;
mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index e6842c9..24dfba5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -373,8 +373,6 @@ struct mac_driver {
void (*set_rx_ignore_pause_frames)(void *mac_drv, u32 enable);
/* config rx mode for promiscuous*/
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);
 
void (*autoneg_stat)(void *mac_drv, u32 *enable);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index aae830a..37a2fc3 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -300,18 +300,6 @@ static void hns_xgmac_set_tx_auto_pause_frames(void 
*mac_drv, u16 enable)
 }
 
 /**
- *hns_xgmac_get_id - get xgmac port id
- *@mac_drv: mac driver
- *@newval:xgmac max frame length
- */
-static void hns_xgmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
-/**
  *hns_xgmac_config_max_frame_length - set xgmac max frame length
  *@mac_drv: mac driver
  *@newval:xgmac max frame length
@@ -833,7 +821,6 @@ void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_half_duplex = NULL;
mac_drv->set_rx_ignore_pause_frames =
hns_xgmac_set_rx_ignore_pause_frames;
-   mac_drv->mac_get_id = hns_xgmac_get_id;
mac_drv->mac_free = hns_xgmac_free;
mac_drv->adjust_link = NULL;
mac_drv->set_tx_auto_pause_frames = hns_xgmac_set_tx_auto_pause_frames;
-- 
2.7.4




[PATCH V2 net-next 07/18] net: hns: Fix to adjust buf_size of ring according to mtu

2017-03-31 Thread Salil Mehta
From: lipeng 

Because buf_size of ring set to 2048, the process of rx_poll_one
can reuse the page, therefore the performance of XGE can improve.
But the chip only supports three bds in one package, so the max mtu
is 6K when it sets to 2048. For better performane in litter mtu, we
need change buf_size according to mtu.

When user change mtu, hns is only change the desc in memory. There
are some desc has been fetched by the chip, these desc can not be
changed by the code. So it needs set the port loopback and send
some packages to let the chip consumes the wrong desc and fetch new
desc.
Because the Pv660 do not support rss indirection, we need add version
check in mtu change process.

Signed-off-by: lipeng 
reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |  37 
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  26 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c |   3 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h |   2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c |  41 +++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h |   3 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 249 +-
 7 files changed, 337 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 8016854..c66581d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -67,6 +67,8 @@ do { \
 #define AE_IS_VER1(ver) ((ver) == AE_VERSION_1)
 #define AE_NAME_SIZE 16
 
+#define BD_SIZE_2048_MAX_MTU   6000
+
 /* some said the RX and TX RCB format should not be the same in the future. But
  * it is the same now...
  */
@@ -646,6 +648,41 @@ static inline void hnae_reuse_buffer(struct hnae_ring 
*ring, int i)
ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
 }
 
+/* when reinit buffer size, we should reinit buffer description */
+static inline void hnae_reinit_all_ring_desc(struct hnae_handle *h)
+{
+   int i, j;
+   struct hnae_ring *ring;
+
+   for (i = 0; i < h->q_num; i++) {
+   ring = &h->qs[i]->rx_ring;
+   for (j = 0; j < ring->desc_num; j++)
+   ring->desc[j].addr = cpu_to_le64(ring->desc_cb[j].dma);
+   }
+
+   wmb();  /* commit all data before submit */
+}
+
+/* when reinit buffer size, we should reinit page offset */
+static inline void hnae_reinit_all_ring_page_off(struct hnae_handle *h)
+{
+   int i, j;
+   struct hnae_ring *ring;
+
+   for (i = 0; i < h->q_num; i++) {
+   ring = &h->qs[i]->rx_ring;
+   for (j = 0; j < ring->desc_num; j++) {
+   ring->desc_cb[j].page_offset = 0;
+   if (ring->desc[j].addr !=
+   cpu_to_le64(ring->desc_cb[j].dma))
+   ring->desc[j].addr =
+   cpu_to_le64(ring->desc_cb[j].dma);
+   }
+   }
+
+   wmb();  /* commit all data before submit */
+}
+
 #define hnae_set_field(origin, mask, shift, val) \
do { \
(origin) &= (~(mask)); \
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 0a9cdf0..cd7e88e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -267,8 +267,32 @@ static int hns_ae_clr_multicast(struct hnae_handle *handle)
 static int hns_ae_set_mtu(struct hnae_handle *handle, int new_mtu)
 {
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
+   struct hnae_queue *q;
+   u32 rx_buf_size;
+   int i, ret;
+
+   /* when buf_size is 2048, max mtu is 6K for rx ring max bd num is 3. */
+   if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
+   if (new_mtu <= BD_SIZE_2048_MAX_MTU)
+   rx_buf_size = 2048;
+   else
+   rx_buf_size = 4096;
+   } else {
+   rx_buf_size = mac_cb->dsaf_dev->buf_size;
+   }
+
+   ret = hns_mac_set_mtu(mac_cb, new_mtu, rx_buf_size);
 
-   return hns_mac_set_mtu(mac_cb, new_mtu);
+   if (!ret) {
+   /* reinit ring buf_size */
+   for (i = 0; i < handle->q_num; i++) {
+   q = handle->qs[i];
+   q->rx_ring.buf_size = rx_buf_size;
+   hns_rcb_set_rx_ring_bs(q, rx_buf_size);
+   }
+   }
+
+   return ret;
 }
 
 static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 3239d27..edf9a23 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hn

[PATCH V2 net-next 09/18] net: hns: Correct HNS RSS key set function

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch fixes below ethtool configuration error:

localhost:~ # ethtool -X eth0 hkey XX:XX:XX...
Cannot set Rx flow hash configuration: Operation not supported

Signed-off-by: lipeng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 23 ++-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  |  9 -
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index cd7e88e..f0142e5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -826,8 +826,9 @@ 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 * sizeof(*indir));
+   if (indir)
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE  * sizeof(*indir));
 
return 0;
 }
@@ -838,15 +839,19 @@ static int hns_ae_set_rss(struct hnae_handle *handle, 
const u32 *indir,
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);
 
/* set the RSS Hash Key if specififed by the user */
-   if (key)
-   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
+   if (key) {
+   memcpy(ppe_cb->rss_key, key, HNS_PPEV2_RSS_KEY_SIZE);
+   hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
+   }
 
-   /* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir,
-  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
+   if (indir) {
+   /* update the shadow RSS table with user specified qids */
+   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);
+   /* now update the hardware */
+   hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
+   }
 
return 0;
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3404eac..3a2a342 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1244,6 +1244,7 @@ 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,
@@ -1253,12 +1254,10 @@ hns_set_rss(struct net_device *netdev, const u32 
*indir, const u8 *key,
 
ops = priv->ae_handle->dev->ops;
 
-   /* currently hfunc can only be Toeplitz hash */
-   if (key ||
-   (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
+   if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
+   netdev_err(netdev, "Invalid hfunc!\n");
return -EOPNOTSUPP;
-   if (!indir)
-   return 0;
+   }
 
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
-- 
2.7.4




[PATCH V2 net-next 02/18] net: hns: Modify GMAC init TX threshold value

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch reduces GMAC TX threshold value to avoid gmac
hang-up with speed 100M/duplex half.

Signed-off-by: lipeng 
Signed-off-by: JinchuanTian 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 6 ++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  | 4 
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 3382441..a8dbe00 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -325,6 +325,12 @@ static void hns_gmac_init(void *mac_drv)
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);
+
+   /* reduce gmac tx water line to avoid gmac hang-up
+* in speed 100M and duplex half.
+*/
+   dsaf_set_dev_field(drv, GMAC_TX_WATER_LINE_REG, GMAC_TX_WATER_LINE_MASK,
+  GMAC_TX_WATER_LINE_SHIFT, 8);
 }
 
 void hns_gmac_update_stats(void *mac_drv)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 8fa18fc..4b8af68 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -466,6 +466,7 @@
 
 #define GMAC_DUPLEX_TYPE_REG   0x0008UL
 #define GMAC_FD_FC_TYPE_REG0x000CUL
+#define GMAC_TX_WATER_LINE_REG 0x0010UL
 #define GMAC_FC_TX_TIMER_REG   0x001CUL
 #define GMAC_FD_FC_ADDR_LOW_REG0x0020UL
 #define GMAC_FD_FC_ADDR_HIGH_REG   0x0024UL
@@ -912,6 +913,9 @@
 
 #define GMAC_DUPLEX_TYPE_B 0
 
+#define GMAC_TX_WATER_LINE_MASK((1UL << 8) - 1)
+#define GMAC_TX_WATER_LINE_SHIFT   0
+
 #define GMAC_FC_TX_TIMER_S 0
 #define GMAC_FC_TX_TIMER_M 0x
 
-- 
2.7.4




[PATCH V2 net-next 03/18] net: hns: Optimize the code for GMAC pad and crc Config

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch optimises the init configuration code leg
for gmac pad and crc set interface.

Signed-off-by: lipeng 
Signed-off-by: JinchuanTian 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 36 ++
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index a8dbe00..723f3ae 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -148,6 +148,17 @@ static void hns_gmac_config_max_frame_length(void 
*mac_drv, u16 newval)
   GMAC_MAX_FRM_SIZE_S, newval);
 }
 
+static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
+{
+   u32 tx_ctrl;
+   struct mac_driver *drv = (struct mac_driver *)mac_drv;
+
+   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
+   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
+}
+
 static void hns_gmac_config_an_mode(void *mac_drv, u8 newval)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
@@ -250,7 +261,6 @@ static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 
*rx_pause_en,
 static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
u32 full_duplex)
 {
-   u32 tx_ctrl;
struct mac_driver *drv = (struct mac_driver *)mac_drv;
 
dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG,
@@ -279,14 +289,6 @@ static int hns_gmac_adjust_link(void *mac_drv, enum 
mac_speed speed,
return -EINVAL;
}
 
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, 1);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, 1);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-
-   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
-GMAC_MODE_CHANGE_EB_B, 1);
-
return 0;
 }
 
@@ -326,6 +328,11 @@ static void hns_gmac_init(void *mac_drv)
if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
hns_gmac_set_uc_match(mac_drv, 0);
 
+   hns_gmac_config_pad_and_crc(mac_drv, 1);
+
+   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
+GMAC_MODE_CHANGE_EB_B, 1);
+
/* reduce gmac tx water line to avoid gmac hang-up
 * in speed 100M and duplex half.
 */
@@ -459,17 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
-{
-   u32 tx_ctrl;
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-}
-
 static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
-- 
2.7.4




[PATCH V2 net-next 01/18] net: hns: Fix the implementation of irq affinity function

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch fixes the implementation of the IRQ affinity
function. This function is used to create the cpu mask
which eventually is used to initialize the cpu<->queue
association for XPS(Transmit Packet Steering).

Signed-off-by: lipeng 
Signed-off-by: Kejian Yan 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 75 +++
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  1 +
 2 files changed, 30 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index fca37e2..73ec8c8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1196,54 +1196,31 @@ static void hns_nic_ring_close(struct net_device 
*netdev, int idx)
napi_disable(&priv->ring_data[idx].napi);
 }
 
-static void hns_set_irq_affinity(struct hns_nic_priv *priv)
+static int hns_nic_init_affinity_mask(int q_num, int ring_idx,
+ struct hnae_ring *ring, cpumask_t *mask)
 {
-   struct hnae_handle *h = priv->ae_handle;
-   struct hns_nic_ring_data *rd;
-   int i;
int cpu;
-   cpumask_var_t mask;
 
-   if (!alloc_cpumask_var(&mask, GFP_KERNEL))
-   return;
-
-   /*diffrent irq banlance for 16core and 32core*/
-   if (h->q_num == num_possible_cpus()) {
-   for (i = 0; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   /* Diffrent irq banlance between 16core and 32core.
+* The cpu mask set by ring index according to the ring flag
+* which indicate the ring is tx or rx.
+*/
+   if (q_num == num_possible_cpus()) {
+   if (is_tx_ring(ring))
+   cpu = ring_idx;
+   else
+   cpu = ring_idx - q_num;
} else {
-   for (i = 0; i < h->q_num; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
-
-   for (i = h->q_num; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2 + 1)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2 + 1;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   if (is_tx_ring(ring))
+   cpu = ring_idx * 2;
+   else
+   cpu = (ring_idx - q_num) * 2 + 1;
}
 
-   free_cpumask_var(mask);
+   cpumask_clear(mask);
+   cpumask_set_cpu(cpu, mask);
+
+   return cpu;
 }
 
 static int hns_nic_init_irq(struct hns_nic_priv *priv)
@@ -1252,6 +1229,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
struct hns_nic_ring_data *rd;
int i;
int ret;
+   int cpu;
 
for (i = 0; i < h->q_num * 2; i++) {
rd = &priv->ring_data[i];
@@ -1261,7 +1239,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
 
snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN,
 "%s-%s%d", priv->netdev->name,
-(i < h->q_num ? "tx" : "rx"), rd->queue_index);
+(is_tx_ring(rd->ring) ? "tx" : "rx"), rd->queue_index);
 
rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
 
@@ -1273,12 +1251,17 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
return ret;
}
disable_irq(rd->ring->irq);
+
+   cpu = hns_nic_init_affinity_mask(h->q_num, i,
+rd->ring, &rd-&

RE: [PATCH V2 net-next 18/18] net: hns: Some checkpatch.pl script & warning fixes

2017-03-31 Thread Salil Mehta
> -Original Message-
> From: Joe Perches [mailto:j...@perches.com]
> Sent: Friday, March 31, 2017 4:45 PM
> To: Salil Mehta; da...@davemloft.net
> Cc: Zhuangyuzeng (Yisen); mehta.salil@gmail.com;
> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH V2 net-next 18/18] net: hns: Some checkpatch.pl
> script & warning fixes
> 
> On Fri, 2017-03-31 at 12:20 +0100, Salil Mehta wrote:
> > This patch fixes some checkpatch.pl script caught errors and
> > warnings during the compilation time.
> []
> > diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> []
> > @@ -512,7 +512,8 @@ static void hns_nic_reuse_page(struct sk_buff
> *skb, int i,
> > int last_offset;
> > bool twobufs;
> >
> > -   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring) ==
> HNS_BUFFER_SIZE_2048);
> > +   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring)
> > +   == HNS_BUFFER_SIZE_2048);
> 
> This would read nicer without splitting a comparison test
> onto multiple lines
> 
>   twobufs = PAGE_SIZE < 8192 &&
> hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048;
For sure, thanks for noticing. Will correct this!

Best regards
Salil
> 



[PATCH V3 net-next 05/18] net: hns: bug fix of ethtool show the speed

2017-03-31 Thread Salil Mehta
From: Daode Huang 

When run ethtool ethX on hns driver, the speed will show
as "Unknown". The base.speed is not correct assigned,
this patch fix this bug.

Signed-off-by: Daode Huang 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3ac2183..3404eac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -146,7 +146,7 @@ static int hns_nic_get_link_ksettings(struct net_device 
*net_dev,
 
/* When there is no phy, autoneg is off. */
cmd->base.autoneg = false;
-   cmd->base.cmd = speed;
+   cmd->base.speed = speed;
cmd->base.duplex = duplex;
 
if (net_dev->phydev)
-- 
2.7.4




[PATCH V3 net-next 03/18] net: hns: Optimize the code for GMAC pad and crc Config

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch optimises the init configuration code leg
for gmac pad and crc set interface.

Signed-off-by: lipeng 
Signed-off-by: JinchuanTian 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 36 ++
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index a8dbe00..723f3ae 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -148,6 +148,17 @@ static void hns_gmac_config_max_frame_length(void 
*mac_drv, u16 newval)
   GMAC_MAX_FRM_SIZE_S, newval);
 }
 
+static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
+{
+   u32 tx_ctrl;
+   struct mac_driver *drv = (struct mac_driver *)mac_drv;
+
+   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
+   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
+   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
+}
+
 static void hns_gmac_config_an_mode(void *mac_drv, u8 newval)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
@@ -250,7 +261,6 @@ static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 
*rx_pause_en,
 static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
u32 full_duplex)
 {
-   u32 tx_ctrl;
struct mac_driver *drv = (struct mac_driver *)mac_drv;
 
dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG,
@@ -279,14 +289,6 @@ static int hns_gmac_adjust_link(void *mac_drv, enum 
mac_speed speed,
return -EINVAL;
}
 
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, 1);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, 1);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-
-   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
-GMAC_MODE_CHANGE_EB_B, 1);
-
return 0;
 }
 
@@ -326,6 +328,11 @@ static void hns_gmac_init(void *mac_drv)
if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
hns_gmac_set_uc_match(mac_drv, 0);
 
+   hns_gmac_config_pad_and_crc(mac_drv, 1);
+
+   dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
+GMAC_MODE_CHANGE_EB_B, 1);
+
/* reduce gmac tx water line to avoid gmac hang-up
 * in speed 100M and duplex half.
 */
@@ -459,17 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
-{
-   u32 tx_ctrl;
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
-   dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
-   dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
-}
-
 static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
-- 
2.7.4




[PATCH V3 net-next 01/18] net: hns: Fix the implementation of irq affinity function

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch fixes the implementation of the IRQ affinity
function. This function is used to create the cpu mask
which eventually is used to initialize the cpu<->queue
association for XPS(Transmit Packet Steering).

Signed-off-by: lipeng 
Signed-off-by: Kejian Yan 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 75 +++
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  1 +
 2 files changed, 30 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index fca37e2..73ec8c8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1196,54 +1196,31 @@ static void hns_nic_ring_close(struct net_device 
*netdev, int idx)
napi_disable(&priv->ring_data[idx].napi);
 }
 
-static void hns_set_irq_affinity(struct hns_nic_priv *priv)
+static int hns_nic_init_affinity_mask(int q_num, int ring_idx,
+ struct hnae_ring *ring, cpumask_t *mask)
 {
-   struct hnae_handle *h = priv->ae_handle;
-   struct hns_nic_ring_data *rd;
-   int i;
int cpu;
-   cpumask_var_t mask;
 
-   if (!alloc_cpumask_var(&mask, GFP_KERNEL))
-   return;
-
-   /*diffrent irq banlance for 16core and 32core*/
-   if (h->q_num == num_possible_cpus()) {
-   for (i = 0; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   /* Diffrent irq banlance between 16core and 32core.
+* The cpu mask set by ring index according to the ring flag
+* which indicate the ring is tx or rx.
+*/
+   if (q_num == num_possible_cpus()) {
+   if (is_tx_ring(ring))
+   cpu = ring_idx;
+   else
+   cpu = ring_idx - q_num;
} else {
-   for (i = 0; i < h->q_num; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
-
-   for (i = h->q_num; i < h->q_num * 2; i++) {
-   rd = &priv->ring_data[i];
-   if (cpu_online(rd->queue_index * 2 + 1)) {
-   cpumask_clear(mask);
-   cpu = rd->queue_index * 2 + 1;
-   cpumask_set_cpu(cpu, mask);
-   (void)irq_set_affinity_hint(rd->ring->irq,
-   mask);
-   }
-   }
+   if (is_tx_ring(ring))
+   cpu = ring_idx * 2;
+   else
+   cpu = (ring_idx - q_num) * 2 + 1;
}
 
-   free_cpumask_var(mask);
+   cpumask_clear(mask);
+   cpumask_set_cpu(cpu, mask);
+
+   return cpu;
 }
 
 static int hns_nic_init_irq(struct hns_nic_priv *priv)
@@ -1252,6 +1229,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
struct hns_nic_ring_data *rd;
int i;
int ret;
+   int cpu;
 
for (i = 0; i < h->q_num * 2; i++) {
rd = &priv->ring_data[i];
@@ -1261,7 +1239,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
 
snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN,
 "%s-%s%d", priv->netdev->name,
-(i < h->q_num ? "tx" : "rx"), rd->queue_index);
+(is_tx_ring(rd->ring) ? "tx" : "rx"), rd->queue_index);
 
rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
 
@@ -1273,12 +1251,17 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
return ret;
}
disable_irq(rd->ring->irq);
+
+   cpu = hns_nic_init_affinity_mask(h->q_num, i,
+rd->ring, &rd-&

[PATCH V3 net-next 11/18] net: hns: Remove redundant mac_get_id()

2017-03-31 Thread Salil Mehta
From: Kejian Yan 

There is a mac_id in mac control block structure, so the callback
function mac_get_id() is useless. Here we remove this function.

Reported-by: Weiwei Deng 
Signed-off-by: Kejian Yan 
Reviewed-by: Salil Mehta 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c  |  8 
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h   |  2 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 13 -
 3 files changed, 23 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 723f3ae..035db86 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -466,13 +466,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum 
hnae_loop loop_mode,
return 0;
 }
 
-static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
 static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info)
 {
enum hns_gmac_duplex_mdoe duplex;
@@ -714,7 +707,6 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc;
mac_drv->config_half_duplex = hns_gmac_set_duplex_type;
mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames;
-   mac_drv->mac_get_id = hns_gmac_get_id;
mac_drv->get_info = hns_gmac_get_info;
mac_drv->autoneg_stat = hns_gmac_autoneg_stat;
mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index e6842c9..24dfba5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -373,8 +373,6 @@ struct mac_driver {
void (*set_rx_ignore_pause_frames)(void *mac_drv, u32 enable);
/* config rx mode for promiscuous*/
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);
 
void (*autoneg_stat)(void *mac_drv, u32 *enable);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index aae830a..37a2fc3 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -300,18 +300,6 @@ static void hns_xgmac_set_tx_auto_pause_frames(void 
*mac_drv, u16 enable)
 }
 
 /**
- *hns_xgmac_get_id - get xgmac port id
- *@mac_drv: mac driver
- *@newval:xgmac max frame length
- */
-static void hns_xgmac_get_id(void *mac_drv, u8 *mac_id)
-{
-   struct mac_driver *drv = (struct mac_driver *)mac_drv;
-
-   *mac_id = drv->mac_id;
-}
-
-/**
  *hns_xgmac_config_max_frame_length - set xgmac max frame length
  *@mac_drv: mac driver
  *@newval:xgmac max frame length
@@ -833,7 +821,6 @@ void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct 
mac_params *mac_param)
mac_drv->config_half_duplex = NULL;
mac_drv->set_rx_ignore_pause_frames =
hns_xgmac_set_rx_ignore_pause_frames;
-   mac_drv->mac_get_id = hns_xgmac_get_id;
mac_drv->mac_free = hns_xgmac_free;
mac_drv->adjust_link = NULL;
mac_drv->set_tx_auto_pause_frames = hns_xgmac_set_tx_auto_pause_frames;
-- 
2.7.4




[PATCH V3 net-next 18/18] net: hns: Some checkpatch.pl script & warning fixes

2017-03-31 Thread Salil Mehta
This patch fixes some checkpatch.pl script caught errors and
warnings during the compilation time.

Signed-off-by: Salil Mehta 
---
Patch V3: https://lkml.org/lkml/2017/3/31/538
  Adressed the comment by Joe Perches
---
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 11 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  |  9 +
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  1 -
 6 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index 0943138..04211ac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -103,7 +103,6 @@ enum hnae_led_state {
 #define HNS_RX_FLAG_L4ID_TCP 0x1
 #define HNS_RX_FLAG_L4ID_SCTP 0x3
 
-
 #define HNS_TXD_ASID_S 0
 #define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
 #define HNS_TXD_BUFNUM_S 8
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 035db86..74bd260 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -86,12 +86,11 @@ static void hns_gmac_disable(void *mac_drv, enum 
mac_commom_mode mode)
dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0);
 }
 
-/**
-*hns_gmac_get_en - get port enable
-*@mac_drv:mac device
-*@rx:rx enable
-*@tx:tx enable
-*/
+/* hns_gmac_get_en - get port enable
+ * @mac_drv:mac device
+ * @rx:rx enable
+ * @tx:tx enable
+ */
 static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx)
 {
struct mac_driver *drv = (struct mac_driver *)mac_drv;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 4db02e2..4507e82 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -68,7 +68,7 @@ enum dsaf_roce_qos_sl {
 };
 
 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset
-#define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP)
+#define HNS_DSAF_IS_DEBUG(dev) ((dev)->dsaf_mode == DSAF_MODE_DISABLE_SP)
 
 enum hal_dsaf_mode {
HRD_DSAF_NO_DSAF_MODE   = 0x0,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
index 9b66057..c20a0f4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
@@ -471,7 +471,6 @@ static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb 
*ring_pair_cb)
 static int hns_rcb_get_port_in_comm(
struct rcb_common_cb *rcb_common, int ring_idx)
 {
-
return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn);
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 3634366..1f7b2cd 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -512,7 +512,8 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
int last_offset;
bool twobufs;
 
-   twobufs = ((PAGE_SIZE < 8192) && hnae_buf_size(ring) == 
HNS_BUFFER_SIZE_2048);
+   twobufs = ((PAGE_SIZE < 8192) &&
+   hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048);
 
desc = &ring->desc[ring->next_to_clean];
size = le16_to_cpu(desc->rx.size);
@@ -922,8 +923,8 @@ static int is_valid_clean_head(struct hnae_ring *ring, int 
h)
 
 /* netif_tx_lock will turn down the performance, set only when necessary */
 #ifdef CONFIG_NET_POLL_CONTROLLER
-#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
-#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
+#define NETIF_TX_LOCK(ring) spin_lock(&(ring)->lock)
+#define NETIF_TX_UNLOCK(ring) spin_unlock(&(ring)->lock)
 #else
 #define NETIF_TX_LOCK(ring)
 #define NETIF_TX_UNLOCK(ring)
@@ -2012,7 +2013,7 @@ static void hns_nic_reset_subtask(struct hns_nic_priv 
*priv)
 static void hns_nic_service_event_complete(struct hns_nic_priv *priv)
 {
WARN_ON(!test_bit(NIC_STATE_SERVICE_SCHED, &priv->state));
-
+   /* make sure to commit the things */
smp_mb__before_atomic();
clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 36f33bd..b8fab14 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1242,7 +1242,6 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
 {
struct hns_nic_priv *priv = netdev_priv(net

[PATCH V3 net-next 09/18] net: hns: Correct HNS RSS key set function

2017-03-31 Thread Salil Mehta
From: lipeng 

This patch fixes below ethtool configuration error:

localhost:~ # ethtool -X eth0 hkey XX:XX:XX...
Cannot set Rx flow hash configuration: Operation not supported

Signed-off-by: lipeng 
Reviewed-by: Yisen Zhuang 
Signed-off-by: Salil Mehta 
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 23 ++-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  |  9 -
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index cd7e88e..f0142e5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -826,8 +826,9 @@ 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 * sizeof(*indir));
+   if (indir)
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE  * sizeof(*indir));
 
return 0;
 }
@@ -838,15 +839,19 @@ static int hns_ae_set_rss(struct hnae_handle *handle, 
const u32 *indir,
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);
 
/* set the RSS Hash Key if specififed by the user */
-   if (key)
-   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
+   if (key) {
+   memcpy(ppe_cb->rss_key, key, HNS_PPEV2_RSS_KEY_SIZE);
+   hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
+   }
 
-   /* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir,
-  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
+   if (indir) {
+   /* update the shadow RSS table with user specified qids */
+   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);
+   /* now update the hardware */
+   hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
+   }
 
return 0;
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3404eac..3a2a342 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1244,6 +1244,7 @@ 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,
@@ -1253,12 +1254,10 @@ hns_set_rss(struct net_device *netdev, const u32 
*indir, const u8 *key,
 
ops = priv->ae_handle->dev->ops;
 
-   /* currently hfunc can only be Toeplitz hash */
-   if (key ||
-   (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
+   if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
+   netdev_err(netdev, "Invalid hfunc!\n");
return -EOPNOTSUPP;
-   if (!indir)
-   return 0;
+   }
 
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
-- 
2.7.4




<    1   2   3   4   5   6   7   >